first commit

This commit is contained in:
Yura 2024-09-15 15:12:16 +03:00
commit 417e54da96
5696 changed files with 900003 additions and 0 deletions

View file

@ -0,0 +1,861 @@
# $Id: __init__.py 9544 2024-02-17 10:37:45Z milde $
# Author: David Goodger <goodger@python.org>
# Copyright: This module has been placed in the public domain.
"""
Miscellaneous utilities for the documentation utilities.
"""
__docformat__ = 'reStructuredText'
import sys
import os
import os.path
from pathlib import PurePath, Path
import re
import itertools
import warnings
import unicodedata
from docutils import ApplicationError, DataError, __version_info__
from docutils import io, nodes
# for backwards compatibility
from docutils.nodes import unescape # noqa: F401
class SystemMessage(ApplicationError):
def __init__(self, system_message, level):
Exception.__init__(self, system_message.astext())
self.level = level
class SystemMessagePropagation(ApplicationError):
pass
class Reporter:
"""
Info/warning/error reporter and ``system_message`` element generator.
Five levels of system messages are defined, along with corresponding
methods: `debug()`, `info()`, `warning()`, `error()`, and `severe()`.
There is typically one Reporter object per process. A Reporter object is
instantiated with thresholds for reporting (generating warnings) and
halting processing (raising exceptions), a switch to turn debug output on
or off, and an I/O stream for warnings. These are stored as instance
attributes.
When a system message is generated, its level is compared to the stored
thresholds, and a warning or error is generated as appropriate. Debug
messages are produced if the stored debug switch is on, independently of
other thresholds. Message output is sent to the stored warning stream if
not set to ''.
The Reporter class also employs a modified form of the "Observer" pattern
[GoF95]_ to track system messages generated. The `attach_observer` method
should be called before parsing, with a bound method or function which
accepts system messages. The observer can be removed with
`detach_observer`, and another added in its place.
.. [GoF95] Gamma, Helm, Johnson, Vlissides. *Design Patterns: Elements of
Reusable Object-Oriented Software*. Addison-Wesley, Reading, MA, USA,
1995.
"""
levels = 'DEBUG INFO WARNING ERROR SEVERE'.split()
"""List of names for system message levels, indexed by level."""
# system message level constants:
(DEBUG_LEVEL,
INFO_LEVEL,
WARNING_LEVEL,
ERROR_LEVEL,
SEVERE_LEVEL) = range(5)
def __init__(self, source, report_level, halt_level, stream=None,
debug=False, encoding=None, error_handler='backslashreplace'):
"""
:Parameters:
- `source`: The path to or description of the source data.
- `report_level`: The level at or above which warning output will
be sent to `stream`.
- `halt_level`: The level at or above which `SystemMessage`
exceptions will be raised, halting execution.
- `debug`: Show debug (level=0) system messages?
- `stream`: Where warning output is sent. Can be file-like (has a
``.write`` method), a string (file name, opened for writing),
'' (empty string) or `False` (for discarding all stream messages)
or `None` (implies `sys.stderr`; default).
- `encoding`: The output encoding.
- `error_handler`: The error handler for stderr output encoding.
"""
self.source = source
"""The path to or description of the source data."""
self.error_handler = error_handler
"""The character encoding error handler."""
self.debug_flag = debug
"""Show debug (level=0) system messages?"""
self.report_level = report_level
"""The level at or above which warning output will be sent
to `self.stream`."""
self.halt_level = halt_level
"""The level at or above which `SystemMessage` exceptions
will be raised, halting execution."""
if not isinstance(stream, io.ErrorOutput):
stream = io.ErrorOutput(stream, encoding, error_handler)
self.stream = stream
"""Where warning output is sent."""
self.encoding = encoding or getattr(stream, 'encoding', 'ascii')
"""The output character encoding."""
self.observers = []
"""List of bound methods or functions to call with each system_message
created."""
self.max_level = -1
"""The highest level system message generated so far."""
def set_conditions(self, category, report_level, halt_level,
stream=None, debug=False):
warnings.warn('docutils.utils.Reporter.set_conditions() deprecated; '
'Will be removed in Docutils 0.21 or later. '
'Set attributes via configuration settings or directly.',
DeprecationWarning, stacklevel=2)
self.report_level = report_level
self.halt_level = halt_level
if not isinstance(stream, io.ErrorOutput):
stream = io.ErrorOutput(stream, self.encoding, self.error_handler)
self.stream = stream
self.debug_flag = debug
def attach_observer(self, observer):
"""
The `observer` parameter is a function or bound method which takes one
argument, a `nodes.system_message` instance.
"""
self.observers.append(observer)
def detach_observer(self, observer):
self.observers.remove(observer)
def notify_observers(self, message):
for observer in self.observers:
observer(message)
def system_message(self, level, message, *children, **kwargs):
"""
Return a system_message object.
Raise an exception or generate a warning if appropriate.
"""
# `message` can be a `str` or `Exception` instance.
if isinstance(message, Exception):
message = str(message)
attributes = kwargs.copy()
if 'base_node' in kwargs:
source, line = get_source_line(kwargs['base_node'])
del attributes['base_node']
if source is not None:
attributes.setdefault('source', source)
if line is not None:
attributes.setdefault('line', line)
# assert source is not None, "line- but no source-argument"
if 'source' not in attributes:
# 'line' is absolute line number
try:
source, line = self.get_source_and_line(attributes.get('line'))
except AttributeError:
source, line = None, None
if source is not None:
attributes['source'] = source
if line is not None:
attributes['line'] = line
# assert attributes['line'] is not None, (message, kwargs)
# assert attributes['source'] is not None, (message, kwargs)
attributes.setdefault('source', self.source)
msg = nodes.system_message(message, level=level,
type=self.levels[level],
*children, **attributes)
if self.stream and (level >= self.report_level
or self.debug_flag and level == self.DEBUG_LEVEL
or level >= self.halt_level):
self.stream.write(msg.astext() + '\n')
if level >= self.halt_level:
raise SystemMessage(msg, level)
if level > self.DEBUG_LEVEL or self.debug_flag:
self.notify_observers(msg)
self.max_level = max(level, self.max_level)
return msg
def debug(self, *args, **kwargs):
"""
Level-0, "DEBUG": an internal reporting issue. Typically, there is no
effect on the processing. Level-0 system messages are handled
separately from the others.
"""
if self.debug_flag:
return self.system_message(self.DEBUG_LEVEL, *args, **kwargs)
def info(self, *args, **kwargs):
"""
Level-1, "INFO": a minor issue that can be ignored. Typically there is
no effect on processing, and level-1 system messages are not reported.
"""
return self.system_message(self.INFO_LEVEL, *args, **kwargs)
def warning(self, *args, **kwargs):
"""
Level-2, "WARNING": an issue that should be addressed. If ignored,
there may be unpredictable problems with the output.
"""
return self.system_message(self.WARNING_LEVEL, *args, **kwargs)
def error(self, *args, **kwargs):
"""
Level-3, "ERROR": an error that should be addressed. If ignored, the
output will contain errors.
"""
return self.system_message(self.ERROR_LEVEL, *args, **kwargs)
def severe(self, *args, **kwargs):
"""
Level-4, "SEVERE": a severe error that must be addressed. If ignored,
the output will contain severe errors. Typically level-4 system
messages are turned into exceptions which halt processing.
"""
return self.system_message(self.SEVERE_LEVEL, *args, **kwargs)
class ExtensionOptionError(DataError): pass
class BadOptionError(ExtensionOptionError): pass
class BadOptionDataError(ExtensionOptionError): pass
class DuplicateOptionError(ExtensionOptionError): pass
def extract_extension_options(field_list, options_spec):
"""
Return a dictionary mapping extension option names to converted values.
:Parameters:
- `field_list`: A flat field list without field arguments, where each
field body consists of a single paragraph only.
- `options_spec`: Dictionary mapping known option names to a
conversion function such as `int` or `float`.
:Exceptions:
- `KeyError` for unknown option names.
- `ValueError` for invalid option values (raised by the conversion
function).
- `TypeError` for invalid option value types (raised by conversion
function).
- `DuplicateOptionError` for duplicate options.
- `BadOptionError` for invalid fields.
- `BadOptionDataError` for invalid option data (missing name,
missing data, bad quotes, etc.).
"""
option_list = extract_options(field_list)
return assemble_option_dict(option_list, options_spec)
def extract_options(field_list):
"""
Return a list of option (name, value) pairs from field names & bodies.
:Parameter:
`field_list`: A flat field list, where each field name is a single
word and each field body consists of a single paragraph only.
:Exceptions:
- `BadOptionError` for invalid fields.
- `BadOptionDataError` for invalid option data (missing name,
missing data, bad quotes, etc.).
"""
option_list = []
for field in field_list:
if len(field[0].astext().split()) != 1:
raise BadOptionError(
'extension option field name may not contain multiple words')
name = str(field[0].astext().lower())
body = field[1]
if len(body) == 0:
data = None
elif (len(body) > 1
or not isinstance(body[0], nodes.paragraph)
or len(body[0]) != 1
or not isinstance(body[0][0], nodes.Text)):
raise BadOptionDataError(
'extension option field body may contain\n'
'a single paragraph only (option "%s")' % name)
else:
data = body[0][0].astext()
option_list.append((name, data))
return option_list
def assemble_option_dict(option_list, options_spec):
"""
Return a mapping of option names to values.
:Parameters:
- `option_list`: A list of (name, value) pairs (the output of
`extract_options()`).
- `options_spec`: Dictionary mapping known option names to a
conversion function such as `int` or `float`.
:Exceptions:
- `KeyError` for unknown option names.
- `DuplicateOptionError` for duplicate options.
- `ValueError` for invalid option values (raised by conversion
function).
- `TypeError` for invalid option value types (raised by conversion
function).
"""
options = {}
for name, value in option_list:
convertor = options_spec[name] # raises KeyError if unknown
if convertor is None:
raise KeyError(name) # or if explicitly disabled
if name in options:
raise DuplicateOptionError('duplicate option "%s"' % name)
try:
options[name] = convertor(value)
except (ValueError, TypeError) as detail:
raise detail.__class__('(option: "%s"; value: %r)\n%s'
% (name, value, ' '.join(detail.args)))
return options
class NameValueError(DataError): pass
def decode_path(path):
"""
Ensure `path` is Unicode. Return `str` instance.
Decode file/path string in a failsafe manner if not already done.
"""
# TODO: is this still required with Python 3?
if isinstance(path, str):
return path
try:
path = path.decode(sys.getfilesystemencoding(), 'strict')
except AttributeError: # default value None has no decode method
if not path:
return ''
raise ValueError('`path` value must be a String or ``None``, '
f'not {path!r}')
except UnicodeDecodeError:
try:
path = path.decode('utf-8', 'strict')
except UnicodeDecodeError:
path = path.decode('ascii', 'replace')
return path
def extract_name_value(line):
"""
Return a list of (name, value) from a line of the form "name=value ...".
:Exception:
`NameValueError` for invalid input (missing name, missing data, bad
quotes, etc.).
"""
attlist = []
while line:
equals = line.find('=')
if equals == -1:
raise NameValueError('missing "="')
attname = line[:equals].strip()
if equals == 0 or not attname:
raise NameValueError(
'missing attribute name before "="')
line = line[equals+1:].lstrip()
if not line:
raise NameValueError(
'missing value after "%s="' % attname)
if line[0] in '\'"':
endquote = line.find(line[0], 1)
if endquote == -1:
raise NameValueError(
'attribute "%s" missing end quote (%s)'
% (attname, line[0]))
if len(line) > endquote + 1 and line[endquote + 1].strip():
raise NameValueError(
'attribute "%s" end quote (%s) not followed by '
'whitespace' % (attname, line[0]))
data = line[1:endquote]
line = line[endquote+1:].lstrip()
else:
space = line.find(' ')
if space == -1:
data = line
line = ''
else:
data = line[:space]
line = line[space+1:].lstrip()
attlist.append((attname.lower(), data))
return attlist
def new_reporter(source_path, settings):
"""
Return a new Reporter object.
:Parameters:
`source` : string
The path to or description of the source text of the document.
`settings` : optparse.Values object
Runtime settings.
"""
reporter = Reporter(
source_path, settings.report_level, settings.halt_level,
stream=settings.warning_stream, debug=settings.debug,
encoding=settings.error_encoding,
error_handler=settings.error_encoding_error_handler)
return reporter
def new_document(source_path, settings=None):
"""
Return a new empty document object.
:Parameters:
`source_path` : string
The path to or description of the source text of the document.
`settings` : optparse.Values object
Runtime settings. If none are provided, a default core set will
be used. If you will use the document object with any Docutils
components, you must provide their default settings as well.
For example, if parsing rST, at least provide the rst-parser
settings, obtainable as follows:
Defaults for parser component::
settings = docutils.frontend.get_default_settings(
docutils.parsers.rst.Parser)
Defaults and configuration file customizations::
settings = docutils.core.Publisher(
parser=docutils.parsers.rst.Parser).get_settings()
"""
# Import at top of module would lead to circular dependency!
from docutils import frontend
if settings is None:
settings = frontend.get_default_settings()
source_path = decode_path(source_path)
reporter = new_reporter(source_path, settings)
document = nodes.document(settings, reporter, source=source_path)
document.note_source(source_path, -1)
return document
def clean_rcs_keywords(paragraph, keyword_substitutions):
if len(paragraph) == 1 and isinstance(paragraph[0], nodes.Text):
textnode = paragraph[0]
for pattern, substitution in keyword_substitutions:
match = pattern.search(textnode)
if match:
paragraph[0] = nodes.Text(pattern.sub(substitution, textnode))
return
def relative_path(source, target):
"""
Build and return a path to `target`, relative to `source` (both files).
The return value is a `str` suitable to be included in `source`
as a reference to `target`.
:Parameters:
`source` : path-like object or None
Path of a file in the start directory for the relative path
(the file does not need to exist).
The value ``None`` is replaced with "<cwd>/dummy_file".
`target` : path-like object
End point of the returned relative path.
Differences to `os.path.relpath()`:
* Inverse argument order.
* `source` is assumed to be a FILE in the start directory (add a "dummy"
file name to obtain the path relative from a directory)
while `os.path.relpath()` expects a DIRECTORY as `start` argument.
* Always use Posix path separator ("/") for the output.
* Use `os.sep` for parsing the input
(changing the value of `os.sep` is ignored by `os.relpath()`).
* If there is no common prefix, return the absolute path to `target`.
Differences to `pathlib.PurePath.relative_to(other)`:
* pathlib offers an object oriented interface.
* `source` expects path to a FILE while `other` expects a DIRECTORY.
* `target` defaults to the cwd, no default value for `other`.
* `relative_path()` always returns a path (relative or absolute),
while `PurePath.relative_to()` raises a ValueError
if `target` is not a subpath of `other` (no ".." inserted).
"""
source_parts = os.path.abspath(source or type(target)('dummy_file')
).split(os.sep)
target_parts = os.path.abspath(target).split(os.sep)
# Check first 2 parts because '/dir'.split('/') == ['', 'dir']:
if source_parts[:2] != target_parts[:2]:
# Nothing in common between paths.
# Return absolute path, using '/' for URLs:
return '/'.join(target_parts)
source_parts.reverse()
target_parts.reverse()
while (source_parts and target_parts
and source_parts[-1] == target_parts[-1]):
# Remove path components in common:
source_parts.pop()
target_parts.pop()
target_parts.reverse()
parts = ['..'] * (len(source_parts) - 1) + target_parts
return '/'.join(parts)
def get_stylesheet_reference(settings, relative_to=None):
"""
Retrieve a stylesheet reference from the settings object.
Deprecated. Use get_stylesheet_list() instead to
enable specification of multiple stylesheets as a comma-separated
list.
"""
warnings.warn('utils.get_stylesheet_reference()'
' is obsoleted by utils.get_stylesheet_list()'
' and will be removed in Docutils 2.0.',
DeprecationWarning, stacklevel=2)
if settings.stylesheet_path:
assert not settings.stylesheet, (
'stylesheet and stylesheet_path are mutually exclusive.')
if relative_to is None:
relative_to = settings._destination
return relative_path(relative_to, settings.stylesheet_path)
else:
return settings.stylesheet
# Return 'stylesheet' or 'stylesheet_path' arguments as list.
#
# The original settings arguments are kept unchanged: you can test
# with e.g. ``if settings.stylesheet_path: ...``.
#
# Differences to the depracated `get_stylesheet_reference()`:
# * return value is a list
# * no re-writing of the path (and therefore no optional argument)
# (if required, use ``utils.relative_path(source, target)``
# in the calling script)
def get_stylesheet_list(settings):
"""
Retrieve list of stylesheet references from the settings object.
"""
assert not (settings.stylesheet and settings.stylesheet_path), (
'stylesheet and stylesheet_path are mutually exclusive.')
stylesheets = settings.stylesheet_path or settings.stylesheet or []
# programmatically set default may be string with comma separated list:
if not isinstance(stylesheets, list):
stylesheets = [path.strip() for path in stylesheets.split(',')]
if settings.stylesheet_path:
# expand relative paths if found in stylesheet-dirs:
stylesheets = [find_file_in_dirs(path, settings.stylesheet_dirs)
for path in stylesheets]
return stylesheets
def find_file_in_dirs(path, dirs):
"""
Search for `path` in the list of directories `dirs`.
Return the first expansion that matches an existing file.
"""
path = Path(path)
if path.is_absolute():
return path.as_posix()
for d in dirs:
f = Path(d).expanduser() / path
if f.exists():
return f.as_posix()
return path.as_posix()
def get_trim_footnote_ref_space(settings):
"""
Return whether or not to trim footnote space.
If trim_footnote_reference_space is not None, return it.
If trim_footnote_reference_space is None, return False unless the
footnote reference style is 'superscript'.
"""
if settings.setdefault('trim_footnote_reference_space', None) is None:
return getattr(settings, 'footnote_references', None) == 'superscript'
else:
return settings.trim_footnote_reference_space
def get_source_line(node):
"""
Return the "source" and "line" attributes from the `node` given or from
its closest ancestor.
"""
while node:
if node.source or node.line:
return node.source, node.line
node = node.parent
return None, None
def escape2null(text):
"""Return a string with escape-backslashes converted to nulls."""
parts = []
start = 0
while True:
found = text.find('\\', start)
if found == -1:
parts.append(text[start:])
return ''.join(parts)
parts.append(text[start:found])
parts.append('\x00' + text[found+1:found+2])
start = found + 2 # skip character after escape
def split_escaped_whitespace(text):
"""
Split `text` on escaped whitespace (null+space or null+newline).
Return a list of strings.
"""
strings = text.split('\x00 ')
strings = [string.split('\x00\n') for string in strings]
# flatten list of lists of strings to list of strings:
return list(itertools.chain(*strings))
def strip_combining_chars(text):
return ''.join(c for c in text if not unicodedata.combining(c))
def find_combining_chars(text):
"""Return indices of all combining chars in Unicode string `text`.
>>> from docutils.utils import find_combining_chars
>>> find_combining_chars('A t̆ab̆lĕ')
[3, 6, 9]
"""
return [i for i, c in enumerate(text) if unicodedata.combining(c)]
def column_indices(text):
"""Indices of Unicode string `text` when skipping combining characters.
>>> from docutils.utils import column_indices
>>> column_indices('A t̆ab̆lĕ')
[0, 1, 2, 4, 5, 7, 8]
"""
# TODO: account for asian wide chars here instead of using dummy
# replacements in the tableparser?
string_indices = list(range(len(text)))
for index in find_combining_chars(text):
string_indices[index] = None
return [i for i in string_indices if i is not None]
east_asian_widths = {'W': 2, # Wide
'F': 2, # Full-width (wide)
'Na': 1, # Narrow
'H': 1, # Half-width (narrow)
'N': 1, # Neutral (not East Asian, treated as narrow)
'A': 1, # Ambiguous (s/b wide in East Asian context,
} # narrow otherwise, but that doesn't work)
"""Mapping of result codes from `unicodedata.east_asian_widt()` to character
column widths."""
def column_width(text):
"""Return the column width of text.
Correct ``len(text)`` for wide East Asian and combining Unicode chars.
"""
width = sum(east_asian_widths[unicodedata.east_asian_width(c)]
for c in text)
# correction for combining chars:
width -= len(find_combining_chars(text))
return width
def uniq(L):
r = []
for item in L:
if item not in r:
r.append(item)
return r
def normalize_language_tag(tag):
"""Return a list of normalized combinations for a `BCP 47` language tag.
Example:
>>> from docutils.utils import normalize_language_tag
>>> normalize_language_tag('de_AT-1901')
['de-at-1901', 'de-at', 'de-1901', 'de']
>>> normalize_language_tag('de-CH-x_altquot')
['de-ch-x-altquot', 'de-ch', 'de-x-altquot', 'de']
"""
# normalize:
tag = tag.lower().replace('-', '_')
# split (except singletons, which mark the following tag as non-standard):
tag = re.sub(r'_([a-zA-Z0-9])_', r'_\1-', tag)
subtags = [subtag for subtag in tag.split('_')]
base_tag = (subtags.pop(0),)
# find all combinations of subtags
taglist = []
for n in range(len(subtags), 0, -1):
for tags in itertools.combinations(subtags, n):
taglist.append('-'.join(base_tag+tags))
taglist += base_tag
return taglist
def xml_declaration(encoding=None):
"""Return an XML text declaration.
Include an encoding declaration, if `encoding`
is not 'unicode', '', or None.
"""
if encoding and encoding.lower() != 'unicode':
encoding_declaration = f' encoding="{encoding}"'
else:
encoding_declaration = ''
return f'<?xml version="1.0"{encoding_declaration}?>\n'
class DependencyList:
"""
List of dependencies, with file recording support.
Note that the output file is not automatically closed. You have
to explicitly call the close() method.
"""
def __init__(self, output_file=None, dependencies=()):
"""
Initialize the dependency list, automatically setting the
output file to `output_file` (see `set_output()`) and adding
all supplied dependencies.
If output_file is None, no file output is done when calling add().
"""
self.list = []
self.file = None
if output_file:
self.set_output(output_file)
self.add(*dependencies)
def set_output(self, output_file):
"""
Set the output file and clear the list of already added
dependencies.
`output_file` must be a string. The specified file is
immediately overwritten.
If output_file is '-', the output will be written to stdout.
"""
if output_file:
if output_file == '-':
self.file = sys.stdout
else:
self.file = open(output_file, 'w', encoding='utf-8')
def add(self, *paths):
"""
Append `path` to `self.list` unless it is already there.
Also append to `self.file` unless it is already there
or `self.file is `None`.
"""
for path in paths:
if isinstance(path, PurePath):
path = path.as_posix() # use '/' as separator
if path not in self.list:
self.list.append(path)
if self.file is not None:
self.file.write(path+'\n')
def close(self):
"""
Close the output file.
"""
if self.file is not sys.stdout:
self.file.close()
self.file = None
def __repr__(self):
try:
output_file = self.file.name
except AttributeError:
output_file = None
return '%s(%r, %s)' % (self.__class__.__name__, output_file, self.list)
release_level_abbreviations = {
'alpha': 'a',
'beta': 'b',
'candidate': 'rc',
'final': ''}
def version_identifier(version_info=None):
"""
Return a version identifier string built from `version_info`, a
`docutils.VersionInfo` namedtuple instance or compatible tuple. If
`version_info` is not provided, by default return a version identifier
string based on `docutils.__version_info__` (i.e. the current Docutils
version).
"""
if version_info is None:
version_info = __version_info__
if version_info.micro:
micro = '.%s' % version_info.micro
else:
# 0 is omitted:
micro = ''
releaselevel = release_level_abbreviations[version_info.releaselevel]
if version_info.serial:
serial = version_info.serial
else:
# 0 is omitted:
serial = ''
if version_info.release:
dev = ''
else:
dev = '.dev'
version = '%s.%s%s%s%s%s' % (
version_info.major,
version_info.minor,
micro,
releaselevel,
serial,
dev)
return version

View file

@ -0,0 +1,136 @@
# :Author: Georg Brandl; Lea Wiemann; Günter Milde
# :Date: $Date: 2022-11-16 15:01:31 +0100 (Mi, 16. Nov 2022) $
# :Copyright: This module has been placed in the public domain.
"""Lexical analysis of formal languages (i.e. code) using Pygments."""
from docutils import ApplicationError
try:
import pygments
from pygments.lexers import get_lexer_by_name
from pygments.formatters.html import _get_ttype_class
with_pygments = True
except ImportError:
with_pygments = False
# Filter the following token types from the list of class arguments:
unstyled_tokens = ['token', # Token (base token type)
'text', # Token.Text
''] # short name for Token and Text
# (Add, e.g., Token.Punctuation with ``unstyled_tokens += 'punctuation'``.)
class LexerError(ApplicationError):
pass
class Lexer:
"""Parse `code` lines and yield "classified" tokens.
Arguments
code -- string of source code to parse,
language -- formal language the code is written in,
tokennames -- either 'long', 'short', or 'none' (see below).
Merge subsequent tokens of the same token-type.
Iterating over an instance yields the tokens as ``(tokentype, value)``
tuples. The value of `tokennames` configures the naming of the tokentype:
'long': downcased full token type name,
'short': short name defined by pygments.token.STANDARD_TYPES
(= class argument used in pygments html output),
'none': skip lexical analysis.
"""
def __init__(self, code, language, tokennames='short'):
"""
Set up a lexical analyzer for `code` in `language`.
"""
self.code = code
self.language = language
self.tokennames = tokennames
self.lexer = None
# get lexical analyzer for `language`:
if language in ('', 'text') or tokennames == 'none':
return
if not with_pygments:
raise LexerError('Cannot analyze code. '
'Pygments package not found.')
try:
self.lexer = get_lexer_by_name(self.language)
except pygments.util.ClassNotFound:
raise LexerError('Cannot analyze code. '
'No Pygments lexer found for "%s".' % language)
# self.lexer.add_filter('tokenmerge')
# Since version 1.2. (released Jan 01, 2010) Pygments has a
# TokenMergeFilter. # ``self.merge(tokens)`` in __iter__ could
# be replaced by ``self.lexer.add_filter('tokenmerge')`` in __init__.
# However, `merge` below also strips a final newline added by pygments.
#
# self.lexer.add_filter('tokenmerge')
def merge(self, tokens):
"""Merge subsequent tokens of same token-type.
Also strip the final newline (added by pygments).
"""
tokens = iter(tokens)
(lasttype, lastval) = next(tokens)
for ttype, value in tokens:
if ttype is lasttype:
lastval += value
else:
yield lasttype, lastval
(lasttype, lastval) = (ttype, value)
if lastval.endswith('\n'):
lastval = lastval[:-1]
if lastval:
yield lasttype, lastval
def __iter__(self):
"""Parse self.code and yield "classified" tokens.
"""
if self.lexer is None:
yield [], self.code
return
tokens = pygments.lex(self.code, self.lexer)
for tokentype, value in self.merge(tokens):
if self.tokennames == 'long': # long CSS class args
classes = str(tokentype).lower().split('.')
else: # short CSS class args
classes = [_get_ttype_class(tokentype)]
classes = [cls for cls in classes if cls not in unstyled_tokens]
yield classes, value
class NumberLines:
"""Insert linenumber-tokens at the start of every code line.
Arguments
tokens -- iterable of ``(classes, value)`` tuples
startline -- first line number
endline -- last line number
Iterating over an instance yields the tokens with a
``(['ln'], '<the line number>')`` token added for every code line.
Multi-line tokens are split."""
def __init__(self, tokens, startline, endline):
self.tokens = tokens
self.startline = startline
# pad linenumbers, e.g. endline == 100 -> fmt_str = '%3d '
self.fmt_str = '%%%dd ' % len(str(endline))
def __iter__(self):
lineno = self.startline
yield ['ln'], self.fmt_str % lineno
for ttype, value in self.tokens:
lines = value.split('\n')
for line in lines[:-1]:
yield ttype, line + '\n'
lineno += 1
yield ['ln'], self.fmt_str % lineno
yield ttype, lines[-1]

View file

@ -0,0 +1,222 @@
#!/usr/bin/env python3
# :Id: $Id: error_reporting.py 9078 2022-06-17 11:31:40Z milde $
# :Copyright: © 2011 Günter Milde.
# :License: Released under the terms of the `2-Clause BSD license`_, in short:
#
# Copying and distribution of this file, with or without modification,
# are permitted in any medium without royalty provided the copyright
# notice and this notice are preserved.
# This file is offered as-is, without any warranty.
#
# .. _2-Clause BSD license: https://opensource.org/licenses/BSD-2-Clause
"""
Deprecated module to handle Exceptions across Python versions.
.. warning::
This module is deprecated with the end of support for Python 2.7
and will be removed in Docutils 0.21 or later.
Replacements:
| SafeString -> str
| ErrorString -> docutils.io.error_string()
| ErrorOutput -> docutils.io.ErrorOutput
Error reporting should be safe from encoding/decoding errors.
However, implicit conversions of strings and exceptions like
>>> u'%s world: %s' % ('H\xe4llo', Exception(u'H\xe4llo'))
fail in some Python versions:
* In Python <= 2.6, ``unicode(<exception instance>)`` uses
`__str__` and fails with non-ASCII chars in`unicode` arguments.
(work around http://bugs.python.org/issue2517):
* In Python 2, unicode(<exception instance>) fails, with non-ASCII
chars in arguments. (Use case: in some locales, the errstr
argument of IOError contains non-ASCII chars.)
* In Python 2, str(<exception instance>) fails, with non-ASCII chars
in `unicode` arguments.
The `SafeString`, `ErrorString` and `ErrorOutput` classes handle
common exceptions.
"""
import sys
import warnings
from docutils.io import _locale_encoding as locale_encoding # noqa
warnings.warn('The `docutils.utils.error_reporting` module is deprecated '
'and will be removed in Docutils 0.21 or later.\n'
'Details with help("docutils.utils.error_reporting").',
DeprecationWarning, stacklevel=2)
if sys.version_info >= (3, 0):
unicode = str # noqa
class SafeString:
"""
A wrapper providing robust conversion to `str` and `unicode`.
"""
def __init__(self, data, encoding=None, encoding_errors='backslashreplace',
decoding_errors='replace'):
self.data = data
self.encoding = (encoding or getattr(data, 'encoding', None)
or locale_encoding or 'ascii')
self.encoding_errors = encoding_errors
self.decoding_errors = decoding_errors
def __str__(self):
try:
return str(self.data)
except UnicodeEncodeError:
if isinstance(self.data, Exception):
args = [str(SafeString(arg, self.encoding,
self.encoding_errors))
for arg in self.data.args]
return ', '.join(args)
if isinstance(self.data, unicode):
if sys.version_info > (3, 0):
return self.data
else:
return self.data.encode(self.encoding,
self.encoding_errors)
raise
def __unicode__(self):
"""
Return unicode representation of `self.data`.
Try ``unicode(self.data)``, catch `UnicodeError` and
* if `self.data` is an Exception instance, work around
http://bugs.python.org/issue2517 with an emulation of
Exception.__unicode__,
* else decode with `self.encoding` and `self.decoding_errors`.
"""
try:
u = unicode(self.data)
if isinstance(self.data, EnvironmentError):
u = u.replace(": u'", ": '") # normalize filename quoting
return u
except UnicodeError as error: # catch ..Encode.. and ..Decode.. errors
if isinstance(self.data, EnvironmentError):
return "[Errno %s] %s: '%s'" % (
self.data.errno,
SafeString(self.data.strerror, self.encoding,
self.decoding_errors),
SafeString(self.data.filename, self.encoding,
self.decoding_errors))
if isinstance(self.data, Exception):
args = [unicode(SafeString(
arg, self.encoding,
decoding_errors=self.decoding_errors))
for arg in self.data.args]
return u', '.join(args)
if isinstance(error, UnicodeDecodeError):
return unicode(self.data, self.encoding, self.decoding_errors)
raise
class ErrorString(SafeString):
"""
Safely report exception type and message.
"""
def __str__(self):
return '%s: %s' % (self.data.__class__.__name__,
super(ErrorString, self).__str__())
def __unicode__(self):
return u'%s: %s' % (self.data.__class__.__name__,
super(ErrorString, self).__unicode__())
class ErrorOutput:
"""
Wrapper class for file-like error streams with
failsafe de- and encoding of `str`, `bytes`, `unicode` and
`Exception` instances.
"""
def __init__(self, stream=None, encoding=None,
encoding_errors='backslashreplace',
decoding_errors='replace'):
"""
:Parameters:
- `stream`: a file-like object,
a string (path to a file),
`None` (write to `sys.stderr`, default), or
evaluating to `False` (write() requests are ignored).
- `encoding`: `stream` text encoding. Guessed if None.
- `encoding_errors`: how to treat encoding errors.
"""
if stream is None:
stream = sys.stderr
elif not stream:
stream = False
# if `stream` is a file name, open it
elif isinstance(stream, str):
stream = open(stream, 'w')
elif isinstance(stream, unicode):
stream = open(stream.encode(sys.getfilesystemencoding()), 'w')
self.stream = stream
"""Where warning output is sent."""
self.encoding = (encoding or getattr(stream, 'encoding', None)
or locale_encoding or 'ascii')
"""The output character encoding."""
self.encoding_errors = encoding_errors
"""Encoding error handler."""
self.decoding_errors = decoding_errors
"""Decoding error handler."""
def write(self, data):
"""
Write `data` to self.stream. Ignore, if self.stream is False.
`data` can be a `string`, `unicode`, or `Exception` instance.
"""
if self.stream is False:
return
if isinstance(data, Exception):
data = unicode(SafeString(data, self.encoding,
self.encoding_errors,
self.decoding_errors))
try:
self.stream.write(data)
except UnicodeEncodeError:
self.stream.write(data.encode(self.encoding, self.encoding_errors))
except TypeError:
if isinstance(data, unicode): # passed stream may expect bytes
self.stream.write(data.encode(self.encoding,
self.encoding_errors))
return
if self.stream in (sys.stderr, sys.stdout):
self.stream.buffer.write(data) # write bytes to raw stream
else:
self.stream.write(unicode(data, self.encoding,
self.decoding_errors))
def close(self):
"""
Close the error-output stream.
Ignored if the stream is` sys.stderr` or `sys.stdout` or has no
close() method.
"""
if self.stream in (sys.stdout, sys.stderr):
return
try:
self.stream.close()
except AttributeError:
pass

View file

@ -0,0 +1,73 @@
# :Id: $Id: __init__.py 9516 2024-01-15 16:11:08Z milde $
# :Author: Guenter Milde.
# :License: Released under the terms of the `2-Clause BSD license`_, in short:
#
# Copying and distribution of this file, with or without modification,
# are permitted in any medium without royalty provided the copyright
# notice and this notice are preserved.
# This file is offered as-is, without any warranty.
#
# .. _2-Clause BSD license: https://opensource.org/licenses/BSD-2-Clause
"""
This is the Docutils (Python Documentation Utilities) "math" sub-package.
It contains various modules for conversion between different math formats
(LaTeX, MathML, HTML).
:math2html: LaTeX math -> HTML conversion from eLyXer
:latex2mathml: LaTeX math -> presentational MathML
:unichar2tex: Unicode character to LaTeX math translation table
:tex2unichar: LaTeX math to Unicode character translation dictionaries
:mathalphabet2unichar: LaTeX math alphabets to Unicode character translation
:tex2mathml_extern: Wrapper for 3rd party TeX -> MathML converters
"""
# helpers for Docutils math support
# =================================
class MathError(ValueError):
"""Exception for math syntax and math conversion errors.
The additional attribute `details` may hold a list of Docutils
nodes suitable as children for a ``<system_message>``.
"""
def __init__(self, msg, details=[]):
super().__init__(msg)
self.details = details
def toplevel_code(code):
"""Return string (LaTeX math) `code` with environments stripped out."""
chunks = code.split(r'\begin{')
return r'\begin{'.join(chunk.split(r'\end{')[-1]
for chunk in chunks)
def pick_math_environment(code, numbered=False):
"""Return the right math environment to display `code`.
The test simply looks for line-breaks (``\\``) outside environments.
Multi-line formulae are set with ``align``, one-liners with
``equation``.
If `numbered` evaluates to ``False``, the "starred" versions are used
to suppress numbering.
"""
if toplevel_code(code).find(r'\\') >= 0:
env = 'align'
else:
env = 'equation'
if not numbered:
env += '*'
return env
def wrap_math_code(code, as_block):
# Wrap math-code in mode-switching TeX command/environment.
# If `as_block` is True, use environment for displayed equation(s).
if as_block:
env = pick_math_environment(code)
return '\\begin{%s}\n%s\n\\end{%s}' % (env, code, env)
return '$%s$' % code

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,892 @@
#!/usr/bin/env python3
#
# LaTeX math to Unicode symbols translation dictionaries for
# the content of math alphabet commands (\mathtt, \mathbf, ...).
# Generated with ``write_mathalphabet2unichar.py`` from the data in
# http://milde.users.sourceforge.net/LUCR/Math/
#
# :Copyright: © 2024 Günter Milde.
# :License: Released under the terms of the `2-Clause BSD license`__, in short:
#
# Copying and distribution of this file, with or without modification,
# are permitted in any medium without royalty provided the copyright
# notice and this notice are preserved.
# This file is offered as-is, without any warranty.
#
# __ https://opensource.org/licenses/BSD-2-Clause
mathbb = {
'0': '\U0001d7d8', # 𝟘 MATHEMATICAL DOUBLE-STRUCK DIGIT ZERO
'1': '\U0001d7d9', # 𝟙 MATHEMATICAL DOUBLE-STRUCK DIGIT ONE
'2': '\U0001d7da', # 𝟚 MATHEMATICAL DOUBLE-STRUCK DIGIT TWO
'3': '\U0001d7db', # 𝟛 MATHEMATICAL DOUBLE-STRUCK DIGIT THREE
'4': '\U0001d7dc', # 𝟜 MATHEMATICAL DOUBLE-STRUCK DIGIT FOUR
'5': '\U0001d7dd', # 𝟝 MATHEMATICAL DOUBLE-STRUCK DIGIT FIVE
'6': '\U0001d7de', # 𝟞 MATHEMATICAL DOUBLE-STRUCK DIGIT SIX
'7': '\U0001d7df', # 𝟟 MATHEMATICAL DOUBLE-STRUCK DIGIT SEVEN
'8': '\U0001d7e0', # 𝟠 MATHEMATICAL DOUBLE-STRUCK DIGIT EIGHT
'9': '\U0001d7e1', # 𝟡 MATHEMATICAL DOUBLE-STRUCK DIGIT NINE
'A': '\U0001d538', # 𝔸 MATHEMATICAL DOUBLE-STRUCK CAPITAL A
'B': '\U0001d539', # 𝔹 MATHEMATICAL DOUBLE-STRUCK CAPITAL B
'C': '\u2102', # DOUBLE-STRUCK CAPITAL C
'D': '\U0001d53b', # 𝔻 MATHEMATICAL DOUBLE-STRUCK CAPITAL D
'E': '\U0001d53c', # 𝔼 MATHEMATICAL DOUBLE-STRUCK CAPITAL E
'F': '\U0001d53d', # 𝔽 MATHEMATICAL DOUBLE-STRUCK CAPITAL F
'G': '\U0001d53e', # 𝔾 MATHEMATICAL DOUBLE-STRUCK CAPITAL G
'H': '\u210d', # DOUBLE-STRUCK CAPITAL H
'I': '\U0001d540', # 𝕀 MATHEMATICAL DOUBLE-STRUCK CAPITAL I
'J': '\U0001d541', # 𝕁 MATHEMATICAL DOUBLE-STRUCK CAPITAL J
'K': '\U0001d542', # 𝕂 MATHEMATICAL DOUBLE-STRUCK CAPITAL K
'L': '\U0001d543', # 𝕃 MATHEMATICAL DOUBLE-STRUCK CAPITAL L
'M': '\U0001d544', # 𝕄 MATHEMATICAL DOUBLE-STRUCK CAPITAL M
'N': '\u2115', # DOUBLE-STRUCK CAPITAL N
'O': '\U0001d546', # 𝕆 MATHEMATICAL DOUBLE-STRUCK CAPITAL O
'P': '\u2119', # DOUBLE-STRUCK CAPITAL P
'Q': '\u211a', # DOUBLE-STRUCK CAPITAL Q
'R': '\u211d', # DOUBLE-STRUCK CAPITAL R
'S': '\U0001d54a', # 𝕊 MATHEMATICAL DOUBLE-STRUCK CAPITAL S
'T': '\U0001d54b', # 𝕋 MATHEMATICAL DOUBLE-STRUCK CAPITAL T
'U': '\U0001d54c', # 𝕌 MATHEMATICAL DOUBLE-STRUCK CAPITAL U
'V': '\U0001d54d', # 𝕍 MATHEMATICAL DOUBLE-STRUCK CAPITAL V
'W': '\U0001d54e', # 𝕎 MATHEMATICAL DOUBLE-STRUCK CAPITAL W
'X': '\U0001d54f', # 𝕏 MATHEMATICAL DOUBLE-STRUCK CAPITAL X
'Y': '\U0001d550', # 𝕐 MATHEMATICAL DOUBLE-STRUCK CAPITAL Y
'Z': '\u2124', # DOUBLE-STRUCK CAPITAL Z
'a': '\U0001d552', # 𝕒 MATHEMATICAL DOUBLE-STRUCK SMALL A
'b': '\U0001d553', # 𝕓 MATHEMATICAL DOUBLE-STRUCK SMALL B
'c': '\U0001d554', # 𝕔 MATHEMATICAL DOUBLE-STRUCK SMALL C
'd': '\U0001d555', # 𝕕 MATHEMATICAL DOUBLE-STRUCK SMALL D
'e': '\U0001d556', # 𝕖 MATHEMATICAL DOUBLE-STRUCK SMALL E
'f': '\U0001d557', # 𝕗 MATHEMATICAL DOUBLE-STRUCK SMALL F
'g': '\U0001d558', # 𝕘 MATHEMATICAL DOUBLE-STRUCK SMALL G
'h': '\U0001d559', # 𝕙 MATHEMATICAL DOUBLE-STRUCK SMALL H
'i': '\U0001d55a', # 𝕚 MATHEMATICAL DOUBLE-STRUCK SMALL I
'j': '\U0001d55b', # 𝕛 MATHEMATICAL DOUBLE-STRUCK SMALL J
'k': '\U0001d55c', # 𝕜 MATHEMATICAL DOUBLE-STRUCK SMALL K
'l': '\U0001d55d', # 𝕝 MATHEMATICAL DOUBLE-STRUCK SMALL L
'm': '\U0001d55e', # 𝕞 MATHEMATICAL DOUBLE-STRUCK SMALL M
'n': '\U0001d55f', # 𝕟 MATHEMATICAL DOUBLE-STRUCK SMALL N
'o': '\U0001d560', # 𝕠 MATHEMATICAL DOUBLE-STRUCK SMALL O
'p': '\U0001d561', # 𝕡 MATHEMATICAL DOUBLE-STRUCK SMALL P
'q': '\U0001d562', # 𝕢 MATHEMATICAL DOUBLE-STRUCK SMALL Q
'r': '\U0001d563', # 𝕣 MATHEMATICAL DOUBLE-STRUCK SMALL R
's': '\U0001d564', # 𝕤 MATHEMATICAL DOUBLE-STRUCK SMALL S
't': '\U0001d565', # 𝕥 MATHEMATICAL DOUBLE-STRUCK SMALL T
'u': '\U0001d566', # 𝕦 MATHEMATICAL DOUBLE-STRUCK SMALL U
'v': '\U0001d567', # 𝕧 MATHEMATICAL DOUBLE-STRUCK SMALL V
'w': '\U0001d568', # 𝕨 MATHEMATICAL DOUBLE-STRUCK SMALL W
'x': '\U0001d569', # 𝕩 MATHEMATICAL DOUBLE-STRUCK SMALL X
'y': '\U0001d56a', # 𝕪 MATHEMATICAL DOUBLE-STRUCK SMALL Y
'z': '\U0001d56b', # 𝕫 MATHEMATICAL DOUBLE-STRUCK SMALL Z
'Γ': '\u213e', # ℾ DOUBLE-STRUCK CAPITAL GAMMA
'Π': '\u213f', # ℿ DOUBLE-STRUCK CAPITAL PI
'Σ': '\u2140', # ⅀ DOUBLE-STRUCK N-ARY SUMMATION
'γ': '\u213d', # DOUBLE-STRUCK SMALL GAMMA
'π': '\u213c', # ℼ DOUBLE-STRUCK SMALL PI
}
mathbf = {
'0': '\U0001d7ce', # 𝟎 MATHEMATICAL BOLD DIGIT ZERO
'1': '\U0001d7cf', # 𝟏 MATHEMATICAL BOLD DIGIT ONE
'2': '\U0001d7d0', # 𝟐 MATHEMATICAL BOLD DIGIT TWO
'3': '\U0001d7d1', # 𝟑 MATHEMATICAL BOLD DIGIT THREE
'4': '\U0001d7d2', # 𝟒 MATHEMATICAL BOLD DIGIT FOUR
'5': '\U0001d7d3', # 𝟓 MATHEMATICAL BOLD DIGIT FIVE
'6': '\U0001d7d4', # 𝟔 MATHEMATICAL BOLD DIGIT SIX
'7': '\U0001d7d5', # 𝟕 MATHEMATICAL BOLD DIGIT SEVEN
'8': '\U0001d7d6', # 𝟖 MATHEMATICAL BOLD DIGIT EIGHT
'9': '\U0001d7d7', # 𝟗 MATHEMATICAL BOLD DIGIT NINE
'A': '\U0001d400', # 𝐀 MATHEMATICAL BOLD CAPITAL A
'B': '\U0001d401', # 𝐁 MATHEMATICAL BOLD CAPITAL B
'C': '\U0001d402', # 𝐂 MATHEMATICAL BOLD CAPITAL C
'D': '\U0001d403', # 𝐃 MATHEMATICAL BOLD CAPITAL D
'E': '\U0001d404', # 𝐄 MATHEMATICAL BOLD CAPITAL E
'F': '\U0001d405', # 𝐅 MATHEMATICAL BOLD CAPITAL F
'G': '\U0001d406', # 𝐆 MATHEMATICAL BOLD CAPITAL G
'H': '\U0001d407', # 𝐇 MATHEMATICAL BOLD CAPITAL H
'I': '\U0001d408', # 𝐈 MATHEMATICAL BOLD CAPITAL I
'J': '\U0001d409', # 𝐉 MATHEMATICAL BOLD CAPITAL J
'K': '\U0001d40a', # 𝐊 MATHEMATICAL BOLD CAPITAL K
'L': '\U0001d40b', # 𝐋 MATHEMATICAL BOLD CAPITAL L
'M': '\U0001d40c', # 𝐌 MATHEMATICAL BOLD CAPITAL M
'N': '\U0001d40d', # 𝐍 MATHEMATICAL BOLD CAPITAL N
'O': '\U0001d40e', # 𝐎 MATHEMATICAL BOLD CAPITAL O
'P': '\U0001d40f', # 𝐏 MATHEMATICAL BOLD CAPITAL P
'Q': '\U0001d410', # 𝐐 MATHEMATICAL BOLD CAPITAL Q
'R': '\U0001d411', # 𝐑 MATHEMATICAL BOLD CAPITAL R
'S': '\U0001d412', # 𝐒 MATHEMATICAL BOLD CAPITAL S
'T': '\U0001d413', # 𝐓 MATHEMATICAL BOLD CAPITAL T
'U': '\U0001d414', # 𝐔 MATHEMATICAL BOLD CAPITAL U
'V': '\U0001d415', # 𝐕 MATHEMATICAL BOLD CAPITAL V
'W': '\U0001d416', # 𝐖 MATHEMATICAL BOLD CAPITAL W
'X': '\U0001d417', # 𝐗 MATHEMATICAL BOLD CAPITAL X
'Y': '\U0001d418', # 𝐘 MATHEMATICAL BOLD CAPITAL Y
'Z': '\U0001d419', # 𝐙 MATHEMATICAL BOLD CAPITAL Z
'a': '\U0001d41a', # 𝐚 MATHEMATICAL BOLD SMALL A
'b': '\U0001d41b', # 𝐛 MATHEMATICAL BOLD SMALL B
'c': '\U0001d41c', # 𝐜 MATHEMATICAL BOLD SMALL C
'd': '\U0001d41d', # 𝐝 MATHEMATICAL BOLD SMALL D
'e': '\U0001d41e', # 𝐞 MATHEMATICAL BOLD SMALL E
'f': '\U0001d41f', # 𝐟 MATHEMATICAL BOLD SMALL F
'g': '\U0001d420', # 𝐠 MATHEMATICAL BOLD SMALL G
'h': '\U0001d421', # 𝐡 MATHEMATICAL BOLD SMALL H
'i': '\U0001d422', # 𝐢 MATHEMATICAL BOLD SMALL I
'j': '\U0001d423', # 𝐣 MATHEMATICAL BOLD SMALL J
'k': '\U0001d424', # 𝐤 MATHEMATICAL BOLD SMALL K
'l': '\U0001d425', # 𝐥 MATHEMATICAL BOLD SMALL L
'm': '\U0001d426', # 𝐦 MATHEMATICAL BOLD SMALL M
'n': '\U0001d427', # 𝐧 MATHEMATICAL BOLD SMALL N
'o': '\U0001d428', # 𝐨 MATHEMATICAL BOLD SMALL O
'p': '\U0001d429', # 𝐩 MATHEMATICAL BOLD SMALL P
'q': '\U0001d42a', # 𝐪 MATHEMATICAL BOLD SMALL Q
'r': '\U0001d42b', # 𝐫 MATHEMATICAL BOLD SMALL R
's': '\U0001d42c', # 𝐬 MATHEMATICAL BOLD SMALL S
't': '\U0001d42d', # 𝐭 MATHEMATICAL BOLD SMALL T
'u': '\U0001d42e', # 𝐮 MATHEMATICAL BOLD SMALL U
'v': '\U0001d42f', # 𝐯 MATHEMATICAL BOLD SMALL V
'w': '\U0001d430', # 𝐰 MATHEMATICAL BOLD SMALL W
'x': '\U0001d431', # 𝐱 MATHEMATICAL BOLD SMALL X
'y': '\U0001d432', # 𝐲 MATHEMATICAL BOLD SMALL Y
'z': '\U0001d433', # 𝐳 MATHEMATICAL BOLD SMALL Z
'Γ': '\U0001d6aa', # 𝚪 MATHEMATICAL BOLD CAPITAL GAMMA
'Δ': '\U0001d6ab', # 𝚫 MATHEMATICAL BOLD CAPITAL DELTA
'Θ': '\U0001d6af', # 𝚯 MATHEMATICAL BOLD CAPITAL THETA
'Λ': '\U0001d6b2', # 𝚲 MATHEMATICAL BOLD CAPITAL LAMDA
'Ξ': '\U0001d6b5', # 𝚵 MATHEMATICAL BOLD CAPITAL XI
'Π': '\U0001d6b7', # 𝚷 MATHEMATICAL BOLD CAPITAL PI
'Σ': '\U0001d6ba', # 𝚺 MATHEMATICAL BOLD CAPITAL SIGMA
'Υ': '\U0001d6bc', # 𝚼 MATHEMATICAL BOLD CAPITAL UPSILON
'Φ': '\U0001d6bd', # 𝚽 MATHEMATICAL BOLD CAPITAL PHI
'Ψ': '\U0001d6bf', # 𝚿 MATHEMATICAL BOLD CAPITAL PSI
'Ω': '\U0001d6c0', # 𝛀 MATHEMATICAL BOLD CAPITAL OMEGA
'α': '\U0001d6c2', # 𝛂 MATHEMATICAL BOLD SMALL ALPHA
'β': '\U0001d6c3', # 𝛃 MATHEMATICAL BOLD SMALL BETA
'γ': '\U0001d6c4', # 𝛄 MATHEMATICAL BOLD SMALL GAMMA
'δ': '\U0001d6c5', # 𝛅 MATHEMATICAL BOLD SMALL DELTA
'ε': '\U0001d6c6', # 𝛆 MATHEMATICAL BOLD SMALL EPSILON
'ζ': '\U0001d6c7', # 𝛇 MATHEMATICAL BOLD SMALL ZETA
'η': '\U0001d6c8', # 𝛈 MATHEMATICAL BOLD SMALL ETA
'θ': '\U0001d6c9', # 𝛉 MATHEMATICAL BOLD SMALL THETA
'ι': '\U0001d6ca', # 𝛊 MATHEMATICAL BOLD SMALL IOTA
'κ': '\U0001d6cb', # 𝛋 MATHEMATICAL BOLD SMALL KAPPA
'λ': '\U0001d6cc', # 𝛌 MATHEMATICAL BOLD SMALL LAMDA
'μ': '\U0001d6cd', # 𝛍 MATHEMATICAL BOLD SMALL MU
'ν': '\U0001d6ce', # 𝛎 MATHEMATICAL BOLD SMALL NU
'ξ': '\U0001d6cf', # 𝛏 MATHEMATICAL BOLD SMALL XI
'π': '\U0001d6d1', # 𝛑 MATHEMATICAL BOLD SMALL PI
'ρ': '\U0001d6d2', # 𝛒 MATHEMATICAL BOLD SMALL RHO
'ς': '\U0001d6d3', # 𝛓 MATHEMATICAL BOLD SMALL FINAL SIGMA
'σ': '\U0001d6d4', # 𝛔 MATHEMATICAL BOLD SMALL SIGMA
'τ': '\U0001d6d5', # 𝛕 MATHEMATICAL BOLD SMALL TAU
'υ': '\U0001d6d6', # 𝛖 MATHEMATICAL BOLD SMALL UPSILON
'φ': '\U0001d6d7', # 𝛗 MATHEMATICAL BOLD SMALL PHI
'χ': '\U0001d6d8', # 𝛘 MATHEMATICAL BOLD SMALL CHI
'ψ': '\U0001d6d9', # 𝛙 MATHEMATICAL BOLD SMALL PSI
'ω': '\U0001d6da', # 𝛚 MATHEMATICAL BOLD SMALL OMEGA
'ϑ': '\U0001d6dd', # 𝛝 MATHEMATICAL BOLD THETA SYMBOL
'ϕ': '\U0001d6df', # 𝛟 MATHEMATICAL BOLD PHI SYMBOL
'ϖ': '\U0001d6e1', # 𝛡 MATHEMATICAL BOLD PI SYMBOL
'Ϝ': '\U0001d7ca', # 𝟊 MATHEMATICAL BOLD CAPITAL DIGAMMA
'ϝ': '\U0001d7cb', # 𝟋 MATHEMATICAL BOLD SMALL DIGAMMA
'ϰ': '\U0001d6de', # 𝛞 MATHEMATICAL BOLD KAPPA SYMBOL
'ϱ': '\U0001d6e0', # 𝛠 MATHEMATICAL BOLD RHO SYMBOL
'ϵ': '\U0001d6dc', # 𝛜 MATHEMATICAL BOLD EPSILON SYMBOL
'': '\U0001d6db', # 𝛛 MATHEMATICAL BOLD PARTIAL DIFFERENTIAL
'': '\U0001d6c1', # 𝛁 MATHEMATICAL BOLD NABLA
}
mathbfit = {
'A': '\U0001d468', # 𝑨 MATHEMATICAL BOLD ITALIC CAPITAL A
'B': '\U0001d469', # 𝑩 MATHEMATICAL BOLD ITALIC CAPITAL B
'C': '\U0001d46a', # 𝑪 MATHEMATICAL BOLD ITALIC CAPITAL C
'D': '\U0001d46b', # 𝑫 MATHEMATICAL BOLD ITALIC CAPITAL D
'E': '\U0001d46c', # 𝑬 MATHEMATICAL BOLD ITALIC CAPITAL E
'F': '\U0001d46d', # 𝑭 MATHEMATICAL BOLD ITALIC CAPITAL F
'G': '\U0001d46e', # 𝑮 MATHEMATICAL BOLD ITALIC CAPITAL G
'H': '\U0001d46f', # 𝑯 MATHEMATICAL BOLD ITALIC CAPITAL H
'I': '\U0001d470', # 𝑰 MATHEMATICAL BOLD ITALIC CAPITAL I
'J': '\U0001d471', # 𝑱 MATHEMATICAL BOLD ITALIC CAPITAL J
'K': '\U0001d472', # 𝑲 MATHEMATICAL BOLD ITALIC CAPITAL K
'L': '\U0001d473', # 𝑳 MATHEMATICAL BOLD ITALIC CAPITAL L
'M': '\U0001d474', # 𝑴 MATHEMATICAL BOLD ITALIC CAPITAL M
'N': '\U0001d475', # 𝑵 MATHEMATICAL BOLD ITALIC CAPITAL N
'O': '\U0001d476', # 𝑶 MATHEMATICAL BOLD ITALIC CAPITAL O
'P': '\U0001d477', # 𝑷 MATHEMATICAL BOLD ITALIC CAPITAL P
'Q': '\U0001d478', # 𝑸 MATHEMATICAL BOLD ITALIC CAPITAL Q
'R': '\U0001d479', # 𝑹 MATHEMATICAL BOLD ITALIC CAPITAL R
'S': '\U0001d47a', # 𝑺 MATHEMATICAL BOLD ITALIC CAPITAL S
'T': '\U0001d47b', # 𝑻 MATHEMATICAL BOLD ITALIC CAPITAL T
'U': '\U0001d47c', # 𝑼 MATHEMATICAL BOLD ITALIC CAPITAL U
'V': '\U0001d47d', # 𝑽 MATHEMATICAL BOLD ITALIC CAPITAL V
'W': '\U0001d47e', # 𝑾 MATHEMATICAL BOLD ITALIC CAPITAL W
'X': '\U0001d47f', # 𝑿 MATHEMATICAL BOLD ITALIC CAPITAL X
'Y': '\U0001d480', # 𝒀 MATHEMATICAL BOLD ITALIC CAPITAL Y
'Z': '\U0001d481', # 𝒁 MATHEMATICAL BOLD ITALIC CAPITAL Z
'a': '\U0001d482', # 𝒂 MATHEMATICAL BOLD ITALIC SMALL A
'b': '\U0001d483', # 𝒃 MATHEMATICAL BOLD ITALIC SMALL B
'c': '\U0001d484', # 𝒄 MATHEMATICAL BOLD ITALIC SMALL C
'd': '\U0001d485', # 𝒅 MATHEMATICAL BOLD ITALIC SMALL D
'e': '\U0001d486', # 𝒆 MATHEMATICAL BOLD ITALIC SMALL E
'f': '\U0001d487', # 𝒇 MATHEMATICAL BOLD ITALIC SMALL F
'g': '\U0001d488', # 𝒈 MATHEMATICAL BOLD ITALIC SMALL G
'h': '\U0001d489', # 𝒉 MATHEMATICAL BOLD ITALIC SMALL H
'i': '\U0001d48a', # 𝒊 MATHEMATICAL BOLD ITALIC SMALL I
'j': '\U0001d48b', # 𝒋 MATHEMATICAL BOLD ITALIC SMALL J
'k': '\U0001d48c', # 𝒌 MATHEMATICAL BOLD ITALIC SMALL K
'l': '\U0001d48d', # 𝒍 MATHEMATICAL BOLD ITALIC SMALL L
'm': '\U0001d48e', # 𝒎 MATHEMATICAL BOLD ITALIC SMALL M
'n': '\U0001d48f', # 𝒏 MATHEMATICAL BOLD ITALIC SMALL N
'o': '\U0001d490', # 𝒐 MATHEMATICAL BOLD ITALIC SMALL O
'p': '\U0001d491', # 𝒑 MATHEMATICAL BOLD ITALIC SMALL P
'q': '\U0001d492', # 𝒒 MATHEMATICAL BOLD ITALIC SMALL Q
'r': '\U0001d493', # 𝒓 MATHEMATICAL BOLD ITALIC SMALL R
's': '\U0001d494', # 𝒔 MATHEMATICAL BOLD ITALIC SMALL S
't': '\U0001d495', # 𝒕 MATHEMATICAL BOLD ITALIC SMALL T
'u': '\U0001d496', # 𝒖 MATHEMATICAL BOLD ITALIC SMALL U
'v': '\U0001d497', # 𝒗 MATHEMATICAL BOLD ITALIC SMALL V
'w': '\U0001d498', # 𝒘 MATHEMATICAL BOLD ITALIC SMALL W
'x': '\U0001d499', # 𝒙 MATHEMATICAL BOLD ITALIC SMALL X
'y': '\U0001d49a', # 𝒚 MATHEMATICAL BOLD ITALIC SMALL Y
'z': '\U0001d49b', # 𝒛 MATHEMATICAL BOLD ITALIC SMALL Z
'Γ': '\U0001d71e', # 𝜞 MATHEMATICAL BOLD ITALIC CAPITAL GAMMA
'Δ': '\U0001d71f', # 𝜟 MATHEMATICAL BOLD ITALIC CAPITAL DELTA
'Θ': '\U0001d723', # 𝜣 MATHEMATICAL BOLD ITALIC CAPITAL THETA
'Λ': '\U0001d726', # 𝜦 MATHEMATICAL BOLD ITALIC CAPITAL LAMDA
'Ξ': '\U0001d729', # 𝜩 MATHEMATICAL BOLD ITALIC CAPITAL XI
'Π': '\U0001d72b', # 𝜫 MATHEMATICAL BOLD ITALIC CAPITAL PI
'Σ': '\U0001d72e', # 𝜮 MATHEMATICAL BOLD ITALIC CAPITAL SIGMA
'Υ': '\U0001d730', # 𝜰 MATHEMATICAL BOLD ITALIC CAPITAL UPSILON
'Φ': '\U0001d731', # 𝜱 MATHEMATICAL BOLD ITALIC CAPITAL PHI
'Ψ': '\U0001d733', # 𝜳 MATHEMATICAL BOLD ITALIC CAPITAL PSI
'Ω': '\U0001d734', # 𝜴 MATHEMATICAL BOLD ITALIC CAPITAL OMEGA
'α': '\U0001d736', # 𝜶 MATHEMATICAL BOLD ITALIC SMALL ALPHA
'β': '\U0001d737', # 𝜷 MATHEMATICAL BOLD ITALIC SMALL BETA
'γ': '\U0001d738', # 𝜸 MATHEMATICAL BOLD ITALIC SMALL GAMMA
'δ': '\U0001d739', # 𝜹 MATHEMATICAL BOLD ITALIC SMALL DELTA
'ε': '\U0001d73a', # 𝜺 MATHEMATICAL BOLD ITALIC SMALL EPSILON
'ζ': '\U0001d73b', # 𝜻 MATHEMATICAL BOLD ITALIC SMALL ZETA
'η': '\U0001d73c', # 𝜼 MATHEMATICAL BOLD ITALIC SMALL ETA
'θ': '\U0001d73d', # 𝜽 MATHEMATICAL BOLD ITALIC SMALL THETA
'ι': '\U0001d73e', # 𝜾 MATHEMATICAL BOLD ITALIC SMALL IOTA
'κ': '\U0001d73f', # 𝜿 MATHEMATICAL BOLD ITALIC SMALL KAPPA
'λ': '\U0001d740', # 𝝀 MATHEMATICAL BOLD ITALIC SMALL LAMDA
'μ': '\U0001d741', # 𝝁 MATHEMATICAL BOLD ITALIC SMALL MU
'ν': '\U0001d742', # 𝝂 MATHEMATICAL BOLD ITALIC SMALL NU
'ξ': '\U0001d743', # 𝝃 MATHEMATICAL BOLD ITALIC SMALL XI
'π': '\U0001d745', # 𝝅 MATHEMATICAL BOLD ITALIC SMALL PI
'ρ': '\U0001d746', # 𝝆 MATHEMATICAL BOLD ITALIC SMALL RHO
'ς': '\U0001d747', # 𝝇 MATHEMATICAL BOLD ITALIC SMALL FINAL SIGMA
'σ': '\U0001d748', # 𝝈 MATHEMATICAL BOLD ITALIC SMALL SIGMA
'τ': '\U0001d749', # 𝝉 MATHEMATICAL BOLD ITALIC SMALL TAU
'υ': '\U0001d74a', # 𝝊 MATHEMATICAL BOLD ITALIC SMALL UPSILON
'φ': '\U0001d74b', # 𝝋 MATHEMATICAL BOLD ITALIC SMALL PHI
'χ': '\U0001d74c', # 𝝌 MATHEMATICAL BOLD ITALIC SMALL CHI
'ψ': '\U0001d74d', # 𝝍 MATHEMATICAL BOLD ITALIC SMALL PSI
'ω': '\U0001d74e', # 𝝎 MATHEMATICAL BOLD ITALIC SMALL OMEGA
'ϑ': '\U0001d751', # 𝝑 MATHEMATICAL BOLD ITALIC THETA SYMBOL
'ϕ': '\U0001d753', # 𝝓 MATHEMATICAL BOLD ITALIC PHI SYMBOL
'ϖ': '\U0001d755', # 𝝕 MATHEMATICAL BOLD ITALIC PI SYMBOL
'ϰ': '\U0001d752', # 𝝒 MATHEMATICAL BOLD ITALIC KAPPA SYMBOL
'ϱ': '\U0001d754', # 𝝔 MATHEMATICAL BOLD ITALIC RHO SYMBOL
'ϵ': '\U0001d750', # 𝝐 MATHEMATICAL BOLD ITALIC EPSILON SYMBOL
'': '\U0001d74f', # 𝝏 MATHEMATICAL BOLD ITALIC PARTIAL DIFFERENTIAL
'': '\U0001d735', # 𝜵 MATHEMATICAL BOLD ITALIC NABLA
}
mathcal = {
'A': '\U0001d49c', # 𝒜 MATHEMATICAL SCRIPT CAPITAL A
'B': '\u212c', # SCRIPT CAPITAL B
'C': '\U0001d49e', # 𝒞 MATHEMATICAL SCRIPT CAPITAL C
'D': '\U0001d49f', # 𝒟 MATHEMATICAL SCRIPT CAPITAL D
'E': '\u2130', # SCRIPT CAPITAL E
'F': '\u2131', # SCRIPT CAPITAL F
'G': '\U0001d4a2', # 𝒢 MATHEMATICAL SCRIPT CAPITAL G
'H': '\u210b', # SCRIPT CAPITAL H
'I': '\u2110', # SCRIPT CAPITAL I
'J': '\U0001d4a5', # 𝒥 MATHEMATICAL SCRIPT CAPITAL J
'K': '\U0001d4a6', # 𝒦 MATHEMATICAL SCRIPT CAPITAL K
'L': '\u2112', # SCRIPT CAPITAL L
'M': '\u2133', # SCRIPT CAPITAL M
'N': '\U0001d4a9', # 𝒩 MATHEMATICAL SCRIPT CAPITAL N
'O': '\U0001d4aa', # 𝒪 MATHEMATICAL SCRIPT CAPITAL O
'P': '\U0001d4ab', # 𝒫 MATHEMATICAL SCRIPT CAPITAL P
'Q': '\U0001d4ac', # 𝒬 MATHEMATICAL SCRIPT CAPITAL Q
'R': '\u211b', # SCRIPT CAPITAL R
'S': '\U0001d4ae', # 𝒮 MATHEMATICAL SCRIPT CAPITAL S
'T': '\U0001d4af', # 𝒯 MATHEMATICAL SCRIPT CAPITAL T
'U': '\U0001d4b0', # 𝒰 MATHEMATICAL SCRIPT CAPITAL U
'V': '\U0001d4b1', # 𝒱 MATHEMATICAL SCRIPT CAPITAL V
'W': '\U0001d4b2', # 𝒲 MATHEMATICAL SCRIPT CAPITAL W
'X': '\U0001d4b3', # 𝒳 MATHEMATICAL SCRIPT CAPITAL X
'Y': '\U0001d4b4', # 𝒴 MATHEMATICAL SCRIPT CAPITAL Y
'Z': '\U0001d4b5', # 𝒵 MATHEMATICAL SCRIPT CAPITAL Z
'a': '\U0001d4b6', # 𝒶 MATHEMATICAL SCRIPT SMALL A
'b': '\U0001d4b7', # 𝒷 MATHEMATICAL SCRIPT SMALL B
'c': '\U0001d4b8', # 𝒸 MATHEMATICAL SCRIPT SMALL C
'd': '\U0001d4b9', # 𝒹 MATHEMATICAL SCRIPT SMALL D
'e': '\u212f', # SCRIPT SMALL E
'f': '\U0001d4bb', # 𝒻 MATHEMATICAL SCRIPT SMALL F
'g': '\u210a', # SCRIPT SMALL G
'h': '\U0001d4bd', # 𝒽 MATHEMATICAL SCRIPT SMALL H
'i': '\U0001d4be', # 𝒾 MATHEMATICAL SCRIPT SMALL I
'j': '\U0001d4bf', # 𝒿 MATHEMATICAL SCRIPT SMALL J
'k': '\U0001d4c0', # 𝓀 MATHEMATICAL SCRIPT SMALL K
'l': '\U0001d4c1', # 𝓁 MATHEMATICAL SCRIPT SMALL L
'm': '\U0001d4c2', # 𝓂 MATHEMATICAL SCRIPT SMALL M
'n': '\U0001d4c3', # 𝓃 MATHEMATICAL SCRIPT SMALL N
'o': '\u2134', # SCRIPT SMALL O
'p': '\U0001d4c5', # 𝓅 MATHEMATICAL SCRIPT SMALL P
'q': '\U0001d4c6', # 𝓆 MATHEMATICAL SCRIPT SMALL Q
'r': '\U0001d4c7', # 𝓇 MATHEMATICAL SCRIPT SMALL R
's': '\U0001d4c8', # 𝓈 MATHEMATICAL SCRIPT SMALL S
't': '\U0001d4c9', # 𝓉 MATHEMATICAL SCRIPT SMALL T
'u': '\U0001d4ca', # 𝓊 MATHEMATICAL SCRIPT SMALL U
'v': '\U0001d4cb', # 𝓋 MATHEMATICAL SCRIPT SMALL V
'w': '\U0001d4cc', # 𝓌 MATHEMATICAL SCRIPT SMALL W
'x': '\U0001d4cd', # 𝓍 MATHEMATICAL SCRIPT SMALL X
'y': '\U0001d4ce', # 𝓎 MATHEMATICAL SCRIPT SMALL Y
'z': '\U0001d4cf', # 𝓏 MATHEMATICAL SCRIPT SMALL Z
}
mathfrak = {
'A': '\U0001d504', # 𝔄 MATHEMATICAL FRAKTUR CAPITAL A
'B': '\U0001d505', # 𝔅 MATHEMATICAL FRAKTUR CAPITAL B
'C': '\u212d', # BLACK-LETTER CAPITAL C
'D': '\U0001d507', # 𝔇 MATHEMATICAL FRAKTUR CAPITAL D
'E': '\U0001d508', # 𝔈 MATHEMATICAL FRAKTUR CAPITAL E
'F': '\U0001d509', # 𝔉 MATHEMATICAL FRAKTUR CAPITAL F
'G': '\U0001d50a', # 𝔊 MATHEMATICAL FRAKTUR CAPITAL G
'H': '\u210c', # BLACK-LETTER CAPITAL H
'I': '\u2111', # BLACK-LETTER CAPITAL I
'J': '\U0001d50d', # 𝔍 MATHEMATICAL FRAKTUR CAPITAL J
'K': '\U0001d50e', # 𝔎 MATHEMATICAL FRAKTUR CAPITAL K
'L': '\U0001d50f', # 𝔏 MATHEMATICAL FRAKTUR CAPITAL L
'M': '\U0001d510', # 𝔐 MATHEMATICAL FRAKTUR CAPITAL M
'N': '\U0001d511', # 𝔑 MATHEMATICAL FRAKTUR CAPITAL N
'O': '\U0001d512', # 𝔒 MATHEMATICAL FRAKTUR CAPITAL O
'P': '\U0001d513', # 𝔓 MATHEMATICAL FRAKTUR CAPITAL P
'Q': '\U0001d514', # 𝔔 MATHEMATICAL FRAKTUR CAPITAL Q
'R': '\u211c', # BLACK-LETTER CAPITAL R
'S': '\U0001d516', # 𝔖 MATHEMATICAL FRAKTUR CAPITAL S
'T': '\U0001d517', # 𝔗 MATHEMATICAL FRAKTUR CAPITAL T
'U': '\U0001d518', # 𝔘 MATHEMATICAL FRAKTUR CAPITAL U
'V': '\U0001d519', # 𝔙 MATHEMATICAL FRAKTUR CAPITAL V
'W': '\U0001d51a', # 𝔚 MATHEMATICAL FRAKTUR CAPITAL W
'X': '\U0001d51b', # 𝔛 MATHEMATICAL FRAKTUR CAPITAL X
'Y': '\U0001d51c', # 𝔜 MATHEMATICAL FRAKTUR CAPITAL Y
'Z': '\u2128', # BLACK-LETTER CAPITAL Z
'a': '\U0001d51e', # 𝔞 MATHEMATICAL FRAKTUR SMALL A
'b': '\U0001d51f', # 𝔟 MATHEMATICAL FRAKTUR SMALL B
'c': '\U0001d520', # 𝔠 MATHEMATICAL FRAKTUR SMALL C
'd': '\U0001d521', # 𝔡 MATHEMATICAL FRAKTUR SMALL D
'e': '\U0001d522', # 𝔢 MATHEMATICAL FRAKTUR SMALL E
'f': '\U0001d523', # 𝔣 MATHEMATICAL FRAKTUR SMALL F
'g': '\U0001d524', # 𝔤 MATHEMATICAL FRAKTUR SMALL G
'h': '\U0001d525', # 𝔥 MATHEMATICAL FRAKTUR SMALL H
'i': '\U0001d526', # 𝔦 MATHEMATICAL FRAKTUR SMALL I
'j': '\U0001d527', # 𝔧 MATHEMATICAL FRAKTUR SMALL J
'k': '\U0001d528', # 𝔨 MATHEMATICAL FRAKTUR SMALL K
'l': '\U0001d529', # 𝔩 MATHEMATICAL FRAKTUR SMALL L
'm': '\U0001d52a', # 𝔪 MATHEMATICAL FRAKTUR SMALL M
'n': '\U0001d52b', # 𝔫 MATHEMATICAL FRAKTUR SMALL N
'o': '\U0001d52c', # 𝔬 MATHEMATICAL FRAKTUR SMALL O
'p': '\U0001d52d', # 𝔭 MATHEMATICAL FRAKTUR SMALL P
'q': '\U0001d52e', # 𝔮 MATHEMATICAL FRAKTUR SMALL Q
'r': '\U0001d52f', # 𝔯 MATHEMATICAL FRAKTUR SMALL R
's': '\U0001d530', # 𝔰 MATHEMATICAL FRAKTUR SMALL S
't': '\U0001d531', # 𝔱 MATHEMATICAL FRAKTUR SMALL T
'u': '\U0001d532', # 𝔲 MATHEMATICAL FRAKTUR SMALL U
'v': '\U0001d533', # 𝔳 MATHEMATICAL FRAKTUR SMALL V
'w': '\U0001d534', # 𝔴 MATHEMATICAL FRAKTUR SMALL W
'x': '\U0001d535', # 𝔵 MATHEMATICAL FRAKTUR SMALL X
'y': '\U0001d536', # 𝔶 MATHEMATICAL FRAKTUR SMALL Y
'z': '\U0001d537', # 𝔷 MATHEMATICAL FRAKTUR SMALL Z
}
mathit = {
'A': '\U0001d434', # 𝐴 MATHEMATICAL ITALIC CAPITAL A
'B': '\U0001d435', # 𝐵 MATHEMATICAL ITALIC CAPITAL B
'C': '\U0001d436', # 𝐶 MATHEMATICAL ITALIC CAPITAL C
'D': '\U0001d437', # 𝐷 MATHEMATICAL ITALIC CAPITAL D
'E': '\U0001d438', # 𝐸 MATHEMATICAL ITALIC CAPITAL E
'F': '\U0001d439', # 𝐹 MATHEMATICAL ITALIC CAPITAL F
'G': '\U0001d43a', # 𝐺 MATHEMATICAL ITALIC CAPITAL G
'H': '\U0001d43b', # 𝐻 MATHEMATICAL ITALIC CAPITAL H
'I': '\U0001d43c', # 𝐼 MATHEMATICAL ITALIC CAPITAL I
'J': '\U0001d43d', # 𝐽 MATHEMATICAL ITALIC CAPITAL J
'K': '\U0001d43e', # 𝐾 MATHEMATICAL ITALIC CAPITAL K
'L': '\U0001d43f', # 𝐿 MATHEMATICAL ITALIC CAPITAL L
'M': '\U0001d440', # 𝑀 MATHEMATICAL ITALIC CAPITAL M
'N': '\U0001d441', # 𝑁 MATHEMATICAL ITALIC CAPITAL N
'O': '\U0001d442', # 𝑂 MATHEMATICAL ITALIC CAPITAL O
'P': '\U0001d443', # 𝑃 MATHEMATICAL ITALIC CAPITAL P
'Q': '\U0001d444', # 𝑄 MATHEMATICAL ITALIC CAPITAL Q
'R': '\U0001d445', # 𝑅 MATHEMATICAL ITALIC CAPITAL R
'S': '\U0001d446', # 𝑆 MATHEMATICAL ITALIC CAPITAL S
'T': '\U0001d447', # 𝑇 MATHEMATICAL ITALIC CAPITAL T
'U': '\U0001d448', # 𝑈 MATHEMATICAL ITALIC CAPITAL U
'V': '\U0001d449', # 𝑉 MATHEMATICAL ITALIC CAPITAL V
'W': '\U0001d44a', # 𝑊 MATHEMATICAL ITALIC CAPITAL W
'X': '\U0001d44b', # 𝑋 MATHEMATICAL ITALIC CAPITAL X
'Y': '\U0001d44c', # 𝑌 MATHEMATICAL ITALIC CAPITAL Y
'Z': '\U0001d44d', # 𝑍 MATHEMATICAL ITALIC CAPITAL Z
'a': '\U0001d44e', # 𝑎 MATHEMATICAL ITALIC SMALL A
'b': '\U0001d44f', # 𝑏 MATHEMATICAL ITALIC SMALL B
'c': '\U0001d450', # 𝑐 MATHEMATICAL ITALIC SMALL C
'd': '\U0001d451', # 𝑑 MATHEMATICAL ITALIC SMALL D
'e': '\U0001d452', # 𝑒 MATHEMATICAL ITALIC SMALL E
'f': '\U0001d453', # 𝑓 MATHEMATICAL ITALIC SMALL F
'g': '\U0001d454', # 𝑔 MATHEMATICAL ITALIC SMALL G
'h': '\u210e', # PLANCK CONSTANT
'i': '\U0001d456', # 𝑖 MATHEMATICAL ITALIC SMALL I
'j': '\U0001d457', # 𝑗 MATHEMATICAL ITALIC SMALL J
'k': '\U0001d458', # 𝑘 MATHEMATICAL ITALIC SMALL K
'l': '\U0001d459', # 𝑙 MATHEMATICAL ITALIC SMALL L
'm': '\U0001d45a', # 𝑚 MATHEMATICAL ITALIC SMALL M
'n': '\U0001d45b', # 𝑛 MATHEMATICAL ITALIC SMALL N
'o': '\U0001d45c', # 𝑜 MATHEMATICAL ITALIC SMALL O
'p': '\U0001d45d', # 𝑝 MATHEMATICAL ITALIC SMALL P
'q': '\U0001d45e', # 𝑞 MATHEMATICAL ITALIC SMALL Q
'r': '\U0001d45f', # 𝑟 MATHEMATICAL ITALIC SMALL R
's': '\U0001d460', # 𝑠 MATHEMATICAL ITALIC SMALL S
't': '\U0001d461', # 𝑡 MATHEMATICAL ITALIC SMALL T
'u': '\U0001d462', # 𝑢 MATHEMATICAL ITALIC SMALL U
'v': '\U0001d463', # 𝑣 MATHEMATICAL ITALIC SMALL V
'w': '\U0001d464', # 𝑤 MATHEMATICAL ITALIC SMALL W
'x': '\U0001d465', # 𝑥 MATHEMATICAL ITALIC SMALL X
'y': '\U0001d466', # 𝑦 MATHEMATICAL ITALIC SMALL Y
'z': '\U0001d467', # 𝑧 MATHEMATICAL ITALIC SMALL Z
'ı': '\U0001d6a4', # 𝚤 MATHEMATICAL ITALIC SMALL DOTLESS I
'ȷ': '\U0001d6a5', # 𝚥 MATHEMATICAL ITALIC SMALL DOTLESS J
'Γ': '\U0001d6e4', # 𝛤 MATHEMATICAL ITALIC CAPITAL GAMMA
'Δ': '\U0001d6e5', # 𝛥 MATHEMATICAL ITALIC CAPITAL DELTA
'Θ': '\U0001d6e9', # 𝛩 MATHEMATICAL ITALIC CAPITAL THETA
'Λ': '\U0001d6ec', # 𝛬 MATHEMATICAL ITALIC CAPITAL LAMDA
'Ξ': '\U0001d6ef', # 𝛯 MATHEMATICAL ITALIC CAPITAL XI
'Π': '\U0001d6f1', # 𝛱 MATHEMATICAL ITALIC CAPITAL PI
'Σ': '\U0001d6f4', # 𝛴 MATHEMATICAL ITALIC CAPITAL SIGMA
'Υ': '\U0001d6f6', # 𝛶 MATHEMATICAL ITALIC CAPITAL UPSILON
'Φ': '\U0001d6f7', # 𝛷 MATHEMATICAL ITALIC CAPITAL PHI
'Ψ': '\U0001d6f9', # 𝛹 MATHEMATICAL ITALIC CAPITAL PSI
'Ω': '\U0001d6fa', # 𝛺 MATHEMATICAL ITALIC CAPITAL OMEGA
'α': '\U0001d6fc', # 𝛼 MATHEMATICAL ITALIC SMALL ALPHA
'β': '\U0001d6fd', # 𝛽 MATHEMATICAL ITALIC SMALL BETA
'γ': '\U0001d6fe', # 𝛾 MATHEMATICAL ITALIC SMALL GAMMA
'δ': '\U0001d6ff', # 𝛿 MATHEMATICAL ITALIC SMALL DELTA
'ε': '\U0001d700', # 𝜀 MATHEMATICAL ITALIC SMALL EPSILON
'ζ': '\U0001d701', # 𝜁 MATHEMATICAL ITALIC SMALL ZETA
'η': '\U0001d702', # 𝜂 MATHEMATICAL ITALIC SMALL ETA
'θ': '\U0001d703', # 𝜃 MATHEMATICAL ITALIC SMALL THETA
'ι': '\U0001d704', # 𝜄 MATHEMATICAL ITALIC SMALL IOTA
'κ': '\U0001d705', # 𝜅 MATHEMATICAL ITALIC SMALL KAPPA
'λ': '\U0001d706', # 𝜆 MATHEMATICAL ITALIC SMALL LAMDA
'μ': '\U0001d707', # 𝜇 MATHEMATICAL ITALIC SMALL MU
'ν': '\U0001d708', # 𝜈 MATHEMATICAL ITALIC SMALL NU
'ξ': '\U0001d709', # 𝜉 MATHEMATICAL ITALIC SMALL XI
'π': '\U0001d70b', # 𝜋 MATHEMATICAL ITALIC SMALL PI
'ρ': '\U0001d70c', # 𝜌 MATHEMATICAL ITALIC SMALL RHO
'ς': '\U0001d70d', # 𝜍 MATHEMATICAL ITALIC SMALL FINAL SIGMA
'σ': '\U0001d70e', # 𝜎 MATHEMATICAL ITALIC SMALL SIGMA
'τ': '\U0001d70f', # 𝜏 MATHEMATICAL ITALIC SMALL TAU
'υ': '\U0001d710', # 𝜐 MATHEMATICAL ITALIC SMALL UPSILON
'φ': '\U0001d711', # 𝜑 MATHEMATICAL ITALIC SMALL PHI
'χ': '\U0001d712', # 𝜒 MATHEMATICAL ITALIC SMALL CHI
'ψ': '\U0001d713', # 𝜓 MATHEMATICAL ITALIC SMALL PSI
'ω': '\U0001d714', # 𝜔 MATHEMATICAL ITALIC SMALL OMEGA
'ϑ': '\U0001d717', # 𝜗 MATHEMATICAL ITALIC THETA SYMBOL
'ϕ': '\U0001d719', # 𝜙 MATHEMATICAL ITALIC PHI SYMBOL
'ϖ': '\U0001d71b', # 𝜛 MATHEMATICAL ITALIC PI SYMBOL
'ϱ': '\U0001d71a', # 𝜚 MATHEMATICAL ITALIC RHO SYMBOL
'ϵ': '\U0001d716', # 𝜖 MATHEMATICAL ITALIC EPSILON SYMBOL
'': '\U0001d715', # 𝜕 MATHEMATICAL ITALIC PARTIAL DIFFERENTIAL
'': '\U0001d6fb', # 𝛻 MATHEMATICAL ITALIC NABLA
}
mathsf = {
'0': '\U0001d7e2', # 𝟢 MATHEMATICAL SANS-SERIF DIGIT ZERO
'1': '\U0001d7e3', # 𝟣 MATHEMATICAL SANS-SERIF DIGIT ONE
'2': '\U0001d7e4', # 𝟤 MATHEMATICAL SANS-SERIF DIGIT TWO
'3': '\U0001d7e5', # 𝟥 MATHEMATICAL SANS-SERIF DIGIT THREE
'4': '\U0001d7e6', # 𝟦 MATHEMATICAL SANS-SERIF DIGIT FOUR
'5': '\U0001d7e7', # 𝟧 MATHEMATICAL SANS-SERIF DIGIT FIVE
'6': '\U0001d7e8', # 𝟨 MATHEMATICAL SANS-SERIF DIGIT SIX
'7': '\U0001d7e9', # 𝟩 MATHEMATICAL SANS-SERIF DIGIT SEVEN
'8': '\U0001d7ea', # 𝟪 MATHEMATICAL SANS-SERIF DIGIT EIGHT
'9': '\U0001d7eb', # 𝟫 MATHEMATICAL SANS-SERIF DIGIT NINE
'A': '\U0001d5a0', # 𝖠 MATHEMATICAL SANS-SERIF CAPITAL A
'B': '\U0001d5a1', # 𝖡 MATHEMATICAL SANS-SERIF CAPITAL B
'C': '\U0001d5a2', # 𝖢 MATHEMATICAL SANS-SERIF CAPITAL C
'D': '\U0001d5a3', # 𝖣 MATHEMATICAL SANS-SERIF CAPITAL D
'E': '\U0001d5a4', # 𝖤 MATHEMATICAL SANS-SERIF CAPITAL E
'F': '\U0001d5a5', # 𝖥 MATHEMATICAL SANS-SERIF CAPITAL F
'G': '\U0001d5a6', # 𝖦 MATHEMATICAL SANS-SERIF CAPITAL G
'H': '\U0001d5a7', # 𝖧 MATHEMATICAL SANS-SERIF CAPITAL H
'I': '\U0001d5a8', # 𝖨 MATHEMATICAL SANS-SERIF CAPITAL I
'J': '\U0001d5a9', # 𝖩 MATHEMATICAL SANS-SERIF CAPITAL J
'K': '\U0001d5aa', # 𝖪 MATHEMATICAL SANS-SERIF CAPITAL K
'L': '\U0001d5ab', # 𝖫 MATHEMATICAL SANS-SERIF CAPITAL L
'M': '\U0001d5ac', # 𝖬 MATHEMATICAL SANS-SERIF CAPITAL M
'N': '\U0001d5ad', # 𝖭 MATHEMATICAL SANS-SERIF CAPITAL N
'O': '\U0001d5ae', # 𝖮 MATHEMATICAL SANS-SERIF CAPITAL O
'P': '\U0001d5af', # 𝖯 MATHEMATICAL SANS-SERIF CAPITAL P
'Q': '\U0001d5b0', # 𝖰 MATHEMATICAL SANS-SERIF CAPITAL Q
'R': '\U0001d5b1', # 𝖱 MATHEMATICAL SANS-SERIF CAPITAL R
'S': '\U0001d5b2', # 𝖲 MATHEMATICAL SANS-SERIF CAPITAL S
'T': '\U0001d5b3', # 𝖳 MATHEMATICAL SANS-SERIF CAPITAL T
'U': '\U0001d5b4', # 𝖴 MATHEMATICAL SANS-SERIF CAPITAL U
'V': '\U0001d5b5', # 𝖵 MATHEMATICAL SANS-SERIF CAPITAL V
'W': '\U0001d5b6', # 𝖶 MATHEMATICAL SANS-SERIF CAPITAL W
'X': '\U0001d5b7', # 𝖷 MATHEMATICAL SANS-SERIF CAPITAL X
'Y': '\U0001d5b8', # 𝖸 MATHEMATICAL SANS-SERIF CAPITAL Y
'Z': '\U0001d5b9', # 𝖹 MATHEMATICAL SANS-SERIF CAPITAL Z
'a': '\U0001d5ba', # 𝖺 MATHEMATICAL SANS-SERIF SMALL A
'b': '\U0001d5bb', # 𝖻 MATHEMATICAL SANS-SERIF SMALL B
'c': '\U0001d5bc', # 𝖼 MATHEMATICAL SANS-SERIF SMALL C
'd': '\U0001d5bd', # 𝖽 MATHEMATICAL SANS-SERIF SMALL D
'e': '\U0001d5be', # 𝖾 MATHEMATICAL SANS-SERIF SMALL E
'f': '\U0001d5bf', # 𝖿 MATHEMATICAL SANS-SERIF SMALL F
'g': '\U0001d5c0', # 𝗀 MATHEMATICAL SANS-SERIF SMALL G
'h': '\U0001d5c1', # 𝗁 MATHEMATICAL SANS-SERIF SMALL H
'i': '\U0001d5c2', # 𝗂 MATHEMATICAL SANS-SERIF SMALL I
'j': '\U0001d5c3', # 𝗃 MATHEMATICAL SANS-SERIF SMALL J
'k': '\U0001d5c4', # 𝗄 MATHEMATICAL SANS-SERIF SMALL K
'l': '\U0001d5c5', # 𝗅 MATHEMATICAL SANS-SERIF SMALL L
'm': '\U0001d5c6', # 𝗆 MATHEMATICAL SANS-SERIF SMALL M
'n': '\U0001d5c7', # 𝗇 MATHEMATICAL SANS-SERIF SMALL N
'o': '\U0001d5c8', # 𝗈 MATHEMATICAL SANS-SERIF SMALL O
'p': '\U0001d5c9', # 𝗉 MATHEMATICAL SANS-SERIF SMALL P
'q': '\U0001d5ca', # 𝗊 MATHEMATICAL SANS-SERIF SMALL Q
'r': '\U0001d5cb', # 𝗋 MATHEMATICAL SANS-SERIF SMALL R
's': '\U0001d5cc', # 𝗌 MATHEMATICAL SANS-SERIF SMALL S
't': '\U0001d5cd', # 𝗍 MATHEMATICAL SANS-SERIF SMALL T
'u': '\U0001d5ce', # 𝗎 MATHEMATICAL SANS-SERIF SMALL U
'v': '\U0001d5cf', # 𝗏 MATHEMATICAL SANS-SERIF SMALL V
'w': '\U0001d5d0', # 𝗐 MATHEMATICAL SANS-SERIF SMALL W
'x': '\U0001d5d1', # 𝗑 MATHEMATICAL SANS-SERIF SMALL X
'y': '\U0001d5d2', # 𝗒 MATHEMATICAL SANS-SERIF SMALL Y
'z': '\U0001d5d3', # 𝗓 MATHEMATICAL SANS-SERIF SMALL Z
}
mathsfbf = {
'0': '\U0001d7ec', # 𝟬 MATHEMATICAL SANS-SERIF BOLD DIGIT ZERO
'1': '\U0001d7ed', # 𝟭 MATHEMATICAL SANS-SERIF BOLD DIGIT ONE
'2': '\U0001d7ee', # 𝟮 MATHEMATICAL SANS-SERIF BOLD DIGIT TWO
'3': '\U0001d7ef', # 𝟯 MATHEMATICAL SANS-SERIF BOLD DIGIT THREE
'4': '\U0001d7f0', # 𝟰 MATHEMATICAL SANS-SERIF BOLD DIGIT FOUR
'5': '\U0001d7f1', # 𝟱 MATHEMATICAL SANS-SERIF BOLD DIGIT FIVE
'6': '\U0001d7f2', # 𝟲 MATHEMATICAL SANS-SERIF BOLD DIGIT SIX
'7': '\U0001d7f3', # 𝟳 MATHEMATICAL SANS-SERIF BOLD DIGIT SEVEN
'8': '\U0001d7f4', # 𝟴 MATHEMATICAL SANS-SERIF BOLD DIGIT EIGHT
'9': '\U0001d7f5', # 𝟵 MATHEMATICAL SANS-SERIF BOLD DIGIT NINE
'A': '\U0001d5d4', # 𝗔 MATHEMATICAL SANS-SERIF BOLD CAPITAL A
'B': '\U0001d5d5', # 𝗕 MATHEMATICAL SANS-SERIF BOLD CAPITAL B
'C': '\U0001d5d6', # 𝗖 MATHEMATICAL SANS-SERIF BOLD CAPITAL C
'D': '\U0001d5d7', # 𝗗 MATHEMATICAL SANS-SERIF BOLD CAPITAL D
'E': '\U0001d5d8', # 𝗘 MATHEMATICAL SANS-SERIF BOLD CAPITAL E
'F': '\U0001d5d9', # 𝗙 MATHEMATICAL SANS-SERIF BOLD CAPITAL F
'G': '\U0001d5da', # 𝗚 MATHEMATICAL SANS-SERIF BOLD CAPITAL G
'H': '\U0001d5db', # 𝗛 MATHEMATICAL SANS-SERIF BOLD CAPITAL H
'I': '\U0001d5dc', # 𝗜 MATHEMATICAL SANS-SERIF BOLD CAPITAL I
'J': '\U0001d5dd', # 𝗝 MATHEMATICAL SANS-SERIF BOLD CAPITAL J
'K': '\U0001d5de', # 𝗞 MATHEMATICAL SANS-SERIF BOLD CAPITAL K
'L': '\U0001d5df', # 𝗟 MATHEMATICAL SANS-SERIF BOLD CAPITAL L
'M': '\U0001d5e0', # 𝗠 MATHEMATICAL SANS-SERIF BOLD CAPITAL M
'N': '\U0001d5e1', # 𝗡 MATHEMATICAL SANS-SERIF BOLD CAPITAL N
'O': '\U0001d5e2', # 𝗢 MATHEMATICAL SANS-SERIF BOLD CAPITAL O
'P': '\U0001d5e3', # 𝗣 MATHEMATICAL SANS-SERIF BOLD CAPITAL P
'Q': '\U0001d5e4', # 𝗤 MATHEMATICAL SANS-SERIF BOLD CAPITAL Q
'R': '\U0001d5e5', # 𝗥 MATHEMATICAL SANS-SERIF BOLD CAPITAL R
'S': '\U0001d5e6', # 𝗦 MATHEMATICAL SANS-SERIF BOLD CAPITAL S
'T': '\U0001d5e7', # 𝗧 MATHEMATICAL SANS-SERIF BOLD CAPITAL T
'U': '\U0001d5e8', # 𝗨 MATHEMATICAL SANS-SERIF BOLD CAPITAL U
'V': '\U0001d5e9', # 𝗩 MATHEMATICAL SANS-SERIF BOLD CAPITAL V
'W': '\U0001d5ea', # 𝗪 MATHEMATICAL SANS-SERIF BOLD CAPITAL W
'X': '\U0001d5eb', # 𝗫 MATHEMATICAL SANS-SERIF BOLD CAPITAL X
'Y': '\U0001d5ec', # 𝗬 MATHEMATICAL SANS-SERIF BOLD CAPITAL Y
'Z': '\U0001d5ed', # 𝗭 MATHEMATICAL SANS-SERIF BOLD CAPITAL Z
'a': '\U0001d5ee', # 𝗮 MATHEMATICAL SANS-SERIF BOLD SMALL A
'b': '\U0001d5ef', # 𝗯 MATHEMATICAL SANS-SERIF BOLD SMALL B
'c': '\U0001d5f0', # 𝗰 MATHEMATICAL SANS-SERIF BOLD SMALL C
'd': '\U0001d5f1', # 𝗱 MATHEMATICAL SANS-SERIF BOLD SMALL D
'e': '\U0001d5f2', # 𝗲 MATHEMATICAL SANS-SERIF BOLD SMALL E
'f': '\U0001d5f3', # 𝗳 MATHEMATICAL SANS-SERIF BOLD SMALL F
'g': '\U0001d5f4', # 𝗴 MATHEMATICAL SANS-SERIF BOLD SMALL G
'h': '\U0001d5f5', # 𝗵 MATHEMATICAL SANS-SERIF BOLD SMALL H
'i': '\U0001d5f6', # 𝗶 MATHEMATICAL SANS-SERIF BOLD SMALL I
'j': '\U0001d5f7', # 𝗷 MATHEMATICAL SANS-SERIF BOLD SMALL J
'k': '\U0001d5f8', # 𝗸 MATHEMATICAL SANS-SERIF BOLD SMALL K
'l': '\U0001d5f9', # 𝗹 MATHEMATICAL SANS-SERIF BOLD SMALL L
'm': '\U0001d5fa', # 𝗺 MATHEMATICAL SANS-SERIF BOLD SMALL M
'n': '\U0001d5fb', # 𝗻 MATHEMATICAL SANS-SERIF BOLD SMALL N
'o': '\U0001d5fc', # 𝗼 MATHEMATICAL SANS-SERIF BOLD SMALL O
'p': '\U0001d5fd', # 𝗽 MATHEMATICAL SANS-SERIF BOLD SMALL P
'q': '\U0001d5fe', # 𝗾 MATHEMATICAL SANS-SERIF BOLD SMALL Q
'r': '\U0001d5ff', # 𝗿 MATHEMATICAL SANS-SERIF BOLD SMALL R
's': '\U0001d600', # 𝘀 MATHEMATICAL SANS-SERIF BOLD SMALL S
't': '\U0001d601', # 𝘁 MATHEMATICAL SANS-SERIF BOLD SMALL T
'u': '\U0001d602', # 𝘂 MATHEMATICAL SANS-SERIF BOLD SMALL U
'v': '\U0001d603', # 𝘃 MATHEMATICAL SANS-SERIF BOLD SMALL V
'w': '\U0001d604', # 𝘄 MATHEMATICAL SANS-SERIF BOLD SMALL W
'x': '\U0001d605', # 𝘅 MATHEMATICAL SANS-SERIF BOLD SMALL X
'y': '\U0001d606', # 𝘆 MATHEMATICAL SANS-SERIF BOLD SMALL Y
'z': '\U0001d607', # 𝘇 MATHEMATICAL SANS-SERIF BOLD SMALL Z
'Γ': '\U0001d758', # 𝝘 MATHEMATICAL SANS-SERIF BOLD CAPITAL GAMMA
'Δ': '\U0001d759', # 𝝙 MATHEMATICAL SANS-SERIF BOLD CAPITAL DELTA
'Θ': '\U0001d75d', # 𝝝 MATHEMATICAL SANS-SERIF BOLD CAPITAL THETA
'Λ': '\U0001d760', # 𝝠 MATHEMATICAL SANS-SERIF BOLD CAPITAL LAMDA
'Ξ': '\U0001d763', # 𝝣 MATHEMATICAL SANS-SERIF BOLD CAPITAL XI
'Π': '\U0001d765', # 𝝥 MATHEMATICAL SANS-SERIF BOLD CAPITAL PI
'Σ': '\U0001d768', # 𝝨 MATHEMATICAL SANS-SERIF BOLD CAPITAL SIGMA
'Υ': '\U0001d76a', # 𝝪 MATHEMATICAL SANS-SERIF BOLD CAPITAL UPSILON
'Φ': '\U0001d76b', # 𝝫 MATHEMATICAL SANS-SERIF BOLD CAPITAL PHI
'Ψ': '\U0001d76d', # 𝝭 MATHEMATICAL SANS-SERIF BOLD CAPITAL PSI
'Ω': '\U0001d76e', # 𝝮 MATHEMATICAL SANS-SERIF BOLD CAPITAL OMEGA
'α': '\U0001d770', # 𝝰 MATHEMATICAL SANS-SERIF BOLD SMALL ALPHA
'β': '\U0001d771', # 𝝱 MATHEMATICAL SANS-SERIF BOLD SMALL BETA
'γ': '\U0001d772', # 𝝲 MATHEMATICAL SANS-SERIF BOLD SMALL GAMMA
'δ': '\U0001d773', # 𝝳 MATHEMATICAL SANS-SERIF BOLD SMALL DELTA
'ε': '\U0001d774', # 𝝴 MATHEMATICAL SANS-SERIF BOLD SMALL EPSILON
'ζ': '\U0001d775', # 𝝵 MATHEMATICAL SANS-SERIF BOLD SMALL ZETA
'η': '\U0001d776', # 𝝶 MATHEMATICAL SANS-SERIF BOLD SMALL ETA
'θ': '\U0001d777', # 𝝷 MATHEMATICAL SANS-SERIF BOLD SMALL THETA
'ι': '\U0001d778', # 𝝸 MATHEMATICAL SANS-SERIF BOLD SMALL IOTA
'κ': '\U0001d779', # 𝝹 MATHEMATICAL SANS-SERIF BOLD SMALL KAPPA
'λ': '\U0001d77a', # 𝝺 MATHEMATICAL SANS-SERIF BOLD SMALL LAMDA
'μ': '\U0001d77b', # 𝝻 MATHEMATICAL SANS-SERIF BOLD SMALL MU
'ν': '\U0001d77c', # 𝝼 MATHEMATICAL SANS-SERIF BOLD SMALL NU
'ξ': '\U0001d77d', # 𝝽 MATHEMATICAL SANS-SERIF BOLD SMALL XI
'π': '\U0001d77f', # 𝝿 MATHEMATICAL SANS-SERIF BOLD SMALL PI
'ρ': '\U0001d780', # 𝞀 MATHEMATICAL SANS-SERIF BOLD SMALL RHO
'ς': '\U0001d781', # 𝞁 MATHEMATICAL SANS-SERIF BOLD SMALL FINAL SIGMA
'σ': '\U0001d782', # 𝞂 MATHEMATICAL SANS-SERIF BOLD SMALL SIGMA
'τ': '\U0001d783', # 𝞃 MATHEMATICAL SANS-SERIF BOLD SMALL TAU
'υ': '\U0001d784', # 𝞄 MATHEMATICAL SANS-SERIF BOLD SMALL UPSILON
'φ': '\U0001d785', # 𝞅 MATHEMATICAL SANS-SERIF BOLD SMALL PHI
'χ': '\U0001d786', # 𝞆 MATHEMATICAL SANS-SERIF BOLD SMALL CHI
'ψ': '\U0001d787', # 𝞇 MATHEMATICAL SANS-SERIF BOLD SMALL PSI
'ω': '\U0001d788', # 𝞈 MATHEMATICAL SANS-SERIF BOLD SMALL OMEGA
'ϑ': '\U0001d78b', # 𝞋 MATHEMATICAL SANS-SERIF BOLD THETA SYMBOL
'ϕ': '\U0001d78d', # 𝞍 MATHEMATICAL SANS-SERIF BOLD PHI SYMBOL
'ϖ': '\U0001d78f', # 𝞏 MATHEMATICAL SANS-SERIF BOLD PI SYMBOL
'ϱ': '\U0001d78e', # 𝞎 MATHEMATICAL SANS-SERIF BOLD RHO SYMBOL
'ϵ': '\U0001d78a', # 𝞊 MATHEMATICAL SANS-SERIF BOLD EPSILON SYMBOL
'': '\U0001d76f', # 𝝯 MATHEMATICAL SANS-SERIF BOLD NABLA
}
mathsfbfit = {
'A': '\U0001d63c', # 𝘼 MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL A
'B': '\U0001d63d', # 𝘽 MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL B
'C': '\U0001d63e', # 𝘾 MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL C
'D': '\U0001d63f', # 𝘿 MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL D
'E': '\U0001d640', # 𝙀 MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL E
'F': '\U0001d641', # 𝙁 MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL F
'G': '\U0001d642', # 𝙂 MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL G
'H': '\U0001d643', # 𝙃 MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL H
'I': '\U0001d644', # 𝙄 MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL I
'J': '\U0001d645', # 𝙅 MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL J
'K': '\U0001d646', # 𝙆 MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL K
'L': '\U0001d647', # 𝙇 MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL L
'M': '\U0001d648', # 𝙈 MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL M
'N': '\U0001d649', # 𝙉 MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL N
'O': '\U0001d64a', # 𝙊 MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL O
'P': '\U0001d64b', # 𝙋 MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL P
'Q': '\U0001d64c', # 𝙌 MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL Q
'R': '\U0001d64d', # 𝙍 MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL R
'S': '\U0001d64e', # 𝙎 MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL S
'T': '\U0001d64f', # 𝙏 MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL T
'U': '\U0001d650', # 𝙐 MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL U
'V': '\U0001d651', # 𝙑 MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL V
'W': '\U0001d652', # 𝙒 MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL W
'X': '\U0001d653', # 𝙓 MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL X
'Y': '\U0001d654', # 𝙔 MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL Y
'Z': '\U0001d655', # 𝙕 MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL Z
'a': '\U0001d656', # 𝙖 MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL A
'b': '\U0001d657', # 𝙗 MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL B
'c': '\U0001d658', # 𝙘 MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL C
'd': '\U0001d659', # 𝙙 MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL D
'e': '\U0001d65a', # 𝙚 MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL E
'f': '\U0001d65b', # 𝙛 MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL F
'g': '\U0001d65c', # 𝙜 MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL G
'h': '\U0001d65d', # 𝙝 MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL H
'i': '\U0001d65e', # 𝙞 MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL I
'j': '\U0001d65f', # 𝙟 MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL J
'k': '\U0001d660', # 𝙠 MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL K
'l': '\U0001d661', # 𝙡 MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL L
'm': '\U0001d662', # 𝙢 MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL M
'n': '\U0001d663', # 𝙣 MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL N
'o': '\U0001d664', # 𝙤 MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL O
'p': '\U0001d665', # 𝙥 MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL P
'q': '\U0001d666', # 𝙦 MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL Q
'r': '\U0001d667', # 𝙧 MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL R
's': '\U0001d668', # 𝙨 MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL S
't': '\U0001d669', # 𝙩 MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL T
'u': '\U0001d66a', # 𝙪 MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL U
'v': '\U0001d66b', # 𝙫 MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL V
'w': '\U0001d66c', # 𝙬 MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL W
'x': '\U0001d66d', # 𝙭 MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL X
'y': '\U0001d66e', # 𝙮 MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL Y
'z': '\U0001d66f', # 𝙯 MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL Z
'Γ': '\U0001d792', # 𝞒 MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL GAMMA
'Δ': '\U0001d793', # 𝞓 MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL DELTA
'Θ': '\U0001d797', # 𝞗 MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL THETA
'Λ': '\U0001d79a', # 𝞚 MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL LAMDA
'Ξ': '\U0001d79d', # 𝞝 MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL XI
'Π': '\U0001d79f', # 𝞟 MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL PI
'Σ': '\U0001d7a2', # 𝞢 MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL SIGMA
'Υ': '\U0001d7a4', # 𝞤 MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL UPSILON
'Φ': '\U0001d7a5', # 𝞥 MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL PHI
'Ψ': '\U0001d7a7', # 𝞧 MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL PSI
'Ω': '\U0001d7a8', # 𝞨 MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL OMEGA
'α': '\U0001d7aa', # 𝞪 MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL ALPHA
'β': '\U0001d7ab', # 𝞫 MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL BETA
'γ': '\U0001d7ac', # 𝞬 MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL GAMMA
'δ': '\U0001d7ad', # 𝞭 MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL DELTA
'ε': '\U0001d7ae', # 𝞮 MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL EPSILON
'ζ': '\U0001d7af', # 𝞯 MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL ZETA
'η': '\U0001d7b0', # 𝞰 MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL ETA
'θ': '\U0001d7b1', # 𝞱 MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL THETA
'ι': '\U0001d7b2', # 𝞲 MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL IOTA
'κ': '\U0001d7b3', # 𝞳 MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL KAPPA
'λ': '\U0001d7b4', # 𝞴 MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL LAMDA
'μ': '\U0001d7b5', # 𝞵 MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL MU
'ν': '\U0001d7b6', # 𝞶 MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL NU
'ξ': '\U0001d7b7', # 𝞷 MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL XI
'π': '\U0001d7b9', # 𝞹 MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL PI
'ρ': '\U0001d7ba', # 𝞺 MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL RHO
'ς': '\U0001d7bb', # 𝞻 MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL FINAL SIGMA
'σ': '\U0001d7bc', # 𝞼 MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL SIGMA
'τ': '\U0001d7bd', # 𝞽 MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL TAU
'υ': '\U0001d7be', # 𝞾 MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL UPSILON
'φ': '\U0001d7bf', # 𝞿 MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL PHI
'χ': '\U0001d7c0', # 𝟀 MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL CHI
'ψ': '\U0001d7c1', # 𝟁 MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL PSI
'ω': '\U0001d7c2', # 𝟂 MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL OMEGA
'ϑ': '\U0001d7c5', # 𝟅 MATHEMATICAL SANS-SERIF BOLD ITALIC THETA SYMBOL
'ϕ': '\U0001d7c7', # 𝟇 MATHEMATICAL SANS-SERIF BOLD ITALIC PHI SYMBOL
'ϖ': '\U0001d7c9', # 𝟉 MATHEMATICAL SANS-SERIF BOLD ITALIC PI SYMBOL
'ϰ': '\U0001d7c6', # 𝟆 MATHEMATICAL SANS-SERIF BOLD ITALIC KAPPA SYMBOL
'ϱ': '\U0001d7c8', # 𝟈 MATHEMATICAL SANS-SERIF BOLD ITALIC RHO SYMBOL
'ϵ': '\U0001d7c4', # 𝟄 MATHEMATICAL SANS-SERIF BOLD ITALIC EPSILON SYMBOL
'': '\U0001d7c3', # 𝟃 MATHEMATICAL SANS-SERIF BOLD ITALIC PARTIAL DIFFERENTIAL
'': '\U0001d7a9', # 𝞩 MATHEMATICAL SANS-SERIF BOLD ITALIC NABLA
}
mathsfit = {
'A': '\U0001d608', # 𝘈 MATHEMATICAL SANS-SERIF ITALIC CAPITAL A
'B': '\U0001d609', # 𝘉 MATHEMATICAL SANS-SERIF ITALIC CAPITAL B
'C': '\U0001d60a', # 𝘊 MATHEMATICAL SANS-SERIF ITALIC CAPITAL C
'D': '\U0001d60b', # 𝘋 MATHEMATICAL SANS-SERIF ITALIC CAPITAL D
'E': '\U0001d60c', # 𝘌 MATHEMATICAL SANS-SERIF ITALIC CAPITAL E
'F': '\U0001d60d', # 𝘍 MATHEMATICAL SANS-SERIF ITALIC CAPITAL F
'G': '\U0001d60e', # 𝘎 MATHEMATICAL SANS-SERIF ITALIC CAPITAL G
'H': '\U0001d60f', # 𝘏 MATHEMATICAL SANS-SERIF ITALIC CAPITAL H
'I': '\U0001d610', # 𝘐 MATHEMATICAL SANS-SERIF ITALIC CAPITAL I
'J': '\U0001d611', # 𝘑 MATHEMATICAL SANS-SERIF ITALIC CAPITAL J
'K': '\U0001d612', # 𝘒 MATHEMATICAL SANS-SERIF ITALIC CAPITAL K
'L': '\U0001d613', # 𝘓 MATHEMATICAL SANS-SERIF ITALIC CAPITAL L
'M': '\U0001d614', # 𝘔 MATHEMATICAL SANS-SERIF ITALIC CAPITAL M
'N': '\U0001d615', # 𝘕 MATHEMATICAL SANS-SERIF ITALIC CAPITAL N
'O': '\U0001d616', # 𝘖 MATHEMATICAL SANS-SERIF ITALIC CAPITAL O
'P': '\U0001d617', # 𝘗 MATHEMATICAL SANS-SERIF ITALIC CAPITAL P
'Q': '\U0001d618', # 𝘘 MATHEMATICAL SANS-SERIF ITALIC CAPITAL Q
'R': '\U0001d619', # 𝘙 MATHEMATICAL SANS-SERIF ITALIC CAPITAL R
'S': '\U0001d61a', # 𝘚 MATHEMATICAL SANS-SERIF ITALIC CAPITAL S
'T': '\U0001d61b', # 𝘛 MATHEMATICAL SANS-SERIF ITALIC CAPITAL T
'U': '\U0001d61c', # 𝘜 MATHEMATICAL SANS-SERIF ITALIC CAPITAL U
'V': '\U0001d61d', # 𝘝 MATHEMATICAL SANS-SERIF ITALIC CAPITAL V
'W': '\U0001d61e', # 𝘞 MATHEMATICAL SANS-SERIF ITALIC CAPITAL W
'X': '\U0001d61f', # 𝘟 MATHEMATICAL SANS-SERIF ITALIC CAPITAL X
'Y': '\U0001d620', # 𝘠 MATHEMATICAL SANS-SERIF ITALIC CAPITAL Y
'Z': '\U0001d621', # 𝘡 MATHEMATICAL SANS-SERIF ITALIC CAPITAL Z
'a': '\U0001d622', # 𝘢 MATHEMATICAL SANS-SERIF ITALIC SMALL A
'b': '\U0001d623', # 𝘣 MATHEMATICAL SANS-SERIF ITALIC SMALL B
'c': '\U0001d624', # 𝘤 MATHEMATICAL SANS-SERIF ITALIC SMALL C
'd': '\U0001d625', # 𝘥 MATHEMATICAL SANS-SERIF ITALIC SMALL D
'e': '\U0001d626', # 𝘦 MATHEMATICAL SANS-SERIF ITALIC SMALL E
'f': '\U0001d627', # 𝘧 MATHEMATICAL SANS-SERIF ITALIC SMALL F
'g': '\U0001d628', # 𝘨 MATHEMATICAL SANS-SERIF ITALIC SMALL G
'h': '\U0001d629', # 𝘩 MATHEMATICAL SANS-SERIF ITALIC SMALL H
'i': '\U0001d62a', # 𝘪 MATHEMATICAL SANS-SERIF ITALIC SMALL I
'j': '\U0001d62b', # 𝘫 MATHEMATICAL SANS-SERIF ITALIC SMALL J
'k': '\U0001d62c', # 𝘬 MATHEMATICAL SANS-SERIF ITALIC SMALL K
'l': '\U0001d62d', # 𝘭 MATHEMATICAL SANS-SERIF ITALIC SMALL L
'm': '\U0001d62e', # 𝘮 MATHEMATICAL SANS-SERIF ITALIC SMALL M
'n': '\U0001d62f', # 𝘯 MATHEMATICAL SANS-SERIF ITALIC SMALL N
'o': '\U0001d630', # 𝘰 MATHEMATICAL SANS-SERIF ITALIC SMALL O
'p': '\U0001d631', # 𝘱 MATHEMATICAL SANS-SERIF ITALIC SMALL P
'q': '\U0001d632', # 𝘲 MATHEMATICAL SANS-SERIF ITALIC SMALL Q
'r': '\U0001d633', # 𝘳 MATHEMATICAL SANS-SERIF ITALIC SMALL R
's': '\U0001d634', # 𝘴 MATHEMATICAL SANS-SERIF ITALIC SMALL S
't': '\U0001d635', # 𝘵 MATHEMATICAL SANS-SERIF ITALIC SMALL T
'u': '\U0001d636', # 𝘶 MATHEMATICAL SANS-SERIF ITALIC SMALL U
'v': '\U0001d637', # 𝘷 MATHEMATICAL SANS-SERIF ITALIC SMALL V
'w': '\U0001d638', # 𝘸 MATHEMATICAL SANS-SERIF ITALIC SMALL W
'x': '\U0001d639', # 𝘹 MATHEMATICAL SANS-SERIF ITALIC SMALL X
'y': '\U0001d63a', # 𝘺 MATHEMATICAL SANS-SERIF ITALIC SMALL Y
'z': '\U0001d63b', # 𝘻 MATHEMATICAL SANS-SERIF ITALIC SMALL Z
}
mathtt = {
'0': '\U0001d7f6', # 𝟶 MATHEMATICAL MONOSPACE DIGIT ZERO
'1': '\U0001d7f7', # 𝟷 MATHEMATICAL MONOSPACE DIGIT ONE
'2': '\U0001d7f8', # 𝟸 MATHEMATICAL MONOSPACE DIGIT TWO
'3': '\U0001d7f9', # 𝟹 MATHEMATICAL MONOSPACE DIGIT THREE
'4': '\U0001d7fa', # 𝟺 MATHEMATICAL MONOSPACE DIGIT FOUR
'5': '\U0001d7fb', # 𝟻 MATHEMATICAL MONOSPACE DIGIT FIVE
'6': '\U0001d7fc', # 𝟼 MATHEMATICAL MONOSPACE DIGIT SIX
'7': '\U0001d7fd', # 𝟽 MATHEMATICAL MONOSPACE DIGIT SEVEN
'8': '\U0001d7fe', # 𝟾 MATHEMATICAL MONOSPACE DIGIT EIGHT
'9': '\U0001d7ff', # 𝟿 MATHEMATICAL MONOSPACE DIGIT NINE
'A': '\U0001d670', # 𝙰 MATHEMATICAL MONOSPACE CAPITAL A
'B': '\U0001d671', # 𝙱 MATHEMATICAL MONOSPACE CAPITAL B
'C': '\U0001d672', # 𝙲 MATHEMATICAL MONOSPACE CAPITAL C
'D': '\U0001d673', # 𝙳 MATHEMATICAL MONOSPACE CAPITAL D
'E': '\U0001d674', # 𝙴 MATHEMATICAL MONOSPACE CAPITAL E
'F': '\U0001d675', # 𝙵 MATHEMATICAL MONOSPACE CAPITAL F
'G': '\U0001d676', # 𝙶 MATHEMATICAL MONOSPACE CAPITAL G
'H': '\U0001d677', # 𝙷 MATHEMATICAL MONOSPACE CAPITAL H
'I': '\U0001d678', # 𝙸 MATHEMATICAL MONOSPACE CAPITAL I
'J': '\U0001d679', # 𝙹 MATHEMATICAL MONOSPACE CAPITAL J
'K': '\U0001d67a', # 𝙺 MATHEMATICAL MONOSPACE CAPITAL K
'L': '\U0001d67b', # 𝙻 MATHEMATICAL MONOSPACE CAPITAL L
'M': '\U0001d67c', # 𝙼 MATHEMATICAL MONOSPACE CAPITAL M
'N': '\U0001d67d', # 𝙽 MATHEMATICAL MONOSPACE CAPITAL N
'O': '\U0001d67e', # 𝙾 MATHEMATICAL MONOSPACE CAPITAL O
'P': '\U0001d67f', # 𝙿 MATHEMATICAL MONOSPACE CAPITAL P
'Q': '\U0001d680', # 𝚀 MATHEMATICAL MONOSPACE CAPITAL Q
'R': '\U0001d681', # 𝚁 MATHEMATICAL MONOSPACE CAPITAL R
'S': '\U0001d682', # 𝚂 MATHEMATICAL MONOSPACE CAPITAL S
'T': '\U0001d683', # 𝚃 MATHEMATICAL MONOSPACE CAPITAL T
'U': '\U0001d684', # 𝚄 MATHEMATICAL MONOSPACE CAPITAL U
'V': '\U0001d685', # 𝚅 MATHEMATICAL MONOSPACE CAPITAL V
'W': '\U0001d686', # 𝚆 MATHEMATICAL MONOSPACE CAPITAL W
'X': '\U0001d687', # 𝚇 MATHEMATICAL MONOSPACE CAPITAL X
'Y': '\U0001d688', # 𝚈 MATHEMATICAL MONOSPACE CAPITAL Y
'Z': '\U0001d689', # 𝚉 MATHEMATICAL MONOSPACE CAPITAL Z
'a': '\U0001d68a', # 𝚊 MATHEMATICAL MONOSPACE SMALL A
'b': '\U0001d68b', # 𝚋 MATHEMATICAL MONOSPACE SMALL B
'c': '\U0001d68c', # 𝚌 MATHEMATICAL MONOSPACE SMALL C
'd': '\U0001d68d', # 𝚍 MATHEMATICAL MONOSPACE SMALL D
'e': '\U0001d68e', # 𝚎 MATHEMATICAL MONOSPACE SMALL E
'f': '\U0001d68f', # 𝚏 MATHEMATICAL MONOSPACE SMALL F
'g': '\U0001d690', # 𝚐 MATHEMATICAL MONOSPACE SMALL G
'h': '\U0001d691', # 𝚑 MATHEMATICAL MONOSPACE SMALL H
'i': '\U0001d692', # 𝚒 MATHEMATICAL MONOSPACE SMALL I
'j': '\U0001d693', # 𝚓 MATHEMATICAL MONOSPACE SMALL J
'k': '\U0001d694', # 𝚔 MATHEMATICAL MONOSPACE SMALL K
'l': '\U0001d695', # 𝚕 MATHEMATICAL MONOSPACE SMALL L
'm': '\U0001d696', # 𝚖 MATHEMATICAL MONOSPACE SMALL M
'n': '\U0001d697', # 𝚗 MATHEMATICAL MONOSPACE SMALL N
'o': '\U0001d698', # 𝚘 MATHEMATICAL MONOSPACE SMALL O
'p': '\U0001d699', # 𝚙 MATHEMATICAL MONOSPACE SMALL P
'q': '\U0001d69a', # 𝚚 MATHEMATICAL MONOSPACE SMALL Q
'r': '\U0001d69b', # 𝚛 MATHEMATICAL MONOSPACE SMALL R
's': '\U0001d69c', # 𝚜 MATHEMATICAL MONOSPACE SMALL S
't': '\U0001d69d', # 𝚝 MATHEMATICAL MONOSPACE SMALL T
'u': '\U0001d69e', # 𝚞 MATHEMATICAL MONOSPACE SMALL U
'v': '\U0001d69f', # 𝚟 MATHEMATICAL MONOSPACE SMALL V
'w': '\U0001d6a0', # 𝚠 MATHEMATICAL MONOSPACE SMALL W
'x': '\U0001d6a1', # 𝚡 MATHEMATICAL MONOSPACE SMALL X
'y': '\U0001d6a2', # 𝚢 MATHEMATICAL MONOSPACE SMALL Y
'z': '\U0001d6a3', # 𝚣 MATHEMATICAL MONOSPACE SMALL Z
}

View file

@ -0,0 +1,478 @@
# :Id: $Id: mathml_elements.py 9561 2024-03-14 16:34:48Z milde $
# :Copyright: 2024 Günter Milde.
#
# :License: Released under the terms of the `2-Clause BSD license`_, in short:
#
# Copying and distribution of this file, with or without modification,
# are permitted in any medium without royalty provided the copyright
# notice and this notice are preserved.
# This file is offered as-is, without any warranty.
#
# .. _2-Clause BSD license: https://opensource.org/licenses/BSD-2-Clause
"""MathML element classes based on `xml.etree`.
The module is intended for programmatic generation of MathML
and covers the part of `MathML Core`_ that is required by
Docutil's *TeX math to MathML* converter.
This module is PROVISIONAL:
the API is not settled and may change with any minor Docutils version.
.. _MathML Core: https://www.w3.org/TR/mathml-core/
"""
# Usage:
#
# >>> from mathml_elements import *
import numbers
import xml.etree.ElementTree as ET
GLOBAL_ATTRIBUTES = (
'class', # space-separated list of element classes
# 'data-*', # custom data attributes (see HTML)
'dir', # directionality ('ltr', 'rtl')
'displaystyle', # True: normal, False: compact
'id', # unique identifier
# 'mathbackground', # color definition, deprecated
# 'mathcolor', # color definition, deprecated
# 'mathsize', # font-size, deprecated
'nonce', # cryptographic nonce ("number used once")
'scriptlevel', # math-depth for the element
'style', # CSS styling declarations
'tabindex', # indicate if the element takes input focus
)
"""Global MathML attributes
https://w3c.github.io/mathml-core/#global-attributes
"""
# Base classes
# ------------
class MathElement(ET.Element):
"""Base class for MathML elements."""
nchildren = None
"""Expected number of children or None"""
# cf. https://www.w3.org/TR/MathML3/chapter3.html#id.3.1.3.2
parent = None
"""Parent node in MathML element tree."""
def __init__(self, *children, **attributes):
"""Set up node with `children` and `attributes`.
Attribute names are normalised to lowercase.
You may use "CLASS" to set a "class" attribute.
Attribute values are converted to strings
(with True -> "true" and False -> "false").
>>> math(CLASS='test', level=3, split=True)
math(class='test', level='3', split='true')
>>> math(CLASS='test', level=3, split=True).toxml()
'<math class="test" level="3" split="true"></math>'
"""
attrib = {k.lower(): self.a_str(v) for k, v in attributes.items()}
super().__init__(self.__class__.__name__, **attrib)
self.extend(children)
@staticmethod
def a_str(v):
# Return string representation for attribute value `v`.
if isinstance(v, bool):
return str(v).lower()
return str(v)
def __repr__(self):
"""Return full string representation."""
args = [repr(child) for child in self]
if self.text:
args.append(repr(self.text))
if self.nchildren != self.__class__.nchildren:
args.append(f'nchildren={self.nchildren}')
if getattr(self, 'switch', None):
args.append('switch=True')
args += [f'{k}={v!r}' for k, v in self.items() if v is not None]
return f'{self.tag}({", ".join(args)})'
def __str__(self):
"""Return concise, informal string representation."""
if self.text:
args = repr(self.text)
else:
args = ', '.join(f'{child}' for child in self)
return f'{self.tag}({args})'
def set(self, key, value):
super().set(key, self.a_str(value))
def __setitem__(self, key, value):
if self.nchildren == 0:
raise TypeError(f'Element "{self}" does not take children.')
if isinstance(value, MathElement):
value.parent = self
else: # value may be an iterable
if self.nchildren and len(self) + len(value) > self.nchildren:
raise TypeError(f'Element "{self}" takes only {self.nchildren}'
' children')
for e in value:
e.parent = self
super().__setitem__(key, value)
def is_full(self):
"""Return boolean indicating whether children may be appended."""
return self.nchildren is not None and len(self) >= self.nchildren
def close(self):
"""Close element and return first non-full anchestor or None."""
self.nchildren = len(self) # mark node as full
parent = self.parent
while parent is not None and parent.is_full():
parent = parent.parent
return parent
def append(self, element):
"""Append `element` and return new "current node" (insertion point).
Append as child element and set the internal `parent` attribute.
If self is already full, raise TypeError.
If self is full after appending, call `self.close()`
(returns first non-full anchestor or None) else return `self`.
"""
if self.is_full():
if self.nchildren:
status = f'takes only {self.nchildren} children'
else:
status = 'does not take children'
raise TypeError(f'Element "{self}" {status}.')
super().append(element)
element.parent = self
if self.is_full():
return self.close()
return self
def extend(self, elements):
"""Sequentially append `elements`. Return new "current node".
Raise TypeError if overfull.
"""
current_node = self
for element in elements:
current_node = self.append(element)
return current_node
def pop(self, index=-1):
element = self[index]
del self[index]
return element
def in_block(self):
"""Return True, if `self` or an ancestor has ``display='block'``.
Used to find out whether we are in inline vs. displayed maths.
"""
if self.get('display') is None:
try:
return self.parent.in_block()
except AttributeError:
return False
return self.get('display') == 'block'
# XML output:
def indent_xml(self, space=' ', level=0):
"""Format XML output with indents.
Use with care:
Formatting whitespace is permanently added to the
`text` and `tail` attributes of `self` and anchestors!
"""
ET.indent(self, space, level)
def unindent_xml(self):
"""Strip whitespace at the end of `text` and `tail` attributes...
to revert changes made by the `indent_xml()` method.
Use with care, trailing whitespace from the original may be lost.
"""
for e in self.iter():
if not isinstance(e, MathToken) and e.text:
e.text = e.text.rstrip()
if e.tail:
e.tail = e.tail.rstrip()
def toxml(self, encoding=None):
"""Return an XML representation of the element.
By default, the return value is a `str` instance. With an explicit
`encoding` argument, the result is a `bytes` instance in the
specified encoding. The XML default encoding is UTF-8, any other
encoding must be specified in an XML document header.
Name and encoding handling match `xml.dom.minidom.Node.toxml()`
while `etree.Element.tostring()` returns `bytes` by default.
"""
xml = ET.tostring(self, encoding or 'unicode',
short_empty_elements=False)
# Visible representation for "Apply Function" character:
try:
xml = xml.replace('\u2061', '&ApplyFunction;')
except TypeError:
xml = xml.replace('\u2061'.encode(encoding), b'&ApplyFunction;')
return xml
# Group sub-expressions in a horizontal row
#
# The elements <msqrt>, <mstyle>, <merror>, <mpadded>, <mphantom>,
# <menclose>, <mtd>, <mscarry>, and <math> treat their contents
# as a single inferred mrow formed from all their children.
# (https://www.w3.org/TR/mathml4/#presm_inferredmrow)
#
# MathML Core uses the term "anonymous mrow element".
class MathRow(MathElement):
"""Base class for elements treating content as a single mrow."""
# 2d Schemata
class MathSchema(MathElement):
"""Base class for schemata expecting 2 or more children.
The special attribute `switch` indicates that the last two child
elements are in reversed order and must be switched before XML-export.
See `msub` for an example.
"""
nchildren = 2
def __init__(self, *children, **kwargs):
self.switch = kwargs.pop('switch', False)
super().__init__(*children, **kwargs)
def append(self, element):
"""Append element. Normalize order and close if full."""
current_node = super().append(element)
if self.switch and self.is_full():
self[-1], self[-2] = self[-2], self[-1]
self.switch = False
return current_node
# Token elements represent the smallest units of mathematical notation which
# carry meaning.
class MathToken(MathElement):
"""Token Element: contains textual data instead of children.
Expect text data on initialisation.
"""
nchildren = 0
def __init__(self, text, **attributes):
super().__init__(**attributes)
if not isinstance(text, (str, numbers.Number)):
raise ValueError('MathToken element expects `str` or number,'
f' not "{text}".')
self.text = str(text)
# MathML element classes
# ----------------------
class math(MathRow):
"""Top-level MathML element, a single mathematical formula."""
# Token elements
# ~~~~~~~~~~~~~~
class mtext(MathToken):
"""Arbitrary text with no notational meaning."""
class mi(MathToken):
"""Identifier, such as a function name, variable or symbolic constant."""
class mn(MathToken):
"""Numeric literal.
>>> mn(3.41).toxml()
'<mn>3.41</mn>'
Normally a sequence of digits with a possible separator (a dot or a comma).
(Values with comma must be specified as `str`.)
"""
class mo(MathToken):
"""Operator, Fence, Separator, or Accent.
>>> mo('<').toxml()
'<mo>&lt;</mo>'
Besides operators in strict mathematical meaning, this element also
includes "operators" like parentheses, separators like comma and
semicolon, or "absolute value" bars.
"""
class mspace(MathElement):
"""Blank space, whose size is set by its attributes.
Takes additional attributes `depth`, `height`, `width`.
Takes no children and no text.
See also `mphantom`.
"""
nchildren = 0
# General Layout Schemata
# ~~~~~~~~~~~~~~~~~~~~~~~
class mrow(MathRow):
"""Generic element to group children as a horizontal row.
Removed on closing if not required (see `mrow.close()`).
"""
def transfer_attributes(self, other):
"""Transfer attributes from self to other.
"List values" (class, style) are appended to existing values,
other values replace existing values.
"""
delimiters = {'class': ' ', 'style': '; '}
for k, v in self.items():
if k in ('class', 'style') and v:
if other.get(k):
v = delimiters[k].join(
(other.get(k).rstrip(delimiters[k]), v))
other.set(k, v)
def close(self):
"""Close element and return first non-full anchestor or None.
Remove <mrow> if it has only one child element.
"""
parent = self.parent
# replace `self` with single child
if parent is not None and len(self) == 1:
child = self[0]
try:
parent[list(parent).index(self)] = child
child.parent = parent
except (AttributeError, ValueError):
return None
self.transfer_attributes(child)
return super().close()
class mfrac(MathSchema):
"""Fractions or fraction-like objects such as binomial coefficients."""
class msqrt(MathRow):
"""Square root. See also `mroot`."""
nchildren = 1 # \sqrt expects one argument or a group
class mroot(MathSchema):
"""Roots with an explicit index. See also `msqrt`."""
class mstyle(MathRow):
"""Style Change.
In modern browsers, <mstyle> is equivalent to an <mrow> element.
However, <mstyle> may still be relevant for compatibility with
MathML implementations outside browsers.
"""
class merror(MathRow):
"""Display contents as error messages."""
class menclose(MathRow):
"""Renders content inside an enclosing notation...
... specified by the notation attribute.
Non-standard but still required by Firefox for boxed expressions.
"""
nchildren = 1 # \boxed expects one argument or a group
class mpadded(MathRow):
"""Adjust space around content."""
# nchildren = 1 # currently not used by latex2mathml
class mphantom(MathRow):
"""Placeholder: Rendered invisibly but dimensions are kept."""
nchildren = 1 # \phantom expects one argument or a group
# Script and Limit Schemata
# ~~~~~~~~~~~~~~~~~~~~~~~~~
class msub(MathSchema):
"""Attach a subscript to an expression."""
class msup(MathSchema):
"""Attach a superscript to an expression."""
class msubsup(MathSchema):
"""Attach both a subscript and a superscript to an expression."""
nchildren = 3
# Examples:
#
# The `switch` attribute reverses the order of the last two children:
# >>> msub(mn(1), mn(2)).toxml()
# '<msub><mn>1</mn><mn>2</mn></msub>'
# >>> msub(mn(1), mn(2), switch=True).toxml()
# '<msub><mn>2</mn><mn>1</mn></msub>'
#
# >>> msubsup(mi('base'), mn(1), mn(2)).toxml()
# '<msubsup><mi>base</mi><mn>1</mn><mn>2</mn></msubsup>'
# >>> msubsup(mi('base'), mn(1), mn(2), switch=True).toxml()
# '<msubsup><mi>base</mi><mn>2</mn><mn>1</mn></msubsup>'
class munder(msub):
"""Attach an accent or a limit under an expression."""
class mover(msup):
"""Attach an accent or a limit over an expression."""
class munderover(msubsup):
"""Attach accents or limits both under and over an expression."""
# Tabular Math
# ~~~~~~~~~~~~
class mtable(MathElement):
"""Table or matrix element."""
class mtr(MathRow):
"""Row in a table or a matrix."""
class mtd(MathRow):
"""Cell in a table or a matrix"""

View file

@ -0,0 +1,261 @@
# :Id: $Id: tex2mathml_extern.py 9536 2024-02-01 13:04:22Z milde $
# :Copyright: © 2015 Günter Milde.
# :License: Released under the terms of the `2-Clause BSD license`__, in short:
#
# Copying and distribution of this file, with or without modification,
# are permitted in any medium without royalty provided the copyright
# notice and this notice are preserved.
# This file is offered as-is, without any warranty.
#
# __ https://opensource.org/licenses/BSD-2-Clause
"""Wrappers for TeX->MathML conversion by external tools
This module is provisional:
the API is not settled and may change with any minor Docutils version.
"""
import subprocess
from docutils import nodes
from docutils.utils.math import MathError, wrap_math_code
# `latexml` expects a complete document:
document_template = r"""\documentclass{article}
\begin{document}
%s
\end{document}
"""
def _check_result(result, details=[]):
# raise MathError if the conversion went wrong
# :details: list of doctree nodes with additional info
msg = ''
if not details and result.stderr:
details = [nodes.paragraph('', result.stderr, classes=['pre-wrap'])]
if details:
msg = f'TeX to MathML converter `{result.args[0]}` failed:'
elif result.returncode:
msg = (f'TeX to MathMl converter `{result.args[0]}` '
f'exited with Errno {result.returncode}.')
elif not result.stdout:
msg = f'TeX to MathML converter `{result.args[0]}` returned no MathML.'
if msg:
raise MathError(msg, details=details)
def blahtexml(math_code, as_block=False):
"""Convert LaTeX math code to MathML with blahtexml__.
__ http://gva.noekeon.org/blahtexml/
"""
args = ['blahtexml',
'--mathml',
'--indented',
'--spacing', 'moderate',
'--mathml-encoding', 'raw',
'--other-encoding', 'raw',
'--doctype-xhtml+mathml',
'--annotate-TeX',
]
# "blahtexml" expects LaTeX code without math-mode-switch.
# We still need to tell it about displayed equation(s).
mathml_args = ' display="block"' if as_block else ''
_wrapped = wrap_math_code(math_code, as_block)
if '{align*}' in _wrapped:
math_code = _wrapped.replace('{align*}', '{aligned}')
result = subprocess.run(args, input=math_code,
capture_output=True, text=True)
# blahtexml writes <error> messages to stdout
if '<error>' in result.stdout:
result.stderr = result.stdout[result.stdout.find('<message>')+9:
result.stdout.find('</message>')]
else:
result.stdout = result.stdout[result.stdout.find('<markup>')+9:
result.stdout.find('</markup>')]
_check_result(result)
return (f'<math xmlns="http://www.w3.org/1998/Math/MathML"{mathml_args}>'
f'\n{result.stdout}</math>')
def latexml(math_code, as_block=False):
"""Convert LaTeX math code to MathML with LaTeXML__.
Comprehensive macro support but **very** slow.
__ http://dlmf.nist.gov/LaTeXML/
"""
# LaTeXML works in 2 stages, expects complete documents.
#
# The `latexmlmath`__ convenience wrapper does not support block-level
# (displayed) equations.
#
# __ https://metacpan.org/dist/LaTeXML/view/bin/latexmlmath
args1 = ['latexml',
'-', # read from stdin
'--preload=amsmath',
'--preload=amssymb', # also loads amsfonts
'--inputencoding=utf8',
'--',
]
math_code = document_template % wrap_math_code(math_code, as_block)
result1 = subprocess.run(args1, input=math_code,
capture_output=True, text=True)
if result1.stderr:
result1.stderr = '\n'.join(line for line in result1.stderr.splitlines()
if line.startswith('Error:')
or line.startswith('Warning:')
or line.startswith('Fatal:'))
_check_result(result1)
args2 = ['latexmlpost',
'-',
'--nonumbersections',
'--format=html5', # maths included as MathML
'--omitdoctype', # Make it simple, we only need the maths.
'--noscan', # ...
'--nocrossref',
'--nographicimages',
'--nopictureimages',
'--nodefaultresources', # do not copy *.css files to output dir
'--'
]
result2 = subprocess.run(args2, input=result1.stdout,
capture_output=True, text=True)
# Extract MathML from HTML document:
# <table> with <math> in cells for "align", <math> element else.
start = result2.stdout.find('<table class="ltx_equationgroup')
if start != -1:
stop = result2.stdout.find('</table>', start)+8
result2.stdout = result2.stdout[start:stop].replace(
'ltx_equationgroup', 'borderless align-center')
else:
result2.stdout = result2.stdout[result2.stdout.find('<math'):
result2.stdout.find('</math>')+7]
# Search for error messages
if result2.stdout:
_msg_source = result2.stdout # latexmlpost reports errors in output
else:
_msg_source = result2.stderr # just in case
result2.stderr = '\n'.join(line for line in _msg_source.splitlines()
if line.startswith('Error:')
or line.startswith('Warning:')
or line.startswith('Fatal:'))
_check_result(result2)
return result2.stdout
def pandoc(math_code, as_block=False):
"""Convert LaTeX math code to MathML with pandoc__.
__ https://pandoc.org/
"""
args = ['pandoc',
'--mathml',
'--from=latex',
]
result = subprocess.run(args, input=wrap_math_code(math_code, as_block),
capture_output=True, text=True)
result.stdout = result.stdout[result.stdout.find('<math'):
result.stdout.find('</math>')+7]
# Pandoc (2.9.2.1) messages are pre-formatted for the terminal:
# 1. summary
# 2. math source (part)
# 3. error spot indicator '^' (works only in a literal block)
# 4. assumed problem
# 5. assumed solution (may be wrong or confusing)
# Construct a "details" list:
details = []
if result.stderr:
lines = result.stderr.splitlines()
details.append(nodes.paragraph('', lines[0]))
details.append(nodes.literal_block('', '\n'.join(lines[1:3])))
details.append(nodes.paragraph('', '\n'.join(lines[3:]),
classes=['pre-wrap']))
_check_result(result, details=details)
return result.stdout
def ttm(math_code, as_block=False):
"""Convert LaTeX math code to MathML with TtM__.
Aged, limited, but fast.
__ http://silas.psfc.mit.edu/tth/mml/
"""
args = ['ttm',
'-L', # source is LaTeX snippet
'-r'] # output MathML snippet
math_code = wrap_math_code(math_code, as_block)
# "ttm" does not support UTF-8 input. (Docutils converts most math
# characters to LaTeX commands before calling this function.)
try:
result = subprocess.run(args, input=math_code,
capture_output=True, text=True,
encoding='ISO-8859-1')
except UnicodeEncodeError as err:
raise MathError(err)
result.stdout = result.stdout[result.stdout.find('<math'):
result.stdout.find('</math>')+7]
if as_block:
result.stdout = result.stdout.replace('<math xmlns=',
'<math display="block" xmlns=')
result.stderr = '\n'.join(line[5:] + '.'
for line in result.stderr.splitlines()
if line.startswith('**** '))
_check_result(result)
return result.stdout
# self-test
if __name__ == "__main__":
example = (r'\frac{\partial \sin^2(\alpha)}{\partial \vec r}'
r'\varpi \mathbb{R} \, \text{Grüße}')
print("""<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<title>test external mathml converters</title>
</head>
<body>
<p>Test external converters</p>
<p>
""")
print(f'latexml: {latexml(example)},')
print(f'ttm: {ttm(example.replace("mathbb", "mathbf"))},')
print(f'blahtexml: {blahtexml(example)},')
print(f'pandoc: {pandoc(example)}.')
print('</p>')
print('<p>latexml:</p>')
print(latexml(example, as_block=True))
print('<p>ttm:</p>')
print(ttm(example.replace('mathbb', 'mathbf'), as_block=True))
print('<p>blahtexml:</p>')
print(blahtexml(example, as_block=True))
print('<p>pandoc:</p>')
print(pandoc(example, as_block=True))
print('</main>\n</body>\n</html>')
buggy = r'\sinc \phy'
# buggy = '\sqrt[e]'
try:
# print(blahtexml(buggy))
# print(latexml(f'${buggy}$'))
print(pandoc(f'${buggy}$'))
# print(ttm(f'${buggy}$'))
except MathError as err:
print(err)
print(err.details)
for node in err.details:
print(node.astext())

View file

@ -0,0 +1,730 @@
#!/usr/bin/env python3
# LaTeX math to Unicode symbols translation dictionaries.
# Generated with ``write_tex2unichar.py`` from the data in
# http://milde.users.sourceforge.net/LUCR/Math/
# Includes commands from:
# standard LaTeX
# amssymb
# amsmath
# amsxtra
# bbold
# esint
# mathabx
# mathdots
# txfonts
# stmaryrd
# wasysym
mathaccent = {
'acute': '\u0301', #  ́ COMBINING ACUTE ACCENT
'bar': '\u0304', #  ̄ COMBINING MACRON
'breve': '\u0306', #  ̆ COMBINING BREVE
'check': '\u030c', #  ̌ COMBINING CARON
'ddddot': '\u20dc', #  ⃜ COMBINING FOUR DOTS ABOVE
'dddot': '\u20db', #  ⃛ COMBINING THREE DOTS ABOVE
'ddot': '\u0308', #  ̈ COMBINING DIAERESIS
'dot': '\u0307', #  ̇ COMBINING DOT ABOVE
'grave': '\u0300', #  ̀ COMBINING GRAVE ACCENT
'hat': '\u0302', #  ̂ COMBINING CIRCUMFLEX ACCENT
'mathring': '\u030a', #  ̊ COMBINING RING ABOVE
'not': '\u0338', #  ̸ COMBINING LONG SOLIDUS OVERLAY
'overleftrightarrow': '\u20e1', #  ⃡ COMBINING LEFT RIGHT ARROW ABOVE
'overline': '\u0305', #  ̅ COMBINING OVERLINE
'tilde': '\u0303', #  ̃ COMBINING TILDE
'underbar': '\u0331', #  ̱ COMBINING MACRON BELOW
'underleftarrow': '\u20ee', #  ⃮ COMBINING LEFT ARROW BELOW
'underline': '\u0332', #  ̲ COMBINING LOW LINE
'underrightarrow': '\u20ef', #  ⃯ COMBINING RIGHT ARROW BELOW
'vec': '\u20d7', #  ⃗ COMBINING RIGHT ARROW ABOVE
}
mathalpha = {
'Bbbk': '\U0001d55c', # 𝕜 MATHEMATICAL DOUBLE-STRUCK SMALL K
'Delta': '\u0394', # Δ GREEK CAPITAL LETTER DELTA
'Gamma': '\u0393', # Γ GREEK CAPITAL LETTER GAMMA
'Im': '\u2111', # BLACK-LETTER CAPITAL I
'Lambda': '\u039b', # Λ GREEK CAPITAL LETTER LAMDA
'Omega': '\u03a9', # Ω GREEK CAPITAL LETTER OMEGA
'Phi': '\u03a6', # Φ GREEK CAPITAL LETTER PHI
'Pi': '\u03a0', # Π GREEK CAPITAL LETTER PI
'Psi': '\u03a8', # Ψ GREEK CAPITAL LETTER PSI
'Re': '\u211c', # BLACK-LETTER CAPITAL R
'Sigma': '\u03a3', # Σ GREEK CAPITAL LETTER SIGMA
'Theta': '\u0398', # Θ GREEK CAPITAL LETTER THETA
'Upsilon': '\u03a5', # Υ GREEK CAPITAL LETTER UPSILON
'Xi': '\u039e', # Ξ GREEK CAPITAL LETTER XI
'aleph': '\u2135', # ℵ ALEF SYMBOL
'alpha': '\u03b1', # α GREEK SMALL LETTER ALPHA
'beta': '\u03b2', # β GREEK SMALL LETTER BETA
'beth': '\u2136', # ℶ BET SYMBOL
'chi': '\u03c7', # χ GREEK SMALL LETTER CHI
'daleth': '\u2138', # ℸ DALET SYMBOL
'delta': '\u03b4', # δ GREEK SMALL LETTER DELTA
'digamma': '\u03dd', # ϝ GREEK SMALL LETTER DIGAMMA
'ell': '\u2113', # SCRIPT SMALL L
'epsilon': '\u03f5', # ϵ GREEK LUNATE EPSILON SYMBOL
'eta': '\u03b7', # η GREEK SMALL LETTER ETA
'eth': '\xf0', # ð LATIN SMALL LETTER ETH
'gamma': '\u03b3', # γ GREEK SMALL LETTER GAMMA
'gimel': '\u2137', # ℷ GIMEL SYMBOL
'imath': '\u0131', # ı LATIN SMALL LETTER DOTLESS I
'iota': '\u03b9', # ι GREEK SMALL LETTER IOTA
'jmath': '\u0237', # ȷ LATIN SMALL LETTER DOTLESS J
'kappa': '\u03ba', # κ GREEK SMALL LETTER KAPPA
'lambda': '\u03bb', # λ GREEK SMALL LETTER LAMDA
'mu': '\u03bc', # μ GREEK SMALL LETTER MU
'nu': '\u03bd', # ν GREEK SMALL LETTER NU
'omega': '\u03c9', # ω GREEK SMALL LETTER OMEGA
'phi': '\u03d5', # ϕ GREEK PHI SYMBOL
'pi': '\u03c0', # π GREEK SMALL LETTER PI
'psi': '\u03c8', # ψ GREEK SMALL LETTER PSI
'rho': '\u03c1', # ρ GREEK SMALL LETTER RHO
'sigma': '\u03c3', # σ GREEK SMALL LETTER SIGMA
'tau': '\u03c4', # τ GREEK SMALL LETTER TAU
'theta': '\u03b8', # θ GREEK SMALL LETTER THETA
'upsilon': '\u03c5', # υ GREEK SMALL LETTER UPSILON
'varDelta': '\U0001d6e5', # 𝛥 MATHEMATICAL ITALIC CAPITAL DELTA
'varGamma': '\U0001d6e4', # 𝛤 MATHEMATICAL ITALIC CAPITAL GAMMA
'varLambda': '\U0001d6ec', # 𝛬 MATHEMATICAL ITALIC CAPITAL LAMDA
'varOmega': '\U0001d6fa', # 𝛺 MATHEMATICAL ITALIC CAPITAL OMEGA
'varPhi': '\U0001d6f7', # 𝛷 MATHEMATICAL ITALIC CAPITAL PHI
'varPi': '\U0001d6f1', # 𝛱 MATHEMATICAL ITALIC CAPITAL PI
'varPsi': '\U0001d6f9', # 𝛹 MATHEMATICAL ITALIC CAPITAL PSI
'varSigma': '\U0001d6f4', # 𝛴 MATHEMATICAL ITALIC CAPITAL SIGMA
'varTheta': '\U0001d6e9', # 𝛩 MATHEMATICAL ITALIC CAPITAL THETA
'varUpsilon': '\U0001d6f6', # 𝛶 MATHEMATICAL ITALIC CAPITAL UPSILON
'varXi': '\U0001d6ef', # 𝛯 MATHEMATICAL ITALIC CAPITAL XI
'varepsilon': '\u03b5', # ε GREEK SMALL LETTER EPSILON
'varkappa': '\u03f0', # ϰ GREEK KAPPA SYMBOL
'varphi': '\u03c6', # φ GREEK SMALL LETTER PHI
'varpi': '\u03d6', # ϖ GREEK PI SYMBOL
'varrho': '\u03f1', # ϱ GREEK RHO SYMBOL
'varsigma': '\u03c2', # ς GREEK SMALL LETTER FINAL SIGMA
'vartheta': '\u03d1', # ϑ GREEK THETA SYMBOL
'wp': '\u2118', # ℘ SCRIPT CAPITAL P
'xi': '\u03be', # ξ GREEK SMALL LETTER XI
'zeta': '\u03b6', # ζ GREEK SMALL LETTER ZETA
}
mathbin = {
'Cap': '\u22d2', # ⋒ DOUBLE INTERSECTION
'Circle': '\u25cb', # ○ WHITE CIRCLE
'Cup': '\u22d3', # ⋓ DOUBLE UNION
'LHD': '\u25c0', # ◀ BLACK LEFT-POINTING TRIANGLE
'RHD': '\u25b6', # ▶ BLACK RIGHT-POINTING TRIANGLE
'amalg': '\u2a3f', # ⨿ AMALGAMATION OR COPRODUCT
'ast': '\u2217', # ASTERISK OPERATOR
'barwedge': '\u22bc', # ⊼ NAND
'bigcirc': '\u25ef', # ◯ LARGE CIRCLE
'bigtriangledown': '\u25bd', # ▽ WHITE DOWN-POINTING TRIANGLE
'bigtriangleup': '\u25b3', # △ WHITE UP-POINTING TRIANGLE
'bindnasrepma': '\u214b', # ⅋ TURNED AMPERSAND
'blacklozenge': '\u29eb', # ⧫ BLACK LOZENGE
'boxast': '\u29c6', # ⧆ SQUARED ASTERISK
'boxbar': '\u25eb', # ◫ WHITE SQUARE WITH VERTICAL BISECTING LINE
'boxbox': '\u29c8', # ⧈ SQUARED SQUARE
'boxbslash': '\u29c5', # ⧅ SQUARED FALLING DIAGONAL SLASH
'boxcircle': '\u29c7', # ⧇ SQUARED SMALL CIRCLE
'boxdot': '\u22a1', # ⊡ SQUARED DOT OPERATOR
'boxminus': '\u229f', # ⊟ SQUARED MINUS
'boxplus': '\u229e', # ⊞ SQUARED PLUS
'boxslash': '\u29c4', # ⧄ SQUARED RISING DIAGONAL SLASH
'boxtimes': '\u22a0', # ⊠ SQUARED TIMES
'bullet': '\u2022', # • BULLET
'cap': '\u2229', # ∩ INTERSECTION
'cdot': '\u22c5', # ⋅ DOT OPERATOR
'circ': '\u2218', # ∘ RING OPERATOR
'circledast': '\u229b', # ⊛ CIRCLED ASTERISK OPERATOR
'circledbslash': '\u29b8', # ⦸ CIRCLED REVERSE SOLIDUS
'circledcirc': '\u229a', # ⊚ CIRCLED RING OPERATOR
'circleddash': '\u229d', # ⊝ CIRCLED DASH
'circledgtr': '\u29c1', # ⧁ CIRCLED GREATER-THAN
'circledless': '\u29c0', # ⧀ CIRCLED LESS-THAN
'cup': '\u222a', # UNION
'curlyvee': '\u22ce', # ⋎ CURLY LOGICAL OR
'curlywedge': '\u22cf', # ⋏ CURLY LOGICAL AND
'dagger': '\u2020', # † DAGGER
'ddagger': '\u2021', # ‡ DOUBLE DAGGER
'diamond': '\u22c4', # ⋄ DIAMOND OPERATOR
'div': '\xf7', # ÷ DIVISION SIGN
'divideontimes': '\u22c7', # ⋇ DIVISION TIMES
'dotplus': '\u2214', # ∔ DOT PLUS
'doublebarwedge': '\u2a5e', # ⩞ LOGICAL AND WITH DOUBLE OVERBAR
'gtrdot': '\u22d7', # ⋗ GREATER-THAN WITH DOT
'intercal': '\u22ba', # ⊺ INTERCALATE
'interleave': '\u2af4', # ⫴ TRIPLE VERTICAL BAR BINARY RELATION
'invamp': '\u214b', # ⅋ TURNED AMPERSAND
'land': '\u2227', # ∧ LOGICAL AND
'leftthreetimes': '\u22cb', # ⋋ LEFT SEMIDIRECT PRODUCT
'lessdot': '\u22d6', # ⋖ LESS-THAN WITH DOT
'lor': '\u2228', # LOGICAL OR
'ltimes': '\u22c9', # ⋉ LEFT NORMAL FACTOR SEMIDIRECT PRODUCT
'mp': '\u2213', # ∓ MINUS-OR-PLUS SIGN
'odot': '\u2299', # ⊙ CIRCLED DOT OPERATOR
'ominus': '\u2296', # ⊖ CIRCLED MINUS
'oplus': '\u2295', # ⊕ CIRCLED PLUS
'oslash': '\u2298', # ⊘ CIRCLED DIVISION SLASH
'otimes': '\u2297', # ⊗ CIRCLED TIMES
'pm': '\xb1', # ± PLUS-MINUS SIGN
'rightthreetimes': '\u22cc', # ⋌ RIGHT SEMIDIRECT PRODUCT
'rtimes': '\u22ca', # ⋊ RIGHT NORMAL FACTOR SEMIDIRECT PRODUCT
'setminus': '\u29f5', # REVERSE SOLIDUS OPERATOR
'slash': '\u2215', # DIVISION SLASH
'smallsetminus': '\u2216', # SET MINUS
'smalltriangledown': '\u25bf', # ▿ WHITE DOWN-POINTING SMALL TRIANGLE
'smalltriangleleft': '\u25c3', # ◃ WHITE LEFT-POINTING SMALL TRIANGLE
'smalltriangleright': '\u25b9', # ▹ WHITE RIGHT-POINTING SMALL TRIANGLE
'sqcap': '\u2293', # ⊓ SQUARE CAP
'sqcup': '\u2294', # ⊔ SQUARE CUP
'sslash': '\u2afd', # ⫽ DOUBLE SOLIDUS OPERATOR
'star': '\u22c6', # ⋆ STAR OPERATOR
'talloblong': '\u2afe', # ⫾ WHITE VERTICAL BAR
'times': '\xd7', # × MULTIPLICATION SIGN
'triangleleft': '\u25c3', # ◃ WHITE LEFT-POINTING SMALL TRIANGLE
'triangleright': '\u25b9', # ▹ WHITE RIGHT-POINTING SMALL TRIANGLE
'uplus': '\u228e', # ⊎ MULTISET UNION
'vee': '\u2228', # LOGICAL OR
'veebar': '\u22bb', # ⊻ XOR
'wedge': '\u2227', # ∧ LOGICAL AND
'wr': '\u2240', # ≀ WREATH PRODUCT
}
mathclose = {
'Rbag': '\u27c6', # ⟆ RIGHT S-SHAPED BAG DELIMITER
'lrcorner': '\u231f', # ⌟ BOTTOM RIGHT CORNER
'rangle': '\u27e9', # ⟩ MATHEMATICAL RIGHT ANGLE BRACKET
'rbag': '\u27c6', # ⟆ RIGHT S-SHAPED BAG DELIMITER
'rbrace': '}', # } RIGHT CURLY BRACKET
'rbrack': ']', # ] RIGHT SQUARE BRACKET
'rceil': '\u2309', # ⌉ RIGHT CEILING
'rfloor': '\u230b', # ⌋ RIGHT FLOOR
'rgroup': '\u27ef', # ⟯ MATHEMATICAL RIGHT FLATTENED PARENTHESIS
'rrbracket': '\u27e7', # ⟧ MATHEMATICAL RIGHT WHITE SQUARE BRACKET
'rrparenthesis': '\u2988', # ⦈ Z NOTATION RIGHT IMAGE BRACKET
'urcorner': '\u231d', # ⌝ TOP RIGHT CORNER
'}': '}', # } RIGHT CURLY BRACKET
}
mathfence = {
'Vert': '\u2016', # ‖ DOUBLE VERTICAL LINE
'vert': '|', # | VERTICAL LINE
'|': '\u2016', # ‖ DOUBLE VERTICAL LINE
}
mathop = {
'bigcap': '\u22c2', # ⋂ N-ARY INTERSECTION
'bigcup': '\u22c3', # N-ARY UNION
'biginterleave': '\u2afc', # ⫼ LARGE TRIPLE VERTICAL BAR OPERATOR
'bigodot': '\u2a00', # ⨀ N-ARY CIRCLED DOT OPERATOR
'bigoplus': '\u2a01', # ⨁ N-ARY CIRCLED PLUS OPERATOR
'bigotimes': '\u2a02', # ⨂ N-ARY CIRCLED TIMES OPERATOR
'bigsqcap': '\u2a05', # ⨅ N-ARY SQUARE INTERSECTION OPERATOR
'bigsqcup': '\u2a06', # ⨆ N-ARY SQUARE UNION OPERATOR
'biguplus': '\u2a04', # ⨄ N-ARY UNION OPERATOR WITH PLUS
'bigvee': '\u22c1', # N-ARY LOGICAL OR
'bigwedge': '\u22c0', # ⋀ N-ARY LOGICAL AND
'coprod': '\u2210', # ∐ N-ARY COPRODUCT
'fatsemi': '\u2a1f', # ⨟ Z NOTATION SCHEMA COMPOSITION
'fint': '\u2a0f', # ⨏ INTEGRAL AVERAGE WITH SLASH
'iiiint': '\u2a0c', # ⨌ QUADRUPLE INTEGRAL OPERATOR
'iiint': '\u222d', # ∭ TRIPLE INTEGRAL
'iint': '\u222c', # ∬ DOUBLE INTEGRAL
'int': '\u222b', # ∫ INTEGRAL
'intop': '\u222b', # ∫ INTEGRAL
'oiiint': '\u2230', # ∰ VOLUME INTEGRAL
'oiint': '\u222f', # ∯ SURFACE INTEGRAL
'oint': '\u222e', # ∮ CONTOUR INTEGRAL
'ointctrclockwise': '\u2233', # ∳ ANTICLOCKWISE CONTOUR INTEGRAL
'ointop': '\u222e', # ∮ CONTOUR INTEGRAL
'prod': '\u220f', # ∏ N-ARY PRODUCT
'sqint': '\u2a16', # ⨖ QUATERNION INTEGRAL OPERATOR
'sum': '\u2211', # ∑ N-ARY SUMMATION
'varointclockwise': '\u2232', # ∲ CLOCKWISE CONTOUR INTEGRAL
'varprod': '\u2a09', # ⨉ N-ARY TIMES OPERATOR
}
mathopen = {
'Lbag': '\u27c5', # ⟅ LEFT S-SHAPED BAG DELIMITER
'langle': '\u27e8', # ⟨ MATHEMATICAL LEFT ANGLE BRACKET
'lbag': '\u27c5', # ⟅ LEFT S-SHAPED BAG DELIMITER
'lbrace': '{', # { LEFT CURLY BRACKET
'lbrack': '[', # [ LEFT SQUARE BRACKET
'lceil': '\u2308', # ⌈ LEFT CEILING
'lfloor': '\u230a', # ⌊ LEFT FLOOR
'lgroup': '\u27ee', # ⟮ MATHEMATICAL LEFT FLATTENED PARENTHESIS
'llbracket': '\u27e6', # ⟦ MATHEMATICAL LEFT WHITE SQUARE BRACKET
'llcorner': '\u231e', # ⌞ BOTTOM LEFT CORNER
'llparenthesis': '\u2987', # ⦇ Z NOTATION LEFT IMAGE BRACKET
'ulcorner': '\u231c', # ⌜ TOP LEFT CORNER
'{': '{', # { LEFT CURLY BRACKET
}
mathord = {
'#': '#', # # NUMBER SIGN
'$': '$', # $ DOLLAR SIGN
'%': '%', # % PERCENT SIGN
'&': '&', # & AMPERSAND
'AC': '\u223f', # ∿ SINE WAVE
'APLcomment': '\u235d', # ⍝ APL FUNCTIONAL SYMBOL UP SHOE JOT
'APLdownarrowbox': '\u2357', # ⍗ APL FUNCTIONAL SYMBOL QUAD DOWNWARDS ARROW
'APLinput': '\u235e', # ⍞ APL FUNCTIONAL SYMBOL QUOTE QUAD
'APLinv': '\u2339', # ⌹ APL FUNCTIONAL SYMBOL QUAD DIVIDE
'APLleftarrowbox': '\u2347', # ⍇ APL FUNCTIONAL SYMBOL QUAD LEFTWARDS ARROW
'APLlog': '\u235f', # ⍟ APL FUNCTIONAL SYMBOL CIRCLE STAR
'APLrightarrowbox': '\u2348', # ⍈ APL FUNCTIONAL SYMBOL QUAD RIGHTWARDS ARROW
'APLuparrowbox': '\u2350', # ⍐ APL FUNCTIONAL SYMBOL QUAD UPWARDS ARROW
'Aries': '\u2648', # ♈ ARIES
'Box': '\u2b1c', # ⬜ WHITE LARGE SQUARE
'CIRCLE': '\u25cf', # ● BLACK CIRCLE
'CheckedBox': '\u2611', # ☑ BALLOT BOX WITH CHECK
'Diamond': '\u25c7', # ◇ WHITE DIAMOND
'Diamondblack': '\u25c6', # ◆ BLACK DIAMOND
'Diamonddot': '\u27d0', # ⟐ WHITE DIAMOND WITH CENTRED DOT
'Finv': '\u2132', # Ⅎ TURNED CAPITAL F
'Game': '\u2141', # ⅁ TURNED SANS-SERIF CAPITAL G
'Gemini': '\u264a', # ♊ GEMINI
'Jupiter': '\u2643', # ♃ JUPITER
'LEFTCIRCLE': '\u25d6', # ◖ LEFT HALF BLACK CIRCLE
'LEFTcircle': '\u25d0', # ◐ CIRCLE WITH LEFT HALF BLACK
'Leo': '\u264c', # ♌ LEO
'Libra': '\u264e', # ♎ LIBRA
'Mars': '\u2642', # ♂ MALE SIGN
'Mercury': '\u263f', # ☿ MERCURY
'Neptune': '\u2646', # ♆ NEPTUNE
'P': '\xb6', # ¶ PILCROW SIGN
'Pluto': '\u2647', # ♇ PLUTO
'RIGHTCIRCLE': '\u25d7', # ◗ RIGHT HALF BLACK CIRCLE
'RIGHTcircle': '\u25d1', # ◑ CIRCLE WITH RIGHT HALF BLACK
'S': '\xa7', # § SECTION SIGN
'Saturn': '\u2644', # ♄ SATURN
'Scorpio': '\u264f', # ♏ SCORPIUS
'Square': '\u2610', # ☐ BALLOT BOX
'Sun': '\u2609', # ☉ SUN
'Taurus': '\u2649', # ♉ TAURUS
'Uranus': '\u2645', # ♅ URANUS
'Venus': '\u2640', # ♀ FEMALE SIGN
'XBox': '\u2612', # ☒ BALLOT BOX WITH X
'Yup': '\u2144', # ⅄ TURNED SANS-SERIF CAPITAL Y
'_': '_', # _ LOW LINE
'angle': '\u2220', # ∠ ANGLE
'aquarius': '\u2652', # ♒ AQUARIUS
'aries': '\u2648', # ♈ ARIES
'arrowvert': '\u23d0', # ⏐ VERTICAL LINE EXTENSION
'backprime': '\u2035', # REVERSED PRIME
'backslash': '\\', # \ REVERSE SOLIDUS
'bigstar': '\u2605', # ★ BLACK STAR
'blacksmiley': '\u263b', # ☻ BLACK SMILING FACE
'blacksquare': '\u25fc', # ◼ BLACK MEDIUM SQUARE
'blacktriangle': '\u25b4', # ▴ BLACK UP-POINTING SMALL TRIANGLE
'blacktriangledown': '\u25be', # ▾ BLACK DOWN-POINTING SMALL TRIANGLE
'blacktriangleup': '\u25b4', # ▴ BLACK UP-POINTING SMALL TRIANGLE
'bot': '\u22a5', # ⊥ UP TACK
'boy': '\u2642', # ♂ MALE SIGN
'bracevert': '\u23aa', # ⎪ CURLY BRACKET EXTENSION
'cancer': '\u264b', # ♋ CANCER
'capricornus': '\u2651', # ♑ CAPRICORN
'cdots': '\u22ef', # ⋯ MIDLINE HORIZONTAL ELLIPSIS
'cent': '\xa2', # ¢ CENT SIGN
'checkmark': '\u2713', # ✓ CHECK MARK
'circledR': '\u24c7', # Ⓡ CIRCLED LATIN CAPITAL LETTER R
'circledS': '\u24c8', # Ⓢ CIRCLED LATIN CAPITAL LETTER S
'clubsuit': '\u2663', # ♣ BLACK CLUB SUIT
'complement': '\u2201', # ∁ COMPLEMENT
'diagdown': '\u27cd', # MATHEMATICAL FALLING DIAGONAL
'diagup': '\u27cb', # MATHEMATICAL RISING DIAGONAL
'diameter': '\u2300', # ⌀ DIAMETER SIGN
'diamondsuit': '\u2662', # ♢ WHITE DIAMOND SUIT
'earth': '\u2641', # ♁ EARTH
'emptyset': '\u2205', # ∅ EMPTY SET
'exists': '\u2203', # ∃ THERE EXISTS
'female': '\u2640', # ♀ FEMALE SIGN
'flat': '\u266d', # ♭ MUSIC FLAT SIGN
'forall': '\u2200', # ∀ FOR ALL
'fourth': '\u2057', # ⁗ QUADRUPLE PRIME
'frownie': '\u2639', # ☹ WHITE FROWNING FACE
'gemini': '\u264a', # ♊ GEMINI
'girl': '\u2640', # ♀ FEMALE SIGN
'heartsuit': '\u2661', # ♡ WHITE HEART SUIT
'hslash': '\u210f', # ℏ PLANCK CONSTANT OVER TWO PI
'infty': '\u221e', # ∞ INFINITY
'invdiameter': '\u2349', # ⍉ APL FUNCTIONAL SYMBOL CIRCLE BACKSLASH
'invneg': '\u2310', # ⌐ REVERSED NOT SIGN
'jupiter': '\u2643', # ♃ JUPITER
'ldots': '\u2026', # … HORIZONTAL ELLIPSIS
'leftmoon': '\u263e', # ☾ LAST QUARTER MOON
'leo': '\u264c', # ♌ LEO
'libra': '\u264e', # ♎ LIBRA
'lmoustache': '\u23b0', # ⎰ UPPER LEFT OR LOWER RIGHT CURLY BRACKET SECTION
'lnot': '\xac', # ¬ NOT SIGN
'lozenge': '\u25ca', # ◊ LOZENGE
'male': '\u2642', # ♂ MALE SIGN
'maltese': '\u2720', # ✠ MALTESE CROSS
'mathcent': '\xa2', # ¢ CENT SIGN
'mathdollar': '$', # $ DOLLAR SIGN
'mathsterling': '\xa3', # £ POUND SIGN
'measuredangle': '\u2221', # ∡ MEASURED ANGLE
'medbullet': '\u26ab', # ⚫ MEDIUM BLACK CIRCLE
'medcirc': '\u26aa', # ⚪ MEDIUM WHITE CIRCLE
'mercury': '\u263f', # ☿ MERCURY
'mho': '\u2127', # ℧ INVERTED OHM SIGN
'nabla': '\u2207', # ∇ NABLA
'natural': '\u266e', # ♮ MUSIC NATURAL SIGN
'neg': '\xac', # ¬ NOT SIGN
'neptune': '\u2646', # ♆ NEPTUNE
'nexists': '\u2204', # ∄ THERE DOES NOT EXIST
'notbackslash': '\u2340', # ⍀ APL FUNCTIONAL SYMBOL BACKSLASH BAR
'partial': '\u2202', # ∂ PARTIAL DIFFERENTIAL
'pisces': '\u2653', # ♓ PISCES
'pluto': '\u2647', # ♇ PLUTO
'pounds': '\xa3', # £ POUND SIGN
'prime': '\u2032', # PRIME
'quarternote': '\u2669', # ♩ QUARTER NOTE
'rightmoon': '\u263d', # ☽ FIRST QUARTER MOON
'rmoustache': '\u23b1', # ⎱ UPPER RIGHT OR LOWER LEFT CURLY BRACKET SECTION
'sagittarius': '\u2650', # ♐ SAGITTARIUS
'saturn': '\u2644', # ♄ SATURN
'scorpio': '\u264f', # ♏ SCORPIUS
'second': '\u2033', # ″ DOUBLE PRIME
'sharp': '\u266f', # ♯ MUSIC SHARP SIGN
'smiley': '\u263a', # ☺ WHITE SMILING FACE
'spadesuit': '\u2660', # ♠ BLACK SPADE SUIT
'spddot': '\xa8', # ¨ DIAERESIS
'sphat': '^', # ^ CIRCUMFLEX ACCENT
'sphericalangle': '\u2222', # ∢ SPHERICAL ANGLE
'sptilde': '~', # ~ TILDE
'square': '\u25fb', # ◻ WHITE MEDIUM SQUARE
'sun': '\u263c', # ☼ WHITE SUN WITH RAYS
'surd': '\u221a', # √ SQUARE ROOT
'taurus': '\u2649', # ♉ TAURUS
'third': '\u2034', # ‴ TRIPLE PRIME
'top': '\u22a4', # DOWN TACK
'twonotes': '\u266b', # ♫ BEAMED EIGHTH NOTES
'uranus': '\u2645', # ♅ URANUS
'varEarth': '\u2641', # ♁ EARTH
'varclubsuit': '\u2667', # ♧ WHITE CLUB SUIT
'vardiamondsuit': '\u2666', # ♦ BLACK DIAMOND SUIT
'varheartsuit': '\u2665', # ♥ BLACK HEART SUIT
'varspadesuit': '\u2664', # ♤ WHITE SPADE SUIT
'virgo': '\u264d', # ♍ VIRGO
'wasylozenge': '\u2311', # ⌑ SQUARE LOZENGE
'yen': '\xa5', # ¥ YEN SIGN
}
mathover = {
'overbrace': '\u23de', # ⏞ TOP CURLY BRACKET
'wideparen': '\u23dc', # ⏜ TOP PARENTHESIS
}
mathpunct = {
'ddots': '\u22f1', # ⋱ DOWN RIGHT DIAGONAL ELLIPSIS
'vdots': '\u22ee', # ⋮ VERTICAL ELLIPSIS
}
mathradical = {
'sqrt[3]': '\u221b', # ∛ CUBE ROOT
'sqrt[4]': '\u221c', # ∜ FOURTH ROOT
}
mathrel = {
'Bot': '\u2aeb', # ⫫ DOUBLE UP TACK
'Bumpeq': '\u224e', # ≎ GEOMETRICALLY EQUIVALENT TO
'Coloneqq': '\u2a74', # ⩴ DOUBLE COLON EQUAL
'Doteq': '\u2251', # ≑ GEOMETRICALLY EQUAL TO
'Downarrow': '\u21d3', # ⇓ DOWNWARDS DOUBLE ARROW
'Leftarrow': '\u21d0', # ⇐ LEFTWARDS DOUBLE ARROW
'Leftrightarrow': '\u21d4', # ⇔ LEFT RIGHT DOUBLE ARROW
'Lleftarrow': '\u21da', # ⇚ LEFTWARDS TRIPLE ARROW
'Longleftarrow': '\u27f8', # ⟸ LONG LEFTWARDS DOUBLE ARROW
'Longleftrightarrow': '\u27fa', # ⟺ LONG LEFT RIGHT DOUBLE ARROW
'Longmapsfrom': '\u27fd', # ⟽ LONG LEFTWARDS DOUBLE ARROW FROM BAR
'Longmapsto': '\u27fe', # ⟾ LONG RIGHTWARDS DOUBLE ARROW FROM BAR
'Longrightarrow': '\u27f9', # ⟹ LONG RIGHTWARDS DOUBLE ARROW
'Lsh': '\u21b0', # ↰ UPWARDS ARROW WITH TIP LEFTWARDS
'Mapsfrom': '\u2906', # ⤆ LEFTWARDS DOUBLE ARROW FROM BAR
'Mapsto': '\u2907', # ⤇ RIGHTWARDS DOUBLE ARROW FROM BAR
'Nearrow': '\u21d7', # ⇗ NORTH EAST DOUBLE ARROW
'Nwarrow': '\u21d6', # ⇖ NORTH WEST DOUBLE ARROW
'Perp': '\u2aeb', # ⫫ DOUBLE UP TACK
'Rightarrow': '\u21d2', # ⇒ RIGHTWARDS DOUBLE ARROW
'Rrightarrow': '\u21db', # ⇛ RIGHTWARDS TRIPLE ARROW
'Rsh': '\u21b1', # ↱ UPWARDS ARROW WITH TIP RIGHTWARDS
'Searrow': '\u21d8', # ⇘ SOUTH EAST DOUBLE ARROW
'Subset': '\u22d0', # ⋐ DOUBLE SUBSET
'Supset': '\u22d1', # ⋑ DOUBLE SUPERSET
'Swarrow': '\u21d9', # ⇙ SOUTH WEST DOUBLE ARROW
'Top': '\u2aea', # ⫪ DOUBLE DOWN TACK
'Uparrow': '\u21d1', # ⇑ UPWARDS DOUBLE ARROW
'Updownarrow': '\u21d5', # ⇕ UP DOWN DOUBLE ARROW
'VDash': '\u22ab', # ⊫ DOUBLE VERTICAL BAR DOUBLE RIGHT TURNSTILE
'Vdash': '\u22a9', # ⊩ FORCES
'Vvdash': '\u22aa', # ⊪ TRIPLE VERTICAL BAR RIGHT TURNSTILE
'apprge': '\u2273', # ≳ GREATER-THAN OR EQUIVALENT TO
'apprle': '\u2272', # ≲ LESS-THAN OR EQUIVALENT TO
'approx': '\u2248', # ≈ ALMOST EQUAL TO
'approxeq': '\u224a', # ≊ ALMOST EQUAL OR EQUAL TO
'asymp': '\u224d', # ≍ EQUIVALENT TO
'backepsilon': '\u220d', # ∍ SMALL CONTAINS AS MEMBER
'backsim': '\u223d', # ∽ REVERSED TILDE
'backsimeq': '\u22cd', # ⋍ REVERSED TILDE EQUALS
'barin': '\u22f6', # ⋶ ELEMENT OF WITH OVERBAR
'barleftharpoon': '\u296b', # ⥫ LEFTWARDS HARPOON WITH BARB DOWN BELOW LONG DASH
'barrightharpoon': '\u296d', # ⥭ RIGHTWARDS HARPOON WITH BARB DOWN BELOW LONG DASH
'because': '\u2235', # ∵ BECAUSE
'between': '\u226c', # ≬ BETWEEN
'blacktriangleleft': '\u25c2', # ◂ BLACK LEFT-POINTING SMALL TRIANGLE
'blacktriangleright': '\u25b8', # ▸ BLACK RIGHT-POINTING SMALL TRIANGLE
'bowtie': '\u22c8', # ⋈ BOWTIE
'bumpeq': '\u224f', # ≏ DIFFERENCE BETWEEN
'circeq': '\u2257', # ≗ RING EQUAL TO
'circlearrowleft': '\u21ba', # ↺ ANTICLOCKWISE OPEN CIRCLE ARROW
'circlearrowright': '\u21bb', # ↻ CLOCKWISE OPEN CIRCLE ARROW
'coloneq': '\u2254', # ≔ COLON EQUALS
'coloneqq': '\u2254', # ≔ COLON EQUALS
'cong': '\u2245', # ≅ APPROXIMATELY EQUAL TO
'corresponds': '\u2259', # ≙ ESTIMATES
'curlyeqprec': '\u22de', # ⋞ EQUAL TO OR PRECEDES
'curlyeqsucc': '\u22df', # ⋟ EQUAL TO OR SUCCEEDS
'curvearrowleft': '\u21b6', # ↶ ANTICLOCKWISE TOP SEMICIRCLE ARROW
'curvearrowright': '\u21b7', # ↷ CLOCKWISE TOP SEMICIRCLE ARROW
'dasharrow': '\u21e2', # ⇢ RIGHTWARDS DASHED ARROW
'dashleftarrow': '\u21e0', # ⇠ LEFTWARDS DASHED ARROW
'dashrightarrow': '\u21e2', # ⇢ RIGHTWARDS DASHED ARROW
'dashv': '\u22a3', # ⊣ LEFT TACK
'dlsh': '\u21b2', # ↲ DOWNWARDS ARROW WITH TIP LEFTWARDS
'doteq': '\u2250', # ≐ APPROACHES THE LIMIT
'doteqdot': '\u2251', # ≑ GEOMETRICALLY EQUAL TO
'downarrow': '\u2193', # ↓ DOWNWARDS ARROW
'downdownarrows': '\u21ca', # ⇊ DOWNWARDS PAIRED ARROWS
'downdownharpoons': '\u2965', # ⥥ DOWNWARDS HARPOON WITH BARB LEFT BESIDE DOWNWARDS HARPOON WITH BARB RIGHT
'downharpoonleft': '\u21c3', # ⇃ DOWNWARDS HARPOON WITH BARB LEFTWARDS
'downharpoonright': '\u21c2', # ⇂ DOWNWARDS HARPOON WITH BARB RIGHTWARDS
'downuparrows': '\u21f5', # ⇵ DOWNWARDS ARROW LEFTWARDS OF UPWARDS ARROW
'downupharpoons': '\u296f', # ⥯ DOWNWARDS HARPOON WITH BARB LEFT BESIDE UPWARDS HARPOON WITH BARB RIGHT
'drsh': '\u21b3', # ↳ DOWNWARDS ARROW WITH TIP RIGHTWARDS
'eqcirc': '\u2256', # ≖ RING IN EQUAL TO
'eqcolon': '\u2255', # ≕ EQUALS COLON
'eqqcolon': '\u2255', # ≕ EQUALS COLON
'eqsim': '\u2242', # ≂ MINUS TILDE
'eqslantgtr': '\u2a96', # ⪖ SLANTED EQUAL TO OR GREATER-THAN
'eqslantless': '\u2a95', # ⪕ SLANTED EQUAL TO OR LESS-THAN
'equiv': '\u2261', # ≡ IDENTICAL TO
'fallingdotseq': '\u2252', # ≒ APPROXIMATELY EQUAL TO OR THE IMAGE OF
'frown': '\u2322', # ⌢ FROWN
'ge': '\u2265', # ≥ GREATER-THAN OR EQUAL TO
'geq': '\u2265', # ≥ GREATER-THAN OR EQUAL TO
'geqq': '\u2267', # ≧ GREATER-THAN OVER EQUAL TO
'geqslant': '\u2a7e', # ⩾ GREATER-THAN OR SLANTED EQUAL TO
'gets': '\u2190', # ← LEFTWARDS ARROW
'gg': '\u226b', # ≫ MUCH GREATER-THAN
'ggcurly': '\u2abc', # ⪼ DOUBLE SUCCEEDS
'ggg': '\u22d9', # ⋙ VERY MUCH GREATER-THAN
'gggtr': '\u22d9', # ⋙ VERY MUCH GREATER-THAN
'gnapprox': '\u2a8a', # ⪊ GREATER-THAN AND NOT APPROXIMATE
'gneq': '\u2a88', # ⪈ GREATER-THAN AND SINGLE-LINE NOT EQUAL TO
'gneqq': '\u2269', # ≩ GREATER-THAN BUT NOT EQUAL TO
'gnsim': '\u22e7', # ⋧ GREATER-THAN BUT NOT EQUIVALENT TO
'gtrapprox': '\u2a86', # ⪆ GREATER-THAN OR APPROXIMATE
'gtreqless': '\u22db', # ⋛ GREATER-THAN EQUAL TO OR LESS-THAN
'gtreqqless': '\u2a8c', # ⪌ GREATER-THAN ABOVE DOUBLE-LINE EQUAL ABOVE LESS-THAN
'gtrless': '\u2277', # ≷ GREATER-THAN OR LESS-THAN
'gtrsim': '\u2273', # ≳ GREATER-THAN OR EQUIVALENT TO
'hash': '\u22d5', # ⋕ EQUAL AND PARALLEL TO
'hookleftarrow': '\u21a9', # ↩ LEFTWARDS ARROW WITH HOOK
'hookrightarrow': '\u21aa', # ↪ RIGHTWARDS ARROW WITH HOOK
'iddots': '\u22f0', # ⋰ UP RIGHT DIAGONAL ELLIPSIS
'impliedby': '\u27f8', # ⟸ LONG LEFTWARDS DOUBLE ARROW
'implies': '\u27f9', # ⟹ LONG RIGHTWARDS DOUBLE ARROW
'in': '\u2208', # ∈ ELEMENT OF
'le': '\u2264', # ≤ LESS-THAN OR EQUAL TO
'leadsto': '\u2933', # ⤳ WAVE ARROW POINTING DIRECTLY RIGHT
'leftarrow': '\u2190', # ← LEFTWARDS ARROW
'leftarrowtail': '\u21a2', # ↢ LEFTWARDS ARROW WITH TAIL
'leftarrowtriangle': '\u21fd', # ⇽ LEFTWARDS OPEN-HEADED ARROW
'leftbarharpoon': '\u296a', # ⥪ LEFTWARDS HARPOON WITH BARB UP ABOVE LONG DASH
'leftharpoondown': '\u21bd', # ↽ LEFTWARDS HARPOON WITH BARB DOWNWARDS
'leftharpoonup': '\u21bc', # ↼ LEFTWARDS HARPOON WITH BARB UPWARDS
'leftleftarrows': '\u21c7', # ⇇ LEFTWARDS PAIRED ARROWS
'leftleftharpoons': '\u2962', # ⥢ LEFTWARDS HARPOON WITH BARB UP ABOVE LEFTWARDS HARPOON WITH BARB DOWN
'leftrightarrow': '\u2194', # ↔ LEFT RIGHT ARROW
'leftrightarrows': '\u21c6', # ⇆ LEFTWARDS ARROW OVER RIGHTWARDS ARROW
'leftrightarrowtriangle': '\u21ff', # ⇿ LEFT RIGHT OPEN-HEADED ARROW
'leftrightharpoon': '\u294a', # ⥊ LEFT BARB UP RIGHT BARB DOWN HARPOON
'leftrightharpoons': '\u21cb', # ⇋ LEFTWARDS HARPOON OVER RIGHTWARDS HARPOON
'leftrightsquigarrow': '\u21ad', # ↭ LEFT RIGHT WAVE ARROW
'leftslice': '\u2aa6', # ⪦ LESS-THAN CLOSED BY CURVE
'leftsquigarrow': '\u21dc', # ⇜ LEFTWARDS SQUIGGLE ARROW
'leftturn': '\u21ba', # ↺ ANTICLOCKWISE OPEN CIRCLE ARROW
'leq': '\u2264', # ≤ LESS-THAN OR EQUAL TO
'leqq': '\u2266', # ≦ LESS-THAN OVER EQUAL TO
'leqslant': '\u2a7d', # ⩽ LESS-THAN OR SLANTED EQUAL TO
'lessapprox': '\u2a85', # ⪅ LESS-THAN OR APPROXIMATE
'lesseqgtr': '\u22da', # ⋚ LESS-THAN EQUAL TO OR GREATER-THAN
'lesseqqgtr': '\u2a8b', # ⪋ LESS-THAN ABOVE DOUBLE-LINE EQUAL ABOVE GREATER-THAN
'lessgtr': '\u2276', # ≶ LESS-THAN OR GREATER-THAN
'lesssim': '\u2272', # ≲ LESS-THAN OR EQUIVALENT TO
'lhd': '\u22b2', # ⊲ NORMAL SUBGROUP OF
'lightning': '\u21af', # ↯ DOWNWARDS ZIGZAG ARROW
'll': '\u226a', # ≪ MUCH LESS-THAN
'llcurly': '\u2abb', # ⪻ DOUBLE PRECEDES
'lll': '\u22d8', # ⋘ VERY MUCH LESS-THAN
'llless': '\u22d8', # ⋘ VERY MUCH LESS-THAN
'lnapprox': '\u2a89', # ⪉ LESS-THAN AND NOT APPROXIMATE
'lneq': '\u2a87', # ⪇ LESS-THAN AND SINGLE-LINE NOT EQUAL TO
'lneqq': '\u2268', # ≨ LESS-THAN BUT NOT EQUAL TO
'lnsim': '\u22e6', # ⋦ LESS-THAN BUT NOT EQUIVALENT TO
'longleftarrow': '\u27f5', # ⟵ LONG LEFTWARDS ARROW
'longleftrightarrow': '\u27f7', # ⟷ LONG LEFT RIGHT ARROW
'longmapsfrom': '\u27fb', # ⟻ LONG LEFTWARDS ARROW FROM BAR
'longmapsto': '\u27fc', # ⟼ LONG RIGHTWARDS ARROW FROM BAR
'longrightarrow': '\u27f6', # ⟶ LONG RIGHTWARDS ARROW
'looparrowleft': '\u21ab', # ↫ LEFTWARDS ARROW WITH LOOP
'looparrowright': '\u21ac', # ↬ RIGHTWARDS ARROW WITH LOOP
'lrtimes': '\u22c8', # ⋈ BOWTIE
'mapsfrom': '\u21a4', # ↤ LEFTWARDS ARROW FROM BAR
'mapsto': '\u21a6', # ↦ RIGHTWARDS ARROW FROM BAR
'mid': '\u2223', # DIVIDES
'models': '\u22a7', # ⊧ MODELS
'multimap': '\u22b8', # ⊸ MULTIMAP
'multimapboth': '\u29df', # ⧟ DOUBLE-ENDED MULTIMAP
'multimapdotbothA': '\u22b6', # ⊶ ORIGINAL OF
'multimapdotbothB': '\u22b7', # ⊷ IMAGE OF
'multimapinv': '\u27dc', # ⟜ LEFT MULTIMAP
'nLeftarrow': '\u21cd', # ⇍ LEFTWARDS DOUBLE ARROW WITH STROKE
'nLeftrightarrow': '\u21ce', # ⇎ LEFT RIGHT DOUBLE ARROW WITH STROKE
'nRightarrow': '\u21cf', # ⇏ RIGHTWARDS DOUBLE ARROW WITH STROKE
'nVDash': '\u22af', # ⊯ NEGATED DOUBLE VERTICAL BAR DOUBLE RIGHT TURNSTILE
'nVdash': '\u22ae', # ⊮ DOES NOT FORCE
'ncong': '\u2247', # ≇ NEITHER APPROXIMATELY NOR ACTUALLY EQUAL TO
'ne': '\u2260', # ≠ NOT EQUAL TO
'nearrow': '\u2197', # ↗ NORTH EAST ARROW
'neq': '\u2260', # ≠ NOT EQUAL TO
'ngeq': '\u2271', # ≱ NEITHER GREATER-THAN NOR EQUAL TO
'ngtr': '\u226f', # ≯ NOT GREATER-THAN
'ngtrless': '\u2279', # ≹ NEITHER GREATER-THAN NOR LESS-THAN
'ni': '\u220b', # ∋ CONTAINS AS MEMBER
'nleftarrow': '\u219a', # ↚ LEFTWARDS ARROW WITH STROKE
'nleftrightarrow': '\u21ae', # ↮ LEFT RIGHT ARROW WITH STROKE
'nleq': '\u2270', # ≰ NEITHER LESS-THAN NOR EQUAL TO
'nless': '\u226e', # ≮ NOT LESS-THAN
'nlessgtr': '\u2278', # ≸ NEITHER LESS-THAN NOR GREATER-THAN
'nmid': '\u2224', # ∤ DOES NOT DIVIDE
'notasymp': '\u226d', # ≭ NOT EQUIVALENT TO
'notin': '\u2209', # ∉ NOT AN ELEMENT OF
'notni': '\u220c', # ∌ DOES NOT CONTAIN AS MEMBER
'notowner': '\u220c', # ∌ DOES NOT CONTAIN AS MEMBER
'notslash': '\u233f', # ⌿ APL FUNCTIONAL SYMBOL SLASH BAR
'nparallel': '\u2226', # ∦ NOT PARALLEL TO
'nprec': '\u2280', # ⊀ DOES NOT PRECEDE
'npreceq': '\u22e0', # ⋠ DOES NOT PRECEDE OR EQUAL
'nrightarrow': '\u219b', # ↛ RIGHTWARDS ARROW WITH STROKE
'nsim': '\u2241', # ≁ NOT TILDE
'nsimeq': '\u2244', # ≄ NOT ASYMPTOTICALLY EQUAL TO
'nsubseteq': '\u2288', # ⊈ NEITHER A SUBSET OF NOR EQUAL TO
'nsucc': '\u2281', # ⊁ DOES NOT SUCCEED
'nsucceq': '\u22e1', # ⋡ DOES NOT SUCCEED OR EQUAL
'nsupseteq': '\u2289', # ⊉ NEITHER A SUPERSET OF NOR EQUAL TO
'ntriangleleft': '\u22ea', # ⋪ NOT NORMAL SUBGROUP OF
'ntrianglelefteq': '\u22ec', # ⋬ NOT NORMAL SUBGROUP OF OR EQUAL TO
'ntriangleright': '\u22eb', # ⋫ DOES NOT CONTAIN AS NORMAL SUBGROUP
'ntrianglerighteq': '\u22ed', # ⋭ DOES NOT CONTAIN AS NORMAL SUBGROUP OR EQUAL
'nvDash': '\u22ad', # ⊭ NOT TRUE
'nvdash': '\u22ac', # ⊬ DOES NOT PROVE
'nwarrow': '\u2196', # ↖ NORTH WEST ARROW
'owns': '\u220b', # ∋ CONTAINS AS MEMBER
'parallel': '\u2225', # ∥ PARALLEL TO
'perp': '\u27c2', # ⟂ PERPENDICULAR
'pitchfork': '\u22d4', # ⋔ PITCHFORK
'prec': '\u227a', # ≺ PRECEDES
'precapprox': '\u2ab7', # ⪷ PRECEDES ABOVE ALMOST EQUAL TO
'preccurlyeq': '\u227c', # ≼ PRECEDES OR EQUAL TO
'preceq': '\u2aaf', # ⪯ PRECEDES ABOVE SINGLE-LINE EQUALS SIGN
'preceqq': '\u2ab3', # ⪳ PRECEDES ABOVE EQUALS SIGN
'precnapprox': '\u2ab9', # ⪹ PRECEDES ABOVE NOT ALMOST EQUAL TO
'precneqq': '\u2ab5', # ⪵ PRECEDES ABOVE NOT EQUAL TO
'precnsim': '\u22e8', # ⋨ PRECEDES BUT NOT EQUIVALENT TO
'precsim': '\u227e', # ≾ PRECEDES OR EQUIVALENT TO
'propto': '\u221d', # ∝ PROPORTIONAL TO
'restriction': '\u21be', # ↾ UPWARDS HARPOON WITH BARB RIGHTWARDS
'rhd': '\u22b3', # ⊳ CONTAINS AS NORMAL SUBGROUP
'rightarrow': '\u2192', # → RIGHTWARDS ARROW
'rightarrowtail': '\u21a3', # ↣ RIGHTWARDS ARROW WITH TAIL
'rightarrowtriangle': '\u21fe', # ⇾ RIGHTWARDS OPEN-HEADED ARROW
'rightbarharpoon': '\u296c', # ⥬ RIGHTWARDS HARPOON WITH BARB UP ABOVE LONG DASH
'rightharpoondown': '\u21c1', # ⇁ RIGHTWARDS HARPOON WITH BARB DOWNWARDS
'rightharpoonup': '\u21c0', # ⇀ RIGHTWARDS HARPOON WITH BARB UPWARDS
'rightleftarrows': '\u21c4', # ⇄ RIGHTWARDS ARROW OVER LEFTWARDS ARROW
'rightleftharpoon': '\u294b', # ⥋ LEFT BARB DOWN RIGHT BARB UP HARPOON
'rightleftharpoons': '\u21cc', # ⇌ RIGHTWARDS HARPOON OVER LEFTWARDS HARPOON
'rightrightarrows': '\u21c9', # ⇉ RIGHTWARDS PAIRED ARROWS
'rightrightharpoons': '\u2964', # ⥤ RIGHTWARDS HARPOON WITH BARB UP ABOVE RIGHTWARDS HARPOON WITH BARB DOWN
'rightslice': '\u2aa7', # ⪧ GREATER-THAN CLOSED BY CURVE
'rightsquigarrow': '\u21dd', # ⇝ RIGHTWARDS SQUIGGLE ARROW
'rightturn': '\u21bb', # ↻ CLOCKWISE OPEN CIRCLE ARROW
'risingdotseq': '\u2253', # ≓ IMAGE OF OR APPROXIMATELY EQUAL TO
'searrow': '\u2198', # ↘ SOUTH EAST ARROW
'sim': '\u223c', # TILDE OPERATOR
'simeq': '\u2243', # ≃ ASYMPTOTICALLY EQUAL TO
'smile': '\u2323', # ⌣ SMILE
'sqsubset': '\u228f', # ⊏ SQUARE IMAGE OF
'sqsubseteq': '\u2291', # ⊑ SQUARE IMAGE OF OR EQUAL TO
'sqsupset': '\u2290', # ⊐ SQUARE ORIGINAL OF
'sqsupseteq': '\u2292', # ⊒ SQUARE ORIGINAL OF OR EQUAL TO
'strictfi': '\u297c', # ⥼ LEFT FISH TAIL
'strictif': '\u297d', # ⥽ RIGHT FISH TAIL
'subset': '\u2282', # ⊂ SUBSET OF
'subseteq': '\u2286', # ⊆ SUBSET OF OR EQUAL TO
'subseteqq': '\u2ac5', # ⫅ SUBSET OF ABOVE EQUALS SIGN
'subsetneq': '\u228a', # ⊊ SUBSET OF WITH NOT EQUAL TO
'subsetneqq': '\u2acb', # ⫋ SUBSET OF ABOVE NOT EQUAL TO
'succ': '\u227b', # ≻ SUCCEEDS
'succapprox': '\u2ab8', # ⪸ SUCCEEDS ABOVE ALMOST EQUAL TO
'succcurlyeq': '\u227d', # ≽ SUCCEEDS OR EQUAL TO
'succeq': '\u2ab0', # ⪰ SUCCEEDS ABOVE SINGLE-LINE EQUALS SIGN
'succeqq': '\u2ab4', # ⪴ SUCCEEDS ABOVE EQUALS SIGN
'succnapprox': '\u2aba', # ⪺ SUCCEEDS ABOVE NOT ALMOST EQUAL TO
'succneqq': '\u2ab6', # ⪶ SUCCEEDS ABOVE NOT EQUAL TO
'succnsim': '\u22e9', # ⋩ SUCCEEDS BUT NOT EQUIVALENT TO
'succsim': '\u227f', # ≿ SUCCEEDS OR EQUIVALENT TO
'supset': '\u2283', # ⊃ SUPERSET OF
'supseteq': '\u2287', # ⊇ SUPERSET OF OR EQUAL TO
'supseteqq': '\u2ac6', # ⫆ SUPERSET OF ABOVE EQUALS SIGN
'supsetneq': '\u228b', # ⊋ SUPERSET OF WITH NOT EQUAL TO
'supsetneqq': '\u2acc', # ⫌ SUPERSET OF ABOVE NOT EQUAL TO
'swarrow': '\u2199', # ↙ SOUTH WEST ARROW
'therefore': '\u2234', # ∴ THEREFORE
'to': '\u2192', # → RIGHTWARDS ARROW
'trianglelefteq': '\u22b4', # ⊴ NORMAL SUBGROUP OF OR EQUAL TO
'triangleq': '\u225c', # ≜ DELTA EQUAL TO
'trianglerighteq': '\u22b5', # ⊵ CONTAINS AS NORMAL SUBGROUP OR EQUAL TO
'twoheadleftarrow': '\u219e', # ↞ LEFTWARDS TWO HEADED ARROW
'twoheadrightarrow': '\u21a0', # ↠ RIGHTWARDS TWO HEADED ARROW
'uparrow': '\u2191', # ↑ UPWARDS ARROW
'updownarrow': '\u2195', # ↕ UP DOWN ARROW
'updownarrows': '\u21c5', # ⇅ UPWARDS ARROW LEFTWARDS OF DOWNWARDS ARROW
'updownharpoons': '\u296e', # ⥮ UPWARDS HARPOON WITH BARB LEFT BESIDE DOWNWARDS HARPOON WITH BARB RIGHT
'upharpoonleft': '\u21bf', # ↿ UPWARDS HARPOON WITH BARB LEFTWARDS
'upharpoonright': '\u21be', # ↾ UPWARDS HARPOON WITH BARB RIGHTWARDS
'upuparrows': '\u21c8', # ⇈ UPWARDS PAIRED ARROWS
'upupharpoons': '\u2963', # ⥣ UPWARDS HARPOON WITH BARB LEFT BESIDE UPWARDS HARPOON WITH BARB RIGHT
'vDash': '\u22a8', # ⊨ TRUE
'vartriangle': '\u25b5', # ▵ WHITE UP-POINTING SMALL TRIANGLE
'vartriangleleft': '\u22b2', # ⊲ NORMAL SUBGROUP OF
'vartriangleright': '\u22b3', # ⊳ CONTAINS AS NORMAL SUBGROUP
'vdash': '\u22a2', # ⊢ RIGHT TACK
'wasytherefore': '\u2234', # ∴ THEREFORE
}
mathunder = {
'underbrace': '\u23df', # ⏟ BOTTOM CURLY BRACKET
}
space = {
' ': ' ', # SPACE
',': '\u2006', # SIX-PER-EM SPACE
':': '\u205f', # MEDIUM MATHEMATICAL SPACE
'medspace': '\u205f', # MEDIUM MATHEMATICAL SPACE
'quad': '\u2001', # EM QUAD
'thinspace': '\u2006', # SIX-PER-EM SPACE
}

View file

@ -0,0 +1,808 @@
# LaTeX math to Unicode symbols translation table
# for use with the translate() method of unicode objects.
# Generated with ``write_unichar2tex.py`` from the data in
# http://milde.users.sourceforge.net/LUCR/Math/
# Includes commands from: standard LaTeX, amssymb, amsmath
uni2tex_table = {
0xa0: '~',
0xa3: '\\pounds ',
0xa5: '\\yen ',
0xa7: '\\S ',
0xac: '\\neg ',
0xb1: '\\pm ',
0xb6: '\\P ',
0xd7: '\\times ',
0xf0: '\\eth ',
0xf7: '\\div ',
0x131: '\\imath ',
0x237: '\\jmath ',
0x393: '\\Gamma ',
0x394: '\\Delta ',
0x398: '\\Theta ',
0x39b: '\\Lambda ',
0x39e: '\\Xi ',
0x3a0: '\\Pi ',
0x3a3: '\\Sigma ',
0x3a5: '\\Upsilon ',
0x3a6: '\\Phi ',
0x3a8: '\\Psi ',
0x3a9: '\\Omega ',
0x3b1: '\\alpha ',
0x3b2: '\\beta ',
0x3b3: '\\gamma ',
0x3b4: '\\delta ',
0x3b5: '\\varepsilon ',
0x3b6: '\\zeta ',
0x3b7: '\\eta ',
0x3b8: '\\theta ',
0x3b9: '\\iota ',
0x3ba: '\\kappa ',
0x3bb: '\\lambda ',
0x3bc: '\\mu ',
0x3bd: '\\nu ',
0x3be: '\\xi ',
0x3c0: '\\pi ',
0x3c1: '\\rho ',
0x3c2: '\\varsigma ',
0x3c3: '\\sigma ',
0x3c4: '\\tau ',
0x3c5: '\\upsilon ',
0x3c6: '\\varphi ',
0x3c7: '\\chi ',
0x3c8: '\\psi ',
0x3c9: '\\omega ',
0x3d1: '\\vartheta ',
0x3d5: '\\phi ',
0x3d6: '\\varpi ',
0x3dd: '\\digamma ',
0x3f0: '\\varkappa ',
0x3f1: '\\varrho ',
0x3f5: '\\epsilon ',
0x3f6: '\\backepsilon ',
0x2001: '\\quad ',
0x2003: '\\quad ',
0x2006: '\\, ',
0x2016: '\\| ',
0x2020: '\\dagger ',
0x2021: '\\ddagger ',
0x2022: '\\bullet ',
0x2026: '\\ldots ',
0x2032: '\\prime ',
0x2035: '\\backprime ',
0x205f: '\\: ',
0x2102: '\\mathbb{C}',
0x210b: '\\mathcal{H}',
0x210c: '\\mathfrak{H}',
0x210d: '\\mathbb{H}',
0x210f: '\\hslash ',
0x2110: '\\mathcal{I}',
0x2111: '\\Im ',
0x2112: '\\mathcal{L}',
0x2113: '\\ell ',
0x2115: '\\mathbb{N}',
0x2118: '\\wp ',
0x2119: '\\mathbb{P}',
0x211a: '\\mathbb{Q}',
0x211b: '\\mathcal{R}',
0x211c: '\\Re ',
0x211d: '\\mathbb{R}',
0x2124: '\\mathbb{Z}',
0x2127: '\\mho ',
0x2128: '\\mathfrak{Z}',
0x212c: '\\mathcal{B}',
0x212d: '\\mathfrak{C}',
0x2130: '\\mathcal{E}',
0x2131: '\\mathcal{F}',
0x2132: '\\Finv ',
0x2133: '\\mathcal{M}',
0x2135: '\\aleph ',
0x2136: '\\beth ',
0x2137: '\\gimel ',
0x2138: '\\daleth ',
0x2190: '\\leftarrow ',
0x2191: '\\uparrow ',
0x2192: '\\rightarrow ',
0x2193: '\\downarrow ',
0x2194: '\\leftrightarrow ',
0x2195: '\\updownarrow ',
0x2196: '\\nwarrow ',
0x2197: '\\nearrow ',
0x2198: '\\searrow ',
0x2199: '\\swarrow ',
0x219a: '\\nleftarrow ',
0x219b: '\\nrightarrow ',
0x219e: '\\twoheadleftarrow ',
0x21a0: '\\twoheadrightarrow ',
0x21a2: '\\leftarrowtail ',
0x21a3: '\\rightarrowtail ',
0x21a6: '\\mapsto ',
0x21a9: '\\hookleftarrow ',
0x21aa: '\\hookrightarrow ',
0x21ab: '\\looparrowleft ',
0x21ac: '\\looparrowright ',
0x21ad: '\\leftrightsquigarrow ',
0x21ae: '\\nleftrightarrow ',
0x21b0: '\\Lsh ',
0x21b1: '\\Rsh ',
0x21b6: '\\curvearrowleft ',
0x21b7: '\\curvearrowright ',
0x21ba: '\\circlearrowleft ',
0x21bb: '\\circlearrowright ',
0x21bc: '\\leftharpoonup ',
0x21bd: '\\leftharpoondown ',
0x21be: '\\upharpoonright ',
0x21bf: '\\upharpoonleft ',
0x21c0: '\\rightharpoonup ',
0x21c1: '\\rightharpoondown ',
0x21c2: '\\downharpoonright ',
0x21c3: '\\downharpoonleft ',
0x21c4: '\\rightleftarrows ',
0x21c6: '\\leftrightarrows ',
0x21c7: '\\leftleftarrows ',
0x21c8: '\\upuparrows ',
0x21c9: '\\rightrightarrows ',
0x21ca: '\\downdownarrows ',
0x21cb: '\\leftrightharpoons ',
0x21cc: '\\rightleftharpoons ',
0x21cd: '\\nLeftarrow ',
0x21ce: '\\nLeftrightarrow ',
0x21cf: '\\nRightarrow ',
0x21d0: '\\Leftarrow ',
0x21d1: '\\Uparrow ',
0x21d2: '\\Rightarrow ',
0x21d3: '\\Downarrow ',
0x21d4: '\\Leftrightarrow ',
0x21d5: '\\Updownarrow ',
0x21da: '\\Lleftarrow ',
0x21db: '\\Rrightarrow ',
0x21dd: '\\rightsquigarrow ',
0x21e0: '\\dashleftarrow ',
0x21e2: '\\dashrightarrow ',
0x2200: '\\forall ',
0x2201: '\\complement ',
0x2202: '\\partial ',
0x2203: '\\exists ',
0x2204: '\\nexists ',
0x2205: '\\emptyset ',
0x2207: '\\nabla ',
0x2208: '\\in ',
0x2209: '\\notin ',
0x220b: '\\ni ',
0x220f: '\\prod ',
0x2210: '\\coprod ',
0x2211: '\\sum ',
0x2212: '-',
0x2213: '\\mp ',
0x2214: '\\dotplus ',
0x2215: '\\slash ',
0x2216: '\\smallsetminus ',
0x2217: '\\ast ',
0x2218: '\\circ ',
0x2219: '\\bullet ',
0x221a: '\\surd ',
0x221b: '\\sqrt[3] ',
0x221c: '\\sqrt[4] ',
0x221d: '\\propto ',
0x221e: '\\infty ',
0x2220: '\\angle ',
0x2221: '\\measuredangle ',
0x2222: '\\sphericalangle ',
0x2223: '\\mid ',
0x2224: '\\nmid ',
0x2225: '\\parallel ',
0x2226: '\\nparallel ',
0x2227: '\\wedge ',
0x2228: '\\vee ',
0x2229: '\\cap ',
0x222a: '\\cup ',
0x222b: '\\int ',
0x222c: '\\iint ',
0x222d: '\\iiint ',
0x222e: '\\oint ',
0x2234: '\\therefore ',
0x2235: '\\because ',
0x2236: ':',
0x223c: '\\sim ',
0x223d: '\\backsim ',
0x2240: '\\wr ',
0x2241: '\\nsim ',
0x2242: '\\eqsim ',
0x2243: '\\simeq ',
0x2245: '\\cong ',
0x2247: '\\ncong ',
0x2248: '\\approx ',
0x224a: '\\approxeq ',
0x224d: '\\asymp ',
0x224e: '\\Bumpeq ',
0x224f: '\\bumpeq ',
0x2250: '\\doteq ',
0x2251: '\\Doteq ',
0x2252: '\\fallingdotseq ',
0x2253: '\\risingdotseq ',
0x2256: '\\eqcirc ',
0x2257: '\\circeq ',
0x225c: '\\triangleq ',
0x2260: '\\neq ',
0x2261: '\\equiv ',
0x2264: '\\leq ',
0x2265: '\\geq ',
0x2266: '\\leqq ',
0x2267: '\\geqq ',
0x2268: '\\lneqq ',
0x2269: '\\gneqq ',
0x226a: '\\ll ',
0x226b: '\\gg ',
0x226c: '\\between ',
0x226e: '\\nless ',
0x226f: '\\ngtr ',
0x2270: '\\nleq ',
0x2271: '\\ngeq ',
0x2272: '\\lesssim ',
0x2273: '\\gtrsim ',
0x2276: '\\lessgtr ',
0x2277: '\\gtrless ',
0x227a: '\\prec ',
0x227b: '\\succ ',
0x227c: '\\preccurlyeq ',
0x227d: '\\succcurlyeq ',
0x227e: '\\precsim ',
0x227f: '\\succsim ',
0x2280: '\\nprec ',
0x2281: '\\nsucc ',
0x2282: '\\subset ',
0x2283: '\\supset ',
0x2286: '\\subseteq ',
0x2287: '\\supseteq ',
0x2288: '\\nsubseteq ',
0x2289: '\\nsupseteq ',
0x228a: '\\subsetneq ',
0x228b: '\\supsetneq ',
0x228e: '\\uplus ',
0x228f: '\\sqsubset ',
0x2290: '\\sqsupset ',
0x2291: '\\sqsubseteq ',
0x2292: '\\sqsupseteq ',
0x2293: '\\sqcap ',
0x2294: '\\sqcup ',
0x2295: '\\oplus ',
0x2296: '\\ominus ',
0x2297: '\\otimes ',
0x2298: '\\oslash ',
0x2299: '\\odot ',
0x229a: '\\circledcirc ',
0x229b: '\\circledast ',
0x229d: '\\circleddash ',
0x229e: '\\boxplus ',
0x229f: '\\boxminus ',
0x22a0: '\\boxtimes ',
0x22a1: '\\boxdot ',
0x22a2: '\\vdash ',
0x22a3: '\\dashv ',
0x22a4: '\\top ',
0x22a5: '\\bot ',
0x22a7: '\\models ',
0x22a8: '\\vDash ',
0x22a9: '\\Vdash ',
0x22aa: '\\Vvdash ',
0x22ac: '\\nvdash ',
0x22ad: '\\nvDash ',
0x22ae: '\\nVdash ',
0x22af: '\\nVDash ',
0x22b2: '\\vartriangleleft ',
0x22b3: '\\vartriangleright ',
0x22b4: '\\trianglelefteq ',
0x22b5: '\\trianglerighteq ',
0x22b8: '\\multimap ',
0x22ba: '\\intercal ',
0x22bb: '\\veebar ',
0x22bc: '\\barwedge ',
0x22c0: '\\bigwedge ',
0x22c1: '\\bigvee ',
0x22c2: '\\bigcap ',
0x22c3: '\\bigcup ',
0x22c4: '\\diamond ',
0x22c5: '\\cdot ',
0x22c6: '\\star ',
0x22c7: '\\divideontimes ',
0x22c8: '\\bowtie ',
0x22c9: '\\ltimes ',
0x22ca: '\\rtimes ',
0x22cb: '\\leftthreetimes ',
0x22cc: '\\rightthreetimes ',
0x22cd: '\\backsimeq ',
0x22ce: '\\curlyvee ',
0x22cf: '\\curlywedge ',
0x22d0: '\\Subset ',
0x22d1: '\\Supset ',
0x22d2: '\\Cap ',
0x22d3: '\\Cup ',
0x22d4: '\\pitchfork ',
0x22d6: '\\lessdot ',
0x22d7: '\\gtrdot ',
0x22d8: '\\lll ',
0x22d9: '\\ggg ',
0x22da: '\\lesseqgtr ',
0x22db: '\\gtreqless ',
0x22de: '\\curlyeqprec ',
0x22df: '\\curlyeqsucc ',
0x22e0: '\\npreceq ',
0x22e1: '\\nsucceq ',
0x22e6: '\\lnsim ',
0x22e7: '\\gnsim ',
0x22e8: '\\precnsim ',
0x22e9: '\\succnsim ',
0x22ea: '\\ntriangleleft ',
0x22eb: '\\ntriangleright ',
0x22ec: '\\ntrianglelefteq ',
0x22ed: '\\ntrianglerighteq ',
0x22ee: '\\vdots ',
0x22ef: '\\cdots ',
0x22f1: '\\ddots ',
0x2308: '\\lceil ',
0x2309: '\\rceil ',
0x230a: '\\lfloor ',
0x230b: '\\rfloor ',
0x231c: '\\ulcorner ',
0x231d: '\\urcorner ',
0x231e: '\\llcorner ',
0x231f: '\\lrcorner ',
0x2322: '\\frown ',
0x2323: '\\smile ',
0x23aa: '\\bracevert ',
0x23b0: '\\lmoustache ',
0x23b1: '\\rmoustache ',
0x23d0: '\\arrowvert ',
0x23de: '\\overbrace ',
0x23df: '\\underbrace ',
0x24c7: '\\circledR ',
0x24c8: '\\circledS ',
0x25b2: '\\blacktriangle ',
0x25b3: '\\bigtriangleup ',
0x25b7: '\\triangleright ',
0x25bc: '\\blacktriangledown ',
0x25bd: '\\bigtriangledown ',
0x25c1: '\\triangleleft ',
0x25c7: '\\Diamond ',
0x25ca: '\\lozenge ',
0x25ef: '\\bigcirc ',
0x25fb: '\\square ',
0x25fc: '\\blacksquare ',
0x2605: '\\bigstar ',
0x2660: '\\spadesuit ',
0x2661: '\\heartsuit ',
0x2662: '\\diamondsuit ',
0x2663: '\\clubsuit ',
0x266d: '\\flat ',
0x266e: '\\natural ',
0x266f: '\\sharp ',
0x2713: '\\checkmark ',
0x2720: '\\maltese ',
0x27c2: '\\perp ',
0x27cb: '\\diagup ',
0x27cd: '\\diagdown ',
0x27e8: '\\langle ',
0x27e9: '\\rangle ',
0x27ee: '\\lgroup ',
0x27ef: '\\rgroup ',
0x27f5: '\\longleftarrow ',
0x27f6: '\\longrightarrow ',
0x27f7: '\\longleftrightarrow ',
0x27f8: '\\Longleftarrow ',
0x27f9: '\\Longrightarrow ',
0x27fa: '\\Longleftrightarrow ',
0x27fc: '\\longmapsto ',
0x29eb: '\\blacklozenge ',
0x29f5: '\\setminus ',
0x2a00: '\\bigodot ',
0x2a01: '\\bigoplus ',
0x2a02: '\\bigotimes ',
0x2a04: '\\biguplus ',
0x2a06: '\\bigsqcup ',
0x2a0c: '\\iiiint ',
0x2a3f: '\\amalg ',
0x2a5e: '\\doublebarwedge ',
0x2a7d: '\\leqslant ',
0x2a7e: '\\geqslant ',
0x2a85: '\\lessapprox ',
0x2a86: '\\gtrapprox ',
0x2a87: '\\lneq ',
0x2a88: '\\gneq ',
0x2a89: '\\lnapprox ',
0x2a8a: '\\gnapprox ',
0x2a8b: '\\lesseqqgtr ',
0x2a8c: '\\gtreqqless ',
0x2a95: '\\eqslantless ',
0x2a96: '\\eqslantgtr ',
0x2aaf: '\\preceq ',
0x2ab0: '\\succeq ',
0x2ab5: '\\precneqq ',
0x2ab6: '\\succneqq ',
0x2ab7: '\\precapprox ',
0x2ab8: '\\succapprox ',
0x2ab9: '\\precnapprox ',
0x2aba: '\\succnapprox ',
0x2ac5: '\\subseteqq ',
0x2ac6: '\\supseteqq ',
0x2acb: '\\subsetneqq ',
0x2acc: '\\supsetneqq ',
0x2b1c: '\\Box ',
0x1d400: '\\mathbf{A}',
0x1d401: '\\mathbf{B}',
0x1d402: '\\mathbf{C}',
0x1d403: '\\mathbf{D}',
0x1d404: '\\mathbf{E}',
0x1d405: '\\mathbf{F}',
0x1d406: '\\mathbf{G}',
0x1d407: '\\mathbf{H}',
0x1d408: '\\mathbf{I}',
0x1d409: '\\mathbf{J}',
0x1d40a: '\\mathbf{K}',
0x1d40b: '\\mathbf{L}',
0x1d40c: '\\mathbf{M}',
0x1d40d: '\\mathbf{N}',
0x1d40e: '\\mathbf{O}',
0x1d40f: '\\mathbf{P}',
0x1d410: '\\mathbf{Q}',
0x1d411: '\\mathbf{R}',
0x1d412: '\\mathbf{S}',
0x1d413: '\\mathbf{T}',
0x1d414: '\\mathbf{U}',
0x1d415: '\\mathbf{V}',
0x1d416: '\\mathbf{W}',
0x1d417: '\\mathbf{X}',
0x1d418: '\\mathbf{Y}',
0x1d419: '\\mathbf{Z}',
0x1d41a: '\\mathbf{a}',
0x1d41b: '\\mathbf{b}',
0x1d41c: '\\mathbf{c}',
0x1d41d: '\\mathbf{d}',
0x1d41e: '\\mathbf{e}',
0x1d41f: '\\mathbf{f}',
0x1d420: '\\mathbf{g}',
0x1d421: '\\mathbf{h}',
0x1d422: '\\mathbf{i}',
0x1d423: '\\mathbf{j}',
0x1d424: '\\mathbf{k}',
0x1d425: '\\mathbf{l}',
0x1d426: '\\mathbf{m}',
0x1d427: '\\mathbf{n}',
0x1d428: '\\mathbf{o}',
0x1d429: '\\mathbf{p}',
0x1d42a: '\\mathbf{q}',
0x1d42b: '\\mathbf{r}',
0x1d42c: '\\mathbf{s}',
0x1d42d: '\\mathbf{t}',
0x1d42e: '\\mathbf{u}',
0x1d42f: '\\mathbf{v}',
0x1d430: '\\mathbf{w}',
0x1d431: '\\mathbf{x}',
0x1d432: '\\mathbf{y}',
0x1d433: '\\mathbf{z}',
0x1d434: 'A',
0x1d435: 'B',
0x1d436: 'C',
0x1d437: 'D',
0x1d438: 'E',
0x1d439: 'F',
0x1d43a: 'G',
0x1d43b: 'H',
0x1d43c: 'I',
0x1d43d: 'J',
0x1d43e: 'K',
0x1d43f: 'L',
0x1d440: 'M',
0x1d441: 'N',
0x1d442: 'O',
0x1d443: 'P',
0x1d444: 'Q',
0x1d445: 'R',
0x1d446: 'S',
0x1d447: 'T',
0x1d448: 'U',
0x1d449: 'V',
0x1d44a: 'W',
0x1d44b: 'X',
0x1d44c: 'Y',
0x1d44d: 'Z',
0x1d44e: 'a',
0x1d44f: 'b',
0x1d450: 'c',
0x1d451: 'd',
0x1d452: 'e',
0x1d453: 'f',
0x1d454: 'g',
0x1d456: 'i',
0x1d457: 'j',
0x1d458: 'k',
0x1d459: 'l',
0x1d45a: 'm',
0x1d45b: 'n',
0x1d45c: 'o',
0x1d45d: 'p',
0x1d45e: 'q',
0x1d45f: 'r',
0x1d460: 's',
0x1d461: 't',
0x1d462: 'u',
0x1d463: 'v',
0x1d464: 'w',
0x1d465: 'x',
0x1d466: 'y',
0x1d467: 'z',
0x1d49c: '\\mathcal{A}',
0x1d49e: '\\mathcal{C}',
0x1d49f: '\\mathcal{D}',
0x1d4a2: '\\mathcal{G}',
0x1d4a5: '\\mathcal{J}',
0x1d4a6: '\\mathcal{K}',
0x1d4a9: '\\mathcal{N}',
0x1d4aa: '\\mathcal{O}',
0x1d4ab: '\\mathcal{P}',
0x1d4ac: '\\mathcal{Q}',
0x1d4ae: '\\mathcal{S}',
0x1d4af: '\\mathcal{T}',
0x1d4b0: '\\mathcal{U}',
0x1d4b1: '\\mathcal{V}',
0x1d4b2: '\\mathcal{W}',
0x1d4b3: '\\mathcal{X}',
0x1d4b4: '\\mathcal{Y}',
0x1d4b5: '\\mathcal{Z}',
0x1d504: '\\mathfrak{A}',
0x1d505: '\\mathfrak{B}',
0x1d507: '\\mathfrak{D}',
0x1d508: '\\mathfrak{E}',
0x1d509: '\\mathfrak{F}',
0x1d50a: '\\mathfrak{G}',
0x1d50d: '\\mathfrak{J}',
0x1d50e: '\\mathfrak{K}',
0x1d50f: '\\mathfrak{L}',
0x1d510: '\\mathfrak{M}',
0x1d511: '\\mathfrak{N}',
0x1d512: '\\mathfrak{O}',
0x1d513: '\\mathfrak{P}',
0x1d514: '\\mathfrak{Q}',
0x1d516: '\\mathfrak{S}',
0x1d517: '\\mathfrak{T}',
0x1d518: '\\mathfrak{U}',
0x1d519: '\\mathfrak{V}',
0x1d51a: '\\mathfrak{W}',
0x1d51b: '\\mathfrak{X}',
0x1d51c: '\\mathfrak{Y}',
0x1d51e: '\\mathfrak{a}',
0x1d51f: '\\mathfrak{b}',
0x1d520: '\\mathfrak{c}',
0x1d521: '\\mathfrak{d}',
0x1d522: '\\mathfrak{e}',
0x1d523: '\\mathfrak{f}',
0x1d524: '\\mathfrak{g}',
0x1d525: '\\mathfrak{h}',
0x1d526: '\\mathfrak{i}',
0x1d527: '\\mathfrak{j}',
0x1d528: '\\mathfrak{k}',
0x1d529: '\\mathfrak{l}',
0x1d52a: '\\mathfrak{m}',
0x1d52b: '\\mathfrak{n}',
0x1d52c: '\\mathfrak{o}',
0x1d52d: '\\mathfrak{p}',
0x1d52e: '\\mathfrak{q}',
0x1d52f: '\\mathfrak{r}',
0x1d530: '\\mathfrak{s}',
0x1d531: '\\mathfrak{t}',
0x1d532: '\\mathfrak{u}',
0x1d533: '\\mathfrak{v}',
0x1d534: '\\mathfrak{w}',
0x1d535: '\\mathfrak{x}',
0x1d536: '\\mathfrak{y}',
0x1d537: '\\mathfrak{z}',
0x1d538: '\\mathbb{A}',
0x1d539: '\\mathbb{B}',
0x1d53b: '\\mathbb{D}',
0x1d53c: '\\mathbb{E}',
0x1d53d: '\\mathbb{F}',
0x1d53e: '\\mathbb{G}',
0x1d540: '\\mathbb{I}',
0x1d541: '\\mathbb{J}',
0x1d542: '\\mathbb{K}',
0x1d543: '\\mathbb{L}',
0x1d544: '\\mathbb{M}',
0x1d546: '\\mathbb{O}',
0x1d54a: '\\mathbb{S}',
0x1d54b: '\\mathbb{T}',
0x1d54c: '\\mathbb{U}',
0x1d54d: '\\mathbb{V}',
0x1d54e: '\\mathbb{W}',
0x1d54f: '\\mathbb{X}',
0x1d550: '\\mathbb{Y}',
0x1d55c: '\\Bbbk ',
0x1d5a0: '\\mathsf{A}',
0x1d5a1: '\\mathsf{B}',
0x1d5a2: '\\mathsf{C}',
0x1d5a3: '\\mathsf{D}',
0x1d5a4: '\\mathsf{E}',
0x1d5a5: '\\mathsf{F}',
0x1d5a6: '\\mathsf{G}',
0x1d5a7: '\\mathsf{H}',
0x1d5a8: '\\mathsf{I}',
0x1d5a9: '\\mathsf{J}',
0x1d5aa: '\\mathsf{K}',
0x1d5ab: '\\mathsf{L}',
0x1d5ac: '\\mathsf{M}',
0x1d5ad: '\\mathsf{N}',
0x1d5ae: '\\mathsf{O}',
0x1d5af: '\\mathsf{P}',
0x1d5b0: '\\mathsf{Q}',
0x1d5b1: '\\mathsf{R}',
0x1d5b2: '\\mathsf{S}',
0x1d5b3: '\\mathsf{T}',
0x1d5b4: '\\mathsf{U}',
0x1d5b5: '\\mathsf{V}',
0x1d5b6: '\\mathsf{W}',
0x1d5b7: '\\mathsf{X}',
0x1d5b8: '\\mathsf{Y}',
0x1d5b9: '\\mathsf{Z}',
0x1d5ba: '\\mathsf{a}',
0x1d5bb: '\\mathsf{b}',
0x1d5bc: '\\mathsf{c}',
0x1d5bd: '\\mathsf{d}',
0x1d5be: '\\mathsf{e}',
0x1d5bf: '\\mathsf{f}',
0x1d5c0: '\\mathsf{g}',
0x1d5c1: '\\mathsf{h}',
0x1d5c2: '\\mathsf{i}',
0x1d5c3: '\\mathsf{j}',
0x1d5c4: '\\mathsf{k}',
0x1d5c5: '\\mathsf{l}',
0x1d5c6: '\\mathsf{m}',
0x1d5c7: '\\mathsf{n}',
0x1d5c8: '\\mathsf{o}',
0x1d5c9: '\\mathsf{p}',
0x1d5ca: '\\mathsf{q}',
0x1d5cb: '\\mathsf{r}',
0x1d5cc: '\\mathsf{s}',
0x1d5cd: '\\mathsf{t}',
0x1d5ce: '\\mathsf{u}',
0x1d5cf: '\\mathsf{v}',
0x1d5d0: '\\mathsf{w}',
0x1d5d1: '\\mathsf{x}',
0x1d5d2: '\\mathsf{y}',
0x1d5d3: '\\mathsf{z}',
0x1d670: '\\mathtt{A}',
0x1d671: '\\mathtt{B}',
0x1d672: '\\mathtt{C}',
0x1d673: '\\mathtt{D}',
0x1d674: '\\mathtt{E}',
0x1d675: '\\mathtt{F}',
0x1d676: '\\mathtt{G}',
0x1d677: '\\mathtt{H}',
0x1d678: '\\mathtt{I}',
0x1d679: '\\mathtt{J}',
0x1d67a: '\\mathtt{K}',
0x1d67b: '\\mathtt{L}',
0x1d67c: '\\mathtt{M}',
0x1d67d: '\\mathtt{N}',
0x1d67e: '\\mathtt{O}',
0x1d67f: '\\mathtt{P}',
0x1d680: '\\mathtt{Q}',
0x1d681: '\\mathtt{R}',
0x1d682: '\\mathtt{S}',
0x1d683: '\\mathtt{T}',
0x1d684: '\\mathtt{U}',
0x1d685: '\\mathtt{V}',
0x1d686: '\\mathtt{W}',
0x1d687: '\\mathtt{X}',
0x1d688: '\\mathtt{Y}',
0x1d689: '\\mathtt{Z}',
0x1d68a: '\\mathtt{a}',
0x1d68b: '\\mathtt{b}',
0x1d68c: '\\mathtt{c}',
0x1d68d: '\\mathtt{d}',
0x1d68e: '\\mathtt{e}',
0x1d68f: '\\mathtt{f}',
0x1d690: '\\mathtt{g}',
0x1d691: '\\mathtt{h}',
0x1d692: '\\mathtt{i}',
0x1d693: '\\mathtt{j}',
0x1d694: '\\mathtt{k}',
0x1d695: '\\mathtt{l}',
0x1d696: '\\mathtt{m}',
0x1d697: '\\mathtt{n}',
0x1d698: '\\mathtt{o}',
0x1d699: '\\mathtt{p}',
0x1d69a: '\\mathtt{q}',
0x1d69b: '\\mathtt{r}',
0x1d69c: '\\mathtt{s}',
0x1d69d: '\\mathtt{t}',
0x1d69e: '\\mathtt{u}',
0x1d69f: '\\mathtt{v}',
0x1d6a0: '\\mathtt{w}',
0x1d6a1: '\\mathtt{x}',
0x1d6a2: '\\mathtt{y}',
0x1d6a3: '\\mathtt{z}',
0x1d6a4: '\\imath ',
0x1d6a5: '\\jmath ',
0x1d6aa: '\\mathbf{\\Gamma}',
0x1d6ab: '\\mathbf{\\Delta}',
0x1d6af: '\\mathbf{\\Theta}',
0x1d6b2: '\\mathbf{\\Lambda}',
0x1d6b5: '\\mathbf{\\Xi}',
0x1d6b7: '\\mathbf{\\Pi}',
0x1d6ba: '\\mathbf{\\Sigma}',
0x1d6bc: '\\mathbf{\\Upsilon}',
0x1d6bd: '\\mathbf{\\Phi}',
0x1d6bf: '\\mathbf{\\Psi}',
0x1d6c0: '\\mathbf{\\Omega}',
0x1d6e4: '\\mathit{\\Gamma}',
0x1d6e5: '\\mathit{\\Delta}',
0x1d6e9: '\\mathit{\\Theta}',
0x1d6ec: '\\mathit{\\Lambda}',
0x1d6ef: '\\mathit{\\Xi}',
0x1d6f1: '\\mathit{\\Pi}',
0x1d6f4: '\\mathit{\\Sigma}',
0x1d6f6: '\\mathit{\\Upsilon}',
0x1d6f7: '\\mathit{\\Phi}',
0x1d6f9: '\\mathit{\\Psi}',
0x1d6fa: '\\mathit{\\Omega}',
0x1d6fc: '\\alpha ',
0x1d6fd: '\\beta ',
0x1d6fe: '\\gamma ',
0x1d6ff: '\\delta ',
0x1d700: '\\varepsilon ',
0x1d701: '\\zeta ',
0x1d702: '\\eta ',
0x1d703: '\\theta ',
0x1d704: '\\iota ',
0x1d705: '\\kappa ',
0x1d706: '\\lambda ',
0x1d707: '\\mu ',
0x1d708: '\\nu ',
0x1d709: '\\xi ',
0x1d70b: '\\pi ',
0x1d70c: '\\rho ',
0x1d70d: '\\varsigma ',
0x1d70e: '\\sigma ',
0x1d70f: '\\tau ',
0x1d710: '\\upsilon ',
0x1d711: '\\varphi ',
0x1d712: '\\chi ',
0x1d713: '\\psi ',
0x1d714: '\\omega ',
0x1d715: '\\partial ',
0x1d716: '\\epsilon ',
0x1d717: '\\vartheta ',
0x1d718: '\\varkappa ',
0x1d719: '\\phi ',
0x1d71a: '\\varrho ',
0x1d71b: '\\varpi ',
0x1d7ce: '\\mathbf{0}',
0x1d7cf: '\\mathbf{1}',
0x1d7d0: '\\mathbf{2}',
0x1d7d1: '\\mathbf{3}',
0x1d7d2: '\\mathbf{4}',
0x1d7d3: '\\mathbf{5}',
0x1d7d4: '\\mathbf{6}',
0x1d7d5: '\\mathbf{7}',
0x1d7d6: '\\mathbf{8}',
0x1d7d7: '\\mathbf{9}',
0x1d7e2: '\\mathsf{0}',
0x1d7e3: '\\mathsf{1}',
0x1d7e4: '\\mathsf{2}',
0x1d7e5: '\\mathsf{3}',
0x1d7e6: '\\mathsf{4}',
0x1d7e7: '\\mathsf{5}',
0x1d7e8: '\\mathsf{6}',
0x1d7e9: '\\mathsf{7}',
0x1d7ea: '\\mathsf{8}',
0x1d7eb: '\\mathsf{9}',
0x1d7f6: '\\mathtt{0}',
0x1d7f7: '\\mathtt{1}',
0x1d7f8: '\\mathtt{2}',
0x1d7f9: '\\mathtt{3}',
0x1d7fa: '\\mathtt{4}',
0x1d7fb: '\\mathtt{5}',
0x1d7fc: '\\mathtt{6}',
0x1d7fd: '\\mathtt{7}',
0x1d7fe: '\\mathtt{8}',
0x1d7ff: '\\mathtt{9}',
}

View file

@ -0,0 +1,123 @@
# :Id: $Id: punctuation_chars.py 9270 2022-11-24 20:28:03Z milde $
# :Copyright: © 2011, 2017 Günter Milde.
# :License: Released under the terms of the `2-Clause BSD license`_, in short:
#
# Copying and distribution of this file, with or without modification,
# are permitted in any medium without royalty provided the copyright
# notice and this notice are preserved.
# This file is offered as-is, without any warranty.
#
# .. _2-Clause BSD license: https://opensource.org/licenses/BSD-2-Clause
#
# This file is generated by
# ``docutils/tools/dev/generate_punctuation_chars.py``.
# ::
"""Docutils character category patterns.
Patterns for the implementation of the `inline markup recognition rules`_
in the reStructuredText parser `docutils.parsers.rst.states.py` based
on Unicode character categories.
The patterns are used inside ``[ ]`` in regular expressions.
Rule (5) requires determination of matching open/close pairs. However, the
pairing of open/close quotes is ambiguous due to different typographic
conventions in different languages. The ``quote_pairs`` function tests
whether two characters form an open/close pair.
The patterns are generated by
``docutils/tools/dev/generate_punctuation_chars.py`` to prevent dependence
on the Python version and avoid the time-consuming generation with every
Docutils run. See there for motives and implementation details.
The category of some characters changed with the development of the
Unicode standard. The current lists are generated with the help of the
"unicodedata" module of Python 2.7.13 (based on Unicode version 5.2.0).
.. _inline markup recognition rules:
https://docutils.sourceforge.io/docs/ref/rst/restructuredtext.html
#inline-markup-recognition-rules
"""
openers = (
'"\'(<\\[{\u0f3a\u0f3c\u169b\u2045\u207d\u208d\u2329\u2768'
'\u276a\u276c\u276e\u2770\u2772\u2774\u27c5\u27e6\u27e8\u27ea'
'\u27ec\u27ee\u2983\u2985\u2987\u2989\u298b\u298d\u298f\u2991'
'\u2993\u2995\u2997\u29d8\u29da\u29fc\u2e22\u2e24\u2e26\u2e28'
'\u3008\u300a\u300c\u300e\u3010\u3014\u3016\u3018\u301a\u301d'
'\u301d\ufd3e\ufe17\ufe35\ufe37\ufe39\ufe3b\ufe3d\ufe3f\ufe41'
'\ufe43\ufe47\ufe59\ufe5b\ufe5d\uff08\uff3b\uff5b\uff5f\uff62'
'\xab\u2018\u201c\u2039\u2e02\u2e04\u2e09\u2e0c\u2e1c\u2e20'
'\u201a\u201e\xbb\u2019\u201d\u203a\u2e03\u2e05\u2e0a\u2e0d'
'\u2e1d\u2e21\u201b\u201f'
)
closers = (
'"\')>\\]}\u0f3b\u0f3d\u169c\u2046\u207e\u208e\u232a\u2769'
'\u276b\u276d\u276f\u2771\u2773\u2775\u27c6\u27e7\u27e9\u27eb'
'\u27ed\u27ef\u2984\u2986\u2988\u298a\u298c\u298e\u2990\u2992'
'\u2994\u2996\u2998\u29d9\u29db\u29fd\u2e23\u2e25\u2e27\u2e29'
'\u3009\u300b\u300d\u300f\u3011\u3015\u3017\u3019\u301b\u301e'
'\u301f\ufd3f\ufe18\ufe36\ufe38\ufe3a\ufe3c\ufe3e\ufe40\ufe42'
'\ufe44\ufe48\ufe5a\ufe5c\ufe5e\uff09\uff3d\uff5d\uff60\uff63'
'\xbb\u2019\u201d\u203a\u2e03\u2e05\u2e0a\u2e0d\u2e1d\u2e21'
'\u201b\u201f\xab\u2018\u201c\u2039\u2e02\u2e04\u2e09\u2e0c'
'\u2e1c\u2e20\u201a\u201e'
)
delimiters = (
'\\-/:\u058a\xa1\xb7\xbf\u037e\u0387\u055a-\u055f\u0589'
'\u05be\u05c0\u05c3\u05c6\u05f3\u05f4\u0609\u060a\u060c'
'\u060d\u061b\u061e\u061f\u066a-\u066d\u06d4\u0700-\u070d'
'\u07f7-\u07f9\u0830-\u083e\u0964\u0965\u0970\u0df4\u0e4f'
'\u0e5a\u0e5b\u0f04-\u0f12\u0f85\u0fd0-\u0fd4\u104a-\u104f'
'\u10fb\u1361-\u1368\u1400\u166d\u166e\u16eb-\u16ed\u1735'
'\u1736\u17d4-\u17d6\u17d8-\u17da\u1800-\u180a\u1944\u1945'
'\u19de\u19df\u1a1e\u1a1f\u1aa0-\u1aa6\u1aa8-\u1aad\u1b5a-'
'\u1b60\u1c3b-\u1c3f\u1c7e\u1c7f\u1cd3\u2010-\u2017\u2020-'
'\u2027\u2030-\u2038\u203b-\u203e\u2041-\u2043\u2047-'
'\u2051\u2053\u2055-\u205e\u2cf9-\u2cfc\u2cfe\u2cff\u2e00'
'\u2e01\u2e06-\u2e08\u2e0b\u2e0e-\u2e1b\u2e1e\u2e1f\u2e2a-'
'\u2e2e\u2e30\u2e31\u3001-\u3003\u301c\u3030\u303d\u30a0'
'\u30fb\ua4fe\ua4ff\ua60d-\ua60f\ua673\ua67e\ua6f2-\ua6f7'
'\ua874-\ua877\ua8ce\ua8cf\ua8f8-\ua8fa\ua92e\ua92f\ua95f'
'\ua9c1-\ua9cd\ua9de\ua9df\uaa5c-\uaa5f\uaade\uaadf\uabeb'
'\ufe10-\ufe16\ufe19\ufe30-\ufe32\ufe45\ufe46\ufe49-\ufe4c'
'\ufe50-\ufe52\ufe54-\ufe58\ufe5f-\ufe61\ufe63\ufe68\ufe6a'
'\ufe6b\uff01-\uff03\uff05-\uff07\uff0a\uff0c-\uff0f\uff1a'
'\uff1b\uff1f\uff20\uff3c\uff61\uff64\uff65'
'\U00010100\U00010101\U0001039f\U000103d0\U00010857'
'\U0001091f\U0001093f\U00010a50-\U00010a58\U00010a7f'
'\U00010b39-\U00010b3f\U000110bb\U000110bc\U000110be-'
'\U000110c1\U00012470-\U00012473'
)
closing_delimiters = r'\\.,;!?'
# Matching open/close quotes
# --------------------------
# Matching open/close pairs are at the same position in
# `punctuation_chars.openers` and `punctuation_chars.closers`.
# Additional matches (due to different typographic conventions
# in different languages) are stored in `quote_pairs`.
quote_pairs = {
# open char: matching closing characters # use case
'\xbb': '\xbb', # » » Swedish
'\u2018': '\u201a', # Albanian/Greek/Turkish
'\u2019': '\u2019', # Swedish
'\u201a': '\u2018\u2019', # German, Polish
'\u201c': '\u201e', # “ „ Albanian/Greek/Turkish
'\u201e': '\u201c\u201d', # „ “ German, „ ” Polish
'\u201d': '\u201d', # ” ” Swedish
'\u203a': '\u203a', # Swedish
}
"""Additional open/close quote pairs."""
def match_chars(c1, c2):
"""Test whether `c1` and `c2` are a matching open/close character pair."""
try:
i = openers.index(c1)
except ValueError: # c1 not in openers
return False
return c2 == closers[i] or c2 in quote_pairs.get(c1, '')

View file

@ -0,0 +1,154 @@
##############################################################################
#
# Copyright (c) 2001 Mark Pilgrim and Contributors.
# All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE.
#
##############################################################################
"""Convert to and from Roman numerals"""
__author__ = "Mark Pilgrim (f8dy@diveintopython.org)"
__version__ = "1.4"
__date__ = "8 August 2001"
__copyright__ = """Copyright (c) 2001 Mark Pilgrim
This program is part of "Dive Into Python", a free Python tutorial for
experienced programmers. Visit http://diveintopython.org/ for the
latest version.
This program is free software; you can redistribute it and/or modify
it under the terms of the Python 2.1.1 license, available at
http://www.python.org/2.1.1/license.html
"""
import argparse
import re
import sys
# Define exceptions
class RomanError(Exception):
pass
class OutOfRangeError(RomanError):
pass
class NotIntegerError(RomanError):
pass
class InvalidRomanNumeralError(RomanError):
pass
# Define digit mapping
romanNumeralMap = (('M', 1000),
('CM', 900),
('D', 500),
('CD', 400),
('C', 100),
('XC', 90),
('L', 50),
('XL', 40),
('X', 10),
('IX', 9),
('V', 5),
('IV', 4),
('I', 1))
def toRoman(n):
"""convert integer to Roman numeral"""
if not isinstance(n, int):
raise NotIntegerError("decimals can not be converted")
if not (-1 < n < 5000):
raise OutOfRangeError("number out of range (must be 0..4999)")
# special case
if n == 0:
return 'N'
result = ""
for numeral, integer in romanNumeralMap:
while n >= integer:
result += numeral
n -= integer
return result
# Define pattern to detect valid Roman numerals
romanNumeralPattern = re.compile("""
^ # beginning of string
M{0,4} # thousands - 0 to 4 M's
(CM|CD|D?C{0,3}) # hundreds - 900 (CM), 400 (CD), 0-300 (0 to 3 C's),
# or 500-800 (D, followed by 0 to 3 C's)
(XC|XL|L?X{0,3}) # tens - 90 (XC), 40 (XL), 0-30 (0 to 3 X's),
# or 50-80 (L, followed by 0 to 3 X's)
(IX|IV|V?I{0,3}) # ones - 9 (IX), 4 (IV), 0-3 (0 to 3 I's),
# or 5-8 (V, followed by 0 to 3 I's)
$ # end of string
""", re.VERBOSE)
def fromRoman(s):
"""convert Roman numeral to integer"""
if not s:
raise InvalidRomanNumeralError('Input can not be blank')
# special case
if s == 'N':
return 0
if not romanNumeralPattern.search(s):
raise InvalidRomanNumeralError('Invalid Roman numeral: %s' % s)
result = 0
index = 0
for numeral, integer in romanNumeralMap:
while s[index:index + len(numeral)] == numeral:
result += integer
index += len(numeral)
return result
def parse_args():
parser = argparse.ArgumentParser(
prog='roman',
description='convert between roman and arabic numerals'
)
parser.add_argument('number', help='the value to convert')
parser.add_argument(
'-r', '--reverse',
action='store_true',
default=False,
help='convert roman to numeral (case insensitive) [default: False]')
args = parser.parse_args()
args.number = args.number
return args
def main():
args = parse_args()
if args.reverse:
u = args.number.upper()
r = fromRoman(u)
print(r)
else:
i = int(args.number)
n = toRoman(i)
print(n)
return 0
if __name__ == "__main__": # pragma: no cover
sys.exit(main()) # pragma: no cover

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,138 @@
# $Id: urischemes.py 9315 2023-01-15 19:27:55Z milde $
# Author: David Goodger <goodger@python.org>
# Copyright: This module has been placed in the public domain.
"""
`schemes` is a dictionary with lowercase URI addressing schemes as
keys and descriptions as values. It was compiled from the index at
http://www.iana.org/assignments/uri-schemes (revised 2005-11-28)
and an older list at https://www.w3.org/Addressing/schemes.html.
"""
# Many values are blank and should be filled in with useful descriptions.
schemes = {
'about': 'provides information on Navigator',
'acap': 'Application Configuration Access Protocol; RFC 2244',
'addbook': "To add vCard entries to Communicator's Address Book",
'afp': 'Apple Filing Protocol',
'afs': 'Andrew File System global file names',
'aim': 'AOL Instant Messenger',
'callto': 'for NetMeeting links',
'castanet': 'Castanet Tuner URLs for Netcaster',
'chttp': 'cached HTTP supported by RealPlayer',
'cid': 'content identifier; RFC 2392',
'crid': 'TV-Anytime Content Reference Identifier; RFC 4078',
'data': 'allows inclusion of small data items as "immediate" data; '
'RFC 2397',
'dav': 'Distributed Authoring and Versioning Protocol; RFC 2518',
'dict': 'dictionary service protocol; RFC 2229',
'dns': 'Domain Name System resources',
'eid': 'External ID; non-URL data; general escape mechanism to allow '
'access to information for applications that are too '
'specialized to justify their own schemes',
'fax': 'a connection to a terminal that can handle telefaxes '
'(facsimiles); RFC 2806',
'feed': 'NetNewsWire feed',
'file': 'Host-specific file names; RFC 1738',
'finger': '',
'freenet': '',
'ftp': 'File Transfer Protocol; RFC 1738',
'go': 'go; RFC 3368',
'gopher': 'The Gopher Protocol',
'gsm-sms': 'Global System for Mobile Communications Short Message '
'Service',
'h323': 'video (audiovisual) communication on local area networks; '
'RFC 3508',
'h324': 'video and audio communications over low bitrate connections '
'such as POTS modem connections',
'hdl': 'CNRI handle system',
'hnews': 'an HTTP-tunneling variant of the NNTP news protocol',
'http': 'Hypertext Transfer Protocol; RFC 2616',
'https': 'HTTP over SSL; RFC 2818',
'hydra': 'SubEthaEdit URI. '
'See http://www.codingmonkeys.de/subethaedit.',
'iioploc': 'Internet Inter-ORB Protocol Location?',
'ilu': 'Inter-Language Unification',
'im': 'Instant Messaging; RFC 3860',
'imap': 'Internet Message Access Protocol; RFC 2192',
'info': 'Information Assets with Identifiers in Public Namespaces',
'ior': 'CORBA interoperable object reference',
'ipp': 'Internet Printing Protocol; RFC 3510',
'irc': 'Internet Relay Chat',
'iris.beep': 'iris.beep; RFC 3983',
'iseek': 'See www.ambrosiasw.com; a little util for OS X.',
'jar': 'Java archive',
'javascript': 'JavaScript code; '
'evaluates the expression after the colon',
'jdbc': 'JDBC connection URI.',
'ldap': 'Lightweight Directory Access Protocol',
'lifn': '',
'livescript': '',
'lrq': '',
'mailbox': 'Mail folder access',
'mailserver': 'Access to data available from mail servers',
'mailto': 'Electronic mail address; RFC 2368',
'md5': '',
'mid': 'message identifier; RFC 2392',
'mocha': '',
'modem': 'a connection to a terminal that can handle incoming data '
'calls; RFC 2806',
'mtqp': 'Message Tracking Query Protocol; RFC 3887',
'mupdate': 'Mailbox Update (MUPDATE) Protocol; RFC 3656',
'news': 'USENET news; RFC 1738',
'nfs': 'Network File System protocol; RFC 2224',
'nntp': 'USENET news using NNTP access; RFC 1738',
'opaquelocktoken': 'RFC 2518',
'phone': '',
'pop': 'Post Office Protocol; RFC 2384',
'pop3': 'Post Office Protocol v3',
'pres': 'Presence; RFC 3859',
'printer': '',
'prospero': 'Prospero Directory Service; RFC 4157',
'rdar': 'URLs found in Darwin source '
'(http://www.opensource.apple.com/darwinsource/).',
'res': '',
'rtsp': 'real time streaming protocol; RFC 2326',
'rvp': '',
'rwhois': '',
'rx': 'Remote Execution',
'sdp': '',
'service': 'service location; RFC 2609',
'shttp': 'secure hypertext transfer protocol',
'sip': 'Session Initiation Protocol; RFC 3261',
'sips': 'secure session intitiaion protocol; RFC 3261',
'smb': 'SAMBA filesystems.',
'snews': 'For NNTP postings via SSL',
'snmp': 'Simple Network Management Protocol; RFC 4088',
'soap.beep': 'RFC 3288',
'soap.beeps': 'RFC 3288',
'ssh': 'Reference to interactive sessions via ssh.',
't120': 'real time data conferencing (audiographics)',
'tag': 'RFC 4151',
'tcp': '',
'tel': 'a connection to a terminal that handles normal voice '
'telephone calls, a voice mailbox or another voice messaging '
'system or a service that can be operated using DTMF tones; '
'RFC 3966.',
'telephone': 'telephone',
'telnet': 'Reference to interactive sessions; RFC 4248',
'tftp': 'Trivial File Transfer Protocol; RFC 3617',
'tip': 'Transaction Internet Protocol; RFC 2371',
'tn3270': 'Interactive 3270 emulation sessions',
'tv': '',
'urn': 'Uniform Resource Name; RFC 2141',
'uuid': '',
'vemmi': 'versatile multimedia interface; RFC 2122',
'videotex': '',
'view-source': 'displays HTML code that was generated with JavaScript',
'wais': 'Wide Area Information Servers; RFC 4156',
'whodp': '',
'whois++': 'Distributed directory service.',
'x-man-page': 'Opens man page in Terminal.app on OS X '
'(see macosxhints.com)',
'xmlrpc.beep': 'RFC 3529',
'xmlrpc.beeps': 'RFC 3529',
'z39.50r': 'Z39.50 Retrieval; RFC 2056',
'z39.50s': 'Z39.50 Session; RFC 2056',
}