Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add JSP (Java Server Pages) lexer #915

Merged
merged 1 commit into from
Aug 10, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 29 additions & 0 deletions lib/rouge/demos/jsp
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ page import="java.time.LocalDateTime" %>

<%! int day = 3; %>

<!DOCTYPE html>
<html>
<head>
<title>Simple JSP Application</title>
</head>
<body>
<%-- This is a JSP comment --%>
<h1>Hello world!</h1>
<h2>Current time is <%= LocalDateTime.now() %></h2>

<% if (day == 1 || day == 7) { %>
<p> Today is weekend</p>
<% } else { %>
<p> Today is not weekend</p>
<% } %>

h2>Using JavaBeans in JSP</h2>
<jsp:useBean id="test" class="action.TestBean" />
<jsp:setProperty name="test" property="message" value="Hello JSP..." />

<p>Got message:</p>
<jsp:getProperty name="test" property="message" />
</body>
</html>
119 changes: 119 additions & 0 deletions lib/rouge/lexers/jsp.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
# -*- coding: utf-8 -*- #

module Rouge
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please change all indenting to 2 spaces.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FWIW, I'm not sure why Rubocop didn't complain. I'll investigate that later.

module Lexers
class JSP < TemplateLexer
desc 'JSP'
tag 'jsp'
filenames '*.jsp'
mimetypes 'text/x-jsp', 'application/x-jsp'

def initialize(*)
super
@java = Java.new
end

directives = %w(page include taglib)
actions = %w(scriptlet declaration expression)

state :root do

rule /<%--/, Comment, :jsp_comment

rule /<%@\s*(#{directives.join('|')})\s*/, Name::Tag, :jsp_directive

rule /<jsp:directive\.(#{directives.join('|')})/, Name::Tag, :jsp_directive2

rule /<jsp:(#{actions.join('|')})>/, Name::Tag, :jsp_expression

# start of tag, e.g. <c:if>
rule /<[a-zA-Z]*:[a-zA-Z]*\s*/, Name::Tag, :jsp_tag

# end of tag, e.g. </c:if>
rule /<\/[a-zA-Z]*:[a-zA-Z]*>/, Name::Tag

rule /<%[!=]?/, Name::Tag, :jsp_expression2

# fallback to HTML
rule(/(.+?)(?=(<%|<\/?[a-zA-Z]*:))/m) { delegate parent }
rule(/.+/m) { delegate parent }
end

state :jsp_comment do
rule /(--%>)/, Comment, :pop!
rule /./m, Comment
end

state :jsp_directive do
rule /(%>)/, Name::Tag, :pop!
mixin :attributes
rule(/(.+?)(?=%>)/m) { delegate parent }
end

state :jsp_directive2 do
rule /(\/>)/, Name::Tag, :pop!
mixin :attributes
rule(/(.+?)(?=\/>)/m) { delegate parent }
end

state :jsp_expression do
rule /<\/jsp:(#{actions.join('|')})>/, Name::Tag, :pop!
mixin :attributes
rule(/[^<\/]+/) { delegate @java }
end

state :jsp_expression2 do
rule /%>/, Name::Tag, :pop!
rule(/[^%>]+/) { delegate @java }
end

state :jsp_tag do
rule /\/?>/, Name::Tag, :pop!
mixin :attributes
rule(/(.+?)(?=\/?>)/m) { delegate parent }
end

state :attributes do
rule /\s*[a-zA-Z0-9_:-]+\s*=\s*/m, Name::Attribute, :attr
end

state :attr do
rule /"/ do
token Str
goto :double_quotes
end

rule /'/ do
token Str
goto :single_quotes
end

rule /[^\s>]+/, Str, :pop!
end

state :double_quotes do
rule /"/, Str, :pop!
rule /\$\{/, Str::Interpol, :jsp_interp
rule /[^"]+/, Str
end

state :single_quotes do
rule /'/, Str, :pop!
rule /\$\{/, Str::Interpol, :jsp_interp
rule /[^']+/, Str
end

state :jsp_interp do
rule /\}/, Str::Interpol, :pop!
rule /'/, Literal, :jsp_interp_literal_start
rule(/[^'\}]+/) { delegate @java }
end

state :jsp_interp_literal_start do
rule /'/, Literal, :pop!
rule /[^']*/, Literal
end

end
end
end
20 changes: 20 additions & 0 deletions spec/lexers/jsp_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# -*- coding: utf-8 -*- #

describe Rouge::Lexers::JSP do
let(:subject) { Rouge::Lexers::JSP.new }
let(:bom) { "\xEF\xBB\xBF" }

describe 'guessing' do
include Support::Guessing

it 'guesses by filename' do
assert_guess :filename => 'file.jsp'
end

it 'guesses by mimetype' do
assert_guess :mimetype => 'text/x-jsp'
assert_guess :mimetype => 'application/x-jsp'
end

end
end
142 changes: 142 additions & 0 deletions spec/visual/samples/jsp
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
<%@ taglib uri="uri" prefix="prefixOfTag" %>
<%@taglib prefix="c" uri="uri"%>
<%@ page isELIgnored = "false" %>

<%-- This is
a
multiline
comment
--%>

<html>
<head><title>Hello World</title></head>
<c:set var="realm" value='<%=AppConfig.getRealm().name()%>' />

<body>
Hello World!<br/>

<script type="text/javascript">
<c:if test="${includeJS}">
alert("hello!");
var country = "argentina";
</c:if>
<jsp:scriptlet>
out.println("Your IP address is " + request.getRemoteAddr());
</jsp:scriptlet>
</script>

<style>
.timer {position:relative; height:8px; margin-bottom:2px; font-size:1px;}
<c:if test="${includeJS}">
.timer2 {position:absolute;}
</c:if>
</style>

<div class="nav-link" style="display:<%=isAdmin ? "inline" : "none" %>">
</div>

<a href="/search?q=<c:out value="${query}"/>&h_pageNumber=1&h_pageSize=10">
A link!
</a>

<select name="role" <c:if test="${isAdmin}">disabled="disabled"</c:if>>
<option value="User" <c:if test="${user.role eq 'ENTITY_USER'}">selected="selected"</c:if>></option>
</select>

<%-- Interpolations --%>

<input type="${'hidden'}" id="sampleCertificate" value="<c:out value ="${sampleCertificate}"/>" />

<c:text>
${myViewModel.myProperty}
</c:text>

<%-- Scriptlets --%>

<%
out.println("Your IP address is " + request.getRemoteAddr());
%>
<jsp:scriptlet>
out.println("Your IP address is " + request.getRemoteAddr());
</jsp:scriptlet>

<%-- Declarations --%>

<%! int i=0; %>
<%! int a, b, c; %>
<%! Circle a=new Circle(2.0); %>

<jsp:declaration>
Rectangle r=new Rectangle(2.0);
</jsp:declaration>

<%-- Expressions --%>

<p>Today's date: <%= (new java.util.Date()).toLocaleString()%></p>

<jsp:expression>
(new java.util.Date()).toLocaleString();
</jsp:expression>

<%-- Directives --%>

<%@ page attribute="value" %>
<jsp:directive.page attribute="value" />
<%@ include file="relative url" %>
<jsp:directive.include file="relative url" />
<%@ taglib uri="uri" prefix="prefixOfTag" %>
<jsp:directive.taglib uri="uri" prefix="prefixOfTag" />

<%-- Actions --%>

<jsp:include page="relative URL" flush="true" />
<jsp:useBean id="name" class="package.class" />
<jsp:useBean id="myName" class="package.class" >
<jsp:setProperty name="myName" property="someProperty" />
</jsp:useBean>
<jsp:getProperty name="myName" property="someProperty" />
<jsp:forward page="date.jsp" />
<jsp:plugin type="applet" codebase="dirname" code="MyApplet.class"
width="60" height="80">
<jsp:param name="fontcolor" value="red" />
<jsp:param name="background" value="black" />

<jsp:fallback>
Unable to initialize Java Plugin
</jsp:fallback>

</jsp:plugin>
<jsp:element name="xmlElement">
<jsp:attribute name="xmlElementAttr">
Value for the attribute
</jsp:attribute>

<jsp:body>
Body for XML element
</jsp:body>

</jsp:element>
<jsp:text>Template data</jsp:text>

<%-- Using tag libraries --%>

<c:set var="nameofvariable" value="10"/>
<c:if test="nameofvariable == 10">
<p>Condition is true!</p>
<input name="pswd" type="password" />
<script type="text/javascript">
function callMe() {
return 42;
}
</script>
<jsp:scriptlet>
out.println("Your IP address is " + request.getRemoteAddr());
</jsp:scriptlet>
</c:if>
<c:otherwise>
<p>Boo! Condition is false!</p>
</c:otherwise>


</body>
</html>