From cf6eac40639ef64fe07a83abd313dab06a45a1e1 Mon Sep 17 00:00:00 2001 From: Raymond Hettinger Date: Tue, 3 Jul 2012 00:12:27 -0700 Subject: Minor cleanups --- Tools/scripts/README | 2 +- Tools/scripts/highlight.py | 127 ++++++++++++++++++++++++++++++++++++++++++++ Tools/scripts/pycolorize.py | 127 -------------------------------------------- 3 files changed, 128 insertions(+), 128 deletions(-) create mode 100755 Tools/scripts/highlight.py delete mode 100755 Tools/scripts/pycolorize.py diff --git a/Tools/scripts/README b/Tools/scripts/README index 84b888f..d65d1fd 100644 --- a/Tools/scripts/README +++ b/Tools/scripts/README @@ -28,6 +28,7 @@ ftpmirror.py FTP mirror script google.py Open a webbrowser with Google gprof2html.py Transform gprof(1) output into useful HTML h2py.py Translate #define's into Python assignments +highlight.py Python syntax highlighting with HTML output idle3 Main program to start IDLE ifdef.py Remove #if(n)def groups from C sources lfcr.py Change LF line endings to CRLF (Unix to Windows) @@ -47,7 +48,6 @@ pdeps.py Print dependencies between Python modules pickle2db.py Load a pickle generated by db2pickle.py to a database pindent.py Indent Python code, giving block-closing comments ptags.py Create vi tags file for Python modules -pycolorize.py Python syntax highlighting with HTML output pydoc3 Python documentation browser pysource.py Find Python source files redemo.py Basic regular expression demonstration facility diff --git a/Tools/scripts/highlight.py b/Tools/scripts/highlight.py new file mode 100755 index 0000000..85ce091 --- /dev/null +++ b/Tools/scripts/highlight.py @@ -0,0 +1,127 @@ +#!/usr/bin/env python3 +'Convert Python source code to HTML with colorized markup' + +__all__ = ['colorize', 'build_page', 'default_css', 'default_html'] +__author__ = 'Raymond Hettinger' + +import keyword, tokenize, cgi, functools + +def is_builtin(s): + 'Return True if s is the name of a builtin' + return s in vars(__builtins__) + +def escape_range(lines, start, end): + 'Return escaped 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 cgi.escape(''.join(rows)), end + +def colorize(source): + 'Convert Python source code to an HTML fragment with colorized markup' + lines = source.splitlines(keepends=True) + lines.append('') + readline = functools.partial(next, iter(lines), '') + kind = tok_str = '' + tok_type = tokenize.COMMENT + written = (1, 0) + result = [] + for tok in tokenize.generate_tokens(readline): + prev_tok_type, prev_tok_str = tok_type, tok_str + tok_type, tok_str, (srow, scol), (erow, ecol), logical_lineno = tok + kind = '' + if tok_type == tokenize.COMMENT: + kind = 'comment' + elif tok_type == tokenize.OP and tok_str[:1] not in '{}[](),.:;': + kind = 'operator' + elif tok_type == tokenize.STRING: + kind = 'string' + if prev_tok_type == tokenize.INDENT or scol==0: + kind = 'docstring' + elif tok_type == tokenize.NAME: + if tok_str in ('def', 'class', 'import', 'from'): + kind = 'definition' + elif prev_tok_str in ('def', 'class'): + kind = 'defname' + elif keyword.iskeyword(tok_str): + kind = 'keyword' + elif is_builtin(tok_str) and prev_tok_str != '.': + kind = 'builtin' + if kind: + line_upto_token, written = escape_range(lines, written, (srow, scol)) + line_thru_token, written = escape_range(lines, written, (erow, ecol)) + result += [line_upto_token, '' % kind, + line_thru_token, ''] + else: + line_thru_token, written = escape_range(lines, written, (erow, ecol)) + result += [line_thru_token] + + result.insert(0, '
\n')
+    result.append('
\n') + return ''.join(result) + +default_css = { + '.comment': '{color: crimson;}', + '.string': '{color: forestgreen;}', + '.docstring': '{color: forestgreen; font-style:italic}', + '.keyword': '{color: darkorange;}', + '.builtin': '{color: purple;}', + '.definition': '{color: darkorange; font-weight:bold;}', + '.defname': '{color: blue;}', + '.operator': '{color: brown;}', +} + +default_html = '''\ + + + + + {title} + + + +{body} + + +''' + +def build_page(source, title='python', css=default_css, html=default_html): + 'Create a complete HTML page with colorized Python source code' + css_str = '\n'.join(['%s %s' % item for item in css.items()]) + result = colorize(source) + title = cgi.escape(title) + return html.format(title=title, css=css_str, body=result) + + +if __name__ == '__main__': + import sys, argparse, webbrowser, os + + parser = argparse.ArgumentParser( + description = 'Convert Python source code to colorized HTML') + parser.add_argument('sourcefile', metavar = 'SOURCEFILE', + help = 'File containing Python sourcecode') + parser.add_argument('-b', '--browser', action = 'store_true', + help = 'launch a browser to show results') + parser.add_argument('-s', '--section', action = 'store_true', + help = 'show an HTML section rather than a complete webpage') + args = parser.parse_args() + if args.browser and args.section: + parser.error('The -s/--section option is incompatible with ' + 'the -b/--browser option') + + sourcefile = args.sourcefile + with open(sourcefile) as f: + page = f.read() + html = colorize(page) if args.section else build_page(page, title=sourcefile) + if args.browser: + htmlfile = os.path.splitext(os.path.basename(sourcefile))[0] + '.html' + with open(htmlfile, 'w') as f: + f.write(html) + webbrowser.open('file://' + os.path.abspath(htmlfile)) + else: + sys.stdout.write(html) diff --git a/Tools/scripts/pycolorize.py b/Tools/scripts/pycolorize.py deleted file mode 100755 index 7a177b9..0000000 --- a/Tools/scripts/pycolorize.py +++ /dev/null @@ -1,127 +0,0 @@ -#!/usr/bin/env python3 -'Convert Python source code to HTML with colorized markup' - -__all__ = ['colorize', 'build_page', 'default_css', 'default_html'] -__author__ = 'Raymond Hettinger' - -import keyword, tokenize, cgi, functools - -def is_builtin(s): - 'Return True if s is the name of a builtin' - return s in vars(__builtins__) - -def escape_range(lines, start, end): - 'Return escaped 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 cgi.escape(''.join(rows)), end - -def colorize(source): - 'Convert Python source code to an HTML fragment with colorized markup' - lines = source.splitlines(True) - lines.append('') - readline = functools.partial(next, iter(lines), '') - kind = tok_str = '' - tok_type = tokenize.COMMENT - written = (1, 0) - result = [] - for tok in tokenize.generate_tokens(readline): - prev_tok_type, prev_tok_str = tok_type, tok_str - tok_type, tok_str, (srow, scol), (erow, ecol), logical_lineno = tok - kind, prev_kind = '', kind - if tok_type == tokenize.COMMENT: - kind = 'comment' - elif tok_type == tokenize.OP and tok_str[:1] not in '{}[](),.:;': - kind = 'operator' - elif tok_type == tokenize.STRING: - kind = 'string' - if prev_tok_type == tokenize.INDENT or scol==0: - kind = 'docstring' - elif tok_type == tokenize.NAME: - if tok_str in ('def', 'class', 'import', 'from'): - kind = 'definition' - elif prev_tok_str in ('def', 'class'): - kind = 'defname' - elif keyword.iskeyword(tok_str): - kind = 'keyword' - elif is_builtin(tok_str) and prev_tok_str != '.': - kind = 'builtin' - if kind: - line_upto_token, written = escape_range(lines, written, (srow, scol)) - line_thru_token, written = escape_range(lines, written, (erow, ecol)) - result += [line_upto_token, '' % kind, - line_thru_token, ''] - else: - line_thru_token, written = escape_range(lines, written, (erow, ecol)) - result += [line_thru_token] - - result.insert(0, '
\n')
-    result.append('
\n') - return ''.join(result) - -default_css = { - '.comment': '{color: crimson;}', - '.string': '{color: forestgreen;}', - '.docstring': '{color: forestgreen; font-style:italic}', - '.keyword': '{color: darkorange;}', - '.builtin': '{color: purple;}', - '.definition': '{color: darkorange; font-weight:bold;}', - '.defname': '{color: blue;}', - '.operator': '{color: brown;}', -} - -default_html = '''\ - - - - - {title} - - - -{body} - - -''' - -def build_page(source, title='python', css=default_css, html=default_html): - 'Create a complete HTML page with colorized Python source code' - css_str = '\n'.join(['%s %s' % item for item in css.items()]) - result = colorize(source) - title = cgi.escape(title) - return html.format(title=title, css=css_str, body=result) - - -if __name__ == '__main__': - import sys, argparse, webbrowser, os - - parser = argparse.ArgumentParser( - description = 'Convert Python source code to colorized HTML') - parser.add_argument('sourcefile', metavar = 'SOURCEFILE', nargs = 1, - help = 'File containing Python sourcecode') - parser.add_argument('-b', '--browser', action = 'store_true', - help = 'launch a browser to show results') - parser.add_argument('-s', '--standalone', action = 'store_true', - help = 'show a standalone snippet rather than a complete webpage') - args = parser.parse_args() - if args.browser and args.standalone: - parser.error('The -s/--standalone option is incompatible with ' - 'the -b/--browser option') - - sourcefile = args.sourcefile[0] - with open(sourcefile) as f: - page = f.read() - html = colorize(page) if args.standalone else build_page(page, title=sourcefile) - if args.browser: - htmlfile = os.path.splitext(os.path.basename(sourcefile))[0] + '.html' - with open(htmlfile, 'w') as f: - f.write(html) - webbrowser.open('file://' + os.path.abspath(htmlfile)) - else: - sys.stdout.write(html) -- cgit v0.12