Skip to main content

MWParserFromHell is a parser for MediaWiki wikicode.

Project description

Build Status Coverage Status

mwparserfromhell (the MediaWiki Parser from Hell) is a Python package that provides an easy-to-use and outrageously powerful parser for MediaWiki wikicode. It supports Python 2 and Python 3.

Developed by Earwig with contributions from Σ, Legoktm, and others. Full documentation is available on ReadTheDocs. Development occurs on GitHub.

Installation

The easiest way to install the parser is through the Python Package Index; you can install the latest release with pip install mwparserfromhell (get pip). Make sure your pip is up-to-date first, especially on Windows.

Alternatively, get the latest development version:

git clone https://github.com/earwig/mwparserfromhell.git
cd mwparserfromhell
python setup.py install

You can run the comprehensive unit testing suite with python setup.py test -q.

Usage

Normal usage is rather straightforward (where text is page text):

>>> import mwparserfromhell
>>> wikicode = mwparserfromhell.parse(text)

wikicode is a mwparserfromhell.Wikicode object, which acts like an ordinary str object (or unicode in Python 2) with some extra methods. For example:

>>> text = "I has a template! {{foo|bar|baz|eggs=spam}} See it?"
>>> wikicode = mwparserfromhell.parse(text)
>>> print(wikicode)
I has a template! {{foo|bar|baz|eggs=spam}} See it?
>>> templates = wikicode.filter_templates()
>>> print(templates)
['{{foo|bar|baz|eggs=spam}}']
>>> template = templates[0]
>>> print(template.name)
foo
>>> print(template.params)
['bar', 'baz', 'eggs=spam']
>>> print(template.get(1).value)
bar
>>> print(template.get("eggs").value)
spam

Since nodes can contain other nodes, getting nested templates is trivial:

>>> text = "{{foo|{{bar}}={{baz|{{spam}}}}}}"
>>> mwparserfromhell.parse(text).filter_templates()
['{{foo|{{bar}}={{baz|{{spam}}}}}}', '{{bar}}', '{{baz|{{spam}}}}', '{{spam}}']

You can also pass recursive=False to filter_templates() and explore templates manually. This is possible because nodes can contain additional Wikicode objects:

>>> code = mwparserfromhell.parse("{{foo|this {{includes a|template}}}}")
>>> print(code.filter_templates(recursive=False))
['{{foo|this {{includes a|template}}}}']
>>> foo = code.filter_templates(recursive=False)[0]
>>> print(foo.get(1).value)
this {{includes a|template}}
>>> print(foo.get(1).value.filter_templates()[0])
{{includes a|template}}
>>> print(foo.get(1).value.filter_templates()[0].get(1).value)
template

Templates can be easily modified to add, remove, or alter params. Wikicode objects can be treated like lists, with append(), insert(), remove(), replace(), and more. They also have a matches() method for comparing page or template names, which takes care of capitalization and whitespace:

>>> text = "{{cleanup}} '''Foo''' is a [[bar]]. {{uncategorized}}"
>>> code = mwparserfromhell.parse(text)
>>> for template in code.filter_templates():
...     if template.name.matches("Cleanup") and not template.has("date"):
...         template.add("date", "July 2012")
...
>>> print(code)
{{cleanup|date=July 2012}} '''Foo''' is a [[bar]]. {{uncategorized}}
>>> code.replace("{{uncategorized}}", "{{bar-stub}}")
>>> print(code)
{{cleanup|date=July 2012}} '''Foo''' is a [[bar]]. {{bar-stub}}
>>> print(code.filter_templates())
['{{cleanup|date=July 2012}}', '{{bar-stub}}']

You can then convert code back into a regular str object (for saving the page!) by calling str() on it:

>>> text = str(code)
>>> print(text)
{{cleanup|date=July 2012}} '''Foo''' is a [[bar]]. {{bar-stub}}
>>> text == code
True

Likewise, use unicode(code) in Python 2.

Limitations

While the MediaWiki parser generates HTML and has access to the contents of templates, among other things, mwparserfromhell acts as a direct interface to the source code only. This has several implications:

  • Syntax elements produced by a template transclusion cannot be detected. For example, imagine a hypothetical page "Template:End-bold" that contained the text </b>. While MediaWiki would correctly understand that <b>foobar{{end-bold}} translates to <b>foobar</b>, mwparserfromhell has no way of examining the contents of {{end-bold}}. Instead, it would treat the bold tag as unfinished, possibly extending further down the page.

  • Templates adjacent to external links, as in http://example.com{{foo}}, are considered part of the link. In reality, this would depend on the contents of the template.

  • When different syntax elements cross over each other, as in {{echo|''Hello}}, world!'', the parser gets confused because this cannot be represented by an ordinary syntax tree. Instead, the parser will treat the first syntax construct as plain text. In this case, only the italic tag would be properly parsed.

    Workaround: Since this commonly occurs with text formatting and text formatting is often not of interest to users, you may pass skip_style_tags=True to mwparserfromhell.parse(). This treats '' and ''' as plain text.

    A future version of mwparserfromhell may include multiple parsing modes to get around this restriction more sensibly.

Additionally, the parser lacks awareness of certain wiki-specific settings:

  • Word-ending links are not supported, since the linktrail rules are language-specific.

  • Localized namespace names aren’t recognized, so file links (such as [[File:...]]) are treated as regular wikilinks.

  • Anything that looks like an XML tag is treated as a tag, even if it is not a recognized tag name, since the list of valid tags depends on loaded MediaWiki extensions.

Integration

mwparserfromhell is used by and originally developed for EarwigBot; Page objects have a parse method that essentially calls mwparserfromhell.parse() on page.get().

If you’re using Pywikibot, your code might look like this:

import mwparserfromhell
import pywikibot

def parse(title):
    site = pywikibot.Site()
    page = pywikibot.Page(site, title)
    text = page.get()
    return mwparserfromhell.parse(text)

If you’re not using a library, you can parse any page using the following Python 3 code (via the API):

import json
from urllib.parse import urlencode
from urllib.request import urlopen
import mwparserfromhell
API_URL = "https://en.wikipedia.org/w/api.php"

def parse(title):
    data = {"action": "query", "prop": "revisions", "rvlimit": 1,
            "rvprop": "content", "format": "json", "titles": title}
    raw = urlopen(API_URL, urlencode(data).encode()).read()
    res = json.loads(raw)
    text = res["query"]["pages"].values()[0]["revisions"][0]["*"]
    return mwparserfromhell.parse(text)

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

mwparserfromhell-0.5.1.tar.gz (132.4 kB view details)

Uploaded Source

Built Distributions

mwparserfromhell-0.5.1-cp36-cp36m-win_amd64.whl (100.8 kB view details)

Uploaded CPython 3.6m Windows x86-64

mwparserfromhell-0.5.1-cp36-cp36m-win32.whl (97.0 kB view details)

Uploaded CPython 3.6m Windows x86

mwparserfromhell-0.5.1-cp35-cp35m-win_amd64.whl (100.8 kB view details)

Uploaded CPython 3.5m Windows x86-64

mwparserfromhell-0.5.1-cp35-cp35m-win32.whl (97.0 kB view details)

Uploaded CPython 3.5m Windows x86

mwparserfromhell-0.5.1-cp34-cp34m-win_amd64.whl (96.7 kB view details)

Uploaded CPython 3.4m Windows x86-64

mwparserfromhell-0.5.1-cp34-cp34m-win32.whl (94.7 kB view details)

Uploaded CPython 3.4m Windows x86

mwparserfromhell-0.5.1-cp33-cp33m-win_amd64.whl (96.8 kB view details)

Uploaded CPython 3.3m Windows x86-64

mwparserfromhell-0.5.1-cp33-cp33m-win32.whl (94.7 kB view details)

Uploaded CPython 3.3m Windows x86

mwparserfromhell-0.5.1-cp27-cp27m-win_amd64.whl (96.5 kB view details)

Uploaded CPython 2.7m Windows x86-64

mwparserfromhell-0.5.1-cp27-cp27m-win32.whl (94.1 kB view details)

Uploaded CPython 2.7m Windows x86

File details

Details for the file mwparserfromhell-0.5.1.tar.gz.

File metadata

File hashes

Hashes for mwparserfromhell-0.5.1.tar.gz
Algorithm Hash digest
SHA256 2ab2822ffc965711f5350b44850d2e2d2c5b715acba0116787449475df6ff855
MD5 417973f6fc0d77b3f93980f8a033e225
BLAKE2b-256 97d69251b27defdc89c37f85fe23ad88595c973e70d376b60d9b36086f74b9af

See more details on using hashes here.

File details

Details for the file mwparserfromhell-0.5.1-cp36-cp36m-win_amd64.whl.

File metadata

File hashes

Hashes for mwparserfromhell-0.5.1-cp36-cp36m-win_amd64.whl
Algorithm Hash digest
SHA256 71b22081bec43ac6bd2966506b8422c71a9603d83880aab727e7d0fd0fd0e2d4
MD5 ac62c5ba87f2590c71f65d8f14efcb32
BLAKE2b-256 f9ce2d43287d437dd794fa82fa7135aab0d6809883bbf5e95663664f222a3d7a

See more details on using hashes here.

File details

Details for the file mwparserfromhell-0.5.1-cp36-cp36m-win32.whl.

File metadata

File hashes

Hashes for mwparserfromhell-0.5.1-cp36-cp36m-win32.whl
Algorithm Hash digest
SHA256 6dbeb936d91f5eeb5c92591fb25a9225fab2ba4697d034d246c542f06702f181
MD5 71034d6a3d1aea4ff70889f187fb8e3b
BLAKE2b-256 495419b3ff190a6dd595fca2d808b10ee751b5c34729b2afc6f786a1095eff38

See more details on using hashes here.

File details

Details for the file mwparserfromhell-0.5.1-cp35-cp35m-win_amd64.whl.

File metadata

File hashes

Hashes for mwparserfromhell-0.5.1-cp35-cp35m-win_amd64.whl
Algorithm Hash digest
SHA256 50114436fc3eda52db46daed02848b0bc966ca7c5e6877a3de259df6f1023246
MD5 e03892ebd3ddf6e6a98a682056bacb1b
BLAKE2b-256 4f640733e042a34052572928373d191c263fdc0026b8b342e385b4a706add28a

See more details on using hashes here.

File details

Details for the file mwparserfromhell-0.5.1-cp35-cp35m-win32.whl.

File metadata

File hashes

Hashes for mwparserfromhell-0.5.1-cp35-cp35m-win32.whl
Algorithm Hash digest
SHA256 bbaacf6527b4fcb5485225f5a9b29b65b4edbf3d50aab372f58e80bb920953d9
MD5 30b938c4e74e0f3d5129ea091ab9bb2b
BLAKE2b-256 a5c0bdc78bd14b546eea52998c0c91afa95fc1cc485bbe50dd0d298c8a5a4b35

See more details on using hashes here.

File details

Details for the file mwparserfromhell-0.5.1-cp34-cp34m-win_amd64.whl.

File metadata

File hashes

Hashes for mwparserfromhell-0.5.1-cp34-cp34m-win_amd64.whl
Algorithm Hash digest
SHA256 8d7f2146940c333d5874592903b03e5e709beac526aaff94d01a4cf42397f498
MD5 6f0948ebbfee5b880c09eddf7bf8dff2
BLAKE2b-256 92fbef272f865f188c285eb1acf4db21b8149fd71a6be0c756deb7690c56fa37

See more details on using hashes here.

File details

Details for the file mwparserfromhell-0.5.1-cp34-cp34m-win32.whl.

File metadata

File hashes

Hashes for mwparserfromhell-0.5.1-cp34-cp34m-win32.whl
Algorithm Hash digest
SHA256 3142ff4bafa587013aaf7e23f71ed5fa4e84fc119c1abc02cbaab7571db5691a
MD5 8f2cd592089a988ade7cce19c5e469e3
BLAKE2b-256 6d26ffe34657a4fcc9ad348964a2d358922447e6c2b9c8c19e55cd17318a9e9c

See more details on using hashes here.

File details

Details for the file mwparserfromhell-0.5.1-cp33-cp33m-win_amd64.whl.

File metadata

File hashes

Hashes for mwparserfromhell-0.5.1-cp33-cp33m-win_amd64.whl
Algorithm Hash digest
SHA256 9ef3c5a0927cccad13533d80acff296edf7d6c05a57894b870948e1f3592d92e
MD5 01030c8a0a26b299bb52018de80c3d02
BLAKE2b-256 b269b850afdeedb0710c18efa4b4a9fc4427b9d617390fc2e1552de99dbc86f6

See more details on using hashes here.

File details

Details for the file mwparserfromhell-0.5.1-cp33-cp33m-win32.whl.

File metadata

File hashes

Hashes for mwparserfromhell-0.5.1-cp33-cp33m-win32.whl
Algorithm Hash digest
SHA256 73f536a2514160f9d3186e144e271cc12dfaed129ac9ef5bed623273f5ced4a6
MD5 57bca6e0b496d8208026f18a6f17e394
BLAKE2b-256 0dc53b58a29d71626042564fa0b9a4924708fe61cd277131ecb170fd723ee66f

See more details on using hashes here.

File details

Details for the file mwparserfromhell-0.5.1-cp27-cp27m-win_amd64.whl.

File metadata

File hashes

Hashes for mwparserfromhell-0.5.1-cp27-cp27m-win_amd64.whl
Algorithm Hash digest
SHA256 6e92c89e480c3c7c0533b5177692d899968dd44a2e826065578cfae63997d653
MD5 b7d5e54729bbf816af808b8b271bdbc4
BLAKE2b-256 161d1594b389c80c7aeaae670e4cdd32b7477765c6f51a668dc42f141e9d8c91

See more details on using hashes here.

File details

Details for the file mwparserfromhell-0.5.1-cp27-cp27m-win32.whl.

File metadata

File hashes

Hashes for mwparserfromhell-0.5.1-cp27-cp27m-win32.whl
Algorithm Hash digest
SHA256 c4beaa1c790f19d6f8437be8d9e96dd49ec8146530d2ebe1e2a7d07b1a7c7e17
MD5 f3227e4c258963d3e826cb5b6cff10a2
BLAKE2b-256 7e7b4cb15c5aa88ed04e34d9f8ee1c67c1d81ea1b36e6a2f2238ab8a4569c399

See more details on using hashes here.

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page