diff --git a/.github/release-drafter.yml b/.github/release-drafter.yml
new file mode 100644
index 0000000..a444deb
--- /dev/null
+++ b/.github/release-drafter.yml
@@ -0,0 +1,27 @@
+# Format and labels used aim to match those used by Ansible project
+categories:
+ - title: 'Major Changes'
+ labels:
+ - 'major' # c6476b
+ - title: 'Minor Changes'
+ labels:
+ - 'feature' # 006b75
+ - 'enhancement' # ededed
+ - 'performance' # 555555
+ - title: 'Bugfixes'
+ labels:
+ - 'fix'
+ - 'bugfix'
+ - 'bug' # fbca04
+ - 'docs' # 4071a5
+ - 'packaging' # 4071a5
+ - 'test' # #0e8a16
+ - title: 'Deprecations'
+ labels:
+ - 'deprecated' # fef2c0
+exclude-labels:
+ - 'skip-changelog'
+template: |
+ ## Changes
+
+ $CHANGES
diff --git a/.github/workflows/release-drafter.yml b/.github/workflows/release-drafter.yml
new file mode 100644
index 0000000..7d3004a
--- /dev/null
+++ b/.github/workflows/release-drafter.yml
@@ -0,0 +1,18 @@
+name: Release Drafter
+
+on:
+ push:
+ # branches to consider in the event; optional, defaults to all
+ branches:
+ - master
+ - 'releases/**'
+ - 'stable/**'
+
+jobs:
+ update_release_draft:
+ runs-on: ubuntu-latest
+ steps:
+ # Drafts your next Release notes as Pull Requests are merged into "master"
+ - uses: release-drafter/release-drafter@v5
+ env:
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
diff --git a/.github/workflows/tox.yml b/.github/workflows/tox.yml
new file mode 100644
index 0000000..389f369
--- /dev/null
+++ b/.github/workflows/tox.yml
@@ -0,0 +1,124 @@
+name: tox
+
+on:
+ create: # is used for publishing to PyPI and TestPyPI
+ tags: # any tag regardless of its name, no branches
+ push: # only publishes pushes to the main branch to TestPyPI
+ branches: # any integration branch but not tag
+ - "master"
+ - "main"
+ - "develop"
+ tags-ignore:
+ - "**"
+ pull_request:
+ schedule:
+ - cron: 1 0 * * * # Run daily at 0:01 UTC
+
+jobs:
+ build:
+ name: ${{ matrix.tox_env }}
+ runs-on: ubuntu-latest
+ strategy:
+ fail-fast: false
+ matrix:
+ include:
+ - tox_env: lint
+ - tox_env: py36
+ - tox_env: py37
+ - tox_env: py38
+ - tox_env: py39
+ - tox_env: packaging
+ steps:
+ - uses: actions/checkout@v1
+ - name: Find python version
+ id: py_ver
+ shell: python
+ if: ${{ contains(matrix.tox_env, 'py') }}
+ run: |
+ v = '${{ matrix.tox_env }}'.split('-')[0].lstrip('py')
+ print('::set-output name=version::{0}.{1}'.format(v[0],v[1:]))
+ # Even our lint and other envs need access to tox
+ - name: Install a default Python
+ uses: actions/setup-python@v2
+ if: ${{ ! contains(matrix.tox_env, 'py') }}
+ # Be sure to install the version of python needed by a specific test, if necessary
+ - name: Set up Python version
+ uses: actions/setup-python@v2
+ if: ${{ contains(matrix.tox_env, 'py') }}
+ with:
+ python-version: ${{ steps.py_ver.outputs.version }}
+ - name: Install dependencies
+ run: |
+ python -m pip install -U pip
+ pip install tox
+ - name: Run tox -e ${{ matrix.tox_env }}
+ run: |
+ echo "${{ matrix.PREFIX }} tox -e ${{ matrix.tox_env }}"
+ ${{ matrix.PREFIX }} tox -e ${{ matrix.tox_env }}
+
+ publish:
+ name: Publish to PyPI registry
+ needs:
+ - build
+ runs-on: ubuntu-latest
+
+ env:
+ PY_COLORS: 1
+ TOXENV: packaging
+
+ steps:
+ - name: Switch to using Python 3.6 by default
+ uses: actions/setup-python@v2
+ with:
+ python-version: 3.6
+ - name: Install tox
+ run: python -m pip install --user tox
+ - name: Check out src from Git
+ uses: actions/checkout@v2
+ with:
+ # Get shallow Git history (default) for tag creation events
+ # but have a complete clone for any other workflows.
+ # Both options fetch tags but since we're going to remove
+ # one from HEAD in non-create-tag workflows, we need full
+ # history for them.
+ fetch-depth: >-
+ ${{
+ (
+ github.event_name == 'create' &&
+ github.event.ref_type == 'tag'
+ ) &&
+ 1 || 0
+ }}
+ - name: Drop Git tags from HEAD for non-tag-create events
+ if: >-
+ github.event_name != 'create' ||
+ github.event.ref_type != 'tag'
+ run: >-
+ git tag --points-at HEAD
+ |
+ xargs git tag --delete
+ - name: Build dists
+ run: python -m tox
+ - name: Publish to test.pypi.org
+ if: >-
+ (
+ github.event_name == 'push' &&
+ github.ref == format(
+ 'refs/heads/{0}', github.event.repository.default_branch
+ )
+ ) ||
+ (
+ github.event_name == 'create' &&
+ github.event.ref_type == 'tag'
+ )
+ uses: pypa/gh-action-pypi-publish@master
+ with:
+ password: ${{ secrets.testpypi_password }}
+ repository_url: https://test.pypi.org/legacy/
+ - name: Publish to pypi.org
+ if: >- # "create" workflows run separately from "push" & "pull_request"
+ github.event_name == 'create' &&
+ github.event.ref_type == 'tag'
+ uses: pypa/gh-action-pypi-publish@master
+ with:
+ password: ${{ secrets.pypi_password }}
diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
new file mode 100644
index 0000000..214d3b5
--- /dev/null
+++ b/.pre-commit-config.yaml
@@ -0,0 +1,39 @@
+---
+repos:
+ - repo: https://github.com/PyCQA/isort
+ rev: 5.6.4
+ hooks:
+ - id: isort
+ - repo: https://github.com/python/black.git
+ rev: 20.8b1
+ hooks:
+ - id: black
+ language_version: python3
+ - repo: https://github.com/pre-commit/pre-commit-hooks.git
+ rev: v3.2.0
+ hooks:
+ - id: end-of-file-fixer
+ - id: trailing-whitespace
+ - id: mixed-line-ending
+ - id: check-byte-order-marker
+ - id: check-executables-have-shebangs
+ - id: check-merge-conflict
+ - id: debug-statements
+ language_version: python3
+ - repo: https://gitlab.com/pycqa/flake8.git
+ rev: 3.8.4
+ hooks:
+ - id: flake8
+ additional_dependencies:
+ - pydocstyle>=5.1.1
+ - flake8-absolute-import
+ - flake8-black>=0.1.1
+ - flake8-docstrings>=1.5.0
+ language_version: python3
+ - repo: https://github.com/pre-commit/mirrors-pylint
+ rev: v2.6.0
+ hooks:
+ - id: pylint
+ additional_dependencies:
+ - ansible-base
+ - testinfra
diff --git a/.pylintrc b/.pylintrc
new file mode 100644
index 0000000..455ad61
--- /dev/null
+++ b/.pylintrc
@@ -0,0 +1,29 @@
+[MESSAGES CONTROL]
+
+disable =
+ # TODO(ssbarnea): remove temporary skips adding during initial adoption:
+ attribute-defined-outside-init,
+ consider-using-dict-comprehension,
+ consider-using-enumerate,
+ deprecated-module,
+ import-error,
+ invalid-name,
+ line-too-long,
+ missing-class-docstring,
+ missing-function-docstring,
+ missing-module-docstring,
+ no-self-use,
+ redefined-builtin,
+ redefined-outer-name,
+ too-few-public-methods,
+ too-many-arguments,
+ too-many-branches,
+ too-many-instance-attributes,
+ too-many-locals,
+ too-many-public-methods,
+ too-many-statements,
+ unused-argument,
+ unused-variable,
+
+[REPORTS]
+output-format = colorized
diff --git a/.travis.yml b/.travis.yml
deleted file mode 100644
index 3caaf7d..0000000
--- a/.travis.yml
+++ /dev/null
@@ -1,15 +0,0 @@
-language: python
-python:
- - "2.7"
- - "3.5"
- - "3.6"
-install:
-- python setup.py develop
-- pip install nose mock
-script: nosetests -x tests/*.py
-notifications:
- email: true
- irc:
- - "irc.freenode.net#threebean"
- on_success: change
- on_failure: always
diff --git a/README.rst b/README.rst
index 0f74ca5..6a9ff3b 100644
--- a/README.rst
+++ b/README.rst
@@ -16,13 +16,13 @@ Inspired by and developed off of the work of `pixelbeat`_ and `blackjack`_.
Build Status
------------
-.. |master| image:: https://secure.travis-ci.org/ralphbean/ansi2html.png?branch=master
+.. |master| image:: https://github.com/pycontribs/ansi2html/workflows/tox/badge.svg?branch=master
:alt: Build Status - master branch
- :target: http://travis-ci.org/#!/ralphbean/ansi2html
+ :target: https://github.com/pycontribs/ansi2html/actions?query=workflow%3Atox+branch%3Amaster
-.. |develop| image:: https://secure.travis-ci.org/ralphbean/ansi2html.png?branch=develop
+.. |develop| image:: https://github.com/pycontribs/ansi2html/workflows/tox/badge.svg?branch=develop
:alt: Build Status - develop branch
- :target: http://travis-ci.org/#!/ralphbean/ansi2html
+ :target: https://github.com/pycontribs/ansi2html/actions?query=workflow%3Atox+branch%3Adevelop
+----------+-----------+
| Branch | Status |
diff --git a/ansi2html/__init__.py b/ansi2html/__init__.py
index 58250b8..db1f4fd 100644
--- a/ansi2html/__init__.py
+++ b/ansi2html/__init__.py
@@ -1,2 +1,3 @@
from ansi2html.converter import Ansi2HTMLConverter
-__all__ = ['Ansi2HTMLConverter']
+
+__all__ = ["Ansi2HTMLConverter"]
diff --git a/ansi2html/__main__.py b/ansi2html/__main__.py
new file mode 100644
index 0000000..4cbddc4
--- /dev/null
+++ b/ansi2html/__main__.py
@@ -0,0 +1,4 @@
+from ansi2html.converter import main
+
+if __name__ == "__main__":
+ main()
diff --git a/ansi2html/converter.py b/ansi2html/converter.py
old mode 100755
new mode 100644
index 33ddac2..5f75796
--- a/ansi2html/converter.py
+++ b/ansi2html/converter.py
@@ -20,22 +20,19 @@
# along with this program. If not, see
# .
+import io
+import optparse
import re
import sys
-import optparse
+
import pkg_resources
-import io
try:
from collections import OrderedDict
except ImportError:
from ordereddict import OrderedDict
-from ansi2html.style import get_styles, SCHEME
-import six
-from six.moves import map
-from six.moves import zip
-
+from ansi2html.style import SCHEME, get_styles
ANSI_FULL_RESET = 0
ANSI_INTENSITY_INCREASED = 1
@@ -68,21 +65,21 @@
ANSI_BACKGROUND_HIGH_INTENSITY_MAX = 107
VT100_BOX_CODES = {
- '0x71': '─',
- '0x74': '├',
- '0x75': '┤',
- '0x76': '┴',
- '0x77': '┬',
- '0x78': '│',
- '0x6a': '┘',
- '0x6b': '┐',
- '0x6c': '┌',
- '0x6d': '└',
- '0x6e': '┼'
+ "0x71": "─",
+ "0x74": "├",
+ "0x75": "┤",
+ "0x76": "┴",
+ "0x77": "┬",
+ "0x78": "│",
+ "0x6a": "┘",
+ "0x6b": "┐",
+ "0x6c": "┌",
+ "0x6d": "└",
+ "0x6e": "┼",
}
# http://stackoverflow.com/a/15190498
-_latex_template = '''\\documentclass{scrartcl}
+_latex_template = """\\documentclass{scrartcl}
\\usepackage[utf8]{inputenc}
\\usepackage{fancyvrb}
\\usepackage[usenames,dvipsnames]{xcolor}
@@ -90,7 +87,7 @@
\\title{%(title)s}
-\\fvset{commandchars=\\\\\\{\}}
+\\fvset{commandchars=\\\\\\{\\}}
\\begin{document}
@@ -98,9 +95,9 @@
%(content)s
\\end{Verbatim}
\\end{document}
-'''
+"""
-_html_template = six.u("""
+_html_template = """
@@ -114,9 +111,10 @@
-""")
+"""
-class _State(object):
+
+class _State:
def __init__(self):
self.reset()
@@ -132,7 +130,11 @@ def reset(self):
self.negative = ANSI_NEGATIVE_OFF
def adjust(self, ansi_code, parameter=None):
- if ansi_code in (ANSI_INTENSITY_INCREASED, ANSI_INTENSITY_REDUCED, ANSI_INTENSITY_NORMAL):
+ if ansi_code in (
+ ANSI_INTENSITY_INCREASED,
+ ANSI_INTENSITY_REDUCED,
+ ANSI_INTENSITY_NORMAL,
+ ):
self.intensity = ansi_code
elif ansi_code in (ANSI_STYLE_ITALIC, ANSI_STYLE_NORMAL):
self.style = ansi_code
@@ -146,7 +148,11 @@ def adjust(self, ansi_code, parameter=None):
self.visibility = ansi_code
elif ANSI_FOREGROUND_CUSTOM_MIN <= ansi_code <= ANSI_FOREGROUND_CUSTOM_MAX:
self.foreground = (ansi_code, None)
- elif ANSI_FOREGROUND_HIGH_INTENSITY_MIN <= ansi_code <= ANSI_FOREGROUND_HIGH_INTENSITY_MAX:
+ elif (
+ ANSI_FOREGROUND_HIGH_INTENSITY_MIN
+ <= ansi_code
+ <= ANSI_FOREGROUND_HIGH_INTENSITY_MAX
+ ):
self.foreground = (ansi_code, None)
elif ansi_code == ANSI_FOREGROUND_256:
self.foreground = (ansi_code, parameter)
@@ -154,7 +160,11 @@ def adjust(self, ansi_code, parameter=None):
self.foreground = (ansi_code, None)
elif ANSI_BACKGROUND_CUSTOM_MIN <= ansi_code <= ANSI_BACKGROUND_CUSTOM_MAX:
self.background = (ansi_code, None)
- elif ANSI_BACKGROUND_HIGH_INTENSITY_MIN <= ansi_code <= ANSI_BACKGROUND_HIGH_INTENSITY_MAX:
+ elif (
+ ANSI_BACKGROUND_HIGH_INTENSITY_MIN
+ <= ansi_code
+ <= ANSI_BACKGROUND_HIGH_INTENSITY_MAX
+ ):
self.background = (ansi_code, None)
elif ansi_code == ANSI_BACKGROUND_256:
self.background = (ansi_code, parameter)
@@ -168,16 +178,18 @@ def to_css_classes(self):
def append_unless_default(output, value, default):
if value != default:
- css_class = 'ansi%d' % value
+ css_class = "ansi%d" % value
output.append(css_class)
- def append_color_unless_default(output, color, default, negative, neg_css_class):
+ def append_color_unless_default(
+ output, color, default, negative, neg_css_class
+ ):
value, parameter = color
if value != default:
- prefix = 'inv' if negative else 'ansi'
- css_class_index = str(value) \
- if (parameter is None) \
- else '%d-%d' % (value, parameter)
+ prefix = "inv" if negative else "ansi"
+ css_class_index = (
+ str(value) if (parameter is None) else "%d-%d" % (value, parameter)
+ )
output.append(prefix + css_class_index)
elif negative:
output.append(neg_css_class)
@@ -189,39 +201,53 @@ def append_color_unless_default(output, color, default, negative, neg_css_class)
append_unless_default(css_classes, self.crossedout, ANSI_CROSSED_OUT_OFF)
append_unless_default(css_classes, self.visibility, ANSI_VISIBILITY_ON)
- flip_fore_and_background = (self.negative == ANSI_NEGATIVE_ON)
- append_color_unless_default(css_classes, self.foreground, ANSI_FOREGROUND_DEFAULT, flip_fore_and_background, 'inv_background')
- append_color_unless_default(css_classes, self.background, ANSI_BACKGROUND_DEFAULT, flip_fore_and_background, 'inv_foreground')
+ flip_fore_and_background = self.negative == ANSI_NEGATIVE_ON
+ append_color_unless_default(
+ css_classes,
+ self.foreground,
+ ANSI_FOREGROUND_DEFAULT,
+ flip_fore_and_background,
+ "inv_background",
+ )
+ append_color_unless_default(
+ css_classes,
+ self.background,
+ ANSI_BACKGROUND_DEFAULT,
+ flip_fore_and_background,
+ "inv_foreground",
+ )
return css_classes
def linkify(line, latex_mode):
url_matcher = re.compile(
- r'(((((https?|ftps?|gopher|telnet|nntp)://)|'
- r'(mailto:|news:))(%[0-9A-Fa-f]{2}|[-()_.!~*'
- r'\';/?:@&=+$,A-Za-z0-9])+)([).!\';/?:,][[:blank:]])?)')
+ r"(((((https?|ftps?|gopher|telnet|nntp)://)|"
+ r"(mailto:|news:))(%[0-9A-Fa-f]{2}|[-()_.!~*"
+ r"\';/?:@&=+$,A-Za-z0-9])+)([).!\';/?:,][\s])?)"
+ )
if latex_mode:
- return url_matcher.sub(r'\\url{\1}', line)
- else:
- return url_matcher.sub(r'\1', line)
+ return url_matcher.sub(r"\\url{\1}", line)
+ return url_matcher.sub(r'\1', line)
+
def map_vt100_box_code(char):
char_hex = hex(ord(char))
return VT100_BOX_CODES[char_hex] if char_hex in VT100_BOX_CODES else char
+
def _needs_extra_newline(text):
- if not text or text.endswith('\n'):
+ if not text or text.endswith("\n"):
return False
return True
-class CursorMoveUp(object):
+class CursorMoveUp:
pass
-class Ansi2HTMLConverter(object):
- """ Convert Ansi color codes to CSS+HTML
+class Ansi2HTMLConverter:
+ """Convert Ansi color codes to CSS+HTML
Example:
>>> conv = Ansi2HTMLConverter()
@@ -229,19 +255,20 @@ class Ansi2HTMLConverter(object):
>>> html = conv.convert(ansi)
"""
- def __init__(self,
- latex=False,
- inline=False,
- dark_bg=True,
- line_wrap=True,
- font_size='normal',
- linkify=False,
- escaped=True,
- markup_lines=False,
- output_encoding='utf-8',
- scheme='ansi2html',
- title=''
- ):
+ def __init__(
+ self,
+ latex=False,
+ inline=False,
+ dark_bg=True,
+ line_wrap=True,
+ font_size="normal",
+ linkify=False,
+ escaped=True,
+ markup_lines=False,
+ output_encoding="utf-8",
+ scheme="ansi2html",
+ title="",
+ ):
self.latex = latex
self.inline = inline
@@ -257,10 +284,15 @@ def __init__(self,
self._attrs = None
if inline:
- self.styles = dict([(item.klass.strip('.'), item) for item in get_styles(self.dark_bg, self.line_wrap, self.scheme)])
+ self.styles = dict(
+ [
+ (item.klass.strip("."), item)
+ for item in get_styles(self.dark_bg, self.line_wrap, self.scheme)
+ ]
+ )
- self.vt100_box_codes_prog = re.compile('\033\\(([B0])')
- self.ansi_codes_prog = re.compile('\033\\[' '([\\d;]*)' '([a-zA-z])')
+ self.vt100_box_codes_prog = re.compile("\033\\(([B0])")
+ self.ansi_codes_prog = re.compile("\033\\[" "([\\d;]*)" "([a-zA-z])")
def apply_regex(self, ansi):
styles_used = set()
@@ -274,24 +306,29 @@ def apply_regex(self, ansi):
combined = "".join(parts)
if self.markup_lines and not self.latex:
- combined = "\n".join([
- """%s""" % (i, line)
- for i, line in enumerate(combined.split('\n'))
- ])
+ combined = "\n".join(
+ [
+ """%s""" % (i, line)
+ for i, line in enumerate(combined.split("\n"))
+ ]
+ )
return combined, styles_used
def _apply_regex(self, ansi, styles_used):
if self.escaped:
- if self.latex: # Known Perl function which does this: https://tex.stackexchange.com/questions/34580/escape-character-in-latex/119383#119383
- specials = OrderedDict([
- ])
+ if (
+ self.latex
+ ): # Known Perl function which does this: https://tex.stackexchange.com/questions/34580/escape-character-in-latex/119383#119383
+ specials = OrderedDict([])
else:
- specials = OrderedDict([
- ('&', '&'),
- ('<', '<'),
- ('>', '>'),
- ])
+ specials = OrderedDict(
+ [
+ ("&", "&"),
+ ("<", "<"),
+ (">", ">"),
+ ]
+ )
for pattern, special in specials.items():
ansi = ansi.replace(pattern, special)
@@ -299,36 +336,37 @@ def _vt100_box_drawing():
last_end = 0 # the index of the last end of a code we've seen
box_drawing_mode = False
for match in self.vt100_box_codes_prog.finditer(ansi):
- trailer = ansi[last_end:match.start()]
+ trailer = ansi[last_end : match.start()]
if box_drawing_mode:
for char in trailer:
yield map_vt100_box_code(char)
else:
yield trailer
last_end = match.end()
- box_drawing_mode = (match.groups()[0] == "0")
+ box_drawing_mode = match.groups()[0] == "0"
yield ansi[last_end:]
+
ansi = "".join(_vt100_box_drawing())
state = _State()
inside_span = False
last_end = 0 # the index of the last end of a code we've seen
for match in self.ansi_codes_prog.finditer(ansi):
- yield ansi[last_end:match.start()]
+ yield ansi[last_end : match.start()]
last_end = match.end()
params, command = match.groups()
- if command not in 'mMA':
+ if command not in "mMA":
continue
# Special cursor-moving code. The only supported one.
- if command == 'A':
+ if command == "A":
yield CursorMoveUp
continue
try:
- params = list(map(int, params.split(';')))
+ params = list(map(int, params.split(";")))
except ValueError:
params = [ANSI_FULL_RESET]
@@ -346,13 +384,13 @@ def _vt100_box_drawing():
# Process reset marker, drop everything before
if last_null_index is not None:
- params = params[last_null_index + 1:]
+ params = params[last_null_index + 1 :]
if inside_span:
inside_span = False
if self.latex:
- yield '}'
+ yield "}"
else:
- yield ''
+ yield ""
state.reset()
if not params:
@@ -376,9 +414,9 @@ def _vt100_box_drawing():
if inside_span:
if self.latex:
- yield '}'
+ yield "}"
else:
- yield ''
+ yield ""
inside_span = False
css_classes = state.to_css_classes()
@@ -388,16 +426,22 @@ def _vt100_box_drawing():
if self.inline:
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]
+ 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]
+ style = [
+ self.styles[klass].kw
+ for klass in css_classes
+ if klass in self.styles
+ ]
yield '' % "; ".join(style)
else:
if self.latex:
- yield '\\textcolor{%s}{' % " ".join(css_classes)
+ yield "\\textcolor{%s}{" % " ".join(css_classes)
else:
yield '' % " ".join(css_classes)
inside_span = True
@@ -405,9 +449,9 @@ def _vt100_box_drawing():
yield ansi[last_end:]
if inside_span:
if self.latex:
- yield '}'
+ yield "}"
else:
- yield ''
+ yield ""
inside_span = False
def _collapse_cursor(self, parts):
@@ -425,7 +469,7 @@ def _collapse_cursor(self, parts):
if final_parts:
final_parts.pop()
- while final_parts and '\n' not in final_parts[-1]:
+ while final_parts and "\n" not in final_parts[-1]:
final_parts.pop()
continue
@@ -435,20 +479,20 @@ def _collapse_cursor(self, parts):
return final_parts
- def prepare(self, ansi='', ensure_trailing_newline=False):
+ def prepare(self, ansi="", ensure_trailing_newline=False):
""" Load the contents of 'ansi' into this object """
body, styles = self.apply_regex(ansi)
if ensure_trailing_newline and _needs_extra_newline(body):
- body += '\n'
+ body += "\n"
self._attrs = {
- 'dark_bg': self.dark_bg,
- 'line_wrap': self.line_wrap,
- 'font_size': self.font_size,
- 'body': body,
- 'styles': styles,
+ "dark_bg": self.dark_bg,
+ "line_wrap": self.line_wrap,
+ "font_size": self.font_size,
+ "body": body,
+ "styles": styles,
}
return self._attrs
@@ -463,26 +507,29 @@ def convert(self, ansi, full=True, ensure_trailing_newline=False):
attrs = self.prepare(ansi, ensure_trailing_newline=ensure_trailing_newline)
if not full:
return attrs["body"]
+ if self.latex:
+ _template = _latex_template
else:
- if self.latex:
- _template = _latex_template
- else:
- _template = _html_template
- all_styles = get_styles(self.dark_bg, self.line_wrap, self.scheme)
- backgrounds = all_styles[:6]
- used_styles = filter(lambda e: e.klass.lstrip(".") in attrs["styles"], all_styles)
-
- return _template % {
- 'style' : "\n".join(list(map(str, backgrounds + list(used_styles)))),
- 'title' : self.title,
- 'font_size' : self.font_size,
- 'content' : attrs["body"],
- 'output_encoding' : self.output_encoding,
- }
+ _template = _html_template
+ all_styles = get_styles(self.dark_bg, self.line_wrap, self.scheme)
+ backgrounds = all_styles[:6]
+ used_styles = filter(
+ lambda e: e.klass.lstrip(".") in attrs["styles"], all_styles
+ )
+
+ return _template % {
+ "style": "\n".join(list(map(str, backgrounds + list(used_styles)))),
+ "title": self.title,
+ "font_size": self.font_size,
+ "content": attrs["body"],
+ "output_encoding": self.output_encoding,
+ }
def produce_headers(self):
return '\n' % {
- 'style' : "\n".join(map(str, get_styles(self.dark_bg, self.line_wrap, self.scheme)))
+ "style": "\n".join(
+ map(str, get_styles(self.dark_bg, self.line_wrap, self.scheme))
+ )
}
@@ -493,68 +540,120 @@ def main():
$ task burndown | ansi2html > burndown.html
"""
- scheme_names = sorted(six.iterkeys(SCHEME))
- version_str = pkg_resources.get_distribution('ansi2html').version
+ scheme_names = sorted(SCHEME.keys())
+ version_str = pkg_resources.get_distribution("ansi2html").version
parser = optparse.OptionParser(
- usage=main.__doc__,
- version="%%prog %s" % version_str)
+ usage=main.__doc__, version="%%prog %s" % version_str
+ )
parser.add_option(
- "-p", "--partial", dest="partial",
- default=False, action="store_true",
- help="Process lines as them come in. No headers are produced.")
+ "-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.")
+ "-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",
- help="Inline style without headers or template.")
+ "-i",
+ "--inline",
+ dest="inline",
+ default=False,
+ action="store_true",
+ help="Inline style without headers or template.",
+ )
parser.add_option(
- "-H", "--headers", dest="headers",
- default=False, action="store_true",
- help="Just produce the
@@ -69,6 +69,7 @@
Found 5 matches.
+