mirror of
https://github.com/sphinx-doc/sphinx.git
synced 2025-02-25 18:55:22 -06:00
Add code-block directive, to simplify integrating snippets
in other languages, and with line numbers.
This commit is contained in:
parent
910e488e39
commit
f2ff0419bd
@ -10,6 +10,7 @@
|
||||
"""
|
||||
|
||||
import re
|
||||
import sys
|
||||
import string
|
||||
import posixpath
|
||||
from os import path
|
||||
@ -613,15 +614,42 @@ centered_directive.arguments = (1, 0, 1)
|
||||
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 ---------------------------------------------------
|
||||
|
@ -19,8 +19,10 @@ try:
|
||||
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
|
||||
@ -74,10 +76,12 @@ class PygmentsBridge(object):
|
||||
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'
|
||||
@ -114,9 +118,14 @@ class PygmentsBridge(object):
|
||||
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()
|
||||
@ -124,4 +133,4 @@ class PygmentsBridge(object):
|
||||
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()
|
||||
|
@ -9,6 +9,8 @@
|
||||
:license: BSD.
|
||||
"""
|
||||
|
||||
import sys
|
||||
|
||||
from docutils import nodes
|
||||
from docutils.writers.html4css1 import Writer, HTMLTranslator as BaseTranslator
|
||||
|
||||
@ -50,6 +52,7 @@ class HTMLTranslator(BaseTranslator):
|
||||
self.no_smarty = 0
|
||||
self.builder = builder
|
||||
self.highlightlang = 'python'
|
||||
self.highlightlinenothreshold = sys.maxint
|
||||
self.language.labels['warning'] = 'Caveat'
|
||||
|
||||
def visit_desc(self, node):
|
||||
@ -175,8 +178,13 @@ class HTMLTranslator(BaseTranslator):
|
||||
|
||||
# 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
|
||||
@ -224,6 +232,7 @@ class HTMLTranslator(BaseTranslator):
|
||||
|
||||
def visit_highlightlang(self, node):
|
||||
self.highlightlang = node['lang']
|
||||
self.highlightlinenothreshold = node['linenothreshold']
|
||||
def depart_highlightlang(self, node):
|
||||
pass
|
||||
|
||||
|
@ -13,6 +13,7 @@
|
||||
"""
|
||||
|
||||
import re
|
||||
import sys
|
||||
import time
|
||||
|
||||
from docutils import nodes, writers
|
||||
@ -76,7 +77,7 @@ class TableSpec:
|
||||
|
||||
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
|
||||
@ -109,6 +110,7 @@ class LaTeXTranslator(nodes.NodeVisitor):
|
||||
self.context = []
|
||||
self.descstack = []
|
||||
self.highlightlang = 'python'
|
||||
self.highlightlinenothreshold = sys.maxint
|
||||
self.written_ids = set()
|
||||
if docclass == 'manual':
|
||||
self.top_sectionlevel = 0
|
||||
@ -141,6 +143,7 @@ class LaTeXTranslator(nodes.NodeVisitor):
|
||||
|
||||
def visit_highlightlang(self, node):
|
||||
self.highlightlang = node['lang']
|
||||
self.highlightlinenothreshold = node['linenothreshold']
|
||||
raise nodes.SkipNode
|
||||
|
||||
def visit_comment(self, node):
|
||||
@ -239,8 +242,7 @@ class LaTeXTranslator(nodes.NodeVisitor):
|
||||
'cvar': 'cvardesc',
|
||||
|
||||
'describe': 'describe',
|
||||
'cmdoption': 'describe',
|
||||
'envvar': 'describe',
|
||||
# and all others are 'describe' too
|
||||
}
|
||||
|
||||
def visit_desc(self, node):
|
||||
@ -646,8 +648,14 @@ class LaTeXTranslator(nodes.NodeVisitor):
|
||||
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
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user