{ "info": { "author": "anatoly techtonik", "author_email": "techtonik@gmail.com", "bugtrack_url": null, "classifiers": [ "License :: Public Domain", "Topic :: Text Processing" ], "description": "**wikify** your texts! \r\n*micro-framework for text wikification*\r\n\r\ngoals - avoid conflicts between text modifications rules\r\n and be easy to extend and debug\r\n\r\n**author**: anatoly techtonik \r\n**license**: Public Domain\r\n\r\n[![Build Status](https://drone.io/bitbucket.org/techtonik/wikify/status.png)](https://drone.io/bitbucket.org/techtonik/wikify/latest)\r\n\r\n#### the problem and solution\r\n\r\nthis example is pasted from real-word replacement rules of\r\nRoundup issue tracker:\r\n\r\n >>> import re\r\n >>> rules = [\r\n # link to debian bug tracker\r\n (re.compile('debian:\\#(?P\\d+)'),\r\n '\">debian#\\g' ),\r\n\r\n # link to local issue\r\n (re.compile('\\#(?P\\d+)'),\r\n '\">#\\g' ),\r\n ]\r\n >>> text = \"debian:#222\"\r\n >>> for search, replace in rules:\r\n ... text = search.sub(replace, text)\r\n ...\r\n >>> text\r\n 'debian#222'\r\n\r\nexpected output is:\r\n\r\n 'debian#222'\r\n\r\nthe solution:\r\n\r\n >>> import wikify\r\n >>> wrules = [wikify.RegexpRule(s,r) for s,r in rules]\r\n >>> wikify.wikify(\"debian:#222\", wrules)\r\n 'debian#222'\r\n\r\n\r\n#### usage\r\n\r\n1. define rules that match and process parts of text\r\n2. text = wikify(text, rules)\r\n\r\n`rule` is a function or an object run() method that takes text and\r\nreturns either `None` (means not matched) or this text split into\r\nthree parts [ not-matched, processed, the-rest ]. `processed` part\r\nof text is returned modified by the rule.\r\n\r\nexample of a rule in action:\r\n\r\n >>> import wikify\r\n >>> wikify.rule_link_wikify('wikify your texts!')\r\n ('', 'wikify', ' your texts!')\r\n\r\nand its source code:\r\n\r\n def rule_link_wikify(text):\r\n \"\"\" replace `wikify` text with a link to repository \"\"\"\r\n if not 'wikify' in text:\r\n return None\r\n res = text.split('wikify', 1)\r\n site = 'https://bitbucket.org/techtonik/wikify/'\r\n url = 'wikify' % site\r\n return (res[0], url, res[1])\r\n\r\nusing the rule with wikify to get processed text:\r\n\r\n >>> from wikify import wikify, rule_link_wikify\r\n >>> wikify('wikify your texts!', rule_link_wikify)\r\n 'wikify your texts!'\r\n\r\nyou probably want change url and searched string, so to avoid\r\nrewriting the rule from scratch, **wikify** provides some.\r\n\r\n\r\n#### API\r\n\r\n###### RegexpRule(search, replace=r'\\0')\r\nwikify rule class. `search` is regexp, `replace` can be string\r\nwith backreferences (like \\0, \\1 etc.) or a callable that receives\r\n`re.MatchObject`.\r\n\r\n r = RegexpRule('(\\d+)', '[\\\\1]')\r\n print(wikify('wrap list 1 2 3 45', r))\r\n # wrap list [1] [2] [3] [45]\r\n\r\nin comparison to standard `re.sub`, RegexpRule expands \\0 in\r\nreplacement template to the whole matched string.\r\n\r\n\r\n###### tracker_link_rule(url)\r\nchained function rule (function that returns list of rules) that\r\nreplaces references like #123, issue #123 with link to `url` with\r\nissue number appended.\r\n\r\n w = tracker_link_rule('https://bitbucket.org/techtonik/wikify/issue/')\r\n print(wikify('issue #123, Ᾱ', w))\r\n # issue #123, Ᾱ\r\n\r\n###### wikify(text, rules)\r\n`rules` argument can be a list of rules. **wikify** ensures that text\r\nprocessed by one rule is not reachable by others. if you try to process\r\nsome text without **wikify** with just a series of replacement commands,\r\nthere can be situations when later replacement may affect the text just\r\npasted by previous one. **wikify** was made to prevent this from\r\nhappening.\r\n\r\n\r\n#### using as a Sphinx extension\r\n**wikify** is also a Sphinx extension. the following lines if added\r\nto `conf.py`, will link issue numbers on `changes` page to bugtracker for\r\nthe `sphinx` project:\r\n\r\n extensions = ['wikify']\r\n\r\n # setup wikify extension to convert issue references to links\r\n from wikify import RegexpRule, tracker_link_rule\r\n wikify_html_rules = [\r\n # PR#123 or pull request #123\r\n RegexpRule('(PR|pull request\\s)\\s*#(\\d+)',\r\n '\\\\0'),\r\n # issue #123 or just #123\r\n tracker_link_rule('https://bitbucket.org/birkenfeld/sphinx/issue/')\r\n ]\r\n wikify_html_pages = ['changes']\r\n\r\n\r\n#### operation (flat algorithm)\r\nfor each region\r\n - find region in processed text\r\n - process text matched by region\r\n - exclude processed text from further processing\r\n\r\nnote: (flat algorithm) doesn't process nested markup,\r\nsuch as:\r\n\r\n *`bold preformatted text`*\r\n\r\nexample - replace all wiki:something with HTML links\r\n\r\n - [x] wrap text into list with single item\r\n - [x] split text into three parts using regexp `wiki:\\w+`\r\n - [x] copy 1st part (not-matched) into the resulting list\r\n - [x] replace matched part with link, insert (processed)\r\n into the resulting list\r\n - [ ] process (the-rest) until text list doesn't change\r\n - [x] repeat the above for the rest of rules, skipping\r\n (processed) parts\r\n - [x] reassemble text from the list\r\n\r\n\r\n#### roadmap\r\n- [ ] optimize - measure performance of using indexes\r\n instead of text chunks\r\n- [x] write docs\r\n- [x] upload to PyPI\r\n\r\n\r\n#### history\r\n- 1.5 - fixed major flaw in subst order for single rule\r\n- 1.4 - support named group replacements in RegexpRule\r\n- 1.3 - create_tracker_link_rule to tracker_link_rule\r\n- 1.2 - convert create_regexp_rule to RegexpRule class\r\n- 1.1 - allow rules to be classes (necessary for Sphinx)\r\n- 1.0 - use wikify as Sphinx extension\r\n\r\n- 0.9 - case insensitive match in tracker link rule\r\n- 0.8 - python 3 compatibility\r\n- 0.7 - fixed major flaw in text replacements mapping\r\n- 0.5 - helper to build rules to link tracker references\r\n- 0.6 - flatten nested rule lists\r\n- 0.4 - accept single rule in wikify in addition to list\r\n- 0.3 - allow callables in replacements for regexp rules\r\n- 0.2 - helper to build regexp based rules\r\n- 0.1 - proof of concept, production ready, no API sugar and optimizations", "description_content_type": null, "docs_url": null, "download_url": "UNKNOWN", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "https://bitbucket.org/techtonik/wikify", "keywords": "", "license": "Public Domain", "maintainer": "", "maintainer_email": "", "name": "wikify", "package_url": "https://pypi.org/project/wikify/", "platform": "UNKNOWN", "project_url": "https://pypi.org/project/wikify/", "project_urls": { "Download": "UNKNOWN", "Homepage": "https://bitbucket.org/techtonik/wikify" }, "release_url": "https://pypi.org/project/wikify/1.5/", "requires_dist": null, "requires_python": null, "summary": "wikify your texts! micro-framework for text wikification", "version": "1.5" }, "last_serial": 1060984, "releases": { "1.3": [ { "comment_text": "", "digests": { "md5": "01122f9b1ee2957a489e7b7e6fe7ddfc", "sha256": "2c42fba3fd468c1614b9543dc0eae65937af6ffda6424b2b399400dca51a8586" }, "downloads": -1, "filename": "wikify-1.3.zip", "has_sig": false, "md5_digest": "01122f9b1ee2957a489e7b7e6fe7ddfc", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 8250, "upload_time": "2014-03-21T06:33:24", "url": "https://files.pythonhosted.org/packages/ba/73/e8a749cdf791ab41802527aeb14e0e9e1bed8ac28e6b22c7d5ee4f2c594c/wikify-1.3.zip" } ], "1.4": [ { "comment_text": "", "digests": { "md5": "bcb2f3975470e374d0701678f9eb8aef", "sha256": "3ff089693f1ee5fabd28309395c36728f23cf5a3fe204919dbf97cd1e8bb7950" }, "downloads": -1, "filename": "wikify-1.4.zip", "has_sig": false, "md5_digest": "bcb2f3975470e374d0701678f9eb8aef", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 8918, "upload_time": "2014-04-14T23:00:29", "url": "https://files.pythonhosted.org/packages/65/1a/258d62fed618c611e49310a78d76a7724b157cec2463412d0738b652fb89/wikify-1.4.zip" } ], "1.5": [ { "comment_text": "", "digests": { "md5": "d030ec5a2d497634448462e7065fbb8a", "sha256": "0009c84e7eae012b2c19993fdd35b3129fb865b5eedc3d721b48f2ea150cb765" }, "downloads": -1, "filename": "wikify-1.5.zip", "has_sig": false, "md5_digest": "d030ec5a2d497634448462e7065fbb8a", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 9197, "upload_time": "2014-04-15T11:32:47", "url": "https://files.pythonhosted.org/packages/ae/d4/e7640058d040d24462c9e20d0044b37a6e27ae6c4d7c402d2af25c4ca79a/wikify-1.5.zip" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "d030ec5a2d497634448462e7065fbb8a", "sha256": "0009c84e7eae012b2c19993fdd35b3129fb865b5eedc3d721b48f2ea150cb765" }, "downloads": -1, "filename": "wikify-1.5.zip", "has_sig": false, "md5_digest": "d030ec5a2d497634448462e7065fbb8a", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 9197, "upload_time": "2014-04-15T11:32:47", "url": "https://files.pythonhosted.org/packages/ae/d4/e7640058d040d24462c9e20d0044b37a6e27ae6c4d7c402d2af25c4ca79a/wikify-1.5.zip" } ] }