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 re
|
||||||
|
import sys
|
||||||
import string
|
import string
|
||||||
import posixpath
|
import posixpath
|
||||||
from os import path
|
from os import path
|
||||||
@ -613,15 +614,42 @@ centered_directive.arguments = (1, 0, 1)
|
|||||||
directives.register_directive('centered', centered_directive)
|
directives.register_directive('centered', centered_directive)
|
||||||
|
|
||||||
|
|
||||||
# ------ highlightlanguage directive ------------------------------------------------
|
# ------ highlight directive --------------------------------------------------------
|
||||||
|
|
||||||
def highlightlang_directive(name, arguments, options, content, lineno,
|
def highlightlang_directive(name, arguments, options, content, lineno,
|
||||||
content_offset, block_text, state, state_machine):
|
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.content = 0
|
||||||
highlightlang_directive.arguments = (1, 0, 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 ---------------------------------------------------
|
# ------ literalinclude directive ---------------------------------------------------
|
||||||
|
@ -19,8 +19,10 @@ try:
|
|||||||
from pygments import highlight
|
from pygments import highlight
|
||||||
from pygments.lexers import PythonLexer, PythonConsoleLexer, CLexer, \
|
from pygments.lexers import PythonLexer, PythonConsoleLexer, CLexer, \
|
||||||
TextLexer, RstLexer
|
TextLexer, RstLexer
|
||||||
|
from pygments.lexers import get_lexer_by_name
|
||||||
from pygments.formatters import HtmlFormatter, LatexFormatter
|
from pygments.formatters import HtmlFormatter, LatexFormatter
|
||||||
from pygments.filters import ErrorToken
|
from pygments.filters import ErrorToken
|
||||||
|
from pygments.util import ClassNotFound
|
||||||
from pygments.style import Style
|
from pygments.style import Style
|
||||||
from pygments.styles import get_style_by_name
|
from pygments.styles import get_style_by_name
|
||||||
from pygments.styles.friendly import FriendlyStyle
|
from pygments.styles.friendly import FriendlyStyle
|
||||||
@ -74,10 +76,12 @@ class PygmentsBridge(object):
|
|||||||
style = SphinxStyle
|
style = SphinxStyle
|
||||||
else:
|
else:
|
||||||
style = get_style_by_name(stylename)
|
style = get_style_by_name(stylename)
|
||||||
self.hfmter = HtmlFormatter(style=style)
|
self.hfmter = {False: HtmlFormatter(style=style),
|
||||||
self.lfmter = LatexFormatter(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():
|
def unhighlighted():
|
||||||
if self.dest == 'html':
|
if self.dest == 'html':
|
||||||
return '<pre>' + cgi.escape(source) + '</pre>\n'
|
return '<pre>' + cgi.escape(source) + '</pre>\n'
|
||||||
@ -114,9 +118,14 @@ class PygmentsBridge(object):
|
|||||||
else:
|
else:
|
||||||
lexer = lexers['python']
|
lexer = lexers['python']
|
||||||
else:
|
else:
|
||||||
|
if lang in lexers:
|
||||||
lexer = lexers[lang]
|
lexer = lexers[lang]
|
||||||
|
else:
|
||||||
|
lexer = lexers[lang] = get_lexer_by_name(lang)
|
||||||
|
lexer.add_filter('raiseonerror')
|
||||||
try:
|
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:
|
except ErrorToken:
|
||||||
# this is most probably not the selected language, so let it pass unhighlighted
|
# this is most probably not the selected language, so let it pass unhighlighted
|
||||||
return unhighlighted()
|
return unhighlighted()
|
||||||
@ -124,4 +133,4 @@ class PygmentsBridge(object):
|
|||||||
def get_stylesheet(self):
|
def get_stylesheet(self):
|
||||||
if not pygments:
|
if not pygments:
|
||||||
return ''
|
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.
|
:license: BSD.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
import sys
|
||||||
|
|
||||||
from docutils import nodes
|
from docutils import nodes
|
||||||
from docutils.writers.html4css1 import Writer, HTMLTranslator as BaseTranslator
|
from docutils.writers.html4css1 import Writer, HTMLTranslator as BaseTranslator
|
||||||
|
|
||||||
@ -50,6 +52,7 @@ class HTMLTranslator(BaseTranslator):
|
|||||||
self.no_smarty = 0
|
self.no_smarty = 0
|
||||||
self.builder = builder
|
self.builder = builder
|
||||||
self.highlightlang = 'python'
|
self.highlightlang = 'python'
|
||||||
|
self.highlightlinenothreshold = sys.maxint
|
||||||
self.language.labels['warning'] = 'Caveat'
|
self.language.labels['warning'] = 'Caveat'
|
||||||
|
|
||||||
def visit_desc(self, node):
|
def visit_desc(self, node):
|
||||||
@ -175,8 +178,13 @@ class HTMLTranslator(BaseTranslator):
|
|||||||
|
|
||||||
# overwritten
|
# overwritten
|
||||||
def visit_literal_block(self, node):
|
def visit_literal_block(self, node):
|
||||||
self.body.append(self.highlighter.highlight_block(node.rawsource,
|
lang = self.highlightlang
|
||||||
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
|
raise nodes.SkipNode
|
||||||
|
|
||||||
# overwritten
|
# overwritten
|
||||||
@ -224,6 +232,7 @@ class HTMLTranslator(BaseTranslator):
|
|||||||
|
|
||||||
def visit_highlightlang(self, node):
|
def visit_highlightlang(self, node):
|
||||||
self.highlightlang = node['lang']
|
self.highlightlang = node['lang']
|
||||||
|
self.highlightlinenothreshold = node['linenothreshold']
|
||||||
def depart_highlightlang(self, node):
|
def depart_highlightlang(self, node):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
@ -13,6 +13,7 @@
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
import re
|
import re
|
||||||
|
import sys
|
||||||
import time
|
import time
|
||||||
|
|
||||||
from docutils import nodes, writers
|
from docutils import nodes, writers
|
||||||
@ -76,7 +77,7 @@ class TableSpec:
|
|||||||
|
|
||||||
class Desc:
|
class Desc:
|
||||||
def __init__(self, node):
|
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.ni = node['noindex']
|
||||||
self.type = self.cls = self.name = self.params = ''
|
self.type = self.cls = self.name = self.params = ''
|
||||||
self.count = 0
|
self.count = 0
|
||||||
@ -109,6 +110,7 @@ class LaTeXTranslator(nodes.NodeVisitor):
|
|||||||
self.context = []
|
self.context = []
|
||||||
self.descstack = []
|
self.descstack = []
|
||||||
self.highlightlang = 'python'
|
self.highlightlang = 'python'
|
||||||
|
self.highlightlinenothreshold = sys.maxint
|
||||||
self.written_ids = set()
|
self.written_ids = set()
|
||||||
if docclass == 'manual':
|
if docclass == 'manual':
|
||||||
self.top_sectionlevel = 0
|
self.top_sectionlevel = 0
|
||||||
@ -141,6 +143,7 @@ class LaTeXTranslator(nodes.NodeVisitor):
|
|||||||
|
|
||||||
def visit_highlightlang(self, node):
|
def visit_highlightlang(self, node):
|
||||||
self.highlightlang = node['lang']
|
self.highlightlang = node['lang']
|
||||||
|
self.highlightlinenothreshold = node['linenothreshold']
|
||||||
raise nodes.SkipNode
|
raise nodes.SkipNode
|
||||||
|
|
||||||
def visit_comment(self, node):
|
def visit_comment(self, node):
|
||||||
@ -239,8 +242,7 @@ class LaTeXTranslator(nodes.NodeVisitor):
|
|||||||
'cvar': 'cvardesc',
|
'cvar': 'cvardesc',
|
||||||
|
|
||||||
'describe': 'describe',
|
'describe': 'describe',
|
||||||
'cmdoption': 'describe',
|
# and all others are 'describe' too
|
||||||
'envvar': 'describe',
|
|
||||||
}
|
}
|
||||||
|
|
||||||
def visit_desc(self, node):
|
def visit_desc(self, node):
|
||||||
@ -646,8 +648,14 @@ class LaTeXTranslator(nodes.NodeVisitor):
|
|||||||
def visit_literal_block(self, node):
|
def visit_literal_block(self, node):
|
||||||
self.verbatim = ''
|
self.verbatim = ''
|
||||||
def depart_literal_block(self, node):
|
def depart_literal_block(self, node):
|
||||||
hlcode = self.highlighter.highlight_block(self.verbatim.rstrip('\n'),
|
code = self.verbatim.rstrip('\n')
|
||||||
self.highlightlang)
|
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
|
# workaround for Unicode issue
|
||||||
hlcode = hlcode.replace(u'€', u'@texteuro[]')
|
hlcode = hlcode.replace(u'€', u'@texteuro[]')
|
||||||
# workaround for Pygments bug
|
# workaround for Pygments bug
|
||||||
|
@ -704,6 +704,21 @@ pre {
|
|||||||
border-right: none;
|
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 {
|
tt {
|
||||||
background-color: #ecf0f3;
|
background-color: #ecf0f3;
|
||||||
padding: 0 1px 0 1px;
|
padding: 0 1px 0 1px;
|
||||||
|
@ -37,6 +37,21 @@ pre {
|
|||||||
background-color: #f8f8f8;
|
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 {
|
cite, code, tt {
|
||||||
font-family: 'Consolas', 'Deja Vu Sans Mono', 'Bitstream Vera Sans Mono', monospace;
|
font-family: 'Consolas', 'Deja Vu Sans Mono', 'Bitstream Vera Sans Mono', monospace;
|
||||||
font-size: 0.95em;
|
font-size: 0.95em;
|
||||||
|
Loading…
Reference in New Issue
Block a user