Skip to content

Commit

Permalink
Add code-block directive, to simplify integrating snippets
Browse files Browse the repository at this point in the history
in other languages, and with line numbers.
  • Loading branch information
birkenfeld committed Mar 9, 2008
1 parent 910e488 commit f2ff041
Show file tree
Hide file tree
Showing 6 changed files with 100 additions and 16 deletions.
34 changes: 31 additions & 3 deletions sphinx/directives.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
"""

import re
import sys
import string
import posixpath
from os import path
Expand Down Expand Up @@ -613,15 +614,42 @@ def centered_directive(name, arguments, options, content, lineno,
directives.register_directive('centered', centered_directive)


# ------ highlightlanguage directive ------------------------------------------------
# ------ highlight directive --------------------------------------------------------

def highlightlang_directive(name, arguments, options, content, lineno,
content_offset, block_text, state, state_machine):
return [addnodes.highlightlang(lang=arguments[0].strip())]
if 'linenothreshold' in options:
try:
linenothreshold = int(options['linenothreshold'])
except Exception:
linenothreshold = 10
else:
linenothreshold = sys.maxint
return [addnodes.highlightlang(lang=arguments[0].strip(),
linenothreshold=linenothreshold)]

highlightlang_directive.content = 0
highlightlang_directive.arguments = (1, 0, 0)
directives.register_directive('highlightlang', highlightlang_directive)
highlightlang_directive.options = {'linenothreshold': directives.unchanged}
directives.register_directive('highlight', highlightlang_directive)
directives.register_directive('highlightlang', highlightlang_directive) # old name


# ------ code-block directive -------------------------------------------------------

def codeblock_directive(name, arguments, options, content, lineno,
content_offset, block_text, state, state_machine):
code = u'\n'.join(content)
literal = nodes.literal_block(code, code)
literal['language'] = arguments[0]
literal['linenos'] = 'linenos' in options
return [literal]

codeblock_directive.content = 1
codeblock_directive.arguments = (1, 0, 0)
codeblock_directive.options = {'linenos': directives.flag}
directives.register_directive('code-block', codeblock_directive)
directives.register_directive('sourcecode', codeblock_directive)


# ------ literalinclude directive ---------------------------------------------------
Expand Down
21 changes: 15 additions & 6 deletions sphinx/highlighting.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,10 @@
from pygments import highlight
from pygments.lexers import PythonLexer, PythonConsoleLexer, CLexer, \
TextLexer, RstLexer
from pygments.lexers import get_lexer_by_name
from pygments.formatters import HtmlFormatter, LatexFormatter
from pygments.filters import ErrorToken
from pygments.util import ClassNotFound
from pygments.style import Style
from pygments.styles import get_style_by_name
from pygments.styles.friendly import FriendlyStyle
Expand Down Expand Up @@ -74,10 +76,12 @@ def __init__(self, dest='html', stylename='sphinx'):
style = SphinxStyle
else:
style = get_style_by_name(stylename)
self.hfmter = HtmlFormatter(style=style)
self.lfmter = LatexFormatter(style=style)
self.hfmter = {False: HtmlFormatter(style=style),
True: HtmlFormatter(style=style, linenos=True)}
self.lfmter = {False: LatexFormatter(style=style),
True: LatexFormatter(style=style, linenos=True)}

def highlight_block(self, source, lang):
def highlight_block(self, source, lang, linenos=False):
def unhighlighted():
if self.dest == 'html':
return '<pre>' + cgi.escape(source) + '</pre>\n'
Expand Down Expand Up @@ -114,14 +118,19 @@ def unhighlighted():
else:
lexer = lexers['python']
else:
lexer = lexers[lang]
if lang in lexers:
lexer = lexers[lang]
else:
lexer = lexers[lang] = get_lexer_by_name(lang)
lexer.add_filter('raiseonerror')
try:
return highlight(source, lexer, self.dest == 'html' and self.hfmter or self.lfmter)
fmter = (self.dest == 'html' and self.hfmter or self.lfmter)[bool(linenos)]
return highlight(source, lexer, fmter)
except ErrorToken:
# this is most probably not the selected language, so let it pass unhighlighted
return unhighlighted()

def get_stylesheet(self):
if not pygments:
return ''
return (self.dest == 'html' and self.hfmter or self.lfmter).get_style_defs()
return (self.dest == 'html' and self.hfmter or self.lfmter)[0].get_style_defs()
13 changes: 11 additions & 2 deletions sphinx/htmlwriter.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
:license: BSD.
"""

import sys

from docutils import nodes
from docutils.writers.html4css1 import Writer, HTMLTranslator as BaseTranslator

Expand Down Expand Up @@ -50,6 +52,7 @@ def __init__(self, builder, *args, **kwds):
self.no_smarty = 0
self.builder = builder
self.highlightlang = 'python'
self.highlightlinenothreshold = sys.maxint
self.language.labels['warning'] = 'Caveat'

def visit_desc(self, node):
Expand Down Expand Up @@ -175,8 +178,13 @@ def visit_title(self, node, move_ids=1):

# overwritten
def visit_literal_block(self, node):
self.body.append(self.highlighter.highlight_block(node.rawsource,
self.highlightlang))
lang = self.highlightlang
linenos = node.rawsource.count('\n') >= self.highlightlinenothreshold - 1
if node.has_key('language'):
# code-block directives
lang = node['language']
linenos = node['linenos']
self.body.append(self.highlighter.highlight_block(node.rawsource, lang, linenos))
raise nodes.SkipNode

# overwritten
Expand Down Expand Up @@ -224,6 +232,7 @@ def depart_compact_paragraph(self, node):

def visit_highlightlang(self, node):
self.highlightlang = node['lang']
self.highlightlinenothreshold = node['linenothreshold']
def depart_highlightlang(self, node):
pass

Expand Down
18 changes: 13 additions & 5 deletions sphinx/latexwriter.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
"""

import re
import sys
import time

from docutils import nodes, writers
Expand Down Expand Up @@ -76,7 +77,7 @@ def __init__(self):

class Desc:
def __init__(self, node):
self.env = LaTeXTranslator.desc_map[node['desctype']]
self.env = LaTeXTranslator.desc_map.get(node['desctype'], 'describe')
self.ni = node['noindex']
self.type = self.cls = self.name = self.params = ''
self.count = 0
Expand Down Expand Up @@ -109,6 +110,7 @@ def __init__(self, document, builder):
self.context = []
self.descstack = []
self.highlightlang = 'python'
self.highlightlinenothreshold = sys.maxint
self.written_ids = set()
if docclass == 'manual':
self.top_sectionlevel = 0
Expand Down Expand Up @@ -141,6 +143,7 @@ def depart_document(self, node):

def visit_highlightlang(self, node):
self.highlightlang = node['lang']
self.highlightlinenothreshold = node['linenothreshold']
raise nodes.SkipNode

def visit_comment(self, node):
Expand Down Expand Up @@ -239,8 +242,7 @@ def depart_title(self, node):
'cvar': 'cvardesc',

'describe': 'describe',
'cmdoption': 'describe',
'envvar': 'describe',
# and all others are 'describe' too
}

def visit_desc(self, node):
Expand Down Expand Up @@ -646,8 +648,14 @@ def visit_footnote_reference(self, node):
def visit_literal_block(self, node):
self.verbatim = ''
def depart_literal_block(self, node):
hlcode = self.highlighter.highlight_block(self.verbatim.rstrip('\n'),
self.highlightlang)
code = self.verbatim.rstrip('\n')
lang = self.highlightlang
linenos = code.count('\n') >= self.highlightlinenothreshold - 1
if node.has_key('language'):
# code-block directives
lang = node['language']
linenos = node['linenos']
hlcode = self.highlighter.highlight_block(code, lang, linenos)
# workaround for Unicode issue
hlcode = hlcode.replace(u'€', u'@texteuro[]')
# workaround for Pygments bug
Expand Down
15 changes: 15 additions & 0 deletions sphinx/static/default.css
Original file line number Diff line number Diff line change
Expand Up @@ -704,6 +704,21 @@ pre {
border-right: none;
}

td.linenos pre {
padding: 0;
border: 0;
background-color: transparent;
color: #aaa;
}

table.highlighttable {
margin-left: 0.5em;
}

table.highlighttable td {
padding: 0 0.5em 0 0.5em;
}

tt {
background-color: #ecf0f3;
padding: 0 1px 0 1px;
Expand Down
15 changes: 15 additions & 0 deletions sphinx/static/sphinxdoc.css
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,21 @@ pre {
background-color: #f8f8f8;
}

td.linenos pre {
padding: 0;
border: 0;
background-color: transparent;
color: #aaa;
}

table.highlighttable {
margin-left: 0.5em;
}

table.highlighttable td {
padding: 0 0.5em 0 0.5em;
}

cite, code, tt {
font-family: 'Consolas', 'Deja Vu Sans Mono', 'Bitstream Vera Sans Mono', monospace;
font-size: 0.95em;
Expand Down

0 comments on commit f2ff041

Please sign in to comment.