summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Matusiak <numerodix@gmail.com>2014-03-08 19:50:14 +0100
committerMartin Matusiak <numerodix@gmail.com>2014-03-08 19:50:14 +0100
commit7e335dfd75db8a5eeac9cdbc9da539486c07d3f3 (patch)
tree4c0b60c489c700757d85298932dfb94e4288e4a3
parent5ab5f0ccdb6a09ed96391c73473ee233f6d56985 (diff)
parentc97681ddf26ed52f02800140d81dc69ff54dcee8 (diff)
downloadansicolor-7e335dfd75db8a5eeac9cdbc9da539486c07d3f3.tar.gz
Merge branch 'release/0.0.4'0.0.4
-rw-r--r--.gitignore1
-rw-r--r--README.rst87
-rw-r--r--ansicolor/__init__.py6
-rw-r--r--ansicolor/ansicolor.py153
-rw-r--r--ansicolor/demos.py107
-rw-r--r--dev-requirements.txt2
-rw-r--r--docs/Makefile177
-rw-r--r--docs/conf.py263
-rw-r--r--docs/index.rst24
-rw-r--r--setup.cfg3
-rw-r--r--setup.py5
-rw-r--r--tests/__init__.py0
-rw-r--r--tests/test_colors.py91
-rw-r--r--tests/test_imports.py33
-rw-r--r--tox.ini8
15 files changed, 827 insertions, 133 deletions
diff --git a/.gitignore b/.gitignore
index 2d1d981..c2028ff 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,4 +1,5 @@
build/
+docs/_build/
dist/
*.egg-info/
*.pyc
diff --git a/README.rst b/README.rst
index 8c5d312..d9d4d27 100644
--- a/README.rst
+++ b/README.rst
@@ -10,10 +10,14 @@ ansicolor
.. image:: https://pypip.in/wheel/ansicolor/badge.png
:target: https://pypi.python.org/pypi/ansicolor/
-Runs on:
+Python version support: CPython 2.6, 2.7, 3.2, 3.3 and PyPy.
-- CPython 2.6, 2.7, 3.2, 3.3
-- PyPy
+
+Introduction
+------------
+
+``ansicolor`` is a library that makes it easy to use ansi color markup in command
+line programs.
Installation
@@ -22,3 +26,80 @@ Installation
.. code:: bash
$ pip install ansicolor
+
+
+Getting started
+---------------
+
+To get some simple color output:
+
+.. code:: python
+
+ from ansicolor import green
+ from ansicolor import red
+ from ansicolor import white
+
+ print("Let's try two colors: %s and %s!" % (red("red"), green("green")))
+ print("It's also easy to produce text in %s," % (red("bold", bold=True)))
+ print("...%s," % (green("reverse", reverse=True)))
+ print("...and %s." % (cyan("bold and reverse", bold=True, reverse=True)))
+
+
+This will emit ansi escapes into the string: one when starting a color, another
+to reset the color back to the default:
+
+.. code:: python
+
+ >>> from ansicolor import green
+
+ >>> green("green")
+ '\x1b[0;0;32mgreen\x1b[0;0m'
+
+
+If I want to be able to pass a color as an argument I can also use the
+``colorize`` function:
+
+.. code:: python
+
+ from ansicolor import Colors
+ from ansicolor import colorize
+
+ print(colorize("I'm blue", Colors.Blue))
+
+
+I can also apply color on a portion of a string:
+
+.. code:: python
+
+ from ansicolor import Colors
+ from ansicolor import wrap_string
+
+ print(wrap_string("I'm blue, said the policeman.", 8, Colors.Blue))
+
+
+Sometimes I may have a string that contains markup and I'll want to do something
+with it that concerns only the text, so I can strip the markup:
+
+.. code:: python
+
+ >>> from ansicolor import red
+ >>> from ansicolor import strip_escapes
+ >>> from ansicolor import yellow
+
+ >>> message = "My favorite colors are %s and %s" % (yellow("yellow"), red("red"))
+ >>> print("The length of this string is not: %d" % len(message))
+ The length of this string is not: 67
+ >>> print("The length of this string is: %d" % len(strip_escapes(message)))
+ The length of this string is: 37
+
+
+Going further
+-------------
+
+Take a look at the ``demos`` to see what's possible.
+
+.. code:: bash
+
+ $ python -m ansicolor.demos --color
+ $ python -m ansicolor.demos --highlight
+ $ python -m ansicolor.demos --diff
diff --git a/ansicolor/__init__.py b/ansicolor/__init__.py
index 28f242e..957c5ea 100644
--- a/ansicolor/__init__.py
+++ b/ansicolor/__init__.py
@@ -1,3 +1,5 @@
-from ansicolor import * # noqa
+from __future__ import absolute_import
+from ansicolor.ansicolor import * # noqa
-__version__ = "0.0.3"
+
+__version__ = "0.0.4"
diff --git a/ansicolor/ansicolor.py b/ansicolor/ansicolor.py
index a472fb3..628078a 100644
--- a/ansicolor/ansicolor.py
+++ b/ansicolor/ansicolor.py
@@ -5,7 +5,8 @@
__all__ = ['Colors',
'black', 'red', 'green', 'yellow', 'blue', 'magenta', 'cyan',
'white',
- 'colorize', 'colordiff', 'get_code', 'get_highlighter', 'highlight_string',
+ 'colorize', 'colordiff', 'get_code', 'get_highlighter',
+ 'highlight_string',
'justify_formatted', 'strip_escapes', 'wrap_string',
'set_term_title', 'write_out', 'write_err']
@@ -23,7 +24,7 @@ class Colors(object):
@classmethod
def new(cls, colorname):
try:
- _ = cls.colorlist
+ cls.colorlist
except AttributeError:
cls.colorlist = []
@@ -89,19 +90,21 @@ def get_code(color, bold=False, reverse=False):
fmt = '0;7'
elif bold:
fmt = '0;1'
- color = (color != None) and ';3%s' % color.id or ''
+ color = (color is not None) and ';3%s' % color.id or ''
return '\033[' + fmt + color + 'm'
def colorize(s, color, bold=False, reverse=False):
'''Colorize the string'''
- return "%s%s%s" % (get_code(color, bold=bold, reverse=reverse), s, get_code(None))
+ return ("%s%s%s" % (get_code(color, bold=bold, reverse=reverse),
+ s, get_code(None)))
def wrap_string(s, pos, color, bold=False, reverse=False):
'''Colorize the string up to a position'''
if _disabled:
- if pos == 0: pos = 1
- return s[:pos-1] + "|" + s[pos:]
+ if pos == 0:
+ pos = 1
+ return s[:pos - 1] + "|" + s[pos:]
return "%s%s%s%s" % (get_code(color, bold=bold, reverse=reverse),
s[:pos],
@@ -120,17 +123,17 @@ def highlight_string(s, *spanlists, **kw):
for spanlist in spanlists:
get_id = lambda spanlist: spanlists.index(spanlist)
get_color = lambda spanlist: get_highlighter(get_id(spanlist))
- tuples.extend( [(span, get_color(spanlist), get_id(spanlist))
- for span in spanlist] )
+ tuples.extend([(span, get_color(spanlist), get_id(spanlist))
+ for span in spanlist])
# produce list of (pos,color,start_end,list_id) pairs
# (begin, Red, True, list_id) # start new color
# (end, Red, False, list_id) # end current color
markers = []
for i in tuples:
- (begin,end),color,list_id = i
- markers.append( (begin, color, True, list_id) )
- markers.append( (end, color, False, list_id) )
+ (begin, end), color, list_id = i
+ markers.append((begin, color, True, list_id))
+ markers.append((end, color, False, list_id))
def get_key(tup):
pos, color, start_end, list_id = tup
@@ -145,21 +148,21 @@ def highlight_string(s, *spanlists, **kw):
# stack invariant : list_id1 < list_id2 => i1 < i2
if start_end:
inserted = False
- for (i, (c,id)) in enumerate(stack):
+ for (i, (c, id)) in enumerate(stack):
if list_id < id:
- stack.insert(i, (color, list_id) )
+ stack.insert(i, (color, list_id))
inserted = True
break
if not inserted:
- stack.append( (color, list_id) )
+ stack.append((color, list_id))
else:
- stack.remove( (color,list_id) )
+ stack.remove((color, list_id))
cur_color = None
if len(stack) > 0:
(cur_color, _) = stack[-1]
- codes.append( (pos, cur_color, len(stack)) )
+ codes.append((pos, cur_color, len(stack)))
# apply codes to the string
cursor = 0
@@ -185,11 +188,11 @@ def highlight_string(s, *spanlists, **kw):
bold = True
reverse = True
- segments.append( s[cursor:pos] )
- segments.append( get_code(color, bold=bold, reverse=reverse) )
+ segments.append(s[cursor:pos])
+ segments.append(get_code(color, bold=bold, reverse=reverse))
cursor = pos
- segments.append( s[cursor:] )
+ segments.append(s[cursor:])
return ''.join(segments)
@@ -202,11 +205,11 @@ def colordiff(x, y, color_x=Colors.Cyan, color_y=Colors.Green, debug=False):
sm = difflib.SequenceMatcher(None, x, y)
seq = ''
for match in sm.get_matching_blocks():
- seq += x[match.a:match.a+match.size]
+ seq += x[match.a:match.a + match.size]
return seq
def make_generator(it):
- g = ((i,e) for (i,e) in enumerate(it))
+ g = ((i, e) for (i, e) in enumerate(it))
def f():
try:
return next(g)
@@ -247,24 +250,24 @@ def colordiff(x, y, color_x=Colors.Cyan, color_y=Colors.Green, debug=False):
# -> added in new
elif s == a:
log('+%s' % b)
- y_spans.append( (bid,bid+1) )
+ y_spans.append((bid, bid + 1))
(bid, b) = it_y()
# character the same in new and common
# -> removed in orig
elif s == b:
log('-%s' % a)
- x_spans.append( (aid,aid+1) )
+ x_spans.append((aid, aid + 1))
(aid, a) = it_x()
# character not the same (eg. case change)
# -> removed in orig and added in new
elif a != b:
if a:
log('-%s' % a)
- x_spans.append( (aid,aid+1) )
+ x_spans.append((aid, aid + 1))
(aid, a) = it_x()
if b:
- log('+%s'% b)
- y_spans.append( (bid,bid+1) )
+ log('+%s' % b)
+ y_spans.append((bid, bid + 1))
(bid, b) = it_y()
x_fmt = highlight_string(x, x_spans, reverse=True, color=color_x)
@@ -275,7 +278,7 @@ def colordiff(x, y, color_x=Colors.Cyan, color_y=Colors.Green, debug=False):
def justify_formatted(s, justify_func, width):
'''Justify formatted string to width using function (eg. string.ljust)'''
dx = len(s) - len(strip_escapes(s))
- return justify_func(s, width+dx)
+ return justify_func(s, width + dx)
def strip_escapes(s):
'''Strip escapes from string'''
@@ -303,99 +306,3 @@ def write_out(s):
def write_err(s):
'''Write a string to stderr, strip escapes if output is a pipe'''
write_to(sys.stderr, s)
-
-
-if __name__ == '__main__':
- def test_color():
- width = 10
-
- lst = []
-
- lst.extend([ [], ['>>> Without colors'], [] ])
- line = []
- line.append( colorize("Standard".ljust(width), None) )
- line.append( colorize("Bold".ljust(width), None, bold=True) )
- line.append( colorize("Reverse".ljust(width), None, reverse=True) )
- line.append( colorize("Bold & Rev".ljust(width), None, bold=True, reverse=True) )
- lst.append(line)
-
- lst.extend([ [], ['>>> Using colors'], [] ])
- for color in Colors.iter():
- line = []
- line.append( colorize(color.__name__.ljust(width), color) )
- line.append( colorize(color.__name__.ljust(width), color, bold=True) )
- line.append( colorize(color.__name__.ljust(width), color, reverse=True) )
- line.append( colorize(color.__name__.ljust(width), color, bold=True, reverse=True) )
- lst.append(line)
-
- lst.extend([ [], ['>>> Using highlighting colors'], [] ])
- for color in Colors.iter():
- color = get_highlighter(color.id)
- line = []
- line.append( colorize(color.__name__.ljust(width), color) )
- line.append( colorize(color.__name__.ljust(width), color, bold=True) )
- line.append( colorize(color.__name__.ljust(width), color, reverse=True) )
- line.append( colorize(color.__name__.ljust(width), color, bold=True, reverse=True) )
- lst.append(line)
-
- for line in lst:
- for item in line:
- write_out('%s ' % item)
- write_out("\n")
-
- def test_highlight():
- import re
- rxs = [
- '(b+).*\\1',
- '(c+).*\\1',
- '(d+).*\\1',
- '(e+).*\\1',
- ]
- s = """\
-aaabbbcccdddeeefffeeedddcccbbbaaa
-fffeeedddcccbbbaaabbbcccdddeeefff
-"""
- def display(rxs, s):
- spanlists = []
- for rx in rxs:
- spanlist = []
- for m in re.finditer(rx, s):
- spanlist.append(m.span())
- spanlists.append(spanlist)
- s = highlight_string(s, *spanlists)
- for (i,rx) in enumerate(rxs):
- color = get_highlighter(i)
- color = colorize(color.__name__.ljust(10), color)
- write_out('Regex %s: %s %s\n' % (i, color, rx))
- write_out(s)
-
- for i in range(0, len(rxs) + 1):
- write_out('\n')
- display(rxs[:i], s)
-
- def test_diff():
- def display_diff(s, t):
- (s_fmt, t_fmt) = colordiff(s, t)
- write_out('>>> %s\n' % s_fmt)
- write_out(' %s\n\n' % t_fmt)
-
- display_diff('first last', 'First Last')
- display_diff('the the boss', 'the boss')
- display_diff('the coder', 'the first coder')
- display_diff('agcat', 'gac')
- display_diff('XMJYAUZ', 'MZJAWXU')
- display_diff('abcdfghjqz', 'abcdefgijkrxyz')
-
-
- try:
- action = sys.argv[1]
- except IndexError:
- print("Usage: %s [ --color | --highlight | --diff ]" % sys.argv[0])
- sys.exit(1)
-
- if action == '--color':
- test_color()
- elif action == '--highlight':
- test_highlight()
- elif action == '--diff':
- test_diff()
diff --git a/ansicolor/demos.py b/ansicolor/demos.py
new file mode 100644
index 0000000..def30fe
--- /dev/null
+++ b/ansicolor/demos.py
@@ -0,0 +1,107 @@
+from __future__ import absolute_import
+
+import re
+import sys
+
+from ansicolor.ansicolor import Colors
+from ansicolor.ansicolor import colorize
+from ansicolor.ansicolor import colordiff
+from ansicolor.ansicolor import get_highlighter
+from ansicolor.ansicolor import highlight_string
+from ansicolor.ansicolor import write_out
+
+
+def demo_color():
+ width = 10
+
+ lst = []
+
+ lst.extend([[], ['>>> Without colors'], []])
+ line = []
+ line.append(colorize("Standard".ljust(width), None))
+ line.append(colorize("Bold".ljust(width), None, bold=True))
+ line.append(colorize("Reverse".ljust(width), None, reverse=True))
+ line.append(colorize("Bold & Rev".ljust(width), None, bold=True, reverse=True)) # noqa
+ lst.append(line)
+
+ lst.extend([[], ['>>> Using colors'], []])
+ for color in Colors.iter():
+ line = []
+ line.append(colorize(color.__name__.ljust(width), color))
+ line.append(colorize(color.__name__.ljust(width), color, bold=True)) # noqa
+ line.append(colorize(color.__name__.ljust(width), color, reverse=True)) # noqa
+ line.append(colorize(color.__name__.ljust(width), color, bold=True, reverse=True)) # noqa
+ lst.append(line)
+
+ lst.extend([[], ['>>> Using highlighting colors'], []])
+ for color in Colors.iter():
+ color = get_highlighter(color.id)
+ line = []
+ line.append(colorize(color.__name__.ljust(width), color))
+ line.append(colorize(color.__name__.ljust(width), color, bold=True)) # noqa
+ line.append(colorize(color.__name__.ljust(width), color, reverse=True)) # noqa
+ line.append(colorize(color.__name__.ljust(width), color, bold=True, reverse=True)) # noqa
+ lst.append(line)
+
+ for line in lst:
+ for item in line:
+ write_out('%s ' % item)
+ write_out("\n")
+
+def demo_highlight():
+ rxs = [
+ '(b+).*\\1',
+ '(c+).*\\1',
+ '(d+).*\\1',
+ '(e+).*\\1',
+ ]
+ s = """\
+aaabbbcccdddeeefffeeedddcccbbbaaa
+fffeeedddcccbbbaaabbbcccdddeeefff
+"""
+ def display(rxs, s):
+ spanlists = []
+ for rx in rxs:
+ spanlist = []
+ for m in re.finditer(rx, s):
+ spanlist.append(m.span())
+ spanlists.append(spanlist)
+ s = highlight_string(s, *spanlists)
+ for (i, rx) in enumerate(rxs):
+ color = get_highlighter(i)
+ color = colorize(color.__name__.ljust(10), color)
+ write_out('Regex %s: %s %s\n' % (i, color, rx))
+ write_out(s)
+
+ for i in range(0, len(rxs) + 1):
+ write_out('\n')
+ display(rxs[:i], s)
+
+def demo_diff():
+ def display_diff(s, t):
+ (s_fmt, t_fmt) = colordiff(s, t)
+ write_out('>>> %s\n' % s_fmt)
+ write_out(' %s\n\n' % t_fmt)
+
+ display_diff('first last', 'First Last')
+ display_diff('the the boss', 'the boss')
+ display_diff('the coder', 'the first coder')
+ display_diff('agcat', 'gac')
+ display_diff('XMJYAUZ', 'MZJAWXU')
+ display_diff('abcdfghjqz', 'abcdefgijkrxyz')
+
+
+
+if __name__ == '__main__':
+ try:
+ action = sys.argv[1]
+ except IndexError:
+ print("Usage: %s [ --color | --highlight | --diff ]" % sys.argv[0])
+ sys.exit(1)
+
+ if action == '--color':
+ demo_color()
+ elif action == '--highlight':
+ demo_highlight()
+ elif action == '--diff':
+ demo_diff()
diff --git a/dev-requirements.txt b/dev-requirements.txt
index 91cfbf2..8d53218 100644
--- a/dev-requirements.txt
+++ b/dev-requirements.txt
@@ -1,4 +1,6 @@
cheesecake
flake8
+pytest
+sphinx
tox
wheel
diff --git a/docs/Makefile b/docs/Makefile
new file mode 100644
index 0000000..b6756d6
--- /dev/null
+++ b/docs/Makefile
@@ -0,0 +1,177 @@
+# Makefile for Sphinx documentation
+#
+
+# You can set these variables from the command line.
+SPHINXOPTS =
+SPHINXBUILD = sphinx-build
+PAPER =
+BUILDDIR = _build
+
+# User-friendly check for sphinx-build
+ifeq ($(shell which $(SPHINXBUILD) >/dev/null 2>&1; echo $$?), 1)
+$(error The '$(SPHINXBUILD)' command was not found. Make sure you have Sphinx installed, then set the SPHINXBUILD environment variable to point to the full path of the '$(SPHINXBUILD)' executable. Alternatively you can add the directory with the executable to your PATH. If you don't have Sphinx installed, grab it from http://sphinx-doc.org/)
+endif
+
+# Internal variables.
+PAPEROPT_a4 = -D latex_paper_size=a4
+PAPEROPT_letter = -D latex_paper_size=letter
+ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
+# the i18n builder cannot share the environment and doctrees with the others
+I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
+
+.PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest gettext
+
+help:
+ @echo "Please use \`make <target>' where <target> is one of"
+ @echo " html to make standalone HTML files"
+ @echo " dirhtml to make HTML files named index.html in directories"
+ @echo " singlehtml to make a single large HTML file"
+ @echo " pickle to make pickle files"
+ @echo " json to make JSON files"
+ @echo " htmlhelp to make HTML files and a HTML help project"
+ @echo " qthelp to make HTML files and a qthelp project"
+ @echo " devhelp to make HTML files and a Devhelp project"
+ @echo " epub to make an epub"
+ @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter"
+ @echo " latexpdf to make LaTeX files and run them through pdflatex"
+ @echo " latexpdfja to make LaTeX files and run them through platex/dvipdfmx"
+ @echo " text to make text files"
+ @echo " man to make manual pages"
+ @echo " texinfo to make Texinfo files"
+ @echo " info to make Texinfo files and run them through makeinfo"
+ @echo " gettext to make PO message catalogs"
+ @echo " changes to make an overview of all changed/added/deprecated items"
+ @echo " xml to make Docutils-native XML files"
+ @echo " pseudoxml to make pseudoxml-XML files for display purposes"
+ @echo " linkcheck to check all external links for integrity"
+ @echo " doctest to run all doctests embedded in the documentation (if enabled)"
+
+clean:
+ rm -rf $(BUILDDIR)/*
+
+html:
+ $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html
+ @echo
+ @echo "Build finished. The HTML pages are in $(BUILDDIR)/html."
+
+dirhtml:
+ $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml
+ @echo
+ @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml."
+
+singlehtml:
+ $(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml
+ @echo
+ @echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml."
+
+pickle:
+ $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle
+ @echo
+ @echo "Build finished; now you can process the pickle files."
+
+json:
+ $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json
+ @echo
+ @echo "Build finished; now you can process the JSON files."
+
+htmlhelp:
+ $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp
+ @echo
+ @echo "Build finished; now you can run HTML Help Workshop with the" \
+ ".hhp project file in $(BUILDDIR)/htmlhelp."
+
+qthelp:
+ $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp
+ @echo
+ @echo "Build finished; now you can run "qcollectiongenerator" with the" \
+ ".qhcp project file in $(BUILDDIR)/qthelp, like this:"
+ @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/ansicolor.qhcp"
+ @echo "To view the help file:"
+ @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/ansicolor.qhc"
+
+devhelp:
+ $(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp
+ @echo
+ @echo "Build finished."
+ @echo "To view the help file:"
+ @echo "# mkdir -p $$HOME/.local/share/devhelp/ansicolor"
+ @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/ansicolor"
+ @echo "# devhelp"
+
+epub:
+ $(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub
+ @echo
+ @echo "Build finished. The epub file is in $(BUILDDIR)/epub."
+
+latex:
+ $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
+ @echo
+ @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex."
+ @echo "Run \`make' in that directory to run these through (pdf)latex" \
+ "(use \`make latexpdf' here to do that automatically)."
+
+latexpdf:
+ $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
+ @echo "Running LaTeX files through pdflatex..."
+ $(MAKE) -C $(BUILDDIR)/latex all-pdf
+ @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex."
+
+latexpdfja:
+ $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
+ @echo "Running LaTeX files through platex and dvipdfmx..."
+ $(MAKE) -C $(BUILDDIR)/latex all-pdf-ja
+ @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex."
+
+text:
+ $(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text
+ @echo
+ @echo "Build finished. The text files are in $(BUILDDIR)/text."
+
+man:
+ $(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man
+ @echo
+ @echo "Build finished. The manual pages are in $(BUILDDIR)/man."
+
+texinfo:
+ $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo
+ @echo
+ @echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo."
+ @echo "Run \`make' in that directory to run these through makeinfo" \
+ "(use \`make info' here to do that automatically)."
+
+info:
+ $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo
+ @echo "Running Texinfo files through makeinfo..."
+ make -C $(BUILDDIR)/texinfo info
+ @echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo."
+
+gettext:
+ $(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale
+ @echo
+ @echo "Build finished. The message catalogs are in $(BUILDDIR)/locale."
+
+changes:
+ $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes
+ @echo
+ @echo "The overview file is in $(BUILDDIR)/changes."
+
+linkcheck:
+ $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck
+ @echo
+ @echo "Link check complete; look for any errors in the above output " \
+ "or in $(BUILDDIR)/linkcheck/output.txt."
+
+doctest:
+ $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest
+ @echo "Testing of doctests in the sources finished, look at the " \
+ "results in $(BUILDDIR)/doctest/output.txt."
+
+xml:
+ $(SPHINXBUILD) -b xml $(ALLSPHINXOPTS) $(BUILDDIR)/xml
+ @echo
+ @echo "Build finished. The XML files are in $(BUILDDIR)/xml."
+
+pseudoxml:
+ $(SPHINXBUILD) -b pseudoxml $(ALLSPHINXOPTS) $(BUILDDIR)/pseudoxml
+ @echo
+ @echo "Build finished. The pseudo-XML files are in $(BUILDDIR)/pseudoxml."
diff --git a/docs/conf.py b/docs/conf.py
new file mode 100644
index 0000000..13a964e
--- /dev/null
+++ b/docs/conf.py
@@ -0,0 +1,263 @@
+# -*- coding: utf-8 -*-
+#
+# ansicolor documentation build configuration file, created by
+# sphinx-quickstart on Sat Mar 8 16:16:41 2014.
+#
+# This file is execfile()d with the current directory set to its
+# containing dir.
+#
+# Note that not all possible configuration values are present in this
+# autogenerated file.
+#
+# All configuration values have a default; values that are commented out
+# serve to show the default.
+
+import sys
+import os
+
+import ansicolor
+
+# If extensions (or modules to document with autodoc) are in another directory,
+# add these directories to sys.path here. If the directory is relative to the
+# documentation root, use os.path.abspath to make it absolute, like shown here.
+#sys.path.insert(0, os.path.abspath('.'))
+
+# -- General configuration ------------------------------------------------
+
+# If your documentation needs a minimal Sphinx version, state it here.
+#needs_sphinx = '1.0'
+
+# Add any Sphinx extension module names here, as strings. They can be
+# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
+# ones.
+extensions = [
+ 'sphinx.ext.autodoc',
+ 'sphinx.ext.viewcode',
+]
+
+# Add any paths that contain templates here, relative to this directory.
+templates_path = ['_templates']
+
+# The suffix of source filenames.
+source_suffix = '.rst'
+
+# The encoding of source files.
+#source_encoding = 'utf-8-sig'
+
+# The master toctree document.
+master_doc = 'index'
+
+# General information about the project.
+project = ansicolor.__name__
+copyright = u'2014, Martin Matusiak'
+
+# The version info for the project you're documenting, acts as replacement for
+# |version| and |release|, also used in various other places throughout the
+# built documents.
+#
+# The short X.Y version.
+version = ansicolor.__version__
+# The full version, including alpha/beta/rc tags.
+release = ansicolor.__version__
+
+# The language for content autogenerated by Sphinx. Refer to documentation
+# for a list of supported languages.
+#language = None
+
+# There are two options for replacing |today|: either, you set today to some
+# non-false value, then it is used:
+#today = ''
+# Else, today_fmt is used as the format for a strftime call.
+#today_fmt = '%B %d, %Y'
+
+# List of patterns, relative to source directory, that match files and
+# directories to ignore when looking for source files.
+exclude_patterns = ['_build']
+
+# The reST default role (used for this markup: `text`) to use for all
+# documents.
+#default_role = None
+
+# If true, '()' will be appended to :func: etc. cross-reference text.
+#add_function_parentheses = True
+
+# If true, the current module name will be prepended to all description
+# unit titles (such as .. function::).
+#add_module_names = True
+
+# If true, sectionauthor and moduleauthor directives will be shown in the
+# output. They are ignored by default.
+#show_authors = False
+
+# The name of the Pygments (syntax highlighting) style to use.
+pygments_style = 'sphinx'
+
+# A list of ignored prefixes for module index sorting.
+#modindex_common_prefix = []
+
+# If true, keep warnings as "system message" paragraphs in the built documents.
+#keep_warnings = False
+
+
+# -- Options for HTML output ----------------------------------------------
+
+# The theme to use for HTML and HTML Help pages. See the documentation for
+# a list of builtin themes.
+html_theme = 'default'
+
+# Theme options are theme-specific and customize the look and feel of a theme
+# further. For a list of options available for each theme, see the
+# documentation.
+#html_theme_options = {}
+
+# Add any paths that contain custom themes here, relative to this directory.
+#html_theme_path = []
+
+# The name for this set of Sphinx documents. If None, it defaults to
+# "<project> v<release> documentation".
+#html_title = None
+
+# A shorter title for the navigation bar. Default is the same as html_title.
+#html_short_title = None
+
+# The name of an image file (relative to this directory) to place at the top
+# of the sidebar.
+#html_logo = None
+
+# The name of an image file (within the static path) to use as favicon of the
+# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32
+# pixels large.
+#html_favicon = None
+
+# Add any paths that contain custom static files (such as style sheets) here,
+# relative to this directory. They are copied after the builtin static files,
+# so a file named "default.css" will overwrite the builtin "default.css".
+html_static_path = ['_static']
+
+# Add any extra paths that contain custom files (such as robots.txt or
+# .htaccess) here, relative to this directory. These files are copied
+# directly to the root of the documentation.
+#html_extra_path = []
+
+# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
+# using the given strftime format.
+#html_last_updated_fmt = '%b %d, %Y'
+
+# If true, SmartyPants will be used to convert quotes and dashes to
+# typographically correct entities.
+#html_use_smartypants = True
+
+# Custom sidebar templates, maps document names to template names.
+#html_sidebars = {}
+
+# Additional templates that should be rendered to pages, maps page names to
+# template names.
+#html_additional_pages = {}
+
+# If false, no module index is generated.
+#html_domain_indices = True
+
+# If false, no index is generated.
+#html_use_index = True
+
+# If true, the index is split into individual pages for each letter.
+#html_split_index = False
+
+# If true, links to the reST sources are added to the pages.
+#html_show_sourcelink = True
+
+# If true, "Created using Sphinx" is shown in the HTML footer. Default is True.
+#html_show_sphinx = True
+
+# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True.
+#html_show_copyright = True
+
+# If true, an OpenSearch description file will be output, and all pages will
+# contain a <link> tag referring to it. The value of this option must be the
+# base URL from which the finished HTML is served.
+#html_use_opensearch = ''
+
+# This is the file name suffix for HTML files (e.g. ".xhtml").
+#html_file_suffix = None
+
+# Output file base name for HTML help builder.
+htmlhelp_basename = 'ansicolordoc'
+
+
+# -- Options for LaTeX output ---------------------------------------------
+
+latex_elements = {
+# The paper size ('letterpaper' or 'a4paper').
+#'papersize': 'letterpaper',
+
+# The font size ('10pt', '11pt' or '12pt').
+#'pointsize': '10pt',
+
+# Additional stuff for the LaTeX preamble.
+#'preamble': '',
+}
+
+# Grouping the document tree into LaTeX files. List of tuples
+# (source start file, target name, title,
+# author, documentclass [howto, manual, or own class]).
+latex_documents = [
+ ('index', 'ansicolor.tex', u'ansicolor Documentation',
+ u'Martin Matusiak', 'manual'),
+]
+
+# The name of an image file (relative to this directory) to place at the top of
+# the title page.
+#latex_logo = None
+
+# For "manual" documents, if this is true, then toplevel headings are parts,
+# not chapters.
+#latex_use_parts = False
+
+# If true, show page references after internal links.
+#latex_show_pagerefs = False
+
+# If true, show URL addresses after external links.
+#latex_show_urls = False
+
+# Documents to append as an appendix to all manuals.
+#latex_appendices = []
+
+# If false, no module index is generated.
+#latex_domain_indices = True
+
+
+# -- Options for manual page output ---------------------------------------
+
+# One entry per manual page. List of tuples
+# (source start file, name, description, authors, manual section).
+man_pages = [
+ ('index', 'ansicolor', u'ansicolor Documentation',
+ [u'Martin Matusiak'], 1)
+]
+
+# If true, show URL addresses after external links.
+#man_show_urls = False
+
+
+# -- Options for Texinfo output -------------------------------------------
+
+# Grouping the document tree into Texinfo files. List of tuples
+# (source start file, target name, title, author,
+# dir menu entry, description, category)
+texinfo_documents = [
+ ('index', 'ansicolor', u'ansicolor Documentation',
+ u'Martin Matusiak', 'ansicolor', 'One line description of project.',
+ 'Miscellaneous'),
+]
+
+# Documents to append as an appendix to all manuals.
+#texinfo_appendices = []
+
+# If false, no module index is generated.
+#texinfo_domain_indices = True
+
+# How to display URL addresses: 'footnote', 'no', or 'inline'.
+#texinfo_show_urls = 'footnote'
+
+# If true, do not generate a @detailmenu in the "Top" node's menu.
+#texinfo_no_detailmenu = False
diff --git a/docs/index.rst b/docs/index.rst
new file mode 100644
index 0000000..28288a9
--- /dev/null
+++ b/docs/index.rst
@@ -0,0 +1,24 @@
+.. ansicolor documentation master file, created by
+ sphinx-quickstart on Sat Mar 8 16:16:41 2014.
+ You can adapt this file completely to your liking, but it should at least
+ contain the root `toctree` directive.
+
+Welcome to ansicolor's documentation!
+=====================================
+
+Contents:
+
+.. toctree::
+ :maxdepth: 2
+
+ ansicolor
+
+
+
+Indices and tables
+==================
+
+* :ref:`genindex`
+* :ref:`modindex`
+* :ref:`search`
+
diff --git a/setup.cfg b/setup.cfg
index c2866a0..6bb7506 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -1,5 +1,6 @@
[flake8]
-exclude = .tox/*
+exclude = .tox/,build/
+ignore = E301,E302,E303
[wheel]
universal = 1
diff --git a/setup.py b/setup.py
index 037a5e1..f1a0843 100644
--- a/setup.py
+++ b/setup.py
@@ -6,7 +6,10 @@ import ansicolor
setup(
name='ansicolor',
version=ansicolor.__version__,
- description='A library to produce ansi color output and colored highlighting and diffing',
+ description=(
+ 'A library to produce ansi color output '
+ 'and colored highlighting and diffing'
+ ),
author='Martin Matusiak',
author_email='numerodix@gmail.com',
url='https://github.com/numerodix/ansicolor',
diff --git a/tests/__init__.py b/tests/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tests/__init__.py
diff --git a/tests/test_colors.py b/tests/test_colors.py
new file mode 100644
index 0000000..0e1bb1a
--- /dev/null
+++ b/tests/test_colors.py
@@ -0,0 +1,91 @@
+from ansicolor import Colors
+from ansicolor import blue
+from ansicolor import colordiff
+from ansicolor import colorize
+from ansicolor import get_code
+from ansicolor import get_highlighter
+from ansicolor import justify_formatted
+from ansicolor import red
+from ansicolor import strip_escapes
+from ansicolor import wrap_string
+
+
+def test_codes():
+ # reset code
+ assert '\033[0;0m' == get_code(None)
+
+ # plain color codes
+ assert '\033[0;0;30m' == get_code(Colors.Black)
+ assert '\033[0;0;31m' == get_code(Colors.Red)
+ assert '\033[0;0;32m' == get_code(Colors.Green)
+ assert '\033[0;0;33m' == get_code(Colors.Yellow)
+ assert '\033[0;0;34m' == get_code(Colors.Blue)
+ assert '\033[0;0;35m' == get_code(Colors.Magenta)
+ assert '\033[0;0;36m' == get_code(Colors.Cyan)
+ assert '\033[0;0;37m' == get_code(Colors.White)
+
+ # bold color
+ assert '\033[0;1;31m' == get_code(Colors.Red, bold=True)
+
+ # reverse color
+ assert '\033[0;7;31m' == get_code(Colors.Red, reverse=True)
+
+ # bold + reverse color
+ assert '\033[1;7;31m' == get_code(Colors.Red, bold=True, reverse=True)
+
+
+def test_coloring():
+ assert '\033[0;0;31m' + 'hi' + '\033[0;0m' == red('hi')
+
+
+def test_highlights():
+ # can I get a highlighter?
+ assert Colors.Green == get_highlighter(0)
+ assert Colors.Yellow == get_highlighter(1)
+
+
+def test_colorize():
+ assert (
+ get_code(Colors.Red)
+ + "Hi there"
+ + get_code(None)
+ ) == colorize("Hi there", Colors.Red)
+
+
+def test_wrap_string():
+ assert (
+ get_code(Colors.Red)
+ + "Hi "
+ + get_code(None)
+ + "there"
+ ) == wrap_string("Hi there", 3, Colors.Red)
+
+
+def test_strip_escapes():
+ assert "Hi there" == strip_escapes(wrap_string("Hi there", 3, Colors.Red))
+
+ assert strip_escapes(
+ colorize("Hi", None, bold=True) +
+ " there, " +
+ colorize("stranger", Colors.Green, bold=True)
+ ) == "Hi there, stranger"
+
+
+def test_colordiff():
+ x, y = colordiff("hi bob", "hi there",
+ color_x=Colors.Red, color_y=Colors.Blue)
+
+ fx = lambda s: red(s, reverse=True)
+ fy = lambda s: blue(s, reverse=True)
+
+ assert x == "hi " + fx("b") + fx("o") + fx("b")
+ assert y == "hi " + fy("t") + fy("h") + fy("e") + fy("r") + fy("e")
+
+
+def test_justify_formatted():
+ def rjust(s, width):
+ return s.rjust(width)
+
+ assert justify_formatted(
+ red("hi"), rjust, 10
+ ) == " " + red("hi")
diff --git a/tests/test_imports.py b/tests/test_imports.py
new file mode 100644
index 0000000..ed5f654
--- /dev/null
+++ b/tests/test_imports.py
@@ -0,0 +1,33 @@
+def test_importability():
+ from ansicolor import black # noqa
+ from ansicolor import blue # noqa
+ from ansicolor import cyan # noqa
+ from ansicolor import green # noqa
+ from ansicolor import magenta # noqa
+ from ansicolor import red # noqa
+ from ansicolor import white # noqa
+ from ansicolor import yellow # noqa
+
+ from ansicolor import Colors # noqa
+ Colors.Black
+ Colors.Blue
+ Colors.Cyan
+ Colors.Green
+ Colors.Magenta
+ Colors.Red
+ Colors.White
+ Colors.Yellow
+
+ from ansicolor import get_highlighter # noqa
+ from ansicolor import get_code # noqa
+
+ from ansicolor import colorize # noqa
+ from ansicolor import wrap_string # noqa
+ from ansicolor import highlight_string # noqa
+ from ansicolor import colordiff # noqa
+ from ansicolor import justify_formatted # noqa
+ from ansicolor import strip_escapes # noqa
+ from ansicolor import set_term_title # noqa
+
+ from ansicolor import write_err # noqa
+ from ansicolor import write_out # noqa
diff --git a/tox.ini b/tox.ini
index f8e74c0..df44434 100644
--- a/tox.ini
+++ b/tox.ini
@@ -4,6 +4,8 @@ develop=true
[testenv]
commands=
- python -m ansicolor.ansicolor --color
- python -m ansicolor.ansicolor --diff
- python -m ansicolor.ansicolor --highlight
+ pip install pytest
+ python -m ansicolor.demos --color
+ python -m ansicolor.demos --diff
+ python -m ansicolor.demos --highlight
+ py.test