A Python parser for MediaWiki wikicode https://mwparserfromhell.readthedocs.io/
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

260 lines
7.3 KiB

  1. # -*- coding: utf-8 -*-
  2. #
  3. # Copyright (C) 2012 Ben Kurtovic <ben.kurtovic@verizon.net>
  4. #
  5. # Permission is hereby granted, free of charge, to any person obtaining a copy
  6. # of this software and associated documentation files (the "Software"), to deal
  7. # in the Software without restriction, including without limitation the rights
  8. # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  9. # copies of the Software, and to permit persons to whom the Software is
  10. # furnished to do so, subject to the following conditions:
  11. #
  12. # The above copyright notice and this permission notice shall be included in
  13. # all copies or substantial portions of the Software.
  14. #
  15. # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  16. # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  17. # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  18. # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  19. # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  20. # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  21. # SOFTWARE.
  22. from __future__ import unicode_literals
  23. from .compat import str, bytes, v
  24. __all__ = ["StringMixIn"]
  25. def inheritdoc(method):
  26. try:
  27. method.__doc__ = getattr(str, method.__name__).__doc__
  28. except AttributeError:
  29. method.__doc__ = "This feature is only available on Python 2."
  30. return method
  31. class StringMixIn(object):
  32. if v >= 3:
  33. def __str__(self):
  34. return self.__unicode__()
  35. else:
  36. def __str__(self):
  37. return self.__unicode__().encode("utf8")
  38. def __repr__(self):
  39. return repr(self.__unicode__())
  40. def __lt__(self, other):
  41. if isinstance(other, StringMixIn):
  42. return self.__unicode__() < other.__unicode__()
  43. return self.__unicode__() < other
  44. def __le__(self, other):
  45. if isinstance(other, StringMixIn):
  46. return self.__unicode__() <= other.__unicode__()
  47. return self.__unicode__() <= other
  48. def __eq__(self, other):
  49. if isinstance(other, StringMixIn):
  50. return self.__unicode__() == other.__unicode__()
  51. return self.__unicode__() == other
  52. def __ne__(self, other):
  53. if isinstance(other, StringMixIn):
  54. return self.__unicode__() != other.__unicode__()
  55. return self.__unicode__() != other
  56. def __gt__(self, other):
  57. if isinstance(other, StringMixIn):
  58. return self.__unicode__() > other.__unicode__()
  59. return self.__unicode__() > other
  60. def __ge__(self, other):
  61. if isinstance(other, StringMixIn):
  62. return self.__unicode__() >= other.__unicode__()
  63. return self.__unicode__() >= other
  64. def __nonzero__(self):
  65. return bool(self.__unicode__())
  66. def __unicode__(self):
  67. raise NotImplementedError()
  68. def __len__(self):
  69. return len(self.__unicode__())
  70. def __iter__(self):
  71. for char in self.__unicode__():
  72. yield char
  73. def __getitem__(self, key):
  74. return self.__unicode__()[key]
  75. def __contains__(self, item):
  76. if isinstance(item, StringMixIn):
  77. return unicode(item) in self.__unicode__()
  78. return item in self.__unicode__()
  79. @inheritdoc
  80. def capitalize(self):
  81. return self.__unicode__().capitalize()
  82. @inheritdoc
  83. def center(self, width, fillchar=None):
  84. return self.__unicode__().center(width, fillchar)
  85. @inheritdoc
  86. def count(self, sub=None, start=None, end=None):
  87. return self.__unicode__().count(sub, start, end)
  88. @inheritdoc
  89. def decode(self, encoding=None, errors=None):
  90. return self.__unicode__().decode(encoding, errors)
  91. @inheritdoc
  92. def encode(self, encoding=None, errors=None):
  93. return self.__unicode__().encode(encoding, errors)
  94. @inheritdoc
  95. def endswith(self, prefix, start=None, end=None):
  96. return self.__unicode__().endswith(prefix, start, end)
  97. @inheritdoc
  98. def expandtabs(self, tabsize=None):
  99. return self.__unicode__().expandtabs(tabsize)
  100. @inheritdoc
  101. def find(self, sub=None, start=None, end=None):
  102. return self.__unicode__().find(sub, start, end)
  103. @inheritdoc
  104. def format(self, *args, **kwargs):
  105. return self.__unicode__().format(*args, **kwargs)
  106. @inheritdoc
  107. def index(self, sub=None, start=None, end=None):
  108. return self.__unicode__().index(sub, start, end)
  109. @inheritdoc
  110. def isalnum(self):
  111. return self.__unicode__().isalnum()
  112. @inheritdoc
  113. def isalpha(self):
  114. return self.__unicode__().isalpha()
  115. @inheritdoc
  116. def isdecimal(self):
  117. return self.__unicode__().isdecimal()
  118. @inheritdoc
  119. def isdigit(self):
  120. return self.__unicode__().isdigit()
  121. @inheritdoc
  122. def islower(self):
  123. return self.__unicode__().islower()
  124. @inheritdoc
  125. def isnumeric(self):
  126. return self.__unicode__().isnumeric()
  127. @inheritdoc
  128. def isspace(self):
  129. return self.__unicode__().isspace()
  130. @inheritdoc
  131. def istitle(self):
  132. return self.__unicode__().istitle()
  133. @inheritdoc
  134. def isupper(self):
  135. return self.__unicode__().isupper()
  136. @inheritdoc
  137. def join(self, iterable):
  138. return self.__unicode__().join(iterable)
  139. @inheritdoc
  140. def ljust(self, width, fillchar=None):
  141. return self.__unicode__().ljust(width, fillchar)
  142. @inheritdoc
  143. def lower(self):
  144. return self.__unicode__().lower()
  145. @inheritdoc
  146. def lstrip(self, chars=None):
  147. return self.__unicode__().lstrip(chars)
  148. @inheritdoc
  149. def partition(self, sep):
  150. return self.__unicode__().partition(sep)
  151. @inheritdoc
  152. def replace(self, old, new, count):
  153. return self.__unicode__().replace(old, new, count)
  154. @inheritdoc
  155. def rfind(self, sub=None, start=None, end=None):
  156. return self.__unicode__().rfind(sub, start, end)
  157. @inheritdoc
  158. def rindex(self, sub=None, start=None, end=None):
  159. return self.__unicode__().rindex(sub, start, end)
  160. @inheritdoc
  161. def rjust(self, width, fillchar=None):
  162. return self.__unicode__().rjust(width, fillchar)
  163. @inheritdoc
  164. def rpartition(self, sep):
  165. return self.__unicode__().rpartition(sep)
  166. @inheritdoc
  167. def rsplit(self, sep=None, maxsplit=None):
  168. return self.__unicode__().rsplit(sep, maxsplit)
  169. @inheritdoc
  170. def rstrip(self, chars=None):
  171. return self.__unicode__().rstrip(chars)
  172. @inheritdoc
  173. def split(self, sep=None, maxsplit=None):
  174. return self.__unicode__().split(sep, maxsplit)
  175. @inheritdoc
  176. def splitlines(self, keepends=None):
  177. return self.__unicode__().splitlines(keepends)
  178. @inheritdoc
  179. def startswith(self, prefix, start=None, end=None):
  180. return self.__unicode__().startswith(prefix, start, end)
  181. @inheritdoc
  182. def strip(self, chars=None):
  183. return self.__unicode__().strip(chars)
  184. @inheritdoc
  185. def swapcase(self):
  186. return self.__unicode__().swapcase()
  187. @inheritdoc
  188. def title(self):
  189. return self.__unicode__().title()
  190. @inheritdoc
  191. def translate(self, table, deletechars=None):
  192. return self.__unicode__().translate(table, deletechars)
  193. @inheritdoc
  194. def upper(self):
  195. return self.__unicode__().upper()
  196. @inheritdoc
  197. def zfill(self, width):
  198. return self.__unicode__().zfill(width)
  199. del inheritdoc