Added javac compiler message highlighting.
This commit is contained in:
parent
eb1aef1b67
commit
80c7b57717
|
@ -15,7 +15,7 @@ from lodgeit.lib import antispam
|
|||
from lodgeit.i18n import list_languages, _
|
||||
from lodgeit.utils import render_to_response
|
||||
from lodgeit.database import session, Paste
|
||||
from lodgeit.lib.highlighting import LANGUAGES, STYLES, get_style
|
||||
from lodgeit.lib.highlighting import list_languages, STYLES, get_style
|
||||
from lodgeit.lib.pagination import generate_pagination
|
||||
from lodgeit.lib.captcha import check_hashed_solution, Captcha
|
||||
|
||||
|
@ -71,7 +71,7 @@ class PasteController(object):
|
|||
private = parent.private
|
||||
|
||||
return render_to_response('new_paste.html',
|
||||
languages=LANGUAGES,
|
||||
languages=list_languages(),
|
||||
parent=parent,
|
||||
code=code,
|
||||
language=language,
|
||||
|
|
|
@ -22,15 +22,35 @@ _gcc_message_re = re.compile(r'''(?ux)
|
|||
$
|
||||
''')
|
||||
|
||||
_javac_message_re = re.compile(r'''(?ux)
|
||||
^\s*
|
||||
(?P<filename>[^:]*)
|
||||
:(?P<line>\d*)
|
||||
(:(?P<column>\d*))?
|
||||
\s(?P<message>.*)
|
||||
$
|
||||
''')
|
||||
_javac_prefix_re = re.compile(r'^\s*\[javac\]\s')
|
||||
_javac_junk_re = re.compile(r'^((Note:\s+.*?)|(\d+)\s+errors\s*)$')
|
||||
|
||||
class Message(object):
|
||||
|
||||
class Raw(object):
|
||||
is_raw = True
|
||||
|
||||
def __init__(self, raw):
|
||||
self.raw = raw
|
||||
|
||||
|
||||
class Message(Raw):
|
||||
is_raw = False
|
||||
|
||||
def __init__(self, raw, filename, lineno, column, message):
|
||||
self.raw = raw
|
||||
Raw.__init__(self, raw)
|
||||
self.filename = filename
|
||||
self.lineno = lineno
|
||||
self.column = column
|
||||
self.message = message
|
||||
self.context = ''
|
||||
|
||||
@property
|
||||
def level(self):
|
||||
|
@ -65,3 +85,46 @@ def parse_gcc_messages(data):
|
|||
if match is not None:
|
||||
result.append(make_message(line, **match.groupdict()))
|
||||
return result
|
||||
|
||||
|
||||
def parse_javac_messages(data):
|
||||
"""Parse javac messages."""
|
||||
result = []
|
||||
linebuffer = []
|
||||
|
||||
def _remove_prefix(line):
|
||||
match = _javac_prefix_re.match(line)
|
||||
if match is not None:
|
||||
line = line[match.end():]
|
||||
return line
|
||||
|
||||
def _append_buffered_lines():
|
||||
if not linebuffer:
|
||||
return
|
||||
if not result:
|
||||
result.append(Raw('\n'.join(linebuffer)))
|
||||
else:
|
||||
last = result[-1]
|
||||
last.raw = '\n'.join([last.raw] + linebuffer)
|
||||
if not last.is_raw:
|
||||
before = last.context and [last.context] or []
|
||||
last.context = '\n'.join(before + linebuffer)
|
||||
del linebuffer[:]
|
||||
|
||||
lineiter = iter(data.splitlines())
|
||||
for line in lineiter:
|
||||
line = _remove_prefix(line)
|
||||
match = _javac_junk_re.match(line)
|
||||
if match is not None:
|
||||
_append_buffered_lines()
|
||||
result.append(Raw(line))
|
||||
continue
|
||||
match = _javac_message_re.match(line)
|
||||
if match is None:
|
||||
linebuffer.append(line)
|
||||
else:
|
||||
_append_buffered_lines()
|
||||
result.append(make_message(line, **match.groupdict()))
|
||||
|
||||
_append_buffered_lines()
|
||||
return result
|
||||
|
|
|
@ -13,7 +13,7 @@ import pygments
|
|||
import csv
|
||||
from pygments.util import ClassNotFound
|
||||
from pygments.lexers import get_lexer_by_name, get_lexer_for_filename, \
|
||||
get_lexer_for_mimetype, PhpLexer
|
||||
get_lexer_for_mimetype, PhpLexer, TextLexer
|
||||
from pygments.styles import get_all_styles
|
||||
from pygments.formatters import HtmlFormatter
|
||||
|
||||
|
@ -21,7 +21,8 @@ from lodgeit import local
|
|||
from lodgeit.i18n import lazy_gettext as _
|
||||
from lodgeit.utils import render_template
|
||||
from lodgeit.lib.diff import prepare_udiff
|
||||
from lodgeit.lib.compilerparser import parse_gcc_messages
|
||||
from lodgeit.lib.compilerparser import parse_gcc_messages, \
|
||||
parse_javac_messages
|
||||
|
||||
from werkzeug import escape
|
||||
|
||||
|
@ -55,6 +56,7 @@ LANGUAGES = {
|
|||
'html+genshi': _('Genshi Templates'),
|
||||
'js': _('JavaScript'),
|
||||
'java': _('Java'),
|
||||
'javac-messages': _('javac Messages'),
|
||||
'jsp': _('JSP'),
|
||||
'lua': _('Lua'),
|
||||
'haskell': _('Haskell'),
|
||||
|
@ -109,20 +111,26 @@ _escaped_marker = re.compile(r'^\\(?=###)(?m)')
|
|||
|
||||
def highlight(code, language, _preview=False):
|
||||
"""Highlight a given code to HTML"""
|
||||
if not _preview and language == 'diff':
|
||||
return highlight_diff(code)
|
||||
if language == 'creole':
|
||||
return format_creole(code)
|
||||
elif language == 'multi':
|
||||
if not _preview:
|
||||
if language == 'diff':
|
||||
return highlight_diff(code)
|
||||
elif language == 'creole':
|
||||
return format_creole(code)
|
||||
elif language == 'csv':
|
||||
return format_csv(code)
|
||||
elif language == 'gcc-messages':
|
||||
return format_compiler_messages(parse_gcc_messages(code), 'gcc')
|
||||
elif language == 'javac-messages':
|
||||
return format_compiler_messages(parse_javac_messages(code), 'javac')
|
||||
if language == 'multi':
|
||||
return highlight_multifile(code)
|
||||
elif language == 'csv':
|
||||
return format_csv(code)
|
||||
elif language == 'gcc-messages':
|
||||
return format_compiler_messages(parse_gcc_messages(code))
|
||||
elif language == 'php':
|
||||
lexer = PhpLexer(startinline=True)
|
||||
else:
|
||||
lexer = get_lexer_by_name(language)
|
||||
try:
|
||||
lexer = get_lexer_by_name(language)
|
||||
except ClassNotFound:
|
||||
lexer = TextLexer()
|
||||
style = get_style(name_only=True)
|
||||
formatter = HtmlFormatter(linenos=True, cssclass='syntax', style=style)
|
||||
return u'<div class="code">%s</div>' % \
|
||||
|
@ -180,9 +188,10 @@ def format_csv(code):
|
|||
return ''.join(result).decode('utf-8')
|
||||
|
||||
|
||||
def format_compiler_messages(lines):
|
||||
def format_compiler_messages(lines, compiler):
|
||||
"""Highlights compiler messages."""
|
||||
return render_template('utils/compiler-messages.html', lines=lines)
|
||||
return render_template('utils/compiler-messages.html',
|
||||
lines=lines, compiler=compiler)
|
||||
|
||||
|
||||
def highlight_multifile(code):
|
||||
|
@ -271,3 +280,10 @@ def get_known_alias(lexer, default='text'):
|
|||
if alias in LANGUAGES:
|
||||
return alias
|
||||
return default
|
||||
|
||||
|
||||
def list_languages():
|
||||
"""List all languages."""
|
||||
languages = LANGUAGES.items()
|
||||
languages.sort(key=lambda x: x[1].lstrip(' _-.').lower())
|
||||
return languages
|
||||
|
|
|
@ -586,6 +586,7 @@ div.compiler-messages table {
|
|||
|
||||
div.compiler-messages table td {
|
||||
padding: 3px 7px;
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
div.compiler-messages table td.level {
|
||||
|
@ -597,8 +598,30 @@ div.compiler-messages table tr.error td.level {
|
|||
}
|
||||
|
||||
div.compiler-messages table td.message {
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
div.compiler-messages table tr.raw pre {
|
||||
font-family: 'Bitstream Vera Sans Mono', monospace;
|
||||
font-size: 12px;
|
||||
font-size: 12px!important;
|
||||
padding: 0!important;
|
||||
}
|
||||
|
||||
div.compiler-messages table td.message {
|
||||
font-family: 'Bitstream Vera Sans Mono', monospace;
|
||||
font-size: 12px!important;
|
||||
}
|
||||
|
||||
div.compiler-messages table tr.context pre {
|
||||
border: 1px solid #C8DADA;
|
||||
background: #EDF6F7;
|
||||
padding: 2px!important;
|
||||
font-family: 'Bitstream Vera Sans Mono', monospace;
|
||||
font-size: 12px!important;
|
||||
}
|
||||
|
||||
div.compiler-javac table tr.context pre {
|
||||
padding-top: 7px!important; /* to balance the closing "^" */
|
||||
}
|
||||
|
||||
div.compiler-messages table td.location span.filename {
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
{%- endif %}
|
||||
<textarea name="code" rows="10" cols="80">{{ code|e }}</textarea>
|
||||
<select name="language">
|
||||
{%- for key, caption in languages|dictsort(true, 'value') %}
|
||||
{%- for key, caption in languages %}
|
||||
<option value="{{ key }}"{% if language == key
|
||||
%} selected="selected"{% endif %}>{{ caption|e }}</option>
|
||||
{%- endfor %}
|
||||
|
|
|
@ -1,6 +1,9 @@
|
|||
<div class="compiler-messages">
|
||||
<div class="compiler-messages compiler-{{ compiler }}">
|
||||
<table class="formatted">
|
||||
{% for line in lines %}
|
||||
{%- for line in lines %}
|
||||
{%- if line.is_raw %}
|
||||
<tr class="raw"><td colspan="3"><pre>{{ line.raw|e }}</pre></td></tr>
|
||||
{%- else %}
|
||||
<tr class="{{ line.level }}">
|
||||
<td class="level">{{ line.level }}</td>
|
||||
<td class="location">
|
||||
|
@ -16,6 +19,13 @@
|
|||
</td>
|
||||
<td class="message">{{ line.message|e }}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
{% if line.context %}
|
||||
<tr class="context">
|
||||
<td> </td>
|
||||
<td colspan="2"><pre>{{ line.context|e }}</pre></td>
|
||||
</tr>
|
||||
{% endif %}
|
||||
{%- endif %}
|
||||
{%- endfor %}
|
||||
</table>
|
||||
</div>
|
||||
|
|
Loading…
Reference in New Issue