mirror of
https://github.com/sphinx-doc/sphinx.git
synced 2025-02-25 18:55:22 -06:00
merge with 1.0
This commit is contained in:
23
CHANGES
23
CHANGES
@@ -11,6 +11,29 @@ Release 1.1 (in development)
|
||||
* #443: Allow referencing external graphviz files.
|
||||
|
||||
|
||||
Release 1.0.3 (in development)
|
||||
==============================
|
||||
|
||||
* #495: Fix internal vs. external link distinction for links coming
|
||||
from a docutils table-of-contents.
|
||||
|
||||
* #494: Fix the ``maxdepth`` option for the ``toctree()`` template
|
||||
callable when used with ``collapse=True``.
|
||||
|
||||
* #507: Fix crash parsing Python argument lists containing brackets
|
||||
in string literals.
|
||||
|
||||
* #501: Fix regression when building LaTeX docs with figures that
|
||||
don't have captions.
|
||||
|
||||
* #510: Fix inheritance diagrams for classes that are not picklable.
|
||||
|
||||
* #497: Introduce separate background color for the sidebar collapse
|
||||
button, making it easier to see.
|
||||
|
||||
* #502, #503, #496: Fix small layout bugs in several builtin themes.
|
||||
|
||||
|
||||
Release 1.0.2 (Aug 14, 2010)
|
||||
============================
|
||||
|
||||
|
||||
@@ -141,8 +141,50 @@ Referencing downloadable files
|
||||
suitable link generated to it.
|
||||
|
||||
|
||||
Cross-referencing other items of interest
|
||||
-----------------------------------------
|
||||
|
||||
The following roles do possibly create a cross-reference, but do not refer to
|
||||
objects:
|
||||
|
||||
.. rst:role:: envvar
|
||||
|
||||
An environment variable. Index entries are generated. Also generates a link
|
||||
to the matching :rst:dir:`envvar` directive, if it exists.
|
||||
|
||||
.. rst:role:: token
|
||||
|
||||
The name of a grammar token (used to create links between
|
||||
:rst:dir:`productionlist` directives).
|
||||
|
||||
.. rst:role:: keyword
|
||||
|
||||
The name of a keyword in Python. This creates a link to a reference label
|
||||
with that name, if it exists.
|
||||
|
||||
.. rst:role:: option
|
||||
|
||||
A command-line option to an executable program. The leading hyphen(s) must
|
||||
be included. This generates a link to a :rst:dir:`option` directive, if it
|
||||
exists.
|
||||
|
||||
|
||||
The following role creates a cross-reference to the term in the glossary:
|
||||
|
||||
.. rst:role:: term
|
||||
|
||||
Reference to a term in the glossary. The glossary is created using the
|
||||
``glossary`` directive containing a definition list with terms and
|
||||
definitions. It does not have to be in the same file as the ``term`` markup,
|
||||
for example the Python docs have one global glossary in the ``glossary.rst``
|
||||
file.
|
||||
|
||||
If you use a term that's not explained in a glossary, you'll get a warning
|
||||
during build.
|
||||
|
||||
|
||||
Other semantic markup
|
||||
---------------------
|
||||
~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
The following roles don't do anything special except formatting the text
|
||||
in a different style:
|
||||
@@ -289,52 +331,10 @@ Note that there are no special roles for including hyperlinks as you can use
|
||||
the standard reST markup for that purpose.
|
||||
|
||||
|
||||
Cross-referencing other items of interest
|
||||
-----------------------------------------
|
||||
|
||||
The following roles do possibly create a cross-reference, but do not refer to
|
||||
objects:
|
||||
|
||||
.. rst:role:: envvar
|
||||
|
||||
An environment variable. Index entries are generated. Also generates a link
|
||||
to the matching :rst:dir:`envvar` directive, if it exists.
|
||||
|
||||
.. rst:role:: token
|
||||
|
||||
The name of a grammar token (used to create links between
|
||||
:rst:dir:`productionlist` directives).
|
||||
|
||||
.. rst:role:: keyword
|
||||
|
||||
The name of a keyword in Python. This creates a link to a reference label
|
||||
with that name, if it exists.
|
||||
|
||||
.. rst:role:: option
|
||||
|
||||
A command-line option to an executable program. The leading hyphen(s) must
|
||||
be included. This generates a link to a :rst:dir:`option` directive, if it
|
||||
exists.
|
||||
|
||||
|
||||
The following role creates a cross-reference to the term in the glossary:
|
||||
|
||||
.. rst:role:: term
|
||||
|
||||
Reference to a term in the glossary. The glossary is created using the
|
||||
``glossary`` directive containing a definition list with terms and
|
||||
definitions. It does not have to be in the same file as the ``term`` markup,
|
||||
for example the Python docs have one global glossary in the ``glossary.rst``
|
||||
file.
|
||||
|
||||
If you use a term that's not explained in a glossary, you'll get a warning
|
||||
during build.
|
||||
|
||||
|
||||
.. _default-substitutions:
|
||||
|
||||
Substitutions
|
||||
-------------
|
||||
~~~~~~~~~~~~~
|
||||
|
||||
The documentation system provides three substitutions that are defined by default.
|
||||
They are set in the build configuration file.
|
||||
|
||||
@@ -119,6 +119,8 @@ These themes are:
|
||||
- **footerbgcolor** (CSS color): Background color for the footer line.
|
||||
- **footertextcolor** (CSS color): Text color for the footer line.
|
||||
- **sidebarbgcolor** (CSS color): Background color for the sidebar.
|
||||
- **sidebarbtncolor** (CSS color): Background color for the sidebar collapse
|
||||
button (used when *collapsiblesidebar* is true).
|
||||
- **sidebartextcolor** (CSS color): Text color for the sidebar.
|
||||
- **sidebarlinkcolor** (CSS color): Link color for the sidebar.
|
||||
- **relbarbgcolor** (CSS color): Background color for the relation bar.
|
||||
|
||||
@@ -200,7 +200,7 @@ class HTMLHelpBuilder(StandaloneHTMLBuilder):
|
||||
outdir += os.sep
|
||||
olen = len(outdir)
|
||||
for root, dirs, files in os.walk(outdir):
|
||||
staticdir = (root == path.join(outdir, '_static'))
|
||||
staticdir = root.startswith(path.join(outdir, '_static'))
|
||||
for fn in files:
|
||||
if (staticdir and not fn.endswith('.js')) or \
|
||||
fn.endswith('.html'):
|
||||
|
||||
@@ -13,8 +13,8 @@ from sphinx import addnodes
|
||||
from sphinx.domains import Domain, ObjType
|
||||
from sphinx.locale import l_, _
|
||||
from sphinx.directives import ObjectDescription
|
||||
from sphinx.domains.python import py_paramlist_re as js_paramlist_re
|
||||
from sphinx.roles import XRefRole
|
||||
from sphinx.domains.python import _pseudo_parse_arglist
|
||||
from sphinx.util.nodes import make_refnode
|
||||
from sphinx.util.docfields import Field, GroupedField, TypedField
|
||||
|
||||
@@ -68,28 +68,10 @@ class JSObject(ObjectDescription):
|
||||
signode += addnodes.desc_addname(nameprefix + '.', nameprefix + '.')
|
||||
signode += addnodes.desc_name(name, name)
|
||||
if self.has_arguments:
|
||||
signode += addnodes.desc_parameterlist()
|
||||
if not arglist:
|
||||
return fullname, nameprefix
|
||||
|
||||
stack = [signode[-1]]
|
||||
for token in js_paramlist_re.split(arglist):
|
||||
if token == '[':
|
||||
opt = addnodes.desc_optional()
|
||||
stack[-1] += opt
|
||||
stack.append(opt)
|
||||
elif token == ']':
|
||||
try:
|
||||
stack.pop()
|
||||
except IndexError:
|
||||
raise ValueError()
|
||||
elif not token or token == ',' or token.isspace():
|
||||
pass
|
||||
if not arglist:
|
||||
signode += addnodes.desc_parameterlist()
|
||||
else:
|
||||
token = token.strip()
|
||||
stack[-1] += addnodes.desc_parameter(token, token)
|
||||
if len(stack) != 1:
|
||||
raise ValueError()
|
||||
_pseudo_parse_arglist(signode, arglist)
|
||||
return fullname, nameprefix
|
||||
|
||||
def add_target_and_index(self, name_obj, sig, signode):
|
||||
|
||||
@@ -33,7 +33,52 @@ py_sig_re = re.compile(
|
||||
)? $ # and nothing more
|
||||
''', re.VERBOSE)
|
||||
|
||||
py_paramlist_re = re.compile(r'([\[\],])') # split at '[', ']' and ','
|
||||
|
||||
def _pseudo_parse_arglist(signode, arglist):
|
||||
""""Parse" a list of arguments separated by commas.
|
||||
|
||||
Arguments can have "optional" annotations given by enclosing them in
|
||||
brackets. Currently, this will split at any comma, even if it's inside a
|
||||
string literal (e.g. default argument value).
|
||||
"""
|
||||
paramlist = addnodes.desc_parameterlist()
|
||||
stack = [paramlist]
|
||||
try:
|
||||
for argument in arglist.split(','):
|
||||
argument = argument.strip()
|
||||
ends_open = ends_close = 0
|
||||
while argument.startswith('['):
|
||||
stack.append(addnodes.desc_optional())
|
||||
stack[-2] += stack[-1]
|
||||
argument = argument[1:].strip()
|
||||
while argument.startswith(']'):
|
||||
stack.pop()
|
||||
argument = argument[1:].strip()
|
||||
while argument.endswith(']'):
|
||||
ends_close += 1
|
||||
argument = argument[:-1].strip()
|
||||
while argument.endswith('['):
|
||||
ends_open += 1
|
||||
argument = argument[:-1].strip()
|
||||
if argument:
|
||||
stack[-1] += addnodes.desc_parameter(argument, argument)
|
||||
while ends_open:
|
||||
stack.append(addnodes.desc_optional())
|
||||
stack[-2] += stack[-1]
|
||||
ends_open -= 1
|
||||
while ends_close:
|
||||
stack.pop()
|
||||
ends_close -= 1
|
||||
if len(stack) != 1:
|
||||
raise IndexError
|
||||
except IndexError:
|
||||
# if there are too few or too many elements on the stack, just give up
|
||||
# and treat the whole argument list as one argument, discarding the
|
||||
# already partially populated paramlist node
|
||||
signode += addnodes.desc_parameterlist()
|
||||
signode[-1] += addnodes.desc_parameter(arglist, arglist)
|
||||
else:
|
||||
signode += paramlist
|
||||
|
||||
|
||||
class PyObject(ObjectDescription):
|
||||
@@ -141,26 +186,7 @@ class PyObject(ObjectDescription):
|
||||
if retann:
|
||||
signode += addnodes.desc_returns(retann, retann)
|
||||
return fullname, name_prefix
|
||||
signode += addnodes.desc_parameterlist()
|
||||
|
||||
stack = [signode[-1]]
|
||||
for token in py_paramlist_re.split(arglist):
|
||||
if token == '[':
|
||||
opt = addnodes.desc_optional()
|
||||
stack[-1] += opt
|
||||
stack.append(opt)
|
||||
elif token == ']':
|
||||
try:
|
||||
stack.pop()
|
||||
except IndexError:
|
||||
raise ValueError
|
||||
elif not token or token == ',' or token.isspace():
|
||||
pass
|
||||
else:
|
||||
token = token.strip()
|
||||
stack[-1] += addnodes.desc_parameter(token, token)
|
||||
if len(stack) != 1:
|
||||
raise ValueError
|
||||
_pseudo_parse_arglist(signode, arglist)
|
||||
if retann:
|
||||
signode += addnodes.desc_returns(retann, retann)
|
||||
return fullname, name_prefix
|
||||
|
||||
@@ -1183,32 +1183,62 @@ class BuildEnvironment:
|
||||
|
||||
def _walk_depth(node, depth, maxdepth):
|
||||
"""Utility: Cut a TOC at a specified depth."""
|
||||
|
||||
# For reading this function, it is useful to keep in mind the node
|
||||
# structure of a toctree (using HTML-like node names for brevity):
|
||||
#
|
||||
# <ul>
|
||||
# <li>
|
||||
# <p><a></p>
|
||||
# <p><a></p>
|
||||
# ...
|
||||
# <ul>
|
||||
# ...
|
||||
# </ul>
|
||||
# </li>
|
||||
# </ul>
|
||||
|
||||
for subnode in node.children[:]:
|
||||
if isinstance(subnode, (addnodes.compact_paragraph,
|
||||
nodes.list_item)):
|
||||
# for <p> and <li>, just indicate the depth level and
|
||||
# recurse to children
|
||||
subnode['classes'].append('toctree-l%d' % (depth-1))
|
||||
_walk_depth(subnode, depth, maxdepth)
|
||||
|
||||
elif isinstance(subnode, nodes.bullet_list):
|
||||
# for <ul>, determine if the depth is too large or if the
|
||||
# entry is to be collapsed
|
||||
if maxdepth > 0 and depth > maxdepth:
|
||||
subnode.parent.replace(subnode, [])
|
||||
else:
|
||||
# to find out what to collapse, *first* walk subitems,
|
||||
# since that determines which children point to the
|
||||
# current page
|
||||
_walk_depth(subnode, depth+1, maxdepth)
|
||||
|
||||
# cull sub-entries whose parents aren't 'current'
|
||||
if (collapse and
|
||||
depth > 1 and
|
||||
'current' not in subnode.parent['classes']):
|
||||
if (collapse and depth > 1 and
|
||||
'iscurrent' not in subnode.parent):
|
||||
subnode.parent.remove(subnode)
|
||||
|
||||
elif isinstance(subnode, nodes.reference):
|
||||
# identify the toc entry pointing to the current document
|
||||
if subnode['refuri'] == docname and \
|
||||
not subnode['anchorname']:
|
||||
# tag the whole branch as 'current'
|
||||
p = subnode
|
||||
while p:
|
||||
p['classes'].append('current')
|
||||
p = p.parent
|
||||
# for <a>, identify which entries point to the current
|
||||
# document and therefore may not be collapsed
|
||||
if subnode['refuri'] == docname:
|
||||
if not subnode['anchorname']:
|
||||
# give the whole branch a 'current' class
|
||||
# (useful for styling it differently)
|
||||
branchnode = subnode
|
||||
while branchnode:
|
||||
branchnode['classes'].append('current')
|
||||
branchnode = branchnode.parent
|
||||
# mark the list_item as "on current page"
|
||||
if subnode.parent.parent.get('iscurrent'):
|
||||
# but only if it's not already done
|
||||
return
|
||||
while subnode:
|
||||
subnode['iscurrent'] = True
|
||||
subnode = subnode.parent
|
||||
|
||||
def _entries_from_toctree(toctreenode, separate=False, subtree=False):
|
||||
"""Return TOC entries for a toctree node."""
|
||||
|
||||
@@ -66,19 +66,18 @@ class InheritanceGraph(object):
|
||||
from all the way to the root "object", and then is able to generate a
|
||||
graphviz dot graph from them.
|
||||
"""
|
||||
def __init__(self, class_names, currmodule, show_builtins=False):
|
||||
def __init__(self, class_names, currmodule, show_builtins=False, parts=0):
|
||||
"""*class_names* is a list of child classes to show bases from.
|
||||
|
||||
If *show_builtins* is True, then Python builtins will be shown
|
||||
in the graph.
|
||||
"""
|
||||
self.class_names = class_names
|
||||
self.classes = self._import_classes(class_names, currmodule)
|
||||
self.all_classes = self._all_classes(self.classes)
|
||||
if len(self.all_classes) == 0:
|
||||
classes = self._import_classes(class_names, currmodule)
|
||||
self.class_info = self._class_info(classes, show_builtins, parts)
|
||||
if not self.class_info:
|
||||
raise InheritanceException('No classes found for '
|
||||
'inheritance diagram')
|
||||
self.show_builtins = show_builtins
|
||||
|
||||
def _import_class_or_module(self, name, currmodule):
|
||||
"""Import a class using its fully-qualified *name*."""
|
||||
@@ -132,20 +131,36 @@ class InheritanceGraph(object):
|
||||
classes.extend(self._import_class_or_module(name, currmodule))
|
||||
return classes
|
||||
|
||||
def _all_classes(self, classes):
|
||||
"""Return a list of all classes that are ancestors of *classes*."""
|
||||
def _class_info(self, classes, show_builtins, parts):
|
||||
"""Return name and bases for all classes that are ancestors of
|
||||
*classes*.
|
||||
|
||||
*parts* gives the number of dotted name parts that is removed from the
|
||||
displayed node names.
|
||||
"""
|
||||
all_classes = {}
|
||||
builtins = __builtins__.values()
|
||||
|
||||
def recurse(cls):
|
||||
all_classes[cls] = None
|
||||
for c in cls.__bases__:
|
||||
if c not in all_classes:
|
||||
recurse(c)
|
||||
if not show_builtins and cls in builtins:
|
||||
return
|
||||
|
||||
nodename = self.class_name(cls, parts)
|
||||
fullname = self.class_name(cls, 0)
|
||||
|
||||
baselist = []
|
||||
all_classes[cls] = (nodename, fullname, baselist)
|
||||
for base in cls.__bases__:
|
||||
if not show_builtins and base in builtins:
|
||||
return
|
||||
baselist.append(self.class_name(base, parts))
|
||||
if base not in all_classes:
|
||||
recurse(base)
|
||||
|
||||
for cls in classes:
|
||||
recurse(cls)
|
||||
|
||||
return all_classes.keys()
|
||||
return all_classes.values()
|
||||
|
||||
def class_name(self, cls, parts=0):
|
||||
"""Given a class object, return a fully-qualified name.
|
||||
@@ -165,7 +180,7 @@ class InheritanceGraph(object):
|
||||
|
||||
def get_all_class_names(self):
|
||||
"""Get all of the class names involved in the graph."""
|
||||
return [self.class_name(x) for x in self.all_classes]
|
||||
return [fullname for (_, fullname, _) in self.class_info]
|
||||
|
||||
# These are the default attrs for graphviz
|
||||
default_graph_attrs = {
|
||||
@@ -191,7 +206,7 @@ class InheritanceGraph(object):
|
||||
def _format_graph_attrs(self, attrs):
|
||||
return ''.join(['%s=%s;\n' % x for x in attrs.items()])
|
||||
|
||||
def generate_dot(self, name, parts=0, urls={}, env=None,
|
||||
def generate_dot(self, name, urls={}, env=None,
|
||||
graph_attrs={}, node_attrs={}, edge_attrs={}):
|
||||
"""Generate a graphviz dot graph from the classes that were passed in
|
||||
to __init__.
|
||||
@@ -218,26 +233,17 @@ class InheritanceGraph(object):
|
||||
res.append('digraph %s {\n' % name)
|
||||
res.append(self._format_graph_attrs(g_attrs))
|
||||
|
||||
for cls in self.all_classes:
|
||||
if not self.show_builtins and cls in __builtins__.values():
|
||||
continue
|
||||
|
||||
name = self.class_name(cls, parts)
|
||||
|
||||
for name, fullname, bases in self.class_info:
|
||||
# Write the node
|
||||
this_node_attrs = n_attrs.copy()
|
||||
url = urls.get(self.class_name(cls))
|
||||
url = urls.get(fullname)
|
||||
if url is not None:
|
||||
this_node_attrs['URL'] = '"%s"' % url
|
||||
res.append(' "%s" [%s];\n' %
|
||||
(name, self._format_node_attrs(this_node_attrs)))
|
||||
|
||||
# Write the edges
|
||||
for base in cls.__bases__:
|
||||
if not self.show_builtins and base in __builtins__.values():
|
||||
continue
|
||||
|
||||
base_name = self.class_name(base, parts)
|
||||
for base_name in bases:
|
||||
res.append(' "%s" -> "%s" [%s];\n' %
|
||||
(base_name, name,
|
||||
self._format_node_attrs(e_attrs)))
|
||||
@@ -270,11 +276,15 @@ class InheritanceDiagram(Directive):
|
||||
env = self.state.document.settings.env
|
||||
class_names = self.arguments[0].split()
|
||||
class_role = env.get_domain('py').role('class')
|
||||
# Store the original content for use as a hash
|
||||
node['parts'] = self.options.get('parts', 0)
|
||||
node['content'] = ', '.join(class_names)
|
||||
|
||||
# Create a graph starting with the list of classes
|
||||
try:
|
||||
graph = InheritanceGraph(class_names,
|
||||
env.temp_data.get('py:module'))
|
||||
graph = InheritanceGraph(
|
||||
class_names, env.temp_data.get('py:module'),
|
||||
parts=node['parts'])
|
||||
except InheritanceException, err:
|
||||
return [node.document.reporter.warning(err.args[0],
|
||||
line=self.lineno)]
|
||||
@@ -290,9 +300,6 @@ class InheritanceDiagram(Directive):
|
||||
# Store the graph object so we can use it to generate the
|
||||
# dot file later
|
||||
node['graph'] = graph
|
||||
# Store the original content for use as a hash
|
||||
node['parts'] = self.options.get('parts', 0)
|
||||
node['content'] = ', '.join(class_names)
|
||||
return [node]
|
||||
|
||||
|
||||
@@ -306,7 +313,6 @@ def html_visit_inheritance_diagram(self, node):
|
||||
image map.
|
||||
"""
|
||||
graph = node['graph']
|
||||
parts = node['parts']
|
||||
|
||||
graph_hash = get_graph_hash(node)
|
||||
name = 'inheritance%s' % graph_hash
|
||||
@@ -319,7 +325,7 @@ def html_visit_inheritance_diagram(self, node):
|
||||
elif child.get('refid') is not None:
|
||||
urls[child['reftitle']] = '#' + child.get('refid')
|
||||
|
||||
dotcode = graph.generate_dot(name, parts, urls, env=self.builder.env)
|
||||
dotcode = graph.generate_dot(name, urls, env=self.builder.env)
|
||||
render_dot_html(self, node, dotcode, [], 'inheritance', 'inheritance',
|
||||
alt='Inheritance diagram of ' + node['content'])
|
||||
raise nodes.SkipNode
|
||||
@@ -330,12 +336,11 @@ def latex_visit_inheritance_diagram(self, node):
|
||||
Output the graph for LaTeX. This will insert a PDF.
|
||||
"""
|
||||
graph = node['graph']
|
||||
parts = node['parts']
|
||||
|
||||
graph_hash = get_graph_hash(node)
|
||||
name = 'inheritance%s' % graph_hash
|
||||
|
||||
dotcode = graph.generate_dot(name, parts, env=self.builder.env,
|
||||
dotcode = graph.generate_dot(name, env=self.builder.env,
|
||||
graph_attrs={'size': '"6.0,6.0"'})
|
||||
render_dot_latex(self, node, dotcode, [], 'inheritance')
|
||||
raise nodes.SkipNode
|
||||
|
||||
@@ -446,7 +446,10 @@
|
||||
linkcolor=InnerLinkColor,filecolor=OuterLinkColor,
|
||||
menucolor=OuterLinkColor,urlcolor=OuterLinkColor,
|
||||
citecolor=InnerLinkColor]{hyperref}
|
||||
\RequirePackage[figure,table]{hypcap}
|
||||
% Fix anchor placement for figures with captions.
|
||||
% (Note: we don't use a package option here; instead, we give an explicit
|
||||
% \capstart for figures that actually have a caption.)
|
||||
\RequirePackage{hypcap}
|
||||
|
||||
% From docutils.writers.latex2e
|
||||
\providecommand{\DUspan}[2]{%
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
<h1><a href="{{ pathto(master_doc) }}">{{ shorttitle|e }}</a></h1>
|
||||
{%- endblock %}
|
||||
<div class="rel">
|
||||
{%- for rellink in rellinks %}
|
||||
{%- for rellink in rellinks|reverse %}
|
||||
<a href="{{ pathto(rellink[0]) }}" title="{{ rellink[1]|striptags|e }}"
|
||||
{{ accesskey(rellink[2]) }}>{{ rellink[3] }}</a>
|
||||
{%- if not loop.last %}{{ reldelim2 }}{% endif %}
|
||||
@@ -67,7 +67,7 @@
|
||||
<div class="footer-wrapper">
|
||||
<div class="footer">
|
||||
<div class="left">
|
||||
{%- for rellink in rellinks %}
|
||||
{%- for rellink in rellinks|reverse %}
|
||||
<a href="{{ pathto(rellink[0]) }}" title="{{ rellink[1]|striptags|e }}"
|
||||
{{ accesskey(rellink[2]) }}>{{ rellink[3] }}</a>
|
||||
{%- if not loop.last %}{{ reldelim2 }}{% endif %}
|
||||
|
||||
@@ -147,6 +147,12 @@ div.sphinxsidebar input {
|
||||
font-size: 1em;
|
||||
}
|
||||
|
||||
{% if theme_collapsiblesidebar|tobool %}
|
||||
/* for collapsible sidebar */
|
||||
div#sidebarbutton {
|
||||
background-color: {{ theme_sidebarbtncolor }};
|
||||
}
|
||||
{% endif %}
|
||||
|
||||
/* -- hyperlink styles ------------------------------------------------------ */
|
||||
|
||||
@@ -174,6 +180,11 @@ a.external:hover {
|
||||
text-decoration: none;
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
a.external:visited {
|
||||
text-decoration: none;
|
||||
border-bottom: 1px dashed {{ theme_visitedlinkcolor }};
|
||||
}
|
||||
{% endif %}
|
||||
|
||||
/* -- body styles ----------------------------------------------------------- */
|
||||
|
||||
@@ -91,6 +91,7 @@ $(function() {
|
||||
'<div id="sidebarbutton"><span>«</span></div>'
|
||||
);
|
||||
var sidebarbutton = $('#sidebarbutton');
|
||||
light_color = sidebarbutton.css('background-color');
|
||||
// find the height of the viewport to center the '<<' in the page
|
||||
var viewport_height;
|
||||
if (window.innerHeight)
|
||||
@@ -144,4 +145,4 @@ $(function() {
|
||||
add_sidebar_button();
|
||||
var sidebarbutton = $('#sidebarbutton');
|
||||
set_position_from_cookie();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -12,6 +12,7 @@ externalrefs = false
|
||||
footerbgcolor = #11303d
|
||||
footertextcolor = #ffffff
|
||||
sidebarbgcolor = #1c4e63
|
||||
sidebarbtncolor = #3c6e83
|
||||
sidebartextcolor = #ffffff
|
||||
sidebarlinkcolor = #98dbcc
|
||||
relbarbgcolor = #133f52
|
||||
|
||||
@@ -292,7 +292,7 @@ li {
|
||||
line-height: 1.3;
|
||||
}
|
||||
|
||||
div.content li {
|
||||
div.content ul > li {
|
||||
-moz-background-clip:border;
|
||||
-moz-background-inline-policy:continuous;
|
||||
-moz-background-origin:padding;
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
r"""
|
||||
This is based on SmartyPants.py by `Chad Miller`_.
|
||||
This is based on SmartyPants.py by `Chad Miller`_ <smartypantspy@chad.org>,
|
||||
version 1.5_1.6.
|
||||
|
||||
Copyright and License
|
||||
=====================
|
||||
@@ -75,8 +76,8 @@ import re
|
||||
|
||||
def sphinx_smarty_pants(t):
|
||||
t = t.replace('"', '"')
|
||||
t = educateDashesOldSchool(t)
|
||||
t = educateQuotes(t)
|
||||
t = educate_dashes_oldschool(t)
|
||||
t = educate_quotes(t)
|
||||
t = t.replace('"', '"')
|
||||
return t
|
||||
|
||||
@@ -152,7 +153,7 @@ closing_single_quotes_regex_2 = re.compile(r"""
|
||||
(\s | s\b)
|
||||
""" % (close_class,), re.VERBOSE)
|
||||
|
||||
def educateQuotes(s):
|
||||
def educate_quotes(s):
|
||||
"""
|
||||
Parameter: String.
|
||||
|
||||
@@ -191,7 +192,7 @@ def educateQuotes(s):
|
||||
return s.replace('"', "“")
|
||||
|
||||
|
||||
def educateQuotesLatex(s, dquotes=("``", "''")):
|
||||
def educate_quotes_latex(s, dquotes=("``", "''")):
|
||||
"""
|
||||
Parameter: String.
|
||||
|
||||
@@ -234,7 +235,7 @@ def educateQuotesLatex(s, dquotes=("``", "''")):
|
||||
replace("\x03", "`").replace("\x04", "'")
|
||||
|
||||
|
||||
def educateBackticks(s):
|
||||
def educate_backticks(s):
|
||||
"""
|
||||
Parameter: String.
|
||||
Returns: The string, with ``backticks'' -style double quotes
|
||||
@@ -245,7 +246,7 @@ def educateBackticks(s):
|
||||
return s.replace("``", "“").replace("''", "”")
|
||||
|
||||
|
||||
def educateSingleBackticks(s):
|
||||
def educate_single_backticks(s):
|
||||
"""
|
||||
Parameter: String.
|
||||
Returns: The string, with `backticks' -style single quotes
|
||||
@@ -257,7 +258,7 @@ def educateSingleBackticks(s):
|
||||
return s.replace('`', "‘").replace("'", "’")
|
||||
|
||||
|
||||
def educateDashesOldSchool(s):
|
||||
def educate_dashes_oldschool(s):
|
||||
"""
|
||||
Parameter: String.
|
||||
|
||||
@@ -268,7 +269,7 @@ def educateDashesOldSchool(s):
|
||||
return s.replace('---', "—").replace('--', "–")
|
||||
|
||||
|
||||
def educateDashesOldSchoolInverted(s):
|
||||
def educate_dashes_oldschool_inverted(s):
|
||||
"""
|
||||
Parameter: String.
|
||||
|
||||
@@ -276,7 +277,7 @@ def educateDashesOldSchoolInverted(s):
|
||||
an em-dash HTML entity, and each "---" translated to
|
||||
an en-dash HTML entity. Two reasons why: First, unlike the
|
||||
en- and em-dash syntax supported by
|
||||
EducateDashesOldSchool(), it's compatible with existing
|
||||
educate_dashes_oldschool(), it's compatible with existing
|
||||
entries written before SmartyPants 1.1, back when "--" was
|
||||
only used for em-dashes. Second, em-dashes are more
|
||||
common than en-dashes, and so it sort of makes sense that
|
||||
@@ -286,8 +287,7 @@ def educateDashesOldSchoolInverted(s):
|
||||
return s.replace('---', "–").replace('--', "—")
|
||||
|
||||
|
||||
|
||||
def educateEllipses(s):
|
||||
def educate_ellipses(s):
|
||||
"""
|
||||
Parameter: String.
|
||||
Returns: The string, with each instance of "..." translated to
|
||||
@@ -297,11 +297,3 @@ def educateEllipses(s):
|
||||
Example output: Huh…?
|
||||
"""
|
||||
return s.replace('...', "…").replace('. . .', "…")
|
||||
|
||||
|
||||
__author__ = "Chad Miller <smartypantspy@chad.org>"
|
||||
__version__ = "1.5_1.5: Sat, 13 Aug 2005 15:50:24 -0400"
|
||||
__url__ = "http://wiki.chad.org/SmartyPantsPy"
|
||||
__description__ = \
|
||||
"Smart-quotes, smart-ellipses, and smart-dashes for weblog entries" \
|
||||
" in pyblosxom"
|
||||
|
||||
@@ -159,7 +159,7 @@ class HTMLTranslator(BaseTranslator):
|
||||
# overwritten
|
||||
def visit_reference(self, node):
|
||||
atts = {'class': 'reference'}
|
||||
if node.get('internal'):
|
||||
if node.get('internal') or 'refuri' not in node:
|
||||
atts['class'] += ' internal'
|
||||
else:
|
||||
atts['class'] += ' external'
|
||||
|
||||
@@ -24,8 +24,9 @@ from sphinx import highlighting
|
||||
from sphinx.errors import SphinxError
|
||||
from sphinx.locale import admonitionlabels, versionlabels, _
|
||||
from sphinx.util.osutil import ustrftime
|
||||
from sphinx.util.pycompat import any
|
||||
from sphinx.util.texescape import tex_escape_map, tex_replace_map
|
||||
from sphinx.util.smartypants import educateQuotesLatex
|
||||
from sphinx.util.smartypants import educate_quotes_latex
|
||||
|
||||
HEADER = r'''%% Generated by Sphinx.
|
||||
\def\sphinxdocclass{%(docclass)s}
|
||||
@@ -614,7 +615,7 @@ class LaTeXTranslator(nodes.NodeVisitor):
|
||||
self.body = self._body
|
||||
if not self.table.longtable and self.table.caption is not None:
|
||||
self.body.append(u'\n\\begin{threeparttable}\n'
|
||||
u'\\caption{%s}\n' % self.table.caption)
|
||||
u'\\capstart\\caption{%s}\n' % self.table.caption)
|
||||
if self.table.longtable:
|
||||
self.body.append('\n\\begin{longtable}')
|
||||
elif self.table.has_verbatim:
|
||||
@@ -634,7 +635,7 @@ class LaTeXTranslator(nodes.NodeVisitor):
|
||||
else:
|
||||
self.body.append('{|' + ('L|' * self.table.colcount) + '}\n')
|
||||
if self.table.longtable and self.table.caption is not None:
|
||||
self.body.append(u'\\caption{%s} \\\\\n' % self.table.caption)
|
||||
self.body.append(u'\\capstart\\caption{%s} \\\\\n' % self.table.caption)
|
||||
if self.table.caption is not None:
|
||||
for id in self.next_table_ids:
|
||||
self.body.append(self.hypertarget(id, anchor=False))
|
||||
@@ -912,6 +913,8 @@ class LaTeXTranslator(nodes.NodeVisitor):
|
||||
align = '\\begin{flush%s}' % node.attributes['align']
|
||||
align_end = '\\end{flush%s}' % node.attributes['align']
|
||||
self.body.append('\\begin{figure}[htbp]%s\n' % align)
|
||||
if any(isinstance(child, nodes.caption) for child in node):
|
||||
self.body.append('\\capstart\n')
|
||||
self.context.append(ids + align_end + '\\end{figure}\n')
|
||||
def depart_figure(self, node):
|
||||
self.body.append(self.context.pop())
|
||||
@@ -1396,7 +1399,7 @@ class LaTeXTranslator(nodes.NodeVisitor):
|
||||
self.verbatim += node.astext()
|
||||
else:
|
||||
text = self.encode(node.astext())
|
||||
self.body.append(educateQuotesLatex(text))
|
||||
self.body.append(educate_quotes_latex(text))
|
||||
def depart_Text(self, node):
|
||||
pass
|
||||
|
||||
|
||||
Reference in New Issue
Block a user