__init__.py 3.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  1. # $Id: __init__.py 9048 2022-03-29 21:50:15Z milde $
  2. # Author: David Goodger <goodger@python.org>
  3. # Copyright: This module has been placed in the public domain.
  4. """
  5. This package contains Docutils parser modules.
  6. """
  7. __docformat__ = 'reStructuredText'
  8. from importlib import import_module
  9. from docutils import Component, frontend
  10. class Parser(Component):
  11. settings_spec = (
  12. 'Generic Parser Options',
  13. None,
  14. (('Disable directives that insert the contents of an external file; '
  15. 'replaced with a "warning" system message.',
  16. ['--no-file-insertion'],
  17. {'action': 'store_false', 'default': 1,
  18. 'dest': 'file_insertion_enabled',
  19. 'validator': frontend.validate_boolean}),
  20. ('Enable directives that insert the contents '
  21. 'of an external file. (default)',
  22. ['--file-insertion-enabled'],
  23. {'action': 'store_true'}),
  24. ('Disable the "raw" directive; '
  25. 'replaced with a "warning" system message.',
  26. ['--no-raw'],
  27. {'action': 'store_false', 'default': 1, 'dest': 'raw_enabled',
  28. 'validator': frontend.validate_boolean}),
  29. ('Enable the "raw" directive. (default)',
  30. ['--raw-enabled'],
  31. {'action': 'store_true'}),
  32. ('Maximal number of characters in an input line. Default 10 000.',
  33. ['--line-length-limit'],
  34. {'metavar': '<length>', 'type': 'int', 'default': 10000,
  35. 'validator': frontend.validate_nonnegative_int}),
  36. )
  37. )
  38. component_type = 'parser'
  39. config_section = 'parsers'
  40. def parse(self, inputstring, document):
  41. """Override to parse `inputstring` into document tree `document`."""
  42. raise NotImplementedError('subclass must override this method')
  43. def setup_parse(self, inputstring, document):
  44. """Initial parse setup. Call at start of `self.parse()`."""
  45. self.inputstring = inputstring
  46. # provide fallbacks in case the document has only generic settings
  47. document.settings.setdefault('file_insertion_enabled', False)
  48. document.settings.setdefault('raw_enabled', False)
  49. document.settings.setdefault('line_length_limit', 10000)
  50. self.document = document
  51. document.reporter.attach_observer(document.note_parse_message)
  52. def finish_parse(self):
  53. """Finalize parse details. Call at end of `self.parse()`."""
  54. self.document.reporter.detach_observer(
  55. self.document.note_parse_message)
  56. _parser_aliases = { # short names for known parsers
  57. 'null': 'docutils.parsers.null',
  58. # reStructuredText
  59. 'rst': 'docutils.parsers.rst',
  60. 'restructuredtext': 'docutils.parsers.rst',
  61. 'rest': 'docutils.parsers.rst',
  62. 'restx': 'docutils.parsers.rst',
  63. 'rtxt': 'docutils.parsers.rst',
  64. # 3rd-party Markdown parsers
  65. 'recommonmark': 'docutils.parsers.recommonmark_wrapper',
  66. 'myst': 'myst_parser.docutils_',
  67. # 'pycmark': works out of the box
  68. # dispatcher for 3rd-party Markdown parsers
  69. 'commonmark': 'docutils.parsers.commonmark_wrapper',
  70. 'markdown': 'docutils.parsers.commonmark_wrapper',
  71. }
  72. def get_parser_class(parser_name):
  73. """Return the Parser class from the `parser_name` module."""
  74. name = parser_name.lower()
  75. try:
  76. module = import_module(_parser_aliases.get(name, name))
  77. except ImportError as err:
  78. raise ImportError(f'Parser "{parser_name}" not found. {err}')
  79. return module.Parser