diff options
Diffstat (limited to 'docs/howto')
-rw-r--r-- | docs/howto/html-stylesheets.txt | 76 | ||||
-rw-r--r-- | docs/howto/i18n.txt | 191 | ||||
-rw-r--r-- | docs/howto/rst-directives.txt | 399 | ||||
-rw-r--r-- | docs/howto/rst-roles.txt | 228 |
4 files changed, 894 insertions, 0 deletions
diff --git a/docs/howto/html-stylesheets.txt b/docs/howto/html-stylesheets.txt new file mode 100644 index 000000000..9369f2d3c --- /dev/null +++ b/docs/howto/html-stylesheets.txt @@ -0,0 +1,76 @@ +============================================== + Writing HTML (CSS) Stylesheets for Docutils_ +============================================== + +:Author: Felix Wiemann +:Contact: Felix.Wiemann@ososo.de +:Date: $Date$ +:Revision: $Revision$ +:Copyright: This document has been placed in the public domain. + +.. _Docutils: http://docutils.sourceforge.net/ + + +The look of Docutils' HTML output is customizable via a CSS +stylesheet. The default stylesheet is called ``html4css1.css`` and +can be found in the ``writers/html4css1/`` directory of the Docutils +installation. Use the command ``rst2html.py --help`` and look at the +description of the ``--stylesheet-path`` command-line option for the +exact machine-specific location. + +To customize the stylesheet, first copy ``html4css1.css`` to the same +place as your output HTML files will go. Next, place a new file +(e.g. called ``my-docutils.css``) in the same directory and use the +following template:: + + /* + :Author: Your Name + :Contact: Your Email Address + :Copyright: This stylesheet has been placed in the public domain. + + Stylesheet for use with Docutils. [Optionally place a more + detailed description here.] + */ + + @import url(html4css1.css); + + /* Your customizations go here. For example: */ + + h1, h2, h3, h4, h5, h6, p.topic-title { + font-family: sans-serif } + +For help on the CSS syntax, please see `the WDG's guide to Cascading +Style Sheets`__ and, in particular, their `list of CSS1 properties`__. + +__ http://www.htmlhelp.com/reference/css/ +__ http://www.htmlhelp.com/reference/css/all-properties.html + +It is important that you do not edit a copy of ``html4css1.css`` +directly because ``html4css1.css`` is frequently updated with each new +release of Docutils. + +Also make sure that you import ``html4css1.css`` (using "``@import +url(html4css1.css);``") because the definitions contained in the +default stylesheet are required for correct rendering (margins, +alignment, etc.). + +If you think your stylesheet is fancy and you would like to let others +benefit from your efforts, you are encouraged to post the stylesheet +to the Docutils-users_ mailing list. We can upload it to the +`Docutils repository`__ if you would like us to do so. + +If you decide to share you stylesheet with other users of Docutils, +please keep website-specific customizations not applicable to +Docutils' HTML code in a separate stylesheet. + +.. _Docutils-users: ../user/mailing-lists.html#docutils-users +__ http://docutils.sourceforge.net/sandbox/stylesheets/ + + +.. + Local Variables: + mode: indented-text + indent-tabs-mode: nil + sentence-end-double-space: t + fill-column: 70 + End: diff --git a/docs/howto/i18n.txt b/docs/howto/i18n.txt new file mode 100644 index 000000000..4a5b1de5a --- /dev/null +++ b/docs/howto/i18n.txt @@ -0,0 +1,191 @@ +================================ + Docutils_ Internationalization +================================ + +:Author: David Goodger +:Contact: goodger@users.sourceforge.net +:Date: $Date$ +:Revision: $Revision$ +:Copyright: This document has been placed in the public domain. + + +.. contents:: + + +This document describes the internationalization facilities of the +Docutils_ project. `Introduction to i18n`_ by Tomohiro KUBOTA is a +good general reference. "Internationalization" is often abbreviated +as "i18n": "i" + 18 letters + "n". + +.. Note:: + + The i18n facilities of Docutils should be considered a "first + draft". They work so far, but improvements are welcome. + Specifically, standard i18n facilities like "gettext" have yet to + be explored. + +Docutils is designed to work flexibly with text in multiple languages +(one language at a time). Language-specific features are (or should +be [#]_) fully parameterized. To enable a new language, two modules +have to be added to the project: one for Docutils itself (the +`Docutils Language Module`_) and one for the reStructuredText parser +(the `reStructuredText Language Module`_). + +.. [#] If anything in Docutils is insufficiently parameterized, it + should be considered a bug. Please report bugs to the Docutils + project bug tracker on SourceForge at + http://sourceforge.net/tracker/?group_id=38414&atid=422030. + +.. _Docutils: http://docutils.sourceforge.net/ +.. _Introduction to i18n: + http://www.debian.org/doc/manuals/intro-i18n/ + + +Language Module Names +===================== + +Language modules are named using a case-insensitive language +identifier as defined in `RFC 1766`_, converting hyphens to +underscores [#]_. A typical language identifier consists of a +2-letter language code from `ISO 639`_ (3-letter codes can be used if +no 2-letter code exists; RFC 1766 is currently being revised to allow +3-letter codes). The language identifier can have an optional subtag, +typically for variations based on country (from `ISO 3166`_ 2-letter +country codes). If no language identifier is specified, the default +is "en" for English. Examples of module names include ``en.py``, +``fr.py``, ``ja.py``, and ``pt_br.py``. + +.. [#] Subtags are separated from primary tags by underscores instead + of hyphens, to conform to Python naming rules. + +.. _RFC 1766: http://www.faqs.org/rfcs/rfc1766.html +.. _ISO 639: http://www.loc.gov/standards/iso639-2/englangn.html +.. _ISO 3166: http://www.iso.ch/iso/en/prods-services/iso3166ma/ + 02iso-3166-code-lists/index.html + + +Python Code +=========== + +All Python code in Docutils will be ASCII-only. In language modules, +Unicode-escapes will have to be used for non-ASCII characters. +Although it may be possible for some developers to store non-ASCII +characters directly in strings, it will cause problems for other +developers whose locales are set up differently. + +`PEP 263`_ introduces source code encodings to Python modules, +implemented beginning in Python 2.3. Until PEP 263 is fully +implemented as a well-established convention, proven robust in daily +use, and the tools (editors, CVS, email, etc.) recognize this +convention, Docutils shall remain conservative. + +As mentioned in the note above, developers are invited to explore +"gettext" and other i18n technologies. + +.. _PEP 263: http://www.python.org/peps/pep-0263.html + + +Docutils Language Module +======================== + +Modules in ``docutils/languages`` contain language mappings for +markup-independent language-specific features of Docutils. To make a +new language module, just copy the ``en.py`` file, rename it with the +code for your language (see `Language Module Names`_ above), and +translate the terms as described below. + +Each Docutils language module contains three module attributes: + +``labels`` + This is a mapping of node class names to language-dependent + boilerplate label text. The label text is used by Writer + components when they encounter document tree elements whose class + names are the mapping keys. + + The entry values (*not* the keys) should be translated to the + target language. + +``bibliographic_fields`` + This is a mapping of language-dependent field names (converted to + lower case) to canonical field names (keys of + ``DocInfo.biblio_notes`` in ``docutils.transforms.frontmatter``). + It is used when transforming bibliographic fields. + + The keys should be translated to the target language. + +``author_separators`` + This is a list of strings used to parse the 'Authors' + bibliographic field. They separate individual authors' names, and + are tried in order (i.e., earlier items take priority, and the + first item that matches wins). The English-language module + defines them as ``[';', ',']``; semi-colons can be used to + separate names like "Arthur Pewtie, Esq.". + + Most languages won't have to "translate" this list. + + +reStructuredText Language Module +================================ + +Modules in ``docutils/parsers/rst/languages`` contain language +mappings for language-specific features of the reStructuredText +parser. To make a new language module, just copy the ``en.py`` file, +rename it with the code for your language (see `Language Module +Names`_ above), and translate the terms as described below. + +Each reStructuredText language module contains two module attributes: + +``directives`` + This is a mapping from language-dependent directive names to + canonical directive names. The canonical directive names are + registered in ``docutils/parsers/rst/directives/__init__.py``, in + ``_directive_registry``. + + The keys should be translated to the target language. Synonyms + (multiple keys with the same values) are allowed; this is useful + for abbreviations. + +``roles`` + This is a mapping language-dependent role names to canonical role + names for interpreted text. The canonical directive names are + registered in ``docutils/parsers/rst/states.py``, in + ``Inliner._interpreted_roles`` (this may change). + + The keys should be translated to the target language. Synonyms + (multiple keys with the same values) are allowed; this is useful + for abbreviations. + + +Testing the Language Modules +============================ + +Whenever a new language module is added or an existing one modified, +the unit tests should be run. The test modules can be found in the +docutils/test directory from CVS_ or from the `latest CVS snapshot`_. + +The ``test_language.py`` module can be run as a script. With no +arguments, it will test all language modules. With one or more +language codes, it will test just those languages. For example:: + + $ python test_language.py en + .. + ---------------------------------------- + Ran 2 tests in 0.095s + + OK + +Use the "alltests.py" script to run all test modules, exhaustively +testing the parser and other parts of the Docutils system. + +.. _CVS: http://sourceforge.net/cvs/?group_id=38414 +.. _latest CVS snapshot: http://docutils.sf.net/docutils-snapshot.tgz + + +Submitting the Language Modules +=============================== + +If you do not have CVS write access and want to contribute your +language modules, feel free to submit them at the `SourceForge patch +tracker`__. + +__ http://sourceforge.net/tracker/?group_id=38414&atid=422032 diff --git a/docs/howto/rst-directives.txt b/docs/howto/rst-directives.txt new file mode 100644 index 000000000..6210940c8 --- /dev/null +++ b/docs/howto/rst-directives.txt @@ -0,0 +1,399 @@ +====================================== + Creating reStructuredText Directives +====================================== + +:Authors: Dethe Elza, David Goodger +:Contact: delza@enfoldingsystems.com +:Date: $Date$ +:Revision: $Revision$ +:Copyright: This document has been placed in the public domain. + +Directives are the primary extension mechanism of reStructuredText. +This document aims to make the creation of new directives as easy and +understandable as possible. There are only a couple of +reStructuredText-specific features the developer needs to know to +create a basic directive. + +The syntax of directives is detailed in the `reStructuredText Markup +Specification`_, and standard directives are described in +`reStructuredText Directives`_. + +Directives are a reStructuredText markup/parser concept. There is no +"directive" element, no single element that corresponds exactly to the +concept of directives. Instead, choose the most appropriate elements +from the existing Docutils elements. Directives build structures +using the existing building blocks. See `The Docutils Document Tree`_ +and the ``docutils.nodes`` module for more about the building blocks +of Docutils documents. + +.. _reStructuredText Markup Specification: + ../ref/rst/restructuredtext.html#directives +.. _reStructuredText Directives: ../ref/rst/directives.html +.. _The Docutils Document Tree: ../ref/doctree.html + + +.. contents:: Table of Contents + + +Define the Directive Function +============================= + +The directive function does any processing that the directive +requires. This may require the use of other parts of the +reStructuredText parser. This is where the directive actually *does* +something. + +The directive implementation itself is a callback function whose +signature is as follows:: + + def directive_fn(name, arguments, options, content, lineno, + content_offset, block_text, state, state_machine): + code... + + # Set function attributes: + directive_fn.arguments = ... + directive_fn.options = ... + direcitve_fn.content = ... + +Function attributes are described below (see `Specify Directive +Arguments, Options, and Content`_). The directive function parameters +are as follows: + +- ``name`` is the directive type or name. + +- ``arguments`` is a list of positional arguments, as specified in the + ``arguments`` function attribute. + +- ``options`` is a dictionary mapping option names to values. The + options handled by a directive function are specified in the + ``options`` function attribute. + +- ``content`` is a list of strings, the directive content. Use the + ``content`` function attribute to allow directive content. + +- ``lineno`` is the line number of the first line of the directive. + +- ``content_offset`` is the line offset of the first line of the + content from the beginning of the current input. Used when + initiating a nested parse. + +- ``block_text`` is a string containing the entire directive. Include + it as the content of a literal block in a system message if there is + a problem. + +- ``state`` is the state which called the directive function. + +- ``state_machine`` is the state machine which controls the state + which called the directive function. + +Directive functions return a list of nodes which will be inserted into +the document tree at the point where the directive was encountered. +This can be an empty list if there is nothing to insert. For ordinary +directives, the list must contain body elements or structural +elements. Some directives are intended specifically for substitution +definitions, and must return a list of ``Text`` nodes and/or inline +elements (suitable for inline insertion, in place of the substitution +reference). Such directives must verify substitution definition +context, typically using code like this:: + + if not isinstance(state, states.SubstitutionDef): + error = state_machine.reporter.error( + 'Invalid context: the "%s" directive can only be used ' + 'within a substitution definition.' % (name), + nodes.literal_block(block_text, block_text), line=lineno) + return [error] + + +Specify Directive Arguments, Options, and Content +================================================= + +Function attributes are interpreted by the directive parser (from the +``docutils.parsers.rst.states.Body.run_directive()`` method). If +unspecified, directive function attributes are assumed to have the +value ``None``. Three directive function attributes are recognized: + +- ``arguments``: A 3-tuple specifying the expected positional + arguments, or ``None`` if the directive has no arguments. The 3 + items in the tuple are: + + 1. The number of required arguments. + 2. The number of optional arguments. + 3. A boolean, indicating if the final argument may contain whitespace. + + Arguments are normally single whitespace-separated words. The final + argument may contain whitespace when indicated by the value 1 (True) + for the third item in the argument spec tuple. In this case, the + final argument in the ``arguments`` parameter to the directive + function will contain spaces and/or newlines, preserved from the + input text. + + If the form of the arguments is more complex, specify only one + argument (either required or optional) and indicate that final + whitespace is OK (1/True); the client code must do any + context-sensitive parsing. + +- ``options``: The option specification. ``None`` or an empty dict + implies no options to parse. + + An option specification must be defined detailing the options + available to the directive. An option spec is a mapping of option + name to conversion function; conversion functions are applied to + each option value to check validity and convert them to the expected + type. Python's built-in conversion functions are often usable for + this, such as ``int``, ``float``, and ``bool`` (included in Python + from version 2.2.1). Other useful conversion functions are included + in the ``docutils.parsers.rst.directives`` package (in the + ``__init__.py`` module): + + - ``flag``: For options with no option arguments. Checks for an + argument (raises ``ValueError`` if found), returns ``None`` for + valid flag options. + + - ``unchanged_required``: Returns the text argument, unchanged. + Raises ``ValueError`` if no argument is found. + + - ``unchanged``: Returns the text argument, unchanged. Returns an + empty string ("") if no argument is found. + + - ``path``: Returns the path argument unwrapped (with newlines + removed). Raises ``ValueError`` if no argument is found. + + - ``uri``: Returns the URI argument with whitespace removed. Raises + ``ValueError`` if no argument is found. + + - ``nonnegative_int``: Checks for a nonnegative integer argument, + and raises ``ValueError`` if not. + + - ``class_option``: Converts the argument into an ID-compatible + string and returns it. Raises ``ValueError`` if no argument is + found. + + - ``unicode_code``: Convert a Unicode character code to a Unicode + character. + + - ``single_char_or_unicode``: A single character is returned as-is. + Unicode characters codes are converted as in ``unicode_code``. + + - ``single_char_or_whitespace_or_unicode``: As with + ``single_char_or_unicode``, but "tab" and "space" are also + supported. + + - ``positive_int``: Converts the argument into an integer. Raises + ValueError for negative, zero, or non-integer values. + + - ``positive_int_list``: Converts a space- or comma-separated list + of integers into a Python list of integers. Raises ValueError for + non-positive-integer values. + + - ``encoding``: Verfies the encoding argument by lookup. Raises + ValueError for unknown encodings. + + A further utility function, ``choice``, is supplied to enable + options whose argument must be a member of a finite set of possible + values. A custom conversion function must be written to use it. + For example:: + + from docutils.parsers.rst import directives + + def yesno(argument): + return directives.choice(argument, ('yes', 'no')) + + For example, here is an option spec for a directive which allows two + options, "name" and "value", each with an option argument:: + + directive_fn.options = {'name': unchanged, 'value': int} + +- ``content``: A boolean; true if content is allowed. Directive + functions must handle the case where content is required but not + present in the input text (an empty content list will be supplied). + +The final step of the ``run_directive()`` method is to call the +directive function itself. + + +Register the Directive +====================== + +If the directive is a general-use addition to the Docutils core, it +must be registered with the parser and language mappings added: + +1. Register the new directive using its canonical name in + ``docutils/parsers/rst/directives/__init__.py``, in the + ``_directive_registry`` dictionary. This allows the + reStructuredText parser to find and use the directive. + +2. Add an entry to the ``directives`` dictionary in + ``docutils/parsers/rst/languages/en.py`` for the directive, mapping + the English name to the canonical name (both lowercase). Usually + the English name and the canonical name are the same. + +3. Update all the other language modules as well. For languages in + which you are proficient, please add translations. For other + languages, add the English directive name plus "(translation + required)". + +If the directive is application-specific, use the +``register_directive`` function:: + + from docutils.parsers.rst import directives + directives.register_directive(directive_name, directive_function) + + +Examples +======== + +For the most direct and accurate information, "Use the Source, Luke!". +All standard directives are documented in `reStructuredText +Directives`_, and the source code implementing them is located in the +``docutils/parsers/rst/directives`` package. The ``__init__.py`` +module contains a mapping of directive name to module & function name. +Several representative directives are described below. + + +Admonitions +----------- + +Admonition directives, such as "note" and "caution", are quite simple. +They have no directive arguments or options. Admonition directive +content is interpreted as ordinary reStructuredText. The directive +function simply hands off control to a generic directive function:: + + def note(*args): + return admonition(nodes.note, *args) + + attention.content = 1 + +Note that the only thing distinguishing the various admonition +directives is the element (node class) generated. In the code above, +the node class is passed as the first argument to the generic +directive function (early version), where the actual processing takes +place:: + + def admonition(node_class, name, arguments, options, content, lineno, + content_offset, block_text, state, state_machine): + text = '\n'.join(content) + admonition_node = node_class(text) + if text: + state.nested_parse(content, content_offset, admonition_node) + return [admonition_node] + else: + warning = state_machine.reporter.warning( + 'The "%s" admonition is empty; content required.' + % (name), '', + nodes.literal_block(block_text, block_text), line=lineno) + return [warning] + +Three things are noteworthy in the function above: + +1. The ``admonition_node = node_class(text)`` line creates the wrapper + element, using the class passed in from the initial (stub) + directive function. + +2. The call to ``state.nested_parse()`` is what does the actual + processing. It parses the directive content and adds any generated + elements as child elements of ``admonition_node``. + +3. If there was no directive content, a warning is generated and + returned. The call to ``state_machine.reporter.warning()`` + includes a literal block containing the entire directive text + (``block_text``) and the line (``lineno``) of the top of the + directive. + + +"image" +------- + +The "image" directive is used to insert a picture into a document. +This directive has one argument, the path to the image file, and +supports several options. There is no directive content. Here's an +early version of the image directive function:: + + def image(name, arguments, options, content, lineno, + content_offset, block_text, state, state_machine): + reference = directives.uri(arguments[0]) + options['uri'] = reference + image_node = nodes.image(block_text, **options) + return [image_node] + + image.arguments = (1, 0, 1) + image.options = {'alt': directives.unchanged, + 'height': directives.nonnegative_int, + 'width': directives.nonnegative_int, + 'scale': directives.nonnegative_int, + 'align': align} + +Several things are noteworthy in the code above: + +1. The "image" directive requires a single argument, which is allowed + to contain whitespace (see the argument spec above, + ``image.arguments = (1, 0, 1)``). This is to allow for long URLs + which may span multiple lines. The first line of the ``image`` + function joins the URL, discarding any embedded whitespace. + +2. The reference is added to the ``options`` dictionary under the + "uri" key; this becomes an attribute of the ``nodes.image`` element + object. Any other attributes have already been set explicitly in + the source text. + +3. The "align" option depends on the following definitions (which + actually occur earlier in the source code):: + + align_values = ('top', 'middle', 'bottom', 'left', 'center', + 'right') + + def align(argument): + return directives.choice(argument, align_values) + + +"contents" +---------- + +The "contents" directive is used to insert an auto-generated table of +contents (TOC) into a document. It takes one optional argument, a +title for the TOC. If no title is specified, a default title is used +instead. The directive also handles several options. Here's an early +version of the code:: + + def contents(name, arguments, options, content, lineno, + content_offset, block_text, state, state_machine): + """Table of contents.""" + if arguments: + title_text = arguments[0] + text_nodes, messages = state.inline_text(title_text, lineno) + title = nodes.title(title_text, '', *text_nodes) + else: + messages = [] + title = None + pending = nodes.pending(parts.Contents, {'title': title}, + block_text) + pending.details.update(options) + state_machine.document.note_pending(pending) + return [pending] + messages + + contents.arguments = (0, 1, 1) + contents.options = {'depth': directives.nonnegative_int, + 'local': directives.flag, + 'backlinks': backlinks} + +Aspects of note include: + +1. The ``contents.arguments = (0, 1, 1)`` function attribute specifies + a single, *optional* argument. If no argument is present, the + ``arguments`` parameter to the directive function will be an empty + list. + +2. If an argument *is* present, its text is passed to + ``state.inline_text()`` for parsing. Titles may contain inline + markup, such as emphasis or inline literals. + +3. The table of contents is not generated right away. Typically, a + TOC is placed near the beginning of a document, and is a summary or + outline of the section structure of the document. The entire + document must already be processed before a summary can be made. + This directive leaves a ``nodes.pending`` placeholder element in + the document tree, marking the position of the TOC and including a + ``details`` internal attribute containing all the directive + options, effectively communicating the options forward. The actual + table of contents processing is performed by a transform, + ``docutils.transforms.parts.Contents``, after the rest of the + document has been parsed. diff --git a/docs/howto/rst-roles.txt b/docs/howto/rst-roles.txt new file mode 100644 index 000000000..f8ce08bca --- /dev/null +++ b/docs/howto/rst-roles.txt @@ -0,0 +1,228 @@ +================================================== + Creating reStructuredText Interpreted Text Roles +================================================== + +:Authors: David Goodger +:Contact: goodger@python.org +:Date: $Date$ +:Revision: $Revision$ +:Copyright: This document has been placed in the public domain. + +Interpreted text roles are an extension mechanism for inline markup in +reStructuredText. This document aims to make the creation of new +roles as easy and understandable as possible. + +Standard roles are described in `reStructuredText Interpreted Text +Roles`_. See the `Interpreted Text`_ section in the `reStructuredText +Markup Specification`_ for syntax details. + +.. _reStructuredText Interpreted Text Roles: ../ref/rst/roles.html +.. _Interpreted Text: + ../ref/rst/restructuredtext.html#interpreted-text +.. _reStructuredText Markup Specification: + ../ref/rst/restructuredtext.html + + +.. contents:: + + +Define the Role Function +======================== + +The role function creates and returns inline elements (nodes) and does +any additional processing required. Its signature is as follows:: + + def role_fn(name, rawtext, text, lineno, inliner, + options={}, content=[]): + code... + + # Set function attributes for customization: + role_fn.options = ... + role_fn.content = ... + +Function attributes are described below (see `Specify Role Function +Options and Content`_). The role function parameters are as follows: + +* ``name``: The local name of the interpreted role, the role name + actually used in the document. + +* ``rawtext``: A string containing the enitre interpreted text input, + including the role and markup. Return it as a ``problematic`` node + linked to a system message if a problem is encountered. + +* ``text``: The interpreted text content. + +* ``lineno``: The line number where the interpreted text begins. + +* ``inliner``: The ``docutils.parsers.rst.states.Inliner`` object that + called role_fn. It contains the several attributes useful for error + reporting and document tree access. + +* ``options``: A dictionary of directive options for customization + (from the `"role" directive`_), to be interpreted by the role + function. Used for additional attributes for the generated elements + and other functionality. + +* ``content``: A list of strings, the directive content for + customization (from the `"role" directive`_). To be interpreted by + the role function. + +Role functions return a tuple of two values: + +* A list of nodes which will be inserted into the document tree at the + point where the interpreted role was encountered (can be an empty + list). + +* A list of system messages, which will be inserted into the document tree + immediately after the end of the current block (can also be empty). + + +Specify Role Function Options and Content +========================================= + +Function attributes are for customization, and are interpreted by the +`"role" directive`_. If unspecified, role function attributes are +assumed to have the value ``None``. Two function attributes are +recognized: + +- ``options``: The option specification. All role functions + implicitly support the "class" option, unless disabled with an + explicit ``{'class': None}``. + + An option specification must be defined detailing the options + available to the "role" directive. An option spec is a mapping of + option name to conversion function; conversion functions are applied + to each option value to check validity and convert them to the + expected type. Python's built-in conversion functions are often + usable for this, such as ``int``, ``float``, and ``bool`` (included + in Python from version 2.2.1). Other useful conversion functions + are included in the ``docutils.parsers.rst.directives`` package. + For further details, see `Creating reStructuredText Directives`_. + +- ``content``: A boolean; true if "role" directive content is allowed. + Role functions must handle the case where content is required but + not supplied (an empty content list will be supplied). + + As of this writing, no roles accept directive content. + +Note that unlike directives, the "arguments" function attribute is not +supported for role customization. Directive arguments are handled by +the "role" directive itself. + +.. _"role" directive: ../ref/rst/directives.html#role +.. _Creating reStructuredText Directives: + rst-directives.html#specify-directive-arguments-options-and-content + + +Register the Role +================= + +If the role is a general-use addition to the Docutils core, it must be +registered with the parser and language mappings added: + +1. Register the new role using the canonical name:: + + from docutils.parsers.rst import roles + roles.register_canonical_role(name, role_function) + + This code is normally placed immediately after the definition of + the role funtion. + +2. Add an entry to the ``roles`` dictionary in + ``docutils/parsers/rst/languages/en.py`` for the role, mapping the + English name to the canonical name (both lowercase). Usually the + English name and the canonical name are the same. Abbreviations + and other aliases may also be added here. + +3. Update all the other language modules as well. For languages in + which you are proficient, please add translations. For other + languages, add the English role name plus "(translation required)". + +If the role is application-specific, use the ``register_local_role`` +function:: + + from docutils.parsers.rst import roles + roles.register_local_role(name, role_function) + + +Examples +======== + +For the most direct and accurate information, "Use the Source, Luke!". +All standard roles are documented in `reStructuredText Interpreted +Text Roles`_, and the source code implementing them is located in the +``docutils/parsers/rst/roles.py`` module. Several representative +roles are described below. + + +Generic Roles +------------- + +Many roles simply wrap a given element around the text. There's a +special helper function, ``register_generic_role``, which generates a +role function from the canonical role name and node class:: + + register_generic_role('emphasis', nodes.emphasis) + +For the implementation of ``register_generic_role``, see the +``docutils.parsers.rst.roles`` module. + + +RFC Reference Role +------------------ + +This role allows easy references to RFCs_ (Request For Comments +documents) by automatically providing the base URL, +http://www.faqs.org/rfcs/, and appending the RFC document itself +(rfcXXXX.html, where XXXX is the RFC number). For example:: + + See :RFC:`2822` for information about email headers. + +This is equivalent to:: + + See `RFC 2822`__ for information about email headers. + + __ http://www.faqs.org/rfcs/rfc2822.html + +Here is the implementation of the role:: + + def rfc_reference_role(role, rawtext, text, lineno, inliner, + options={}, content=[]): + try: + rfcnum = int(text) + if rfcnum <= 0: + raise ValueError + except ValueError: + msg = inliner.reporter.error( + 'RFC number must be a number greater than or equal to 1; ' + '"%s" is invalid.' % text, line=lineno) + prb = inliner.problematic(rawtext, rawtext, msg) + return [prb], [msg] + # Base URL mainly used by inliner.rfc_reference, so this is correct: + ref = inliner.document.settings.rfc_base_url + inliner.rfc_url % rfcnum + set_classes(options) + node = nodes.reference(rawtext, 'RFC ' + utils.unescape(text), refuri=ref, + **options) + return [node], [] + + register_canonical_role('rfc-reference', rfc_reference_role) + +Noteworthy in the code above are: + +1. The interpreted text itself should contain the RFC number. The + ``try`` clause verifies by converting it to an integer. If the + conversion fails, the ``except`` clause is executed: a system + message is generated, the entire interpreted text construct (in + ``rawtext``) is wrapped in a ``problematic`` node (linked to the + system message), and the two are returned. + +2. The RFC reference itself is constructed from a stock URI, set as + the "refuri" attribute of a "reference" element. + +3. The ``options`` function parameter, a dictionary, may contain a + "class" customization attribute; it is interpreted and replaced + with a "classes" attribute by the ``set_classes()`` function. The + resulting "classes" attribute is passed through to the "reference" + element node constructor. + +.. _RFCs: http://foldoc.doc.ic.ac.uk/foldoc/foldoc.cgi?query=rfc&action=Search&sourceid=Mozilla-search |