diff --git a/Tools/scripts/highlight.py b/Tools/scripts/highlight.py index 51125236db8..ef010e8f31c 100755 --- a/Tools/scripts/highlight.py +++ b/Tools/scripts/highlight.py @@ -1,24 +1,9 @@ #!/usr/bin/env python3 -'''Add syntax highlighting to Python source code +'''Add syntax highlighting to Python source code''' -Example command-line calls: +__all__ = ['analyze_python', 'ansi_highlight', 'default_ansi', + 'html_highlight', 'build_html_page', 'default_css', 'default_html'] - # Show syntax highlighted code in the terminal window - $ ./highlight.py myfile.py - - # Colorize myfile.py and display in a browser - $ ./highlight.py -b myfile.py - - # Create an HTML section that can be embedded in an existing webpage - ./highlight.py -s myfile.py - - # Create a complete HTML file - $ ./highlight.py -c myfile.py > myfile.html - -''' - -__all__ = ['colorize_html', 'build_page', 'default_css', 'default_html', - 'colorize_ansi', 'default_ansi'] __author__ = 'Raymond Hettinger' import keyword, tokenize, cgi, functools @@ -31,13 +16,16 @@ def combine_range(lines, start, end): 'Join content from a range of lines between start and end' (srow, scol), (erow, ecol) = start, end if srow == erow: - rows = [lines[srow-1][scol:ecol]] - else: - rows = [lines[srow-1][scol:]] + lines[srow: erow-1] + [lines[erow-1][:ecol]] + return lines[srow-1][scol:ecol], end + rows = [lines[srow-1][scol:]] + lines[srow: erow-1] + [lines[erow-1][:ecol]] return ''.join(rows), end -def isolate_tokens(source): - 'Generate chunks of source and identify chunks to be highlighted' +def analyze_python(source): + '''Generate and classify chunks of Python for syntax highlighting. + Yields tuples in the form: (leadin_text, category, categorized_text). + The final tuple has empty strings for the category and categorized text. + + ''' lines = source.splitlines(True) lines.append('') readline = functools.partial(next, iter(lines), '') @@ -65,36 +53,37 @@ def isolate_tokens(source): kind = 'keyword' elif is_builtin(tok_str) and prev_tok_str != '.': kind = 'builtin' - line_upto_token, written = combine_range(lines, written, (srow, scol)) - line_thru_token, written = combine_range(lines, written, (erow, ecol)) - yield kind, line_upto_token, line_thru_token + if kind: + line_upto_token, written = combine_range(lines, written, (srow, scol)) + line_thru_token, written = combine_range(lines, written, (erow, ecol)) + yield line_upto_token, kind, line_thru_token + line_upto_token, written = combine_range(lines, written, (erow, ecol)) + yield line_upto_token, '', '' default_ansi = { - 'comment': '\033[0;31m', - 'string': '\033[0;32m', - 'docstring': '\033[0;32m', - 'keyword': '\033[0;33m', - 'builtin': '\033[0;35m', - 'definition': '\033[0;33m', - 'defname': '\033[0;34m', - 'operator': '\033[0;33m', + 'comment': ('\033[0;31m', '\033[0m'), + 'string': ('\033[0;32m', '\033[0m'), + 'docstring': ('\033[0;32m', '\033[0m'), + 'keyword': ('\033[0;33m', '\033[0m'), + 'builtin': ('\033[0;35m', '\033[0m'), + 'definition': ('\033[0;33m', '\033[0m'), + 'defname': ('\033[0;34m', '\033[0m'), + 'operator': ('\033[0;33m', '\033[0m'), } -def colorize_ansi(source, colors=default_ansi): - 'Add syntax highlighting to Python source code using ANSI escape sequences' +def ansi_highlight(classified_text, colors=default_ansi): + 'Add syntax highlighting to source code using ANSI escape sequences' # http://en.wikipedia.org/wiki/ANSI_escape_code result = [] - for kind, line_upto_token, line_thru_token in isolate_tokens(source): - if kind: - result += [line_upto_token, colors[kind], line_thru_token, '\033[0m'] - else: - result += [line_upto_token, line_thru_token] + for line_upto_token, kind, line_thru_token in classified_text: + opener, closer = colors.get(kind, ('', '')) + result += [line_upto_token, opener, line_thru_token, closer] return ''.join(result) -def colorize_html(source): - 'Convert Python source code to an HTML fragment with colorized markup' - result = ['
\n'] - for kind, line_upto_token, line_thru_token in isolate_tokens(source): +def html_highlight(classified_text,opener='\n'] + result += [closer] return ''.join(result) default_css = { @@ -134,21 +123,38 @@ default_html = '''\\n', closer='\n'): + 'Convert classified text to an HTML fragment' + result = [opener] + for line_upto_token, kind, line_thru_token in classified_text: if kind: result += [cgi.escape(line_upto_token), '' % kind, @@ -103,7 +92,7 @@ def colorize_html(source): else: result += [cgi.escape(line_upto_token), cgi.escape(line_thru_token)] - result += ['