From 4a52a71956a8d46fcb7294ac71734504bb09bcc2 Mon Sep 17 00:00:00 2001 From: S. Solomon Darnell Date: Fri, 28 Mar 2025 21:52:21 -0500 Subject: two version of R2R are here --- .../python3.12/site-packages/docutils/frontend.py | 1065 ++++++++++++++++++++ 1 file changed, 1065 insertions(+) create mode 100644 .venv/lib/python3.12/site-packages/docutils/frontend.py (limited to '.venv/lib/python3.12/site-packages/docutils/frontend.py') diff --git a/.venv/lib/python3.12/site-packages/docutils/frontend.py b/.venv/lib/python3.12/site-packages/docutils/frontend.py new file mode 100644 index 00000000..2499c628 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/docutils/frontend.py @@ -0,0 +1,1065 @@ +# $Id: frontend.py 9540 2024-02-17 10:36:59Z milde $ +# Author: David Goodger +# Copyright: This module has been placed in the public domain. + +""" +Command-line and common processing for Docutils front-end tools. + +This module is provisional. +Major changes will happen with the switch from the deprecated +"optparse" module to "arparse". + +Applications should use the high-level API provided by `docutils.core`. +See https://docutils.sourceforge.io/docs/api/runtime-settings.html. + +Exports the following classes: + +* `OptionParser`: Standard Docutils command-line processing. + Deprecated. Will be replaced by an ArgumentParser. +* `Option`: Customized version of `optparse.Option`; validation support. + Deprecated. Will be removed. +* `Values`: Runtime settings; objects are simple structs + (``object.attribute``). Supports cumulative list settings (attributes). + Deprecated. Will be removed. +* `ConfigParser`: Standard Docutils config file processing. + Provisional. Details will change. + +Also exports the following functions: + +Interface function: + `get_default_settings()`. New in 0.19. + +Option callbacks: + `store_multiple()`, `read_config_file()`. Deprecated. + +Setting validators: + `validate_encoding()`, `validate_encoding_error_handler()`, + `validate_encoding_and_error_handler()`, + `validate_boolean()`, `validate_ternary()`, + `validate_nonnegative_int()`, `validate_threshold()`, + `validate_colon_separated_string_list()`, + `validate_comma_separated_list()`, + `validate_url_trailing_slash()`, + `validate_dependency_file()`, + `validate_strip_class()` + `validate_smartquotes_locales()`. + + Provisional. + +Misc: + `make_paths_absolute()`, `filter_settings_spec()`. Provisional. +""" + +__docformat__ = 'reStructuredText' + + +import codecs +import configparser +import optparse +from optparse import SUPPRESS_HELP +import os +import os.path +from pathlib import Path +import sys +import warnings + +import docutils +from docutils import io, utils + + +def store_multiple(option, opt, value, parser, *args, **kwargs): + """ + Store multiple values in `parser.values`. (Option callback.) + + Store `None` for each attribute named in `args`, and store the value for + each key (attribute name) in `kwargs`. + """ + for attribute in args: + setattr(parser.values, attribute, None) + for key, value in kwargs.items(): + setattr(parser.values, key, value) + + +def read_config_file(option, opt, value, parser): + """ + Read a configuration file during option processing. (Option callback.) + """ + try: + new_settings = parser.get_config_file_settings(value) + except ValueError as err: + parser.error(err) + parser.values.update(new_settings, parser) + + +def validate_encoding(setting, value=None, option_parser=None, + config_parser=None, config_section=None): + # All arguments except `value` are ignored + # (kept for compatibility with "optparse" module). + # If there is only one positional argument, it is interpreted as `value`. + if value is None: + value = setting + if value == '': + return None # allow overwriting a config file value + try: + codecs.lookup(value) + except LookupError: + raise LookupError('setting "%s": unknown encoding: "%s"' + % (setting, value)) + return value + + +def validate_encoding_error_handler(setting, value=None, option_parser=None, + config_parser=None, config_section=None): + # All arguments except `value` are ignored + # (kept for compatibility with "optparse" module). + # If there is only one positional argument, it is interpreted as `value`. + if value is None: + value = setting + try: + codecs.lookup_error(value) + except LookupError: + raise LookupError( + 'unknown encoding error handler: "%s" (choices: ' + '"strict", "ignore", "replace", "backslashreplace", ' + '"xmlcharrefreplace", and possibly others; see documentation for ' + 'the Python ``codecs`` module)' % value) + return value + + +def validate_encoding_and_error_handler( + setting, value, option_parser, config_parser=None, config_section=None): + """ + Side-effect: if an error handler is included in the value, it is inserted + into the appropriate place as if it were a separate setting/option. + """ + if ':' in value: + encoding, handler = value.split(':') + validate_encoding_error_handler(handler) + if config_parser: + config_parser.set(config_section, setting + '_error_handler', + handler) + else: + setattr(option_parser.values, setting + '_error_handler', handler) + else: + encoding = value + return validate_encoding(encoding) + + +def validate_boolean(setting, value=None, option_parser=None, + config_parser=None, config_section=None): + """Check/normalize boolean settings: + True: '1', 'on', 'yes', 'true' + False: '0', 'off', 'no','false', '' + + All arguments except `value` are ignored + (kept for compatibility with "optparse" module). + If there is only one positional argument, it is interpreted as `value`. + """ + if value is None: + value = setting + if isinstance(value, bool): + return value + try: + return OptionParser.booleans[value.strip().lower()] + except KeyError: + raise LookupError('unknown boolean value: "%s"' % value) + + +def validate_ternary(setting, value=None, option_parser=None, + config_parser=None, config_section=None): + """Check/normalize three-value settings: + True: '1', 'on', 'yes', 'true' + False: '0', 'off', 'no','false', '' + any other value: returned as-is. + + All arguments except `value` are ignored + (kept for compatibility with "optparse" module). + If there is only one positional argument, it is interpreted as `value`. + """ + if value is None: + value = setting + if isinstance(value, bool) or value is None: + return value + try: + return OptionParser.booleans[value.strip().lower()] + except KeyError: + return value + + +def validate_nonnegative_int(setting, value=None, option_parser=None, + config_parser=None, config_section=None): + # All arguments except `value` are ignored + # (kept for compatibility with "optparse" module). + # If there is only one positional argument, it is interpreted as `value`. + if value is None: + value = setting + value = int(value) + if value < 0: + raise ValueError('negative value; must be positive or zero') + return value + + +def validate_threshold(setting, value=None, option_parser=None, + config_parser=None, config_section=None): + # All arguments except `value` are ignored + # (kept for compatibility with "optparse" module). + # If there is only one positional argument, it is interpreted as `value`. + if value is None: + value = setting + try: + return int(value) + except ValueError: + try: + return OptionParser.thresholds[value.lower()] + except (KeyError, AttributeError): + raise LookupError('unknown threshold: %r.' % value) + + +def validate_colon_separated_string_list( + setting, value=None, option_parser=None, + config_parser=None, config_section=None): + # All arguments except `value` are ignored + # (kept for compatibility with "optparse" module). + # If there is only one positional argument, it is interpreted as `value`. + if value is None: + value = setting + if not isinstance(value, list): + value = value.split(':') + else: + last = value.pop() + value.extend(last.split(':')) + return value + + +def validate_comma_separated_list(setting, value=None, option_parser=None, + config_parser=None, config_section=None): + """Check/normalize list arguments (split at "," and strip whitespace). + + All arguments except `value` are ignored + (kept for compatibility with "optparse" module). + If there is only one positional argument, it is interpreted as `value`. + """ + if value is None: + value = setting + # `value` may be ``bytes``, ``str``, or a ``list`` (when given as + # command line option and "action" is "append"). + if not isinstance(value, list): + value = [value] + # this function is called for every option added to `value` + # -> split the last item and append the result: + last = value.pop() + items = [i.strip(' \t\n') for i in last.split(',') if i.strip(' \t\n')] + value.extend(items) + return value + + +def validate_math_output(setting, value=None, option_parser=None, + config_parser=None, config_section=None): + """Check "math-output" setting, return list with "format" and "options". + + See also https://docutils.sourceforge.io/docs/user/config.html#math-output + + Argument list for compatibility with "optparse" module. + All arguments except `value` are ignored. + If there is only one positional argument, it is interpreted as `value`. + """ + if value is None: + value = setting + + formats = ('html', 'latex', 'mathml', 'mathjax') + tex2mathml_converters = ('', 'latexml', 'ttm', 'blahtexml', 'pandoc') + + if not value: + return [] + values = value.split(maxsplit=1) + format = values[0].lower() + try: + options = values[1] + except IndexError: + options = '' + if format not in formats: + raise LookupError(f'Unknown math output format: "{value}",\n' + f' choose from {formats}.') + if format == 'mathml': + converter = options.lower() + if converter not in tex2mathml_converters: + raise LookupError(f'MathML converter "{options}" not supported,\n' + f' choose from {tex2mathml_converters}.') + options = converter + return [format, options] + + +def validate_url_trailing_slash(setting, value=None, option_parser=None, + config_parser=None, config_section=None): + # All arguments except `value` are ignored + # (kept for compatibility with "optparse" module). + # If there is only one positional argument, it is interpreted as `value`. + if value is None: + value = setting + if not value: + return './' + elif value.endswith('/'): + return value + else: + return value + '/' + + +def validate_dependency_file(setting, value=None, option_parser=None, + config_parser=None, config_section=None): + # All arguments except `value` are ignored + # (kept for compatibility with "optparse" module). + # If there is only one positional argument, it is interpreted as `value`. + if value is None: + value = setting + try: + return utils.DependencyList(value) + except OSError: + # TODO: warn/info? + return utils.DependencyList(None) + + +def validate_strip_class(setting, value=None, option_parser=None, + config_parser=None, config_section=None): + # All arguments except `value` are ignored + # (kept for compatibility with "optparse" module). + # If there is only one positional argument, it is interpreted as `value`. + if value is None: + value = setting + # value is a comma separated string list: + value = validate_comma_separated_list(value) + # validate list elements: + for cls in value: + normalized = docutils.nodes.make_id(cls) + if cls != normalized: + raise ValueError('Invalid class value %r (perhaps %r?)' + % (cls, normalized)) + return value + + +def validate_smartquotes_locales(setting, value=None, option_parser=None, + config_parser=None, config_section=None): + """Check/normalize a comma separated list of smart quote definitions. + + Return a list of (language-tag, quotes) string tuples. + + All arguments except `value` are ignored + (kept for compatibility with "optparse" module). + If there is only one positional argument, it is interpreted as `value`. + """ + if value is None: + value = setting + # value is a comma separated string list: + value = validate_comma_separated_list(value) + # validate list elements + lc_quotes = [] + for item in value: + try: + lang, quotes = item.split(':', 1) + except AttributeError: + # this function is called for every option added to `value` + # -> ignore if already a tuple: + lc_quotes.append(item) + continue + except ValueError: + raise ValueError('Invalid value "%s".' + ' Format is ":".' + % item.encode('ascii', 'backslashreplace')) + # parse colon separated string list: + quotes = quotes.strip() + multichar_quotes = quotes.split(':') + if len(multichar_quotes) == 4: + quotes = multichar_quotes + elif len(quotes) != 4: + raise ValueError('Invalid value "%s". Please specify 4 quotes\n' + ' (primary open/close; secondary open/close).' + % item.encode('ascii', 'backslashreplace')) + lc_quotes.append((lang, quotes)) + return lc_quotes + + +def make_paths_absolute(pathdict, keys, base_path=None): + """ + Interpret filesystem path settings relative to the `base_path` given. + + Paths are values in `pathdict` whose keys are in `keys`. Get `keys` from + `OptionParser.relative_path_settings`. + """ + if base_path is None: + base_path = Path.cwd() + else: + base_path = Path(base_path) + for key in keys: + if key in pathdict: + value = pathdict[key] + if isinstance(value, list): + value = [str((base_path/path).resolve()) for path in value] + elif value: + value = str((base_path/value).resolve()) + pathdict[key] = value + + +def make_one_path_absolute(base_path, path): + # deprecated, will be removed + warnings.warn('frontend.make_one_path_absolute() will be removed ' + 'in Docutils 0.23.', DeprecationWarning, stacklevel=2) + return os.path.abspath(os.path.join(base_path, path)) + + +def filter_settings_spec(settings_spec, *exclude, **replace): + """Return a copy of `settings_spec` excluding/replacing some settings. + + `settings_spec` is a tuple of configuration settings + (cf. `docutils.SettingsSpec.settings_spec`). + + Optional positional arguments are names of to-be-excluded settings. + Keyword arguments are option specification replacements. + (See the html4strict writer for an example.) + """ + settings = list(settings_spec) + # every third item is a sequence of option tuples + for i in range(2, len(settings), 3): + newopts = [] + for opt_spec in settings[i]: + # opt_spec is ("", [