Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement 16 named ANSI colors #259

Merged
merged 4 commits into from
Apr 7, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
79 changes: 30 additions & 49 deletions nbconvert/filters/ansi.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,48 +14,23 @@

_ANSI_RE = re.compile('\x1b\\[(.*?)([@-~])')

_FG_HTML = (
'ansiblack',
'ansired',
'ansigreen',
'ansiyellow',
'ansiblue',
'ansipurple',
'ansicyan',
'ansigray',
)

_BG_HTML = (
'ansibgblack',
'ansibgred',
'ansibggreen',
'ansibgyellow',
'ansibgblue',
'ansibgpurple',
'ansibgcyan',
'ansibggray',
)

_FG_LATEX = (
'black',
'red',
'green',
'brown',
'blue',
'purple',
'cyan',
'lightgray',
)

_BG_LATEX = (
'darkgray',
'lightred',
'lightgreen',
'yellow',
'lightblue',
'lightpurple',
'lightcyan',
'white',
_ANSI_COLORS = (
'ansi-black',
'ansi-red',
'ansi-green',
'ansi-yellow',
'ansi-blue',
'ansi-magenta',
'ansi-cyan',
'ansi-white',
'ansi-black-intense',
'ansi-red-intense',
'ansi-green-intense',
'ansi-yellow-intense',
'ansi-blue-intense',
'ansi-magenta-intense',
'ansi-cyan-intense',
'ansi-white-intense',
)


Expand Down Expand Up @@ -111,17 +86,17 @@ def _htmlconverter(fg, bg, bold):
styles = []

if isinstance(fg, int):
classes.append(_FG_HTML[fg])
classes.append(_ANSI_COLORS[fg] + '-fg')
elif fg:
styles.append('color: rgb({},{},{})'.format(*fg))

if isinstance(bg, int):
classes.append(_BG_HTML[bg])
classes.append(_ANSI_COLORS[bg] + '-bg')
elif bg:
styles.append('background-color: rgb({},{},{})'.format(*bg))

if bold:
classes.append('ansibold')
classes.append('ansi-bold')

starttag = '<span'
if classes:
Expand All @@ -143,7 +118,7 @@ def _latexconverter(fg, bg, bold):
starttag, endtag = '', ''

if isinstance(fg, int):
starttag += r'\textcolor{' + _FG_LATEX[fg] + '}{'
starttag += r'\textcolor{' + _ANSI_COLORS[fg] + '}{'
endtag = '}' + endtag
elif fg:
# See http://tex.stackexchange.com/a/291102/13684
Expand All @@ -153,7 +128,7 @@ def _latexconverter(fg, bg, bold):

if isinstance(bg, int):
starttag += r'\setlength{\fboxsep}{0pt}\colorbox{'
starttag += _BG_LATEX[bg] + '}{'
starttag += _ANSI_COLORS[bg] + '}{'
endtag = r'\strut}' + endtag
elif bg:
starttag += r'\setlength{\fboxsep}{0pt}'
Expand Down Expand Up @@ -210,6 +185,8 @@ def _ansi2anything(text, converter):
chunk, text = text, ''

if chunk:
if bold and fg in range(8):
fg += 8
starttag, endtag = converter(fg, bg, bold)
out.append(starttag)
out.append(chunk)
Expand Down Expand Up @@ -242,6 +219,10 @@ def _ansi2anything(text, converter):
numbers.clear()
elif n == 49:
bg = None
elif 90 <= n <= 97:
fg = n - 90 + 8
elif 100 <= n <= 107:
bg = n - 100 + 8
else:
pass # Unknown codes are ignored
return ''.join(out)
Expand All @@ -262,8 +243,8 @@ def _get_extended_color(numbers):
if idx < 0:
raise ValueError()
elif idx < 16:
# 8 default terminal colors
return idx % 8 # ignore bright/non-bright distinction
# 16 default terminal colors
return idx
elif idx < 232:
# 6x6x6 color cube, see http://stackoverflow.com/a/27165165/500098
r = (idx - 16) // 36
Expand Down
30 changes: 15 additions & 15 deletions nbconvert/filters/tests/test_ansi.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,33 +35,33 @@ def test_ansi2html(self):
correct_outputs = {
'\x1b[31m': '',
'hello\x1b[34m': 'hello',
'he\x1b[32m\x1b[36mllo': 'he<span class="ansicyan">llo</span>',
'\x1b[1;33mhello': '<span class="ansiyellow ansibold">hello</span>',
'\x1b[37mh\x1b[0;037me\x1b[;0037ml\x1b[00;37ml\x1b[;;37mo': '<span class="ansigray">h</span><span class="ansigray">e</span><span class="ansigray">l</span><span class="ansigray">l</span><span class="ansigray">o</span>',
'hel\x1b[0;32mlo': 'hel<span class="ansigreen">lo</span>',
'he\x1b[32m\x1b[36mllo': 'he<span class="ansi-cyan-fg">llo</span>',
'\x1b[1;33mhello': '<span class="ansi-yellow-intense-fg ansi-bold">hello</span>',
'\x1b[37mh\x1b[0;037me\x1b[;0037ml\x1b[00;37ml\x1b[;;37mo': '<span class="ansi-white-fg">h</span><span class="ansi-white-fg">e</span><span class="ansi-white-fg">l</span><span class="ansi-white-fg">l</span><span class="ansi-white-fg">o</span>',
'hel\x1b[0;32mlo': 'hel<span class="ansi-green-fg">lo</span>',
'hellø': 'hellø',
'\x1b[1mhello\x1b[33mworld\x1b[0m': '<span class="ansibold">hello</span><span class="ansiyellow ansibold">world</span>',
'\x1b[1mhello\x1b[33mworld\x1b[0m': '<span class="ansi-bold">hello</span><span class="ansi-yellow-intense-fg ansi-bold">world</span>',
}

for inval, outval in correct_outputs.items():
self.fuzzy_compare(outval, ansi2html(inval))
self.assertEqual(outval, ansi2html(inval))

def test_ansi2latex(self):
"""ansi2latex test"""
correct_outputs = {
'\x1b[31m': '',
'hello\x1b[34m': 'hello',
'he\x1b[32m\x1b[36mllo': r'he\textcolor{cyan}{llo}',
'\x1b[1;33mhello': r'\textcolor{brown}{\textbf{hello}}',
'\x1b[37mh\x1b[0;037me\x1b[;0037ml\x1b[00;37ml\x1b[;;37mo': r'\textcolor{lightgray}{h}\textcolor{lightgray}{e}\textcolor{lightgray}{l}\textcolor{lightgray}{l}\textcolor{lightgray}{o}',
'hel\x1b[0;32mlo': r'hel\textcolor{green}{lo}',
'he\x1b[32m\x1b[36mllo': r'he\textcolor{ansi-cyan}{llo}',
'\x1b[1;33mhello': r'\textcolor{ansi-yellow-intense}{\textbf{hello}}',
'\x1b[37mh\x1b[0;037me\x1b[;0037ml\x1b[00;37ml\x1b[;;37mo': r'\textcolor{ansi-white}{h}\textcolor{ansi-white}{e}\textcolor{ansi-white}{l}\textcolor{ansi-white}{l}\textcolor{ansi-white}{o}',
'hel\x1b[0;32mlo': r'hel\textcolor{ansi-green}{lo}',
'hello': 'hello',
'hello\x1b[34mthere\x1b[mworld': r'hello\textcolor{blue}{there}world',
'hello\x1b[34mthere\x1b[mworld': r'hello\textcolor{ansi-blue}{there}world',
'hello\x1b[mthere': 'hellothere',
'hello\x1b[01;34mthere': r'hello\textcolor{blue}{\textbf{there}}',
'hello\x1b[001;34mthere': r'hello\textcolor{blue}{\textbf{there}}',
'\x1b[1mhello\x1b[33mworld\x1b[0m': r'\textbf{hello}\textcolor{brown}{\textbf{world}}',
'hello\x1b[01;34mthere': r'hello\textcolor{ansi-blue-intense}{\textbf{there}}',
'hello\x1b[001;34mthere': r'hello\textcolor{ansi-blue-intense}{\textbf{there}}',
'\x1b[1mhello\x1b[33mworld\x1b[0m': r'\textbf{hello}\textcolor{ansi-yellow-intense}{\textbf{world}}',
}

for inval, outval in correct_outputs.items():
self.fuzzy_compare(outval, ansi2latex(inval), case_sensitive=True)
self.assertEqual(outval, ansi2latex(inval))
41 changes: 41 additions & 0 deletions nbconvert/preprocessors/csshtmlheader.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,47 @@ def _generate_header(self, resources):
pygments_css = formatter.get_style_defs(self.highlight_class)
header.append(pygments_css)

# These ANSI CSS definitions will be part of style.min.css with the
# Notebook release 5.0 and shall be removed afterwards!
# See https://github.com/jupyter/nbconvert/pull/259
header.append("""
/* Temporary definitions which will become obsolete with Notebook release 5.0 */
.ansi-black-fg { color: #3E424D; }
.ansi-black-bg { background-color: #3E424D; }
.ansi-black-intense-fg { color: #282C36; }
.ansi-black-intense-bg { background-color: #282C36; }
.ansi-red-fg { color: #E75C58; }
.ansi-red-bg { background-color: #E75C58; }
.ansi-red-intense-fg { color: #B22B31; }
.ansi-red-intense-bg { background-color: #B22B31; }
.ansi-green-fg { color: #00A250; }
.ansi-green-bg { background-color: #00A250; }
.ansi-green-intense-fg { color: #007427; }
.ansi-green-intense-bg { background-color: #007427; }
.ansi-yellow-fg { color: #DDB62B; }
.ansi-yellow-bg { background-color: #DDB62B; }
.ansi-yellow-intense-fg { color: #B27D12; }
.ansi-yellow-intense-bg { background-color: #B27D12; }
.ansi-blue-fg { color: #208FFB; }
.ansi-blue-bg { background-color: #208FFB; }
.ansi-blue-intense-fg { color: #0065CA; }
.ansi-blue-intense-bg { background-color: #0065CA; }
.ansi-magenta-fg { color: #D160C4; }
.ansi-magenta-bg { background-color: #D160C4; }
.ansi-magenta-intense-fg { color: #A03196; }
.ansi-magenta-intense-bg { background-color: #A03196; }
.ansi-cyan-fg { color: #60C6C8; }
.ansi-cyan-bg { background-color: #60C6C8; }
.ansi-cyan-intense-fg { color: #258F8F; }
.ansi-cyan-intense-bg { background-color: #258F8F; }
.ansi-white-fg { color: #C5C1B4; }
.ansi-white-bg { background-color: #C5C1B4; }
.ansi-white-intense-fg { color: #A1A6B2; }
.ansi-white-intense-bg { background-color: #A1A6B2; }

.ansi-bold { font-weight: bold; }
""")

# Load the user's custom CSS and IPython's default custom CSS. If they
# differ, assume the user has made modifications to his/her custom CSS
# and that we should inline it in the nbconvert output.
Expand Down
54 changes: 25 additions & 29 deletions nbconvert/templates/latex/base.tplx
Original file line number Diff line number Diff line change
Expand Up @@ -66,32 +66,28 @@ This template does not define a docclass, the inheriting class must define this.
((* endblock packages *))

((* block definitions *))
\definecolor{orange}{cmyk}{0,0.4,0.8,0.2}
\definecolor{darkorange}{rgb}{.71,0.21,0.01}
\definecolor{darkgreen}{rgb}{.12,.54,.11}
\definecolor{myteal}{rgb}{.26, .44, .56}
\definecolor{gray}{gray}{0.45}
\definecolor{lightgray}{gray}{.95}
\definecolor{mediumgray}{gray}{.8}
\definecolor{inputbackground}{rgb}{.95, .95, .85}
\definecolor{outputbackground}{rgb}{.95, .95, .95}
\definecolor{traceback}{rgb}{1, .95, .95}
% ansi colors
\definecolor{red}{rgb}{.6,0,0}
\definecolor{green}{rgb}{0,.65,0}
\definecolor{brown}{rgb}{0.6,0.6,0}
\definecolor{blue}{rgb}{0,.145,.698}
\definecolor{purple}{rgb}{.698,.145,.698}
\definecolor{cyan}{rgb}{0,.698,.698}
\definecolor{lightgray}{gray}{0.5}

% bright ansi colors
\definecolor{darkgray}{gray}{0.25}
\definecolor{lightred}{rgb}{1.0,0.39,0.28}
\definecolor{lightgreen}{rgb}{0.48,0.99,0.0}
\definecolor{lightblue}{rgb}{0.53,0.81,0.92}
\definecolor{lightpurple}{rgb}{0.87,0.63,0.87}
\definecolor{lightcyan}{rgb}{0.5,1.0,0.83}
% Colors for the hyperref package
\definecolor{urlcolor}{rgb}{0,.145,.698}
\definecolor{linkcolor}{rgb}{.71,0.21,0.01}
\definecolor{citecolor}{rgb}{.12,.54,.11}

% ANSI colors
\definecolor{ansi-black}{HTML}{3E424D}
\definecolor{ansi-black-intense}{HTML}{282C36}
\definecolor{ansi-red}{HTML}{E75C58}
\definecolor{ansi-red-intense}{HTML}{B22B31}
\definecolor{ansi-green}{HTML}{00A250}
\definecolor{ansi-green-intense}{HTML}{007427}
\definecolor{ansi-yellow}{HTML}{DDB62B}
\definecolor{ansi-yellow-intense}{HTML}{B27D12}
\definecolor{ansi-blue}{HTML}{208FFB}
\definecolor{ansi-blue-intense}{HTML}{0065CA}
\definecolor{ansi-magenta}{HTML}{D160C4}
\definecolor{ansi-magenta-intense}{HTML}{A03196}
\definecolor{ansi-cyan}{HTML}{60C6C8}
\definecolor{ansi-cyan-intense}{HTML}{258F8F}
\definecolor{ansi-white}{HTML}{C5C1B4}
\definecolor{ansi-white-intense}{HTML}{A1A6B2}

% commands and environments needed by pandoc snippets
% extracted from the output of `pandoc -s`
Expand Down Expand Up @@ -154,9 +150,9 @@ This template does not define a docclass, the inheriting class must define this.
\hypersetup{
breaklinks=true, % so long urls are correctly broken across lines
colorlinks=true,
urlcolor=blue,
linkcolor=darkorange,
citecolor=darkgreen,
urlcolor=urlcolor,
linkcolor=linkcolor,
citecolor=citecolor,
}
% Slightly bigger margins than the latex defaults
((* block margins *))
Expand Down