@@ -2,10 +2,10 @@ | |||||
""" | """ | ||||
Implements support for both Python 2 and Python 3 by defining common types in | Implements support for both Python 2 and Python 3 by defining common types in | ||||
terms of their Python 2/3 variants. For example, :py:class:`str` is set to | |||||
:py:class:`unicode` on Python 2 but :py:class:`str` on Python 3; likewise, | |||||
:py:class:`bytes` is :py:class:`str` on 2 but :py:class:`bytes` on 3. These | |||||
types are meant to be imported directly from within the parser's modules. | |||||
terms of their Python 2/3 variants. For example, :class:`str` is set to | |||||
:class:`unicode` on Python 2 but :class:`str` on Python 3; likewise, | |||||
:class:`bytes` is :class:`str` on 2 but :class:`bytes` on 3. These types are | |||||
meant to be imported directly from within the parser's modules. | |||||
""" | """ | ||||
import sys | import sys | ||||
@@ -21,12 +21,12 @@ | |||||
# SOFTWARE. | # SOFTWARE. | ||||
""" | """ | ||||
This package contains :py:class:`~.Wikicode` "nodes", which represent a single | |||||
unit of wikitext, such as a Template, an HTML tag, a Heading, or plain text. | |||||
The node "tree" is far from flat, as most types can contain additional | |||||
:py:class:`~.Wikicode` types within them - and with that, more nodes. For | |||||
example, the name of a :py:class:`~.Template` is a :py:class:`~.Wikicode` | |||||
object that can contain text or more templates. | |||||
This package contains :class:`.Wikicode` "nodes", which represent a single unit | |||||
of wikitext, such as a Template, an HTML tag, a Heading, or plain text. The | |||||
node "tree" is far from flat, as most types can contain additional | |||||
:class:`.Wikicode` types within them - and with that, more nodes. For example, | |||||
the name of a :class:`.Template` is a :class:`.Wikicode` object that can | |||||
contain text or more templates. | |||||
""" | """ | ||||
from __future__ import unicode_literals | from __future__ import unicode_literals | ||||
@@ -40,16 +40,16 @@ __all__ = ["Node", "Text", "Argument", "Heading", "HTMLEntity", "Tag", | |||||
class Node(StringMixIn): | class Node(StringMixIn): | ||||
"""Represents the base Node type, demonstrating the methods to override. | """Represents the base Node type, demonstrating the methods to override. | ||||
:py:meth:`__unicode__` must be overridden. It should return a ``unicode`` | |||||
or (``str`` in py3k) representation of the node. If the node contains | |||||
:py:class:`~.Wikicode` objects inside of it, :py:meth:`__children__` | |||||
should be a generator that iterates over them. If the node is printable | |||||
(shown when the page is rendered), :py:meth:`__strip__` should return its | |||||
:meth:`__unicode__` must be overridden. It should return a ``unicode`` or | |||||
(``str`` in py3k) representation of the node. If the node contains | |||||
:class:`.Wikicode` objects inside of it, :meth:`__children__` should be a | |||||
generator that iterates over them. If the node is printable | |||||
(shown when the page is rendered), :meth:`__strip__` should return its | |||||
printable version, stripping out any formatting marks. It does not have to | printable version, stripping out any formatting marks. It does not have to | ||||
return a string, but something that can be converted to a string with | return a string, but something that can be converted to a string with | ||||
``str()``. Finally, :py:meth:`__showtree__` can be overridden to build a | |||||
``str()``. Finally, :meth:`__showtree__` can be overridden to build a | |||||
nice tree representation of the node, if desired, for | nice tree representation of the node, if desired, for | ||||
:py:meth:`~.Wikicode.get_tree`. | |||||
:meth:`~.Wikicode.get_tree`. | |||||
""" | """ | ||||
def __unicode__(self): | def __unicode__(self): | ||||
raise NotImplementedError() | raise NotImplementedError() | ||||
@@ -67,12 +67,12 @@ class ExternalLink(Node): | |||||
@property | @property | ||||
def url(self): | def url(self): | ||||
"""The URL of the link target, as a :py:class:`~.Wikicode` object.""" | |||||
"""The URL of the link target, as a :class:`.Wikicode` object.""" | |||||
return self._url | return self._url | ||||
@property | @property | ||||
def title(self): | def title(self): | ||||
"""The link title (if given), as a :py:class:`~.Wikicode` object.""" | |||||
"""The link title (if given), as a :class:`.Wikicode` object.""" | |||||
return self._title | return self._title | ||||
@property | @property | ||||
@@ -21,9 +21,8 @@ | |||||
# SOFTWARE. | # SOFTWARE. | ||||
""" | """ | ||||
This package contains objects used by | |||||
:py:class:`~.Node`\ s, but are not nodes themselves. This includes the | |||||
parameters of Templates or the attributes of HTML tags. | |||||
This package contains objects used by :class:`.Node`\ s, but that are not nodes | |||||
themselves. This includes template parameters and HTML tag attributes. | |||||
""" | """ | ||||
from .attribute import Attribute | from .attribute import Attribute | ||||
@@ -31,7 +31,7 @@ __all__ = ["Attribute"] | |||||
class Attribute(StringMixIn): | class Attribute(StringMixIn): | ||||
"""Represents an attribute of an HTML tag. | """Represents an attribute of an HTML tag. | ||||
This is used by :py:class:`~.Tag` objects. For example, the tag | |||||
This is used by :class:`.Tag` objects. For example, the tag | |||||
``<ref name="foo">`` contains an Attribute whose name is ``"name"`` and | ``<ref name="foo">`` contains an Attribute whose name is ``"name"`` and | ||||
whose value is ``"foo"``. | whose value is ``"foo"``. | ||||
""" | """ | ||||
@@ -84,12 +84,12 @@ class Attribute(StringMixIn): | |||||
@property | @property | ||||
def name(self): | def name(self): | ||||
"""The name of the attribute as a :py:class:`~.Wikicode` object.""" | |||||
"""The name of the attribute as a :class:`.Wikicode` object.""" | |||||
return self._name | return self._name | ||||
@property | @property | ||||
def value(self): | def value(self): | ||||
"""The value of the attribute as a :py:class:`~.Wikicode` object.""" | |||||
"""The value of the attribute as a :class:`.Wikicode` object.""" | |||||
return self._value | return self._value | ||||
@property | @property | ||||
@@ -58,12 +58,12 @@ class Parameter(StringMixIn): | |||||
@property | @property | ||||
def name(self): | def name(self): | ||||
"""The name of the parameter as a :py:class:`~.Wikicode` object.""" | |||||
"""The name of the parameter as a :class:`.Wikicode` object.""" | |||||
return self._name | return self._name | ||||
@property | @property | ||||
def value(self): | def value(self): | ||||
"""The value of the parameter as a :py:class:`~.Wikicode` object.""" | |||||
"""The value of the parameter as a :class:`.Wikicode` object.""" | |||||
return self._value | return self._value | ||||
@property | @property | ||||
@@ -52,7 +52,7 @@ class Heading(Node): | |||||
@property | @property | ||||
def title(self): | def title(self): | ||||
"""The title of the heading, as a :py:class:`~.Wikicode` object.""" | |||||
"""The title of the heading, as a :class:`.Wikicode` object.""" | |||||
return self._title | return self._title | ||||
@property | @property | ||||
@@ -108,19 +108,19 @@ class Tag(Node): | |||||
@property | @property | ||||
def tag(self): | def tag(self): | ||||
"""The tag itself, as a :py:class:`~.Wikicode` object.""" | |||||
"""The tag itself, as a :class:`.Wikicode` object.""" | |||||
return self._tag | return self._tag | ||||
@property | @property | ||||
def contents(self): | def contents(self): | ||||
"""The contents of the tag, as a :py:class:`~.Wikicode` object.""" | |||||
"""The contents of the tag, as a :class:`.Wikicode` object.""" | |||||
return self._contents | return self._contents | ||||
@property | @property | ||||
def attributes(self): | def attributes(self): | ||||
"""The list of attributes affecting the tag. | """The list of attributes affecting the tag. | ||||
Each attribute is an instance of :py:class:`~.Attribute`. | |||||
Each attribute is an instance of :class:`.Attribute`. | |||||
""" | """ | ||||
return self._attrs | return self._attrs | ||||
@@ -146,7 +146,7 @@ class Tag(Node): | |||||
This makes the tag look like a lone close tag. It is technically | This makes the tag look like a lone close tag. It is technically | ||||
invalid and is only parsable Wikicode when the tag itself is | invalid and is only parsable Wikicode when the tag itself is | ||||
single-only, like ``<br>`` and ``<img>``. See | single-only, like ``<br>`` and ``<img>``. See | ||||
:py:func:`.definitions.is_single_only`. | |||||
:func:`.definitions.is_single_only`. | |||||
""" | """ | ||||
return self._invalid | return self._invalid | ||||
@@ -155,8 +155,8 @@ class Tag(Node): | |||||
"""Whether the tag is implicitly self-closing, with no ending slash. | """Whether the tag is implicitly self-closing, with no ending slash. | ||||
This is only possible for specific "single" tags like ``<br>`` and | This is only possible for specific "single" tags like ``<br>`` and | ||||
``<li>``. See :py:func:`.definitions.is_single`. This field only has an | |||||
effect if :py:attr:`self_closing` is also ``True``. | |||||
``<li>``. See :func:`.definitions.is_single`. This field only has an | |||||
effect if :attr:`self_closing` is also ``True``. | |||||
""" | """ | ||||
return self._implicit | return self._implicit | ||||
@@ -167,9 +167,9 @@ class Tag(Node): | |||||
@property | @property | ||||
def closing_tag(self): | def closing_tag(self): | ||||
"""The closing tag, as a :py:class:`~.Wikicode` object. | |||||
"""The closing tag, as a :class:`.Wikicode` object. | |||||
This will usually equal :py:attr:`tag`, unless there is additional | |||||
This will usually equal :attr:`tag`, unless there is additional | |||||
spacing, comments, or the like. | spacing, comments, or the like. | ||||
""" | """ | ||||
return self._closing_tag | return self._closing_tag | ||||
@@ -226,8 +226,8 @@ class Tag(Node): | |||||
def get(self, name): | def get(self, name): | ||||
"""Get the attribute with the given *name*. | """Get the attribute with the given *name*. | ||||
The returned object is a :py:class:`~.Attribute` instance. Raises | |||||
:py:exc:`ValueError` if no attribute has this name. Since multiple | |||||
The returned object is a :class:`.Attribute` instance. Raises | |||||
:exc:`ValueError` if no attribute has this name. Since multiple | |||||
attributes can have the same name, we'll return the last match, since | attributes can have the same name, we'll return the last match, since | ||||
all but the last are ignored by the MediaWiki parser. | all but the last are ignored by the MediaWiki parser. | ||||
""" | """ | ||||
@@ -241,9 +241,9 @@ class Tag(Node): | |||||
"""Add an attribute with the given *name* and *value*. | """Add an attribute with the given *name* and *value*. | ||||
*name* and *value* can be anything parsable by | *name* and *value* can be anything parsable by | ||||
:py:func:`.utils.parse_anything`; *value* can be omitted if the | |||||
attribute is valueless. If *quotes* is not ``None``, it should be a | |||||
string (either ``"`` or ``'``) that *value* will be wrapped in (this is | |||||
:func:`.utils.parse_anything`; *value* can be omitted if the attribute | |||||
is valueless. If *quotes* is not ``None``, it should be a string | |||||
(either ``"`` or ``'``) that *value* will be wrapped in (this is | |||||
recommended). ``None`` is only legal if *value* contains no spacing. | recommended). ``None`` is only legal if *value* contains no spacing. | ||||
*pad_first*, *pad_before_eq*, and *pad_after_eq* are whitespace used as | *pad_first*, *pad_before_eq*, and *pad_after_eq* are whitespace used as | ||||
@@ -110,8 +110,8 @@ class Template(Node): | |||||
"""Try to determine the whitespace conventions for parameters. | """Try to determine the whitespace conventions for parameters. | ||||
This will examine the existing parameters and use | This will examine the existing parameters and use | ||||
:py:meth:`_select_theory` to determine if there are any preferred | |||||
styles for how much whitespace to put before or after the value. | |||||
:meth:`_select_theory` to determine if there are any preferred styles | |||||
for how much whitespace to put before or after the value. | |||||
""" | """ | ||||
before_theories = defaultdict(lambda: 0) | before_theories = defaultdict(lambda: 0) | ||||
after_theories = defaultdict(lambda: 0) | after_theories = defaultdict(lambda: 0) | ||||
@@ -159,7 +159,7 @@ class Template(Node): | |||||
@property | @property | ||||
def name(self): | def name(self): | ||||
"""The name of the template, as a :py:class:`~.Wikicode` object.""" | |||||
"""The name of the template, as a :class:`.Wikicode` object.""" | |||||
return self._name | return self._name | ||||
@property | @property | ||||
@@ -189,13 +189,13 @@ class Template(Node): | |||||
has_param = lambda self, name, ignore_empty=False: \ | has_param = lambda self, name, ignore_empty=False: \ | ||||
self.has(name, ignore_empty) | self.has(name, ignore_empty) | ||||
has_param.__doc__ = "Alias for :py:meth:`has`." | |||||
has_param.__doc__ = "Alias for :meth:`has`." | |||||
def get(self, name): | def get(self, name): | ||||
"""Get the parameter whose name is *name*. | """Get the parameter whose name is *name*. | ||||
The returned object is a :py:class:`~.Parameter` instance. Raises | |||||
:py:exc:`ValueError` if no parameter has this name. Since multiple | |||||
The returned object is a :class:`.Parameter` instance. Raises | |||||
:exc:`ValueError` if no parameter has this name. Since multiple | |||||
parameters can have the same name, we'll return the last match, since | parameters can have the same name, we'll return the last match, since | ||||
the last parameter is the only one read by the MediaWiki parser. | the last parameter is the only one read by the MediaWiki parser. | ||||
""" | """ | ||||
@@ -210,8 +210,8 @@ class Template(Node): | |||||
"""Add a parameter to the template with a given *name* and *value*. | """Add a parameter to the template with a given *name* and *value*. | ||||
*name* and *value* can be anything parsable by | *name* and *value* can be anything parsable by | ||||
:py:func:`.utils.parse_anything`; pipes and equal signs are | |||||
automatically escaped from *value* when appropriate. | |||||
:func:`.utils.parse_anything`; pipes and equal signs are automatically | |||||
escaped from *value* when appropriate. | |||||
If *showkey* is given, this will determine whether or not to show the | If *showkey* is given, this will determine whether or not to show the | ||||
parameter's name (e.g., ``{{foo|bar}}``'s parameter has a name of | parameter's name (e.g., ``{{foo|bar}}``'s parameter has a name of | ||||
@@ -221,13 +221,13 @@ class Template(Node): | |||||
If *name* is already a parameter in the template, we'll replace its | If *name* is already a parameter in the template, we'll replace its | ||||
value while keeping the same whitespace around it. We will also try to | value while keeping the same whitespace around it. We will also try to | ||||
guess the dominant spacing convention when adding a new parameter using | guess the dominant spacing convention when adding a new parameter using | ||||
:py:meth:`_get_spacing_conventions`. | |||||
:meth:`_get_spacing_conventions`. | |||||
If *before* is given (either a :py:class:`~.Parameter` object or a | |||||
name), then we will place the parameter immediately before this one. | |||||
If *before* is given (either a :class:`.Parameter` object or a name), | |||||
then we will place the parameter immediately before this one. | |||||
Otherwise, it will be added at the end. If *before* is a name and | Otherwise, it will be added at the end. If *before* is a name and | ||||
exists multiple times in the template, we will place it before the last | exists multiple times in the template, we will place it before the last | ||||
occurrence. If *before* is not in the template, :py:exc:`ValueError` is | |||||
occurrence. If *before* is not in the template, :exc:`ValueError` is | |||||
raised. The argument is ignored if the new parameter already exists. | raised. The argument is ignored if the new parameter already exists. | ||||
If *preserve_spacing* is ``False``, we will avoid preserving spacing | If *preserve_spacing* is ``False``, we will avoid preserving spacing | ||||
@@ -289,9 +289,9 @@ class Template(Node): | |||||
def remove(self, param, keep_field=False): | def remove(self, param, keep_field=False): | ||||
"""Remove a parameter from the template, identified by *param*. | """Remove a parameter from the template, identified by *param*. | ||||
If *param* is a :py:class:`.Parameter` object, it will be matched | |||||
exactly, otherwise it will be treated like the *name* argument to | |||||
:py:meth:`has` and :py:meth:`get`. | |||||
If *param* is a :class:`.Parameter` object, it will be matched exactly, | |||||
otherwise it will be treated like the *name* argument to :meth:`has` | |||||
and :meth:`get`. | |||||
If *keep_field* is ``True``, we will keep the parameter's name, but | If *keep_field* is ``True``, we will keep the parameter's name, but | ||||
blank its value. Otherwise, we will remove the parameter completely | blank its value. Otherwise, we will remove the parameter completely | ||||
@@ -300,7 +300,7 @@ class Template(Node): | |||||
we expected, so ``{{foo||baz}}`` will be produced instead). | we expected, so ``{{foo||baz}}`` will be produced instead). | ||||
If the parameter shows up multiple times in the template and *param* is | If the parameter shows up multiple times in the template and *param* is | ||||
not a :py:class:`.Parameter` object, we will remove all instances of it | |||||
not a :class:`.Parameter` object, we will remove all instances of it | |||||
(and keep only one if *keep_field* is ``True`` - the first instance if | (and keep only one if *keep_field* is ``True`` - the first instance if | ||||
none have dependents, otherwise the one with dependents will be kept). | none have dependents, otherwise the one with dependents will be kept). | ||||
""" | """ | ||||
@@ -62,12 +62,12 @@ class Wikilink(Node): | |||||
@property | @property | ||||
def title(self): | def title(self): | ||||
"""The title of the linked page, as a :py:class:`~.Wikicode` object.""" | |||||
"""The title of the linked page, as a :class:`.Wikicode` object.""" | |||||
return self._title | return self._title | ||||
@property | @property | ||||
def text(self): | def text(self): | ||||
"""The text to display (if any), as a :py:class:`~.Wikicode` object.""" | |||||
"""The text to display (if any), as a :class:`.Wikicode` object.""" | |||||
return self._text | return self._text | ||||
@title.setter | @title.setter | ||||
@@ -22,8 +22,8 @@ | |||||
""" | """ | ||||
This package contains the actual wikicode parser, split up into two main | This package contains the actual wikicode parser, split up into two main | ||||
modules: the :py:mod:`~.tokenizer` and the :py:mod:`~.builder`. This module | |||||
joins them together under one interface. | |||||
modules: the :mod:`.tokenizer` and the :mod:`.builder`. This module joins them | |||||
together into one interface. | |||||
""" | """ | ||||
class ParserError(Exception): | class ParserError(Exception): | ||||
@@ -54,16 +54,16 @@ class Parser(object): | |||||
"""Represents a parser for wikicode. | """Represents a parser for wikicode. | ||||
Actual parsing is a two-step process: first, the text is split up into a | Actual parsing is a two-step process: first, the text is split up into a | ||||
series of tokens by the :py:class:`.Tokenizer`, and then the tokens are | |||||
converted into trees of :py:class:`.Wikicode` objects and | |||||
:py:class:`.Node`\ s by the :py:class:`.Builder`. | |||||
series of tokens by the :class:`.Tokenizer`, and then the tokens are | |||||
converted into trees of :class:`.Wikicode` objects and :class:`.Node`\ s by | |||||
the :class:`.Builder`. | |||||
Instances of this class or its dependents (:py:class:`.Tokenizer` and | |||||
:py:class:`.Builder`) should not be shared between threads. | |||||
:py:meth:`parse` can be called multiple times as long as it is not done | |||||
concurrently. In general, there is no need to do this because parsing | |||||
should be done through :py:func:`mwparserfromhell.parse`, which creates a | |||||
new :py:class:`.Parser` object as necessary. | |||||
Instances of this class or its dependents (:class:`.Tokenizer` and | |||||
:class:`.Builder`) should not be shared between threads. :meth:`parse` can | |||||
be called multiple times as long as it is not done concurrently. In | |||||
general, there is no need to do this because parsing should be done through | |||||
:func:`mwparserfromhell.parse`, which creates a new :class:`.Parser` object | |||||
as necessary. | |||||
""" | """ | ||||
def __init__(self): | def __init__(self): | ||||
@@ -74,20 +74,20 @@ class Parser(object): | |||||
self._builder = Builder() | self._builder = Builder() | ||||
def parse(self, text, context=0, skip_style_tags=False): | def parse(self, text, context=0, skip_style_tags=False): | ||||
"""Parse *text*, returning a :py:class:`~.Wikicode` object tree. | |||||
"""Parse *text*, returning a :class:`.Wikicode` object tree. | |||||
If given, *context* will be passed as a starting context to the parser. | If given, *context* will be passed as a starting context to the parser. | ||||
This is helpful when this function is used inside node attribute | This is helpful when this function is used inside node attribute | ||||
setters. For example, :py:class:`~.ExternalLink`\ 's | |||||
:py:attr:`~.ExternalLink.url` setter sets *context* to | |||||
:py:mod:`contexts.EXT_LINK_URI <.contexts>` to prevent the URL itself | |||||
from becoming an :py:class:`~.ExternalLink`. | |||||
setters. For example, :class:`.ExternalLink`\ 's | |||||
:attr:`~.ExternalLink.url` setter sets *context* to | |||||
:mod:`contexts.EXT_LINK_URI <.contexts>` to prevent the URL itself | |||||
from becoming an :class:`.ExternalLink`. | |||||
If *skip_style_tags* is ``True``, then ``''`` and ``'''`` will not be | If *skip_style_tags* is ``True``, then ``''`` and ``'''`` will not be | ||||
parsed, but instead will be treated as plain text. | parsed, but instead will be treated as plain text. | ||||
If there is an internal error while parsing, :py:exc:`.ParserError` | |||||
will be raised. | |||||
If there is an internal error while parsing, :exc:`.ParserError` will | |||||
be raised. | |||||
""" | """ | ||||
tokens = self._tokenizer.tokenize(text, context, skip_style_tags) | tokens = self._tokenizer.tokenize(text, context, skip_style_tags) | ||||
code = self._builder.build(tokens) | code = self._builder.build(tokens) | ||||
@@ -48,9 +48,9 @@ def _add_handler(token_type): | |||||
class Builder(object): | class Builder(object): | ||||
"""Builds a tree of nodes out of a sequence of tokens. | """Builds a tree of nodes out of a sequence of tokens. | ||||
To use, pass a list of :py:class:`~.Token`\ s to the :py:meth:`build` | |||||
method. The list will be exhausted as it is parsed and a | |||||
:py:class:`.Wikicode` object containing the node tree will be returned. | |||||
To use, pass a list of :class:`.Token`\ s to the :meth:`build` method. The | |||||
list will be exhausted as it is parsed and a :class:`.Wikicode` object | |||||
containing the node tree will be returned. | |||||
""" | """ | ||||
def __init__(self): | def __init__(self): | ||||
@@ -64,8 +64,8 @@ class Builder(object): | |||||
def _pop(self): | def _pop(self): | ||||
"""Pop the current node list off of the stack. | """Pop the current node list off of the stack. | ||||
The raw node list is wrapped in a :py:class:`.SmartList` and then in a | |||||
:py:class:`.Wikicode` object. | |||||
The raw node list is wrapped in a :class:`.SmartList` and then in a | |||||
:class:`.Wikicode` object. | |||||
""" | """ | ||||
return Wikicode(SmartList(self._stacks.pop())) | return Wikicode(SmartList(self._stacks.pop())) | ||||
@@ -35,72 +35,72 @@ will cover ``BAR == 0b10`` and ``BAZ == 0b01``). | |||||
Local (stack-specific) contexts: | Local (stack-specific) contexts: | ||||
* :py:const:`TEMPLATE` | |||||
* :const:`TEMPLATE` | |||||
* :py:const:`TEMPLATE_NAME` | |||||
* :py:const:`TEMPLATE_PARAM_KEY` | |||||
* :py:const:`TEMPLATE_PARAM_VALUE` | |||||
* :const:`TEMPLATE_NAME` | |||||
* :const:`TEMPLATE_PARAM_KEY` | |||||
* :const:`TEMPLATE_PARAM_VALUE` | |||||
* :py:const:`ARGUMENT` | |||||
* :const:`ARGUMENT` | |||||
* :py:const:`ARGUMENT_NAME` | |||||
* :py:const:`ARGUMENT_DEFAULT` | |||||
* :const:`ARGUMENT_NAME` | |||||
* :const:`ARGUMENT_DEFAULT` | |||||
* :py:const:`WIKILINK` | |||||
* :const:`WIKILINK` | |||||
* :py:const:`WIKILINK_TITLE` | |||||
* :py:const:`WIKILINK_TEXT` | |||||
* :const:`WIKILINK_TITLE` | |||||
* :const:`WIKILINK_TEXT` | |||||
* :py:const:`EXT_LINK` | |||||
* :const:`EXT_LINK` | |||||
* :py:const:`EXT_LINK_URI` | |||||
* :py:const:`EXT_LINK_TITLE` | |||||
* :const:`EXT_LINK_URI` | |||||
* :const:`EXT_LINK_TITLE` | |||||
* :py:const:`HEADING` | |||||
* :const:`HEADING` | |||||
* :py:const:`HEADING_LEVEL_1` | |||||
* :py:const:`HEADING_LEVEL_2` | |||||
* :py:const:`HEADING_LEVEL_3` | |||||
* :py:const:`HEADING_LEVEL_4` | |||||
* :py:const:`HEADING_LEVEL_5` | |||||
* :py:const:`HEADING_LEVEL_6` | |||||
* :const:`HEADING_LEVEL_1` | |||||
* :const:`HEADING_LEVEL_2` | |||||
* :const:`HEADING_LEVEL_3` | |||||
* :const:`HEADING_LEVEL_4` | |||||
* :const:`HEADING_LEVEL_5` | |||||
* :const:`HEADING_LEVEL_6` | |||||
* :py:const:`TAG` | |||||
* :const:`TAG` | |||||
* :py:const:`TAG_OPEN` | |||||
* :py:const:`TAG_ATTR` | |||||
* :py:const:`TAG_BODY` | |||||
* :py:const:`TAG_CLOSE` | |||||
* :const:`TAG_OPEN` | |||||
* :const:`TAG_ATTR` | |||||
* :const:`TAG_BODY` | |||||
* :const:`TAG_CLOSE` | |||||
* :py:const:`STYLE` | |||||
* :const:`STYLE` | |||||
* :py:const:`STYLE_ITALICS` | |||||
* :py:const:`STYLE_BOLD` | |||||
* :py:const:`STYLE_PASS_AGAIN` | |||||
* :py:const:`STYLE_SECOND_PASS` | |||||
* :const:`STYLE_ITALICS` | |||||
* :const:`STYLE_BOLD` | |||||
* :const:`STYLE_PASS_AGAIN` | |||||
* :const:`STYLE_SECOND_PASS` | |||||
* :py:const:`DL_TERM` | |||||
* :const:`DL_TERM` | |||||
* :py:const:`SAFETY_CHECK` | |||||
* :const:`SAFETY_CHECK` | |||||
* :py:const:`HAS_TEXT` | |||||
* :py:const:`FAIL_ON_TEXT` | |||||
* :py:const:`FAIL_NEXT` | |||||
* :py:const:`FAIL_ON_LBRACE` | |||||
* :py:const:`FAIL_ON_RBRACE` | |||||
* :py:const:`FAIL_ON_EQUALS` | |||||
* :const:`HAS_TEXT` | |||||
* :const:`FAIL_ON_TEXT` | |||||
* :const:`FAIL_NEXT` | |||||
* :const:`FAIL_ON_LBRACE` | |||||
* :const:`FAIL_ON_RBRACE` | |||||
* :const:`FAIL_ON_EQUALS` | |||||
Global contexts: | Global contexts: | ||||
* :py:const:`GL_HEADING` | |||||
* :const:`GL_HEADING` | |||||
Aggregate contexts: | Aggregate contexts: | ||||
* :py:const:`FAIL` | |||||
* :py:const:`UNSAFE` | |||||
* :py:const:`DOUBLE` | |||||
* :py:const:`NO_WIKILINKS` | |||||
* :py:const:`NO_EXT_LINKS` | |||||
* :const:`FAIL` | |||||
* :const:`UNSAFE` | |||||
* :const:`DOUBLE` | |||||
* :const:`NO_WIKILINKS` | |||||
* :const:`NO_EXT_LINKS` | |||||
""" | """ | ||||
@@ -135,7 +135,7 @@ class Tokenizer(object): | |||||
"""Fail the current tokenization route. | """Fail the current tokenization route. | ||||
Discards the current stack/context/textbuffer and raises | Discards the current stack/context/textbuffer and raises | ||||
:py:exc:`~.BadRoute`. | |||||
:exc:`.BadRoute`. | |||||
""" | """ | ||||
context = self._context | context = self._context | ||||
self._pop() | self._pop() | ||||
@@ -173,14 +173,14 @@ class Tokenizer(object): | |||||
def _read(self, delta=0, wrap=False, strict=False): | def _read(self, delta=0, wrap=False, strict=False): | ||||
"""Read the value at a relative point in the wikicode. | """Read the value at a relative point in the wikicode. | ||||
The value is read from :py:attr:`self._head <_head>` plus the value of | |||||
The value is read from :attr:`self._head <_head>` plus the value of | |||||
*delta* (which can be negative). If *wrap* is ``False``, we will not | *delta* (which can be negative). If *wrap* is ``False``, we will not | ||||
allow attempts to read from the end of the string if ``self._head + | allow attempts to read from the end of the string if ``self._head + | ||||
delta`` is negative. If *strict* is ``True``, the route will be failed | delta`` is negative. If *strict* is ``True``, the route will be failed | ||||
(with :py:meth:`_fail_route`) if we try to read from past the end of | |||||
the string; otherwise, :py:attr:`self.END <END>` is returned. If we try | |||||
to read from before the start of the string, :py:attr:`self.START | |||||
<START>` is returned. | |||||
(with :meth:`_fail_route`) if we try to read from past the end of the | |||||
string; otherwise, :attr:`self.END <END>` is returned. If we try to | |||||
read from before the start of the string, :attr:`self.START <START>` is | |||||
returned. | |||||
""" | """ | ||||
index = self._head + delta | index = self._head + delta | ||||
if index < 0 and (not wrap or abs(index) > len(self._text)): | if index < 0 and (not wrap or abs(index) > len(self._text)): | ||||
@@ -24,8 +24,8 @@ | |||||
This module contains the token definitions that are used as an intermediate | This module contains the token definitions that are used as an intermediate | ||||
parsing data type - they are stored in a flat list, with each token being | parsing data type - they are stored in a flat list, with each token being | ||||
identified by its type and optional attributes. The token list is generated in | identified by its type and optional attributes. The token list is generated in | ||||
a syntactically valid form by the :py:class:`~.Tokenizer`, and then converted | |||||
into the :py:class`~.Wikicode` tree by the :py:class:`~.Builder`. | |||||
a syntactically valid form by the :class:`.Tokenizer`, and then converted into | |||||
the :class`.Wikicode` tree by the :class:`.Builder`. | |||||
""" | """ | ||||
from __future__ import unicode_literals | from __future__ import unicode_literals | ||||
@@ -21,8 +21,8 @@ | |||||
# SOFTWARE. | # SOFTWARE. | ||||
""" | """ | ||||
This module contains the :py:class:`~.SmartList` type, as well as its | |||||
:py:class:`~._ListProxy` child, which together implement a list whose sublists | |||||
This module contains the :class:`.SmartList` type, as well as its | |||||
:class:`._ListProxy` child, which together implement a list whose sublists | |||||
reflect changes made to the main list, and vice-versa. | reflect changes made to the main list, and vice-versa. | ||||
""" | """ | ||||
@@ -35,7 +35,7 @@ __all__ = ["SmartList"] | |||||
def inheritdoc(method): | def inheritdoc(method): | ||||
"""Set __doc__ of *method* to __doc__ of *method* in its parent class. | """Set __doc__ of *method* to __doc__ of *method* in its parent class. | ||||
Since this is used on :py:class:`~.SmartList`, the "parent class" used is | |||||
Since this is used on :class:`.SmartList`, the "parent class" used is | |||||
``list``. This function can be used as a decorator. | ``list``. This function can be used as a decorator. | ||||
""" | """ | ||||
method.__doc__ = getattr(list, method.__name__).__doc__ | method.__doc__ = getattr(list, method.__name__).__doc__ | ||||
@@ -65,9 +65,9 @@ class SmartList(_SliceNormalizerMixIn, list): | |||||
list (such as the addition, removal, or replacement of elements) will be | list (such as the addition, removal, or replacement of elements) will be | ||||
reflected in the sublist, or vice-versa, to the greatest degree possible. | reflected in the sublist, or vice-versa, to the greatest degree possible. | ||||
This is implemented by having sublists - instances of the | This is implemented by having sublists - instances of the | ||||
:py:class:`~._ListProxy` type - dynamically determine their elements by | |||||
storing their slice info and retrieving that slice from the parent. Methods | |||||
that change the size of the list also change the slice info. For example:: | |||||
:class:`._ListProxy` type - dynamically determine their elements by storing | |||||
their slice info and retrieving that slice from the parent. Methods that | |||||
change the size of the list also change the slice info. For example:: | |||||
>>> parent = SmartList([0, 1, 2, 3]) | >>> parent = SmartList([0, 1, 2, 3]) | ||||
>>> parent | >>> parent | ||||
@@ -84,8 +84,8 @@ class SmartList(_SliceNormalizerMixIn, list): | |||||
The parent needs to keep a list of its children in order to update them, | The parent needs to keep a list of its children in order to update them, | ||||
which prevents them from being garbage-collected. If you are keeping the | which prevents them from being garbage-collected. If you are keeping the | ||||
parent around for a while but creating many children, it is advisable to | parent around for a while but creating many children, it is advisable to | ||||
call :py:meth:`~._ListProxy.detach` when you're finished with them. Certain | |||||
parent methods, like :py:meth:`reverse` and :py:meth:`sort`, will do this | |||||
call :meth:`._ListProxy.detach` when you're finished with them. Certain | |||||
parent methods, like :meth:`reverse` and :meth:`sort`, will do this | |||||
automatically. | automatically. | ||||
""" | """ | ||||
@@ -217,9 +217,9 @@ class SmartList(_SliceNormalizerMixIn, list): | |||||
class _ListProxy(_SliceNormalizerMixIn, list): | class _ListProxy(_SliceNormalizerMixIn, list): | ||||
"""Implement the ``list`` interface by getting elements from a parent. | """Implement the ``list`` interface by getting elements from a parent. | ||||
This is created by a :py:class:`~.SmartList` object when slicing. It does | |||||
not actually store the list at any time; instead, whenever the list is | |||||
needed, it builds it dynamically using the :py:meth:`_render` method. | |||||
This is created by a :class:`.SmartList` object when slicing. It does not | |||||
actually store the list at any time; instead, whenever the list is needed, | |||||
it builds it dynamically using the :meth:`_render` method. | |||||
""" | """ | ||||
def __init__(self, parent, sliceinfo): | def __init__(self, parent, sliceinfo): | ||||
@@ -21,7 +21,7 @@ | |||||
# SOFTWARE. | # SOFTWARE. | ||||
""" | """ | ||||
This module contains the :py:class:`~.StringMixIn` type, which implements the | |||||
This module contains the :class:`.StringMixIn` type, which implements the | |||||
interface for the ``unicode`` type (``str`` on py3k) in a dynamic manner. | interface for the ``unicode`` type (``str`` on py3k) in a dynamic manner. | ||||
""" | """ | ||||
@@ -35,7 +35,7 @@ __all__ = ["StringMixIn"] | |||||
def inheritdoc(method): | def inheritdoc(method): | ||||
"""Set __doc__ of *method* to __doc__ of *method* in its parent class. | """Set __doc__ of *method* to __doc__ of *method* in its parent class. | ||||
Since this is used on :py:class:`~.StringMixIn`, the "parent class" used is | |||||
Since this is used on :class:`.StringMixIn`, the "parent class" used is | |||||
``str``. This function can be used as a decorator. | ``str``. This function can be used as a decorator. | ||||
""" | """ | ||||
method.__doc__ = getattr(str, method.__name__).__doc__ | method.__doc__ = getattr(str, method.__name__).__doc__ | ||||
@@ -44,11 +44,10 @@ def inheritdoc(method): | |||||
class StringMixIn(object): | class StringMixIn(object): | ||||
"""Implement the interface for ``unicode``/``str`` in a dynamic manner. | """Implement the interface for ``unicode``/``str`` in a dynamic manner. | ||||
To use this class, inherit from it and override the :py:meth:`__unicode__` | |||||
To use this class, inherit from it and override the :meth:`__unicode__` | |||||
method (same on py3k) to return the string representation of the object. | method (same on py3k) to return the string representation of the object. | ||||
The various string methods will operate on the value of | |||||
:py:meth:`__unicode__` instead of the immutable ``self`` like the regular | |||||
``str`` type. | |||||
The various string methods will operate on the value of :meth:`__unicode__` | |||||
instead of the immutable ``self`` like the regular ``str`` type. | |||||
""" | """ | ||||
if py3k: | if py3k: | ||||
@@ -34,18 +34,18 @@ from .smart_list import SmartList | |||||
__all__ = ["parse_anything"] | __all__ = ["parse_anything"] | ||||
def parse_anything(value, context=0, skip_style_tags=False): | def parse_anything(value, context=0, skip_style_tags=False): | ||||
"""Return a :py:class:`~.Wikicode` for *value*, allowing multiple types. | |||||
"""Return a :class:`.Wikicode` for *value*, allowing multiple types. | |||||
This differs from :py:meth:`.Parser.parse` in that we accept more than just | |||||
a string to be parsed. Unicode objects (strings in py3k), strings (bytes in | |||||
py3k), integers (converted to strings), ``None``, existing | |||||
:py:class:`~.Node` or :py:class:`~.Wikicode` objects, as well as an | |||||
iterable of these types, are supported. This is used to parse input | |||||
on-the-fly by various methods of :py:class:`~.Wikicode` and others like | |||||
:py:class:`~.Template`, such as :py:meth:`wikicode.insert() | |||||
<.Wikicode.insert>` or setting :py:meth:`template.name <.Template.name>`. | |||||
This differs from :meth:`.Parser.parse` in that we accept more than just a | |||||
string to be parsed. Unicode objects (strings in py3k), strings (bytes in | |||||
py3k), integers (converted to strings), ``None``, existing :class:`.Node` | |||||
or :class:`.Wikicode` objects, as well as an iterable of these types, are | |||||
supported. This is used to parse input on-the-fly by various methods of | |||||
:class:`.Wikicode` and others like :class:`.Template`, such as | |||||
:meth:`wikicode.insert() <.Wikicode.insert>` or setting | |||||
:meth:`template.name <.Template.name>`. | |||||
Additional arguments are passed directly to :py:meth:`.Parser.parse`. | |||||
Additional arguments are passed directly to :meth:`.Parser.parse`. | |||||
""" | """ | ||||
from .parser import Parser | from .parser import Parser | ||||
from .wikicode import Wikicode | from .wikicode import Wikicode | ||||
@@ -39,8 +39,8 @@ class Wikicode(StringMixIn): | |||||
Additionally, it contains methods that can be used to extract data from or | Additionally, it contains methods that can be used to extract data from or | ||||
modify the nodes, implemented in an interface similar to a list. For | modify the nodes, implemented in an interface similar to a list. For | ||||
example, :py:meth:`index` can get the index of a node in the list, and | |||||
:py:meth:`insert` can add a new node at that index. The :py:meth:`filter() | |||||
example, :meth:`index` can get the index of a node in the list, and | |||||
:meth:`insert` can add a new node at that index. The :meth:`filter() | |||||
<ifilter>` series of functions is very useful for extracting and iterating | <ifilter>` series of functions is very useful for extracting and iterating | ||||
over, for example, all of the templates in the object. | over, for example, all of the templates in the object. | ||||
""" | """ | ||||
@@ -55,7 +55,7 @@ class Wikicode(StringMixIn): | |||||
@staticmethod | @staticmethod | ||||
def _get_children(node, contexts=False, restrict=None, parent=None): | def _get_children(node, contexts=False, restrict=None, parent=None): | ||||
"""Iterate over all child :py:class:`.Node`\ s of a given *node*.""" | |||||
"""Iterate over all child :class:`.Node`\ s of a given *node*.""" | |||||
yield (parent, node) if contexts else node | yield (parent, node) if contexts else node | ||||
if restrict and isinstance(node, restrict): | if restrict and isinstance(node, restrict): | ||||
return | return | ||||
@@ -74,7 +74,7 @@ class Wikicode(StringMixIn): | |||||
@staticmethod | @staticmethod | ||||
def _build_matcher(matches, flags): | def _build_matcher(matches, flags): | ||||
"""Helper for :py:meth:`_indexed_ifilter` and others. | |||||
"""Helper for :meth:`_indexed_ifilter` and others. | |||||
If *matches* is a function, return it. If it's a regex, return a | If *matches* is a function, return it. If it's a regex, return a | ||||
wrapper around it that can be called with a node to do a search. If | wrapper around it that can be called with a node to do a search. If | ||||
@@ -90,7 +90,7 @@ class Wikicode(StringMixIn): | |||||
forcetype=None): | forcetype=None): | ||||
"""Iterate over nodes and their corresponding indices in the node list. | """Iterate over nodes and their corresponding indices in the node list. | ||||
The arguments are interpreted as for :py:meth:`ifilter`. For each tuple | |||||
The arguments are interpreted as for :meth:`ifilter`. For each tuple | |||||
``(i, node)`` yielded by this method, ``self.index(node) == i``. Note | ``(i, node)`` yielded by this method, ``self.index(node) == i``. Note | ||||
that if *recursive* is ``True``, ``self.nodes[i]`` might not be the | that if *recursive* is ``True``, ``self.nodes[i]`` might not be the | ||||
node itself, but will still contain it. | node itself, but will still contain it. | ||||
@@ -111,14 +111,14 @@ class Wikicode(StringMixIn): | |||||
def _do_strong_search(self, obj, recursive=True): | def _do_strong_search(self, obj, recursive=True): | ||||
"""Search for the specific element *obj* within the node list. | """Search for the specific element *obj* within the node list. | ||||
*obj* can be either a :py:class:`.Node` or a :py:class:`.Wikicode` | |||||
object. If found, we return a tuple (*context*, *index*) where | |||||
*context* is the :py:class:`.Wikicode` that contains *obj* and *index* | |||||
is its index there, as a :py:class:`slice`. Note that if *recursive* is | |||||
``False``, *context* will always be ``self`` (since we only look for | |||||
*obj* among immediate descendants), but if *recursive* is ``True``, | |||||
then it could be any :py:class:`.Wikicode` contained by a node within | |||||
``self``. If *obj* is not found, :py:exc:`ValueError` is raised. | |||||
*obj* can be either a :class:`.Node` or a :class:`.Wikicode` object. If | |||||
found, we return a tuple (*context*, *index*) where *context* is the | |||||
:class:`.Wikicode` that contains *obj* and *index* is its index there, | |||||
as a :class:`slice`. Note that if *recursive* is ``False``, *context* | |||||
will always be ``self`` (since we only look for *obj* among immediate | |||||
descendants), but if *recursive* is ``True``, then it could be any | |||||
:class:`.Wikicode` contained by a node within ``self``. If *obj* is not | |||||
found, :exc:`ValueError` is raised. | |||||
""" | """ | ||||
if isinstance(obj, Node): | if isinstance(obj, Node): | ||||
mkslice = lambda i: slice(i, i + 1) | mkslice = lambda i: slice(i, i + 1) | ||||
@@ -141,14 +141,14 @@ class Wikicode(StringMixIn): | |||||
def _do_weak_search(self, obj, recursive): | def _do_weak_search(self, obj, recursive): | ||||
"""Search for an element that looks like *obj* within the node list. | """Search for an element that looks like *obj* within the node list. | ||||
This follows the same rules as :py:meth:`_do_strong_search` with some | |||||
This follows the same rules as :meth:`_do_strong_search` with some | |||||
differences. *obj* is treated as a string that might represent any | differences. *obj* is treated as a string that might represent any | ||||
:py:class:`.Node`, :py:class:`.Wikicode`, or combination of the two | |||||
present in the node list. Thus, matching is weak (using string | |||||
comparisons) rather than strong (using ``is``). Because multiple nodes | |||||
can match *obj*, the result is a list of tuples instead of just one | |||||
(however, :py:exc:`ValueError` is still raised if nothing is found). | |||||
Individual matches will never overlap. | |||||
:class:`.Node`, :class:`.Wikicode`, or combination of the two present | |||||
in the node list. Thus, matching is weak (using string comparisons) | |||||
rather than strong (using ``is``). Because multiple nodes can match | |||||
*obj*, the result is a list of tuples instead of just one (however, | |||||
:exc:`ValueError` is still raised if nothing is found). Individual | |||||
matches will never overlap. | |||||
The tuples contain a new first element, *exact*, which is ``True`` if | The tuples contain a new first element, *exact*, which is ``True`` if | ||||
we were able to match *obj* exactly to one or more adjacent nodes, or | we were able to match *obj* exactly to one or more adjacent nodes, or | ||||
@@ -212,19 +212,19 @@ class Wikicode(StringMixIn): | |||||
def _build_filter_methods(cls, **meths): | def _build_filter_methods(cls, **meths): | ||||
"""Given Node types, build the corresponding i?filter shortcuts. | """Given Node types, build the corresponding i?filter shortcuts. | ||||
The should be given as keys storing the method's base name paired | |||||
with values storing the corresponding :py:class:`~.Node` type. For | |||||
example, the dict may contain the pair ``("templates", Template)``, | |||||
which will produce the methods :py:meth:`ifilter_templates` and | |||||
:py:meth:`filter_templates`, which are shortcuts for | |||||
:py:meth:`ifilter(forcetype=Template) <ifilter>` and | |||||
:py:meth:`filter(forcetype=Template) <filter>`, respectively. These | |||||
The should be given as keys storing the method's base name paired with | |||||
values storing the corresponding :class:`.Node` type. For example, the | |||||
dict may contain the pair ``("templates", Template)``, which will | |||||
produce the methods :meth:`ifilter_templates` and | |||||
:meth:`filter_templates`, which are shortcuts for | |||||
:meth:`ifilter(forcetype=Template) <ifilter>` and | |||||
:meth:`filter(forcetype=Template) <filter>`, respectively. These | |||||
shortcuts are added to the class itself, with an appropriate docstring. | shortcuts are added to the class itself, with an appropriate docstring. | ||||
""" | """ | ||||
doc = """Iterate over {0}. | doc = """Iterate over {0}. | ||||
This is equivalent to :py:meth:`{1}` with *forcetype* set to | |||||
:py:class:`~{2.__module__}.{2.__name__}`. | |||||
This is equivalent to :meth:`{1}` with *forcetype* set to | |||||
:class:`~{2.__module__}.{2.__name__}`. | |||||
""" | """ | ||||
make_ifilter = lambda ftype: (lambda self, *a, **kw: | make_ifilter = lambda ftype: (lambda self, *a, **kw: | ||||
self.ifilter(forcetype=ftype, *a, **kw)) | self.ifilter(forcetype=ftype, *a, **kw)) | ||||
@@ -240,10 +240,10 @@ class Wikicode(StringMixIn): | |||||
@property | @property | ||||
def nodes(self): | def nodes(self): | ||||
"""A list of :py:class:`~.Node` objects. | |||||
"""A list of :class:`.Node` objects. | |||||
This is the internal data actually stored within a | |||||
:py:class:`~.Wikicode` object. | |||||
This is the internal data actually stored within a :class:`.Wikicode` | |||||
object. | |||||
""" | """ | ||||
return self._nodes | return self._nodes | ||||
@@ -260,11 +260,10 @@ class Wikicode(StringMixIn): | |||||
def set(self, index, value): | def set(self, index, value): | ||||
"""Set the ``Node`` at *index* to *value*. | """Set the ``Node`` at *index* to *value*. | ||||
Raises :py:exc:`IndexError` if *index* is out of range, or | |||||
:py:exc:`ValueError` if *value* cannot be coerced into one | |||||
:py:class:`~.Node`. To insert multiple nodes at an index, use | |||||
:py:meth:`get` with either :py:meth:`remove` and :py:meth:`insert` or | |||||
:py:meth:`replace`. | |||||
Raises :exc:`IndexError` if *index* is out of range, or | |||||
:exc:`ValueError` if *value* cannot be coerced into one :class:`.Node`. | |||||
To insert multiple nodes at an index, use :meth:`get` with either | |||||
:meth:`remove` and :meth:`insert` or :meth:`replace`. | |||||
""" | """ | ||||
nodes = parse_anything(value).nodes | nodes = parse_anything(value).nodes | ||||
if len(nodes) > 1: | if len(nodes) > 1: | ||||
@@ -279,7 +278,7 @@ class Wikicode(StringMixIn): | |||||
def index(self, obj, recursive=False): | def index(self, obj, recursive=False): | ||||
"""Return the index of *obj* in the list of nodes. | """Return the index of *obj* in the list of nodes. | ||||
Raises :py:exc:`ValueError` if *obj* is not found. If *recursive* is | |||||
Raises :exc:`ValueError` if *obj* is not found. If *recursive* is | |||||
``True``, we will look in all nodes of ours and their descendants, and | ``True``, we will look in all nodes of ours and their descendants, and | ||||
return the index of our direct descendant node within *our* list of | return the index of our direct descendant node within *our* list of | ||||
nodes. Otherwise, the lookup is done only on direct descendants. | nodes. Otherwise, the lookup is done only on direct descendants. | ||||
@@ -298,9 +297,8 @@ class Wikicode(StringMixIn): | |||||
def insert(self, index, value): | def insert(self, index, value): | ||||
"""Insert *value* at *index* in the list of nodes. | """Insert *value* at *index* in the list of nodes. | ||||
*value* can be anything parsable by :py:func:`.parse_anything`, which | |||||
includes strings or other :py:class:`~.Wikicode` or :py:class:`~.Node` | |||||
objects. | |||||
*value* can be anything parsable by :func:`.parse_anything`, which | |||||
includes strings or other :class:`.Wikicode` or :class:`.Node` objects. | |||||
""" | """ | ||||
nodes = parse_anything(value).nodes | nodes = parse_anything(value).nodes | ||||
for node in reversed(nodes): | for node in reversed(nodes): | ||||
@@ -309,15 +307,14 @@ class Wikicode(StringMixIn): | |||||
def insert_before(self, obj, value, recursive=True): | def insert_before(self, obj, value, recursive=True): | ||||
"""Insert *value* immediately before *obj*. | """Insert *value* immediately before *obj*. | ||||
*obj* can be either a string, a :py:class:`~.Node`, or another | |||||
:py:class:`~.Wikicode` object (as created by :py:meth:`get_sections`, | |||||
for example). If *obj* is a string, we will operate on all instances | |||||
of that string within the code, otherwise only on the specific instance | |||||
given. *value* can be anything parsable by :py:func:`.parse_anything`. | |||||
If *recursive* is ``True``, we will try to find *obj* within our child | |||||
nodes even if it is not a direct descendant of this | |||||
:py:class:`~.Wikicode` object. If *obj* is not found, | |||||
:py:exc:`ValueError` is raised. | |||||
*obj* can be either a string, a :class:`.Node`, or another | |||||
:class:`.Wikicode` object (as created by :meth:`get_sections`, for | |||||
example). If *obj* is a string, we will operate on all instances of | |||||
that string within the code, otherwise only on the specific instance | |||||
given. *value* can be anything parsable by :func:`.parse_anything`. If | |||||
*recursive* is ``True``, we will try to find *obj* within our child | |||||
nodes even if it is not a direct descendant of this :class:`.Wikicode` | |||||
object. If *obj* is not found, :exc:`ValueError` is raised. | |||||
""" | """ | ||||
if isinstance(obj, (Node, Wikicode)): | if isinstance(obj, (Node, Wikicode)): | ||||
context, index = self._do_strong_search(obj, recursive) | context, index = self._do_strong_search(obj, recursive) | ||||
@@ -333,15 +330,14 @@ class Wikicode(StringMixIn): | |||||
def insert_after(self, obj, value, recursive=True): | def insert_after(self, obj, value, recursive=True): | ||||
"""Insert *value* immediately after *obj*. | """Insert *value* immediately after *obj*. | ||||
*obj* can be either a string, a :py:class:`~.Node`, or another | |||||
:py:class:`~.Wikicode` object (as created by :py:meth:`get_sections`, | |||||
for example). If *obj* is a string, we will operate on all instances | |||||
of that string within the code, otherwise only on the specific instance | |||||
given. *value* can be anything parsable by :py:func:`.parse_anything`. | |||||
If *recursive* is ``True``, we will try to find *obj* within our child | |||||
nodes even if it is not a direct descendant of this | |||||
:py:class:`~.Wikicode` object. If *obj* is not found, | |||||
:py:exc:`ValueError` is raised. | |||||
*obj* can be either a string, a :class:`.Node`, or another | |||||
:class:`.Wikicode` object (as created by :meth:`get_sections`, for | |||||
example). If *obj* is a string, we will operate on all instances of | |||||
that string within the code, otherwise only on the specific instance | |||||
given. *value* can be anything parsable by :func:`.parse_anything`. If | |||||
*recursive* is ``True``, we will try to find *obj* within our child | |||||
nodes even if it is not a direct descendant of this :class:`.Wikicode` | |||||
object. If *obj* is not found, :exc:`ValueError` is raised. | |||||
""" | """ | ||||
if isinstance(obj, (Node, Wikicode)): | if isinstance(obj, (Node, Wikicode)): | ||||
context, index = self._do_strong_search(obj, recursive) | context, index = self._do_strong_search(obj, recursive) | ||||
@@ -357,15 +353,14 @@ class Wikicode(StringMixIn): | |||||
def replace(self, obj, value, recursive=True): | def replace(self, obj, value, recursive=True): | ||||
"""Replace *obj* with *value*. | """Replace *obj* with *value*. | ||||
*obj* can be either a string, a :py:class:`~.Node`, or another | |||||
:py:class:`~.Wikicode` object (as created by :py:meth:`get_sections`, | |||||
for example). If *obj* is a string, we will operate on all instances | |||||
of that string within the code, otherwise only on the specific instance | |||||
given. *value* can be anything parsable by :py:func:`.parse_anything`. | |||||
*obj* can be either a string, a :class:`.Node`, or another | |||||
:class:`.Wikicode` object (as created by :meth:`get_sections`, for | |||||
example). If *obj* is a string, we will operate on all instances of | |||||
that string within the code, otherwise only on the specific instance | |||||
given. *value* can be anything parsable by :func:`.parse_anything`. | |||||
If *recursive* is ``True``, we will try to find *obj* within our child | If *recursive* is ``True``, we will try to find *obj* within our child | ||||
nodes even if it is not a direct descendant of this | |||||
:py:class:`~.Wikicode` object. If *obj* is not found, | |||||
:py:exc:`ValueError` is raised. | |||||
nodes even if it is not a direct descendant of this :class:`.Wikicode` | |||||
object. If *obj* is not found, :exc:`ValueError` is raised. | |||||
""" | """ | ||||
if isinstance(obj, (Node, Wikicode)): | if isinstance(obj, (Node, Wikicode)): | ||||
context, index = self._do_strong_search(obj, recursive) | context, index = self._do_strong_search(obj, recursive) | ||||
@@ -384,7 +379,7 @@ class Wikicode(StringMixIn): | |||||
def append(self, value): | def append(self, value): | ||||
"""Insert *value* at the end of the list of nodes. | """Insert *value* at the end of the list of nodes. | ||||
*value* can be anything parsable by :py:func:`.parse_anything`. | |||||
*value* can be anything parsable by :func:`.parse_anything`. | |||||
""" | """ | ||||
nodes = parse_anything(value).nodes | nodes = parse_anything(value).nodes | ||||
for node in nodes: | for node in nodes: | ||||
@@ -393,14 +388,14 @@ class Wikicode(StringMixIn): | |||||
def remove(self, obj, recursive=True): | def remove(self, obj, recursive=True): | ||||
"""Remove *obj* from the list of nodes. | """Remove *obj* from the list of nodes. | ||||
*obj* can be either a string, a :py:class:`~.Node`, or another | |||||
:py:class:`~.Wikicode` object (as created by :py:meth:`get_sections`, | |||||
for example). If *obj* is a string, we will operate on all instances | |||||
of that string within the code, otherwise only on the specific instance | |||||
*obj* can be either a string, a :class:`.Node`, or another | |||||
:class:`.Wikicode` object (as created by :meth:`get_sections`, for | |||||
example). If *obj* is a string, we will operate on all instances of | |||||
that string within the code, otherwise only on the specific instance | |||||
given. If *recursive* is ``True``, we will try to find *obj* within our | given. If *recursive* is ``True``, we will try to find *obj* within our | ||||
child nodes even if it is not a direct descendant of this | child nodes even if it is not a direct descendant of this | ||||
:py:class:`~.Wikicode` object. If *obj* is not found, | |||||
:py:exc:`ValueError` is raised. | |||||
:class:`.Wikicode` object. If *obj* is not found, :exc:`ValueError` is | |||||
raised. | |||||
""" | """ | ||||
if isinstance(obj, (Node, Wikicode)): | if isinstance(obj, (Node, Wikicode)): | ||||
context, index = self._do_strong_search(obj, recursive) | context, index = self._do_strong_search(obj, recursive) | ||||
@@ -417,10 +412,10 @@ class Wikicode(StringMixIn): | |||||
def matches(self, other): | def matches(self, other): | ||||
"""Do a loose equivalency test suitable for comparing page names. | """Do a loose equivalency test suitable for comparing page names. | ||||
*other* can be any string-like object, including | |||||
:py:class:`~.Wikicode`, or a tuple of these. This operation is | |||||
symmetric; both sides are adjusted. Specifically, whitespace and markup | |||||
is stripped and the first letter's case is normalized. Typical usage is | |||||
*other* can be any string-like object, including :class:`.Wikicode`, or | |||||
a tuple of these. This operation is symmetric; both sides are adjusted. | |||||
Specifically, whitespace and markup is stripped and the first letter's | |||||
case is normalized. Typical usage is | |||||
``if template.name.matches("stub"): ...``. | ``if template.name.matches("stub"): ...``. | ||||
""" | """ | ||||
cmp = lambda a, b: (a[0].upper() + a[1:] == b[0].upper() + b[1:] | cmp = lambda a, b: (a[0].upper() + a[1:] == b[0].upper() + b[1:] | ||||
@@ -453,12 +448,12 @@ class Wikicode(StringMixIn): | |||||
["{{foo}}", "{{foo|{{bar}}}}"] | ["{{foo}}", "{{foo|{{bar}}}}"] | ||||
*matches* can be used to further restrict the nodes, either as a | *matches* can be used to further restrict the nodes, either as a | ||||
function (taking a single :py:class:`.Node` and returning a boolean) or | |||||
a regular expression (matched against the node's string representation | |||||
with :py:func:`re.search`). If *matches* is a regex, the flags passed | |||||
to :py:func:`re.search` are :py:const:`re.IGNORECASE`, | |||||
:py:const:`re.DOTALL`, and :py:const:`re.UNICODE`, but custom flags can | |||||
be specified by passing *flags*. | |||||
function (taking a single :class:`.Node` and returning a boolean) or a | |||||
regular expression (matched against the node's string representation | |||||
with :func:`re.search`). If *matches* is a regex, the flags passed to | |||||
:func:`re.search` are :const:`re.IGNORECASE`, :const:`re.DOTALL`, and | |||||
:const:`re.UNICODE`, but custom flags can be specified by passing | |||||
*flags*. | |||||
""" | """ | ||||
gen = self._indexed_ifilter(recursive, matches, flags, forcetype) | gen = self._indexed_ifilter(recursive, matches, flags, forcetype) | ||||
return (node for i, node in gen) | return (node for i, node in gen) | ||||
@@ -466,7 +461,7 @@ class Wikicode(StringMixIn): | |||||
def filter(self, *args, **kwargs): | def filter(self, *args, **kwargs): | ||||
"""Return a list of nodes within our list matching certain conditions. | """Return a list of nodes within our list matching certain conditions. | ||||
This is equivalent to calling :py:func:`list` on :py:meth:`ifilter`. | |||||
This is equivalent to calling :func:`list` on :meth:`ifilter`. | |||||
""" | """ | ||||
return list(self.ifilter(*args, **kwargs)) | return list(self.ifilter(*args, **kwargs)) | ||||
@@ -474,9 +469,9 @@ class Wikicode(StringMixIn): | |||||
include_lead=None, include_headings=True): | include_lead=None, include_headings=True): | ||||
"""Return a list of sections within the page. | """Return a list of sections within the page. | ||||
Sections are returned as :py:class:`~.Wikicode` objects with a shared | |||||
node list (implemented using :py:class:`~.SmartList`) so that changes | |||||
to sections are reflected in the parent Wikicode object. | |||||
Sections are returned as :class:`.Wikicode` objects with a shared node | |||||
list (implemented using :class:`.SmartList`) so that changes to | |||||
sections are reflected in the parent Wikicode object. | |||||
Each section contains all of its subsections, unless *flat* is | Each section contains all of its subsections, unless *flat* is | ||||
``True``. If *levels* is given, it should be a iterable of integers; | ``True``. If *levels* is given, it should be a iterable of integers; | ||||
@@ -484,14 +479,13 @@ class Wikicode(StringMixIn): | |||||
*matches* is given, it should be either a function or a regex; only | *matches* is given, it should be either a function or a regex; only | ||||
sections whose headings match it (without the surrounding equal signs) | sections whose headings match it (without the surrounding equal signs) | ||||
will be included. *flags* can be used to override the default regex | will be included. *flags* can be used to override the default regex | ||||
flags (see :py:meth:`ifilter`) if a regex *matches* is used. | |||||
flags (see :meth:`ifilter`) if a regex *matches* is used. | |||||
If *include_lead* is ``True``, the first, lead section (without a | If *include_lead* is ``True``, the first, lead section (without a | ||||
heading) will be included in the list; ``False`` will not include it; | heading) will be included in the list; ``False`` will not include it; | ||||
the default will include it only if no specific *levels* were given. If | the default will include it only if no specific *levels* were given. If | ||||
*include_headings* is ``True``, the section's beginning | *include_headings* is ``True``, the section's beginning | ||||
:py:class:`~.Heading` object will be included; otherwise, this is | |||||
skipped. | |||||
:class:`.Heading` object will be included; otherwise, this is skipped. | |||||
""" | """ | ||||
title_matcher = self._build_matcher(matches, flags) | title_matcher = self._build_matcher(matches, flags) | ||||
matcher = lambda heading: (title_matcher(heading.title) and | matcher = lambda heading: (title_matcher(heading.title) and | ||||
@@ -540,7 +534,7 @@ class Wikicode(StringMixIn): | |||||
"""Return a rendered string without unprintable code such as templates. | """Return a rendered string without unprintable code such as templates. | ||||
The way a node is stripped is handled by the | The way a node is stripped is handled by the | ||||
:py:meth:`~.Node.__strip__` method of :py:class:`~.Node` objects, which | |||||
:meth:`~.Node.__strip__` method of :class:`.Node` objects, which | |||||
generally return a subset of their nodes or ``None``. For example, | generally return a subset of their nodes or ``None``. For example, | ||||
templates and tags are removed completely, links are stripped to just | templates and tags are removed completely, links are stripped to just | ||||
their display part, headings are stripped to just their title. If | their display part, headings are stripped to just their title. If | ||||
@@ -568,9 +562,9 @@ class Wikicode(StringMixIn): | |||||
"""Return a hierarchical tree representation of the object. | """Return a hierarchical tree representation of the object. | ||||
The representation is a string makes the most sense printed. It is | The representation is a string makes the most sense printed. It is | ||||
built by calling :py:meth:`_get_tree` on the | |||||
:py:class:`~.Wikicode` object and its children recursively. The end | |||||
result may look something like the following:: | |||||
built by calling :meth:`_get_tree` on the :class:`.Wikicode` object and | |||||
its children recursively. The end result may look something like the | |||||
following:: | |||||
>>> text = "Lorem ipsum {{foo|bar|{{baz}}|spam=eggs}}" | >>> text = "Lorem ipsum {{foo|bar|{{baz}}|spam=eggs}}" | ||||
>>> print mwparserfromhell.parse(text).get_tree() | >>> print mwparserfromhell.parse(text).get_tree() | ||||