From caa8c6fe5010c3d912aac47ce1e6e3aeaddfaa17 Mon Sep 17 00:00:00 2001 From: Robin Schneider Date: Tue, 20 May 2014 12:54:13 +0200 Subject: [PATCH] Implemented LaTeX support. Only colors are supported but it does already what I need. Tested with subnetcalc and ls. --- ansi2html/converter.py | 62 ++++++++++++++++++++++++++++++++++++------ ansi2html/style.py | 2 ++ 2 files changed, 55 insertions(+), 9 deletions(-) diff --git a/ansi2html/converter.py b/ansi2html/converter.py index 04cf89c..a088b59 100755 --- a/ansi2html/converter.py +++ b/ansi2html/converter.py @@ -62,7 +62,24 @@ ANSI_NEGATIVE_OFF = 27 -_template = six.u(""" +# http://stackoverflow.com/a/15190498 +_latex_template = '''\documentclass{scrartcl} +\usepackage[utf8]{inputenc} +\usepackage{fancyvrb} +\usepackage[usenames,dvipsnames]{xcolor} +\definecolor{red-sd}{HTML}{7ed2d2} + +\\fvset{commandchars=\\\\\\{\}} + +\\begin{document} + +\\begin{Verbatim}[label={My orange command sample output}] +%(content)s +\end{Verbatim} +\end{document} +''' + +_html_template = six.u(""" @@ -78,7 +95,6 @@ """) - class _State(object): def __init__(self): self.reset() @@ -182,6 +198,7 @@ class Ansi2HTMLConverter(object): """ def __init__(self, + latex=False, inline=False, dark_bg=True, font_size='normal', @@ -193,6 +210,7 @@ def __init__(self, title='' ): + self.latex = latex self.inline = inline self.dark_bg = dark_bg self.font_size = font_size @@ -276,7 +294,10 @@ def _apply_regex(self, ansi): params = params[last_null_index + 1:] if inside_span: inside_span = False - yield '' + if self.latex: + yield '}' + else: + yield '' state.reset() if not params: @@ -299,7 +320,10 @@ def _apply_regex(self, ansi): state.adjust(v, parameter=parameter) if inside_span: - yield '' + if self.latex: + yield '}' + else: + yield '' inside_span = False css_classes = state.to_css_classes() @@ -307,16 +331,27 @@ def _apply_regex(self, ansi): continue if self.inline: - style = [self.styles[klass].kw for klass in css_classes if - klass in self.styles] - yield '' % "; ".join(style) + if self.latex: + style = [self.styles[klass].kwl[0][1] for klass in css_classes if + self.styles[klass].kwl[0][0] == 'color'] + yield '\\textcolor[HTML]{%s}{' % style[0] + else: + style = [self.styles[klass].kw for klass in css_classes if + klass in self.styles] + yield '' % "; ".join(style) else: - yield '' % " ".join(css_classes) + if self.latex: + yield '\\textcolor{%s}{' % " ".join(css_classes) + else: + yield '' % " ".join(css_classes) inside_span = True yield ansi[last_end:] if inside_span: - yield '' + if self.latex: + yield '}' + else: + yield '' inside_span = False def _collapse_cursor(self, parts): @@ -369,6 +404,10 @@ def convert(self, ansi, full=True, ensure_trailing_newline=False): if not full: return attrs["body"] else: + if self.latex: + _template = _latex_template + else: + _template = _html_template return _template % { 'style' : "\n".join(map(str, get_styles(self.dark_bg, self.scheme))), 'title' : self.title, @@ -399,6 +438,10 @@ def main(): "-p", "--partial", dest="partial", default=False, action="store_true", help="Process lines as them come in. No headers are produced.") + parser.add_option( + "-L", "--latex", dest="latex", + default=False, action="store_true", + help="Export as LaTeX instead of HTML.") parser.add_option( "-i", "--inline", dest="inline", default=False, action="store_true", @@ -448,6 +491,7 @@ def main(): opts, args = parser.parse_args() conv = Ansi2HTMLConverter( + latex=opts.latex, inline=opts.inline, dark_bg=not opts.light_background, font_size=opts.font_size, diff --git a/ansi2html/style.py b/ansi2html/style.py index 3a55ecf..09be418 100644 --- a/ansi2html/style.py +++ b/ansi2html/style.py @@ -26,6 +26,8 @@ def __init__(self, klass, **kw): self.klass = klass self.kw = '; '.join([(k.replace('_', '-')+': '+kw[k]) for k in sorted(kw.keys())]).strip() + self.kwl = [(k.replace('_', '-'), kw[k][1:]) + for k in sorted(kw.keys())] def __str__(self): return '%s { %s; }' % (self.klass, self.kw)