first commit
This commit is contained in:
commit
417e54da96
5696 changed files with 900003 additions and 0 deletions
|
@ -0,0 +1,159 @@
|
|||
# $Id: __init__.py 9368 2023-04-28 21:26:36Z milde $
|
||||
# Author: David Goodger <goodger@python.org>
|
||||
# Copyright: This module has been placed in the public domain.
|
||||
|
||||
"""
|
||||
This package contains Docutils Writer modules.
|
||||
"""
|
||||
|
||||
__docformat__ = 'reStructuredText'
|
||||
|
||||
from importlib import import_module
|
||||
|
||||
import docutils
|
||||
from docutils import languages, Component
|
||||
from docutils.transforms import universal
|
||||
|
||||
|
||||
class Writer(Component):
|
||||
|
||||
"""
|
||||
Abstract base class for docutils Writers.
|
||||
|
||||
Each writer module or package must export a subclass also called 'Writer'.
|
||||
Each writer must support all standard node types listed in
|
||||
`docutils.nodes.node_class_names`.
|
||||
|
||||
The `write()` method is the main entry point.
|
||||
"""
|
||||
|
||||
component_type = 'writer'
|
||||
config_section = 'writers'
|
||||
|
||||
def get_transforms(self):
|
||||
return super().get_transforms() + [universal.Messages,
|
||||
universal.FilterMessages,
|
||||
universal.StripClassesAndElements]
|
||||
|
||||
document = None
|
||||
"""The document to write (Docutils doctree); set by `write()`."""
|
||||
|
||||
output = None
|
||||
"""Final translated form of `document`
|
||||
|
||||
(`str` for text, `bytes` for binary formats); set by `translate()`.
|
||||
"""
|
||||
|
||||
language = None
|
||||
"""Language module for the document; set by `write()`."""
|
||||
|
||||
destination = None
|
||||
"""`docutils.io` Output object; where to write the document.
|
||||
|
||||
Set by `write()`.
|
||||
"""
|
||||
|
||||
def __init__(self):
|
||||
|
||||
self.parts = {}
|
||||
"""Mapping of document part names to fragments of `self.output`.
|
||||
|
||||
See `Writer.assemble_parts()` below and
|
||||
<https://docutils.sourceforge.io/docs/api/publisher.html>.
|
||||
"""
|
||||
|
||||
def write(self, document, destination):
|
||||
"""
|
||||
Process a document into its final form.
|
||||
|
||||
Translate `document` (a Docutils document tree) into the Writer's
|
||||
native format, and write it out to its `destination` (a
|
||||
`docutils.io.Output` subclass object).
|
||||
|
||||
Normally not overridden or extended in subclasses.
|
||||
"""
|
||||
self.document = document
|
||||
self.language = languages.get_language(
|
||||
document.settings.language_code,
|
||||
document.reporter)
|
||||
self.destination = destination
|
||||
self.translate()
|
||||
return self.destination.write(self.output)
|
||||
|
||||
def translate(self):
|
||||
"""
|
||||
Do final translation of `self.document` into `self.output`. Called
|
||||
from `write`. Override in subclasses.
|
||||
|
||||
Usually done with a `docutils.nodes.NodeVisitor` subclass, in
|
||||
combination with a call to `docutils.nodes.Node.walk()` or
|
||||
`docutils.nodes.Node.walkabout()`. The ``NodeVisitor`` subclass must
|
||||
support all standard elements (listed in
|
||||
`docutils.nodes.node_class_names`) and possibly non-standard elements
|
||||
used by the current Reader as well.
|
||||
"""
|
||||
raise NotImplementedError('subclass must override this method')
|
||||
|
||||
def assemble_parts(self):
|
||||
"""Assemble the `self.parts` dictionary. Extend in subclasses.
|
||||
|
||||
See <https://docutils.sourceforge.io/docs/api/publisher.html>.
|
||||
"""
|
||||
self.parts['whole'] = self.output
|
||||
self.parts['encoding'] = self.document.settings.output_encoding
|
||||
self.parts['errors'] = (
|
||||
self.document.settings.output_encoding_error_handler)
|
||||
self.parts['version'] = docutils.__version__
|
||||
|
||||
|
||||
class UnfilteredWriter(Writer):
|
||||
|
||||
"""
|
||||
A writer that passes the document tree on unchanged (e.g. a
|
||||
serializer.)
|
||||
|
||||
Documents written by UnfilteredWriters are typically reused at a
|
||||
later date using a subclass of `readers.ReReader`.
|
||||
"""
|
||||
|
||||
def get_transforms(self):
|
||||
# Do not add any transforms. When the document is reused
|
||||
# later, the then-used writer will add the appropriate
|
||||
# transforms.
|
||||
return Component.get_transforms(self)
|
||||
|
||||
|
||||
_writer_aliases = {
|
||||
'html': 'html4css1', # may change to html5 some day
|
||||
'html4': 'html4css1',
|
||||
'xhtml10': 'html4css1',
|
||||
'html5': 'html5_polyglot',
|
||||
'xhtml': 'html5_polyglot',
|
||||
's5': 's5_html',
|
||||
'latex': 'latex2e',
|
||||
'xelatex': 'xetex',
|
||||
'luatex': 'xetex',
|
||||
'lualatex': 'xetex',
|
||||
'odf': 'odf_odt',
|
||||
'odt': 'odf_odt',
|
||||
'ooffice': 'odf_odt',
|
||||
'openoffice': 'odf_odt',
|
||||
'libreoffice': 'odf_odt',
|
||||
'pprint': 'pseudoxml',
|
||||
'pformat': 'pseudoxml',
|
||||
'pdf': 'rlpdf',
|
||||
'xml': 'docutils_xml'}
|
||||
|
||||
|
||||
def get_writer_class(writer_name):
|
||||
"""Return the Writer class from the `writer_name` module."""
|
||||
name = writer_name.lower()
|
||||
name = _writer_aliases.get(name, name)
|
||||
try:
|
||||
module = import_module('docutils.writers.'+name)
|
||||
except ImportError:
|
||||
try:
|
||||
module = import_module(name)
|
||||
except ImportError as err:
|
||||
raise ImportError(f'Writer "{writer_name}" not found. {err}')
|
||||
return module.Writer
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
File diff suppressed because it is too large
Load diff
|
@ -0,0 +1,187 @@
|
|||
# $Id: docutils_xml.py 9502 2023-12-14 22:39:08Z milde $
|
||||
# Author: David Goodger, Paul Tremblay, Guenter Milde
|
||||
# Maintainer: docutils-develop@lists.sourceforge.net
|
||||
# Copyright: This module has been placed in the public domain.
|
||||
|
||||
"""
|
||||
Simple document tree Writer, writes Docutils XML according to
|
||||
https://docutils.sourceforge.io/docs/ref/docutils.dtd.
|
||||
"""
|
||||
|
||||
__docformat__ = 'reStructuredText'
|
||||
|
||||
from io import StringIO
|
||||
import xml.sax.saxutils
|
||||
|
||||
import docutils
|
||||
from docutils import frontend, nodes, writers, utils
|
||||
|
||||
|
||||
class RawXmlError(docutils.ApplicationError):
|
||||
pass
|
||||
|
||||
|
||||
class Writer(writers.Writer):
|
||||
|
||||
supported = ('xml',)
|
||||
"""Formats this writer supports."""
|
||||
|
||||
settings_spec = (
|
||||
'"Docutils XML" Writer Options',
|
||||
None,
|
||||
(('Generate XML with newlines before and after tags.',
|
||||
['--newlines'],
|
||||
{'action': 'store_true', 'validator': frontend.validate_boolean}),
|
||||
('Generate XML with indents and newlines.',
|
||||
['--indents'], # TODO use integer value for number of spaces?
|
||||
{'action': 'store_true', 'validator': frontend.validate_boolean}),
|
||||
('Omit the XML declaration. Use with caution.',
|
||||
['--no-xml-declaration'],
|
||||
{'dest': 'xml_declaration', 'default': 1, 'action': 'store_false',
|
||||
'validator': frontend.validate_boolean}),
|
||||
('Omit the DOCTYPE declaration.',
|
||||
['--no-doctype'],
|
||||
{'dest': 'doctype_declaration', 'default': 1,
|
||||
'action': 'store_false', 'validator': frontend.validate_boolean}),))
|
||||
|
||||
settings_defaults = {'output_encoding_error_handler': 'xmlcharrefreplace'}
|
||||
|
||||
config_section = 'docutils_xml writer'
|
||||
config_section_dependencies = ('writers',)
|
||||
|
||||
output = None
|
||||
"""Final translated form of `document`."""
|
||||
|
||||
def __init__(self):
|
||||
writers.Writer.__init__(self)
|
||||
self.translator_class = XMLTranslator
|
||||
|
||||
def translate(self):
|
||||
self.visitor = visitor = self.translator_class(self.document)
|
||||
self.document.walkabout(visitor)
|
||||
self.output = ''.join(visitor.output)
|
||||
|
||||
|
||||
class XMLTranslator(nodes.GenericNodeVisitor):
|
||||
|
||||
# TODO: add stylesheet options similar to HTML and LaTeX writers?
|
||||
# xml_stylesheet = '<?xml-stylesheet type="text/xsl" href="%s"?>\n'
|
||||
doctype = (
|
||||
'<!DOCTYPE document PUBLIC'
|
||||
' "+//IDN docutils.sourceforge.net//DTD Docutils Generic//EN//XML"'
|
||||
' "http://docutils.sourceforge.net/docs/ref/docutils.dtd">\n')
|
||||
generator = '<!-- Generated by Docutils %s -->\n'
|
||||
|
||||
xmlparser = xml.sax.make_parser()
|
||||
"""SAX parser instance to check/extract raw XML."""
|
||||
xmlparser.setFeature(
|
||||
"http://xml.org/sax/features/external-general-entities", True)
|
||||
|
||||
def __init__(self, document):
|
||||
nodes.NodeVisitor.__init__(self, document)
|
||||
|
||||
# Reporter
|
||||
self.warn = self.document.reporter.warning
|
||||
self.error = self.document.reporter.error
|
||||
|
||||
# Settings
|
||||
self.settings = settings = document.settings
|
||||
self.indent = self.newline = ''
|
||||
if settings.newlines:
|
||||
self.newline = '\n'
|
||||
if settings.indents:
|
||||
self.newline = '\n'
|
||||
self.indent = ' ' # TODO make this configurable?
|
||||
self.level = 0 # indentation level
|
||||
self.in_simple = 0 # level of nesting inside mixed-content elements
|
||||
self.fixed_text = 0 # level of nesting inside FixedText elements
|
||||
|
||||
# Output
|
||||
self.output = []
|
||||
if settings.xml_declaration:
|
||||
self.output.append(utils.xml_declaration(settings.output_encoding))
|
||||
if settings.doctype_declaration:
|
||||
self.output.append(self.doctype)
|
||||
self.output.append(self.generator % docutils.__version__)
|
||||
|
||||
# initialize XML parser
|
||||
self.the_handle = TestXml()
|
||||
self.xmlparser.setContentHandler(self.the_handle)
|
||||
|
||||
# generic visit and depart methods
|
||||
# --------------------------------
|
||||
|
||||
simple_nodes = (nodes.TextElement, nodes.meta,
|
||||
nodes.image, nodes.colspec, nodes.transition)
|
||||
|
||||
def default_visit(self, node):
|
||||
"""Default node visit method."""
|
||||
if not self.in_simple:
|
||||
self.output.append(self.indent*self.level)
|
||||
self.output.append(node.starttag(xml.sax.saxutils.quoteattr))
|
||||
self.level += 1
|
||||
# `nodes.literal` is not an instance of FixedTextElement by design,
|
||||
# see docs/ref/rst/restructuredtext.html#inline-literals
|
||||
if isinstance(node, (nodes.FixedTextElement, nodes.literal)):
|
||||
self.fixed_text += 1
|
||||
if isinstance(node, self.simple_nodes):
|
||||
self.in_simple += 1
|
||||
if not self.in_simple:
|
||||
self.output.append(self.newline)
|
||||
|
||||
def default_departure(self, node):
|
||||
"""Default node depart method."""
|
||||
self.level -= 1
|
||||
if not self.in_simple:
|
||||
self.output.append(self.indent*self.level)
|
||||
self.output.append(node.endtag())
|
||||
if isinstance(node, (nodes.FixedTextElement, nodes.literal)):
|
||||
self.fixed_text -= 1
|
||||
if isinstance(node, self.simple_nodes):
|
||||
self.in_simple -= 1
|
||||
if not self.in_simple:
|
||||
self.output.append(self.newline)
|
||||
|
||||
# specific visit and depart methods
|
||||
# ---------------------------------
|
||||
|
||||
def visit_Text(self, node):
|
||||
text = xml.sax.saxutils.escape(node.astext())
|
||||
# indent text if we are not in a FixedText element:
|
||||
if not self.fixed_text:
|
||||
text = text.replace('\n', '\n'+self.indent*self.level)
|
||||
self.output.append(text)
|
||||
|
||||
def depart_Text(self, node):
|
||||
pass
|
||||
|
||||
def visit_raw(self, node):
|
||||
if 'xml' not in node.get('format', '').split():
|
||||
# skip other raw content?
|
||||
# raise nodes.SkipNode
|
||||
self.default_visit(node)
|
||||
return
|
||||
# wrap in <raw> element
|
||||
self.default_visit(node) # or not?
|
||||
xml_string = node.astext()
|
||||
self.output.append(xml_string)
|
||||
self.default_departure(node) # or not?
|
||||
# Check validity of raw XML:
|
||||
try:
|
||||
self.xmlparser.parse(StringIO(xml_string))
|
||||
except xml.sax._exceptions.SAXParseException:
|
||||
col_num = self.the_handle.locator.getColumnNumber()
|
||||
line_num = self.the_handle.locator.getLineNumber()
|
||||
srcline = node.line
|
||||
if not isinstance(node.parent, nodes.TextElement):
|
||||
srcline += 2 # directive content start line
|
||||
msg = 'Invalid raw XML in column %d, line offset %d:\n%s' % (
|
||||
col_num, line_num, node.astext())
|
||||
self.warn(msg, source=node.source, line=srcline+line_num-1)
|
||||
raise nodes.SkipNode # content already processed
|
||||
|
||||
|
||||
class TestXml(xml.sax.handler.ContentHandler):
|
||||
|
||||
def setDocumentLocator(self, locator):
|
||||
self.locator = locator
|
|
@ -0,0 +1,955 @@
|
|||
# $Id: __init__.py 9558 2024-03-11 17:48:52Z milde $
|
||||
# Author: David Goodger
|
||||
# Maintainer: docutils-develop@lists.sourceforge.net
|
||||
# Copyright: This module has been placed in the public domain.
|
||||
|
||||
"""
|
||||
Simple HyperText Markup Language document tree Writer.
|
||||
|
||||
The output conforms to the XHTML version 1.0 Transitional DTD
|
||||
(*almost* strict). The output contains a minimum of formatting
|
||||
information. The cascading style sheet "html4css1.css" is required
|
||||
for proper viewing with a modern graphical browser.
|
||||
"""
|
||||
|
||||
__docformat__ = 'reStructuredText'
|
||||
|
||||
import os.path
|
||||
import re
|
||||
|
||||
from docutils import frontend, nodes, writers
|
||||
from docutils.writers import _html_base
|
||||
from docutils.writers._html_base import PIL
|
||||
|
||||
|
||||
class Writer(writers._html_base.Writer):
|
||||
|
||||
supported = ('html', 'html4', 'html4css1', 'xhtml', 'xhtml10')
|
||||
"""Formats this writer supports."""
|
||||
|
||||
default_stylesheets = ['html4css1.css']
|
||||
default_stylesheet_dirs = ['.',
|
||||
os.path.abspath(os.path.dirname(__file__)),
|
||||
os.path.abspath(os.path.join(
|
||||
os.path.dirname(os.path.dirname(__file__)),
|
||||
'html5_polyglot')) # for math.css
|
||||
]
|
||||
default_template = os.path.join(
|
||||
os.path.dirname(os.path.abspath(__file__)), 'template.txt')
|
||||
|
||||
# use a copy of the parent spec with some modifications
|
||||
settings_spec = frontend.filter_settings_spec(
|
||||
writers._html_base.Writer.settings_spec,
|
||||
template=(
|
||||
'Template file. (UTF-8 encoded, default: "%s")' % default_template,
|
||||
['--template'],
|
||||
{'default': default_template, 'metavar': '<file>'}),
|
||||
stylesheet_path=(
|
||||
'Comma separated list of stylesheet paths. '
|
||||
'Relative paths are expanded if a matching file is found in '
|
||||
'the --stylesheet-dirs. With --link-stylesheet, '
|
||||
'the path is rewritten relative to the output HTML file. '
|
||||
'(default: "%s")' % ','.join(default_stylesheets),
|
||||
['--stylesheet-path'],
|
||||
{'metavar': '<file[,file,...]>', 'overrides': 'stylesheet',
|
||||
'validator': frontend.validate_comma_separated_list,
|
||||
'default': default_stylesheets}),
|
||||
stylesheet_dirs=(
|
||||
'Comma-separated list of directories where stylesheets are found. '
|
||||
'Used by --stylesheet-path when expanding relative path '
|
||||
'arguments. (default: "%s")' % ','.join(default_stylesheet_dirs),
|
||||
['--stylesheet-dirs'],
|
||||
{'metavar': '<dir[,dir,...]>',
|
||||
'validator': frontend.validate_comma_separated_list,
|
||||
'default': default_stylesheet_dirs}),
|
||||
initial_header_level=(
|
||||
'Specify the initial header level. Does not affect document '
|
||||
'title & subtitle (see --no-doc-title). (default: 1 for "<h1>")',
|
||||
['--initial-header-level'],
|
||||
{'choices': '1 2 3 4 5 6'.split(), 'default': '1',
|
||||
'metavar': '<level>'}),
|
||||
xml_declaration=(
|
||||
'Prepend an XML declaration (default). ',
|
||||
['--xml-declaration'],
|
||||
{'default': True, 'action': 'store_true',
|
||||
'validator': frontend.validate_boolean}),
|
||||
)
|
||||
settings_spec = settings_spec + (
|
||||
'HTML4 Writer Options',
|
||||
'',
|
||||
(('Specify the maximum width (in characters) for one-column field '
|
||||
'names. Longer field names will span an entire row of the table '
|
||||
'used to render the field list. Default is 14 characters. '
|
||||
'Use 0 for "no limit".',
|
||||
['--field-name-limit'],
|
||||
{'default': 14, 'metavar': '<level>',
|
||||
'validator': frontend.validate_nonnegative_int}),
|
||||
('Specify the maximum width (in characters) for options in option '
|
||||
'lists. Longer options will span an entire row of the table used '
|
||||
'to render the option list. Default is 14 characters. '
|
||||
'Use 0 for "no limit".',
|
||||
['--option-limit'],
|
||||
{'default': 14, 'metavar': '<level>',
|
||||
'validator': frontend.validate_nonnegative_int}),
|
||||
)
|
||||
)
|
||||
|
||||
config_section = 'html4css1 writer'
|
||||
|
||||
def __init__(self):
|
||||
self.parts = {}
|
||||
self.translator_class = HTMLTranslator
|
||||
|
||||
|
||||
class HTMLTranslator(writers._html_base.HTMLTranslator):
|
||||
"""
|
||||
The html4css1 writer has been optimized to produce visually compact
|
||||
lists (less vertical whitespace). HTML's mixed content models
|
||||
allow list items to contain "<li><p>body elements</p></li>" or
|
||||
"<li>just text</li>" or even "<li>text<p>and body
|
||||
elements</p>combined</li>", each with different effects. It would
|
||||
be best to stick with strict body elements in list items, but they
|
||||
affect vertical spacing in older browsers (although they really
|
||||
shouldn't).
|
||||
The html5_polyglot writer solves this using CSS2.
|
||||
|
||||
Here is an outline of the optimization:
|
||||
|
||||
- Check for and omit <p> tags in "simple" lists: list items
|
||||
contain either a single paragraph, a nested simple list, or a
|
||||
paragraph followed by a nested simple list. This means that
|
||||
this list can be compact:
|
||||
|
||||
- Item 1.
|
||||
- Item 2.
|
||||
|
||||
But this list cannot be compact:
|
||||
|
||||
- Item 1.
|
||||
|
||||
This second paragraph forces space between list items.
|
||||
|
||||
- Item 2.
|
||||
|
||||
- In non-list contexts, omit <p> tags on a paragraph if that
|
||||
paragraph is the only child of its parent (footnotes & citations
|
||||
are allowed a label first).
|
||||
|
||||
- Regardless of the above, in definitions, table cells, field bodies,
|
||||
option descriptions, and list items, mark the first child with
|
||||
'class="first"' and the last child with 'class="last"'. The stylesheet
|
||||
sets the margins (top & bottom respectively) to 0 for these elements.
|
||||
|
||||
The ``no_compact_lists`` setting (``--no-compact-lists`` command-line
|
||||
option) disables list whitespace optimization.
|
||||
"""
|
||||
|
||||
# The following definitions are required for display in browsers limited
|
||||
# to CSS1 or backwards compatible behaviour of the writer:
|
||||
|
||||
doctype = (
|
||||
'<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"'
|
||||
' "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">\n')
|
||||
|
||||
content_type = ('<meta http-equiv="Content-Type"'
|
||||
' content="text/html; charset=%s" />\n')
|
||||
content_type_mathml = ('<meta http-equiv="Content-Type"'
|
||||
' content="application/xhtml+xml; charset=%s" />\n')
|
||||
|
||||
# encode also non-breaking space
|
||||
special_characters = _html_base.HTMLTranslator.special_characters.copy()
|
||||
special_characters[0xa0] = ' '
|
||||
|
||||
# use character reference for dash (not valid in HTML5)
|
||||
attribution_formats = {'dash': ('—', ''),
|
||||
'parentheses': ('(', ')'),
|
||||
'parens': ('(', ')'),
|
||||
'none': ('', '')}
|
||||
|
||||
# ersatz for first/last pseudo-classes missing in CSS1
|
||||
def set_first_last(self, node):
|
||||
self.set_class_on_child(node, 'first', 0)
|
||||
self.set_class_on_child(node, 'last', -1)
|
||||
|
||||
# add newline after opening tag
|
||||
def visit_address(self, node):
|
||||
self.visit_docinfo_item(node, 'address', meta=False)
|
||||
self.body.append(self.starttag(node, 'pre', CLASS='address'))
|
||||
|
||||
def depart_address(self, node):
|
||||
self.body.append('\n</pre>\n')
|
||||
self.depart_docinfo_item()
|
||||
|
||||
# ersatz for first/last pseudo-classes
|
||||
def visit_admonition(self, node):
|
||||
node['classes'].insert(0, 'admonition')
|
||||
self.body.append(self.starttag(node, 'div'))
|
||||
self.set_first_last(node)
|
||||
|
||||
def depart_admonition(self, node=None):
|
||||
self.body.append('</div>\n')
|
||||
|
||||
# author, authors: use <br> instead of paragraphs
|
||||
def visit_author(self, node):
|
||||
if isinstance(node.parent, nodes.authors):
|
||||
if self.author_in_authors:
|
||||
self.body.append('\n<br />')
|
||||
else:
|
||||
self.visit_docinfo_item(node, 'author')
|
||||
|
||||
def depart_author(self, node):
|
||||
if isinstance(node.parent, nodes.authors):
|
||||
self.author_in_authors = True
|
||||
else:
|
||||
self.depart_docinfo_item()
|
||||
|
||||
def visit_authors(self, node):
|
||||
self.visit_docinfo_item(node, 'authors')
|
||||
self.author_in_authors = False # initialize
|
||||
|
||||
def depart_authors(self, node):
|
||||
self.depart_docinfo_item()
|
||||
|
||||
# use "width" argument instead of "style: 'width'":
|
||||
def visit_colspec(self, node):
|
||||
self.colspecs.append(node)
|
||||
# "stubs" list is an attribute of the tgroup element:
|
||||
node.parent.stubs.append(node.attributes.get('stub'))
|
||||
|
||||
def depart_colspec(self, node):
|
||||
# write out <colgroup> when all colspecs are processed
|
||||
if isinstance(node.next_node(descend=False, siblings=True),
|
||||
nodes.colspec):
|
||||
return
|
||||
if ('colwidths-auto' in node.parent.parent['classes']
|
||||
or ('colwidths-auto' in self.settings.table_style
|
||||
and 'colwidths-given' not in node.parent.parent['classes'])):
|
||||
return
|
||||
total_width = sum(node['colwidth'] for node in self.colspecs)
|
||||
self.body.append(self.starttag(node, 'colgroup'))
|
||||
for node in self.colspecs:
|
||||
colwidth = int(node['colwidth'] * 100.0 / total_width + 0.5)
|
||||
self.body.append(self.emptytag(node, 'col',
|
||||
width='%i%%' % colwidth))
|
||||
self.body.append('</colgroup>\n')
|
||||
|
||||
# Compact lists:
|
||||
# exclude definition lists and field lists (non-compact by default)
|
||||
|
||||
def is_compactable(self, node):
|
||||
return ('compact' in node['classes']
|
||||
or (self.settings.compact_lists
|
||||
and 'open' not in node['classes']
|
||||
and (self.compact_simple
|
||||
or 'contents' in node.parent['classes']
|
||||
# TODO: self.in_contents
|
||||
or self.check_simple_list(node))))
|
||||
|
||||
# citations: Use table for bibliographic references.
|
||||
def visit_citation(self, node):
|
||||
self.body.append(self.starttag(node, 'table',
|
||||
CLASS='docutils citation',
|
||||
frame="void", rules="none"))
|
||||
self.body.append('<colgroup><col class="label" /><col /></colgroup>\n'
|
||||
'<tbody valign="top">\n'
|
||||
'<tr>')
|
||||
self.footnote_backrefs(node)
|
||||
|
||||
def depart_citation(self, node):
|
||||
self.body.append('</td></tr>\n'
|
||||
'</tbody>\n</table>\n')
|
||||
|
||||
def visit_citation_reference(self, node):
|
||||
href = '#'
|
||||
if 'refid' in node:
|
||||
href += node['refid']
|
||||
elif 'refname' in node:
|
||||
href += self.document.nameids[node['refname']]
|
||||
self.body.append(self.starttag(node, 'a', suffix='[', href=href,
|
||||
classes=['citation-reference']))
|
||||
|
||||
def depart_citation_reference(self, node):
|
||||
self.body.append(']</a>')
|
||||
|
||||
# insert classifier-delimiter (not required with CSS2)
|
||||
def visit_classifier(self, node):
|
||||
self.body.append(' <span class="classifier-delimiter">:</span> ')
|
||||
self.body.append(self.starttag(node, 'span', '', CLASS='classifier'))
|
||||
|
||||
def depart_classifier(self, node):
|
||||
self.body.append('</span>')
|
||||
self.depart_term(node) # close the <dt> after last classifier
|
||||
|
||||
# ersatz for first/last pseudo-classes
|
||||
def visit_compound(self, node):
|
||||
self.body.append(self.starttag(node, 'div', CLASS='compound'))
|
||||
if len(node) > 1:
|
||||
node[0]['classes'].append('compound-first')
|
||||
node[-1]['classes'].append('compound-last')
|
||||
for child in node[1:-1]:
|
||||
child['classes'].append('compound-middle')
|
||||
|
||||
def depart_compound(self, node):
|
||||
self.body.append('</div>\n')
|
||||
|
||||
# ersatz for first/last pseudo-classes, no special handling of "details"
|
||||
def visit_definition(self, node):
|
||||
self.body.append(self.starttag(node, 'dd', ''))
|
||||
self.set_first_last(node)
|
||||
|
||||
def depart_definition(self, node):
|
||||
self.body.append('</dd>\n')
|
||||
|
||||
# don't add "simple" class value, no special handling of "details"
|
||||
def visit_definition_list(self, node):
|
||||
self.body.append(self.starttag(node, 'dl', CLASS='docutils'))
|
||||
|
||||
def depart_definition_list(self, node):
|
||||
self.body.append('</dl>\n')
|
||||
|
||||
# no special handling of "details"
|
||||
def visit_definition_list_item(self, node):
|
||||
pass
|
||||
|
||||
def depart_definition_list_item(self, node):
|
||||
pass
|
||||
|
||||
# use a table for description lists
|
||||
def visit_description(self, node):
|
||||
self.body.append(self.starttag(node, 'td', ''))
|
||||
self.set_first_last(node)
|
||||
|
||||
def depart_description(self, node):
|
||||
self.body.append('</td>')
|
||||
|
||||
# use table for docinfo
|
||||
def visit_docinfo(self, node):
|
||||
self.context.append(len(self.body))
|
||||
self.body.append(self.starttag(node, 'table',
|
||||
CLASS='docinfo',
|
||||
frame="void", rules="none"))
|
||||
self.body.append('<col class="docinfo-name" />\n'
|
||||
'<col class="docinfo-content" />\n'
|
||||
'<tbody valign="top">\n')
|
||||
self.in_docinfo = True
|
||||
|
||||
def depart_docinfo(self, node):
|
||||
self.body.append('</tbody>\n</table>\n')
|
||||
self.in_docinfo = False
|
||||
start = self.context.pop()
|
||||
self.docinfo = self.body[start:]
|
||||
self.body = []
|
||||
|
||||
def visit_docinfo_item(self, node, name, meta=True):
|
||||
if meta:
|
||||
meta_tag = '<meta name="%s" content="%s" />\n' \
|
||||
% (name, self.attval(node.astext()))
|
||||
self.meta.append(meta_tag)
|
||||
self.body.append(self.starttag(node, 'tr', ''))
|
||||
self.body.append('<th class="docinfo-name">%s:</th>\n<td>'
|
||||
% self.language.labels[name])
|
||||
if len(node):
|
||||
if isinstance(node[0], nodes.Element):
|
||||
node[0]['classes'].append('first')
|
||||
if isinstance(node[-1], nodes.Element):
|
||||
node[-1]['classes'].append('last')
|
||||
|
||||
def depart_docinfo_item(self):
|
||||
self.body.append('</td></tr>\n')
|
||||
|
||||
# add newline after opening tag
|
||||
def visit_doctest_block(self, node):
|
||||
self.body.append(self.starttag(node, 'pre', CLASS='doctest-block'))
|
||||
|
||||
def depart_doctest_block(self, node):
|
||||
self.body.append('\n</pre>\n')
|
||||
|
||||
# insert an NBSP into empty cells, ersatz for first/last
|
||||
def visit_entry(self, node):
|
||||
writers._html_base.HTMLTranslator.visit_entry(self, node)
|
||||
if len(node) == 0: # empty cell
|
||||
self.body.append(' ')
|
||||
self.set_first_last(node)
|
||||
|
||||
def depart_entry(self, node):
|
||||
self.body.append(self.context.pop())
|
||||
|
||||
# ersatz for first/last pseudo-classes
|
||||
def visit_enumerated_list(self, node):
|
||||
"""
|
||||
The 'start' attribute does not conform to HTML 4.01's strict.dtd, but
|
||||
cannot be emulated in CSS1 (HTML 5 reincludes it).
|
||||
"""
|
||||
atts = {}
|
||||
if 'start' in node:
|
||||
atts['start'] = node['start']
|
||||
if 'enumtype' in node:
|
||||
atts['class'] = node['enumtype']
|
||||
# @@@ To do: prefix, suffix. How? Change prefix/suffix to a
|
||||
# single "format" attribute? Use CSS2?
|
||||
old_compact_simple = self.compact_simple
|
||||
self.context.append((self.compact_simple, self.compact_p))
|
||||
self.compact_p = None
|
||||
self.compact_simple = self.is_compactable(node)
|
||||
if self.compact_simple and not old_compact_simple:
|
||||
atts['class'] = (atts.get('class', '') + ' simple').strip()
|
||||
self.body.append(self.starttag(node, 'ol', **atts))
|
||||
|
||||
def depart_enumerated_list(self, node):
|
||||
self.compact_simple, self.compact_p = self.context.pop()
|
||||
self.body.append('</ol>\n')
|
||||
|
||||
# use table for field-list:
|
||||
def visit_field(self, node):
|
||||
self.body.append(self.starttag(node, 'tr', '', CLASS='field'))
|
||||
|
||||
def depart_field(self, node):
|
||||
self.body.append('</tr>\n')
|
||||
|
||||
def visit_field_body(self, node):
|
||||
self.body.append(self.starttag(node, 'td', '', CLASS='field-body'))
|
||||
self.set_class_on_child(node, 'first', 0)
|
||||
field = node.parent
|
||||
if (self.compact_field_list
|
||||
or isinstance(field.parent, nodes.docinfo)
|
||||
or field.parent.index(field) == len(field.parent) - 1):
|
||||
# If we are in a compact list, the docinfo, or if this is
|
||||
# the last field of the field list, do not add vertical
|
||||
# space after last element.
|
||||
self.set_class_on_child(node, 'last', -1)
|
||||
|
||||
def depart_field_body(self, node):
|
||||
self.body.append('</td>\n')
|
||||
|
||||
def visit_field_list(self, node):
|
||||
self.context.append((self.compact_field_list, self.compact_p))
|
||||
self.compact_p = None
|
||||
if 'compact' in node['classes']:
|
||||
self.compact_field_list = True
|
||||
elif (self.settings.compact_field_lists
|
||||
and 'open' not in node['classes']):
|
||||
self.compact_field_list = True
|
||||
if self.compact_field_list:
|
||||
for field in node:
|
||||
field_body = field[-1]
|
||||
assert isinstance(field_body, nodes.field_body)
|
||||
children = [n for n in field_body
|
||||
if not isinstance(n, nodes.Invisible)]
|
||||
if not (len(children) == 0
|
||||
or len(children) == 1
|
||||
and isinstance(children[0],
|
||||
(nodes.paragraph, nodes.line_block))):
|
||||
self.compact_field_list = False
|
||||
break
|
||||
self.body.append(self.starttag(node, 'table', frame='void',
|
||||
rules='none',
|
||||
CLASS='docutils field-list'))
|
||||
self.body.append('<col class="field-name" />\n'
|
||||
'<col class="field-body" />\n'
|
||||
'<tbody valign="top">\n')
|
||||
|
||||
def depart_field_list(self, node):
|
||||
self.body.append('</tbody>\n</table>\n')
|
||||
self.compact_field_list, self.compact_p = self.context.pop()
|
||||
|
||||
def visit_field_name(self, node):
|
||||
atts = {}
|
||||
if self.in_docinfo:
|
||||
atts['class'] = 'docinfo-name'
|
||||
else:
|
||||
atts['class'] = 'field-name'
|
||||
if (self.settings.field_name_limit
|
||||
and len(node.astext()) > self.settings.field_name_limit):
|
||||
atts['colspan'] = 2
|
||||
self.context.append('</tr>\n'
|
||||
+ self.starttag(node.parent, 'tr', '',
|
||||
CLASS='field')
|
||||
+ '<td> </td>')
|
||||
else:
|
||||
self.context.append('')
|
||||
self.body.append(self.starttag(node, 'th', '', **atts))
|
||||
|
||||
def depart_field_name(self, node):
|
||||
self.body.append(':</th>')
|
||||
self.body.append(self.context.pop())
|
||||
|
||||
# use table for footnote text
|
||||
def visit_footnote(self, node):
|
||||
self.body.append(self.starttag(node, 'table',
|
||||
CLASS='docutils footnote',
|
||||
frame="void", rules="none"))
|
||||
self.body.append('<colgroup><col class="label" /><col /></colgroup>\n'
|
||||
'<tbody valign="top">\n'
|
||||
'<tr>')
|
||||
self.footnote_backrefs(node)
|
||||
|
||||
def footnote_backrefs(self, node):
|
||||
backlinks = []
|
||||
backrefs = node['backrefs']
|
||||
if self.settings.footnote_backlinks and backrefs:
|
||||
if len(backrefs) == 1:
|
||||
self.context.append('')
|
||||
self.context.append('</a>')
|
||||
self.context.append('<a class="fn-backref" href="#%s">'
|
||||
% backrefs[0])
|
||||
else:
|
||||
for (i, backref) in enumerate(backrefs, 1):
|
||||
backlinks.append('<a class="fn-backref" href="#%s">%s</a>'
|
||||
% (backref, i))
|
||||
self.context.append('<em>(%s)</em> ' % ', '.join(backlinks))
|
||||
self.context += ['', '']
|
||||
else:
|
||||
self.context.append('')
|
||||
self.context += ['', '']
|
||||
# If the node does not only consist of a label.
|
||||
if len(node) > 1:
|
||||
# If there are preceding backlinks, we do not set class
|
||||
# 'first', because we need to retain the top-margin.
|
||||
if not backlinks:
|
||||
node[1]['classes'].append('first')
|
||||
node[-1]['classes'].append('last')
|
||||
|
||||
def depart_footnote(self, node):
|
||||
self.body.append('</td></tr>\n'
|
||||
'</tbody>\n</table>\n')
|
||||
|
||||
# insert markers in text (pseudo-classes are not supported in CSS1):
|
||||
def visit_footnote_reference(self, node):
|
||||
href = '#' + node['refid']
|
||||
format = self.settings.footnote_references
|
||||
if format == 'brackets':
|
||||
suffix = '['
|
||||
self.context.append(']')
|
||||
else:
|
||||
assert format == 'superscript'
|
||||
suffix = '<sup>'
|
||||
self.context.append('</sup>')
|
||||
self.body.append(self.starttag(node, 'a', suffix,
|
||||
CLASS='footnote-reference', href=href))
|
||||
|
||||
def depart_footnote_reference(self, node):
|
||||
self.body.append(self.context.pop() + '</a>')
|
||||
|
||||
# just pass on generated text
|
||||
def visit_generated(self, node):
|
||||
pass
|
||||
|
||||
# Backwards-compatibility implementation:
|
||||
# * Do not use <video>,
|
||||
# * don't embed images,
|
||||
# * use <object> instead of <img> for SVG.
|
||||
# (SVG not supported by IE up to version 8,
|
||||
# html4css1 strives for IE6 compatibility.)
|
||||
object_image_types = {'.svg': 'image/svg+xml',
|
||||
'.swf': 'application/x-shockwave-flash',
|
||||
'.mp4': 'video/mp4',
|
||||
'.webm': 'video/webm',
|
||||
'.ogg': 'video/ogg',
|
||||
}
|
||||
|
||||
def visit_image(self, node):
|
||||
atts = {}
|
||||
uri = node['uri']
|
||||
ext = os.path.splitext(uri)[1].lower()
|
||||
if ext in self.object_image_types:
|
||||
atts['data'] = uri
|
||||
atts['type'] = self.object_image_types[ext]
|
||||
else:
|
||||
atts['src'] = uri
|
||||
atts['alt'] = node.get('alt', uri)
|
||||
# image size
|
||||
if 'width' in node:
|
||||
atts['width'] = node['width']
|
||||
if 'height' in node:
|
||||
atts['height'] = node['height']
|
||||
if 'scale' in node:
|
||||
if (PIL and ('width' not in node or 'height' not in node)
|
||||
and self.settings.file_insertion_enabled):
|
||||
imagepath = self.uri2imagepath(uri)
|
||||
try:
|
||||
with PIL.Image.open(imagepath) as img:
|
||||
img_size = img.size
|
||||
except (OSError, UnicodeEncodeError):
|
||||
pass # TODO: warn/info?
|
||||
else:
|
||||
self.settings.record_dependencies.add(
|
||||
imagepath.replace('\\', '/'))
|
||||
if 'width' not in atts:
|
||||
atts['width'] = '%dpx' % img_size[0]
|
||||
if 'height' not in atts:
|
||||
atts['height'] = '%dpx' % img_size[1]
|
||||
for att_name in 'width', 'height':
|
||||
if att_name in atts:
|
||||
match = re.match(r'([0-9.]+)(\S*)$', atts[att_name])
|
||||
assert match
|
||||
atts[att_name] = '%s%s' % (
|
||||
float(match.group(1)) * (float(node['scale']) / 100),
|
||||
match.group(2))
|
||||
style = []
|
||||
for att_name in 'width', 'height':
|
||||
if att_name in atts:
|
||||
if re.match(r'^[0-9.]+$', atts[att_name]):
|
||||
# Interpret unitless values as pixels.
|
||||
atts[att_name] += 'px'
|
||||
style.append('%s: %s;' % (att_name, atts[att_name]))
|
||||
del atts[att_name]
|
||||
if style:
|
||||
atts['style'] = ' '.join(style)
|
||||
# No newlines around inline images.
|
||||
if (not isinstance(node.parent, nodes.TextElement)
|
||||
or isinstance(node.parent, nodes.reference)
|
||||
and not isinstance(node.parent.parent, nodes.TextElement)):
|
||||
suffix = '\n'
|
||||
else:
|
||||
suffix = ''
|
||||
if 'align' in node:
|
||||
atts['class'] = 'align-%s' % node['align']
|
||||
if ext in self.object_image_types:
|
||||
# do NOT use an empty tag: incorrect rendering in browsers
|
||||
self.body.append(self.starttag(node, 'object', '', **atts)
|
||||
+ node.get('alt', uri) + '</object>' + suffix)
|
||||
else:
|
||||
self.body.append(self.emptytag(node, 'img', suffix, **atts))
|
||||
|
||||
def depart_image(self, node):
|
||||
pass
|
||||
|
||||
# use table for footnote text,
|
||||
# context added in footnote_backrefs.
|
||||
def visit_label(self, node):
|
||||
self.body.append(self.starttag(node, 'td', '%s[' % self.context.pop(),
|
||||
CLASS='label'))
|
||||
|
||||
def depart_label(self, node):
|
||||
self.body.append(f']{self.context.pop()}</td><td>{self.context.pop()}')
|
||||
|
||||
# ersatz for first/last pseudo-classes
|
||||
def visit_list_item(self, node):
|
||||
self.body.append(self.starttag(node, 'li', ''))
|
||||
if len(node):
|
||||
node[0]['classes'].append('first')
|
||||
|
||||
def depart_list_item(self, node):
|
||||
self.body.append('</li>\n')
|
||||
|
||||
# use <tt> (not supported by HTML5),
|
||||
# cater for limited styling options in CSS1 using hard-coded NBSPs
|
||||
def visit_literal(self, node):
|
||||
# special case: "code" role
|
||||
classes = node['classes']
|
||||
if 'code' in classes:
|
||||
# filter 'code' from class arguments
|
||||
node['classes'] = [cls for cls in classes if cls != 'code']
|
||||
self.body.append(self.starttag(node, 'code', ''))
|
||||
return
|
||||
self.body.append(
|
||||
self.starttag(node, 'tt', '', CLASS='docutils literal'))
|
||||
text = node.astext()
|
||||
for token in self.words_and_spaces.findall(text):
|
||||
if token.strip():
|
||||
# Protect text like "--an-option" and the regular expression
|
||||
# ``[+]?(\d+(\.\d*)?|\.\d+)`` from bad line wrapping
|
||||
if self.in_word_wrap_point.search(token):
|
||||
self.body.append('<span class="pre">%s</span>'
|
||||
% self.encode(token))
|
||||
else:
|
||||
self.body.append(self.encode(token))
|
||||
elif token in ('\n', ' '):
|
||||
# Allow breaks at whitespace:
|
||||
self.body.append(token)
|
||||
else:
|
||||
# Protect runs of multiple spaces; the last space can wrap:
|
||||
self.body.append(' ' * (len(token) - 1) + ' ')
|
||||
self.body.append('</tt>')
|
||||
# Content already processed:
|
||||
raise nodes.SkipNode
|
||||
|
||||
def depart_literal(self, node):
|
||||
# skipped unless literal element is from "code" role:
|
||||
self.body.append('</code>')
|
||||
|
||||
# add newline after wrapper tags, don't use <code> for code
|
||||
def visit_literal_block(self, node):
|
||||
self.body.append(self.starttag(node, 'pre', CLASS='literal-block'))
|
||||
|
||||
def depart_literal_block(self, node):
|
||||
self.body.append('\n</pre>\n')
|
||||
|
||||
# use table for option list
|
||||
def visit_option_group(self, node):
|
||||
atts = {}
|
||||
if (self.settings.option_limit
|
||||
and len(node.astext()) > self.settings.option_limit):
|
||||
atts['colspan'] = 2
|
||||
self.context.append('</tr>\n<tr><td> </td>')
|
||||
else:
|
||||
self.context.append('')
|
||||
self.body.append(
|
||||
self.starttag(node, 'td', CLASS='option-group', **atts))
|
||||
self.body.append('<kbd>')
|
||||
self.context.append(0) # count number of options
|
||||
|
||||
def depart_option_group(self, node):
|
||||
self.context.pop()
|
||||
self.body.append('</kbd></td>\n')
|
||||
self.body.append(self.context.pop())
|
||||
|
||||
def visit_option_list(self, node):
|
||||
self.body.append(
|
||||
self.starttag(node, 'table', CLASS='docutils option-list',
|
||||
frame="void", rules="none"))
|
||||
self.body.append('<col class="option" />\n'
|
||||
'<col class="description" />\n'
|
||||
'<tbody valign="top">\n')
|
||||
|
||||
def depart_option_list(self, node):
|
||||
self.body.append('</tbody>\n</table>\n')
|
||||
|
||||
def visit_option_list_item(self, node):
|
||||
self.body.append(self.starttag(node, 'tr', ''))
|
||||
|
||||
def depart_option_list_item(self, node):
|
||||
self.body.append('</tr>\n')
|
||||
|
||||
# Omit <p> tags to produce visually compact lists (less vertical
|
||||
# whitespace) as CSS styling requires CSS2.
|
||||
def should_be_compact_paragraph(self, node):
|
||||
"""
|
||||
Determine if the <p> tags around paragraph ``node`` can be omitted.
|
||||
"""
|
||||
if (isinstance(node.parent, nodes.document)
|
||||
or isinstance(node.parent, nodes.compound)):
|
||||
# Never compact paragraphs in document or compound.
|
||||
return False
|
||||
for key, value in node.attlist():
|
||||
if (node.is_not_default(key)
|
||||
and not (key == 'classes'
|
||||
and value in ([], ['first'],
|
||||
['last'], ['first', 'last']))):
|
||||
# Attribute which needs to survive.
|
||||
return False
|
||||
first = isinstance(node.parent[0], nodes.label) # skip label
|
||||
for child in node.parent.children[first:]:
|
||||
# only first paragraph can be compact
|
||||
if isinstance(child, nodes.Invisible):
|
||||
continue
|
||||
if child is node:
|
||||
break
|
||||
return False
|
||||
parent_length = len([n for n in node.parent if not isinstance(
|
||||
n, (nodes.Invisible, nodes.label))])
|
||||
if (self.compact_simple
|
||||
or self.compact_field_list
|
||||
or self.compact_p and parent_length == 1):
|
||||
return True
|
||||
return False
|
||||
|
||||
def visit_paragraph(self, node):
|
||||
if self.should_be_compact_paragraph(node):
|
||||
self.context.append('')
|
||||
else:
|
||||
self.body.append(self.starttag(node, 'p', ''))
|
||||
self.context.append('</p>\n')
|
||||
|
||||
def depart_paragraph(self, node):
|
||||
self.body.append(self.context.pop())
|
||||
self.report_messages(node)
|
||||
|
||||
# ersatz for first/last pseudo-classes
|
||||
def visit_sidebar(self, node):
|
||||
self.body.append(
|
||||
self.starttag(node, 'div', CLASS='sidebar'))
|
||||
self.set_first_last(node)
|
||||
self.in_sidebar = True
|
||||
|
||||
def depart_sidebar(self, node):
|
||||
self.body.append('</div>\n')
|
||||
self.in_sidebar = False
|
||||
|
||||
# <sub> not allowed in <pre>
|
||||
def visit_subscript(self, node):
|
||||
if isinstance(node.parent, nodes.literal_block):
|
||||
self.body.append(self.starttag(node, 'span', '',
|
||||
CLASS='subscript'))
|
||||
else:
|
||||
self.body.append(self.starttag(node, 'sub', ''))
|
||||
|
||||
def depart_subscript(self, node):
|
||||
if isinstance(node.parent, nodes.literal_block):
|
||||
self.body.append('</span>')
|
||||
else:
|
||||
self.body.append('</sub>')
|
||||
|
||||
# Use <h*> for subtitles (deprecated in HTML 5)
|
||||
def visit_subtitle(self, node):
|
||||
if isinstance(node.parent, nodes.sidebar):
|
||||
self.body.append(self.starttag(node, 'p', '',
|
||||
CLASS='sidebar-subtitle'))
|
||||
self.context.append('</p>\n')
|
||||
elif isinstance(node.parent, nodes.document):
|
||||
self.body.append(self.starttag(node, 'h2', '', CLASS='subtitle'))
|
||||
self.context.append('</h2>\n')
|
||||
self.in_document_title = len(self.body)
|
||||
elif isinstance(node.parent, nodes.section):
|
||||
tag = 'h%s' % (self.section_level + self.initial_header_level - 1)
|
||||
self.body.append(
|
||||
self.starttag(node, tag, '', CLASS='section-subtitle')
|
||||
+ self.starttag({}, 'span', '', CLASS='section-subtitle'))
|
||||
self.context.append('</span></%s>\n' % tag)
|
||||
|
||||
def depart_subtitle(self, node):
|
||||
self.body.append(self.context.pop())
|
||||
if self.in_document_title:
|
||||
self.subtitle = self.body[self.in_document_title:-1]
|
||||
self.in_document_title = 0
|
||||
self.body_pre_docinfo.extend(self.body)
|
||||
self.html_subtitle.extend(self.body)
|
||||
del self.body[:]
|
||||
|
||||
# <sup> not allowed in <pre> in HTML 4
|
||||
def visit_superscript(self, node):
|
||||
if isinstance(node.parent, nodes.literal_block):
|
||||
self.body.append(self.starttag(node, 'span', '',
|
||||
CLASS='superscript'))
|
||||
else:
|
||||
self.body.append(self.starttag(node, 'sup', ''))
|
||||
|
||||
def depart_superscript(self, node):
|
||||
if isinstance(node.parent, nodes.literal_block):
|
||||
self.body.append('</span>')
|
||||
else:
|
||||
self.body.append('</sup>')
|
||||
|
||||
# <tt> element deprecated in HTML 5
|
||||
def visit_system_message(self, node):
|
||||
self.body.append(self.starttag(node, 'div', CLASS='system-message'))
|
||||
self.body.append('<p class="system-message-title">')
|
||||
backref_text = ''
|
||||
if len(node['backrefs']):
|
||||
backrefs = node['backrefs']
|
||||
if len(backrefs) == 1:
|
||||
backref_text = ('; <em><a href="#%s">backlink</a></em>'
|
||||
% backrefs[0])
|
||||
else:
|
||||
i = 1
|
||||
backlinks = []
|
||||
for backref in backrefs:
|
||||
backlinks.append('<a href="#%s">%s</a>' % (backref, i))
|
||||
i += 1
|
||||
backref_text = ('; <em>backlinks: %s</em>'
|
||||
% ', '.join(backlinks))
|
||||
if node.hasattr('line'):
|
||||
line = ', line %s' % node['line']
|
||||
else:
|
||||
line = ''
|
||||
self.body.append('System Message: %s/%s '
|
||||
'(<tt class="docutils">%s</tt>%s)%s</p>\n'
|
||||
% (node['type'], node['level'],
|
||||
self.encode(node['source']), line, backref_text))
|
||||
|
||||
def depart_system_message(self, node):
|
||||
self.body.append('</div>\n')
|
||||
|
||||
# "hard coded" border setting
|
||||
def visit_table(self, node):
|
||||
self.context.append(self.compact_p)
|
||||
self.compact_p = True
|
||||
atts = {'border': 1}
|
||||
classes = ['docutils', self.settings.table_style]
|
||||
if 'align' in node:
|
||||
classes.append('align-%s' % node['align'])
|
||||
if 'width' in node:
|
||||
atts['style'] = 'width: %s' % node['width']
|
||||
self.body.append(
|
||||
self.starttag(node, 'table', CLASS=' '.join(classes), **atts))
|
||||
|
||||
def depart_table(self, node):
|
||||
self.compact_p = self.context.pop()
|
||||
self.body.append('</table>\n')
|
||||
|
||||
# hard-coded vertical alignment
|
||||
def visit_tbody(self, node):
|
||||
self.body.append(self.starttag(node, 'tbody', valign='top'))
|
||||
|
||||
def depart_tbody(self, node):
|
||||
self.body.append('</tbody>\n')
|
||||
|
||||
# no special handling of "details" in definition list
|
||||
def visit_term(self, node):
|
||||
self.body.append(self.starttag(node, 'dt', '',
|
||||
classes=node.parent['classes'],
|
||||
ids=node.parent['ids']))
|
||||
|
||||
def depart_term(self, node):
|
||||
# Nest (optional) classifier(s) in the <dt> element
|
||||
if node.next_node(nodes.classifier, descend=False, siblings=True):
|
||||
return # skip (depart_classifier() calls this function again)
|
||||
self.body.append('</dt>\n')
|
||||
|
||||
# hard-coded vertical alignment
|
||||
def visit_thead(self, node):
|
||||
self.body.append(self.starttag(node, 'thead', valign='bottom'))
|
||||
|
||||
def depart_thead(self, node):
|
||||
self.body.append('</thead>\n')
|
||||
|
||||
# auxiliary method, called by visit_title()
|
||||
# "with-subtitle" class, no ARIA roles
|
||||
def section_title_tags(self, node):
|
||||
classes = []
|
||||
h_level = self.section_level + self.initial_header_level - 1
|
||||
if (len(node.parent) >= 2
|
||||
and isinstance(node.parent[1], nodes.subtitle)):
|
||||
classes.append('with-subtitle')
|
||||
if h_level > 6:
|
||||
classes.append('h%i' % h_level)
|
||||
tagname = 'h%i' % min(h_level, 6)
|
||||
start_tag = self.starttag(node, tagname, '', classes=classes)
|
||||
if node.hasattr('refid'):
|
||||
atts = {}
|
||||
atts['class'] = 'toc-backref'
|
||||
atts['href'] = '#' + node['refid']
|
||||
start_tag += self.starttag({}, 'a', '', **atts)
|
||||
close_tag = '</a></%s>\n' % tagname
|
||||
else:
|
||||
close_tag = '</%s>\n' % tagname
|
||||
return start_tag, close_tag
|
||||
|
||||
|
||||
class SimpleListChecker(writers._html_base.SimpleListChecker):
|
||||
|
||||
"""
|
||||
Raise `nodes.NodeFound` if non-simple list item is encountered.
|
||||
|
||||
Here "simple" means a list item containing nothing other than a single
|
||||
paragraph, a simple list, or a paragraph followed by a simple list.
|
||||
"""
|
||||
|
||||
def visit_list_item(self, node):
|
||||
children = []
|
||||
for child in node.children:
|
||||
if not isinstance(child, nodes.Invisible):
|
||||
children.append(child)
|
||||
if (children and isinstance(children[0], nodes.paragraph)
|
||||
and (isinstance(children[-1], nodes.bullet_list)
|
||||
or isinstance(children[-1], nodes.enumerated_list))):
|
||||
children.pop()
|
||||
if len(children) <= 1:
|
||||
return
|
||||
else:
|
||||
raise nodes.NodeFound
|
||||
|
||||
# def visit_bullet_list(self, node):
|
||||
# pass
|
||||
|
||||
# def visit_enumerated_list(self, node):
|
||||
# pass
|
||||
|
||||
def visit_paragraph(self, node):
|
||||
raise nodes.SkipNode
|
||||
|
||||
def visit_definition_list(self, node):
|
||||
raise nodes.NodeFound
|
||||
|
||||
def visit_docinfo(self, node):
|
||||
raise nodes.NodeFound
|
Binary file not shown.
|
@ -0,0 +1,350 @@
|
|||
/*
|
||||
:Author: David Goodger (goodger@python.org)
|
||||
:Id: $Id: html4css1.css 9511 2024-01-13 09:50:07Z milde $
|
||||
:Copyright: This stylesheet has been placed in the public domain.
|
||||
|
||||
Default cascading style sheet for the HTML output of Docutils.
|
||||
Despite the name, some widely supported CSS2 features are used.
|
||||
|
||||
See https://docutils.sourceforge.io/docs/howto/html-stylesheets.html for how to
|
||||
customize this style sheet.
|
||||
*/
|
||||
|
||||
/* used to remove borders from tables and images */
|
||||
.borderless, table.borderless td, table.borderless th {
|
||||
border: 0 }
|
||||
|
||||
table.borderless td, table.borderless th {
|
||||
/* Override padding for "table.docutils td" with "! important".
|
||||
The right padding separates the table cells. */
|
||||
padding: 0 0.5em 0 0 ! important }
|
||||
|
||||
.first {
|
||||
/* Override more specific margin styles with "! important". */
|
||||
margin-top: 0 ! important }
|
||||
|
||||
.last, .with-subtitle {
|
||||
margin-bottom: 0 ! important }
|
||||
|
||||
.hidden {
|
||||
display: none }
|
||||
|
||||
.subscript {
|
||||
vertical-align: sub;
|
||||
font-size: smaller }
|
||||
|
||||
.superscript {
|
||||
vertical-align: super;
|
||||
font-size: smaller }
|
||||
|
||||
a.toc-backref {
|
||||
text-decoration: none ;
|
||||
color: black }
|
||||
|
||||
blockquote.epigraph {
|
||||
margin: 2em 5em ; }
|
||||
|
||||
dl.docutils dd {
|
||||
margin-bottom: 0.5em }
|
||||
|
||||
object[type="image/svg+xml"], object[type="application/x-shockwave-flash"] {
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
/* Uncomment (and remove this text!) to get bold-faced definition list terms
|
||||
dl.docutils dt {
|
||||
font-weight: bold }
|
||||
*/
|
||||
|
||||
div.abstract {
|
||||
margin: 2em 5em }
|
||||
|
||||
div.abstract p.topic-title {
|
||||
font-weight: bold ;
|
||||
text-align: center }
|
||||
|
||||
div.admonition, div.attention, div.caution, div.danger, div.error,
|
||||
div.hint, div.important, div.note, div.tip, div.warning {
|
||||
margin: 2em ;
|
||||
border: medium outset ;
|
||||
padding: 1em }
|
||||
|
||||
div.admonition p.admonition-title, div.hint p.admonition-title,
|
||||
div.important p.admonition-title, div.note p.admonition-title,
|
||||
div.tip p.admonition-title {
|
||||
font-weight: bold ;
|
||||
font-family: sans-serif }
|
||||
|
||||
div.attention p.admonition-title, div.caution p.admonition-title,
|
||||
div.danger p.admonition-title, div.error p.admonition-title,
|
||||
div.warning p.admonition-title, .code .error {
|
||||
color: red ;
|
||||
font-weight: bold ;
|
||||
font-family: sans-serif }
|
||||
|
||||
/* Uncomment (and remove this text!) to get reduced vertical space in
|
||||
compound paragraphs.
|
||||
div.compound .compound-first, div.compound .compound-middle {
|
||||
margin-bottom: 0.5em }
|
||||
|
||||
div.compound .compound-last, div.compound .compound-middle {
|
||||
margin-top: 0.5em }
|
||||
*/
|
||||
|
||||
div.dedication {
|
||||
margin: 2em 5em ;
|
||||
text-align: center ;
|
||||
font-style: italic }
|
||||
|
||||
div.dedication p.topic-title {
|
||||
font-weight: bold ;
|
||||
font-style: normal }
|
||||
|
||||
div.figure {
|
||||
margin-left: 2em ;
|
||||
margin-right: 2em }
|
||||
|
||||
div.footer, div.header {
|
||||
clear: both;
|
||||
font-size: smaller }
|
||||
|
||||
div.line-block {
|
||||
display: block ;
|
||||
margin-top: 1em ;
|
||||
margin-bottom: 1em }
|
||||
|
||||
div.line-block div.line-block {
|
||||
margin-top: 0 ;
|
||||
margin-bottom: 0 ;
|
||||
margin-left: 1.5em }
|
||||
|
||||
div.sidebar {
|
||||
margin: 0 0 0.5em 1em ;
|
||||
border: medium outset ;
|
||||
padding: 1em ;
|
||||
background-color: #ffffee ;
|
||||
width: 40% ;
|
||||
float: right ;
|
||||
clear: right }
|
||||
|
||||
div.sidebar p.rubric {
|
||||
font-family: sans-serif ;
|
||||
font-size: medium }
|
||||
|
||||
div.system-messages {
|
||||
margin: 5em }
|
||||
|
||||
div.system-messages h1 {
|
||||
color: red }
|
||||
|
||||
div.system-message {
|
||||
border: medium outset ;
|
||||
padding: 1em }
|
||||
|
||||
div.system-message p.system-message-title {
|
||||
color: red ;
|
||||
font-weight: bold }
|
||||
|
||||
div.topic {
|
||||
margin: 2em }
|
||||
|
||||
h1.section-subtitle, h2.section-subtitle, h3.section-subtitle,
|
||||
h4.section-subtitle, h5.section-subtitle, h6.section-subtitle {
|
||||
margin-top: 0.4em }
|
||||
|
||||
h1.title {
|
||||
text-align: center }
|
||||
|
||||
h2.subtitle {
|
||||
text-align: center }
|
||||
|
||||
hr.docutils {
|
||||
width: 75% }
|
||||
|
||||
img.align-left, .figure.align-left, object.align-left, table.align-left {
|
||||
clear: left ;
|
||||
float: left ;
|
||||
margin-right: 1em }
|
||||
|
||||
img.align-right, .figure.align-right, object.align-right, table.align-right {
|
||||
clear: right ;
|
||||
float: right ;
|
||||
margin-left: 1em }
|
||||
|
||||
img.align-center, .figure.align-center, object.align-center {
|
||||
display: block;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
}
|
||||
|
||||
table.align-center {
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
}
|
||||
|
||||
.align-left {
|
||||
text-align: left }
|
||||
|
||||
.align-center {
|
||||
clear: both ;
|
||||
text-align: center }
|
||||
|
||||
.align-right {
|
||||
text-align: right }
|
||||
|
||||
/* reset inner alignment in figures */
|
||||
div.align-right {
|
||||
text-align: inherit }
|
||||
|
||||
/* div.align-center * { */
|
||||
/* text-align: left } */
|
||||
|
||||
.align-top {
|
||||
vertical-align: top }
|
||||
|
||||
.align-middle {
|
||||
vertical-align: middle }
|
||||
|
||||
.align-bottom {
|
||||
vertical-align: bottom }
|
||||
|
||||
ol.simple, ul.simple {
|
||||
margin-bottom: 1em }
|
||||
|
||||
ol.arabic {
|
||||
list-style: decimal }
|
||||
|
||||
ol.loweralpha {
|
||||
list-style: lower-alpha }
|
||||
|
||||
ol.upperalpha {
|
||||
list-style: upper-alpha }
|
||||
|
||||
ol.lowerroman {
|
||||
list-style: lower-roman }
|
||||
|
||||
ol.upperroman {
|
||||
list-style: upper-roman }
|
||||
|
||||
p.attribution {
|
||||
text-align: right ;
|
||||
margin-left: 50% }
|
||||
|
||||
p.caption {
|
||||
font-style: italic }
|
||||
|
||||
p.credits {
|
||||
font-style: italic ;
|
||||
font-size: smaller }
|
||||
|
||||
p.label {
|
||||
white-space: nowrap }
|
||||
|
||||
p.rubric {
|
||||
font-weight: bold ;
|
||||
font-size: larger ;
|
||||
color: maroon ;
|
||||
text-align: center }
|
||||
|
||||
p.sidebar-title {
|
||||
font-family: sans-serif ;
|
||||
font-weight: bold ;
|
||||
font-size: larger }
|
||||
|
||||
p.sidebar-subtitle {
|
||||
font-family: sans-serif ;
|
||||
font-weight: bold }
|
||||
|
||||
p.topic-title {
|
||||
font-weight: bold }
|
||||
|
||||
pre.address {
|
||||
margin-bottom: 0 ;
|
||||
margin-top: 0 ;
|
||||
font: inherit }
|
||||
|
||||
pre.literal-block, pre.doctest-block, pre.math, pre.code {
|
||||
margin-left: 2em ;
|
||||
margin-right: 2em }
|
||||
|
||||
pre.code .ln { color: gray; } /* line numbers */
|
||||
pre.code, code { background-color: #eeeeee }
|
||||
pre.code .comment, code .comment { color: #5C6576 }
|
||||
pre.code .keyword, code .keyword { color: #3B0D06; font-weight: bold }
|
||||
pre.code .literal.string, code .literal.string { color: #0C5404 }
|
||||
pre.code .name.builtin, code .name.builtin { color: #352B84 }
|
||||
pre.code .deleted, code .deleted { background-color: #DEB0A1}
|
||||
pre.code .inserted, code .inserted { background-color: #A3D289}
|
||||
|
||||
span.classifier {
|
||||
font-family: sans-serif ;
|
||||
font-style: oblique }
|
||||
|
||||
span.classifier-delimiter {
|
||||
font-family: sans-serif ;
|
||||
font-weight: bold }
|
||||
|
||||
span.interpreted {
|
||||
font-family: sans-serif }
|
||||
|
||||
span.option {
|
||||
white-space: nowrap }
|
||||
|
||||
span.pre {
|
||||
white-space: pre }
|
||||
|
||||
span.problematic, pre.problematic {
|
||||
color: red }
|
||||
|
||||
span.section-subtitle {
|
||||
/* font-size relative to parent (h1..h6 element) */
|
||||
font-size: 80% }
|
||||
|
||||
table.citation {
|
||||
border-left: solid 1px gray;
|
||||
margin-left: 1px }
|
||||
|
||||
table.docinfo {
|
||||
margin: 2em 4em }
|
||||
|
||||
table.docutils {
|
||||
margin-top: 0.5em ;
|
||||
margin-bottom: 0.5em }
|
||||
|
||||
table.footnote {
|
||||
border-left: solid 1px black;
|
||||
margin-left: 1px }
|
||||
|
||||
table.docutils td, table.docutils th,
|
||||
table.docinfo td, table.docinfo th {
|
||||
padding-left: 0.5em ;
|
||||
padding-right: 0.5em ;
|
||||
vertical-align: top }
|
||||
|
||||
table.docutils th.field-name, table.docinfo th.docinfo-name {
|
||||
font-weight: bold ;
|
||||
text-align: left ;
|
||||
white-space: nowrap ;
|
||||
padding-left: 0 }
|
||||
|
||||
/* "booktabs" style (no vertical lines) */
|
||||
table.docutils.booktabs {
|
||||
border: 0px;
|
||||
border-top: 2px solid;
|
||||
border-bottom: 2px solid;
|
||||
border-collapse: collapse;
|
||||
}
|
||||
table.docutils.booktabs * {
|
||||
border: 0px;
|
||||
}
|
||||
table.docutils.booktabs th {
|
||||
border-bottom: thin solid;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
h1 tt.docutils, h2 tt.docutils, h3 tt.docutils,
|
||||
h4 tt.docutils, h5 tt.docutils, h6 tt.docutils {
|
||||
font-size: 100% }
|
||||
|
||||
ul.auto-toc {
|
||||
list-style-type: none }
|
|
@ -0,0 +1,8 @@
|
|||
%(head_prefix)s
|
||||
%(head)s
|
||||
%(stylesheet)s
|
||||
%(body_prefix)s
|
||||
%(body_pre_docinfo)s
|
||||
%(docinfo)s
|
||||
%(body)s
|
||||
%(body_suffix)s
|
|
@ -0,0 +1,393 @@
|
|||
# $Id: __init__.py 9539 2024-02-17 10:36:51Z milde $
|
||||
# :Author: Günter Milde <milde@users.sf.net>
|
||||
# Based on the html4css1 writer by David Goodger.
|
||||
# :Maintainer: docutils-develop@lists.sourceforge.net
|
||||
# :Copyright: © 2005, 2009, 2015 Günter Milde,
|
||||
# portions from html4css1 © David Goodger.
|
||||
# :License: Released under the terms of the `2-Clause BSD license`_, in short:
|
||||
#
|
||||
# Copying and distribution of this file, with or without modification,
|
||||
# are permitted in any medium without royalty provided the copyright
|
||||
# notice and this notice are preserved.
|
||||
# This file is offered as-is, without any warranty.
|
||||
#
|
||||
# .. _2-Clause BSD license: https://opensource.org/licenses/BSD-2-Clause
|
||||
|
||||
# Use "best practice" as recommended by the W3C:
|
||||
# http://www.w3.org/2009/cheatsheet/
|
||||
|
||||
"""
|
||||
Plain HyperText Markup Language document tree Writer.
|
||||
|
||||
The output conforms to the `HTML 5` specification.
|
||||
|
||||
The cascading style sheet "minimal.css" is required for proper viewing,
|
||||
the style sheet "plain.css" improves reading experience.
|
||||
"""
|
||||
__docformat__ = 'reStructuredText'
|
||||
|
||||
from pathlib import Path
|
||||
|
||||
from docutils import frontend, nodes
|
||||
from docutils.writers import _html_base
|
||||
|
||||
|
||||
class Writer(_html_base.Writer):
|
||||
|
||||
supported = ('html5', 'xhtml', 'html')
|
||||
"""Formats this writer supports."""
|
||||
|
||||
default_stylesheets = ['minimal.css', 'plain.css']
|
||||
default_stylesheet_dirs = ['.', str(Path(__file__).parent)]
|
||||
default_template = Path(__file__).parent / 'template.txt'
|
||||
|
||||
# use a copy of the parent spec with some modifications
|
||||
settings_spec = frontend.filter_settings_spec(
|
||||
_html_base.Writer.settings_spec,
|
||||
template=(
|
||||
f'Template file. (UTF-8 encoded, default: "{default_template}")',
|
||||
['--template'],
|
||||
{'default': default_template, 'metavar': '<file>'}),
|
||||
stylesheet_path=(
|
||||
'Comma separated list of stylesheet paths. '
|
||||
'Relative paths are expanded if a matching file is found in '
|
||||
'the --stylesheet-dirs. With --link-stylesheet, '
|
||||
'the path is rewritten relative to the output HTML file. '
|
||||
'(default: "%s")' % ','.join(default_stylesheets),
|
||||
['--stylesheet-path'],
|
||||
{'metavar': '<file[,file,...]>', 'overrides': 'stylesheet',
|
||||
'validator': frontend.validate_comma_separated_list,
|
||||
'default': default_stylesheets}),
|
||||
stylesheet_dirs=(
|
||||
'Comma-separated list of directories where stylesheets are found. '
|
||||
'Used by --stylesheet-path when expanding relative path '
|
||||
'arguments. (default: "%s")' % ','.join(default_stylesheet_dirs),
|
||||
['--stylesheet-dirs'],
|
||||
{'metavar': '<dir[,dir,...]>',
|
||||
'validator': frontend.validate_comma_separated_list,
|
||||
'default': default_stylesheet_dirs}),
|
||||
initial_header_level=(
|
||||
'Specify the initial header level. Does not affect document '
|
||||
'title & subtitle (see --no-doc-title). (default: 2 for "<h2>")',
|
||||
['--initial-header-level'],
|
||||
{'choices': '1 2 3 4 5 6'.split(), 'default': '2',
|
||||
'metavar': '<level>'}),
|
||||
no_xml_declaration=(
|
||||
'Omit the XML declaration (default).',
|
||||
['--no-xml-declaration'],
|
||||
{'dest': 'xml_declaration', 'action': 'store_false'}),
|
||||
)
|
||||
settings_spec = settings_spec + (
|
||||
'HTML5 Writer Options',
|
||||
'',
|
||||
((frontend.SUPPRESS_HELP, # Obsoleted by "--image-loading"
|
||||
['--embed-images'],
|
||||
{'action': 'store_true',
|
||||
'validator': frontend.validate_boolean}),
|
||||
(frontend.SUPPRESS_HELP, # Obsoleted by "--image-loading"
|
||||
['--link-images'],
|
||||
{'dest': 'embed_images', 'action': 'store_false'}),
|
||||
('Suggest at which point images should be loaded: '
|
||||
'"embed", "link" (default), or "lazy".',
|
||||
['--image-loading'],
|
||||
{'choices': ('embed', 'link', 'lazy'),
|
||||
# 'default': 'link' # default set in _html_base.py
|
||||
}),
|
||||
('Append a self-link to section headings.',
|
||||
['--section-self-link'],
|
||||
{'default': False, 'action': 'store_true'}),
|
||||
('Do not append a self-link to section headings. (default)',
|
||||
['--no-section-self-link'],
|
||||
{'dest': 'section_self_link', 'action': 'store_false'}),
|
||||
)
|
||||
)
|
||||
|
||||
config_section = 'html5 writer'
|
||||
|
||||
def __init__(self):
|
||||
self.parts = {}
|
||||
self.translator_class = HTMLTranslator
|
||||
|
||||
|
||||
class HTMLTranslator(_html_base.HTMLTranslator):
|
||||
"""
|
||||
This writer generates `polyglot markup`: HTML5 that is also valid XML.
|
||||
|
||||
Safe subclassing: when overriding, treat ``visit_*`` and ``depart_*``
|
||||
methods as a unit to prevent breaks due to internal changes. See the
|
||||
docstring of docutils.writers._html_base.HTMLTranslator for details
|
||||
and examples.
|
||||
"""
|
||||
|
||||
# self.starttag() arguments for the main document
|
||||
documenttag_args = {'tagname': 'main'}
|
||||
|
||||
# add meta tag to fix rendering in mobile browsers
|
||||
def __init__(self, document):
|
||||
super().__init__(document)
|
||||
self.meta.append('<meta name="viewport" '
|
||||
'content="width=device-width, initial-scale=1" />\n')
|
||||
|
||||
# <acronym> tag obsolete in HTML5. Use the <abbr> tag instead.
|
||||
def visit_acronym(self, node):
|
||||
# @@@ implementation incomplete ("title" attribute)
|
||||
self.body.append(self.starttag(node, 'abbr', ''))
|
||||
|
||||
def depart_acronym(self, node):
|
||||
self.body.append('</abbr>')
|
||||
|
||||
# no standard meta tag name in HTML5, use separate "author" meta tags
|
||||
# https://www.w3.org/TR/html5/document-metadata.html#standard-metadata-names
|
||||
def visit_authors(self, node):
|
||||
self.visit_docinfo_item(node, 'authors', meta=False)
|
||||
for subnode in node:
|
||||
self.meta.append('<meta name="author" content='
|
||||
f'"{self.attval(subnode.astext())}" />\n')
|
||||
|
||||
def depart_authors(self, node):
|
||||
self.depart_docinfo_item()
|
||||
|
||||
# use the <figcaption> semantic tag.
|
||||
def visit_caption(self, node):
|
||||
if isinstance(node.parent, nodes.figure):
|
||||
self.body.append('<figcaption>\n')
|
||||
self.body.append(self.starttag(node, 'p', ''))
|
||||
|
||||
def depart_caption(self, node):
|
||||
self.body.append('</p>\n')
|
||||
# <figcaption> is closed in depart_figure(), as legend may follow.
|
||||
|
||||
# use HTML block-level tags if matching class value found
|
||||
supported_block_tags = {'ins', 'del'}
|
||||
|
||||
def visit_container(self, node):
|
||||
# If there is exactly one of the "supported block tags" in
|
||||
# the list of class values, use it as tag name:
|
||||
classes = node['classes']
|
||||
tags = [cls for cls in classes
|
||||
if cls in self.supported_block_tags]
|
||||
if len(tags) == 1:
|
||||
node.html5tagname = tags[0]
|
||||
classes.remove(tags[0])
|
||||
else:
|
||||
node.html5tagname = 'div'
|
||||
self.body.append(self.starttag(node, node.html5tagname,
|
||||
CLASS='docutils container'))
|
||||
|
||||
def depart_container(self, node):
|
||||
self.body.append(f'</{node.html5tagname}>\n')
|
||||
del node.html5tagname
|
||||
|
||||
# no standard meta tag name in HTML5, use dcterms.rights
|
||||
# see https://wiki.whatwg.org/wiki/MetaExtensions
|
||||
def visit_copyright(self, node):
|
||||
self.visit_docinfo_item(node, 'copyright', meta=False)
|
||||
self.meta.append('<meta name="dcterms.rights" '
|
||||
f'content="{self.attval(node.astext())}" />\n')
|
||||
|
||||
def depart_copyright(self, node):
|
||||
self.depart_docinfo_item()
|
||||
|
||||
# no standard meta tag name in HTML5, use dcterms.date
|
||||
def visit_date(self, node):
|
||||
self.visit_docinfo_item(node, 'date', meta=False)
|
||||
self.meta.append('<meta name="dcterms.date" '
|
||||
f'content="{self.attval(node.astext())}" />\n')
|
||||
|
||||
def depart_date(self, node):
|
||||
self.depart_docinfo_item()
|
||||
|
||||
# use new HTML5 <figure> and <figcaption> elements
|
||||
def visit_figure(self, node):
|
||||
atts = {}
|
||||
if node.get('width'):
|
||||
atts['style'] = f"width: {node['width']}"
|
||||
if node.get('align'):
|
||||
atts['class'] = f"align-{node['align']}"
|
||||
self.body.append(self.starttag(node, 'figure', **atts))
|
||||
|
||||
def depart_figure(self, node):
|
||||
if len(node) > 1:
|
||||
self.body.append('</figcaption>\n')
|
||||
self.body.append('</figure>\n')
|
||||
|
||||
# use HTML5 <footer> element
|
||||
def visit_footer(self, node):
|
||||
self.context.append(len(self.body))
|
||||
|
||||
def depart_footer(self, node):
|
||||
start = self.context.pop()
|
||||
footer = [self.starttag(node, 'footer')]
|
||||
footer.extend(self.body[start:])
|
||||
footer.append('</footer>\n')
|
||||
self.footer.extend(footer)
|
||||
self.body_suffix[:0] = footer
|
||||
del self.body[start:]
|
||||
|
||||
# use HTML5 <header> element
|
||||
def visit_header(self, node):
|
||||
self.context.append(len(self.body))
|
||||
|
||||
def depart_header(self, node):
|
||||
start = self.context.pop()
|
||||
header = [self.starttag(node, 'header')]
|
||||
header.extend(self.body[start:])
|
||||
header.append('</header>\n')
|
||||
self.body_prefix.extend(header)
|
||||
self.header.extend(header)
|
||||
del self.body[start:]
|
||||
|
||||
# use HTML text-level tags if matching class value found
|
||||
supported_inline_tags = {'code', 'kbd', 'dfn', 'samp', 'var',
|
||||
'bdi', 'del', 'ins', 'mark', 'small',
|
||||
'b', 'i', 'q', 's', 'u'}
|
||||
|
||||
# Use `supported_inline_tags` if found in class values
|
||||
def visit_inline(self, node):
|
||||
classes = node['classes']
|
||||
node.html5tagname = 'span'
|
||||
# Special handling for "code" directive content
|
||||
if (isinstance(node.parent, nodes.literal_block)
|
||||
and 'code' in node.parent.get('classes')
|
||||
or isinstance(node.parent, nodes.literal)
|
||||
and getattr(node.parent, 'html5tagname', None) == 'code'):
|
||||
if classes == ['ln']:
|
||||
# line numbers are not part of the "fragment of computer code"
|
||||
if self.body[-1] == '<code>':
|
||||
del self.body[-1]
|
||||
else:
|
||||
self.body.append('</code>')
|
||||
node.html5tagname = 'small'
|
||||
else:
|
||||
tags = [cls for cls in self.supported_inline_tags
|
||||
if cls in classes]
|
||||
if len(tags):
|
||||
node.html5tagname = tags[0]
|
||||
classes.remove(node.html5tagname)
|
||||
self.body.append(self.starttag(node, node.html5tagname, ''))
|
||||
|
||||
def depart_inline(self, node):
|
||||
self.body.append(f'</{node.html5tagname}>')
|
||||
if (node.html5tagname == 'small' and node.get('classes') == ['ln']
|
||||
and isinstance(node.parent, nodes.literal_block)):
|
||||
self.body.append(f'<code data-lineno="{node.astext()}">')
|
||||
del node.html5tagname
|
||||
|
||||
# place inside HTML5 <figcaption> element (together with caption)
|
||||
def visit_legend(self, node):
|
||||
if not isinstance(node.parent[1], nodes.caption):
|
||||
self.body.append('<figcaption>\n')
|
||||
self.body.append(self.starttag(node, 'div', CLASS='legend'))
|
||||
|
||||
def depart_legend(self, node):
|
||||
self.body.append('</div>\n')
|
||||
# <figcaption> closed in visit_figure()
|
||||
|
||||
# use HTML5 text-level tags if matching class value found
|
||||
def visit_literal(self, node):
|
||||
classes = node['classes']
|
||||
html5tagname = 'span'
|
||||
tags = [cls for cls in self.supported_inline_tags
|
||||
if cls in classes]
|
||||
if len(tags):
|
||||
html5tagname = tags[0]
|
||||
classes.remove(html5tagname)
|
||||
if html5tagname == 'code':
|
||||
node.html5tagname = html5tagname
|
||||
self.body.append(self.starttag(node, html5tagname, ''))
|
||||
return
|
||||
self.body.append(
|
||||
self.starttag(node, html5tagname, '', CLASS='docutils literal'))
|
||||
text = node.astext()
|
||||
# remove hard line breaks (except if in a parsed-literal block)
|
||||
if not isinstance(node.parent, nodes.literal_block):
|
||||
text = text.replace('\n', ' ')
|
||||
# Protect text like ``--an-option`` and the regular expression
|
||||
# ``[+]?(\d+(\.\d*)?|\.\d+)`` from bad line wrapping
|
||||
for token in self.words_and_spaces.findall(text):
|
||||
if token.strip() and self.in_word_wrap_point.search(token):
|
||||
self.body.append(
|
||||
f'<span class="pre">{self.encode(token)}</span>')
|
||||
else:
|
||||
self.body.append(self.encode(token))
|
||||
self.body.append(f'</{html5tagname}>')
|
||||
# Content already processed:
|
||||
raise nodes.SkipNode
|
||||
|
||||
def depart_literal(self, node):
|
||||
# skipped unless literal element is from "code" role:
|
||||
self.depart_inline(node)
|
||||
|
||||
# Meta tags: 'lang' attribute replaced by 'xml:lang' in XHTML 1.1
|
||||
# HTML5/polyglot recommends using both
|
||||
def visit_meta(self, node):
|
||||
if node.hasattr('lang'):
|
||||
node['xml:lang'] = node['lang']
|
||||
self.meta.append(self.emptytag(node, 'meta',
|
||||
**node.non_default_attributes()))
|
||||
|
||||
def depart_meta(self, node):
|
||||
pass
|
||||
|
||||
# no standard meta tag name in HTML5
|
||||
def visit_organization(self, node):
|
||||
self.visit_docinfo_item(node, 'organization', meta=False)
|
||||
|
||||
def depart_organization(self, node):
|
||||
self.depart_docinfo_item()
|
||||
|
||||
# use the new HTML5 element <section>
|
||||
def visit_section(self, node):
|
||||
self.section_level += 1
|
||||
self.body.append(
|
||||
self.starttag(node, 'section'))
|
||||
|
||||
def depart_section(self, node):
|
||||
self.section_level -= 1
|
||||
self.body.append('</section>\n')
|
||||
|
||||
# use the new HTML5 element <aside>
|
||||
def visit_sidebar(self, node):
|
||||
self.body.append(
|
||||
self.starttag(node, 'aside', CLASS='sidebar'))
|
||||
self.in_sidebar = True
|
||||
|
||||
def depart_sidebar(self, node):
|
||||
self.body.append('</aside>\n')
|
||||
self.in_sidebar = False
|
||||
|
||||
# Use new HTML5 element <aside> or <nav>
|
||||
# Add class value to <body>, if there is a ToC in the document
|
||||
# (see responsive.css how this is used for a navigation sidebar).
|
||||
def visit_topic(self, node):
|
||||
atts = {'classes': ['topic']}
|
||||
if 'contents' in node['classes']:
|
||||
node.html5tagname = 'nav'
|
||||
del atts['classes']
|
||||
if isinstance(node.parent, nodes.document):
|
||||
atts['role'] = 'doc-toc'
|
||||
self.body_prefix[0] = '</head>\n<body class="with-toc">\n'
|
||||
elif 'abstract' in node['classes']:
|
||||
node.html5tagname = 'div'
|
||||
atts['role'] = 'doc-abstract'
|
||||
elif 'dedication' in node['classes']:
|
||||
node.html5tagname = 'div'
|
||||
atts['role'] = 'doc-dedication'
|
||||
else:
|
||||
node.html5tagname = 'aside'
|
||||
self.body.append(self.starttag(node, node.html5tagname, **atts))
|
||||
|
||||
def depart_topic(self, node):
|
||||
self.body.append(f'</{node.html5tagname}>\n')
|
||||
del node.html5tagname
|
||||
|
||||
# append self-link
|
||||
def section_title_tags(self, node):
|
||||
start_tag, close_tag = super().section_title_tags(node)
|
||||
ids = node.parent['ids']
|
||||
if (ids and getattr(self.settings, 'section_self_link', None)
|
||||
and not isinstance(node.parent, nodes.document)):
|
||||
self_link = ('<a class="self-link" title="link to this section"'
|
||||
f' href="#{ids[0]}"></a>')
|
||||
close_tag = close_tag.replace('</h', self_link + '</h')
|
||||
return start_tag, close_tag
|
Binary file not shown.
|
@ -0,0 +1,26 @@
|
|||
/* italic-field-name.css: */
|
||||
/* Alternative style for Docutils field-lists */
|
||||
|
||||
/* :Copyright: © 2023 Günter Milde. */
|
||||
/* :License: Released under the terms of the `2-Clause BSD license`_, */
|
||||
/* in short: */
|
||||
/* */
|
||||
/* Copying and distribution of this file, with or without modification, */
|
||||
/* are permitted in any medium without royalty provided the copyright */
|
||||
/* notice and this notice are preserved. */
|
||||
/* */
|
||||
/* This file is offered as-is, without any warranty. */
|
||||
/* */
|
||||
/* .. _2-Clause BSD license: http://www.spdx.org/licenses/BSD-2-Clause */
|
||||
|
||||
/* In many contexts, a **bold** field name is too heavy styling. */
|
||||
/* Use *italic* instead:: */
|
||||
|
||||
dl.field-list > dt {
|
||||
font-weight: normal;
|
||||
font-style: italic;
|
||||
}
|
||||
dl.field-list > dt > .colon {
|
||||
font-style: normal;
|
||||
padding-left: 0.05ex;
|
||||
}
|
|
@ -0,0 +1,332 @@
|
|||
/*
|
||||
* math2html: convert LaTeX equations to HTML output.
|
||||
*
|
||||
* Copyright (C) 2009,2010 Alex Fernández
|
||||
* 2021 Günter Milde
|
||||
*
|
||||
* Released under the terms of the `2-Clause BSD license'_, in short:
|
||||
* Copying and distribution of this file, with or without modification,
|
||||
* are permitted in any medium without royalty provided the copyright
|
||||
* notice and this notice are preserved.
|
||||
* This file is offered as-is, without any warranty.
|
||||
*
|
||||
* .. _2-Clause BSD license: http://www.spdx.org/licenses/BSD-2-Clause
|
||||
*
|
||||
* Based on eLyXer: convert LyX source files to HTML output.
|
||||
* http://elyxer.nongnu.org/
|
||||
*
|
||||
*
|
||||
* CSS file for LaTeX formulas.
|
||||
*
|
||||
* References: http://www.zipcon.net/~swhite/docs/math/math.html
|
||||
* http://www.cs.tut.fi/~jkorpela/math/
|
||||
*/
|
||||
|
||||
/* Formulas */
|
||||
.formula {
|
||||
text-align: center;
|
||||
margin: 1.2em 0;
|
||||
line-height: 1.4;
|
||||
}
|
||||
span.formula {
|
||||
white-space: nowrap;
|
||||
}
|
||||
div.formula {
|
||||
padding: 0.5ex;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
}
|
||||
|
||||
/* Basic features */
|
||||
a.eqnumber {
|
||||
display: inline-block;
|
||||
float: right;
|
||||
clear: right;
|
||||
font-weight: bold;
|
||||
}
|
||||
span.unknown {
|
||||
color: #800000;
|
||||
}
|
||||
span.ignored, span.arraydef {
|
||||
display: none;
|
||||
}
|
||||
.phantom {
|
||||
visibility: hidden;
|
||||
}
|
||||
.formula i {
|
||||
letter-spacing: 0.1ex;
|
||||
}
|
||||
|
||||
/* Alignment */
|
||||
.align-l {
|
||||
text-align: left;
|
||||
}
|
||||
.align-r {
|
||||
text-align: right;
|
||||
}
|
||||
.align-c {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
/* Structures */
|
||||
span.hspace {
|
||||
display: inline-block;
|
||||
}
|
||||
span.overline, span.bar {
|
||||
text-decoration: overline;
|
||||
}
|
||||
.fraction, .fullfraction, .textfraction {
|
||||
display: inline-block;
|
||||
vertical-align: middle;
|
||||
text-align: center;
|
||||
}
|
||||
span.formula .fraction,
|
||||
.textfraction,
|
||||
span.smallmatrix {
|
||||
font-size: 80%;
|
||||
line-height: 1;
|
||||
}
|
||||
span.numerator {
|
||||
display: block;
|
||||
line-height: 1;
|
||||
}
|
||||
span.denominator {
|
||||
display: block;
|
||||
line-height: 1;
|
||||
padding: 0ex;
|
||||
border-top: thin solid;
|
||||
}
|
||||
.formula sub, .formula sup {
|
||||
font-size: 80%;
|
||||
}
|
||||
sup.numerator, sup.unit {
|
||||
vertical-align: 80%;
|
||||
}
|
||||
sub.denominator, sub.unit {
|
||||
vertical-align: -20%;
|
||||
}
|
||||
span.smallsymbol {
|
||||
font-size: 75%;
|
||||
line-height: 75%;
|
||||
}
|
||||
span.boldsymbol {
|
||||
font-weight: bold;
|
||||
}
|
||||
span.sqrt {
|
||||
display: inline-block;
|
||||
vertical-align: middle;
|
||||
padding: 0.1ex;
|
||||
}
|
||||
sup.root {
|
||||
position: relative;
|
||||
left: 1.4ex;
|
||||
}
|
||||
span.radical {
|
||||
display: inline-block;
|
||||
padding: 0ex;
|
||||
/* font-size: 160%; for DejaVu, not required with STIX */
|
||||
line-height: 100%;
|
||||
vertical-align: top;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
span.root {
|
||||
display: inline-block;
|
||||
border-top: thin solid;
|
||||
padding: 0ex;
|
||||
vertical-align: middle;
|
||||
}
|
||||
div.formula .bigoperator,
|
||||
.displaystyle .bigoperator,
|
||||
.displaystyle .bigoperator {
|
||||
line-height: 120%;
|
||||
font-size: 140%;
|
||||
padding-right: 0.2ex;
|
||||
}
|
||||
span.fraction .bigoperator,
|
||||
span.scriptstyle .bigoperator {
|
||||
line-height: inherit;
|
||||
font-size: inherit;
|
||||
padding-right: 0;
|
||||
}
|
||||
span.bigdelimiter {
|
||||
display: inline-block;
|
||||
}
|
||||
span.bigdelimiter.size1 {
|
||||
transform: scale(1, 1.2);
|
||||
line-height: 1.2;
|
||||
}
|
||||
span.bigdelimiter.size2 {
|
||||
transform: scale(1, 1.62);
|
||||
line-height: 1.62%;
|
||||
|
||||
}
|
||||
span.bigdelimiter.size3 {
|
||||
transform: scale(1, 2.05);
|
||||
line-height: 2.05%;
|
||||
}
|
||||
span.bigdelimiter.size4 {
|
||||
transform: scale(1, 2.47);
|
||||
line-height: 2.47%;
|
||||
}
|
||||
/* vertically stacked sub and superscript */
|
||||
span.scripts {
|
||||
display: inline-table;
|
||||
vertical-align: middle;
|
||||
padding-right: 0.2ex;
|
||||
}
|
||||
.script {
|
||||
display: table-row;
|
||||
text-align: left;
|
||||
line-height: 150%;
|
||||
}
|
||||
span.limits {
|
||||
display: inline-table;
|
||||
vertical-align: middle;
|
||||
}
|
||||
.limit {
|
||||
display: table-row;
|
||||
line-height: 99%;
|
||||
}
|
||||
sup.limit, sub.limit {
|
||||
line-height: 100%;
|
||||
}
|
||||
span.embellished,
|
||||
span.embellished > .base {
|
||||
display: inline-block;
|
||||
}
|
||||
span.embellished > sup,
|
||||
span.embellished > sub {
|
||||
display: inline-block;
|
||||
font-size: 100%;
|
||||
position: relative;
|
||||
bottom: 0.3em;
|
||||
width: 0px;
|
||||
}
|
||||
span.embellished > sub {
|
||||
top: 0.4em;
|
||||
}
|
||||
|
||||
/* Environments */
|
||||
span.array, span.bracketcases, span.binomial, span.environment {
|
||||
display: inline-table;
|
||||
text-align: center;
|
||||
vertical-align: middle;
|
||||
}
|
||||
span.arrayrow, span.binomrow {
|
||||
display: table-row;
|
||||
padding: 0;
|
||||
border: 0;
|
||||
}
|
||||
span.arraycell, span.bracket, span.case, span.binomcell, span.environmentcell {
|
||||
display: table-cell;
|
||||
padding: 0ex 0.2ex;
|
||||
line-height: 1; /* 99%; */
|
||||
border: 0ex;
|
||||
}
|
||||
.environment.align > .arrayrow > .arraycell.align-l {
|
||||
padding-right: 2em;
|
||||
}
|
||||
|
||||
/* Inline binomials */
|
||||
span.binom {
|
||||
display: inline-block;
|
||||
vertical-align: middle;
|
||||
text-align: center;
|
||||
font-size: 80%;
|
||||
}
|
||||
span.binomstack {
|
||||
display: block;
|
||||
padding: 0em;
|
||||
}
|
||||
|
||||
/* Over- and underbraces */
|
||||
span.overbrace {
|
||||
border-top: 2pt solid;
|
||||
}
|
||||
span.underbrace {
|
||||
border-bottom: 2pt solid;
|
||||
}
|
||||
|
||||
/* Stackrel */
|
||||
span.stackrel {
|
||||
display: inline-block;
|
||||
text-align: center;
|
||||
}
|
||||
span.upstackrel {
|
||||
display: block;
|
||||
padding: 0em;
|
||||
font-size: 80%;
|
||||
line-height: 64%;
|
||||
position: relative;
|
||||
top: 0.15em;
|
||||
|
||||
}
|
||||
span.downstackrel {
|
||||
display: block;
|
||||
vertical-align: bottom;
|
||||
padding: 0em;
|
||||
}
|
||||
|
||||
/* Fonts */
|
||||
.formula {
|
||||
font-family: STIX, "DejaVu Serif", "DejaVu Math TeX Gyre", serif;
|
||||
}
|
||||
span.radical, /* ensure correct size of square-root sign */
|
||||
span.integral { /* upright integral signs for better alignment of indices */
|
||||
font-family: "STIXIntegralsUp", STIX;
|
||||
/* font-size: 115%; match apparent size with DejaVu */
|
||||
}
|
||||
span.bracket {
|
||||
/* some "STIX" and "DejaVu Math TeX Gyre" bracket pieces don't fit */
|
||||
font-family: "DejaVu Serif", serif;
|
||||
}
|
||||
span.mathsf, span.textsf {
|
||||
font-family: sans-serif;
|
||||
}
|
||||
span.mathrm, span.textrm {
|
||||
font-family: STIX, "DejaVu Serif", "DejaVu Math TeX Gyre", serif;
|
||||
}
|
||||
span.mathtt, span.texttt {
|
||||
font-family: monospace;
|
||||
}
|
||||
span.text, span.textnormal,
|
||||
span.mathsf, span.mathtt, span.mathrm {
|
||||
font-style: normal;
|
||||
}
|
||||
span.fraktur {
|
||||
font-family: "Lucida Blackletter", eufm10, blackletter;
|
||||
}
|
||||
span.blackboard {
|
||||
font-family: Blackboard, msbm10, serif;
|
||||
}
|
||||
span.scriptfont {
|
||||
font-family: "Monotype Corsiva", "Apple Chancery", "URW Chancery L", cursive;
|
||||
font-style: italic;
|
||||
}
|
||||
span.mathscr {
|
||||
font-family: MathJax_Script, rsfs10, cursive;
|
||||
font-style: italic;
|
||||
}
|
||||
span.textsc {
|
||||
font-variant: small-caps;
|
||||
}
|
||||
span.textsl {
|
||||
font-style: oblique;
|
||||
}
|
||||
|
||||
/* Colors */
|
||||
span.colorbox {
|
||||
display: inline-block;
|
||||
padding: 5px;
|
||||
}
|
||||
span.fbox {
|
||||
display: inline-block;
|
||||
border: thin solid black;
|
||||
padding: 2px;
|
||||
}
|
||||
span.boxed, span.framebox {
|
||||
display: inline-block;
|
||||
border: thin solid black;
|
||||
padding: 5px;
|
||||
}
|
|
@ -0,0 +1,293 @@
|
|||
/* Minimal style sheet for the HTML output of Docutils. */
|
||||
/* */
|
||||
/* :Author: Günter Milde, based on html4css1.css by David Goodger */
|
||||
/* :Id: $Id: minimal.css 9545 2024-02-17 10:37:56Z milde $ */
|
||||
/* :Copyright: © 2015, 2021 Günter Milde. */
|
||||
/* :License: Released under the terms of the `2-Clause BSD license`_, */
|
||||
/* in short: */
|
||||
/* */
|
||||
/* Copying and distribution of this file, with or without modification, */
|
||||
/* are permitted in any medium without royalty provided the copyright */
|
||||
/* notice and this notice are preserved. */
|
||||
/* */
|
||||
/* This file is offered as-is, without any warranty. */
|
||||
/* */
|
||||
/* .. _2-Clause BSD license: http://www.spdx.org/licenses/BSD-2-Clause */
|
||||
|
||||
/* This CSS3 stylesheet defines rules for Docutils elements without */
|
||||
/* HTML equivalent. It is required to make the document semantics visible. */
|
||||
/* */
|
||||
/* .. _validates: http://jigsaw.w3.org/css-validator/validator$link */
|
||||
|
||||
/* titles */
|
||||
p.topic-title,
|
||||
p.admonition-title,
|
||||
p.system-message-title {
|
||||
font-weight: bold;
|
||||
}
|
||||
p.sidebar-title,
|
||||
p.rubric {
|
||||
font-weight: bold;
|
||||
font-size: larger;
|
||||
}
|
||||
p.rubric {
|
||||
color: maroon;
|
||||
}
|
||||
p.subtitle,
|
||||
p.section-subtitle,
|
||||
p.sidebar-subtitle {
|
||||
font-weight: bold;
|
||||
margin-top: -0.5em;
|
||||
}
|
||||
h1 + p.subtitle {
|
||||
font-size: 1.6em;
|
||||
}
|
||||
a.toc-backref {
|
||||
color: inherit;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
/* Warnings, Errors */
|
||||
.system-messages h2,
|
||||
.system-message-title,
|
||||
pre.problematic,
|
||||
span.problematic {
|
||||
color: red;
|
||||
}
|
||||
|
||||
/* Inline Literals */
|
||||
.docutils.literal {
|
||||
font-family: monospace;
|
||||
white-space: pre-wrap;
|
||||
}
|
||||
/* do not wrap at hyphens and similar: */
|
||||
.literal > span.pre { white-space: nowrap; }
|
||||
|
||||
/* keep line-breaks (\n) visible */
|
||||
.pre-wrap { white-space: pre-wrap; }
|
||||
|
||||
/* Lists */
|
||||
|
||||
/* compact and simple lists: no margin between items */
|
||||
.simple li, .simple ul, .simple ol,
|
||||
.compact li, .compact ul, .compact ol,
|
||||
.simple > li p, dl.simple > dd,
|
||||
.compact > li p, dl.compact > dd {
|
||||
margin-top: 0;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
/* Nested Paragraphs */
|
||||
p:first-child { margin-top: 0; }
|
||||
p:last-child { margin-bottom: 0; }
|
||||
details > p:last-child { margin-bottom: 1em; }
|
||||
|
||||
/* Table of Contents */
|
||||
.contents ul.auto-toc { /* section numbers present */
|
||||
list-style-type: none;
|
||||
}
|
||||
|
||||
/* Enumerated Lists */
|
||||
ol.arabic { list-style: decimal }
|
||||
ol.loweralpha { list-style: lower-alpha }
|
||||
ol.upperalpha { list-style: upper-alpha }
|
||||
ol.lowerroman { list-style: lower-roman }
|
||||
ol.upperroman { list-style: upper-roman }
|
||||
|
||||
/* Definition Lists and Derivatives */
|
||||
dt .classifier { font-style: italic }
|
||||
dt .classifier:before {
|
||||
font-style: normal;
|
||||
margin: 0.5em;
|
||||
content: ":";
|
||||
}
|
||||
/* Field Lists and similar */
|
||||
/* bold field name, content starts on the same line */
|
||||
dl.field-list,
|
||||
dl.option-list,
|
||||
dl.docinfo {
|
||||
display: flow-root;
|
||||
}
|
||||
dl.field-list > dt,
|
||||
dl.option-list > dt,
|
||||
dl.docinfo > dt {
|
||||
font-weight: bold;
|
||||
clear: left;
|
||||
float: left;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
padding-right: 0.25em;
|
||||
}
|
||||
/* Offset for field content (corresponds to the --field-name-limit option) */
|
||||
dl.field-list > dd,
|
||||
dl.option-list > dd,
|
||||
dl.docinfo > dd {
|
||||
margin-left: 9em; /* ca. 14 chars in the test examples, fit all Docinfo fields */
|
||||
}
|
||||
/* start nested lists on new line */
|
||||
dd > dl:first-child,
|
||||
dd > ul:first-child,
|
||||
dd > ol:first-child {
|
||||
clear: left;
|
||||
}
|
||||
/* start field-body on a new line after long field names */
|
||||
dl.field-list > dd > *:first-child,
|
||||
dl.option-list > dd > *:first-child
|
||||
{
|
||||
display: inline-block;
|
||||
width: 100%;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
/* Bibliographic Fields (docinfo) */
|
||||
dl.docinfo pre.address {
|
||||
font: inherit;
|
||||
margin: 0.5em 0;
|
||||
}
|
||||
dl.docinfo > dd.authors > p { margin: 0; }
|
||||
|
||||
/* Option Lists */
|
||||
dl.option-list > dt { font-weight: normal; }
|
||||
span.option { white-space: nowrap; }
|
||||
|
||||
/* Footnotes and Citations */
|
||||
|
||||
.footnote, .citation { margin: 1em 0; } /* default paragraph skip (Firefox) */
|
||||
/* hanging indent */
|
||||
.citation { padding-left: 2em; }
|
||||
.footnote { padding-left: 1.7em; }
|
||||
.footnote.superscript { padding-left: 1.0em; }
|
||||
.citation > .label { margin-left: -2em; }
|
||||
.footnote > .label { margin-left: -1.7em; }
|
||||
.footnote.superscript > .label { margin-left: -1.0em; }
|
||||
|
||||
.footnote > .label + *,
|
||||
.citation > .label + * {
|
||||
display: inline-block;
|
||||
margin-top: 0;
|
||||
vertical-align: top;
|
||||
}
|
||||
.footnote > .backrefs + *,
|
||||
.citation > .backrefs + * {
|
||||
margin-top: 0;
|
||||
}
|
||||
.footnote > .label + p, .footnote > .backrefs + p,
|
||||
.citation > .label + p, .citation > .backrefs + p {
|
||||
display: inline;
|
||||
vertical-align: inherit;
|
||||
}
|
||||
|
||||
.backrefs { user-select: none; }
|
||||
.backrefs > a { font-style: italic; }
|
||||
|
||||
/* superscript footnotes */
|
||||
a[role="doc-noteref"].superscript,
|
||||
.footnote.superscript > .label,
|
||||
.footnote.superscript > .backrefs {
|
||||
vertical-align: super;
|
||||
font-size: smaller;
|
||||
line-height: 1;
|
||||
}
|
||||
a[role="doc-noteref"].superscript > .fn-bracket,
|
||||
.footnote.superscript > .label > .fn-bracket {
|
||||
/* hide brackets in display but leave for copy/paste */
|
||||
display: inline-block;
|
||||
width: 0;
|
||||
overflow: hidden;
|
||||
}
|
||||
[role="doc-noteref"].superscript + [role="doc-noteref"].superscript {
|
||||
padding-left: 0.15em; /* separate consecutive footnote references */
|
||||
/* TODO: unfortunately, "+" also selects with text between the references. */
|
||||
}
|
||||
|
||||
/* Alignment */
|
||||
.align-left {
|
||||
text-align: left;
|
||||
margin-right: auto;
|
||||
}
|
||||
.align-center {
|
||||
text-align: center;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
}
|
||||
.align-right {
|
||||
text-align: right;
|
||||
margin-left: auto;
|
||||
}
|
||||
.align-top { vertical-align: top; }
|
||||
.align-middle { vertical-align: middle; }
|
||||
.align-bottom { vertical-align: bottom; }
|
||||
|
||||
/* reset inner alignment in figures and tables */
|
||||
figure.align-left, figure.align-right,
|
||||
table.align-left, table.align-center, table.align-right {
|
||||
text-align: inherit;
|
||||
}
|
||||
|
||||
/* Text Blocks */
|
||||
.topic { margin: 1em 2em; }
|
||||
.sidebar,
|
||||
.admonition,
|
||||
.system-message {
|
||||
margin: 1em 2em;
|
||||
border: thin solid;
|
||||
padding: 0.5em 1em;
|
||||
}
|
||||
div.line-block { display: block; }
|
||||
div.line-block div.line-block, pre { margin-left: 2em; }
|
||||
|
||||
/* Code line numbers: dropped when copying text from the page */
|
||||
pre.code .ln { display: none; }
|
||||
pre.code code:before {
|
||||
content: attr(data-lineno); /* …, none) fallback not supported by any browser */
|
||||
color: gray;
|
||||
}
|
||||
|
||||
/* Tables */
|
||||
table {
|
||||
border-collapse: collapse;
|
||||
}
|
||||
td, th {
|
||||
border: thin solid silver;
|
||||
padding: 0 1ex;
|
||||
}
|
||||
.borderless td, .borderless th {
|
||||
border: 0;
|
||||
padding: 0;
|
||||
padding-right: 0.5em /* separate table cells */
|
||||
}
|
||||
|
||||
table > caption, figcaption {
|
||||
text-align: left;
|
||||
margin-top: 0.2em;
|
||||
margin-bottom: 0.2em;
|
||||
}
|
||||
table.captionbelow {
|
||||
caption-side: bottom;
|
||||
}
|
||||
|
||||
/* MathML (see "math.css" for --math-output=HTML) */
|
||||
math .boldsymbol { font-weight: bold; }
|
||||
math.boxed, math .boxed {padding: 0.25em; border: thin solid; }
|
||||
/* style table similar to AMS "align" or "aligned" environment: */
|
||||
mtable.cases > mtr > mtd { text-align: left; }
|
||||
mtable.ams-align > mtr > mtd { padding-left: 0; padding-right: 0; }
|
||||
mtable.ams-align > mtr > mtd:nth-child(2n) { text-align: left; }
|
||||
mtable.ams-align > mtr > mtd:nth-child(2n+1) { text-align: right; }
|
||||
mtable.ams-align > mtr > mtd:nth-child(2n+3) { padding-left: 2em; }
|
||||
.mathscr mi, mi.mathscr {
|
||||
font-family: STIX, XITSMathJax_Script, rsfs10,
|
||||
"Asana Math", Garamond, cursive;
|
||||
}
|
||||
|
||||
/* Document Header and Footer */
|
||||
header { border-bottom: 1px solid black; }
|
||||
footer { border-top: 1px solid black; }
|
||||
|
||||
/* Images are block-level by default in Docutils */
|
||||
/* New HTML5 block elements: set display for older browsers */
|
||||
img, svg, header, footer, main, aside, nav, section, figure, video, details {
|
||||
display: block;
|
||||
}
|
||||
svg { width: auto; height: auto; } /* enable scaling of SVG images */
|
||||
/* inline images */
|
||||
p img, p svg, p video { display: inline; }
|
|
@ -0,0 +1,307 @@
|
|||
/* CSS31_ style sheet for the output of Docutils HTML writers. */
|
||||
/* Rules for easy reading and pre-defined style variants. */
|
||||
/* */
|
||||
/* :Author: Günter Milde, based on html4css1.css by David Goodger */
|
||||
/* :Id: $Id: plain.css 9615 2024-04-06 13:28:15Z milde $ */
|
||||
/* :Copyright: © 2015 Günter Milde. */
|
||||
/* :License: Released under the terms of the `2-Clause BSD license`_, */
|
||||
/* in short: */
|
||||
/* */
|
||||
/* Copying and distribution of this file, with or without modification, */
|
||||
/* are permitted in any medium without royalty provided the copyright */
|
||||
/* notice and this notice are preserved. */
|
||||
/* */
|
||||
/* This file is offered as-is, without any warranty. */
|
||||
/* */
|
||||
/* .. _2-Clause BSD license: http://www.spdx.org/licenses/BSD-2-Clause */
|
||||
/* .. _CSS3: https://www.w3.org/Style/CSS/ */
|
||||
|
||||
|
||||
/* Document Structure */
|
||||
/* ****************** */
|
||||
|
||||
/* "page layout" */
|
||||
body {
|
||||
margin: 0;
|
||||
background-color: #dbdbdb;
|
||||
--field-indent: 9em; /* default indent of fields in field lists */
|
||||
}
|
||||
main, footer, header {
|
||||
line-height:1.6;
|
||||
/* avoid long lines --> better reading */
|
||||
/* optimum is 45…75 characters/line <http://webtypography.net/2.1.2> */
|
||||
/* OTOH: lines should not be too short because of missing hyphenation, */
|
||||
max-width: 50rem;
|
||||
padding: 1px 2%; /* 1px on top avoids grey bar above title (mozilla) */
|
||||
margin: auto;
|
||||
}
|
||||
main {
|
||||
counter-reset: table figure;
|
||||
background-color: white;
|
||||
}
|
||||
footer, header {
|
||||
font-size: smaller;
|
||||
padding: 0.5em 2%;
|
||||
border: none;
|
||||
}
|
||||
|
||||
/* Table of Contents */
|
||||
ul.auto-toc > li > p {
|
||||
padding-left: 1em;
|
||||
text-indent: -1em;
|
||||
}
|
||||
nav.contents ul {
|
||||
padding-left: 1em;
|
||||
}
|
||||
main > nav.contents ul ul ul ul:not(.auto-toc) {
|
||||
list-style-type: '\2B29\ ';
|
||||
}
|
||||
main > nav.contents ul ul ul ul ul:not(.auto-toc) {
|
||||
list-style-type: '\2B1D\ ';
|
||||
}
|
||||
|
||||
/* Transitions */
|
||||
hr.docutils {
|
||||
width: 80%;
|
||||
margin-top: 1em;
|
||||
margin-bottom: 1em;
|
||||
clear: both;
|
||||
}
|
||||
|
||||
/* Paragraphs */
|
||||
|
||||
/* vertical space (parskip) */
|
||||
p, ol, ul, dl, li,
|
||||
.footnote, .citation,
|
||||
div > math,
|
||||
table {
|
||||
margin-top: 0.5em;
|
||||
margin-bottom: 0.5em;
|
||||
}
|
||||
|
||||
h1, h2, h3, h4, h5, h6,
|
||||
dd, details > p:last-child {
|
||||
margin-bottom: 0.5em;
|
||||
}
|
||||
|
||||
/* Lists */
|
||||
/* ===== */
|
||||
|
||||
/* Definition Lists */
|
||||
/* Indent lists nested in definition lists */
|
||||
dd > ul:only-child, dd > ol:only-child { padding-left: 1em; }
|
||||
|
||||
/* Description Lists */
|
||||
/* styled like in most dictionaries, encyclopedias etc. */
|
||||
dl.description {
|
||||
display: flow-root;
|
||||
}
|
||||
dl.description > dt {
|
||||
font-weight: bold;
|
||||
clear: left;
|
||||
float: left;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
padding-right: 0.3em;
|
||||
}
|
||||
dl.description > dd:after {
|
||||
display: table;
|
||||
content: "";
|
||||
clear: left; /* clearfix for empty descriptions */
|
||||
}
|
||||
|
||||
/* Field Lists */
|
||||
|
||||
dl.field-list > dd,
|
||||
dl.docinfo > dd {
|
||||
margin-left: var(--field-indent); /* adapted in media queries or HTML */
|
||||
}
|
||||
|
||||
/* example for custom field-name width */
|
||||
dl.field-list.narrow > dd {
|
||||
--field-indent: 5em;
|
||||
}
|
||||
/* run-in: start field-body on same line after long field names */
|
||||
dl.field-list.run-in > dd p {
|
||||
display: block;
|
||||
}
|
||||
|
||||
/* Bibliographic Fields */
|
||||
|
||||
/* generally, bibliographic fields use dl.docinfo */
|
||||
/* but dedication and abstract are placed into divs */
|
||||
div.abstract p.topic-title {
|
||||
text-align: center;
|
||||
}
|
||||
div.dedication {
|
||||
margin: 2em 5em;
|
||||
text-align: center;
|
||||
font-style: italic;
|
||||
}
|
||||
div.dedication p.topic-title {
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
/* disclosures */
|
||||
details { padding-left: 1em; }
|
||||
summary { margin-left: -1em; }
|
||||
|
||||
/* Text Blocks */
|
||||
/* =========== */
|
||||
|
||||
/* Literal Blocks */
|
||||
pre.literal-block, pre.doctest-block,
|
||||
pre.math, pre.code {
|
||||
font-family: monospace;
|
||||
}
|
||||
|
||||
/* Block Quotes and Topics */
|
||||
bockquote { margin: 1em 2em; }
|
||||
blockquote p.attribution,
|
||||
.topic p.attribution {
|
||||
text-align: right;
|
||||
margin-left: 20%;
|
||||
}
|
||||
|
||||
/* Tables */
|
||||
/* ====== */
|
||||
|
||||
/* th { vertical-align: bottom; } */
|
||||
|
||||
table tr { text-align: left; }
|
||||
|
||||
/* "booktabs" style (no vertical lines) */
|
||||
table.booktabs {
|
||||
border: 0;
|
||||
border-top: 2px solid;
|
||||
border-bottom: 2px solid;
|
||||
border-collapse: collapse;
|
||||
}
|
||||
table.booktabs * {
|
||||
border: 0;
|
||||
}
|
||||
table.booktabs th {
|
||||
border-bottom: thin solid;
|
||||
}
|
||||
|
||||
/* numbered tables (counter defined in div.document) */
|
||||
table.numbered > caption:before {
|
||||
counter-increment: table;
|
||||
content: "Table " counter(table) ": ";
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
/* Explicit Markup Blocks */
|
||||
/* ====================== */
|
||||
|
||||
/* Footnotes and Citations */
|
||||
/* ----------------------- */
|
||||
|
||||
/* line on the left */
|
||||
.footnote-list {
|
||||
border-left: solid thin;
|
||||
padding-left: 0.25em;
|
||||
}
|
||||
|
||||
/* Directives */
|
||||
/* ---------- */
|
||||
|
||||
/* Body Elements */
|
||||
/* ~~~~~~~~~~~~~ */
|
||||
|
||||
/* Images and Figures */
|
||||
|
||||
/* let content flow to the side of aligned images and figures */
|
||||
figure.align-left,
|
||||
img.align-left,
|
||||
svg.align-left,
|
||||
video.align-left,
|
||||
div.align-left,
|
||||
object.align-left {
|
||||
clear: left;
|
||||
float: left;
|
||||
margin-right: 1em;
|
||||
}
|
||||
figure.align-right,
|
||||
img.align-right,
|
||||
svg.align-right,
|
||||
video.align-right,
|
||||
div.align-right,
|
||||
object.align-right {
|
||||
clear: right;
|
||||
float: right;
|
||||
margin-left: 1em;
|
||||
}
|
||||
/* Stop floating sidebars, images and figures */
|
||||
h1, h2, h3, h4, footer, header { clear: both; }
|
||||
|
||||
/* Numbered figures */
|
||||
figure.numbered > figcaption > p:before {
|
||||
counter-increment: figure;
|
||||
content: "Figure " counter(figure) ": ";
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
/* Admonitions and System Messages */
|
||||
.caution p.admonition-title,
|
||||
.attention p.admonition-title,
|
||||
.danger p.admonition-title,
|
||||
.error p.admonition-title,
|
||||
.warning p.admonition-title,
|
||||
div.error {
|
||||
color: red;
|
||||
}
|
||||
|
||||
/* Sidebar */
|
||||
/* Move right. In a layout with fixed margins, */
|
||||
/* it can be moved into the margin. */
|
||||
aside.sidebar {
|
||||
width: 30%;
|
||||
max-width: 26em;
|
||||
float: right;
|
||||
clear: right;
|
||||
margin-left: 1em;
|
||||
margin-right: -1%;
|
||||
background-color: #fffffa;
|
||||
}
|
||||
|
||||
|
||||
/* Code */
|
||||
pre.code { padding: 0.7ex }
|
||||
pre.code, code { background-color: #eeeeee }
|
||||
/* basic highlighting: for a complete scheme, see */
|
||||
/* https://docutils.sourceforge.io/sandbox/stylesheets/ */
|
||||
pre.code .comment, code .comment { color: #5C6576 }
|
||||
pre.code .keyword, code .keyword { color: #3B0D06; font-weight: bold }
|
||||
pre.code .literal.string, code .literal.string { color: #0C5404 }
|
||||
pre.code .name.builtin, code .name.builtin { color: #352B84 }
|
||||
pre.code .deleted, code .deleted { background-color: #DEB0A1}
|
||||
pre.code .inserted, code .inserted { background-color: #A3D289}
|
||||
|
||||
|
||||
/* Epigraph */
|
||||
/* Highlights */
|
||||
/* Pull-Quote */
|
||||
/* Compound Paragraph */
|
||||
/* Container */
|
||||
|
||||
/* Inline Markup */
|
||||
/* ============= */
|
||||
|
||||
sup, sub { line-height: 0.8; } /* do not add leading for lines with sup/sub */
|
||||
|
||||
/* Inline Literals */
|
||||
/* possible values: normal, nowrap, pre, pre-wrap, pre-line */
|
||||
/* span.docutils.literal { white-space: pre-wrap; } */
|
||||
|
||||
/* Hyperlink References */
|
||||
a { text-decoration: none; }
|
||||
|
||||
/* External Targets */
|
||||
/* span.target.external */
|
||||
/* Internal Targets */
|
||||
/* span.target.internal */
|
||||
/* Footnote References */
|
||||
/* a[role="doc-noteref"] */
|
||||
/* Citation References */
|
||||
/* a.citation-reference */
|
|
@ -0,0 +1,486 @@
|
|||
/* CSS3_ style sheet for the output of Docutils HTML5 writer. */
|
||||
/* Generic responsive design for all screen sizes. */
|
||||
/* */
|
||||
/* :Author: Günter Milde */
|
||||
/* */
|
||||
/* :Id: $Id: responsive.css 9615 2024-04-06 13:28:15Z milde $ */
|
||||
/* :Copyright: © 2021 Günter Milde. */
|
||||
/* :License: Released under the terms of the `2-Clause BSD license`_, */
|
||||
/* in short: */
|
||||
/* */
|
||||
/* Copying and distribution of this file, with or without modification, */
|
||||
/* are permitted in any medium without royalty provided the copyright */
|
||||
/* notice and this notice are preserved. */
|
||||
/* */
|
||||
/* This file is offered as-is, without any warranty. */
|
||||
/* */
|
||||
/* .. _2-Clause BSD license: http://www.spdx.org/licenses/BSD-2-Clause */
|
||||
/* .. _CSS3: https://www.w3.org/Style/CSS/ */
|
||||
|
||||
/* Note: */
|
||||
/* This style sheet is provisional: */
|
||||
/* the API is not settled and may change with any minor Docutils version. */
|
||||
|
||||
|
||||
|
||||
/* General Settings */
|
||||
/* ================ */
|
||||
|
||||
|
||||
* { box-sizing: border-box; }
|
||||
|
||||
body {
|
||||
background-color: #fafaf6;
|
||||
margin: auto;
|
||||
--field-indent: 6.6em; /* indent of fields in field lists */
|
||||
--sidebar-margin-right: 0; /* adapted in media queries below */
|
||||
}
|
||||
main {
|
||||
counter-reset: figure table;
|
||||
}
|
||||
body > * {
|
||||
background-color: white;
|
||||
line-height: 1.6;
|
||||
padding: 0.5rem calc(29% - 7.2rem); /* go from 5% to 15% (8.15em/54em) */
|
||||
margin: auto;
|
||||
max-width: 100rem;
|
||||
}
|
||||
sup, sub { /* avoid additional inter-line space for lines with sup/sub */
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
/* Vertical Space (Parskip) */
|
||||
p, ol, ul, dl, li,
|
||||
.topic,
|
||||
.footnote, .citation,
|
||||
div > math,
|
||||
table {
|
||||
margin-top: 0.5em;
|
||||
margin-bottom: 0.5em;
|
||||
}
|
||||
h1, h2, h3, h4, h5, h6,
|
||||
dl > dd, details > p:last-child {
|
||||
margin-bottom: 0.5em;
|
||||
}
|
||||
|
||||
/* Indented Blocks */
|
||||
blockquote, figure, .topic {
|
||||
margin: 1em 2%;
|
||||
padding-left: 1em;
|
||||
}
|
||||
div.line-block div.line-block,
|
||||
pre, dd, dl.option-list {
|
||||
margin-left: calc(2% + 1em);
|
||||
}
|
||||
|
||||
/* Object styling */
|
||||
/* ============== */
|
||||
|
||||
footer, header {
|
||||
font-size: small;
|
||||
}
|
||||
|
||||
/* Frontmatter */
|
||||
div.dedication {
|
||||
padding: 0;
|
||||
margin: 1.4em 0;
|
||||
font-style: italic;
|
||||
font-size: large;
|
||||
}
|
||||
.dedication p.topic-title {
|
||||
display: none;
|
||||
}
|
||||
|
||||
blockquote p.attribution,
|
||||
.topic p.attribution {
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
/* Table of Contents */
|
||||
nav.contents ul {
|
||||
padding-left: 1em;
|
||||
}
|
||||
ul.auto-toc > li > p { /* hanging indent */
|
||||
padding-left: 1em;
|
||||
text-indent: -1em;
|
||||
}
|
||||
main > nav.contents ul:not(.auto-toc) {
|
||||
list-style-type: square;
|
||||
}
|
||||
main > nav.contents ul ul:not(.auto-toc) {
|
||||
list-style-type: disc;
|
||||
}
|
||||
main > nav.contents ul ul ul:not(.auto-toc) {
|
||||
list-style-type: '\2B29\ ';
|
||||
}
|
||||
main > nav.contents ul ul ul ul:not(.auto-toc) {
|
||||
list-style-type: '\2B1D\ ';
|
||||
}
|
||||
main > nav.contents ul ul ul ul ul:not(.auto-toc) {
|
||||
list-style-type: '\2B2A\ ';
|
||||
}
|
||||
nav.contents ul > li::marker {
|
||||
color: grey;
|
||||
}
|
||||
|
||||
/* Transitions */
|
||||
hr {
|
||||
margin: 1em 10%;
|
||||
}
|
||||
|
||||
/* Lists */
|
||||
|
||||
dl.field-list.narrow, dl.docinfo, dl.option-list {
|
||||
--field-indent: 2.4em;
|
||||
}
|
||||
|
||||
ul, ol {
|
||||
padding-left: 1.1em; /* indent by bullet width (Firefox, DejaVu fonts) */
|
||||
}
|
||||
dl.field-list > dd,
|
||||
dl.docinfo > dd {
|
||||
margin-left: var(--field-indent); /* adapted in media queries or HTML */
|
||||
}
|
||||
dl.option-list > dd {
|
||||
margin-left: 20%;
|
||||
}
|
||||
/* run-in: start field-body on same line after long field names */
|
||||
dl.field-list.run-in > dd p {
|
||||
display: block;
|
||||
}
|
||||
/* "description style" like in most dictionaries, encyclopedias etc. */
|
||||
dl.description {
|
||||
display: flow-root;
|
||||
}
|
||||
dl.description > dt {
|
||||
clear: left;
|
||||
float: left;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
padding-right: 0.3em;
|
||||
font-weight: bold;
|
||||
}
|
||||
dl.description > dd:after {
|
||||
display: table;
|
||||
content: "";
|
||||
clear: left; /* clearfix for empty descriptions */
|
||||
}
|
||||
/* start lists nested in description/field lists on new line */
|
||||
dd > dl:first-child,
|
||||
dd > ul:first-child,
|
||||
dd > ol:first-child {
|
||||
clear: left;
|
||||
}
|
||||
|
||||
/* disclosures */
|
||||
details { padding-left: 1em; }
|
||||
summary { margin-left: -1em; }
|
||||
|
||||
/* Footnotes and Citations */
|
||||
.footnote {
|
||||
font-size: small;
|
||||
}
|
||||
|
||||
/* Images, Figures, and Tables */
|
||||
figcaption,
|
||||
table > caption {
|
||||
/* font-size: small; */
|
||||
font-style: italic;
|
||||
}
|
||||
figcaption > .legend {
|
||||
font-size: small;
|
||||
font-style: initial;
|
||||
}
|
||||
figure.numbered > figcaption > p:before {
|
||||
counter-increment: figure;
|
||||
content: "Figure " counter(figure) ": ";
|
||||
font-weight: bold;
|
||||
font-style: initial;
|
||||
}
|
||||
|
||||
table tr {
|
||||
text-align: left;
|
||||
vertical-align: baseline;
|
||||
}
|
||||
table.booktabs { /* "booktabs" style (no vertical lines) */
|
||||
border-top: 2px solid;
|
||||
border-bottom: 2px solid;
|
||||
}
|
||||
table.booktabs * {
|
||||
border: 0;
|
||||
}
|
||||
table.booktabs th {
|
||||
border-bottom: thin solid;
|
||||
}
|
||||
table.numbered > caption:before {
|
||||
counter-increment: table;
|
||||
content: "Table " counter(table) ": ";
|
||||
font-weight: bold;
|
||||
font-style: initial;
|
||||
}
|
||||
|
||||
/* Admonitions and System Messages */
|
||||
.admonition,
|
||||
div.system-message {
|
||||
border: thin solid silver;
|
||||
margin: 1em 2%;
|
||||
padding: 0.5em 1em;
|
||||
}
|
||||
.caution p.admonition-title,
|
||||
.attention p.admonition-title,
|
||||
.danger p.admonition-title,
|
||||
.warning p.admonition-title,
|
||||
div.error {
|
||||
color: maroon;
|
||||
}
|
||||
div.system-message > p > span.literal {
|
||||
overflow-wrap: break-word;
|
||||
}
|
||||
|
||||
/* Literal and Code */
|
||||
pre.literal-block, pre.doctest{
|
||||
padding: 0.2em;
|
||||
overflow-x: auto;
|
||||
}
|
||||
.literal-block, .doctest, span.literal {
|
||||
background-color: #f6f9f8;
|
||||
}
|
||||
.system-message span.literal {
|
||||
background-color: inherit;
|
||||
}
|
||||
|
||||
/* basic highlighting: for a complete scheme, see */
|
||||
/* https://docutils.sourceforge.io/sandbox/stylesheets/ */
|
||||
pre.code .comment, code .comment { color: #5C6576 }
|
||||
pre.code .keyword, code .keyword { color: #3B0D06; font-weight: bold }
|
||||
pre.code .literal.string, code .literal.string { color: #0C5404 }
|
||||
pre.code .name.builtin, code .name.builtin { color: #352B84 }
|
||||
pre.code .deleted, code .deleted { background-color: #DEB0A1}
|
||||
pre.code .inserted, code .inserted { background-color: #A3D289}
|
||||
|
||||
/* Hyperlink References */
|
||||
a {
|
||||
text-decoration: none; /* for chromium */
|
||||
/* Wrap links at any place, if this is the only way to prevent overflow */
|
||||
overflow-wrap: break-word;
|
||||
}
|
||||
.contents a, a.toc-backref, a.citation-reference {
|
||||
overflow-wrap: inherit;
|
||||
}
|
||||
/* Undecorated Links (see also minimal.css) */
|
||||
/* a.citation-reference, */
|
||||
.citation a.fn-backref {
|
||||
color: inherit;
|
||||
}
|
||||
a:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
*:hover > a.toc-backref:after,
|
||||
.topic-title:hover > a:after {
|
||||
content: " \2191"; /* ↑ UPWARDS ARROW */
|
||||
color: grey;
|
||||
}
|
||||
*:hover > a.self-link:after {
|
||||
content: "\1F517"; /* LINK SYMBOL */
|
||||
color: grey;
|
||||
font-size: smaller;
|
||||
margin-left: 0.2em;
|
||||
}
|
||||
/* highlight specific targets of the current URL */
|
||||
section:target > h2, section:target > h3, section:target > h4,
|
||||
section:target > h5, section:target > h6,
|
||||
span:target + h2, span:target + h3, span:target + h4,
|
||||
span:target + h5, span:target + h6,
|
||||
dt:target, span:target,
|
||||
.contents :target,
|
||||
.contents:target > .topic-title,
|
||||
[role="doc-biblioentry"]:target > .label,
|
||||
[role="doc-biblioref"]:target,
|
||||
[role="note"]:target, /* Docutils 0.18 ... 0.19 */
|
||||
[role="doc-footnote"]:target, /* Docutils >= 0.20 */
|
||||
[role="doc-noteref"]:target {
|
||||
background-color: #d2e6ec;
|
||||
}
|
||||
|
||||
/* Block Alignment */
|
||||
/* Let content flow to the side of aligned images and figures */
|
||||
|
||||
/* no floats around this elements */
|
||||
footer, header, hr,
|
||||
h1, h2, h3 {
|
||||
clear: both;
|
||||
}
|
||||
|
||||
img.align-left,
|
||||
svg.align-left,
|
||||
video.align-left,
|
||||
figure.align-left,
|
||||
div.align-left,
|
||||
table.align-left {
|
||||
margin-left: 0;
|
||||
padding-left: 0;
|
||||
margin-right: 0.5em;
|
||||
clear: left;
|
||||
float: left;
|
||||
}
|
||||
img.align-right,
|
||||
svg.align-right,
|
||||
video.align-right,
|
||||
figure.align-right,
|
||||
div.align-right,
|
||||
table.align-right {
|
||||
margin-left: 0.5em;
|
||||
margin-right: 0;
|
||||
clear: right;
|
||||
float: right;
|
||||
}
|
||||
|
||||
/* Margin Elements */
|
||||
/* see below for screen size dependent rules */
|
||||
.sidebar,
|
||||
.marginal,
|
||||
.admonition.marginal {
|
||||
max-width: 40%;
|
||||
border: none;
|
||||
background-color: #efefea;
|
||||
margin: 0.5em var(--sidebar-margin-right) 0.5em 1em;
|
||||
padding: 0.5em;
|
||||
padding-left: 0.7em;
|
||||
clear: right;
|
||||
float: right;
|
||||
font-size: small;
|
||||
}
|
||||
.sidebar {
|
||||
width: 40%;
|
||||
}
|
||||
|
||||
/* Adaptive page layout */
|
||||
/* ==================== */
|
||||
|
||||
@media (max-width: 30em) {
|
||||
/* Smaller margins and no floating elements for small screens */
|
||||
/* (main text less than 40 characters/line) */
|
||||
body > * {
|
||||
padding: 0.5rem 5%;
|
||||
line-height: 1.4
|
||||
}
|
||||
.sidebar,
|
||||
.marginal,
|
||||
.admonition.marginal {
|
||||
width: auto;
|
||||
max-width: 100%;
|
||||
float: none;
|
||||
}
|
||||
dl.option-list,
|
||||
pre {
|
||||
margin-left: 0;
|
||||
}
|
||||
body {
|
||||
--field-indent: 4em;
|
||||
}
|
||||
pre, pre * {
|
||||
font-size: 0.9em;
|
||||
/* overflow: auto; */
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 54em) {
|
||||
/* Move ToC to the left */
|
||||
/* Main text width before: 70% ≙ 35em ≙ 75…95 chrs (Dejavu/Times) */
|
||||
/* after: ≳ 30em ≙ 54…70 chrs (Dejavu/Times) */
|
||||
body.with-toc {
|
||||
padding-left: 8%;
|
||||
}
|
||||
body.with-toc > * {
|
||||
margin-left: 0;
|
||||
padding-left: 22rem; /* fallback for webkit */
|
||||
padding-left: min(22%, 22rem);
|
||||
padding-right: 7%;
|
||||
}
|
||||
main > nav.contents { /* global ToC */
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: min(25%, 25em);
|
||||
height: 100vh;
|
||||
margin: 0;
|
||||
background-color: #fafaf6;
|
||||
padding: 1em 2% 0 2%;
|
||||
overflow: auto;
|
||||
}
|
||||
main > nav.contents > * {
|
||||
padding-left: 0;
|
||||
line-height: 1.4;
|
||||
}
|
||||
main > nav.contents a {
|
||||
color: inherit;
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 70em) {
|
||||
body {
|
||||
--field-indent: 9em;
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 77em) {
|
||||
/* Move marginalia to 6rem from right border */
|
||||
/* .sidebar, */
|
||||
/* .marginal, */
|
||||
/* .admonition.marginal { */
|
||||
/* margin-right: calc(6rem - 15%); */
|
||||
/* } */
|
||||
/* BUG: margin is calculated for break point width */
|
||||
/* workaround: variable + many breakpoints */
|
||||
body > * {
|
||||
padding-left: 18%;
|
||||
padding-right: 28%; /* fallback for webkit */
|
||||
padding-right: min(28%, 28rem);
|
||||
--sidebar-margin-right: -20rem;
|
||||
}
|
||||
/* limit main text to ~ 50em ≙ 85…100 characters DejaVu rsp. …120 Times */
|
||||
body.with-toc > * {
|
||||
padding-left: min(22%, 22rem);
|
||||
padding-right: calc(78% - 50rem); /* fallback for webkit */
|
||||
padding-right: min(78% - 50rem, 28rem);
|
||||
--sidebar-margin-right: 0;
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 85em) {
|
||||
body.with-toc > * {
|
||||
--sidebar-margin-right: -9rem;
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 90em) {
|
||||
/* move marginalia into the margin */
|
||||
body > * {
|
||||
padding-left: min(22%, 22rem);
|
||||
--sidebar-margin-right: -23rem;
|
||||
}
|
||||
body.with-toc > * {
|
||||
--sidebar-margin-right: -14rem;
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 99em) {
|
||||
/* move marginalia out of main text area */
|
||||
body.with-toc > * {
|
||||
--sidebar-margin-right: -20rem;
|
||||
}
|
||||
body > *, body.with-toc > * { /* for webkit */
|
||||
padding-left: 22rem;
|
||||
padding-right: 28rem;
|
||||
}
|
||||
.admonition.marginal,
|
||||
.marginal {
|
||||
width: 40%; /* make marginal figures, ... "full width" */
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 104em) {
|
||||
body.with-toc > * {
|
||||
--sidebar-margin-right: -23rem;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
%(head_prefix)s
|
||||
%(head)s
|
||||
%(stylesheet)s
|
||||
%(body_prefix)s
|
||||
%(body_pre_docinfo)s
|
||||
%(docinfo)s
|
||||
%(body)s
|
||||
%(body_suffix)s
|
|
@ -0,0 +1,566 @@
|
|||
/* CSS3_ style sheet for the output of Docutils HTML writers. */
|
||||
/* Rules inspired by Edward Tufte's layout design. */
|
||||
/* */
|
||||
/* :Author: Günter Milde */
|
||||
/* based on tufte.css_ by Dave Liepmann */
|
||||
/* and the tufte-latex_ package. */
|
||||
/* */
|
||||
/* :Id: $Id: tuftig.css 9503 2023-12-16 22:37:59Z milde $ */
|
||||
/* :Copyright: © 2020 Günter Milde. */
|
||||
/* :License: Released under the terms of the `2-Clause BSD license`_, */
|
||||
/* in short: */
|
||||
/* */
|
||||
/* Copying and distribution of this file, with or without modification, */
|
||||
/* are permitted in any medium without royalty provided the copyright */
|
||||
/* notice and this notice are preserved. */
|
||||
/* */
|
||||
/* This file is offered as-is, without any warranty. */
|
||||
/* */
|
||||
/* .. _2-Clause BSD license: http://www.spdx.org/licenses/BSD-2-Clause */
|
||||
/* .. _CSS3: https://www.w3.org/Style/CSS/ */
|
||||
/* .. _tufte.css: https://edwardtufte.github.io/tufte-css/ */
|
||||
/* .. _tufte-latex_: https://www.ctan.org/pkg/tufte-latex */
|
||||
|
||||
|
||||
/* General Settings */
|
||||
/* ================ */
|
||||
|
||||
body {
|
||||
font-family: Georgia, serif;
|
||||
background-color: #fafaf6;
|
||||
font-size: 1.2em;
|
||||
line-height: 1.4;
|
||||
margin: auto;
|
||||
}
|
||||
main {
|
||||
counter-reset: figure table;
|
||||
}
|
||||
main, header, footer {
|
||||
padding: 0.5em 5%;
|
||||
background-color: #fefef8;
|
||||
max-width: 100rem;
|
||||
}
|
||||
|
||||
/* Spacing */
|
||||
|
||||
/* vertical space (parskip) */
|
||||
p, ol, ul, dl, li,
|
||||
h1, h2, h3, h4, h5, h6,
|
||||
div.line-block,
|
||||
.topic,
|
||||
.footnote, .citation,
|
||||
table {
|
||||
margin-top: 0.5em;
|
||||
margin-bottom: 0.5em;
|
||||
}
|
||||
dl > dd {
|
||||
margin-bottom: 0.5em;
|
||||
}
|
||||
/* exceptions */
|
||||
p:first-child {
|
||||
margin-top: 0;
|
||||
}
|
||||
p:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
/* Indented Blocks */
|
||||
blockquote,
|
||||
.topic {
|
||||
/* background-color: Honeydew; */
|
||||
margin: 0.5em 2%;
|
||||
padding-left: 1em;
|
||||
}
|
||||
div.line-block div.line-block,
|
||||
dl.option-list,
|
||||
figure > img,
|
||||
pre.literal-block, pre.math,
|
||||
pre.doctest-block, pre.code {
|
||||
/* background-color: LightCyan; */
|
||||
margin-left: calc(2% + 1em);
|
||||
}
|
||||
|
||||
/* Object styling */
|
||||
/* ============== */
|
||||
|
||||
footer, header {
|
||||
font-size: smaller;
|
||||
}
|
||||
|
||||
/* Titles and Headings */
|
||||
|
||||
h2, h3, h4, p.subtitle, p.section-subtitle,
|
||||
p.topic-title, p.sidebar-title, p.sidebar-subtitle {
|
||||
font-weight: normal;
|
||||
font-style: italic;
|
||||
text-align: left;
|
||||
}
|
||||
.sectnum {
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
h1.title {
|
||||
text-align: left;
|
||||
margin-top: 2.4em;
|
||||
margin-bottom: 2em;
|
||||
font-size: 2.4em;
|
||||
}
|
||||
h1 + p.subtitle {
|
||||
margin-top: -2em;
|
||||
margin-bottom: 2em;
|
||||
font-size: 2.0em;
|
||||
}
|
||||
section {
|
||||
margin-top: 2em;
|
||||
}
|
||||
h2, .contents > p.topic-title {
|
||||
font-size: 2.2em;
|
||||
}
|
||||
h2 + p.section-subtitle {
|
||||
font-size: 1.6em;
|
||||
}
|
||||
h3 {
|
||||
font-size: 1.2em;
|
||||
}
|
||||
h3 + p.section-subtitle {
|
||||
font-size: 1.1em;
|
||||
}
|
||||
h4 {
|
||||
font-size: 1em;
|
||||
}
|
||||
p.section-subtitle {
|
||||
font-size: 1em;
|
||||
}
|
||||
|
||||
/* Dedication and Abstract */
|
||||
div.dedication {
|
||||
padding: 0;
|
||||
margin-left: 0;
|
||||
font-style: italic;
|
||||
font-size: 1.2em;
|
||||
}
|
||||
/* div.abstract p.topic-title, */
|
||||
div.dedication p.topic-title {
|
||||
display: none;
|
||||
}
|
||||
|
||||
/* Attribution */
|
||||
blockquote p.attribution,
|
||||
.topic p.attribution {
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
/* Table of Contents */
|
||||
nav.contents {
|
||||
padding: 0;
|
||||
font-style: italic;
|
||||
}
|
||||
ul.auto-toc > li > p {
|
||||
padding-left: 1em;
|
||||
text-indent: -1em;
|
||||
}
|
||||
nav.contents ul {
|
||||
padding-left: 1em;
|
||||
}
|
||||
|
||||
|
||||
/* Transitions */
|
||||
hr {
|
||||
border: 0;
|
||||
border-top: 1px solid #ccc;
|
||||
margin: 1em 10%;
|
||||
}
|
||||
|
||||
/* Lists */
|
||||
/* Less indent per level */
|
||||
ul, ol {
|
||||
padding-left: 1.1em;
|
||||
}
|
||||
dd {
|
||||
margin-left: 1.5em;
|
||||
}
|
||||
dd > dl:first-child,
|
||||
dd > ul:first-child,
|
||||
dd > ol:first-child {
|
||||
/* lists nested in definition/description/field lists */
|
||||
clear: left;
|
||||
}
|
||||
|
||||
dl.field-list > dd,
|
||||
dl.docinfo > dd,
|
||||
dl.option-list > dd {
|
||||
margin-left: 4em;
|
||||
}
|
||||
/* example for custom field-name width */
|
||||
dl.field-list.narrow > dd {
|
||||
margin-left: 3em;
|
||||
}
|
||||
/* run-in: start field-body on same line after long field names */
|
||||
dl.field-list.run-in > dd p {
|
||||
display: block;
|
||||
}
|
||||
/* italic field name */
|
||||
dl.description > dt,
|
||||
dl.field-list > dt,
|
||||
dl.docinfo > dt {
|
||||
font-weight: normal;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
/* "description style" like in most dictionaries, encyclopedias etc. */
|
||||
dl.description > dt {
|
||||
clear: left;
|
||||
float: left;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
padding-right: 0.5em;
|
||||
}
|
||||
dl.description > dd:after {
|
||||
display: block;
|
||||
content: "";
|
||||
clear: both;
|
||||
}
|
||||
|
||||
/* Citation list (style as description list) */
|
||||
.citation-list,
|
||||
.footnote-list {
|
||||
display: contents;
|
||||
}
|
||||
.citation {
|
||||
padding-left: 1.5em;
|
||||
}
|
||||
.citation .label {
|
||||
margin-left: -1.5em;
|
||||
}
|
||||
|
||||
/* Images and Figures */
|
||||
/* Caption to the left (if there is space) or below: */
|
||||
figure {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
align-items: flex-start;
|
||||
margin: 0.5em 2%;
|
||||
padding-left: 1em;
|
||||
}
|
||||
figure > img,
|
||||
figure.fullwidth > img {
|
||||
margin: 0 0.5em 0.5em 0;
|
||||
padding: 0;
|
||||
}
|
||||
figcaption {
|
||||
font-size: 0.8em;
|
||||
}
|
||||
.fullwidth > figcaption {
|
||||
font-size: inherit;
|
||||
}
|
||||
figure.numbered > figcaption > p:before {
|
||||
counter-increment: figure;
|
||||
content: "Figure " counter(figure) ": ";
|
||||
}
|
||||
|
||||
/* Tables */
|
||||
table tr {
|
||||
text-align: left;
|
||||
}
|
||||
/* th { vertical-align: bottom; } */
|
||||
/* "booktabs" style (no vertical lines) */
|
||||
table.booktabs {
|
||||
border-top: 2px solid;
|
||||
border-bottom: 2px solid;
|
||||
}
|
||||
table.booktabs * {
|
||||
border: 0;
|
||||
}
|
||||
table.booktabs th {
|
||||
border-bottom: thin solid;
|
||||
}
|
||||
table.numbered > caption:before {
|
||||
counter-increment: table;
|
||||
content: "Table " counter(table) ": ";
|
||||
}
|
||||
|
||||
/* Admonitions and System Messages */
|
||||
.admonition, .system-message {
|
||||
border-style: solid;
|
||||
border-color: silver;
|
||||
border-width: thin;
|
||||
margin: 1em 0;
|
||||
padding: 0.5em;
|
||||
}
|
||||
.caution p.admonition-title,
|
||||
.attention p.admonition-title,
|
||||
.danger p.admonition-title,
|
||||
.warning p.admonition-title,
|
||||
div.error {
|
||||
color: maroon;
|
||||
}
|
||||
|
||||
/* Literal and Code */
|
||||
pre.literal-block, pre.doctest-block,
|
||||
pre.math, pre.code {
|
||||
/* font-family: Consolas, "Liberation Mono", Menlo, monospace; */
|
||||
/* font-size: 0.9em; */
|
||||
overflow: auto;
|
||||
}
|
||||
/* basic highlighting: for a complete scheme, see */
|
||||
/* https://docutils.sourceforge.io/sandbox/stylesheets/ */
|
||||
pre.code .comment, code .comment { color: #5C6576 }
|
||||
pre.code .keyword, code .keyword { color: #3B0D06; font-weight: bold }
|
||||
pre.code .literal.string, code .literal.string { color: #0C5404 }
|
||||
pre.code .name.builtin, code .name.builtin { color: #352B84 }
|
||||
pre.code .deleted, code .deleted { background-color: #DEB0A1}
|
||||
pre.code .inserted, code .inserted { background-color: #A3D289}
|
||||
|
||||
.sans {
|
||||
font-family: "Gill Sans", "Gill Sans MT", Calibri, "Lucida Sans", "Noto Sans", sans-serif;
|
||||
letter-spacing: .02em;
|
||||
}
|
||||
|
||||
/* Hyperlink References */
|
||||
/* underline that clears descenders */
|
||||
a {
|
||||
color: inherit;
|
||||
}
|
||||
a:link {
|
||||
text-decoration: underline;
|
||||
/* text-decoration-skip-ink: auto; nonstandard selector */
|
||||
}
|
||||
/* undecorated links */
|
||||
.contents a:link, a.toc-backref:link, a.image-reference:link,
|
||||
a[role="doc-noteref"]:link, a[role="doc-backlink"]:link, .backrefs a:link,
|
||||
a.citation-reference:link,
|
||||
a[href^="#system-message"] {
|
||||
text-decoration: none;
|
||||
}
|
||||
a:link:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
/* Block Alignment */
|
||||
/* Let content flow to the side of aligned images and figures */
|
||||
/* (does not work if the image/figure is a grid element). */
|
||||
|
||||
/* no floats around this elements */
|
||||
footer, header,
|
||||
hr.docutils,
|
||||
h1, h2, h3, .contents > p.topic-title,
|
||||
.fullwidth {
|
||||
clear: both;
|
||||
}
|
||||
|
||||
img.align-left,
|
||||
svg.align-left,
|
||||
video.align-left,
|
||||
figure.align-left,
|
||||
div.align-left,
|
||||
table.align-left {
|
||||
margin-left: 0;
|
||||
padding-left: 0;
|
||||
padding-right: 0.5em;
|
||||
clear: left;
|
||||
float: left;
|
||||
}
|
||||
figure.align-left > img {
|
||||
margin-left: 0;
|
||||
padding-left: 0;
|
||||
}
|
||||
|
||||
img.align-right,
|
||||
svg.align-right,
|
||||
video.align-right,
|
||||
div.align-right {
|
||||
padding-left: 0.5em;
|
||||
clear: right;
|
||||
float: right;
|
||||
}
|
||||
figure.align-right {
|
||||
clear: right;
|
||||
float: right;
|
||||
}
|
||||
figure.align-right > img {
|
||||
justify-self: right;
|
||||
padding: 0;
|
||||
}
|
||||
table.align-right {
|
||||
margin-right: 2.5%;
|
||||
}
|
||||
|
||||
figure.align-center {
|
||||
align-content: center;
|
||||
justify-content: center;
|
||||
}
|
||||
figure.align-center > img {
|
||||
padding-left: 0;
|
||||
justify-self: center;
|
||||
}
|
||||
|
||||
/* Margin Elements */
|
||||
/* see below for screen size dependent rules */
|
||||
aside.sidebar,
|
||||
.marginal,
|
||||
.admonition.marginal,
|
||||
.topic.marginal {
|
||||
background-color: #efefea;
|
||||
box-sizing: border-box;
|
||||
margin-left: 2%;
|
||||
margin-right: 0;
|
||||
padding: 0.5em;
|
||||
font-size: 0.8em;
|
||||
}
|
||||
aside.sidebar {
|
||||
background-color: inherit;
|
||||
}
|
||||
figure.marginal > figcaption {
|
||||
font-size: 1em;
|
||||
}
|
||||
.footnote {
|
||||
font-size: smaller;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
/* Adaptive page layout */
|
||||
|
||||
/* no floating for very small Screens */
|
||||
/* (main text up to ca. 40 characters/line) */
|
||||
@media (min-width: 35em) {
|
||||
main, header, footer {
|
||||
padding: 0.5em calc(15% - 3rem);
|
||||
line-height: 1.6
|
||||
}
|
||||
aside.sidebar,
|
||||
.marginal,
|
||||
.admonition.marginal,
|
||||
.topic.marginal {
|
||||
max-width: 45%;
|
||||
float: right;
|
||||
clear: right;
|
||||
}
|
||||
dl.field-list > dd,
|
||||
dl.docinfo > dd {
|
||||
margin-left: 6em;
|
||||
}
|
||||
dl.option-list > dd {
|
||||
margin-left: 6em;
|
||||
}
|
||||
}
|
||||
|
||||
/* 2 column layout with wide margin */
|
||||
@media (min-width: 65em) {
|
||||
/* use the same grid for main, all sections, and figures */
|
||||
main, section {
|
||||
display: grid;
|
||||
grid-template-columns: [content] minmax(0, 6fr)
|
||||
[margin] 3fr [end];
|
||||
grid-column-gap: calc(3em + 1%);
|
||||
}
|
||||
main > section, section > section {
|
||||
grid-column: 1 / end;
|
||||
}
|
||||
main, header, footer {
|
||||
padding-right: 5%; /* less padding right of margin-column */
|
||||
}
|
||||
section > figure {
|
||||
display: contents; /* to place caption in the margin */
|
||||
}
|
||||
/* Main text elements */
|
||||
main > *, section > *,
|
||||
figure > img,
|
||||
.footnote.align-left, /* override the placement in the margin */
|
||||
.citation.align-left {
|
||||
grid-column: content;
|
||||
}
|
||||
.citation.align-left {
|
||||
font-size: 1em;
|
||||
padding-left: 1.5em;
|
||||
}
|
||||
.citation.align-left .label {
|
||||
margin-left: -1.5em;
|
||||
}
|
||||
figure > img { /* indent */
|
||||
margin: 0.5em 2%;
|
||||
padding-left: 1em;
|
||||
}
|
||||
|
||||
/* Margin Elements */
|
||||
/* Sidebar, Footnotes, Citations, Captions */
|
||||
aside.sidebar,
|
||||
.citation,
|
||||
.footnote,
|
||||
figcaption,
|
||||
/* table > caption, does not work :(*/
|
||||
.marginal,
|
||||
.admonition.marginal,
|
||||
.topic.marginal {
|
||||
/* color: red; */
|
||||
grid-column: margin;
|
||||
width: auto;
|
||||
max-width: 55em;
|
||||
margin: 0.5em 0;
|
||||
border: none;
|
||||
padding: 0;
|
||||
font-size: 0.8em;
|
||||
text-align: initial; /* overwrite align-* */
|
||||
background-color: inherit;
|
||||
}
|
||||
.admonition.marginal {
|
||||
padding: 0.5em;
|
||||
}
|
||||
figure.marginal {
|
||||
display: block;
|
||||
margin: 0.5em 0;
|
||||
}
|
||||
.citation,
|
||||
.footnote {
|
||||
padding-left: 0;
|
||||
}
|
||||
.citation .label,
|
||||
.footnote .label {
|
||||
margin-left: 0;
|
||||
}
|
||||
|
||||
/* Fullwidth Elements */
|
||||
h1.title, p.subtitle,
|
||||
dl.docinfo,
|
||||
div.abstract,
|
||||
div.dedication,
|
||||
nav.contents,
|
||||
aside.system-message,
|
||||
pre,
|
||||
.fullwidth,
|
||||
.fullwidth img,
|
||||
.fullwidth figcaption {
|
||||
/* background-color: Linen; */
|
||||
grid-column: content / end;
|
||||
margin-right: calc(10% - 3rem);
|
||||
max-width: 55em;
|
||||
}
|
||||
}
|
||||
|
||||
/* 3 column layout */
|
||||
|
||||
@media (min-width: 100em) {
|
||||
main, header, footer {
|
||||
padding-left: 30%;
|
||||
}
|
||||
main > nav.contents {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
box-sizing: border-box;
|
||||
width: 25%;
|
||||
height: 100vh;
|
||||
margin: 0;
|
||||
background-color: #fafaf6;
|
||||
padding: 5.5em 2%;
|
||||
overflow: auto;
|
||||
}
|
||||
main > nav.contents > * {
|
||||
padding-left: 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* wrap URLs */
|
||||
/* a:link { */
|
||||
/* white-space: normal; */
|
||||
/* hyphens: none; */
|
||||
/* } */
|
File diff suppressed because it is too large
Load diff
Binary file not shown.
|
@ -0,0 +1,14 @@
|
|||
$head_prefix% generated by Docutils <https://docutils.sourceforge.io/>
|
||||
\usepackage{cmap} % fix search and cut-and-paste in Acrobat
|
||||
$requirements
|
||||
%%% Custom LaTeX preamble
|
||||
$latex_preamble
|
||||
%%% User specified packages and stylesheets
|
||||
$stylesheet
|
||||
%%% Fallback definitions for Docutils-specific commands
|
||||
$fallbacks
|
||||
$pdfsetup
|
||||
%%% Body
|
||||
\begin{document}
|
||||
$titledata$body_pre_docinfo$docinfo$dedication$abstract$body
|
||||
\end{document}
|
|
@ -0,0 +1,223 @@
|
|||
%% docutils.sty: macros for Docutils LaTeX output.
|
||||
%%
|
||||
%% Copyright © 2020 Günter Milde
|
||||
%% Released under the terms of the `2-Clause BSD license`, in short:
|
||||
%%
|
||||
%% Copying and distribution of this file, with or without modification,
|
||||
%% are permitted in any medium without royalty provided the copyright
|
||||
%% notice and this notice are preserved.
|
||||
%% This file is offered as-is, without any warranty.
|
||||
|
||||
% .. include:: README.md
|
||||
%
|
||||
% Implementation
|
||||
% ==============
|
||||
%
|
||||
% ::
|
||||
|
||||
\NeedsTeXFormat{LaTeX2e}
|
||||
\ProvidesPackage{docutils}
|
||||
[2021/05/18 macros for Docutils LaTeX output]
|
||||
|
||||
% Helpers
|
||||
% -------
|
||||
%
|
||||
% duclass::
|
||||
|
||||
% class handling for environments (block-level elements)
|
||||
% \begin{DUclass}{spam} tries \DUCLASSspam and
|
||||
% \end{DUclass}{spam} tries \endDUCLASSspam
|
||||
\ifx\DUclass\undefined % poor man's "provideenvironment"
|
||||
\newenvironment{DUclass}[1]%
|
||||
{% "#1" does not work in end-part of environment.
|
||||
\def\DocutilsClassFunctionName{DUCLASS#1}
|
||||
\csname \DocutilsClassFunctionName \endcsname}%
|
||||
{\csname end\DocutilsClassFunctionName \endcsname}%
|
||||
\fi
|
||||
|
||||
% providelength::
|
||||
|
||||
% Provide a length variable and set default, if it is new
|
||||
\providecommand*{\DUprovidelength}[2]{
|
||||
\ifthenelse{\isundefined{#1}}{\newlength{#1}\setlength{#1}{#2}}{}
|
||||
}
|
||||
|
||||
|
||||
% Configuration defaults
|
||||
% ----------------------
|
||||
%
|
||||
% See `Docutils LaTeX Writer`_ for details.
|
||||
%
|
||||
% abstract::
|
||||
|
||||
\providecommand*{\DUCLASSabstract}{
|
||||
\renewcommand{\DUtitle}[1]{\centerline{\textbf{##1}}}
|
||||
}
|
||||
|
||||
% dedication::
|
||||
|
||||
% special topic for dedications
|
||||
\providecommand*{\DUCLASSdedication}{%
|
||||
\renewenvironment{quote}{\begin{center}}{\end{center}}%
|
||||
}
|
||||
|
||||
% TODO: add \em to set dedication text in italics?
|
||||
%
|
||||
% docinfo::
|
||||
|
||||
% width of docinfo table
|
||||
\DUprovidelength{\DUdocinfowidth}{0.9\linewidth}
|
||||
|
||||
% error::
|
||||
|
||||
\providecommand*{\DUCLASSerror}{\color{red}}
|
||||
|
||||
% highlight_rules::
|
||||
|
||||
% basic code highlight:
|
||||
\providecommand*\DUrolecomment[1]{\textcolor[rgb]{0.40,0.40,0.40}{#1}}
|
||||
\providecommand*\DUroledeleted[1]{\textcolor[rgb]{0.40,0.40,0.40}{#1}}
|
||||
\providecommand*\DUrolekeyword[1]{\textbf{#1}}
|
||||
\providecommand*\DUrolestring[1]{\textit{#1}}
|
||||
|
||||
% Elements
|
||||
% --------
|
||||
%
|
||||
% Definitions for unknown or to-be-configured Docutils elements.
|
||||
%
|
||||
% admonition::
|
||||
|
||||
% admonition environment (specially marked topic)
|
||||
\ifx\DUadmonition\undefined % poor man's "provideenvironment"
|
||||
\newbox{\DUadmonitionbox}
|
||||
\newenvironment{DUadmonition}%
|
||||
{\begin{center}
|
||||
\begin{lrbox}{\DUadmonitionbox}
|
||||
\begin{minipage}{0.9\linewidth}
|
||||
}%
|
||||
{ \end{minipage}
|
||||
\end{lrbox}
|
||||
\fbox{\usebox{\DUadmonitionbox}}
|
||||
\end{center}
|
||||
}
|
||||
\fi
|
||||
|
||||
% fieldlist::
|
||||
|
||||
% field list environment (for separate configuration of `field lists`)
|
||||
\ifthenelse{\isundefined{\DUfieldlist}}{
|
||||
\newenvironment{DUfieldlist}%
|
||||
{\quote\description}
|
||||
{\enddescription\endquote}
|
||||
}{}
|
||||
|
||||
% footnotes::
|
||||
|
||||
% numerical or symbol footnotes with hyperlinks and backlinks
|
||||
\providecommand*{\DUfootnotemark}[3]{%
|
||||
\raisebox{1em}{\hypertarget{#1}{}}%
|
||||
\hyperlink{#2}{\textsuperscript{#3}}%
|
||||
}
|
||||
\providecommand{\DUfootnotetext}[4]{%
|
||||
\begingroup%
|
||||
\renewcommand{\thefootnote}{%
|
||||
\protect\raisebox{1em}{\protect\hypertarget{#1}{}}%
|
||||
\protect\hyperlink{#2}{#3}}%
|
||||
\footnotetext{#4}%
|
||||
\endgroup%
|
||||
}
|
||||
|
||||
% inline::
|
||||
|
||||
% custom inline roles: \DUrole{#1}{#2} tries \DUrole#1{#2}
|
||||
\providecommand*{\DUrole}[2]{%
|
||||
\ifcsname DUrole#1\endcsname%
|
||||
\csname DUrole#1\endcsname{#2}%
|
||||
\else%
|
||||
#2%
|
||||
\fi%
|
||||
}
|
||||
|
||||
% legend::
|
||||
|
||||
% legend environment (in figures and formal tables)
|
||||
\ifthenelse{\isundefined{\DUlegend}}{
|
||||
\newenvironment{DUlegend}{\small}{}
|
||||
}{}
|
||||
|
||||
% lineblock::
|
||||
|
||||
% line block environment
|
||||
\DUprovidelength{\DUlineblockindent}{2.5em}
|
||||
\ifthenelse{\isundefined{\DUlineblock}}{
|
||||
\newenvironment{DUlineblock}[1]{%
|
||||
\list{}{\setlength{\partopsep}{\parskip}
|
||||
\addtolength{\partopsep}{\baselineskip}
|
||||
\setlength{\topsep}{0pt}
|
||||
\setlength{\itemsep}{0.15\baselineskip}
|
||||
\setlength{\parsep}{0pt}
|
||||
\setlength{\leftmargin}{#1}}
|
||||
\raggedright
|
||||
}
|
||||
{\endlist}
|
||||
}{}
|
||||
|
||||
% optionlist::
|
||||
|
||||
% list of command line options
|
||||
\providecommand*{\DUoptionlistlabel}[1]{\bfseries #1 \hfill}
|
||||
\DUprovidelength{\DUoptionlistindent}{3cm}
|
||||
\ifthenelse{\isundefined{\DUoptionlist}}{
|
||||
\newenvironment{DUoptionlist}{%
|
||||
\list{}{\setlength{\labelwidth}{\DUoptionlistindent}
|
||||
\setlength{\rightmargin}{1cm}
|
||||
\setlength{\leftmargin}{\rightmargin}
|
||||
\addtolength{\leftmargin}{\labelwidth}
|
||||
\addtolength{\leftmargin}{\labelsep}
|
||||
\renewcommand{\makelabel}{\DUoptionlistlabel}}
|
||||
}
|
||||
{\endlist}
|
||||
}{}
|
||||
|
||||
% rubric::
|
||||
|
||||
% informal heading
|
||||
\providecommand*{\DUrubric}[1]{\subsubsection*{\emph{#1}}}
|
||||
|
||||
% sidebar::
|
||||
|
||||
% text outside the main text flow
|
||||
\providecommand{\DUsidebar}[1]{%
|
||||
\begin{center}
|
||||
\colorbox[gray]{0.80}{\parbox{0.9\linewidth}{#1}}
|
||||
\end{center}
|
||||
}
|
||||
|
||||
% title::
|
||||
|
||||
% title for topics, admonitions, unsupported section levels, and sidebar
|
||||
\providecommand*{\DUtitle}[1]{%
|
||||
\smallskip\noindent\textbf{#1}\smallskip}
|
||||
|
||||
% subtitle::
|
||||
|
||||
% subtitle (for sidebar)
|
||||
\providecommand*{\DUsubtitle}[1]{\par\emph{#1}\smallskip}
|
||||
|
||||
% documentsubtitle::
|
||||
|
||||
% subtitle (in document title)
|
||||
\providecommand*{\DUdocumentsubtitle}[1]{{\large #1}}
|
||||
|
||||
% titlereference::
|
||||
|
||||
% titlereference standard role
|
||||
\providecommand*{\DUroletitlereference}[1]{\textsl{#1}}
|
||||
|
||||
% transition::
|
||||
|
||||
% transition (break / fancybreak / anonymous section)
|
||||
\providecommand*{\DUtransition}{%
|
||||
\hspace*{\fill}\hrulefill\hspace*{\fill}
|
||||
\vskip 0.5\baselineskip
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
% generated by Docutils <https://docutils.sourceforge.io/>
|
||||
$head_prefix
|
||||
\usepackage{cmap} % fix search and cut-and-paste in Acrobat
|
||||
$requirements
|
||||
%%% Custom LaTeX preamble
|
||||
$latex_preamble
|
||||
%%% User specified packages and stylesheets
|
||||
$stylesheet
|
||||
%%% Fallback definitions for Docutils-specific commands
|
||||
$fallbacks$pdfsetup
|
||||
$titledata
|
||||
%%% Body
|
||||
\begin{document}
|
||||
\begin{titlepage}
|
||||
$body_pre_docinfo$docinfo$dedication$abstract
|
||||
\thispagestyle{empty}
|
||||
\end{titlepage}
|
||||
$body
|
||||
\end{document}
|
|
@ -0,0 +1,18 @@
|
|||
% generated by Docutils <https://docutils.sourceforge.io/>
|
||||
$head_prefix
|
||||
$requirements
|
||||
%%% Custom LaTeX preamble
|
||||
$latex_preamble
|
||||
%%% User specified packages and stylesheets
|
||||
$stylesheet
|
||||
%%% Fallback definitions for Docutils-specific commands
|
||||
$fallbacks$pdfsetup
|
||||
$titledata
|
||||
%%% Body
|
||||
\begin{document}
|
||||
\begin{titlingpage}
|
||||
\thispagestyle{empty}
|
||||
$body_pre_docinfo$docinfo$dedication$abstract
|
||||
\end{titlingpage}
|
||||
$body
|
||||
\end{document}
|
|
@ -0,0 +1,21 @@
|
|||
$head_prefix% generated by Docutils <https://docutils.sourceforge.io/>
|
||||
% rubber: set program xelatex
|
||||
\usepackage{fontspec}
|
||||
% \defaultfontfeatures{Scale=MatchLowercase}
|
||||
% straight double quotes (defined T1 but missing in TU):
|
||||
\ifdefined \UnicodeEncodingName
|
||||
\DeclareTextCommand{\textquotedbl}{\UnicodeEncodingName}{%
|
||||
{\addfontfeatures{RawFeature=-tlig,Mapping=}\char34}}%
|
||||
\fi
|
||||
$requirements
|
||||
%%% Custom LaTeX preamble
|
||||
$latex_preamble
|
||||
%%% User specified packages and stylesheets
|
||||
$stylesheet
|
||||
%%% Fallback definitions for Docutils-specific commands
|
||||
$fallbacks$pdfsetup
|
||||
$titledata
|
||||
%%% Body
|
||||
\begin{document}
|
||||
$body_pre_docinfo$docinfo$dedication$abstract$body
|
||||
\end{document}
|
1214
kivy_venv/lib/python3.11/site-packages/docutils/writers/manpage.py
Normal file
1214
kivy_venv/lib/python3.11/site-packages/docutils/writers/manpage.py
Normal file
File diff suppressed because it is too large
Load diff
|
@ -0,0 +1,25 @@
|
|||
# $Id: null.py 9352 2023-04-17 20:26:41Z milde $
|
||||
# Author: David Goodger <goodger@python.org>
|
||||
# Copyright: This module has been placed in the public domain.
|
||||
|
||||
"""
|
||||
A do-nothing Writer.
|
||||
|
||||
`self.output` will change from ``None`` to the empty string
|
||||
in Docutils 0.22.
|
||||
"""
|
||||
|
||||
from docutils import writers
|
||||
|
||||
|
||||
class Writer(writers.UnfilteredWriter):
|
||||
|
||||
supported = ('null',)
|
||||
"""Formats this writer supports."""
|
||||
|
||||
config_section = 'null writer'
|
||||
config_section_dependencies = ('writers',)
|
||||
|
||||
def translate(self):
|
||||
# output = None # TODO in 0.22
|
||||
pass
|
File diff suppressed because it is too large
Load diff
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -0,0 +1,78 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
# $Id: prepstyles.py 9386 2023-05-16 14:49:31Z milde $
|
||||
# Author: Dave Kuhlman <dkuhlman@rexx.com>
|
||||
# Copyright: This module has been placed in the public domain.
|
||||
|
||||
"""
|
||||
Adapt a word-processor-generated styles.odt for odtwriter use:
|
||||
|
||||
Drop page size specifications from styles.xml in STYLE_FILE.odt.
|
||||
See https://docutils.sourceforge.io/docs/user/odt.html#page-size
|
||||
"""
|
||||
|
||||
# Author: Michael Schutte <michi@uiae.at>
|
||||
|
||||
from xml.etree import ElementTree as etree
|
||||
|
||||
import sys
|
||||
import zipfile
|
||||
from tempfile import mkstemp
|
||||
import shutil
|
||||
import os
|
||||
|
||||
NAMESPACES = {
|
||||
"style": "urn:oasis:names:tc:opendocument:xmlns:style:1.0",
|
||||
"fo": "urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0"
|
||||
}
|
||||
|
||||
|
||||
def prepstyle(filename):
|
||||
|
||||
zin = zipfile.ZipFile(filename)
|
||||
styles = zin.open("styles.xml")
|
||||
|
||||
root = None
|
||||
# some extra effort to preserve namespace prefixes
|
||||
for event, elem in etree.iterparse(styles, events=("start", "start-ns")):
|
||||
if event == "start-ns":
|
||||
etree.register_namespace(elem[0], elem[1])
|
||||
elif event == "start":
|
||||
if root is None:
|
||||
root = elem
|
||||
|
||||
styles.close()
|
||||
|
||||
for el in root.findall(".//style:page-layout-properties",
|
||||
namespaces=NAMESPACES):
|
||||
for attr in list(el.attrib):
|
||||
if attr.startswith("{%s}" % NAMESPACES["fo"]):
|
||||
del el.attrib[attr]
|
||||
|
||||
tempname = mkstemp()
|
||||
zout = zipfile.ZipFile(os.fdopen(tempname[0], "wb"), "w",
|
||||
zipfile.ZIP_DEFLATED)
|
||||
|
||||
for item in zin.infolist():
|
||||
if item.filename == "styles.xml":
|
||||
zout.writestr(item, etree.tostring(root, encoding="UTF-8"))
|
||||
else:
|
||||
zout.writestr(item, zin.read(item.filename))
|
||||
|
||||
zout.close()
|
||||
zin.close()
|
||||
shutil.move(tempname[1], filename)
|
||||
|
||||
|
||||
def main():
|
||||
args = sys.argv[1:]
|
||||
if len(args) != 1 or args[0] in ('-h', '--help'):
|
||||
print(__doc__, file=sys.stderr)
|
||||
print("Usage: %s STYLE_FILE.odt\n" % sys.argv[0], file=sys.stderr)
|
||||
sys.exit(1)
|
||||
filename = args[0]
|
||||
prepstyle(filename)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
|
@ -0,0 +1,109 @@
|
|||
# $Id: pygmentsformatter.py 9015 2022-03-03 22:15:00Z milde $
|
||||
# Author: Dave Kuhlman <dkuhlman@rexx.com>
|
||||
# Copyright: This module has been placed in the public domain.
|
||||
|
||||
"""
|
||||
|
||||
Additional support for Pygments formatter.
|
||||
|
||||
"""
|
||||
|
||||
|
||||
import pygments
|
||||
import pygments.formatter
|
||||
|
||||
|
||||
class OdtPygmentsFormatter(pygments.formatter.Formatter):
|
||||
def __init__(self, rststyle_function, escape_function):
|
||||
pygments.formatter.Formatter.__init__(self)
|
||||
self.rststyle_function = rststyle_function
|
||||
self.escape_function = escape_function
|
||||
|
||||
def rststyle(self, name, parameters=()):
|
||||
return self.rststyle_function(name, parameters)
|
||||
|
||||
|
||||
class OdtPygmentsProgFormatter(OdtPygmentsFormatter):
|
||||
def format(self, tokensource, outfile):
|
||||
tokenclass = pygments.token.Token
|
||||
for ttype, value in tokensource:
|
||||
value = self.escape_function(value)
|
||||
if ttype == tokenclass.Keyword:
|
||||
s2 = self.rststyle('codeblock-keyword')
|
||||
s1 = '<text:span text:style-name="%s">%s</text:span>' % \
|
||||
(s2, value, )
|
||||
elif ttype == tokenclass.Literal.String:
|
||||
s2 = self.rststyle('codeblock-string')
|
||||
s1 = '<text:span text:style-name="%s">%s</text:span>' % \
|
||||
(s2, value, )
|
||||
elif ttype in (
|
||||
tokenclass.Literal.Number.Integer,
|
||||
tokenclass.Literal.Number.Integer.Long,
|
||||
tokenclass.Literal.Number.Float,
|
||||
tokenclass.Literal.Number.Hex,
|
||||
tokenclass.Literal.Number.Oct,
|
||||
tokenclass.Literal.Number,
|
||||
):
|
||||
s2 = self.rststyle('codeblock-number')
|
||||
s1 = '<text:span text:style-name="%s">%s</text:span>' % \
|
||||
(s2, value, )
|
||||
elif ttype == tokenclass.Operator:
|
||||
s2 = self.rststyle('codeblock-operator')
|
||||
s1 = '<text:span text:style-name="%s">%s</text:span>' % \
|
||||
(s2, value, )
|
||||
elif ttype == tokenclass.Comment:
|
||||
s2 = self.rststyle('codeblock-comment')
|
||||
s1 = '<text:span text:style-name="%s">%s</text:span>' % \
|
||||
(s2, value, )
|
||||
elif ttype == tokenclass.Name.Class:
|
||||
s2 = self.rststyle('codeblock-classname')
|
||||
s1 = '<text:span text:style-name="%s">%s</text:span>' % \
|
||||
(s2, value, )
|
||||
elif ttype == tokenclass.Name.Function:
|
||||
s2 = self.rststyle('codeblock-functionname')
|
||||
s1 = '<text:span text:style-name="%s">%s</text:span>' % \
|
||||
(s2, value, )
|
||||
elif ttype == tokenclass.Name:
|
||||
s2 = self.rststyle('codeblock-name')
|
||||
s1 = '<text:span text:style-name="%s">%s</text:span>' % \
|
||||
(s2, value, )
|
||||
else:
|
||||
s1 = value
|
||||
outfile.write(s1)
|
||||
|
||||
|
||||
class OdtPygmentsLaTeXFormatter(OdtPygmentsFormatter):
|
||||
def format(self, tokensource, outfile):
|
||||
tokenclass = pygments.token.Token
|
||||
for ttype, value in tokensource:
|
||||
value = self.escape_function(value)
|
||||
if ttype == tokenclass.Keyword:
|
||||
s2 = self.rststyle('codeblock-keyword')
|
||||
s1 = '<text:span text:style-name="%s">%s</text:span>' % \
|
||||
(s2, value, )
|
||||
elif ttype in (tokenclass.Literal.String,
|
||||
tokenclass.Literal.String.Backtick,
|
||||
):
|
||||
s2 = self.rststyle('codeblock-string')
|
||||
s1 = '<text:span text:style-name="%s">%s</text:span>' % \
|
||||
(s2, value, )
|
||||
elif ttype == tokenclass.Name.Attribute:
|
||||
s2 = self.rststyle('codeblock-operator')
|
||||
s1 = '<text:span text:style-name="%s">%s</text:span>' % \
|
||||
(s2, value, )
|
||||
elif ttype == tokenclass.Comment:
|
||||
if value[-1] == '\n':
|
||||
s2 = self.rststyle('codeblock-comment')
|
||||
s1 = '<text:span text:style-name="%s">%s</text:span>\n' % \
|
||||
(s2, value[:-1], )
|
||||
else:
|
||||
s2 = self.rststyle('codeblock-comment')
|
||||
s1 = '<text:span text:style-name="%s">%s</text:span>' % \
|
||||
(s2, value, )
|
||||
elif ttype == tokenclass.Name.Builtin:
|
||||
s2 = self.rststyle('codeblock-name')
|
||||
s1 = '<text:span text:style-name="%s">%s</text:span>' % \
|
||||
(s2, value, )
|
||||
else:
|
||||
s1 = value
|
||||
outfile.write(s1)
|
Binary file not shown.
|
@ -0,0 +1,101 @@
|
|||
# $Id: __init__.py 9541 2024-02-17 10:37:13Z milde $
|
||||
# Author: David Goodger <goodger@python.org>
|
||||
# Copyright: This module has been placed in the public domain.
|
||||
|
||||
"""
|
||||
PEP HTML Writer.
|
||||
"""
|
||||
|
||||
__docformat__ = 'reStructuredText'
|
||||
|
||||
|
||||
import os
|
||||
import os.path
|
||||
|
||||
from docutils import frontend, nodes, utils
|
||||
from docutils.writers import html4css1
|
||||
|
||||
|
||||
class Writer(html4css1.Writer):
|
||||
|
||||
default_stylesheet = 'pep.css'
|
||||
|
||||
default_stylesheet_path = utils.relative_path(
|
||||
os.path.join(os.getcwd(), 'dummy'),
|
||||
os.path.join(os.path.dirname(__file__), default_stylesheet))
|
||||
|
||||
default_template = 'template.txt'
|
||||
|
||||
default_template_path = utils.relative_path(
|
||||
os.path.join(os.getcwd(), 'dummy'),
|
||||
os.path.join(os.path.dirname(__file__), default_template))
|
||||
|
||||
settings_spec = html4css1.Writer.settings_spec + (
|
||||
'PEP/HTML Writer Options',
|
||||
'For the PEP/HTML writer, the default value for the --stylesheet-path '
|
||||
'option is "%s", and the default value for --template is "%s". '
|
||||
'See HTML Writer Options above.'
|
||||
% (default_stylesheet_path, default_template_path),
|
||||
(('Python\'s home URL. Default is "https://www.python.org".',
|
||||
['--python-home'],
|
||||
{'default': 'https://www.python.org', 'metavar': '<URL>'}),
|
||||
('Home URL prefix for PEPs. Default is "." (current directory).',
|
||||
['--pep-home'],
|
||||
{'default': '.', 'metavar': '<URL>'}),
|
||||
# For testing.
|
||||
(frontend.SUPPRESS_HELP,
|
||||
['--no-random'],
|
||||
{'action': 'store_true', 'validator': frontend.validate_boolean}),))
|
||||
|
||||
settings_default_overrides = {'stylesheet_path': default_stylesheet_path,
|
||||
'template': default_template_path}
|
||||
relative_path_settings = ('template',)
|
||||
config_section = 'pep_html writer'
|
||||
config_section_dependencies = ('writers', 'html writers',
|
||||
'html4css1 writer')
|
||||
|
||||
def __init__(self):
|
||||
html4css1.Writer.__init__(self)
|
||||
self.translator_class = HTMLTranslator
|
||||
|
||||
def interpolation_dict(self):
|
||||
subs = html4css1.Writer.interpolation_dict(self)
|
||||
settings = self.document.settings
|
||||
pyhome = settings.python_home
|
||||
subs['pyhome'] = pyhome
|
||||
subs['pephome'] = settings.pep_home
|
||||
if pyhome == '..':
|
||||
subs['pepindex'] = '.'
|
||||
else:
|
||||
subs['pepindex'] = pyhome + '/dev/peps'
|
||||
index = self.document.first_child_matching_class(nodes.field_list)
|
||||
header = self.document[index]
|
||||
self.pepnum = header[0][1].astext()
|
||||
subs['pep'] = self.pepnum
|
||||
if settings.no_random:
|
||||
subs['banner'] = 0
|
||||
else:
|
||||
import random
|
||||
subs['banner'] = random.randrange(64)
|
||||
try:
|
||||
subs['pepnum'] = '%04i' % int(self.pepnum)
|
||||
except ValueError:
|
||||
subs['pepnum'] = self.pepnum
|
||||
self.title = header[1][1].astext()
|
||||
subs['title'] = self.title
|
||||
subs['body'] = ''.join(
|
||||
self.body_pre_docinfo + self.docinfo + self.body)
|
||||
return subs
|
||||
|
||||
def assemble_parts(self):
|
||||
html4css1.Writer.assemble_parts(self)
|
||||
self.parts['title'] = [self.title]
|
||||
self.parts['pepnum'] = self.pepnum
|
||||
|
||||
|
||||
class HTMLTranslator(html4css1.HTMLTranslator):
|
||||
|
||||
def depart_field_list(self, node):
|
||||
html4css1.HTMLTranslator.depart_field_list(self, node)
|
||||
if 'rfc2822' in node['classes']:
|
||||
self.body.append('<hr />\n')
|
Binary file not shown.
|
@ -0,0 +1,344 @@
|
|||
/*
|
||||
:Author: David Goodger
|
||||
:Contact: goodger@python.org
|
||||
:date: $Date: 2022-01-29 23:26:10 +0100 (Sa, 29. Jän 2022) $
|
||||
:version: $Revision: 8995 $
|
||||
:copyright: This stylesheet has been placed in the public domain.
|
||||
|
||||
Default cascading style sheet for the PEP HTML output of Docutils.
|
||||
*/
|
||||
|
||||
/* "! important" is used here to override other ``margin-top`` and
|
||||
``margin-bottom`` styles that are later in the stylesheet or
|
||||
more specific. See http://www.w3.org/TR/CSS1#the-cascade */
|
||||
.first {
|
||||
margin-top: 0 ! important }
|
||||
|
||||
.last, .with-subtitle {
|
||||
margin-bottom: 0 ! important }
|
||||
|
||||
.hidden {
|
||||
display: none }
|
||||
|
||||
.navigation {
|
||||
width: 100% ;
|
||||
background: #99ccff ;
|
||||
margin-top: 0px ;
|
||||
margin-bottom: 0px }
|
||||
|
||||
.navigation .navicon {
|
||||
width: 150px ;
|
||||
height: 35px }
|
||||
|
||||
.navigation .textlinks {
|
||||
padding-left: 1em ;
|
||||
text-align: left }
|
||||
|
||||
.navigation td, .navigation th {
|
||||
padding-left: 0em ;
|
||||
padding-right: 0em ;
|
||||
vertical-align: middle }
|
||||
|
||||
.rfc2822 {
|
||||
margin-top: 0.5em ;
|
||||
margin-left: 0.5em ;
|
||||
margin-right: 0.5em ;
|
||||
margin-bottom: 0em }
|
||||
|
||||
.rfc2822 td {
|
||||
text-align: left }
|
||||
|
||||
.rfc2822 th.field-name {
|
||||
text-align: right ;
|
||||
font-family: sans-serif ;
|
||||
padding-right: 0.5em ;
|
||||
font-weight: bold ;
|
||||
margin-bottom: 0em }
|
||||
|
||||
a.toc-backref {
|
||||
text-decoration: none ;
|
||||
color: black }
|
||||
|
||||
blockquote.epigraph {
|
||||
margin: 2em 5em ; }
|
||||
|
||||
body {
|
||||
margin: 0px ;
|
||||
margin-bottom: 1em ;
|
||||
padding: 0px }
|
||||
|
||||
dl.docutils dd {
|
||||
margin-bottom: 0.5em }
|
||||
|
||||
div.section {
|
||||
margin-left: 1em ;
|
||||
margin-right: 1em ;
|
||||
margin-bottom: 1.5em }
|
||||
|
||||
div.section div.section {
|
||||
margin-left: 0em ;
|
||||
margin-right: 0em ;
|
||||
margin-top: 1.5em }
|
||||
|
||||
div.abstract {
|
||||
margin: 2em 5em }
|
||||
|
||||
div.abstract p.topic-title {
|
||||
font-weight: bold ;
|
||||
text-align: center }
|
||||
|
||||
div.admonition, div.attention, div.caution, div.danger, div.error,
|
||||
div.hint, div.important, div.note, div.tip, div.warning {
|
||||
margin: 2em ;
|
||||
border: medium outset ;
|
||||
padding: 1em }
|
||||
|
||||
div.admonition p.admonition-title, div.hint p.admonition-title,
|
||||
div.important p.admonition-title, div.note p.admonition-title,
|
||||
div.tip p.admonition-title {
|
||||
font-weight: bold ;
|
||||
font-family: sans-serif }
|
||||
|
||||
div.attention p.admonition-title, div.caution p.admonition-title,
|
||||
div.danger p.admonition-title, div.error p.admonition-title,
|
||||
div.warning p.admonition-title {
|
||||
color: red ;
|
||||
font-weight: bold ;
|
||||
font-family: sans-serif }
|
||||
|
||||
/* Uncomment (and remove this text!) to get reduced vertical space in
|
||||
compound paragraphs.
|
||||
div.compound .compound-first, div.compound .compound-middle {
|
||||
margin-bottom: 0.5em }
|
||||
|
||||
div.compound .compound-last, div.compound .compound-middle {
|
||||
margin-top: 0.5em }
|
||||
*/
|
||||
|
||||
div.dedication {
|
||||
margin: 2em 5em ;
|
||||
text-align: center ;
|
||||
font-style: italic }
|
||||
|
||||
div.dedication p.topic-title {
|
||||
font-weight: bold ;
|
||||
font-style: normal }
|
||||
|
||||
div.figure {
|
||||
margin-left: 2em ;
|
||||
margin-right: 2em }
|
||||
|
||||
div.footer, div.header {
|
||||
clear: both;
|
||||
font-size: smaller }
|
||||
|
||||
div.footer {
|
||||
margin-left: 1em ;
|
||||
margin-right: 1em }
|
||||
|
||||
div.line-block {
|
||||
display: block ;
|
||||
margin-top: 1em ;
|
||||
margin-bottom: 1em }
|
||||
|
||||
div.line-block div.line-block {
|
||||
margin-top: 0 ;
|
||||
margin-bottom: 0 ;
|
||||
margin-left: 1.5em }
|
||||
|
||||
div.sidebar {
|
||||
margin-left: 1em ;
|
||||
border: medium outset ;
|
||||
padding: 1em ;
|
||||
background-color: #ffffee ;
|
||||
width: 40% ;
|
||||
float: right ;
|
||||
clear: right }
|
||||
|
||||
div.sidebar p.rubric {
|
||||
font-family: sans-serif ;
|
||||
font-size: medium }
|
||||
|
||||
div.system-messages {
|
||||
margin: 5em }
|
||||
|
||||
div.system-messages h1 {
|
||||
color: red }
|
||||
|
||||
div.system-message {
|
||||
border: medium outset ;
|
||||
padding: 1em }
|
||||
|
||||
div.system-message p.system-message-title {
|
||||
color: red ;
|
||||
font-weight: bold }
|
||||
|
||||
div.topic {
|
||||
margin: 2em }
|
||||
|
||||
h1.section-subtitle, h2.section-subtitle, h3.section-subtitle,
|
||||
h4.section-subtitle, h5.section-subtitle, h6.section-subtitle {
|
||||
margin-top: 0.4em }
|
||||
|
||||
h1 {
|
||||
font-family: sans-serif ;
|
||||
font-size: large }
|
||||
|
||||
h2 {
|
||||
font-family: sans-serif ;
|
||||
font-size: medium }
|
||||
|
||||
h3 {
|
||||
font-family: sans-serif ;
|
||||
font-size: small }
|
||||
|
||||
h4 {
|
||||
font-family: sans-serif ;
|
||||
font-style: italic ;
|
||||
font-size: small }
|
||||
|
||||
h5 {
|
||||
font-family: sans-serif;
|
||||
font-size: x-small }
|
||||
|
||||
h6 {
|
||||
font-family: sans-serif;
|
||||
font-style: italic ;
|
||||
font-size: x-small }
|
||||
|
||||
hr.docutils {
|
||||
width: 75% }
|
||||
|
||||
img.align-left {
|
||||
clear: left }
|
||||
|
||||
img.align-right {
|
||||
clear: right }
|
||||
|
||||
img.borderless {
|
||||
border: 0 }
|
||||
|
||||
ol.simple, ul.simple {
|
||||
margin-bottom: 1em }
|
||||
|
||||
ol.arabic {
|
||||
list-style: decimal }
|
||||
|
||||
ol.loweralpha {
|
||||
list-style: lower-alpha }
|
||||
|
||||
ol.upperalpha {
|
||||
list-style: upper-alpha }
|
||||
|
||||
ol.lowerroman {
|
||||
list-style: lower-roman }
|
||||
|
||||
ol.upperroman {
|
||||
list-style: upper-roman }
|
||||
|
||||
p.attribution {
|
||||
text-align: right ;
|
||||
margin-left: 50% }
|
||||
|
||||
p.caption {
|
||||
font-style: italic }
|
||||
|
||||
p.credits {
|
||||
font-style: italic ;
|
||||
font-size: smaller }
|
||||
|
||||
p.label {
|
||||
white-space: nowrap }
|
||||
|
||||
p.rubric {
|
||||
font-weight: bold ;
|
||||
font-size: larger ;
|
||||
color: maroon ;
|
||||
text-align: center }
|
||||
|
||||
p.sidebar-title {
|
||||
font-family: sans-serif ;
|
||||
font-weight: bold ;
|
||||
font-size: larger }
|
||||
|
||||
p.sidebar-subtitle {
|
||||
font-family: sans-serif ;
|
||||
font-weight: bold }
|
||||
|
||||
p.topic-title {
|
||||
font-family: sans-serif ;
|
||||
font-weight: bold }
|
||||
|
||||
pre.address {
|
||||
margin-bottom: 0 ;
|
||||
margin-top: 0 ;
|
||||
font-family: serif ;
|
||||
font-size: 100% }
|
||||
|
||||
pre.literal-block, pre.doctest-block {
|
||||
margin-left: 2em ;
|
||||
margin-right: 2em }
|
||||
|
||||
span.classifier {
|
||||
font-family: sans-serif ;
|
||||
font-style: oblique }
|
||||
|
||||
span.classifier-delimiter {
|
||||
font-family: sans-serif ;
|
||||
font-weight: bold }
|
||||
|
||||
span.interpreted {
|
||||
font-family: sans-serif }
|
||||
|
||||
span.option {
|
||||
white-space: nowrap }
|
||||
|
||||
span.option-argument {
|
||||
font-style: italic }
|
||||
|
||||
span.pre {
|
||||
white-space: pre }
|
||||
|
||||
span.problematic {
|
||||
color: red }
|
||||
|
||||
span.section-subtitle {
|
||||
/* font-size relative to parent (h1..h6 element) */
|
||||
font-size: 80% }
|
||||
|
||||
table.citation {
|
||||
border-left: solid 1px gray;
|
||||
margin-left: 1px }
|
||||
|
||||
table.docinfo {
|
||||
margin: 2em 4em }
|
||||
|
||||
table.docutils {
|
||||
margin-top: 0.5em ;
|
||||
margin-bottom: 0.5em }
|
||||
|
||||
table.footnote {
|
||||
border-left: solid 1px black;
|
||||
margin-left: 1px }
|
||||
|
||||
table.docutils td, table.docutils th,
|
||||
table.docinfo td, table.docinfo th {
|
||||
padding-left: 0.5em ;
|
||||
padding-right: 0.5em ;
|
||||
vertical-align: top }
|
||||
|
||||
td.num {
|
||||
text-align: right }
|
||||
|
||||
th.field-name {
|
||||
font-weight: bold ;
|
||||
text-align: left ;
|
||||
white-space: nowrap ;
|
||||
padding-left: 0 }
|
||||
|
||||
h1 tt.docutils, h2 tt.docutils, h3 tt.docutils,
|
||||
h4 tt.docutils, h5 tt.docutils, h6 tt.docutils {
|
||||
font-size: 100% }
|
||||
|
||||
ul.auto-toc {
|
||||
list-style-type: none }
|
|
@ -0,0 +1,25 @@
|
|||
<?xml version="1.0" encoding="%(encoding)s"?>
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
||||
<!--
|
||||
This HTML is auto-generated. DO NOT EDIT THIS FILE! If you are writing a new
|
||||
PEP, see http://peps.python.org/pep-0001 for instructions and links
|
||||
to templates. DO NOT USE THIS HTML FILE AS YOUR TEMPLATE!
|
||||
-->
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=%(encoding)s" />
|
||||
<meta name="generator" content="Docutils %(version)s: https://docutils.sourceforge.io/" />
|
||||
<title>PEP %(pep)s - %(title)s</title>
|
||||
%(stylesheet)s
|
||||
</head>
|
||||
<body bgcolor="white">
|
||||
<div class="header">
|
||||
<strong>Python Enhancement Proposals</strong>
|
||||
| <a href="%(pyhome)s/">Python</a>
|
||||
» <a href="https://peps.python.org/pep-0000/">PEP Index</a>
|
||||
» PEP %(pep)s – %(title)s
|
||||
<hr class="header"/>
|
||||
</div>
|
||||
<div class="document">
|
||||
%(body)s
|
||||
%(body_suffix)s
|
|
@ -0,0 +1,40 @@
|
|||
# $Id: pseudoxml.py 9043 2022-03-11 12:09:16Z milde $
|
||||
# Author: David Goodger <goodger@python.org>
|
||||
# Copyright: This module has been placed in the public domain.
|
||||
|
||||
"""
|
||||
Simple internal document tree Writer, writes indented pseudo-XML.
|
||||
"""
|
||||
|
||||
__docformat__ = 'reStructuredText'
|
||||
|
||||
|
||||
from docutils import writers, frontend
|
||||
|
||||
|
||||
class Writer(writers.Writer):
|
||||
|
||||
supported = ('pseudoxml', 'pprint', 'pformat')
|
||||
"""Formats this writer supports."""
|
||||
|
||||
settings_spec = (
|
||||
'"Docutils pseudo-XML" Writer Options',
|
||||
None,
|
||||
(('Pretty-print <#text> nodes.',
|
||||
['--detailed'],
|
||||
{'action': 'store_true', 'validator': frontend.validate_boolean}),
|
||||
)
|
||||
)
|
||||
|
||||
config_section = 'pseudoxml writer'
|
||||
config_section_dependencies = ('writers',)
|
||||
|
||||
output = None
|
||||
"""Final translated form of `document`."""
|
||||
|
||||
def translate(self):
|
||||
self.output = self.document.pformat()
|
||||
|
||||
def supports(self, format):
|
||||
"""This writer supports all format-specific elements."""
|
||||
return True
|
|
@ -0,0 +1,353 @@
|
|||
# $Id: __init__.py 9542 2024-02-17 10:37:23Z milde $
|
||||
# Authors: Chris Liechti <cliechti@gmx.net>;
|
||||
# David Goodger <goodger@python.org>
|
||||
# Copyright: This module has been placed in the public domain.
|
||||
|
||||
"""
|
||||
S5/HTML Slideshow Writer.
|
||||
"""
|
||||
|
||||
__docformat__ = 'reStructuredText'
|
||||
|
||||
import sys
|
||||
import os
|
||||
import re
|
||||
import docutils
|
||||
from docutils import frontend, nodes, utils
|
||||
from docutils.writers import html4css1
|
||||
|
||||
themes_dir_path = utils.relative_path(
|
||||
os.path.join(os.getcwd(), 'dummy'),
|
||||
os.path.join(os.path.dirname(__file__), 'themes'))
|
||||
|
||||
|
||||
def find_theme(name):
|
||||
# Where else to look for a theme?
|
||||
# Check working dir? Destination dir? Config dir? Plugins dir?
|
||||
path = os.path.join(themes_dir_path, name)
|
||||
if not os.path.isdir(path):
|
||||
raise docutils.ApplicationError(
|
||||
'Theme directory not found: %r (path: %r)' % (name, path))
|
||||
return path
|
||||
|
||||
|
||||
class Writer(html4css1.Writer):
|
||||
|
||||
settings_spec = html4css1.Writer.settings_spec + (
|
||||
'S5 Slideshow Specific Options',
|
||||
'For the S5/HTML writer, the --no-toc-backlinks option '
|
||||
'(defined in General Docutils Options above) is the default, '
|
||||
'and should not be changed.',
|
||||
(('Specify an installed S5 theme by name. Overrides --theme-url. '
|
||||
'The default theme name is "default". The theme files will be '
|
||||
'copied into a "ui/<theme>" directory, in the same directory as the '
|
||||
'destination file (output HTML). Note that existing theme files '
|
||||
'will not be overwritten (unless --overwrite-theme-files is used).',
|
||||
['--theme'],
|
||||
{'default': 'default', 'metavar': '<name>',
|
||||
'overrides': 'theme_url'}),
|
||||
('Specify an S5 theme URL. The destination file (output HTML) will '
|
||||
'link to this theme; nothing will be copied. Overrides --theme.',
|
||||
['--theme-url'],
|
||||
{'metavar': '<URL>', 'overrides': 'theme'}),
|
||||
('Allow existing theme files in the ``ui/<theme>`` directory to be '
|
||||
'overwritten. The default is not to overwrite theme files.',
|
||||
['--overwrite-theme-files'],
|
||||
{'action': 'store_true', 'validator': frontend.validate_boolean}),
|
||||
('Keep existing theme files in the ``ui/<theme>`` directory; do not '
|
||||
'overwrite any. This is the default.',
|
||||
['--keep-theme-files'],
|
||||
{'dest': 'overwrite_theme_files', 'action': 'store_false'}),
|
||||
('Set the initial view mode to "slideshow" [default] or "outline".',
|
||||
['--view-mode'],
|
||||
{'choices': ['slideshow', 'outline'], 'default': 'slideshow',
|
||||
'metavar': '<mode>'}),
|
||||
('Normally hide the presentation controls in slideshow mode. '
|
||||
'This is the default.',
|
||||
['--hidden-controls'],
|
||||
{'action': 'store_true', 'default': True,
|
||||
'validator': frontend.validate_boolean}),
|
||||
('Always show the presentation controls in slideshow mode. '
|
||||
'The default is to hide the controls.',
|
||||
['--visible-controls'],
|
||||
{'dest': 'hidden_controls', 'action': 'store_false'}),
|
||||
('Enable the current slide indicator ("1 / 15"). '
|
||||
'The default is to disable it.',
|
||||
['--current-slide'],
|
||||
{'action': 'store_true', 'validator': frontend.validate_boolean}),
|
||||
('Disable the current slide indicator. This is the default.',
|
||||
['--no-current-slide'],
|
||||
{'dest': 'current_slide', 'action': 'store_false'}),))
|
||||
|
||||
settings_default_overrides = {'toc_backlinks': 0}
|
||||
|
||||
config_section = 's5_html writer'
|
||||
config_section_dependencies = ('writers', 'html writers',
|
||||
'html4css1 writer')
|
||||
|
||||
def __init__(self):
|
||||
html4css1.Writer.__init__(self)
|
||||
self.translator_class = S5HTMLTranslator
|
||||
|
||||
|
||||
class S5HTMLTranslator(html4css1.HTMLTranslator):
|
||||
|
||||
s5_stylesheet_template = """\
|
||||
<!-- configuration parameters -->
|
||||
<meta name="defaultView" content="%(view_mode)s" />
|
||||
<meta name="controlVis" content="%(control_visibility)s" />
|
||||
<!-- style sheet links -->
|
||||
<script src="%(path)s/slides.js" type="text/javascript"></script>
|
||||
<link rel="stylesheet" href="%(path)s/slides.css"
|
||||
type="text/css" media="projection" id="slideProj" />
|
||||
<link rel="stylesheet" href="%(path)s/outline.css"
|
||||
type="text/css" media="screen" id="outlineStyle" />
|
||||
<link rel="stylesheet" href="%(path)s/print.css"
|
||||
type="text/css" media="print" id="slidePrint" />
|
||||
<link rel="stylesheet" href="%(path)s/opera.css"
|
||||
type="text/css" media="projection" id="operaFix" />\n"""
|
||||
# The script element must go in front of the link elements to
|
||||
# avoid a flash of unstyled content (FOUC), reproducible with
|
||||
# Firefox.
|
||||
|
||||
disable_current_slide = """
|
||||
<style type="text/css">
|
||||
#currentSlide {display: none;}
|
||||
</style>\n"""
|
||||
|
||||
layout_template = """\
|
||||
<div class="layout">
|
||||
<div id="controls"></div>
|
||||
<div id="currentSlide"></div>
|
||||
<div id="header">
|
||||
%(header)s
|
||||
</div>
|
||||
<div id="footer">
|
||||
%(title)s%(footer)s
|
||||
</div>
|
||||
</div>\n"""
|
||||
# <div class="topleft"></div>
|
||||
# <div class="topright"></div>
|
||||
# <div class="bottomleft"></div>
|
||||
# <div class="bottomright"></div>
|
||||
|
||||
default_theme = 'default'
|
||||
"""Name of the default theme."""
|
||||
|
||||
base_theme_file = '__base__'
|
||||
"""Name of the file containing the name of the base theme."""
|
||||
|
||||
direct_theme_files = (
|
||||
'slides.css', 'outline.css', 'print.css', 'opera.css', 'slides.js')
|
||||
"""Names of theme files directly linked to in the output HTML"""
|
||||
|
||||
indirect_theme_files = (
|
||||
's5-core.css', 'framing.css', 'pretty.css')
|
||||
"""Names of files used indirectly; imported or used by files in
|
||||
`direct_theme_files`."""
|
||||
|
||||
required_theme_files = indirect_theme_files + direct_theme_files
|
||||
"""Names of mandatory theme files."""
|
||||
|
||||
def __init__(self, *args):
|
||||
html4css1.HTMLTranslator.__init__(self, *args)
|
||||
# insert S5-specific stylesheet and script stuff:
|
||||
self.theme_file_path = None
|
||||
try:
|
||||
self.setup_theme()
|
||||
except docutils.ApplicationError as e:
|
||||
self.document.reporter.warning(e)
|
||||
view_mode = self.document.settings.view_mode
|
||||
control_visibility = ('visible', 'hidden')[self.document.settings
|
||||
.hidden_controls]
|
||||
self.stylesheet.append(self.s5_stylesheet_template
|
||||
% {'path': self.theme_file_path,
|
||||
'view_mode': view_mode,
|
||||
'control_visibility': control_visibility})
|
||||
if not self.document.settings.current_slide:
|
||||
self.stylesheet.append(self.disable_current_slide)
|
||||
self.meta.append('<meta name="version" content="S5 1.1" />\n')
|
||||
self.s5_footer = []
|
||||
self.s5_header = []
|
||||
self.section_count = 0
|
||||
self.theme_files_copied = None
|
||||
|
||||
def setup_theme(self):
|
||||
if self.document.settings.theme:
|
||||
self.copy_theme()
|
||||
elif self.document.settings.theme_url:
|
||||
self.theme_file_path = self.document.settings.theme_url
|
||||
else:
|
||||
raise docutils.ApplicationError(
|
||||
'No theme specified for S5/HTML writer.')
|
||||
|
||||
def copy_theme(self):
|
||||
"""
|
||||
Locate & copy theme files.
|
||||
|
||||
A theme may be explicitly based on another theme via a '__base__'
|
||||
file. The default base theme is 'default'. Files are accumulated
|
||||
from the specified theme, any base themes, and 'default'.
|
||||
"""
|
||||
settings = self.document.settings
|
||||
path = find_theme(settings.theme)
|
||||
theme_paths = [path]
|
||||
self.theme_files_copied = {}
|
||||
required_files_copied = {}
|
||||
# This is a link (URL) in HTML, so we use "/", not os.sep:
|
||||
self.theme_file_path = 'ui/%s' % settings.theme
|
||||
if not settings.output:
|
||||
raise docutils.ApplicationError(
|
||||
'Output path not specified, you may need to copy'
|
||||
' the S5 theme files "by hand" or set the "--output" option.')
|
||||
dest = os.path.join(
|
||||
os.path.dirname(settings.output), 'ui', settings.theme)
|
||||
if not os.path.isdir(dest):
|
||||
os.makedirs(dest)
|
||||
default = False
|
||||
while path:
|
||||
for f in os.listdir(path): # copy all files from each theme
|
||||
if f == self.base_theme_file:
|
||||
continue # ... except the "__base__" file
|
||||
if (self.copy_file(f, path, dest)
|
||||
and f in self.required_theme_files):
|
||||
required_files_copied[f] = True
|
||||
if default:
|
||||
break # "default" theme has no base theme
|
||||
# Find the "__base__" file in theme directory:
|
||||
base_theme_file = os.path.join(path, self.base_theme_file)
|
||||
# If it exists, read it and record the theme path:
|
||||
if os.path.isfile(base_theme_file):
|
||||
with open(base_theme_file, encoding='utf-8') as f:
|
||||
lines = f.readlines()
|
||||
for line in lines:
|
||||
line = line.strip()
|
||||
if line and not line.startswith('#'):
|
||||
path = find_theme(line)
|
||||
if path in theme_paths: # check for duplicates/cycles
|
||||
path = None # if found, use default base
|
||||
else:
|
||||
theme_paths.append(path)
|
||||
break
|
||||
else: # no theme name found
|
||||
path = None # use default base
|
||||
else: # no base theme file found
|
||||
path = None # use default base
|
||||
if not path:
|
||||
path = find_theme(self.default_theme)
|
||||
theme_paths.append(path)
|
||||
default = True
|
||||
if len(required_files_copied) != len(self.required_theme_files):
|
||||
# Some required files weren't found & couldn't be copied.
|
||||
required = list(self.required_theme_files)
|
||||
for f in required_files_copied.keys():
|
||||
required.remove(f)
|
||||
raise docutils.ApplicationError(
|
||||
'Theme files not found: %s'
|
||||
% ', '.join('%r' % f for f in required))
|
||||
|
||||
files_to_skip_pattern = re.compile(r'~$|\.bak$|#$|\.cvsignore$')
|
||||
|
||||
def copy_file(self, name, source_dir, dest_dir):
|
||||
"""
|
||||
Copy file `name` from `source_dir` to `dest_dir`.
|
||||
Return True if the file exists in either `source_dir` or `dest_dir`.
|
||||
"""
|
||||
source = os.path.join(source_dir, name)
|
||||
dest = os.path.join(dest_dir, name)
|
||||
if dest in self.theme_files_copied:
|
||||
return True
|
||||
else:
|
||||
self.theme_files_copied[dest] = True
|
||||
if os.path.isfile(source):
|
||||
if self.files_to_skip_pattern.search(source):
|
||||
return None
|
||||
settings = self.document.settings
|
||||
if os.path.exists(dest) and not settings.overwrite_theme_files:
|
||||
settings.record_dependencies.add(dest)
|
||||
else:
|
||||
with open(source, 'rb') as src_file:
|
||||
src_data = src_file.read()
|
||||
with open(dest, 'wb') as dest_file:
|
||||
dest_dir = dest_dir.replace(os.sep, '/')
|
||||
dest_file.write(src_data.replace(
|
||||
b'ui/default',
|
||||
dest_dir[dest_dir.rfind('ui/'):].encode(
|
||||
sys.getfilesystemencoding())))
|
||||
settings.record_dependencies.add(source)
|
||||
return True
|
||||
if os.path.isfile(dest):
|
||||
return True
|
||||
|
||||
def depart_document(self, node):
|
||||
self.head_prefix.extend([self.doctype,
|
||||
self.head_prefix_template %
|
||||
{'lang': self.settings.language_code}])
|
||||
self.html_prolog.append(self.doctype)
|
||||
self.head = self.meta[:] + self.head
|
||||
if self.math_header:
|
||||
if self.math_output == 'mathjax':
|
||||
self.head.extend(self.math_header)
|
||||
else:
|
||||
self.stylesheet.extend(self.math_header)
|
||||
# skip content-type meta tag with interpolated charset value:
|
||||
self.html_head.extend(self.head[1:])
|
||||
self.fragment.extend(self.body)
|
||||
# special S5 code up to the next comment line
|
||||
header = ''.join(self.s5_header)
|
||||
footer = ''.join(self.s5_footer)
|
||||
title = ''.join(self.html_title).replace('<h1 class="title">', '<h1>')
|
||||
layout = self.layout_template % {'header': header,
|
||||
'title': title,
|
||||
'footer': footer}
|
||||
self.body_prefix.extend(layout)
|
||||
self.body_prefix.append('<div class="presentation">\n')
|
||||
self.body_prefix.append(
|
||||
self.starttag({'classes': ['slide'], 'ids': ['slide0']}, 'div'))
|
||||
if not self.section_count:
|
||||
self.body.append('</div>\n')
|
||||
#
|
||||
self.body_suffix.insert(0, '</div>\n')
|
||||
self.html_body.extend(self.body_prefix[1:] + self.body_pre_docinfo
|
||||
+ self.docinfo + self.body
|
||||
+ self.body_suffix[:-1])
|
||||
|
||||
def depart_footer(self, node):
|
||||
start = self.context.pop()
|
||||
self.s5_footer.append('<h2>')
|
||||
self.s5_footer.extend(self.body[start:])
|
||||
self.s5_footer.append('</h2>')
|
||||
del self.body[start:]
|
||||
|
||||
def depart_header(self, node):
|
||||
start = self.context.pop()
|
||||
header = ['<div id="header">\n']
|
||||
header.extend(self.body[start:])
|
||||
header.append('\n</div>\n')
|
||||
del self.body[start:]
|
||||
self.s5_header.extend(header)
|
||||
|
||||
def visit_section(self, node):
|
||||
if not self.section_count:
|
||||
self.body.append('\n</div>\n')
|
||||
self.section_count += 1
|
||||
self.section_level += 1
|
||||
if self.section_level > 1:
|
||||
# dummy for matching div's
|
||||
self.body.append(self.starttag(node, 'div', CLASS='section'))
|
||||
else:
|
||||
self.body.append(self.starttag(node, 'div', CLASS='slide'))
|
||||
|
||||
def visit_subtitle(self, node):
|
||||
if isinstance(node.parent, nodes.section):
|
||||
level = self.section_level + self.initial_header_level - 1
|
||||
if level == 1:
|
||||
level = 2
|
||||
tag = 'h%s' % level
|
||||
self.body.append(self.starttag(node, tag, ''))
|
||||
self.context.append('</%s>\n' % tag)
|
||||
else:
|
||||
html4css1.HTMLTranslator.visit_subtitle(self, node)
|
||||
|
||||
def visit_title(self, node):
|
||||
html4css1.HTMLTranslator.visit_title(self, node)
|
Binary file not shown.
|
@ -0,0 +1,6 @@
|
|||
Except where otherwise noted, all files in this
|
||||
directory have been released into the Public Domain.
|
||||
|
||||
These files are based on files from S5 1.1, released into the Public
|
||||
Domain by Eric Meyer. For further details, please see
|
||||
http://www.meyerweb.com/eric/tools/s5/credits.html.
|
|
@ -0,0 +1,2 @@
|
|||
# base theme of this theme:
|
||||
big-white
|
|
@ -0,0 +1,25 @@
|
|||
/* The following styles size, place, and layer the slide components.
|
||||
Edit these if you want to change the overall slide layout.
|
||||
The commented lines can be uncommented (and modified, if necessary)
|
||||
to help you with the rearrangement process. */
|
||||
|
||||
/* target = 1024x768 */
|
||||
|
||||
div#header, div#footer, .slide {width: 100%; top: 0; left: 0;}
|
||||
div#header {top: 0; z-index: 1;}
|
||||
div#footer {display:none;}
|
||||
.slide {top: 0; width: 92%; padding: 0.1em 4% 4%; z-index: 2;}
|
||||
/* list-style: none;} */
|
||||
div#controls {left: 50%; bottom: 0; width: 50%; z-index: 100;}
|
||||
div#controls form {position: absolute; bottom: 0; right: 0; width: 100%;
|
||||
margin: 0;}
|
||||
#currentSlide {position: absolute; width: 10%; left: 45%; bottom: 1em;
|
||||
z-index: 10;}
|
||||
html>body #currentSlide {position: fixed;}
|
||||
|
||||
/*
|
||||
div#header {background: #FCC;}
|
||||
div#footer {background: #CCF;}
|
||||
div#controls {background: #BBD;}
|
||||
div#currentSlide {background: #FFC;}
|
||||
*/
|
|
@ -0,0 +1,109 @@
|
|||
/* This file has been placed in the public domain. */
|
||||
/* Following are the presentation styles -- edit away! */
|
||||
|
||||
html, body {margin: 0; padding: 0;}
|
||||
body {background: black; color: white;}
|
||||
:link, :visited {text-decoration: none; color: cyan;}
|
||||
#controls :active {color: #888 !important;}
|
||||
#controls :focus {outline: 1px dotted #CCC;}
|
||||
|
||||
blockquote {padding: 0 2em 0.5em; margin: 0 1.5em 0.5em;}
|
||||
blockquote p {margin: 0;}
|
||||
|
||||
kbd {font-weight: bold; font-size: 1em;}
|
||||
sup {font-size: smaller; line-height: 1px;}
|
||||
|
||||
.slide pre {padding: 0; margin-left: 0; margin-right: 0; font-size: 90%;}
|
||||
.slide ul ul li {list-style: square;}
|
||||
.slide img.leader {display: block; margin: 0 auto;}
|
||||
.slide tt {font-size: 90%;}
|
||||
|
||||
.slide {font-size: 3em; font-family: sans-serif; font-weight: bold;}
|
||||
.slide h1 {padding-top: 0; z-index: 1; margin: 0; font-size: 120%;}
|
||||
.slide h2 {font-size: 110%;}
|
||||
.slide h3 {font-size: 105%;}
|
||||
h1 abbr {font-variant: small-caps;}
|
||||
|
||||
div#controls {position: absolute; left: 50%; bottom: 0;
|
||||
width: 50%; text-align: right; font: bold 0.9em sans-serif;}
|
||||
html>body div#controls {position: fixed; padding: 0 0 1em 0; top: auto;}
|
||||
div#controls form {position: absolute; bottom: 0; right: 0; width: 100%;
|
||||
margin: 0; padding: 0;}
|
||||
#controls #navLinks a {padding: 0; margin: 0 0.5em;
|
||||
border: none; color: #888; cursor: pointer;}
|
||||
#controls #navList {height: 1em;}
|
||||
#controls #navList #jumplist {position: absolute; bottom: 0; right: 0;
|
||||
background: black; color: #CCC;}
|
||||
|
||||
#currentSlide {text-align: center; font-size: 0.5em; color: #AAA;
|
||||
font-family: sans-serif; font-weight: bold;}
|
||||
|
||||
#slide0 h1 {position: static; margin: 0 0 0.5em; padding-top: 0.3em; top: 0;
|
||||
font-size: 150%; white-space: normal; background: transparent;}
|
||||
#slide0 h2 {font: 110%; font-style: italic; color: gray;}
|
||||
#slide0 h3 {margin-top: 1.5em; font-size: 1.5em;}
|
||||
#slide0 h4 {margin-top: 0; font-size: 1em;}
|
||||
|
||||
ul.urls {list-style: none; display: inline; margin: 0;}
|
||||
.urls li {display: inline; margin: 0;}
|
||||
.external {border-bottom: 1px dotted gray;}
|
||||
html>body .external {border-bottom: none;}
|
||||
.external:after {content: " \274F"; font-size: smaller; color: #FCC;}
|
||||
|
||||
.incremental, .incremental *, .incremental *:after {
|
||||
color: black; visibility: visible; border: 0;}
|
||||
img.incremental {visibility: hidden;}
|
||||
.slide .current {color: lime;}
|
||||
|
||||
.slide-display {display: inline ! important;}
|
||||
|
||||
.huge {font-size: 150%;}
|
||||
.big {font-size: 120%;}
|
||||
.small {font-size: 75%;}
|
||||
.tiny {font-size: 50%;}
|
||||
.huge tt, .big tt, .small tt, .tiny tt {font-size: 115%;}
|
||||
.huge pre, .big pre, .small pre, .tiny pre {font-size: 115%;}
|
||||
|
||||
.maroon {color: maroon;}
|
||||
.red {color: red;}
|
||||
.magenta {color: magenta;}
|
||||
.fuchsia {color: fuchsia;}
|
||||
.pink {color: #FAA;}
|
||||
.orange {color: orange;}
|
||||
.yellow {color: yellow;}
|
||||
.lime {color: lime;}
|
||||
.green {color: green;}
|
||||
.olive {color: olive;}
|
||||
.teal {color: teal;}
|
||||
.cyan {color: cyan;}
|
||||
.aqua {color: aqua;}
|
||||
.blue {color: blue;}
|
||||
.navy {color: navy;}
|
||||
.purple {color: purple;}
|
||||
.black {color: black;}
|
||||
.gray {color: gray;}
|
||||
.silver {color: silver;}
|
||||
.white {color: white;}
|
||||
|
||||
.left {text-align: left ! important;}
|
||||
.center {text-align: center ! important;}
|
||||
.right {text-align: right ! important;}
|
||||
|
||||
.animation {position: relative; margin: 1em 0; padding: 0;}
|
||||
.animation img {position: absolute;}
|
||||
|
||||
/* Docutils-specific overrides */
|
||||
|
||||
.slide table.docinfo {margin: 0.5em 0 0.5em 1em;}
|
||||
|
||||
div.sidebar {background-color: black;}
|
||||
|
||||
pre.literal-block, pre.doctest-block {background-color: black;}
|
||||
|
||||
tt.docutils {background-color: black;}
|
||||
|
||||
/* diagnostics */
|
||||
/*
|
||||
li:after {content: " [" attr(class) "]"; color: #F88;}
|
||||
div:before {content: "[" attr(class) "]"; color: #F88;}
|
||||
*/
|
|
@ -0,0 +1,24 @@
|
|||
/* This file has been placed in the public domain. */
|
||||
/* The following styles size, place, and layer the slide components.
|
||||
Edit these if you want to change the overall slide layout.
|
||||
The commented lines can be uncommented (and modified, if necessary)
|
||||
to help you with the rearrangement process. */
|
||||
|
||||
/* target = 1024x768 */
|
||||
|
||||
div#header, div#footer, .slide {width: 100%; top: 0; left: 0;}
|
||||
div#footer {display:none;}
|
||||
.slide {top: 0; width: 92%; padding: 0.25em 4% 4%; z-index: 2;}
|
||||
div#controls {left: 50%; bottom: 0; width: 50%; z-index: 100;}
|
||||
div#controls form {position: absolute; bottom: 0; right: 0; width: 100%;
|
||||
margin: 0;}
|
||||
#currentSlide {position: absolute; width: 10%; left: 45%; bottom: 1em;
|
||||
z-index: 10;}
|
||||
html>body #currentSlide {position: fixed;}
|
||||
|
||||
/*
|
||||
div#header {background: #FCC;}
|
||||
div#footer {background: #CCF;}
|
||||
div#controls {background: #BBD;}
|
||||
div#currentSlide {background: #FFC;}
|
||||
*/
|
|
@ -0,0 +1,107 @@
|
|||
/* This file has been placed in the public domain. */
|
||||
/* Following are the presentation styles -- edit away! */
|
||||
|
||||
html, body {margin: 0; padding: 0;}
|
||||
body {background: white; color: black;}
|
||||
:link, :visited {text-decoration: none; color: #00C;}
|
||||
#controls :active {color: #88A !important;}
|
||||
#controls :focus {outline: 1px dotted #227;}
|
||||
|
||||
blockquote {padding: 0 2em 0.5em; margin: 0 1.5em 0.5em;}
|
||||
blockquote p {margin: 0;}
|
||||
|
||||
kbd {font-weight: bold; font-size: 1em;}
|
||||
sup {font-size: smaller; line-height: 1px;}
|
||||
|
||||
.slide pre {padding: 0; margin-left: 0; margin-right: 0; font-size: 90%;}
|
||||
.slide ul ul li {list-style: square;}
|
||||
.slide img.leader {display: block; margin: 0 auto;}
|
||||
.slide tt {font-size: 90%;}
|
||||
|
||||
.slide {font-size: 3em; font-family: sans-serif; font-weight: bold;}
|
||||
.slide h1 {padding-top: 0; z-index: 1; margin: 0; font-size: 120%;}
|
||||
.slide h2 {font-size: 110%;}
|
||||
.slide h3 {font-size: 105%;}
|
||||
h1 abbr {font-variant: small-caps;}
|
||||
|
||||
div#controls {position: absolute; left: 50%; bottom: 0;
|
||||
width: 50%; text-align: right; font: bold 0.9em sans-serif;}
|
||||
html>body div#controls {position: fixed; padding: 0 0 1em 0; top: auto;}
|
||||
div#controls form {position: absolute; bottom: 0; right: 0; width: 100%;
|
||||
margin: 0; padding: 0;}
|
||||
#controls #navLinks a {padding: 0; margin: 0 0.5em;
|
||||
border: none; color: #005; cursor: pointer;}
|
||||
#controls #navList {height: 1em;}
|
||||
#controls #navList #jumplist {position: absolute; bottom: 0; right: 0;
|
||||
background: #DDD; color: #227;}
|
||||
|
||||
#currentSlide {text-align: center; font-size: 0.5em; color: #444;
|
||||
font-family: sans-serif; font-weight: bold;}
|
||||
|
||||
#slide0 h1 {position: static; margin: 0 0 0.5em; padding-top: 0.3em; top: 0;
|
||||
font-size: 150%; white-space: normal; background: transparent;}
|
||||
#slide0 h2 {font: 110%; font-style: italic; color: gray;}
|
||||
#slide0 h3 {margin-top: 1.5em; font-size: 1.5em;}
|
||||
#slide0 h4 {margin-top: 0; font-size: 1em;}
|
||||
|
||||
ul.urls {list-style: none; display: inline; margin: 0;}
|
||||
.urls li {display: inline; margin: 0;}
|
||||
.external {border-bottom: 1px dotted gray;}
|
||||
html>body .external {border-bottom: none;}
|
||||
.external:after {content: " \274F"; font-size: smaller; color: #77B;}
|
||||
|
||||
.incremental, .incremental *, .incremental *:after {
|
||||
color: white; visibility: visible; border: 0;}
|
||||
img.incremental {visibility: hidden;}
|
||||
.slide .current {color: green;}
|
||||
|
||||
.slide-display {display: inline ! important;}
|
||||
|
||||
.huge {font-size: 150%;}
|
||||
.big {font-size: 120%;}
|
||||
.small {font-size: 75%;}
|
||||
.tiny {font-size: 50%;}
|
||||
.huge tt, .big tt, .small tt, .tiny tt {font-size: 115%;}
|
||||
.huge pre, .big pre, .small pre, .tiny pre {font-size: 115%;}
|
||||
|
||||
.maroon {color: maroon;}
|
||||
.red {color: red;}
|
||||
.magenta {color: magenta;}
|
||||
.fuchsia {color: fuchsia;}
|
||||
.pink {color: #FAA;}
|
||||
.orange {color: orange;}
|
||||
.yellow {color: yellow;}
|
||||
.lime {color: lime;}
|
||||
.green {color: green;}
|
||||
.olive {color: olive;}
|
||||
.teal {color: teal;}
|
||||
.cyan {color: cyan;}
|
||||
.aqua {color: aqua;}
|
||||
.blue {color: blue;}
|
||||
.navy {color: navy;}
|
||||
.purple {color: purple;}
|
||||
.black {color: black;}
|
||||
.gray {color: gray;}
|
||||
.silver {color: silver;}
|
||||
.white {color: white;}
|
||||
|
||||
.left {text-align: left ! important;}
|
||||
.center {text-align: center ! important;}
|
||||
.right {text-align: right ! important;}
|
||||
|
||||
.animation {position: relative; margin: 1em 0; padding: 0;}
|
||||
.animation img {position: absolute;}
|
||||
|
||||
/* Docutils-specific overrides */
|
||||
|
||||
.slide table.docinfo {margin: 0.5em 0 0.5em 1em;}
|
||||
|
||||
pre.literal-block, pre.doctest-block {background-color: white;}
|
||||
|
||||
tt.docutils {background-color: white;}
|
||||
|
||||
/* diagnostics */
|
||||
/*
|
||||
li:after {content: " [" attr(class) "]"; color: #F88;}
|
||||
div:before {content: "[" attr(class) "]"; color: #F88;}
|
||||
*/
|
|
@ -0,0 +1,25 @@
|
|||
/* This file has been placed in the public domain. */
|
||||
/* The following styles size, place, and layer the slide components.
|
||||
Edit these if you want to change the overall slide layout.
|
||||
The commented lines can be uncommented (and modified, if necessary)
|
||||
to help you with the rearrangement process. */
|
||||
|
||||
/* target = 1024x768 */
|
||||
|
||||
div#header, div#footer, .slide {width: 100%; top: 0; left: 0;}
|
||||
div#header {position: fixed; top: 0; height: 3em; z-index: 1;}
|
||||
div#footer {top: auto; bottom: 0; height: 2.5em; z-index: 5;}
|
||||
.slide {top: 0; width: 92%; padding: 2.5em 4% 4%; z-index: 2;}
|
||||
div#controls {left: 50%; bottom: 0; width: 50%; z-index: 100;}
|
||||
div#controls form {position: absolute; bottom: 0; right: 0; width: 100%;
|
||||
margin: 0;}
|
||||
#currentSlide {position: absolute; width: 10%; left: 45%; bottom: 1em;
|
||||
z-index: 10;}
|
||||
html>body #currentSlide {position: fixed;}
|
||||
|
||||
/*
|
||||
div#header {background: #FCC;}
|
||||
div#footer {background: #CCF;}
|
||||
div#controls {background: #BBD;}
|
||||
div#currentSlide {background: #FFC;}
|
||||
*/
|
|
@ -0,0 +1,8 @@
|
|||
/* This file has been placed in the public domain. */
|
||||
/* DO NOT CHANGE THESE unless you really want to break Opera Show */
|
||||
.slide {
|
||||
visibility: visible !important;
|
||||
position: static !important;
|
||||
page-break-before: always;
|
||||
}
|
||||
#slide0 {page-break-before: avoid;}
|
|
@ -0,0 +1,16 @@
|
|||
/* This file has been placed in the public domain. */
|
||||
/* Don't change this unless you want the layout stuff to show up in the
|
||||
outline view! */
|
||||
|
||||
.layout div, #footer *, #controlForm * {display: none;}
|
||||
#footer, #controls, #controlForm, #navLinks, #toggle {
|
||||
display: block; visibility: visible; margin: 0; padding: 0;}
|
||||
#toggle {float: right; padding: 0.5em;}
|
||||
html>body #toggle {position: fixed; top: 0; right: 0;}
|
||||
|
||||
/* making the outline look pretty-ish */
|
||||
|
||||
#slide0 h1, #slide0 h2, #slide0 h3, #slide0 h4 {border: none; margin: 0;}
|
||||
#toggle {border: 1px solid; border-width: 0 0 1px 1px; background: #FFF;}
|
||||
|
||||
.outline {display: inline ! important;}
|
|
@ -0,0 +1,120 @@
|
|||
/* This file has been placed in the public domain. */
|
||||
/* Following are the presentation styles -- edit away! */
|
||||
|
||||
html, body {margin: 0; padding: 0;}
|
||||
body {background: white; color: black;}
|
||||
/* Replace the background style above with the style below (and again for
|
||||
div#header) for a graphic: */
|
||||
/* background: white url(bodybg.gif) -16px 0 no-repeat; */
|
||||
:link, :visited {text-decoration: none; color: #00C;}
|
||||
#controls :active {color: #88A !important;}
|
||||
#controls :focus {outline: 1px dotted #227;}
|
||||
h1, h2, h3, h4 {font-size: 100%; margin: 0; padding: 0; font-weight: inherit;}
|
||||
|
||||
blockquote {padding: 0 2em 0.5em; margin: 0 1.5em 0.5em;}
|
||||
blockquote p {margin: 0;}
|
||||
|
||||
kbd {font-weight: bold; font-size: 1em;}
|
||||
sup {font-size: smaller; line-height: 1px;}
|
||||
|
||||
.slide pre {padding: 0; margin-left: 0; margin-right: 0; font-size: 90%;}
|
||||
.slide ul ul li {list-style: square;}
|
||||
.slide img.leader {display: block; margin: 0 auto;}
|
||||
.slide tt {font-size: 90%;}
|
||||
|
||||
div#header, div#footer {background: #005; color: #AAB; font-family: sans-serif;}
|
||||
/* background: #005 url(bodybg.gif) -16px 0 no-repeat; */
|
||||
div#footer {font-size: 0.5em; font-weight: bold; padding: 1em 0;}
|
||||
#footer h1 {display: block; padding: 0 1em;}
|
||||
#footer h2 {display: block; padding: 0.8em 1em 0;}
|
||||
|
||||
.slide {font-size: 1.2em;}
|
||||
.slide h1 {position: absolute; top: 0.45em; z-index: 1;
|
||||
margin: 0; padding-left: 0.7em; white-space: nowrap;
|
||||
font: bold 150% sans-serif; color: #DDE; background: #005;}
|
||||
.slide h2 {font: bold 120%/1em sans-serif; padding-top: 0.5em;}
|
||||
.slide h3 {font: bold 100% sans-serif; padding-top: 0.5em;}
|
||||
h1 abbr {font-variant: small-caps;}
|
||||
|
||||
div#controls {position: absolute; left: 50%; bottom: 0;
|
||||
width: 50%; text-align: right; font: bold 0.9em sans-serif;}
|
||||
html>body div#controls {position: fixed; padding: 0 0 1em 0; top: auto;}
|
||||
div#controls form {position: absolute; bottom: 0; right: 0; width: 100%;
|
||||
margin: 0; padding: 0;}
|
||||
#controls #navLinks a {padding: 0; margin: 0 0.5em;
|
||||
background: #005; border: none; color: #779; cursor: pointer;}
|
||||
#controls #navList {height: 1em;}
|
||||
#controls #navList #jumplist {position: absolute; bottom: 0; right: 0;
|
||||
background: #DDD; color: #227;}
|
||||
|
||||
#currentSlide {text-align: center; font-size: 0.5em; color: #449;
|
||||
font-family: sans-serif; font-weight: bold;}
|
||||
|
||||
#slide0 {padding-top: 1.5em}
|
||||
#slide0 h1 {position: static; margin: 1em 0 0; padding: 0; color: #000;
|
||||
font: bold 2em sans-serif; white-space: normal; background: transparent;}
|
||||
#slide0 h2 {font: bold italic 1em sans-serif; margin: 0.25em;}
|
||||
#slide0 h3 {margin-top: 1.5em; font-size: 1.5em;}
|
||||
#slide0 h4 {margin-top: 0; font-size: 1em;}
|
||||
|
||||
ul.urls {list-style: none; display: inline; margin: 0;}
|
||||
.urls li {display: inline; margin: 0;}
|
||||
.external {border-bottom: 1px dotted gray;}
|
||||
html>body .external {border-bottom: none;}
|
||||
.external:after {content: " \274F"; font-size: smaller; color: #77B;}
|
||||
|
||||
.incremental, .incremental *, .incremental *:after {visibility: visible;
|
||||
color: white; border: 0;}
|
||||
img.incremental {visibility: hidden;}
|
||||
.slide .current {color: green;}
|
||||
|
||||
.slide-display {display: inline ! important;}
|
||||
|
||||
.huge {font-family: sans-serif; font-weight: bold; font-size: 150%;}
|
||||
.big {font-family: sans-serif; font-weight: bold; font-size: 120%;}
|
||||
.small {font-size: 75%;}
|
||||
.tiny {font-size: 50%;}
|
||||
.huge tt, .big tt, .small tt, .tiny tt {font-size: 115%;}
|
||||
.huge pre, .big pre, .small pre, .tiny pre {font-size: 115%;}
|
||||
|
||||
.maroon {color: maroon;}
|
||||
.red {color: red;}
|
||||
.magenta {color: magenta;}
|
||||
.fuchsia {color: fuchsia;}
|
||||
.pink {color: #FAA;}
|
||||
.orange {color: orange;}
|
||||
.yellow {color: yellow;}
|
||||
.lime {color: lime;}
|
||||
.green {color: green;}
|
||||
.olive {color: olive;}
|
||||
.teal {color: teal;}
|
||||
.cyan {color: cyan;}
|
||||
.aqua {color: aqua;}
|
||||
.blue {color: blue;}
|
||||
.navy {color: navy;}
|
||||
.purple {color: purple;}
|
||||
.black {color: black;}
|
||||
.gray {color: gray;}
|
||||
.silver {color: silver;}
|
||||
.white {color: white;}
|
||||
|
||||
.left {text-align: left ! important;}
|
||||
.center {text-align: center ! important;}
|
||||
.right {text-align: right ! important;}
|
||||
|
||||
.animation {position: relative; margin: 1em 0; padding: 0;}
|
||||
.animation img {position: absolute;}
|
||||
|
||||
/* Docutils-specific overrides */
|
||||
|
||||
.slide table.docinfo {margin: 1em 0 0.5em 2em;}
|
||||
|
||||
pre.literal-block, pre.doctest-block {background-color: white;}
|
||||
|
||||
tt.docutils {background-color: white;}
|
||||
|
||||
/* diagnostics */
|
||||
/*
|
||||
li:after {content: " [" attr(class) "]"; color: #F88;}
|
||||
div:before {content: "[" attr(class) "]"; color: #F88;}
|
||||
*/
|
|
@ -0,0 +1,24 @@
|
|||
/* This file has been placed in the public domain. */
|
||||
/* The following rule is necessary to have all slides appear in print!
|
||||
DO NOT REMOVE IT! */
|
||||
.slide, ul {page-break-inside: avoid; visibility: visible !important;}
|
||||
h1 {page-break-after: avoid;}
|
||||
|
||||
body {font-size: 12pt; background: white;}
|
||||
* {color: black;}
|
||||
|
||||
#slide0 h1 {font-size: 200%; border: none; margin: 0.5em 0 0.25em;}
|
||||
#slide0 h3 {margin: 0; padding: 0;}
|
||||
#slide0 h4 {margin: 0 0 0.5em; padding: 0;}
|
||||
#slide0 {margin-bottom: 3em;}
|
||||
|
||||
#header {display: none;}
|
||||
#footer h1 {margin: 0; border-bottom: 1px solid; color: gray;
|
||||
font-style: italic;}
|
||||
#footer h2, #controls {display: none;}
|
||||
|
||||
.print {display: inline ! important;}
|
||||
|
||||
/* The following rule keeps the layout stuff out of print.
|
||||
Remove at your own risk! */
|
||||
.layout, .layout * {display: none !important;}
|
|
@ -0,0 +1,11 @@
|
|||
/* This file has been placed in the public domain. */
|
||||
/* Do not edit or override these styles!
|
||||
The system will likely break if you do. */
|
||||
|
||||
div#header, div#footer, div#controls, .slide {position: absolute;}
|
||||
html>body div#header, html>body div#footer,
|
||||
html>body div#controls, html>body .slide {position: fixed;}
|
||||
.handout {display: none;}
|
||||
.layout {display: block;}
|
||||
.slide, .hideme, .incremental {visibility: hidden;}
|
||||
#slide0 {visibility: visible;}
|
|
@ -0,0 +1,10 @@
|
|||
/* This file has been placed in the public domain. */
|
||||
|
||||
/* required to make the slide show run at all */
|
||||
@import url(s5-core.css);
|
||||
|
||||
/* sets basic placement and size of slide components */
|
||||
@import url(framing.css);
|
||||
|
||||
/* styles that make the slides look good */
|
||||
@import url(pretty.css);
|
|
@ -0,0 +1,558 @@
|
|||
// S5 v1.1 slides.js -- released into the Public Domain
|
||||
// Modified for Docutils (https://docutils.sourceforge.io) by David Goodger
|
||||
//
|
||||
// Please see http://www.meyerweb.com/eric/tools/s5/credits.html for
|
||||
// information about all the wonderful and talented contributors to this code!
|
||||
|
||||
var undef;
|
||||
var slideCSS = '';
|
||||
var snum = 0;
|
||||
var smax = 1;
|
||||
var slideIDs = new Array();
|
||||
var incpos = 0;
|
||||
var number = undef;
|
||||
var s5mode = true;
|
||||
var defaultView = 'slideshow';
|
||||
var controlVis = 'visible';
|
||||
|
||||
var isIE = navigator.appName == 'Microsoft Internet Explorer' ? 1 : 0;
|
||||
var isOp = navigator.userAgent.indexOf('Opera') > -1 ? 1 : 0;
|
||||
var isGe = navigator.userAgent.indexOf('Gecko') > -1 && navigator.userAgent.indexOf('Safari') < 1 ? 1 : 0;
|
||||
|
||||
function hasClass(object, className) {
|
||||
if (!object.className) return false;
|
||||
return (object.className.search('(^|\\s)' + className + '(\\s|$)') != -1);
|
||||
}
|
||||
|
||||
function hasValue(object, value) {
|
||||
if (!object) return false;
|
||||
return (object.search('(^|\\s)' + value + '(\\s|$)') != -1);
|
||||
}
|
||||
|
||||
function removeClass(object,className) {
|
||||
if (!object) return;
|
||||
object.className = object.className.replace(new RegExp('(^|\\s)'+className+'(\\s|$)'), RegExp.$1+RegExp.$2);
|
||||
}
|
||||
|
||||
function addClass(object,className) {
|
||||
if (!object || hasClass(object, className)) return;
|
||||
if (object.className) {
|
||||
object.className += ' '+className;
|
||||
} else {
|
||||
object.className = className;
|
||||
}
|
||||
}
|
||||
|
||||
function GetElementsWithClassName(elementName,className) {
|
||||
var allElements = document.getElementsByTagName(elementName);
|
||||
var elemColl = new Array();
|
||||
for (var i = 0; i< allElements.length; i++) {
|
||||
if (hasClass(allElements[i], className)) {
|
||||
elemColl[elemColl.length] = allElements[i];
|
||||
}
|
||||
}
|
||||
return elemColl;
|
||||
}
|
||||
|
||||
function isParentOrSelf(element, id) {
|
||||
if (element == null || element.nodeName=='BODY') return false;
|
||||
else if (element.id == id) return true;
|
||||
else return isParentOrSelf(element.parentNode, id);
|
||||
}
|
||||
|
||||
function nodeValue(node) {
|
||||
var result = "";
|
||||
if (node.nodeType == 1) {
|
||||
var children = node.childNodes;
|
||||
for (var i = 0; i < children.length; ++i) {
|
||||
result += nodeValue(children[i]);
|
||||
}
|
||||
}
|
||||
else if (node.nodeType == 3) {
|
||||
result = node.nodeValue;
|
||||
}
|
||||
return(result);
|
||||
}
|
||||
|
||||
function slideLabel() {
|
||||
var slideColl = GetElementsWithClassName('*','slide');
|
||||
var list = document.getElementById('jumplist');
|
||||
smax = slideColl.length;
|
||||
for (var n = 0; n < smax; n++) {
|
||||
var obj = slideColl[n];
|
||||
|
||||
var did = 'slide' + n.toString();
|
||||
if (obj.getAttribute('id')) {
|
||||
slideIDs[n] = obj.getAttribute('id');
|
||||
}
|
||||
else {
|
||||
obj.setAttribute('id',did);
|
||||
slideIDs[n] = did;
|
||||
}
|
||||
if (isOp) continue;
|
||||
|
||||
var otext = '';
|
||||
var menu = obj.firstChild;
|
||||
if (!menu) continue; // to cope with empty slides
|
||||
while (menu && menu.nodeType == 3) {
|
||||
menu = menu.nextSibling;
|
||||
}
|
||||
if (!menu) continue; // to cope with slides with only text nodes
|
||||
|
||||
var menunodes = menu.childNodes;
|
||||
for (var o = 0; o < menunodes.length; o++) {
|
||||
otext += nodeValue(menunodes[o]);
|
||||
}
|
||||
list.options[list.length] = new Option(n + ' : ' + otext, n);
|
||||
}
|
||||
}
|
||||
|
||||
function currentSlide() {
|
||||
var cs;
|
||||
var footer_nodes;
|
||||
var vis = 'visible';
|
||||
if (document.getElementById) {
|
||||
cs = document.getElementById('currentSlide');
|
||||
footer_nodes = document.getElementById('footer').childNodes;
|
||||
} else {
|
||||
cs = document.currentSlide;
|
||||
footer = document.footer.childNodes;
|
||||
}
|
||||
cs.innerHTML = '<span id="csHere">' + snum + '<\/span> ' +
|
||||
'<span id="csSep">\/<\/span> ' +
|
||||
'<span id="csTotal">' + (smax-1) + '<\/span>';
|
||||
if (snum == 0) {
|
||||
vis = 'hidden';
|
||||
}
|
||||
cs.style.visibility = vis;
|
||||
for (var i = 0; i < footer_nodes.length; i++) {
|
||||
if (footer_nodes[i].nodeType == 1) {
|
||||
footer_nodes[i].style.visibility = vis;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function go(step) {
|
||||
if (document.getElementById('slideProj').disabled || step == 0) return;
|
||||
var jl = document.getElementById('jumplist');
|
||||
var cid = slideIDs[snum];
|
||||
var ce = document.getElementById(cid);
|
||||
if (incrementals[snum].length > 0) {
|
||||
for (var i = 0; i < incrementals[snum].length; i++) {
|
||||
removeClass(incrementals[snum][i], 'current');
|
||||
removeClass(incrementals[snum][i], 'incremental');
|
||||
}
|
||||
}
|
||||
if (step != 'j') {
|
||||
snum += step;
|
||||
lmax = smax - 1;
|
||||
if (snum > lmax) snum = lmax;
|
||||
if (snum < 0) snum = 0;
|
||||
} else
|
||||
snum = parseInt(jl.value);
|
||||
var nid = slideIDs[snum];
|
||||
var ne = document.getElementById(nid);
|
||||
if (!ne) {
|
||||
ne = document.getElementById(slideIDs[0]);
|
||||
snum = 0;
|
||||
}
|
||||
if (step < 0) {incpos = incrementals[snum].length} else {incpos = 0;}
|
||||
if (incrementals[snum].length > 0 && incpos == 0) {
|
||||
for (var i = 0; i < incrementals[snum].length; i++) {
|
||||
if (hasClass(incrementals[snum][i], 'current'))
|
||||
incpos = i + 1;
|
||||
else
|
||||
addClass(incrementals[snum][i], 'incremental');
|
||||
}
|
||||
}
|
||||
if (incrementals[snum].length > 0 && incpos > 0)
|
||||
addClass(incrementals[snum][incpos - 1], 'current');
|
||||
ce.style.visibility = 'hidden';
|
||||
ne.style.visibility = 'visible';
|
||||
jl.selectedIndex = snum;
|
||||
currentSlide();
|
||||
number = 0;
|
||||
}
|
||||
|
||||
function goTo(target) {
|
||||
if (target >= smax || target == snum) return;
|
||||
go(target - snum);
|
||||
}
|
||||
|
||||
function subgo(step) {
|
||||
if (step > 0) {
|
||||
removeClass(incrementals[snum][incpos - 1],'current');
|
||||
removeClass(incrementals[snum][incpos], 'incremental');
|
||||
addClass(incrementals[snum][incpos],'current');
|
||||
incpos++;
|
||||
} else {
|
||||
incpos--;
|
||||
removeClass(incrementals[snum][incpos],'current');
|
||||
addClass(incrementals[snum][incpos], 'incremental');
|
||||
addClass(incrementals[snum][incpos - 1],'current');
|
||||
}
|
||||
}
|
||||
|
||||
function toggle() {
|
||||
var slideColl = GetElementsWithClassName('*','slide');
|
||||
var slides = document.getElementById('slideProj');
|
||||
var outline = document.getElementById('outlineStyle');
|
||||
if (!slides.disabled) {
|
||||
slides.disabled = true;
|
||||
outline.disabled = false;
|
||||
s5mode = false;
|
||||
fontSize('1em');
|
||||
for (var n = 0; n < smax; n++) {
|
||||
var slide = slideColl[n];
|
||||
slide.style.visibility = 'visible';
|
||||
}
|
||||
} else {
|
||||
slides.disabled = false;
|
||||
outline.disabled = true;
|
||||
s5mode = true;
|
||||
fontScale();
|
||||
for (var n = 0; n < smax; n++) {
|
||||
var slide = slideColl[n];
|
||||
slide.style.visibility = 'hidden';
|
||||
}
|
||||
slideColl[snum].style.visibility = 'visible';
|
||||
}
|
||||
}
|
||||
|
||||
function showHide(action) {
|
||||
var obj = GetElementsWithClassName('*','hideme')[0];
|
||||
switch (action) {
|
||||
case 's': obj.style.visibility = 'visible'; break;
|
||||
case 'h': obj.style.visibility = 'hidden'; break;
|
||||
case 'k':
|
||||
if (obj.style.visibility != 'visible') {
|
||||
obj.style.visibility = 'visible';
|
||||
} else {
|
||||
obj.style.visibility = 'hidden';
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// 'keys' code adapted from MozPoint (http://mozpoint.mozdev.org/)
|
||||
function keys(key) {
|
||||
if (!key) {
|
||||
key = event;
|
||||
key.which = key.keyCode;
|
||||
}
|
||||
if (key.which == 84) {
|
||||
toggle();
|
||||
return;
|
||||
}
|
||||
if (s5mode) {
|
||||
switch (key.which) {
|
||||
case 10: // return
|
||||
case 13: // enter
|
||||
if (window.event && isParentOrSelf(window.event.srcElement, 'controls')) return;
|
||||
if (key.target && isParentOrSelf(key.target, 'controls')) return;
|
||||
if(number != undef) {
|
||||
goTo(number);
|
||||
break;
|
||||
}
|
||||
case 32: // spacebar
|
||||
case 34: // page down
|
||||
case 39: // rightkey
|
||||
case 40: // downkey
|
||||
if(number != undef) {
|
||||
go(number);
|
||||
} else if (!incrementals[snum] || incpos >= incrementals[snum].length) {
|
||||
go(1);
|
||||
} else {
|
||||
subgo(1);
|
||||
}
|
||||
break;
|
||||
case 33: // page up
|
||||
case 37: // leftkey
|
||||
case 38: // upkey
|
||||
if(number != undef) {
|
||||
go(-1 * number);
|
||||
} else if (!incrementals[snum] || incpos <= 0) {
|
||||
go(-1);
|
||||
} else {
|
||||
subgo(-1);
|
||||
}
|
||||
break;
|
||||
case 36: // home
|
||||
goTo(0);
|
||||
break;
|
||||
case 35: // end
|
||||
goTo(smax-1);
|
||||
break;
|
||||
case 67: // c
|
||||
showHide('k');
|
||||
break;
|
||||
}
|
||||
if (key.which < 48 || key.which > 57) {
|
||||
number = undef;
|
||||
} else {
|
||||
if (window.event && isParentOrSelf(window.event.srcElement, 'controls')) return;
|
||||
if (key.target && isParentOrSelf(key.target, 'controls')) return;
|
||||
number = (((number != undef) ? number : 0) * 10) + (key.which - 48);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function clicker(e) {
|
||||
number = undef;
|
||||
var target;
|
||||
if (window.event) {
|
||||
target = window.event.srcElement;
|
||||
e = window.event;
|
||||
} else target = e.target;
|
||||
if (target.href != null || hasValue(target.rel, 'external') || isParentOrSelf(target, 'controls') || isParentOrSelf(target,'embed') || isParentOrSelf(target, 'object')) return true;
|
||||
if (!e.which || e.which == 1) {
|
||||
if (!incrementals[snum] || incpos >= incrementals[snum].length) {
|
||||
go(1);
|
||||
} else {
|
||||
subgo(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function findSlide(hash) {
|
||||
var target = document.getElementById(hash);
|
||||
if (target) {
|
||||
for (var i = 0; i < slideIDs.length; i++) {
|
||||
if (target.id == slideIDs[i]) return i;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
function slideJump() {
|
||||
if (window.location.hash == null || window.location.hash == '') {
|
||||
currentSlide();
|
||||
return;
|
||||
}
|
||||
if (window.location.hash == null) return;
|
||||
var dest = null;
|
||||
dest = findSlide(window.location.hash.slice(1));
|
||||
if (dest == null) {
|
||||
dest = 0;
|
||||
}
|
||||
go(dest - snum);
|
||||
}
|
||||
|
||||
function fixLinks() {
|
||||
var thisUri = window.location.href;
|
||||
thisUri = thisUri.slice(0, thisUri.length - window.location.hash.length);
|
||||
var aelements = document.getElementsByTagName('A');
|
||||
for (var i = 0; i < aelements.length; i++) {
|
||||
var a = aelements[i].href;
|
||||
var slideID = a.match('\#.+');
|
||||
if ((slideID) && (slideID[0].slice(0,1) == '#')) {
|
||||
var dest = findSlide(slideID[0].slice(1));
|
||||
if (dest != null) {
|
||||
if (aelements[i].addEventListener) {
|
||||
aelements[i].addEventListener("click", new Function("e",
|
||||
"if (document.getElementById('slideProj').disabled) return;" +
|
||||
"go("+dest+" - snum); " +
|
||||
"if (e.preventDefault) e.preventDefault();"), true);
|
||||
} else if (aelements[i].attachEvent) {
|
||||
aelements[i].attachEvent("onclick", new Function("",
|
||||
"if (document.getElementById('slideProj').disabled) return;" +
|
||||
"go("+dest+" - snum); " +
|
||||
"event.returnValue = false;"));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function externalLinks() {
|
||||
if (!document.getElementsByTagName) return;
|
||||
var anchors = document.getElementsByTagName('a');
|
||||
for (var i=0; i<anchors.length; i++) {
|
||||
var anchor = anchors[i];
|
||||
if (anchor.getAttribute('href') && hasValue(anchor.rel, 'external')) {
|
||||
anchor.target = '_blank';
|
||||
addClass(anchor,'external');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function createControls() {
|
||||
var controlsDiv = document.getElementById("controls");
|
||||
if (!controlsDiv) return;
|
||||
var hider = ' onmouseover="showHide(\'s\');" onmouseout="showHide(\'h\');"';
|
||||
var hideDiv, hideList = '';
|
||||
if (controlVis == 'hidden') {
|
||||
hideDiv = hider;
|
||||
} else {
|
||||
hideList = hider;
|
||||
}
|
||||
controlsDiv.innerHTML = '<form action="#" id="controlForm"' + hideDiv + '>' +
|
||||
'<div id="navLinks">' +
|
||||
'<a accesskey="t" id="toggle" href="javascript:toggle();">Ø<\/a>' +
|
||||
'<a accesskey="z" id="prev" href="javascript:go(-1);">«<\/a>' +
|
||||
'<a accesskey="x" id="next" href="javascript:go(1);">»<\/a>' +
|
||||
'<div id="navList"' + hideList + '><select id="jumplist" onchange="go(\'j\');"><\/select><\/div>' +
|
||||
'<\/div><\/form>';
|
||||
if (controlVis == 'hidden') {
|
||||
var hidden = document.getElementById('navLinks');
|
||||
} else {
|
||||
var hidden = document.getElementById('jumplist');
|
||||
}
|
||||
addClass(hidden,'hideme');
|
||||
}
|
||||
|
||||
function fontScale() { // causes layout problems in FireFox that get fixed if browser's Reload is used; same may be true of other Gecko-based browsers
|
||||
if (!s5mode) return false;
|
||||
var vScale = 22; // both yield 32 (after rounding) at 1024x768
|
||||
var hScale = 32; // perhaps should auto-calculate based on theme's declared value?
|
||||
if (window.innerHeight) {
|
||||
var vSize = window.innerHeight;
|
||||
var hSize = window.innerWidth;
|
||||
} else if (document.documentElement.clientHeight) {
|
||||
var vSize = document.documentElement.clientHeight;
|
||||
var hSize = document.documentElement.clientWidth;
|
||||
} else if (document.body.clientHeight) {
|
||||
var vSize = document.body.clientHeight;
|
||||
var hSize = document.body.clientWidth;
|
||||
} else {
|
||||
var vSize = 700; // assuming 1024x768, minus chrome and such
|
||||
var hSize = 1024; // these do not account for kiosk mode or Opera Show
|
||||
}
|
||||
var newSize = Math.min(Math.round(vSize/vScale),Math.round(hSize/hScale));
|
||||
fontSize(newSize + 'px');
|
||||
if (isGe) { // hack to counter incremental reflow bugs
|
||||
var obj = document.getElementsByTagName('body')[0];
|
||||
obj.style.display = 'none';
|
||||
obj.style.display = 'block';
|
||||
}
|
||||
}
|
||||
|
||||
function fontSize(value) {
|
||||
if (!(s5ss = document.getElementById('s5ss'))) {
|
||||
if (!isIE) {
|
||||
document.getElementsByTagName('head')[0].appendChild(s5ss = document.createElement('style'));
|
||||
s5ss.setAttribute('media','screen, projection');
|
||||
s5ss.setAttribute('id','s5ss');
|
||||
} else {
|
||||
document.createStyleSheet();
|
||||
document.s5ss = document.styleSheets[document.styleSheets.length - 1];
|
||||
}
|
||||
}
|
||||
if (!isIE) {
|
||||
while (s5ss.lastChild) s5ss.removeChild(s5ss.lastChild);
|
||||
s5ss.appendChild(document.createTextNode('body {font-size: ' + value + ' !important;}'));
|
||||
} else {
|
||||
document.s5ss.addRule('body','font-size: ' + value + ' !important;');
|
||||
}
|
||||
}
|
||||
|
||||
function notOperaFix() {
|
||||
slideCSS = document.getElementById('slideProj').href;
|
||||
var slides = document.getElementById('slideProj');
|
||||
var outline = document.getElementById('outlineStyle');
|
||||
slides.setAttribute('media','screen');
|
||||
outline.disabled = true;
|
||||
if (isGe) {
|
||||
slides.setAttribute('href','null'); // Gecko fix
|
||||
slides.setAttribute('href',slideCSS); // Gecko fix
|
||||
}
|
||||
if (isIE && document.styleSheets && document.styleSheets[0]) {
|
||||
document.styleSheets[0].addRule('img', 'behavior: url(ui/default/iepngfix.htc)');
|
||||
document.styleSheets[0].addRule('div', 'behavior: url(ui/default/iepngfix.htc)');
|
||||
document.styleSheets[0].addRule('.slide', 'behavior: url(ui/default/iepngfix.htc)');
|
||||
}
|
||||
}
|
||||
|
||||
function getIncrementals(obj) {
|
||||
var incrementals = new Array();
|
||||
if (!obj)
|
||||
return incrementals;
|
||||
var children = obj.childNodes;
|
||||
for (var i = 0; i < children.length; i++) {
|
||||
var child = children[i];
|
||||
if (hasClass(child, 'incremental')) {
|
||||
if (child.nodeName == 'OL' || child.nodeName == 'UL') {
|
||||
removeClass(child, 'incremental');
|
||||
for (var j = 0; j < child.childNodes.length; j++) {
|
||||
if (child.childNodes[j].nodeType == 1) {
|
||||
addClass(child.childNodes[j], 'incremental');
|
||||
}
|
||||
}
|
||||
} else {
|
||||
incrementals[incrementals.length] = child;
|
||||
removeClass(child,'incremental');
|
||||
}
|
||||
}
|
||||
if (hasClass(child, 'show-first')) {
|
||||
if (child.nodeName == 'OL' || child.nodeName == 'UL') {
|
||||
removeClass(child, 'show-first');
|
||||
if (child.childNodes[isGe].nodeType == 1) {
|
||||
removeClass(child.childNodes[isGe], 'incremental');
|
||||
}
|
||||
} else {
|
||||
incrementals[incrementals.length] = child;
|
||||
}
|
||||
}
|
||||
incrementals = incrementals.concat(getIncrementals(child));
|
||||
}
|
||||
return incrementals;
|
||||
}
|
||||
|
||||
function createIncrementals() {
|
||||
var incrementals = new Array();
|
||||
for (var i = 0; i < smax; i++) {
|
||||
incrementals[i] = getIncrementals(document.getElementById(slideIDs[i]));
|
||||
}
|
||||
return incrementals;
|
||||
}
|
||||
|
||||
function defaultCheck() {
|
||||
var allMetas = document.getElementsByTagName('meta');
|
||||
for (var i = 0; i< allMetas.length; i++) {
|
||||
if (allMetas[i].name == 'defaultView') {
|
||||
defaultView = allMetas[i].content;
|
||||
}
|
||||
if (allMetas[i].name == 'controlVis') {
|
||||
controlVis = allMetas[i].content;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Key trap fix, new function body for trap()
|
||||
function trap(e) {
|
||||
if (!e) {
|
||||
e = event;
|
||||
e.which = e.keyCode;
|
||||
}
|
||||
try {
|
||||
modifierKey = e.ctrlKey || e.altKey || e.metaKey;
|
||||
}
|
||||
catch(e) {
|
||||
modifierKey = false;
|
||||
}
|
||||
return modifierKey || e.which == 0;
|
||||
}
|
||||
|
||||
function startup() {
|
||||
defaultCheck();
|
||||
if (!isOp) createControls();
|
||||
slideLabel();
|
||||
fixLinks();
|
||||
externalLinks();
|
||||
fontScale();
|
||||
if (!isOp) {
|
||||
notOperaFix();
|
||||
incrementals = createIncrementals();
|
||||
slideJump();
|
||||
if (defaultView == 'outline') {
|
||||
toggle();
|
||||
}
|
||||
document.onkeyup = keys;
|
||||
document.onkeypress = trap;
|
||||
document.onclick = clicker;
|
||||
}
|
||||
}
|
||||
|
||||
window.onload = startup;
|
||||
window.onresize = function(){setTimeout('fontScale()', 50);}
|
|
@ -0,0 +1,2 @@
|
|||
# base theme of this theme:
|
||||
medium-white
|
|
@ -0,0 +1,115 @@
|
|||
/* This file has been placed in the public domain. */
|
||||
/* Following are the presentation styles -- edit away! */
|
||||
|
||||
html, body {margin: 0; padding: 0;}
|
||||
body {background: black; color: white;}
|
||||
:link, :visited {text-decoration: none; color: cyan;}
|
||||
#controls :active {color: #888 !important;}
|
||||
#controls :focus {outline: 1px dotted #CCC;}
|
||||
h1, h2, h3, h4 {font-size: 100%; margin: 0; padding: 0; font-weight: inherit;}
|
||||
|
||||
blockquote {padding: 0 2em 0.5em; margin: 0 1.5em 0.5em;}
|
||||
blockquote p {margin: 0;}
|
||||
|
||||
kbd {font-weight: bold; font-size: 1em;}
|
||||
sup {font-size: smaller; line-height: 1px;}
|
||||
|
||||
.slide pre {padding: 0; margin-left: 0; margin-right: 0; font-size: 90%;}
|
||||
.slide ul ul li {list-style: square;}
|
||||
.slide img.leader {display: block; margin: 0 auto;}
|
||||
.slide tt {font-size: 90%;}
|
||||
|
||||
div#footer {font-family: sans-serif; color: #AAA;
|
||||
font-size: 0.5em; font-weight: bold; padding: 1em 0;}
|
||||
#footer h1 {display: block; padding: 0 1em;}
|
||||
#footer h2 {display: block; padding: 0.8em 1em 0;}
|
||||
|
||||
.slide {font-size: 1.75em;}
|
||||
.slide h1 {padding-top: 0; z-index: 1; margin: 0; font: bold 150% sans-serif;}
|
||||
.slide h2 {font: bold 125% sans-serif; padding-top: 0.5em;}
|
||||
.slide h3 {font: bold 110% sans-serif; padding-top: 0.5em;}
|
||||
h1 abbr {font-variant: small-caps;}
|
||||
|
||||
div#controls {position: absolute; left: 50%; bottom: 0;
|
||||
width: 50%; text-align: right; font: bold 0.9em sans-serif;}
|
||||
html>body div#controls {position: fixed; padding: 0 0 1em 0; top: auto;}
|
||||
div#controls form {position: absolute; bottom: 0; right: 0; width: 100%;
|
||||
margin: 0; padding: 0;}
|
||||
#controls #navLinks a {padding: 0; margin: 0 0.5em;
|
||||
border: none; color: #888; cursor: pointer;}
|
||||
#controls #navList {height: 1em;}
|
||||
#controls #navList #jumplist {position: absolute; bottom: 0; right: 0;
|
||||
background: black; color: #CCC;}
|
||||
|
||||
#currentSlide {text-align: center; font-size: 0.5em; color: #AAA;
|
||||
font-family: sans-serif; font-weight: bold;}
|
||||
|
||||
#slide0 h1 {position: static; margin: 0 0 0.5em; padding-top: 1em; top: 0;
|
||||
font: bold 150% sans-serif; white-space: normal; background: transparent;}
|
||||
#slide0 h2 {font: bold italic 125% sans-serif; color: gray;}
|
||||
#slide0 h3 {margin-top: 1.5em; font: bold 110% sans-serif;}
|
||||
#slide0 h4 {margin-top: 0; font-size: 1em;}
|
||||
|
||||
ul.urls {list-style: none; display: inline; margin: 0;}
|
||||
.urls li {display: inline; margin: 0;}
|
||||
.external {border-bottom: 1px dotted gray;}
|
||||
html>body .external {border-bottom: none;}
|
||||
.external:after {content: " \274F"; font-size: smaller; color: #FCC;}
|
||||
|
||||
.incremental, .incremental *, .incremental *:after {
|
||||
color: black; visibility: visible; border: 0;}
|
||||
img.incremental {visibility: hidden;}
|
||||
.slide .current {color: lime;}
|
||||
|
||||
.slide-display {display: inline ! important;}
|
||||
|
||||
.huge {font-family: sans-serif; font-weight: bold; font-size: 150%;}
|
||||
.big {font-family: sans-serif; font-weight: bold; font-size: 120%;}
|
||||
.small {font-size: 75%;}
|
||||
.tiny {font-size: 50%;}
|
||||
.huge tt, .big tt, .small tt, .tiny tt {font-size: 115%;}
|
||||
.huge pre, .big pre, .small pre, .tiny pre {font-size: 115%;}
|
||||
|
||||
.maroon {color: maroon;}
|
||||
.red {color: red;}
|
||||
.magenta {color: magenta;}
|
||||
.fuchsia {color: fuchsia;}
|
||||
.pink {color: #FAA;}
|
||||
.orange {color: orange;}
|
||||
.yellow {color: yellow;}
|
||||
.lime {color: lime;}
|
||||
.green {color: green;}
|
||||
.olive {color: olive;}
|
||||
.teal {color: teal;}
|
||||
.cyan {color: cyan;}
|
||||
.aqua {color: aqua;}
|
||||
.blue {color: blue;}
|
||||
.navy {color: navy;}
|
||||
.purple {color: purple;}
|
||||
.black {color: black;}
|
||||
.gray {color: gray;}
|
||||
.silver {color: silver;}
|
||||
.white {color: white;}
|
||||
|
||||
.left {text-align: left ! important;}
|
||||
.center {text-align: center ! important;}
|
||||
.right {text-align: right ! important;}
|
||||
|
||||
.animation {position: relative; margin: 1em 0; padding: 0;}
|
||||
.animation img {position: absolute;}
|
||||
|
||||
/* Docutils-specific overrides */
|
||||
|
||||
.slide table.docinfo {margin: 0.5em 0 0.5em 1em;}
|
||||
|
||||
div.sidebar {background-color: black;}
|
||||
|
||||
pre.literal-block, pre.doctest-block {background-color: black;}
|
||||
|
||||
tt.docutils {background-color: black;}
|
||||
|
||||
/* diagnostics */
|
||||
/*
|
||||
li:after {content: " [" attr(class) "]"; color: #F88;}
|
||||
div:before {content: "[" attr(class) "]"; color: #F88;}
|
||||
*/
|
|
@ -0,0 +1,24 @@
|
|||
/* This file has been placed in the public domain. */
|
||||
/* The following styles size, place, and layer the slide components.
|
||||
Edit these if you want to change the overall slide layout.
|
||||
The commented lines can be uncommented (and modified, if necessary)
|
||||
to help you with the rearrangement process. */
|
||||
|
||||
/* target = 1024x768 */
|
||||
|
||||
div#header, div#footer, .slide {width: 100%; top: 0; left: 0;}
|
||||
div#footer {top: auto; bottom: 0; height: 2.5em; z-index: 5;}
|
||||
.slide {top: 0; width: 92%; padding: 0.75em 4% 0 4%; z-index: 2;}
|
||||
div#controls {left: 50%; bottom: 0; width: 50%; z-index: 100;}
|
||||
div#controls form {position: absolute; bottom: 0; right: 0; width: 100%;
|
||||
margin: 0;}
|
||||
#currentSlide {position: absolute; width: 10%; left: 45%; bottom: 1em;
|
||||
z-index: 10;}
|
||||
html>body #currentSlide {position: fixed;}
|
||||
|
||||
/*
|
||||
div#header {background: #FCC;}
|
||||
div#footer {background: #CCF;}
|
||||
div#controls {background: #BBD;}
|
||||
div#currentSlide {background: #FFC;}
|
||||
*/
|
|
@ -0,0 +1,113 @@
|
|||
/* This file has been placed in the public domain. */
|
||||
/* Following are the presentation styles -- edit away! */
|
||||
|
||||
html, body {margin: 0; padding: 0;}
|
||||
body {background: white; color: black;}
|
||||
:link, :visited {text-decoration: none; color: #00C;}
|
||||
#controls :active {color: #888 !important;}
|
||||
#controls :focus {outline: 1px dotted #222;}
|
||||
h1, h2, h3, h4 {font-size: 100%; margin: 0; padding: 0; font-weight: inherit;}
|
||||
|
||||
blockquote {padding: 0 2em 0.5em; margin: 0 1.5em 0.5em;}
|
||||
blockquote p {margin: 0;}
|
||||
|
||||
kbd {font-weight: bold; font-size: 1em;}
|
||||
sup {font-size: smaller; line-height: 1px;}
|
||||
|
||||
.slide pre {padding: 0; margin-left: 0; margin-right: 0; font-size: 90%;}
|
||||
.slide ul ul li {list-style: square;}
|
||||
.slide img.leader {display: block; margin: 0 auto;}
|
||||
.slide tt {font-size: 90%;}
|
||||
|
||||
div#footer {font-family: sans-serif; color: #444;
|
||||
font-size: 0.5em; font-weight: bold; padding: 1em 0;}
|
||||
#footer h1 {display: block; padding: 0 1em;}
|
||||
#footer h2 {display: block; padding: 0.8em 1em 0;}
|
||||
|
||||
.slide {font-size: 1.75em;}
|
||||
.slide h1 {padding-top: 0; z-index: 1; margin: 0; font: bold 150% sans-serif;}
|
||||
.slide h2 {font: bold 125% sans-serif; padding-top: 0.5em;}
|
||||
.slide h3 {font: bold 110% sans-serif; padding-top: 0.5em;}
|
||||
h1 abbr {font-variant: small-caps;}
|
||||
|
||||
div#controls {position: absolute; left: 50%; bottom: 0;
|
||||
width: 50%; text-align: right; font: bold 0.9em sans-serif;}
|
||||
html>body div#controls {position: fixed; padding: 0 0 1em 0; top: auto;}
|
||||
div#controls form {position: absolute; bottom: 0; right: 0; width: 100%;
|
||||
margin: 0; padding: 0;}
|
||||
#controls #navLinks a {padding: 0; margin: 0 0.5em;
|
||||
border: none; color: #888; cursor: pointer;}
|
||||
#controls #navList {height: 1em;}
|
||||
#controls #navList #jumplist {position: absolute; bottom: 0; right: 0;
|
||||
background: #DDD; color: #222;}
|
||||
|
||||
#currentSlide {text-align: center; font-size: 0.5em; color: #444;
|
||||
font-family: sans-serif; font-weight: bold;}
|
||||
|
||||
#slide0 h1 {position: static; margin: 0 0 0.5em; padding-top: 1em; top: 0;
|
||||
font: bold 150% sans-serif; white-space: normal; background: transparent;}
|
||||
#slide0 h2 {font: bold italic 125% sans-serif; color: gray;}
|
||||
#slide0 h3 {margin-top: 1.5em; font: bold 110% sans-serif;}
|
||||
#slide0 h4 {margin-top: 0; font-size: 1em;}
|
||||
|
||||
ul.urls {list-style: none; display: inline; margin: 0;}
|
||||
.urls li {display: inline; margin: 0;}
|
||||
.external {border-bottom: 1px dotted gray;}
|
||||
html>body .external {border-bottom: none;}
|
||||
.external:after {content: " \274F"; font-size: smaller; color: #77B;}
|
||||
|
||||
.incremental, .incremental *, .incremental *:after {
|
||||
color: white; visibility: visible; border: 0;}
|
||||
img.incremental {visibility: hidden;}
|
||||
.slide .current {color: green;}
|
||||
|
||||
.slide-display {display: inline ! important;}
|
||||
|
||||
.huge {font-family: sans-serif; font-weight: bold; font-size: 150%;}
|
||||
.big {font-family: sans-serif; font-weight: bold; font-size: 120%;}
|
||||
.small {font-size: 75%;}
|
||||
.tiny {font-size: 50%;}
|
||||
.huge tt, .big tt, .small tt, .tiny tt {font-size: 115%;}
|
||||
.huge pre, .big pre, .small pre, .tiny pre {font-size: 115%;}
|
||||
|
||||
.maroon {color: maroon;}
|
||||
.red {color: red;}
|
||||
.magenta {color: magenta;}
|
||||
.fuchsia {color: fuchsia;}
|
||||
.pink {color: #FAA;}
|
||||
.orange {color: orange;}
|
||||
.yellow {color: yellow;}
|
||||
.lime {color: lime;}
|
||||
.green {color: green;}
|
||||
.olive {color: olive;}
|
||||
.teal {color: teal;}
|
||||
.cyan {color: cyan;}
|
||||
.aqua {color: aqua;}
|
||||
.blue {color: blue;}
|
||||
.navy {color: navy;}
|
||||
.purple {color: purple;}
|
||||
.black {color: black;}
|
||||
.gray {color: gray;}
|
||||
.silver {color: silver;}
|
||||
.white {color: white;}
|
||||
|
||||
.left {text-align: left ! important;}
|
||||
.center {text-align: center ! important;}
|
||||
.right {text-align: right ! important;}
|
||||
|
||||
.animation {position: relative; margin: 1em 0; padding: 0;}
|
||||
.animation img {position: absolute;}
|
||||
|
||||
/* Docutils-specific overrides */
|
||||
|
||||
.slide table.docinfo {margin: 0.5em 0 0.5em 1em;}
|
||||
|
||||
pre.literal-block, pre.doctest-block {background-color: white;}
|
||||
|
||||
tt.docutils {background-color: white;}
|
||||
|
||||
/* diagnostics */
|
||||
/*
|
||||
li:after {content: " [" attr(class) "]"; color: #F88;}
|
||||
div:before {content: "[" attr(class) "]"; color: #F88;}
|
||||
*/
|
|
@ -0,0 +1,2 @@
|
|||
# base theme of this theme:
|
||||
small-white
|
|
@ -0,0 +1,116 @@
|
|||
/* This file has been placed in the public domain. */
|
||||
/* Following are the presentation styles -- edit away! */
|
||||
|
||||
html, body {margin: 0; padding: 0;}
|
||||
body {background: black; color: white;}
|
||||
:link, :visited {text-decoration: none; color: cyan;}
|
||||
#controls :active {color: #888 !important;}
|
||||
#controls :focus {outline: 1px dotted #CCC;}
|
||||
h1, h2, h3, h4 {font-size: 100%; margin: 0; padding: 0; font-weight: inherit;}
|
||||
|
||||
blockquote {padding: 0 2em 0.5em; margin: 0 1.5em 0.5em;}
|
||||
blockquote p {margin: 0;}
|
||||
|
||||
kbd {font-weight: bold; font-size: 1em;}
|
||||
sup {font-size: smaller; line-height: 1px;}
|
||||
|
||||
.slide pre {padding: 0; margin-left: 0; margin-right: 0; font-size: 90%;}
|
||||
.slide ul ul li {list-style: square;}
|
||||
.slide img.leader {display: block; margin: 0 auto;}
|
||||
.slide tt {font-size: 90%;}
|
||||
|
||||
div#footer {font-family: sans-serif; color: #AAA;
|
||||
font-size: 0.5em; font-weight: bold; padding: 1em 0;}
|
||||
#footer h1 {display: block; padding: 0 1em;}
|
||||
#footer h2 {display: block; padding: 0.8em 1em 0;}
|
||||
|
||||
.slide {font-size: 1.2em;}
|
||||
.slide h1 {padding-top: 0; z-index: 1; margin: 0; font: bold 150% sans-serif;}
|
||||
.slide h2 {font: bold 120% sans-serif; padding-top: 0.5em;}
|
||||
.slide h3 {font: bold 100% sans-serif; padding-top: 0.5em;}
|
||||
h1 abbr {font-variant: small-caps;}
|
||||
|
||||
div#controls {position: absolute; left: 50%; bottom: 0;
|
||||
width: 50%; text-align: right; font: bold 0.9em sans-serif;}
|
||||
html>body div#controls {position: fixed; padding: 0 0 1em 0; top: auto;}
|
||||
div#controls form {position: absolute; bottom: 0; right: 0; width: 100%;
|
||||
margin: 0; padding: 0;}
|
||||
#controls #navLinks a {padding: 0; margin: 0 0.5em;
|
||||
border: none; color: #888; cursor: pointer;}
|
||||
#controls #navList {height: 1em;}
|
||||
#controls #navList #jumplist {position: absolute; bottom: 0; right: 0;
|
||||
background: black; color: #CCC;}
|
||||
|
||||
#currentSlide {text-align: center; font-size: 0.5em; color: #AAA;
|
||||
font-family: sans-serif; font-weight: bold;}
|
||||
|
||||
#slide0 {padding-top: 0em}
|
||||
#slide0 h1 {position: static; margin: 1em 0 0; padding: 0;
|
||||
font: bold 2em sans-serif; white-space: normal; background: transparent;}
|
||||
#slide0 h2 {font: bold italic 1em sans-serif; margin: 0.25em;}
|
||||
#slide0 h3 {margin-top: 1.5em; font-size: 1.5em;}
|
||||
#slide0 h4 {margin-top: 0; font-size: 1em;}
|
||||
|
||||
ul.urls {list-style: none; display: inline; margin: 0;}
|
||||
.urls li {display: inline; margin: 0;}
|
||||
.external {border-bottom: 1px dotted gray;}
|
||||
html>body .external {border-bottom: none;}
|
||||
.external:after {content: " \274F"; font-size: smaller; color: #FCC;}
|
||||
|
||||
.incremental, .incremental *, .incremental *:after {
|
||||
color: black; visibility: visible; border: 0;}
|
||||
img.incremental {visibility: hidden;}
|
||||
.slide .current {color: lime;}
|
||||
|
||||
.slide-display {display: inline ! important;}
|
||||
|
||||
.huge {font-family: sans-serif; font-weight: bold; font-size: 150%;}
|
||||
.big {font-family: sans-serif; font-weight: bold; font-size: 120%;}
|
||||
.small {font-size: 75%;}
|
||||
.tiny {font-size: 50%;}
|
||||
.huge tt, .big tt, .small tt, .tiny tt {font-size: 115%;}
|
||||
.huge pre, .big pre, .small pre, .tiny pre {font-size: 115%;}
|
||||
|
||||
.maroon {color: maroon;}
|
||||
.red {color: red;}
|
||||
.magenta {color: magenta;}
|
||||
.fuchsia {color: fuchsia;}
|
||||
.pink {color: #FAA;}
|
||||
.orange {color: orange;}
|
||||
.yellow {color: yellow;}
|
||||
.lime {color: lime;}
|
||||
.green {color: green;}
|
||||
.olive {color: olive;}
|
||||
.teal {color: teal;}
|
||||
.cyan {color: cyan;}
|
||||
.aqua {color: aqua;}
|
||||
.blue {color: blue;}
|
||||
.navy {color: navy;}
|
||||
.purple {color: purple;}
|
||||
.black {color: black;}
|
||||
.gray {color: gray;}
|
||||
.silver {color: silver;}
|
||||
.white {color: white;}
|
||||
|
||||
.left {text-align: left ! important;}
|
||||
.center {text-align: center ! important;}
|
||||
.right {text-align: right ! important;}
|
||||
|
||||
.animation {position: relative; margin: 1em 0; padding: 0;}
|
||||
.animation img {position: absolute;}
|
||||
|
||||
/* Docutils-specific overrides */
|
||||
|
||||
.slide table.docinfo {margin: 1em 0 0.5em 2em;}
|
||||
|
||||
div.sidebar {background-color: black;}
|
||||
|
||||
pre.literal-block, pre.doctest-block {background-color: black;}
|
||||
|
||||
tt.docutils {background-color: black;}
|
||||
|
||||
/* diagnostics */
|
||||
/*
|
||||
li:after {content: " [" attr(class) "]"; color: #F88;}
|
||||
div:before {content: "[" attr(class) "]"; color: #F88;}
|
||||
*/
|
|
@ -0,0 +1,24 @@
|
|||
/* This file has been placed in the public domain. */
|
||||
/* The following styles size, place, and layer the slide components.
|
||||
Edit these if you want to change the overall slide layout.
|
||||
The commented lines can be uncommented (and modified, if necessary)
|
||||
to help you with the rearrangement process. */
|
||||
|
||||
/* target = 1024x768 */
|
||||
|
||||
div#header, div#footer, .slide {width: 100%; top: 0; left: 0;}
|
||||
div#footer {top: auto; bottom: 0; height: 2.5em; z-index: 5;}
|
||||
.slide {top: 0; width: 92%; padding: 1em 4% 0 4%; z-index: 2;}
|
||||
div#controls {left: 50%; bottom: 0; width: 50%; z-index: 100;}
|
||||
div#controls form {position: absolute; bottom: 0; right: 0; width: 100%;
|
||||
margin: 0;}
|
||||
#currentSlide {position: absolute; width: 10%; left: 45%; bottom: 1em;
|
||||
z-index: 10;}
|
||||
html>body #currentSlide {position: fixed;}
|
||||
|
||||
/*
|
||||
div#header {background: #FCC;}
|
||||
div#footer {background: #CCF;}
|
||||
div#controls {background: #BBD;}
|
||||
div#currentSlide {background: #FFC;}
|
||||
*/
|
|
@ -0,0 +1,114 @@
|
|||
/* This file has been placed in the public domain. */
|
||||
/* Following are the presentation styles -- edit away! */
|
||||
|
||||
html, body {margin: 0; padding: 0;}
|
||||
body {background: white; color: black;}
|
||||
:link, :visited {text-decoration: none; color: #00C;}
|
||||
#controls :active {color: #888 !important;}
|
||||
#controls :focus {outline: 1px dotted #222;}
|
||||
h1, h2, h3, h4 {font-size: 100%; margin: 0; padding: 0; font-weight: inherit;}
|
||||
|
||||
blockquote {padding: 0 2em 0.5em; margin: 0 1.5em 0.5em;}
|
||||
blockquote p {margin: 0;}
|
||||
|
||||
kbd {font-weight: bold; font-size: 1em;}
|
||||
sup {font-size: smaller; line-height: 1px;}
|
||||
|
||||
.slide pre {padding: 0; margin-left: 0; margin-right: 0; font-size: 90%;}
|
||||
.slide ul ul li {list-style: square;}
|
||||
.slide img.leader {display: block; margin: 0 auto;}
|
||||
.slide tt {font-size: 90%;}
|
||||
|
||||
div#footer {font-family: sans-serif; color: #444;
|
||||
font-size: 0.5em; font-weight: bold; padding: 1em 0;}
|
||||
#footer h1 {display: block; padding: 0 1em;}
|
||||
#footer h2 {display: block; padding: 0.8em 1em 0;}
|
||||
|
||||
.slide {font-size: 1.2em;}
|
||||
.slide h1 {padding-top: 0; z-index: 1; margin: 0; font: bold 150% sans-serif;}
|
||||
.slide h2 {font: bold 120% sans-serif; padding-top: 0.5em;}
|
||||
.slide h3 {font: bold 100% sans-serif; padding-top: 0.5em;}
|
||||
h1 abbr {font-variant: small-caps;}
|
||||
|
||||
div#controls {position: absolute; left: 50%; bottom: 0;
|
||||
width: 50%; text-align: right; font: bold 0.9em sans-serif;}
|
||||
html>body div#controls {position: fixed; padding: 0 0 1em 0; top: auto;}
|
||||
div#controls form {position: absolute; bottom: 0; right: 0; width: 100%;
|
||||
margin: 0; padding: 0;}
|
||||
#controls #navLinks a {padding: 0; margin: 0 0.5em;
|
||||
border: none; color: #888; cursor: pointer;}
|
||||
#controls #navList {height: 1em;}
|
||||
#controls #navList #jumplist {position: absolute; bottom: 0; right: 0;
|
||||
background: #DDD; color: #222;}
|
||||
|
||||
#currentSlide {text-align: center; font-size: 0.5em; color: #444;
|
||||
font-family: sans-serif; font-weight: bold;}
|
||||
|
||||
#slide0 {padding-top: 0em}
|
||||
#slide0 h1 {position: static; margin: 1em 0 0; padding: 0;
|
||||
font: bold 2em sans-serif; white-space: normal; background: transparent;}
|
||||
#slide0 h2 {font: bold italic 1em sans-serif; margin: 0.25em;}
|
||||
#slide0 h3 {margin-top: 1.5em; font-size: 1.5em;}
|
||||
#slide0 h4 {margin-top: 0; font-size: 1em;}
|
||||
|
||||
ul.urls {list-style: none; display: inline; margin: 0;}
|
||||
.urls li {display: inline; margin: 0;}
|
||||
.external {border-bottom: 1px dotted gray;}
|
||||
html>body .external {border-bottom: none;}
|
||||
.external:after {content: " \274F"; font-size: smaller; color: #77B;}
|
||||
|
||||
.incremental, .incremental *, .incremental *:after {
|
||||
color: white; visibility: visible; border: 0; border: 0;}
|
||||
img.incremental {visibility: hidden;}
|
||||
.slide .current {color: green;}
|
||||
|
||||
.slide-display {display: inline ! important;}
|
||||
|
||||
.huge {font-family: sans-serif; font-weight: bold; font-size: 150%;}
|
||||
.big {font-family: sans-serif; font-weight: bold; font-size: 120%;}
|
||||
.small {font-size: 75%;}
|
||||
.tiny {font-size: 50%;}
|
||||
.huge tt, .big tt, .small tt, .tiny tt {font-size: 115%;}
|
||||
.huge pre, .big pre, .small pre, .tiny pre {font-size: 115%;}
|
||||
|
||||
.maroon {color: maroon;}
|
||||
.red {color: red;}
|
||||
.magenta {color: magenta;}
|
||||
.fuchsia {color: fuchsia;}
|
||||
.pink {color: #FAA;}
|
||||
.orange {color: orange;}
|
||||
.yellow {color: yellow;}
|
||||
.lime {color: lime;}
|
||||
.green {color: green;}
|
||||
.olive {color: olive;}
|
||||
.teal {color: teal;}
|
||||
.cyan {color: cyan;}
|
||||
.aqua {color: aqua;}
|
||||
.blue {color: blue;}
|
||||
.navy {color: navy;}
|
||||
.purple {color: purple;}
|
||||
.black {color: black;}
|
||||
.gray {color: gray;}
|
||||
.silver {color: silver;}
|
||||
.white {color: white;}
|
||||
|
||||
.left {text-align: left ! important;}
|
||||
.center {text-align: center ! important;}
|
||||
.right {text-align: right ! important;}
|
||||
|
||||
.animation {position: relative; margin: 1em 0; padding: 0;}
|
||||
.animation img {position: absolute;}
|
||||
|
||||
/* Docutils-specific overrides */
|
||||
|
||||
.slide table.docinfo {margin: 1em 0 0.5em 2em;}
|
||||
|
||||
pre.literal-block, pre.doctest-block {background-color: white;}
|
||||
|
||||
tt.docutils {background-color: white;}
|
||||
|
||||
/* diagnostics */
|
||||
/*
|
||||
li:after {content: " [" attr(class) "]"; color: #F88;}
|
||||
div:before {content: "[" attr(class) "]"; color: #F88;}
|
||||
*/
|
|
@ -0,0 +1,147 @@
|
|||
#!/usr/bin/env python3
|
||||
# :Author: Günter Milde <milde@users.sf.net>
|
||||
# :Revision: $Revision: 9293 $
|
||||
# :Date: $Date: 2022-12-01 22:13:54 +0100 (Do, 01. Dez 2022) $
|
||||
# :Copyright: © 2010 Günter Milde.
|
||||
# :License: Released under the terms of the `2-Clause BSD license`_, in short:
|
||||
#
|
||||
# Copying and distribution of this file, with or without modification,
|
||||
# are permitted in any medium without royalty provided the copyright
|
||||
# notice and this notice are preserved.
|
||||
# This file is offered as-is, without any warranty.
|
||||
#
|
||||
# .. _2-Clause BSD license: https://opensource.org/licenses/BSD-2-Clause
|
||||
|
||||
"""
|
||||
XeLaTeX document tree Writer.
|
||||
|
||||
A variant of Docutils' standard 'latex2e' writer producing LaTeX output
|
||||
suited for processing with the Unicode-aware TeX engines
|
||||
LuaTeX and XeTeX.
|
||||
"""
|
||||
|
||||
__docformat__ = 'reStructuredText'
|
||||
|
||||
from docutils import frontend
|
||||
from docutils.writers import latex2e
|
||||
|
||||
|
||||
class Writer(latex2e.Writer):
|
||||
"""A writer for Unicode-aware LaTeX variants (XeTeX, LuaTeX)"""
|
||||
|
||||
supported = ('latex', 'tex', 'xetex', 'xelatex', 'luatex', 'lualatex')
|
||||
"""Formats this writer supports."""
|
||||
|
||||
default_template = 'xelatex.tex'
|
||||
default_preamble = """\
|
||||
% Linux Libertine (free, wide coverage, not only for Linux)
|
||||
\\setmainfont{Linux Libertine O}
|
||||
\\setsansfont{Linux Biolinum O}
|
||||
\\setmonofont[HyphenChar=None,Scale=MatchLowercase]{DejaVu Sans Mono}"""
|
||||
|
||||
config_section = 'xetex writer'
|
||||
config_section_dependencies = ('writers', 'latex writers')
|
||||
|
||||
# use a copy of the parent spec with some modifications:
|
||||
settings_spec = frontend.filter_settings_spec(
|
||||
latex2e.Writer.settings_spec,
|
||||
# removed settings
|
||||
'font_encoding',
|
||||
# changed settings:
|
||||
template=('Template file. Default: "%s".' % default_template,
|
||||
['--template'],
|
||||
{'default': default_template, 'metavar': '<file>'}),
|
||||
latex_preamble=('Customization by LaTeX code in the preamble. '
|
||||
'Default: select "Linux Libertine" fonts.',
|
||||
['--latex-preamble'],
|
||||
{'default': default_preamble}),
|
||||
)
|
||||
|
||||
def __init__(self):
|
||||
latex2e.Writer.__init__(self)
|
||||
self.settings_defaults.update({'fontencoding': ''}) # use default (TU)
|
||||
self.translator_class = XeLaTeXTranslator
|
||||
|
||||
|
||||
class Babel(latex2e.Babel):
|
||||
"""Language specifics for XeTeX.
|
||||
|
||||
Use `polyglossia` instead of `babel` and adapt settings.
|
||||
"""
|
||||
language_codes = latex2e.Babel.language_codes.copy()
|
||||
# Additionally supported or differently named languages:
|
||||
language_codes.update({
|
||||
# code Polyglossia-name comment
|
||||
'cop': 'coptic',
|
||||
'de': 'german', # new spelling (de_1996)
|
||||
'de-1901': 'ogerman', # old spelling
|
||||
'dv': 'divehi', # Maldivian
|
||||
'dsb': 'lsorbian',
|
||||
'el-polyton': 'polygreek',
|
||||
'fa': 'farsi',
|
||||
'grc': 'ancientgreek',
|
||||
'ko': 'korean',
|
||||
'hsb': 'usorbian',
|
||||
'sh-Cyrl': 'serbian', # Serbo-Croatian, Cyrillic script
|
||||
'sh-Latn': 'croatian', # Serbo-Croatian, Latin script
|
||||
'sq': 'albanian',
|
||||
'sr': 'serbian', # Cyrillic script (sr-Cyrl)
|
||||
'th': 'thai',
|
||||
'vi': 'vietnamese',
|
||||
# zh-Latn: ??? # Chinese Pinyin
|
||||
})
|
||||
# normalize (downcase) keys
|
||||
language_codes = {k.lower(): v for k, v in language_codes.items()}
|
||||
|
||||
# Languages without Polyglossia support:
|
||||
for key in ('af', # 'afrikaans',
|
||||
'de-AT', # 'naustrian',
|
||||
'de-AT-1901', # 'austrian',
|
||||
# TODO: use variant=... for English variants
|
||||
'en-CA', # 'canadian',
|
||||
'en-GB', # 'british',
|
||||
'en-NZ', # 'newzealand',
|
||||
'en-US', # 'american',
|
||||
'fr-CA', # 'canadien',
|
||||
'grc-ibycus', # 'ibycus', (Greek Ibycus encoding)
|
||||
'sr-Latn', # 'serbian script=latin'
|
||||
):
|
||||
del language_codes[key.lower()]
|
||||
|
||||
def __init__(self, language_code, reporter):
|
||||
self.language_code = language_code
|
||||
self.reporter = reporter
|
||||
self.language = self.language_name(language_code)
|
||||
self.otherlanguages = {}
|
||||
self.warn_msg = 'Language "%s" not supported by Polyglossia.'
|
||||
self.quote_index = 0
|
||||
self.quotes = ('"', '"')
|
||||
# language dependent configuration:
|
||||
# double quotes are "active" in some languages (e.g. German).
|
||||
self.literal_double_quote = '"' # TODO: use \textquotedbl ?
|
||||
|
||||
def __call__(self):
|
||||
setup = [r'\usepackage{polyglossia}',
|
||||
r'\setdefaultlanguage{%s}' % self.language]
|
||||
if self.otherlanguages:
|
||||
setup.append(r'\setotherlanguages{%s}' %
|
||||
','.join(sorted(self.otherlanguages.keys())))
|
||||
return '\n'.join(setup)
|
||||
|
||||
|
||||
class XeLaTeXTranslator(latex2e.LaTeXTranslator):
|
||||
"""
|
||||
Generate code for LaTeX using Unicode fonts (XeLaTex or LuaLaTeX).
|
||||
|
||||
See the docstring of docutils.writers._html_base.HTMLTranslator for
|
||||
notes on and examples of safe subclassing.
|
||||
"""
|
||||
|
||||
def __init__(self, document):
|
||||
self.is_xetex = True # typeset with XeTeX or LuaTeX engine
|
||||
latex2e.LaTeXTranslator.__init__(self, document, Babel)
|
||||
if self.latex_encoding == 'utf8':
|
||||
self.requirements.pop('_inputenc', None)
|
||||
else:
|
||||
self.requirements['_inputenc'] = (r'\XeTeXinputencoding %s '
|
||||
% self.latex_encoding)
|
Binary file not shown.
Loading…
Add table
Add a link
Reference in a new issue