commit 9bb57e0e61a4887e7e595d29c8d911201a88caea Author: su-fang Date: Fri Sep 16 13:55:36 2022 +0800 Import Upstream version 1.0.2 diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..62320d3 --- /dev/null +++ b/.gitignore @@ -0,0 +1,6 @@ +*~ +/build/ +/dist/ +/ducktype.egg-info/ +/tests/*.out +__pycache__/ diff --git a/AUTHORS b/AUTHORS new file mode 100644 index 0000000..e2850a2 --- /dev/null +++ b/AUTHORS @@ -0,0 +1 @@ +Shaun McCance diff --git a/COPYING b/COPYING new file mode 100644 index 0000000..89de354 --- /dev/null +++ b/COPYING @@ -0,0 +1,17 @@ +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/README.md b/README.md new file mode 100644 index 0000000..a8a4a5f --- /dev/null +++ b/README.md @@ -0,0 +1,19 @@ +# mallard-ducktype +Parser for the lightweight Ducktype syntax for Mallard + +## Install Ducktype + +Ducktype is Python-3-only, so to build and install: + +``` +python3 setup.py build +sudo python3 setup.py install +``` + +Or to get the latest version uploaded to pypi: + +``` +virtualenv --python=python3 venv +source venv/bin/activate +pip-python3 install mallard-ducktype +``` diff --git a/bin/ducktype b/bin/ducktype new file mode 100755 index 0000000..e74048f --- /dev/null +++ b/bin/ducktype @@ -0,0 +1,58 @@ +#!/usr/bin/env python3 +# -*- Mode: python; indent-tabs-mode: nil -*- + +# Copyright (c) 2014 Shaun McCance +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +import argparse +import os +import sys + +import mallard.ducktype + +if __name__ == '__main__': + argparser = argparse.ArgumentParser() + argparser.add_argument('-o', '--output', nargs='?', + help='specify the output file or directory') + argparser.add_argument('files', nargs='+', + help='list of input duck files') + args = argparser.parse_args() + if args.output is not None: + if len(args.files) > 1 and not os.path.isdir(args.output): + sys.stderr.write('Output must be a directory for multiple files\n') + sys.exit(1) + for file in args.files: + try: + parser = mallard.ducktype.DuckParser() + parser.parse_file(file) + parser.finish() + except mallard.ducktype.SyntaxError as e: + sys.stderr.write(e.fullmessage + '\n') + basename = os.path.basename(file) + if basename.endswith('.duck'): + basename = basename[:-5] + if args.output is None: + outfile = os.path.join(os.path.dirname(file), basename + '.page') + elif os.path.isdir(args.output): + # FIXME: try to recreate directory structure? + outfile = os.path.join(args.output, basename + '.page') + else: + outfile = args.output + parser.document.write_xml(outfile) diff --git a/mallard/__init__.py b/mallard/__init__.py new file mode 100644 index 0000000..5d560f6 --- /dev/null +++ b/mallard/__init__.py @@ -0,0 +1,19 @@ +# Copyright (c) 2015 Shaun McCance +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. diff --git a/mallard/ducktype/__init__.py b/mallard/ducktype/__init__.py new file mode 100755 index 0000000..894889e --- /dev/null +++ b/mallard/ducktype/__init__.py @@ -0,0 +1,21 @@ +# Copyright (c) 2014-2015 Shaun McCance +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +from .parser import DuckParser, SyntaxError diff --git a/mallard/ducktype/entities.py b/mallard/ducktype/entities.py new file mode 100644 index 0000000..97d8d53 --- /dev/null +++ b/mallard/ducktype/entities.py @@ -0,0 +1,2262 @@ +# Copyright (c) 2014 Shaun McCance +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +# http://www.w3.org/TR/xml-entity-names/ + +entities = { +'AElig': 'Æ', # LATIN CAPITAL LETTER AE +'AMP': '&', # AMPERSAND +'Aacgr': 'Ά', # GREEK CAPITAL LETTER ALPHA WITH TONOS +'Aacute': 'Á', # LATIN CAPITAL LETTER A WITH ACUTE +'Abreve': 'Ă', # LATIN CAPITAL LETTER A WITH BREVE +'Acirc': 'Â', # LATIN CAPITAL LETTER A WITH CIRCUMFLEX +'Acy': 'А', # CYRILLIC CAPITAL LETTER A +'Afr': '𝔄', # MATHEMATICAL FRAKTUR CAPITAL A +'Agr': 'Α', # GREEK CAPITAL LETTER ALPHA +'Agrave': 'À', # LATIN CAPITAL LETTER A WITH GRAVE +'Alpha': 'Α', # GREEK CAPITAL LETTER ALPHA +'Amacr': 'Ā', # LATIN CAPITAL LETTER A WITH MACRON +'And': '⩓', # DOUBLE LOGICAL AND +'Aogon': 'Ą', # LATIN CAPITAL LETTER A WITH OGONEK +'Aopf': '𝔸', # MATHEMATICAL DOUBLE-STRUCK CAPITAL A +'ApplyFunction': '⁡', # FUNCTION APPLICATION +'Aring': 'Å', # LATIN CAPITAL LETTER A WITH RING ABOVE +'Ascr': '𝒜', # MATHEMATICAL SCRIPT CAPITAL A +'Assign': '≔', # COLON EQUALS +'Atilde': 'Ã', # LATIN CAPITAL LETTER A WITH TILDE +'Auml': 'Ä', # LATIN CAPITAL LETTER A WITH DIAERESIS +'Backslash': '∖', # SET MINUS +'Barv': '⫧', # SHORT DOWN TACK WITH OVERBAR +'Barwed': '⌆', # PERSPECTIVE +'Bcy': 'Б', # CYRILLIC CAPITAL LETTER BE +'Because': '∵', # BECAUSE +'Bernoullis': 'ℬ', # SCRIPT CAPITAL B +'Beta': 'Β', # GREEK CAPITAL LETTER BETA +'Bfr': '𝔅', # MATHEMATICAL FRAKTUR CAPITAL B +'Bgr': 'Β', # GREEK CAPITAL LETTER BETA +'Bopf': '𝔹', # MATHEMATICAL DOUBLE-STRUCK CAPITAL B +'Breve': '˘', # BREVE +'Bscr': 'ℬ', # SCRIPT CAPITAL B +'Bumpeq': '≎', # GEOMETRICALLY EQUIVALENT TO +'CHcy': 'Ч', # CYRILLIC CAPITAL LETTER CHE +'COPY': '©', # COPYRIGHT SIGN +'Cacute': 'Ć', # LATIN CAPITAL LETTER C WITH ACUTE +'Cap': '⋒', # DOUBLE INTERSECTION +'CapitalDifferentialD': 'ⅅ', # DOUBLE-STRUCK ITALIC CAPITAL D +'Cayleys': 'ℭ', # BLACK-LETTER CAPITAL C +'Ccaron': 'Č', # LATIN CAPITAL LETTER C WITH CARON +'Ccedil': 'Ç', # LATIN CAPITAL LETTER C WITH CEDILLA +'Ccirc': 'Ĉ', # LATIN CAPITAL LETTER C WITH CIRCUMFLEX +'Cconint': '∰', # VOLUME INTEGRAL +'Cdot': 'Ċ', # LATIN CAPITAL LETTER C WITH DOT ABOVE +'Cedilla': '¸', # CEDILLA +'CenterDot': '·', # MIDDLE DOT +'Cfr': 'ℭ', # BLACK-LETTER CAPITAL C +'Chi': 'Χ', # GREEK CAPITAL LETTER CHI +'CircleDot': '⊙', # CIRCLED DOT OPERATOR +'CircleMinus': '⊖', # CIRCLED MINUS +'CirclePlus': '⊕', # CIRCLED PLUS +'CircleTimes': '⊗', # CIRCLED TIMES +'ClockwiseContourIntegral': '∲', # CLOCKWISE CONTOUR INTEGRAL +'CloseCurlyDoubleQuote': '”', # RIGHT DOUBLE QUOTATION MARK +'CloseCurlyQuote': '’', # RIGHT SINGLE QUOTATION MARK +'Colon': '∷', # PROPORTION +'Colone': '⩴', # DOUBLE COLON EQUAL +'Congruent': '≡', # IDENTICAL TO +'Conint': '∯', # SURFACE INTEGRAL +'ContourIntegral': '∮', # CONTOUR INTEGRAL +'Copf': 'ℂ', # DOUBLE-STRUCK CAPITAL C +'Coproduct': '∐', # N-ARY COPRODUCT +'CounterClockwiseContourIntegral': '∳', # ANTICLOCKWISE CONTOUR INTEGRAL +'Cross': '⨯', # VECTOR OR CROSS PRODUCT +'Cscr': '𝒞', # MATHEMATICAL SCRIPT CAPITAL C +'Cup': '⋓', # DOUBLE UNION +'CupCap': '≍', # EQUIVALENT TO +'DD': 'ⅅ', # DOUBLE-STRUCK ITALIC CAPITAL D +'DDotrahd': '⤑', # RIGHTWARDS ARROW WITH DOTTED STEM +'DJcy': 'Ђ', # CYRILLIC CAPITAL LETTER DJE +'DScy': 'Ѕ', # CYRILLIC CAPITAL LETTER DZE +'DZcy': 'Џ', # CYRILLIC CAPITAL LETTER DZHE +'Dagger': '‡', # DOUBLE DAGGER +'Darr': '↡', # DOWNWARDS TWO HEADED ARROW +'Dashv': '⫤', # VERTICAL BAR DOUBLE LEFT TURNSTILE +'Dcaron': 'Ď', # LATIN CAPITAL LETTER D WITH CARON +'Dcy': 'Д', # CYRILLIC CAPITAL LETTER DE +'Del': '∇', # NABLA +'Delta': 'Δ', # GREEK CAPITAL LETTER DELTA +'Dfr': '𝔇', # MATHEMATICAL FRAKTUR CAPITAL D +'Dgr': 'Δ', # GREEK CAPITAL LETTER DELTA +'DiacriticalAcute': '´', # ACUTE ACCENT +'DiacriticalDot': '˙', # DOT ABOVE +'DiacriticalDoubleAcute': '˝', # DOUBLE ACUTE ACCENT +'DiacriticalGrave': '`', # GRAVE ACCENT +'DiacriticalTilde': '˜', # SMALL TILDE +'Diamond': '⋄', # DIAMOND OPERATOR +'DifferentialD': 'ⅆ', # DOUBLE-STRUCK ITALIC SMALL D +'Dopf': '𝔻', # MATHEMATICAL DOUBLE-STRUCK CAPITAL D +'Dot': '¨', # DIAERESIS +'DotDot': '\u20DC', # COMBINING FOUR DOTS ABOVE +'DotEqual': '≐', # APPROACHES THE LIMIT +'DoubleContourIntegral': '∯', # SURFACE INTEGRAL +'DoubleDot': '¨', # DIAERESIS +'DoubleDownArrow': '⇓', # DOWNWARDS DOUBLE ARROW +'DoubleLeftArrow': '⇐', # LEFTWARDS DOUBLE ARROW +'DoubleLeftRightArrow': '⇔', # LEFT RIGHT DOUBLE ARROW +'DoubleLeftTee': '⫤', # VERTICAL BAR DOUBLE LEFT TURNSTILE +'DoubleLongLeftArrow': '⟸', # LONG LEFTWARDS DOUBLE ARROW +'DoubleLongLeftRightArrow': '⟺', # LONG LEFT RIGHT DOUBLE ARROW +'DoubleLongRightArrow': '⟹', # LONG RIGHTWARDS DOUBLE ARROW +'DoubleRightArrow': '⇒', # RIGHTWARDS DOUBLE ARROW +'DoubleRightTee': '⊨', # TRUE +'DoubleUpArrow': '⇑', # UPWARDS DOUBLE ARROW +'DoubleUpDownArrow': '⇕', # UP DOWN DOUBLE ARROW +'DoubleVerticalBar': '∥', # PARALLEL TO +'DownArrow': '↓', # DOWNWARDS ARROW +'DownArrowBar': '⤓', # DOWNWARDS ARROW TO BAR +'DownArrowUpArrow': '⇵', # DOWNWARDS ARROW LEFTWARDS OF UPWARDS ARROW +'DownBreve': '\u0311', # COMBINING INVERTED BREVE +'DownLeftRightVector': '⥐', # LEFT BARB DOWN RIGHT BARB DOWN HARPOON +'DownLeftTeeVector': '⥞', # LEFTWARDS HARPOON WITH BARB DOWN FROM BAR +'DownLeftVector': '↽', # LEFTWARDS HARPOON WITH BARB DOWNWARDS +'DownLeftVectorBar': '⥖', # LEFTWARDS HARPOON WITH BARB DOWN TO BAR +'DownRightTeeVector': '⥟', # RIGHTWARDS HARPOON WITH BARB DOWN FROM BAR +'DownRightVector': '⇁', # RIGHTWARDS HARPOON WITH BARB DOWNWARDS +'DownRightVectorBar': '⥗', # RIGHTWARDS HARPOON WITH BARB DOWN TO BAR +'DownTee': '⊤', # DOWN TACK +'DownTeeArrow': '↧', # DOWNWARDS ARROW FROM BAR +'Downarrow': '⇓', # DOWNWARDS DOUBLE ARROW +'Dscr': '𝒟', # MATHEMATICAL SCRIPT CAPITAL D +'Dstrok': 'Đ', # LATIN CAPITAL LETTER D WITH STROKE +'EEacgr': 'Ή', # GREEK CAPITAL LETTER ETA WITH TONOS +'EEgr': 'Η', # GREEK CAPITAL LETTER ETA +'ENG': 'Ŋ', # LATIN CAPITAL LETTER ENG +'ETH': 'Ð', # LATIN CAPITAL LETTER ETH +'Eacgr': 'Έ', # GREEK CAPITAL LETTER EPSILON WITH TONOS +'Eacute': 'É', # LATIN CAPITAL LETTER E WITH ACUTE +'Ecaron': 'Ě', # LATIN CAPITAL LETTER E WITH CARON +'Ecirc': 'Ê', # LATIN CAPITAL LETTER E WITH CIRCUMFLEX +'Ecy': 'Э', # CYRILLIC CAPITAL LETTER E +'Edot': 'Ė', # LATIN CAPITAL LETTER E WITH DOT ABOVE +'Efr': '𝔈', # MATHEMATICAL FRAKTUR CAPITAL E +'Egr': 'Ε', # GREEK CAPITAL LETTER EPSILON +'Egrave': 'È', # LATIN CAPITAL LETTER E WITH GRAVE +'Element': '∈', # ELEMENT OF +'Emacr': 'Ē', # LATIN CAPITAL LETTER E WITH MACRON +'EmptySmallSquare': '◻', # WHITE MEDIUM SQUARE +'EmptyVerySmallSquare': '▫', # WHITE SMALL SQUARE +'Eogon': 'Ę', # LATIN CAPITAL LETTER E WITH OGONEK +'Eopf': '𝔼', # MATHEMATICAL DOUBLE-STRUCK CAPITAL E +'Epsilon': 'Ε', # GREEK CAPITAL LETTER EPSILON +'Equal': '⩵', # TWO CONSECUTIVE EQUALS SIGNS +'EqualTilde': '≂', # MINUS TILDE +'Equilibrium': '⇌', # RIGHTWARDS HARPOON OVER LEFTWARDS HARPOON +'Escr': 'ℰ', # SCRIPT CAPITAL E +'Esim': '⩳', # EQUALS SIGN ABOVE TILDE OPERATOR +'Eta': 'Η', # GREEK CAPITAL LETTER ETA +'Euml': 'Ë', # LATIN CAPITAL LETTER E WITH DIAERESIS +'Exists': '∃', # THERE EXISTS +'ExponentialE': 'ⅇ', # DOUBLE-STRUCK ITALIC SMALL E +'Fcy': 'Ф', # CYRILLIC CAPITAL LETTER EF +'Ffr': '𝔉', # MATHEMATICAL FRAKTUR CAPITAL F +'FilledSmallSquare': '◼', # BLACK MEDIUM SQUARE +'FilledVerySmallSquare': '▪', # BLACK SMALL SQUARE +'Fopf': '𝔽', # MATHEMATICAL DOUBLE-STRUCK CAPITAL F +'ForAll': '∀', # FOR ALL +'Fouriertrf': 'ℱ', # SCRIPT CAPITAL F +'Fscr': 'ℱ', # SCRIPT CAPITAL F +'GJcy': 'Ѓ', # CYRILLIC CAPITAL LETTER GJE +'GT': '>', # GREATER-THAN SIGN +'Gamma': 'Γ', # GREEK CAPITAL LETTER GAMMA +'Gammad': 'Ϝ', # GREEK LETTER DIGAMMA +'Gbreve': 'Ğ', # LATIN CAPITAL LETTER G WITH BREVE +'Gcedil': 'Ģ', # LATIN CAPITAL LETTER G WITH CEDILLA +'Gcirc': 'Ĝ', # LATIN CAPITAL LETTER G WITH CIRCUMFLEX +'Gcy': 'Г', # CYRILLIC CAPITAL LETTER GHE +'Gdot': 'Ġ', # LATIN CAPITAL LETTER G WITH DOT ABOVE +'Gfr': '𝔊', # MATHEMATICAL FRAKTUR CAPITAL G +'Gg': '⋙', # VERY MUCH GREATER-THAN +'Ggr': 'Γ', # GREEK CAPITAL LETTER GAMMA +'Gopf': '𝔾', # MATHEMATICAL DOUBLE-STRUCK CAPITAL G +'GreaterEqual': '≥', # GREATER-THAN OR EQUAL TO +'GreaterEqualLess': '⋛', # GREATER-THAN EQUAL TO OR LESS-THAN +'GreaterFullEqual': '≧', # GREATER-THAN OVER EQUAL TO +'GreaterGreater': '⪢', # DOUBLE NESTED GREATER-THAN +'GreaterLess': '≷', # GREATER-THAN OR LESS-THAN +'GreaterSlantEqual': '⩾', # GREATER-THAN OR SLANTED EQUAL TO +'GreaterTilde': '≳', # GREATER-THAN OR EQUIVALENT TO +'Gscr': '𝒢', # MATHEMATICAL SCRIPT CAPITAL G +'Gt': '≫', # MUCH GREATER-THAN +'HARDcy': 'Ъ', # CYRILLIC CAPITAL LETTER HARD SIGN +'Hacek': 'ˇ', # CARON +'Hat': '^', # CIRCUMFLEX ACCENT +'Hcirc': 'Ĥ', # LATIN CAPITAL LETTER H WITH CIRCUMFLEX +'Hfr': 'ℌ', # BLACK-LETTER CAPITAL H +'HilbertSpace': 'ℋ', # SCRIPT CAPITAL H +'Hopf': 'ℍ', # DOUBLE-STRUCK CAPITAL H +'HorizontalLine': '─', # BOX DRAWINGS LIGHT HORIZONTAL +'Hscr': 'ℋ', # SCRIPT CAPITAL H +'Hstrok': 'Ħ', # LATIN CAPITAL LETTER H WITH STROKE +'HumpDownHump': '≎', # GEOMETRICALLY EQUIVALENT TO +'HumpEqual': '≏', # DIFFERENCE BETWEEN +'IEcy': 'Е', # CYRILLIC CAPITAL LETTER IE +'IJlig': 'IJ', # LATIN CAPITAL LIGATURE IJ +'IOcy': 'Ё', # CYRILLIC CAPITAL LETTER IO +'Iacgr': 'Ί', # GREEK CAPITAL LETTER IOTA WITH TONOS +'Iacute': 'Í', # LATIN CAPITAL LETTER I WITH ACUTE +'Icirc': 'Î', # LATIN CAPITAL LETTER I WITH CIRCUMFLEX +'Icy': 'И', # CYRILLIC CAPITAL LETTER I +'Idigr': 'Ϊ', # GREEK CAPITAL LETTER IOTA WITH DIALYTIKA +'Idot': 'İ', # LATIN CAPITAL LETTER I WITH DOT ABOVE +'Ifr': 'ℑ', # BLACK-LETTER CAPITAL I +'Igr': 'Ι', # GREEK CAPITAL LETTER IOTA +'Igrave': 'Ì', # LATIN CAPITAL LETTER I WITH GRAVE +'Im': 'ℑ', # BLACK-LETTER CAPITAL I +'Imacr': 'Ī', # LATIN CAPITAL LETTER I WITH MACRON +'ImaginaryI': 'ⅈ', # DOUBLE-STRUCK ITALIC SMALL I +'Implies': '⇒', # RIGHTWARDS DOUBLE ARROW +'Int': '∬', # DOUBLE INTEGRAL +'Integral': '∫', # INTEGRAL +'Intersection': '⋂', # N-ARY INTERSECTION +'InvisibleComma': '⁣', # INVISIBLE SEPARATOR +'InvisibleTimes': '⁢', # INVISIBLE TIMES +'Iogon': 'Į', # LATIN CAPITAL LETTER I WITH OGONEK +'Iopf': '𝕀', # MATHEMATICAL DOUBLE-STRUCK CAPITAL I +'Iota': 'Ι', # GREEK CAPITAL LETTER IOTA +'Iscr': 'ℐ', # SCRIPT CAPITAL I +'Itilde': 'Ĩ', # LATIN CAPITAL LETTER I WITH TILDE +'Iukcy': 'І', # CYRILLIC CAPITAL LETTER BYELORUSSIAN-UKRAINIAN I +'Iuml': 'Ï', # LATIN CAPITAL LETTER I WITH DIAERESIS +'Jcirc': 'Ĵ', # LATIN CAPITAL LETTER J WITH CIRCUMFLEX +'Jcy': 'Й', # CYRILLIC CAPITAL LETTER SHORT I +'Jfr': '𝔍', # MATHEMATICAL FRAKTUR CAPITAL J +'Jopf': '𝕁', # MATHEMATICAL DOUBLE-STRUCK CAPITAL J +'Jscr': '𝒥', # MATHEMATICAL SCRIPT CAPITAL J +'Jsercy': 'Ј', # CYRILLIC CAPITAL LETTER JE +'Jukcy': 'Є', # CYRILLIC CAPITAL LETTER UKRAINIAN IE +'KHcy': 'Х', # CYRILLIC CAPITAL LETTER HA +'KHgr': 'Χ', # GREEK CAPITAL LETTER CHI +'KJcy': 'Ќ', # CYRILLIC CAPITAL LETTER KJE +'Kappa': 'Κ', # GREEK CAPITAL LETTER KAPPA +'Kcedil': 'Ķ', # LATIN CAPITAL LETTER K WITH CEDILLA +'Kcy': 'К', # CYRILLIC CAPITAL LETTER KA +'Kfr': '𝔎', # MATHEMATICAL FRAKTUR CAPITAL K +'Kgr': 'Κ', # GREEK CAPITAL LETTER KAPPA +'Kopf': '𝕂', # MATHEMATICAL DOUBLE-STRUCK CAPITAL K +'Kscr': '𝒦', # MATHEMATICAL SCRIPT CAPITAL K +'LJcy': 'Љ', # CYRILLIC CAPITAL LETTER LJE +'LT': '&', # LESS-THAN SIGN +'Lacute': 'Ĺ', # LATIN CAPITAL LETTER L WITH ACUTE +'Lambda': 'Λ', # GREEK CAPITAL LETTER LAMDA +'Lang': '⟪', # MATHEMATICAL LEFT DOUBLE ANGLE BRACKET +'Laplacetrf': 'ℒ', # SCRIPT CAPITAL L +'Larr': '↞', # LEFTWARDS TWO HEADED ARROW +'Lcaron': 'Ľ', # LATIN CAPITAL LETTER L WITH CARON +'Lcedil': 'Ļ', # LATIN CAPITAL LETTER L WITH CEDILLA +'Lcy': 'Л', # CYRILLIC CAPITAL LETTER EL +'LeftAngleBracket': '⟨', # MATHEMATICAL LEFT ANGLE BRACKET +'LeftArrow': '←', # LEFTWARDS ARROW +'LeftArrowBar': '⇤', # LEFTWARDS ARROW TO BAR +'LeftArrowRightArrow': '⇆', # LEFTWARDS ARROW OVER RIGHTWARDS ARROW +'LeftCeiling': '⌈', # LEFT CEILING +'LeftDoubleBracket': '⟦', # MATHEMATICAL LEFT WHITE SQUARE BRACKET +'LeftDownTeeVector': '⥡', # DOWNWARDS HARPOON WITH BARB LEFT FROM BAR +'LeftDownVector': '⇃', # DOWNWARDS HARPOON WITH BARB LEFTWARDS +'LeftDownVectorBar': '⥙', # DOWNWARDS HARPOON WITH BARB LEFT TO BAR +'LeftFloor': '⌊', # LEFT FLOOR +'LeftRightArrow': '↔', # LEFT RIGHT ARROW +'LeftRightVector': '⥎', # LEFT BARB UP RIGHT BARB UP HARPOON +'LeftTee': '⊣', # LEFT TACK +'LeftTeeArrow': '↤', # LEFTWARDS ARROW FROM BAR +'LeftTeeVector': '⥚', # LEFTWARDS HARPOON WITH BARB UP FROM BAR +'LeftTriangle': '⊲', # NORMAL SUBGROUP OF +'LeftTriangleBar': '⧏', # LEFT TRIANGLE BESIDE VERTICAL BAR +'LeftTriangleEqual': '⊴', # NORMAL SUBGROUP OF OR EQUAL TO +'LeftUpDownVector': '⥑', # UP BARB LEFT DOWN BARB LEFT HARPOON +'LeftUpTeeVector': '⥠', # UPWARDS HARPOON WITH BARB LEFT FROM BAR +'LeftUpVector': '↿', # UPWARDS HARPOON WITH BARB LEFTWARDS +'LeftUpVectorBar': '⥘', # UPWARDS HARPOON WITH BARB LEFT TO BAR +'LeftVector': '↼', # LEFTWARDS HARPOON WITH BARB UPWARDS +'LeftVectorBar': '⥒', # LEFTWARDS HARPOON WITH BARB UP TO BAR +'Leftarrow': '⇐', # LEFTWARDS DOUBLE ARROW +'Leftrightarrow': '⇔', # LEFT RIGHT DOUBLE ARROW +'LessEqualGreater': '⋚', # LESS-THAN EQUAL TO OR GREATER-THAN +'LessFullEqual': '≦', # LESS-THAN OVER EQUAL TO +'LessGreater': '≶', # LESS-THAN OR GREATER-THAN +'LessLess': '⪡', # DOUBLE NESTED LESS-THAN +'LessSlantEqual': '⩽', # LESS-THAN OR SLANTED EQUAL TO +'LessTilde': '≲', # LESS-THAN OR EQUIVALENT TO +'Lfr': '𝔏', # MATHEMATICAL FRAKTUR CAPITAL L +'Lgr': 'Λ', # GREEK CAPITAL LETTER LAMDA +'Ll': '⋘', # VERY MUCH LESS-THAN +'Lleftarrow': '⇚', # LEFTWARDS TRIPLE ARROW +'Lmidot': 'Ŀ', # LATIN CAPITAL LETTER L WITH MIDDLE DOT +'LongLeftArrow': '⟵', # LONG LEFTWARDS ARROW +'LongLeftRightArrow': '⟷', # LONG LEFT RIGHT ARROW +'LongRightArrow': '⟶', # LONG RIGHTWARDS ARROW +'Longleftarrow': '⟸', # LONG LEFTWARDS DOUBLE ARROW +'Longleftrightarrow': '⟺', # LONG LEFT RIGHT DOUBLE ARROW +'Longrightarrow': '⟹', # LONG RIGHTWARDS DOUBLE ARROW +'Lopf': '𝕃', # MATHEMATICAL DOUBLE-STRUCK CAPITAL L +'LowerLeftArrow': '↙', # SOUTH WEST ARROW +'LowerRightArrow': '↘', # SOUTH EAST ARROW +'Lscr': 'ℒ', # SCRIPT CAPITAL L +'Lsh': '↰', # UPWARDS ARROW WITH TIP LEFTWARDS +'Lstrok': 'Ł', # LATIN CAPITAL LETTER L WITH STROKE +'Lt': '≪', # MUCH LESS-THAN +'Map': '⤅', # RIGHTWARDS TWO-HEADED ARROW FROM BAR +'Mcy': 'М', # CYRILLIC CAPITAL LETTER EM +'MediumSpace': ' ', # MEDIUM MATHEMATICAL SPACE +'Mellintrf': 'ℳ', # SCRIPT CAPITAL M +'Mfr': '𝔐', # MATHEMATICAL FRAKTUR CAPITAL M +'Mgr': 'Μ', # GREEK CAPITAL LETTER MU +'MinusPlus': '∓', # MINUS-OR-PLUS SIGN +'Mopf': '𝕄', # MATHEMATICAL DOUBLE-STRUCK CAPITAL M +'Mscr': 'ℳ', # SCRIPT CAPITAL M +'Mu': 'Μ', # GREEK CAPITAL LETTER MU +'NJcy': 'Њ', # CYRILLIC CAPITAL LETTER NJE +'Nacute': 'Ń', # LATIN CAPITAL LETTER N WITH ACUTE +'Ncaron': 'Ň', # LATIN CAPITAL LETTER N WITH CARON +'Ncedil': 'Ņ', # LATIN CAPITAL LETTER N WITH CEDILLA +'Ncy': 'Н', # CYRILLIC CAPITAL LETTER EN +'NegativeMediumSpace': '​', # ZERO WIDTH SPACE +'NegativeThickSpace': '​', # ZERO WIDTH SPACE +'NegativeThinSpace': '​', # ZERO WIDTH SPACE +'NegativeVeryThinSpace': '​', # ZERO WIDTH SPACE +'NestedGreaterGreater': '≫', # MUCH GREATER-THAN +'NestedLessLess': '≪', # MUCH LESS-THAN +'NewLine': '\u000A', # LINE FEED (LF) +'Nfr': '𝔑', # MATHEMATICAL FRAKTUR CAPITAL N +'Ngr': 'Ν', # GREEK CAPITAL LETTER NU +'NoBreak': '⁠', # WORD JOINER +'NonBreakingSpace': ' ', # NO-BREAK SPACE +'Nopf': 'ℕ', # DOUBLE-STRUCK CAPITAL N +'Not': '⫬', # DOUBLE STROKE NOT SIGN +'NotCongruent': '≢', # NOT IDENTICAL TO +'NotCupCap': '≭', # NOT EQUIVALENT TO +'NotDoubleVerticalBar': '∦', # NOT PARALLEL TO +'NotElement': '∉', # NOT AN ELEMENT OF +'NotEqual': '≠', # NOT EQUAL TO +'NotEqualTilde': '≂̸', # MINUS TILDE with slash +'NotExists': '∄', # THERE DOES NOT EXIST +'NotGreater': '≯', # NOT GREATER-THAN +'NotGreaterEqual': '≱', # NEITHER GREATER-THAN NOR EQUAL TO +'NotGreaterFullEqual': '≧̸', # GREATER-THAN OVER EQUAL TO with slash +'NotGreaterGreater': '≫̸', # MUCH GREATER THAN with slash +'NotGreaterLess': '≹', # NEITHER GREATER-THAN NOR LESS-THAN +'NotGreaterSlantEqual': '⩾̸', # GREATER-THAN OR SLANTED EQUAL TO with slash +'NotGreaterTilde': '≵', # NEITHER GREATER-THAN NOR EQUIVALENT TO +'NotHumpDownHump': '≎̸', # GEOMETRICALLY EQUIVALENT TO with slash +'NotHumpEqual': '≏̸', # DIFFERENCE BETWEEN with slash +'NotLeftTriangle': '⋪', # NOT NORMAL SUBGROUP OF +'NotLeftTriangleBar': '⧏̸', # LEFT TRIANGLE BESIDE VERTICAL BAR with slash +'NotLeftTriangleEqual': '⋬', # NOT NORMAL SUBGROUP OF OR EQUAL TO +'NotLess': '≮', # NOT LESS-THAN +'NotLessEqual': '≰', # NEITHER LESS-THAN NOR EQUAL TO +'NotLessGreater': '≸', # NEITHER LESS-THAN NOR GREATER-THAN +'NotLessLess': '≪̸', # MUCH LESS THAN with slash +'NotLessSlantEqual': '⩽̸', # LESS-THAN OR SLANTED EQUAL TO with slash +'NotLessTilde': '≴', # NEITHER LESS-THAN NOR EQUIVALENT TO +'NotNestedGreaterGreater': '⪢̸', # DOUBLE NESTED GREATER-THAN with slash +'NotNestedLessLess': '⪡̸', # DOUBLE NESTED LESS-THAN with slash +'NotPrecedes': '⊀', # DOES NOT PRECEDE +'NotPrecedesEqual': '⪯̸', # PRECEDES ABOVE SINGLE-LINE EQUALS SIGN with slash +'NotPrecedesSlantEqual': '⋠', # DOES NOT PRECEDE OR EQUAL +'NotReverseElement': '∌', # DOES NOT CONTAIN AS MEMBER +'NotRightTriangle': '⋫', # DOES NOT CONTAIN AS NORMAL SUBGROUP +'NotRightTriangleBar': '⧐̸', # VERTICAL BAR BESIDE RIGHT TRIANGLE with slash +'NotRightTriangleEqual': '⋭', # DOES NOT CONTAIN AS NORMAL SUBGROUP OR EQUAL +'NotSquareSubset': '⊏̸', # SQUARE IMAGE OF with slash +'NotSquareSubsetEqual': '⋢', # NOT SQUARE IMAGE OF OR EQUAL TO +'NotSquareSuperset': '⊐̸', # SQUARE ORIGINAL OF with slash +'NotSquareSupersetEqual': '⋣', # NOT SQUARE ORIGINAL OF OR EQUAL TO +'NotSubset': '⊂⃒', # SUBSET OF with vertical line +'NotSubsetEqual': '⊈', # NEITHER A SUBSET OF NOR EQUAL TO +'NotSucceeds': '⊁', # DOES NOT SUCCEED +'NotSucceedsEqual': '⪰̸', # SUCCEEDS ABOVE SINGLE-LINE EQUALS SIGN with slash +'NotSucceedsSlantEqual': '⋡', # DOES NOT SUCCEED OR EQUAL +'NotSucceedsTilde': '≿̸', # SUCCEEDS OR EQUIVALENT TO with slash +'NotSuperset': '⊃⃒', # SUPERSET OF with vertical line +'NotSupersetEqual': '⊉', # NEITHER A SUPERSET OF NOR EQUAL TO +'NotTilde': '≁', # NOT TILDE +'NotTildeEqual': '≄', # NOT ASYMPTOTICALLY EQUAL TO +'NotTildeFullEqual': '≇', # NEITHER APPROXIMATELY NOR ACTUALLY EQUAL TO +'NotTildeTilde': '≉', # NOT ALMOST EQUAL TO +'NotVerticalBar': '∤', # DOES NOT DIVIDE +'Nscr': '𝒩', # MATHEMATICAL SCRIPT CAPITAL N +'Ntilde': 'Ñ', # LATIN CAPITAL LETTER N WITH TILDE +'Nu': 'Ν', # GREEK CAPITAL LETTER NU +'OElig': 'Œ', # LATIN CAPITAL LIGATURE OE +'OHacgr': 'Ώ', # GREEK CAPITAL LETTER OMEGA WITH TONOS +'OHgr': 'Ω', # GREEK CAPITAL LETTER OMEGA +'Oacgr': 'Ό', # GREEK CAPITAL LETTER OMICRON WITH TONOS +'Oacute': 'Ó', # LATIN CAPITAL LETTER O WITH ACUTE +'Ocirc': 'Ô', # LATIN CAPITAL LETTER O WITH CIRCUMFLEX +'Ocy': 'О', # CYRILLIC CAPITAL LETTER O +'Odblac': 'Ő', # LATIN CAPITAL LETTER O WITH DOUBLE ACUTE +'Ofr': '𝔒', # MATHEMATICAL FRAKTUR CAPITAL O +'Ogr': 'Ο', # GREEK CAPITAL LETTER OMICRON +'Ograve': 'Ò', # LATIN CAPITAL LETTER O WITH GRAVE +'Omacr': 'Ō', # LATIN CAPITAL LETTER O WITH MACRON +'Omega': 'Ω', # GREEK CAPITAL LETTER OMEGA +'Omicron': 'Ο', # GREEK CAPITAL LETTER OMICRON +'Oopf': '𝕆', # MATHEMATICAL DOUBLE-STRUCK CAPITAL O +'OpenCurlyDoubleQuote': '“', # LEFT DOUBLE QUOTATION MARK +'OpenCurlyQuote': '‘', # LEFT SINGLE QUOTATION MARK +'Or': '⩔', # DOUBLE LOGICAL OR +'Oscr': '𝒪', # MATHEMATICAL SCRIPT CAPITAL O +'Oslash': 'Ø', # LATIN CAPITAL LETTER O WITH STROKE +'Otilde': 'Õ', # LATIN CAPITAL LETTER O WITH TILDE +'Otimes': '⨷', # MULTIPLICATION SIGN IN DOUBLE CIRCLE +'Ouml': 'Ö', # LATIN CAPITAL LETTER O WITH DIAERESIS +'OverBar': '‾', # OVERLINE +'OverBrace': '⏞', # TOP CURLY BRACKET +'OverBracket': '⎴', # TOP SQUARE BRACKET +'OverParenthesis': '⏜', # TOP PARENTHESIS +'PHgr': 'Φ', # GREEK CAPITAL LETTER PHI +'PSgr': 'Ψ', # GREEK CAPITAL LETTER PSI +'PartialD': '∂', # PARTIAL DIFFERENTIAL +'Pcy': 'П', # CYRILLIC CAPITAL LETTER PE +'Pfr': '𝔓', # MATHEMATICAL FRAKTUR CAPITAL P +'Pgr': 'Π', # GREEK CAPITAL LETTER PI +'Phi': 'Φ', # GREEK CAPITAL LETTER PHI +'Pi': 'Π', # GREEK CAPITAL LETTER PI +'PlusMinus': '±', # PLUS-MINUS SIGN +'Poincareplane': 'ℌ', # BLACK-LETTER CAPITAL H +'Popf': 'ℙ', # DOUBLE-STRUCK CAPITAL P +'Pr': '⪻', # DOUBLE PRECEDES +'Precedes': '≺', # PRECEDES +'PrecedesEqual': '⪯', # PRECEDES ABOVE SINGLE-LINE EQUALS SIGN +'PrecedesSlantEqual': '≼', # PRECEDES OR EQUAL TO +'PrecedesTilde': '≾', # PRECEDES OR EQUIVALENT TO +'Prime': '″', # DOUBLE PRIME +'Product': '∏', # N-ARY PRODUCT +'Proportion': '∷', # PROPORTION +'Proportional': '∝', # PROPORTIONAL TO +'Pscr': '𝒫', # MATHEMATICAL SCRIPT CAPITAL P +'Psi': 'Ψ', # GREEK CAPITAL LETTER PSI +'QUOT': '"', # QUOTATION MARK +'Qfr': '𝔔', # MATHEMATICAL FRAKTUR CAPITAL Q +'Qopf': 'ℚ', # DOUBLE-STRUCK CAPITAL Q +'Qscr': '𝒬', # MATHEMATICAL SCRIPT CAPITAL Q +'RBarr': '⤐', # RIGHTWARDS TWO-HEADED TRIPLE DASH ARROW +'REG': '®', # REGISTERED SIGN +'Racute': 'Ŕ', # LATIN CAPITAL LETTER R WITH ACUTE +'Rang': '⟫', # MATHEMATICAL RIGHT DOUBLE ANGLE BRACKET +'Rarr': '↠', # RIGHTWARDS TWO HEADED ARROW +'Rarrtl': '⤖', # RIGHTWARDS TWO-HEADED ARROW WITH TAIL +'Rcaron': 'Ř', # LATIN CAPITAL LETTER R WITH CARON +'Rcedil': 'Ŗ', # LATIN CAPITAL LETTER R WITH CEDILLA +'Rcy': 'Р', # CYRILLIC CAPITAL LETTER ER +'Re': 'ℜ', # BLACK-LETTER CAPITAL R +'ReverseElement': '∋', # CONTAINS AS MEMBER +'ReverseEquilibrium': '⇋', # LEFTWARDS HARPOON OVER RIGHTWARDS HARPOON +'ReverseUpEquilibrium': '⥯', # DOWNWARDS HARPOON WITH BARB LEFT BESIDE UPWARDS HARPOON WITH BARB RIGHT +'Rfr': 'ℜ', # BLACK-LETTER CAPITAL R +'Rgr': 'Ρ', # GREEK CAPITAL LETTER RHO +'Rho': 'Ρ', # GREEK CAPITAL LETTER RHO +'RightAngleBracket': '⟩', # MATHEMATICAL RIGHT ANGLE BRACKET +'RightArrow': '→', # RIGHTWARDS ARROW +'RightArrowBar': '⇥', # RIGHTWARDS ARROW TO BAR +'RightArrowLeftArrow': '⇄', # RIGHTWARDS ARROW OVER LEFTWARDS ARROW +'RightCeiling': '⌉', # RIGHT CEILING +'RightDoubleBracket': '⟧', # MATHEMATICAL RIGHT WHITE SQUARE BRACKET +'RightDownTeeVector': '⥝', # DOWNWARDS HARPOON WITH BARB RIGHT FROM BAR +'RightDownVector': '⇂', # DOWNWARDS HARPOON WITH BARB RIGHTWARDS +'RightDownVectorBar': '⥕', # DOWNWARDS HARPOON WITH BARB RIGHT TO BAR +'RightFloor': '⌋', # RIGHT FLOOR +'RightTee': '⊢', # RIGHT TACK +'RightTeeArrow': '↦', # RIGHTWARDS ARROW FROM BAR +'RightTeeVector': '⥛', # RIGHTWARDS HARPOON WITH BARB UP FROM BAR +'RightTriangle': '⊳', # CONTAINS AS NORMAL SUBGROUP +'RightTriangleBar': '⧐', # VERTICAL BAR BESIDE RIGHT TRIANGLE +'RightTriangleEqual': '⊵', # CONTAINS AS NORMAL SUBGROUP OR EQUAL TO +'RightUpDownVector': '⥏', # UP BARB RIGHT DOWN BARB RIGHT HARPOON +'RightUpTeeVector': '⥜', # UPWARDS HARPOON WITH BARB RIGHT FROM BAR +'RightUpVector': '↾', # UPWARDS HARPOON WITH BARB RIGHTWARDS +'RightUpVectorBar': '⥔', # UPWARDS HARPOON WITH BARB RIGHT TO BAR +'RightVector': '⇀', # RIGHTWARDS HARPOON WITH BARB UPWARDS +'RightVectorBar': '⥓', # RIGHTWARDS HARPOON WITH BARB UP TO BAR +'Rightarrow': '⇒', # RIGHTWARDS DOUBLE ARROW +'Ropf': 'ℝ', # DOUBLE-STRUCK CAPITAL R +'RoundImplies': '⥰', # RIGHT DOUBLE ARROW WITH ROUNDED HEAD +'Rrightarrow': '⇛', # RIGHTWARDS TRIPLE ARROW +'Rscr': 'ℛ', # SCRIPT CAPITAL R +'Rsh': '↱', # UPWARDS ARROW WITH TIP RIGHTWARDS +'RuleDelayed': '⧴', # RULE-DELAYED +'SHCHcy': 'Щ', # CYRILLIC CAPITAL LETTER SHCHA +'SHcy': 'Ш', # CYRILLIC CAPITAL LETTER SHA +'SOFTcy': 'Ь', # CYRILLIC CAPITAL LETTER SOFT SIGN +'Sacute': 'Ś', # LATIN CAPITAL LETTER S WITH ACUTE +'Sc': '⪼', # DOUBLE SUCCEEDS +'Scaron': 'Š', # LATIN CAPITAL LETTER S WITH CARON +'Scedil': 'Ş', # LATIN CAPITAL LETTER S WITH CEDILLA +'Scirc': 'Ŝ', # LATIN CAPITAL LETTER S WITH CIRCUMFLEX +'Scy': 'С', # CYRILLIC CAPITAL LETTER ES +'Sfr': '𝔖', # MATHEMATICAL FRAKTUR CAPITAL S +'Sgr': 'Σ', # GREEK CAPITAL LETTER SIGMA +'ShortDownArrow': '↓', # DOWNWARDS ARROW +'ShortLeftArrow': '←', # LEFTWARDS ARROW +'ShortRightArrow': '→', # RIGHTWARDS ARROW +'ShortUpArrow': '↑', # UPWARDS ARROW +'Sigma': 'Σ', # GREEK CAPITAL LETTER SIGMA +'SmallCircle': '∘', # RING OPERATOR +'Sopf': '𝕊', # MATHEMATICAL DOUBLE-STRUCK CAPITAL S +'Sqrt': '√', # SQUARE ROOT +'Square': '□', # WHITE SQUARE +'SquareIntersection': '⊓', # SQUARE CAP +'SquareSubset': '⊏', # SQUARE IMAGE OF +'SquareSubsetEqual': '⊑', # SQUARE IMAGE OF OR EQUAL TO +'SquareSuperset': '⊐', # SQUARE ORIGINAL OF +'SquareSupersetEqual': '⊒', # SQUARE ORIGINAL OF OR EQUAL TO +'SquareUnion': '⊔', # SQUARE CUP +'Sscr': '𝒮', # MATHEMATICAL SCRIPT CAPITAL S +'Star': '⋆', # STAR OPERATOR +'Sub': '⋐', # DOUBLE SUBSET +'Subset': '⋐', # DOUBLE SUBSET +'SubsetEqual': '⊆', # SUBSET OF OR EQUAL TO +'Succeeds': '≻', # SUCCEEDS +'SucceedsEqual': '⪰', # SUCCEEDS ABOVE SINGLE-LINE EQUALS SIGN +'SucceedsSlantEqual': '≽', # SUCCEEDS OR EQUAL TO +'SucceedsTilde': '≿', # SUCCEEDS OR EQUIVALENT TO +'SuchThat': '∋', # CONTAINS AS MEMBER +'Sum': '∑', # N-ARY SUMMATION +'Sup': '⋑', # DOUBLE SUPERSET +'Superset': '⊃', # SUPERSET OF +'SupersetEqual': '⊇', # SUPERSET OF OR EQUAL TO +'Supset': '⋑', # DOUBLE SUPERSET +'THORN': 'Þ', # LATIN CAPITAL LETTER THORN +'THgr': 'Θ', # GREEK CAPITAL LETTER THETA +'TRADE': '™', # TRADE MARK SIGN +'TSHcy': 'Ћ', # CYRILLIC CAPITAL LETTER TSHE +'TScy': 'Ц', # CYRILLIC CAPITAL LETTER TSE +'Tab': ' ', # CHARACTER TABULATION +'Tau': 'Τ', # GREEK CAPITAL LETTER TAU +'Tcaron': 'Ť', # LATIN CAPITAL LETTER T WITH CARON +'Tcedil': 'Ţ', # LATIN CAPITAL LETTER T WITH CEDILLA +'Tcy': 'Т', # CYRILLIC CAPITAL LETTER TE +'Tfr': '𝔗', # MATHEMATICAL FRAKTUR CAPITAL T +'Tgr': 'Τ', # GREEK CAPITAL LETTER TAU +'Therefore': '∴', # THEREFORE +'Theta': 'Θ', # GREEK CAPITAL LETTER THETA +'ThickSpace': '  ', # space of width 5/18 em +'ThinSpace': ' ', # THIN SPACE +'Tilde': '∼', # TILDE OPERATOR +'TildeEqual': '≃', # ASYMPTOTICALLY EQUAL TO +'TildeFullEqual': '≅', # APPROXIMATELY EQUAL TO +'TildeTilde': '≈', # ALMOST EQUAL TO +'Topf': '𝕋', # MATHEMATICAL DOUBLE-STRUCK CAPITAL T +'TripleDot': '\u20DB', # COMBINING THREE DOTS ABOVE +'Tscr': '𝒯', # MATHEMATICAL SCRIPT CAPITAL T +'Tstrok': 'Ŧ', # LATIN CAPITAL LETTER T WITH STROKE +'Uacgr': 'Ύ', # GREEK CAPITAL LETTER UPSILON WITH TONOS +'Uacute': 'Ú', # LATIN CAPITAL LETTER U WITH ACUTE +'Uarr': '↟', # UPWARDS TWO HEADED ARROW +'Uarrocir': '⥉', # UPWARDS TWO-HEADED ARROW FROM SMALL CIRCLE +'Ubrcy': 'Ў', # CYRILLIC CAPITAL LETTER SHORT U +'Ubreve': 'Ŭ', # LATIN CAPITAL LETTER U WITH BREVE +'Ucirc': 'Û', # LATIN CAPITAL LETTER U WITH CIRCUMFLEX +'Ucy': 'У', # CYRILLIC CAPITAL LETTER U +'Udblac': 'Ű', # LATIN CAPITAL LETTER U WITH DOUBLE ACUTE +'Udigr': 'Ϋ', # GREEK CAPITAL LETTER UPSILON WITH DIALYTIKA +'Ufr': '𝔘', # MATHEMATICAL FRAKTUR CAPITAL U +'Ugr': 'Υ', # GREEK CAPITAL LETTER UPSILON +'Ugrave': 'Ù', # LATIN CAPITAL LETTER U WITH GRAVE +'Umacr': 'Ū', # LATIN CAPITAL LETTER U WITH MACRON +'UnderBar': '_', # LOW LINE +'UnderBrace': '⏟', # BOTTOM CURLY BRACKET +'UnderBracket': '⎵', # BOTTOM SQUARE BRACKET +'UnderParenthesis': '⏝', # BOTTOM PARENTHESIS +'Union': '⋃', # N-ARY UNION +'UnionPlus': '⊎', # MULTISET UNION +'Uogon': 'Ų', # LATIN CAPITAL LETTER U WITH OGONEK +'Uopf': '𝕌', # MATHEMATICAL DOUBLE-STRUCK CAPITAL U +'UpArrow': '↑', # UPWARDS ARROW +'UpArrowBar': '⤒', # UPWARDS ARROW TO BAR +'UpArrowDownArrow': '⇅', # UPWARDS ARROW LEFTWARDS OF DOWNWARDS ARROW +'UpDownArrow': '↕', # UP DOWN ARROW +'UpEquilibrium': '⥮', # UPWARDS HARPOON WITH BARB LEFT BESIDE DOWNWARDS HARPOON WITH BARB RIGHT +'UpTee': '⊥', # UP TACK +'UpTeeArrow': '↥', # UPWARDS ARROW FROM BAR +'Uparrow': '⇑', # UPWARDS DOUBLE ARROW +'Updownarrow': '⇕', # UP DOWN DOUBLE ARROW +'UpperLeftArrow': '↖', # NORTH WEST ARROW +'UpperRightArrow': '↗', # NORTH EAST ARROW +'Upsi': 'ϒ', # GREEK UPSILON WITH HOOK SYMBOL +'Upsilon': 'Υ', # GREEK CAPITAL LETTER UPSILON +'Uring': 'Ů', # LATIN CAPITAL LETTER U WITH RING ABOVE +'Uscr': '𝒰', # MATHEMATICAL SCRIPT CAPITAL U +'Utilde': 'Ũ', # LATIN CAPITAL LETTER U WITH TILDE +'Uuml': 'Ü', # LATIN CAPITAL LETTER U WITH DIAERESIS +'VDash': '⊫', # DOUBLE VERTICAL BAR DOUBLE RIGHT TURNSTILE +'Vbar': '⫫', # DOUBLE UP TACK +'Vcy': 'В', # CYRILLIC CAPITAL LETTER VE +'Vdash': '⊩', # FORCES +'Vdashl': '⫦', # LONG DASH FROM LEFT MEMBER OF DOUBLE VERTICAL +'Vee': '⋁', # N-ARY LOGICAL OR +'Verbar': '‖', # DOUBLE VERTICAL LINE +'Vert': '‖', # DOUBLE VERTICAL LINE +'VerticalBar': '∣', # DIVIDES +'VerticalLine': '|', # VERTICAL LINE +'VerticalSeparator': '❘', # LIGHT VERTICAL BAR +'VerticalTilde': '≀', # WREATH PRODUCT +'VeryThinSpace': ' ', # HAIR SPACE +'Vfr': '𝔙', # MATHEMATICAL FRAKTUR CAPITAL V +'Vopf': '𝕍', # MATHEMATICAL DOUBLE-STRUCK CAPITAL V +'Vscr': '𝒱', # MATHEMATICAL SCRIPT CAPITAL V +'Vvdash': '⊪', # TRIPLE VERTICAL BAR RIGHT TURNSTILE +'Wcirc': 'Ŵ', # LATIN CAPITAL LETTER W WITH CIRCUMFLEX +'Wedge': '⋀', # N-ARY LOGICAL AND +'Wfr': '𝔚', # MATHEMATICAL FRAKTUR CAPITAL W +'Wopf': '𝕎', # MATHEMATICAL DOUBLE-STRUCK CAPITAL W +'Wscr': '𝒲', # MATHEMATICAL SCRIPT CAPITAL W +'Xfr': '𝔛', # MATHEMATICAL FRAKTUR CAPITAL X +'Xgr': 'Ξ', # GREEK CAPITAL LETTER XI +'Xi': 'Ξ', # GREEK CAPITAL LETTER XI +'Xopf': '𝕏', # MATHEMATICAL DOUBLE-STRUCK CAPITAL X +'Xscr': '𝒳', # MATHEMATICAL SCRIPT CAPITAL X +'YAcy': 'Я', # CYRILLIC CAPITAL LETTER YA +'YIcy': 'Ї', # CYRILLIC CAPITAL LETTER YI +'YUcy': 'Ю', # CYRILLIC CAPITAL LETTER YU +'Yacute': 'Ý', # LATIN CAPITAL LETTER Y WITH ACUTE +'Ycirc': 'Ŷ', # LATIN CAPITAL LETTER Y WITH CIRCUMFLEX +'Ycy': 'Ы', # CYRILLIC CAPITAL LETTER YERU +'Yfr': '𝔜', # MATHEMATICAL FRAKTUR CAPITAL Y +'Yopf': '𝕐', # MATHEMATICAL DOUBLE-STRUCK CAPITAL Y +'Yscr': '𝒴', # MATHEMATICAL SCRIPT CAPITAL Y +'Yuml': 'Ÿ', # LATIN CAPITAL LETTER Y WITH DIAERESIS +'ZHcy': 'Ж', # CYRILLIC CAPITAL LETTER ZHE +'Zacute': 'Ź', # LATIN CAPITAL LETTER Z WITH ACUTE +'Zcaron': 'Ž', # LATIN CAPITAL LETTER Z WITH CARON +'Zcy': 'З', # CYRILLIC CAPITAL LETTER ZE +'Zdot': 'Ż', # LATIN CAPITAL LETTER Z WITH DOT ABOVE +'ZeroWidthSpace': '​', # ZERO WIDTH SPACE +'Zeta': 'Ζ', # GREEK CAPITAL LETTER ZETA +'Zfr': 'ℨ', # BLACK-LETTER CAPITAL Z +'Zgr': 'Ζ', # GREEK CAPITAL LETTER ZETA +'Zopf': 'ℤ', # DOUBLE-STRUCK CAPITAL Z +'Zscr': '𝒵', # MATHEMATICAL SCRIPT CAPITAL Z +'aacgr': 'ά', # GREEK SMALL LETTER ALPHA WITH TONOS +'aacute': 'á', # LATIN SMALL LETTER A WITH ACUTE +'abreve': 'ă', # LATIN SMALL LETTER A WITH BREVE +'ac': '∾', # INVERTED LAZY S +'acE': '∾̳', # INVERTED LAZY S with double underline +'acd': '∿', # SINE WAVE +'acirc': 'â', # LATIN SMALL LETTER A WITH CIRCUMFLEX +'acute': '´', # ACUTE ACCENT +'acy': 'а', # CYRILLIC SMALL LETTER A +'aelig': 'æ', # LATIN SMALL LETTER AE +'af': '⁡', # FUNCTION APPLICATION +'afr': '𝔞', # MATHEMATICAL FRAKTUR SMALL A +'agr': 'α', # GREEK SMALL LETTER ALPHA +'agrave': 'à', # LATIN SMALL LETTER A WITH GRAVE +'alefsym': 'ℵ', # ALEF SYMBOL +'aleph': 'ℵ', # ALEF SYMBOL +'alpha': 'α', # GREEK SMALL LETTER ALPHA +'amacr': 'ā', # LATIN SMALL LETTER A WITH MACRON +'amalg': '⨿', # AMALGAMATION OR COPRODUCT +'amp': '&', # AMPERSAND +'and': '∧', # LOGICAL AND +'andand': '⩕', # TWO INTERSECTING LOGICAL AND +'andd': '⩜', # LOGICAL AND WITH HORIZONTAL DASH +'andslope': '⩘', # SLOPING LARGE AND +'andv': '⩚', # LOGICAL AND WITH MIDDLE STEM +'ang': '∠', # ANGLE +'ange': '⦤', # ANGLE WITH UNDERBAR +'angle': '∠', # ANGLE +'angmsd': '∡', # MEASURED ANGLE +'angmsdaa': '⦨', # MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING UP AND RIGHT +'angmsdab': '⦩', # MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING UP AND LEFT +'angmsdac': '⦪', # MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING DOWN AND RIGHT +'angmsdad': '⦫', # MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING DOWN AND LEFT +'angmsdae': '⦬', # MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING RIGHT AND UP +'angmsdaf': '⦭', # MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING LEFT AND UP +'angmsdag': '⦮', # MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING RIGHT AND DOWN +'angmsdah': '⦯', # MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING LEFT AND DOWN +'angrt': '∟', # RIGHT ANGLE +'angrtvb': '⊾', # RIGHT ANGLE WITH ARC +'angrtvbd': '⦝', # MEASURED RIGHT ANGLE WITH DOT +'angsph': '∢', # SPHERICAL ANGLE +'angst': 'Å', # LATIN CAPITAL LETTER A WITH RING ABOVE +'angzarr': '⍼', # RIGHT ANGLE WITH DOWNWARDS ZIGZAG ARROW +'aogon': 'ą', # LATIN SMALL LETTER A WITH OGONEK +'aopf': '𝕒', # MATHEMATICAL DOUBLE-STRUCK SMALL A +'ap': '≈', # ALMOST EQUAL TO +'apE': '⩰', # APPROXIMATELY EQUAL OR EQUAL TO +'apacir': '⩯', # ALMOST EQUAL TO WITH CIRCUMFLEX ACCENT +'ape': '≊', # ALMOST EQUAL OR EQUAL TO +'apid': '≋', # TRIPLE TILDE +'apos': "'", # APOSTROPHE +'approx': '≈', # ALMOST EQUAL TO +'approxeq': '≊', # ALMOST EQUAL OR EQUAL TO +'aring': 'å', # LATIN SMALL LETTER A WITH RING ABOVE +'ascr': '𝒶', # MATHEMATICAL SCRIPT SMALL A +'ast': '*', # ASTERISK +'asymp': '≈', # ALMOST EQUAL TO +'asympeq': '≍', # EQUIVALENT TO +'atilde': 'ã', # LATIN SMALL LETTER A WITH TILDE +'auml': 'ä', # LATIN SMALL LETTER A WITH DIAERESIS +'awconint': '∳', # ANTICLOCKWISE CONTOUR INTEGRAL +'awint': '⨑', # ANTICLOCKWISE INTEGRATION +'b.Delta': '𝚫', # MATHEMATICAL BOLD CAPITAL DELTA +'b.Gamma': '𝚪', # MATHEMATICAL BOLD CAPITAL GAMMA +'b.Gammad': '𝟊', # MATHEMATICAL BOLD CAPITAL DIGAMMA +'b.Lambda': '𝚲', # MATHEMATICAL BOLD CAPITAL LAMDA +'b.Omega': '𝛀', # MATHEMATICAL BOLD CAPITAL OMEGA +'b.Phi': '𝚽', # MATHEMATICAL BOLD CAPITAL PHI +'b.Pi': '𝚷', # MATHEMATICAL BOLD CAPITAL PI +'b.Psi': '𝚿', # MATHEMATICAL BOLD CAPITAL PSI +'b.Sigma': '𝚺', # MATHEMATICAL BOLD CAPITAL SIGMA +'b.Theta': '𝚯', # MATHEMATICAL BOLD CAPITAL THETA +'b.Upsi': '𝚼', # MATHEMATICAL BOLD CAPITAL UPSILON +'b.Xi': '𝚵', # MATHEMATICAL BOLD CAPITAL XI +'b.alpha': '𝛂', # MATHEMATICAL BOLD SMALL ALPHA +'b.beta': '𝛃', # MATHEMATICAL BOLD SMALL BETA +'b.chi': '𝛘', # MATHEMATICAL BOLD SMALL CHI +'b.delta': '𝛅', # MATHEMATICAL BOLD SMALL DELTA +'b.epsi': '𝛆', # MATHEMATICAL BOLD SMALL EPSILON +'b.epsiv': '𝛜', # MATHEMATICAL BOLD EPSILON SYMBOL +'b.eta': '𝛈', # MATHEMATICAL BOLD SMALL ETA +'b.gamma': '𝛄', # MATHEMATICAL BOLD SMALL GAMMA +'b.gammad': '𝟋', # MATHEMATICAL BOLD SMALL DIGAMMA +'b.iota': '𝛊', # MATHEMATICAL BOLD SMALL IOTA +'b.kappa': '𝛋', # MATHEMATICAL BOLD SMALL KAPPA +'b.kappav': '𝛞', # MATHEMATICAL BOLD KAPPA SYMBOL +'b.lambda': '𝛌', # MATHEMATICAL BOLD SMALL LAMDA +'b.mu': '𝛍', # MATHEMATICAL BOLD SMALL MU +'b.nu': '𝛎', # MATHEMATICAL BOLD SMALL NU +'b.omega': '𝛚', # MATHEMATICAL BOLD SMALL OMEGA +'b.phi': '𝛗', # MATHEMATICAL BOLD SMALL PHI +'b.phiv': '𝛟', # MATHEMATICAL BOLD PHI SYMBOL +'b.pi': '𝛑', # MATHEMATICAL BOLD SMALL PI +'b.piv': '𝛡', # MATHEMATICAL BOLD PI SYMBOL +'b.psi': '𝛙', # MATHEMATICAL BOLD SMALL PSI +'b.rho': '𝛒', # MATHEMATICAL BOLD SMALL RHO +'b.rhov': '𝛠', # MATHEMATICAL BOLD RHO SYMBOL +'b.sigma': '𝛔', # MATHEMATICAL BOLD SMALL SIGMA +'b.sigmav': '𝛓', # MATHEMATICAL BOLD SMALL FINAL SIGMA +'b.tau': '𝛕', # MATHEMATICAL BOLD SMALL TAU +'b.thetas': '𝛉', # MATHEMATICAL BOLD SMALL THETA +'b.thetav': '𝛝', # MATHEMATICAL BOLD THETA SYMBOL +'b.upsi': '𝛖', # MATHEMATICAL BOLD SMALL UPSILON +'b.xi': '𝛏', # MATHEMATICAL BOLD SMALL XI +'b.zeta': '𝛇', # MATHEMATICAL BOLD SMALL ZETA +'bNot': '⫭', # REVERSED DOUBLE STROKE NOT SIGN +'backcong': '≌', # ALL EQUAL TO +'backepsilon': '϶', # GREEK REVERSED LUNATE EPSILON SYMBOL +'backprime': '‵', # REVERSED PRIME +'backsim': '∽', # REVERSED TILDE +'backsimeq': '⋍', # REVERSED TILDE EQUALS +'barvee': '⊽', # NOR +'barwed': '⌅', # PROJECTIVE +'barwedge': '⌅', # PROJECTIVE +'bbrk': '⎵', # BOTTOM SQUARE BRACKET +'bbrktbrk': '⎶', # BOTTOM SQUARE BRACKET OVER TOP SQUARE BRACKET +'bcong': '≌', # ALL EQUAL TO +'bcy': 'б', # CYRILLIC SMALL LETTER BE +'bdquo': '„', # DOUBLE LOW-9 QUOTATION MARK +'becaus': '∵', # BECAUSE +'because': '∵', # BECAUSE +'bemptyv': '⦰', # REVERSED EMPTY SET +'bepsi': '϶', # GREEK REVERSED LUNATE EPSILON SYMBOL +'bernou': 'ℬ', # SCRIPT CAPITAL B +'beta': 'β', # GREEK SMALL LETTER BETA +'beth': 'ℶ', # BET SYMBOL +'between': '≬', # BETWEEN +'bfr': '𝔟', # MATHEMATICAL FRAKTUR SMALL B +'bgr': 'β', # GREEK SMALL LETTER BETA +'bigcap': '⋂', # N-ARY INTERSECTION +'bigcirc': '◯', # LARGE CIRCLE +'bigcup': '⋃', # N-ARY UNION +'bigodot': '⨀', # N-ARY CIRCLED DOT OPERATOR +'bigoplus': '⨁', # N-ARY CIRCLED PLUS OPERATOR +'bigotimes': '⨂', # N-ARY CIRCLED TIMES OPERATOR +'bigsqcup': '⨆', # N-ARY SQUARE UNION OPERATOR +'bigstar': '★', # BLACK STAR +'bigtriangledown': '▽', # WHITE DOWN-POINTING TRIANGLE +'bigtriangleup': '△', # WHITE UP-POINTING TRIANGLE +'biguplus': '⨄', # N-ARY UNION OPERATOR WITH PLUS +'bigvee': '⋁', # N-ARY LOGICAL OR +'bigwedge': '⋀', # N-ARY LOGICAL AND +'bkarow': '⤍', # RIGHTWARDS DOUBLE DASH ARROW +'blacklozenge': '⧫', # BLACK LOZENGE +'blacksquare': '▪', # BLACK SMALL SQUARE +'blacktriangle': '▴', # BLACK UP-POINTING SMALL TRIANGLE +'blacktriangledown': '▾', # BLACK DOWN-POINTING SMALL TRIANGLE +'blacktriangleleft': '◂', # BLACK LEFT-POINTING SMALL TRIANGLE +'blacktriangleright': '▸', # BLACK RIGHT-POINTING SMALL TRIANGLE +'blank': '␣', # OPEN BOX +'blk12': '▒', # MEDIUM SHADE +'blk14': '░', # LIGHT SHADE +'blk34': '▓', # DARK SHADE +'block': '█', # FULL BLOCK +'bne': '=⃥', # EQUALS SIGN with reverse slash +'bnequiv': '≡⃥', # IDENTICAL TO with reverse slash +'bnot': '⌐', # REVERSED NOT SIGN +'bopf': '𝕓', # MATHEMATICAL DOUBLE-STRUCK SMALL B +'bot': '⊥', # UP TACK +'bottom': '⊥', # UP TACK +'bowtie': '⋈', # BOWTIE +'boxDL': '╗', # BOX DRAWINGS DOUBLE DOWN AND LEFT +'boxDR': '╔', # BOX DRAWINGS DOUBLE DOWN AND RIGHT +'boxDl': '╖', # BOX DRAWINGS DOWN DOUBLE AND LEFT SINGLE +'boxDr': '╓', # BOX DRAWINGS DOWN DOUBLE AND RIGHT SINGLE +'boxH': '═', # BOX DRAWINGS DOUBLE HORIZONTAL +'boxHD': '╦', # BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL +'boxHU': '╩', # BOX DRAWINGS DOUBLE UP AND HORIZONTAL +'boxHd': '╤', # BOX DRAWINGS DOWN SINGLE AND HORIZONTAL DOUBLE +'boxHu': '╧', # BOX DRAWINGS UP SINGLE AND HORIZONTAL DOUBLE +'boxUL': '╝', # BOX DRAWINGS DOUBLE UP AND LEFT +'boxUR': '╚', # BOX DRAWINGS DOUBLE UP AND RIGHT +'boxUl': '╜', # BOX DRAWINGS UP DOUBLE AND LEFT SINGLE +'boxUr': '╙', # BOX DRAWINGS UP DOUBLE AND RIGHT SINGLE +'boxV': '║', # BOX DRAWINGS DOUBLE VERTICAL +'boxVH': '╬', # BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL +'boxVL': '╣', # BOX DRAWINGS DOUBLE VERTICAL AND LEFT +'boxVR': '╠', # BOX DRAWINGS DOUBLE VERTICAL AND RIGHT +'boxVh': '╫', # BOX DRAWINGS VERTICAL DOUBLE AND HORIZONTAL SINGLE +'boxVl': '╢', # BOX DRAWINGS VERTICAL DOUBLE AND LEFT SINGLE +'boxVr': '╟', # BOX DRAWINGS VERTICAL DOUBLE AND RIGHT SINGLE +'boxbox': '⧉', # TWO JOINED SQUARES +'boxdL': '╕', # BOX DRAWINGS DOWN SINGLE AND LEFT DOUBLE +'boxdR': '╒', # BOX DRAWINGS DOWN SINGLE AND RIGHT DOUBLE +'boxdl': '┐', # BOX DRAWINGS LIGHT DOWN AND LEFT +'boxdr': '┌', # BOX DRAWINGS LIGHT DOWN AND RIGHT +'boxh': '─', # BOX DRAWINGS LIGHT HORIZONTAL +'boxhD': '╥', # BOX DRAWINGS DOWN DOUBLE AND HORIZONTAL SINGLE +'boxhU': '╨', # BOX DRAWINGS UP DOUBLE AND HORIZONTAL SINGLE +'boxhd': '┬', # BOX DRAWINGS LIGHT DOWN AND HORIZONTAL +'boxhu': '┴', # BOX DRAWINGS LIGHT UP AND HORIZONTAL +'boxminus': '⊟', # SQUARED MINUS +'boxplus': '⊞', # SQUARED PLUS +'boxtimes': '⊠', # SQUARED TIMES +'boxuL': '╛', # BOX DRAWINGS UP SINGLE AND LEFT DOUBLE +'boxuR': '╘', # BOX DRAWINGS UP SINGLE AND RIGHT DOUBLE +'boxul': '┘', # BOX DRAWINGS LIGHT UP AND LEFT +'boxur': '└', # BOX DRAWINGS LIGHT UP AND RIGHT +'boxv': '│', # BOX DRAWINGS LIGHT VERTICAL +'boxvH': '╪', # BOX DRAWINGS VERTICAL SINGLE AND HORIZONTAL DOUBLE +'boxvL': '╡', # BOX DRAWINGS VERTICAL SINGLE AND LEFT DOUBLE +'boxvR': '╞', # BOX DRAWINGS VERTICAL SINGLE AND RIGHT DOUBLE +'boxvh': '┼', # BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL +'boxvl': '┤', # BOX DRAWINGS LIGHT VERTICAL AND LEFT +'boxvr': '├', # BOX DRAWINGS LIGHT VERTICAL AND RIGHT +'bprime': '‵', # REVERSED PRIME +'breve': '˘', # BREVE +'brvbar': '¦', # BROKEN BAR +'bscr': '𝒷', # MATHEMATICAL SCRIPT SMALL B +'bsemi': '⁏', # REVERSED SEMICOLON +'bsim': '∽', # REVERSED TILDE +'bsime': '⋍', # REVERSED TILDE EQUALS +'bsol': '\\', # REVERSE SOLIDUS +'bsolb': '⧅', # SQUARED FALLING DIAGONAL SLASH +'bsolhsub': '⟈', # REVERSE SOLIDUS PRECEDING SUBSET +'bull': '•', # BULLET +'bullet': '•', # BULLET +'bump': '≎', # GEOMETRICALLY EQUIVALENT TO +'bumpE': '⪮', # EQUALS SIGN WITH BUMPY ABOVE +'bumpe': '≏', # DIFFERENCE BETWEEN +'bumpeq': '≏', # DIFFERENCE BETWEEN +'cacute': 'ć', # LATIN SMALL LETTER C WITH ACUTE +'cap': '∩', # INTERSECTION +'capand': '⩄', # INTERSECTION WITH LOGICAL AND +'capbrcup': '⩉', # INTERSECTION ABOVE BAR ABOVE UNION +'capcap': '⩋', # INTERSECTION BESIDE AND JOINED WITH INTERSECTION +'capcup': '⩇', # INTERSECTION ABOVE UNION +'capdot': '⩀', # INTERSECTION WITH DOT +'caps': '∩︀', # INTERSECTION with serifs +'caret': '⁁', # CARET INSERTION POINT +'caron': 'ˇ', # CARON +'ccaps': '⩍', # CLOSED INTERSECTION WITH SERIFS +'ccaron': 'č', # LATIN SMALL LETTER C WITH CARON +'ccedil': 'ç', # LATIN SMALL LETTER C WITH CEDILLA +'ccirc': 'ĉ', # LATIN SMALL LETTER C WITH CIRCUMFLEX +'ccups': '⩌', # CLOSED UNION WITH SERIFS +'ccupssm': '⩐', # CLOSED UNION WITH SERIFS AND SMASH PRODUCT +'cdot': 'ċ', # LATIN SMALL LETTER C WITH DOT ABOVE +'cedil': '¸', # CEDILLA +'cemptyv': '⦲', # EMPTY SET WITH SMALL CIRCLE ABOVE +'cent': '¢', # CENT SIGN +'centerdot': '·', # MIDDLE DOT +'cfr': '𝔠', # MATHEMATICAL FRAKTUR SMALL C +'chcy': 'ч', # CYRILLIC SMALL LETTER CHE +'check': '✓', # CHECK MARK +'checkmark': '✓', # CHECK MARK +'chi': 'χ', # GREEK SMALL LETTER CHI +'cir': '○', # WHITE CIRCLE +'cirE': '⧃', # CIRCLE WITH TWO HORIZONTAL STROKES TO THE RIGHT +'circ': 'ˆ', # MODIFIER LETTER CIRCUMFLEX ACCENT +'circeq': '≗', # RING EQUAL TO +'circlearrowleft': '↺', # ANTICLOCKWISE OPEN CIRCLE ARROW +'circlearrowright': '↻', # CLOCKWISE OPEN CIRCLE ARROW +'circledR': '®', # REGISTERED SIGN +'circledS': 'Ⓢ', # CIRCLED LATIN CAPITAL LETTER S +'circledast': '⊛', # CIRCLED ASTERISK OPERATOR +'circledcirc': '⊚', # CIRCLED RING OPERATOR +'circleddash': '⊝', # CIRCLED DASH +'cire': '≗', # RING EQUAL TO +'cirfnint': '⨐', # CIRCULATION FUNCTION +'cirmid': '⫯', # VERTICAL LINE WITH CIRCLE ABOVE +'cirscir': '⧂', # CIRCLE WITH SMALL CIRCLE TO THE RIGHT +'clubs': '♣', # BLACK CLUB SUIT +'clubsuit': '♣', # BLACK CLUB SUIT +'colon': ':', # COLON +'colone': '≔', # COLON EQUALS +'coloneq': '≔', # COLON EQUALS +'comma': ',', # COMMA +'commat': '@', # COMMERCIAL AT +'comp': '∁', # COMPLEMENT +'compfn': '∘', # RING OPERATOR +'complement': '∁', # COMPLEMENT +'complexes': 'ℂ', # DOUBLE-STRUCK CAPITAL C +'cong': '≅', # APPROXIMATELY EQUAL TO +'congdot': '⩭', # CONGRUENT WITH DOT ABOVE +'conint': '∮', # CONTOUR INTEGRAL +'copf': '𝕔', # MATHEMATICAL DOUBLE-STRUCK SMALL C +'coprod': '∐', # N-ARY COPRODUCT +'copy': '©', # COPYRIGHT SIGN +'copysr': '℗', # SOUND RECORDING COPYRIGHT +'crarr': '↵', # DOWNWARDS ARROW WITH CORNER LEFTWARDS +'cross': '✗', # BALLOT X +'cscr': '𝒸', # MATHEMATICAL SCRIPT SMALL C +'csub': '⫏', # CLOSED SUBSET +'csube': '⫑', # CLOSED SUBSET OR EQUAL TO +'csup': '⫐', # CLOSED SUPERSET +'csupe': '⫒', # CLOSED SUPERSET OR EQUAL TO +'ctdot': '⋯', # MIDLINE HORIZONTAL ELLIPSIS +'cudarrl': '⤸', # RIGHT-SIDE ARC CLOCKWISE ARROW +'cudarrr': '⤵', # ARROW POINTING RIGHTWARDS THEN CURVING DOWNWARDS +'cuepr': '⋞', # EQUAL TO OR PRECEDES +'cuesc': '⋟', # EQUAL TO OR SUCCEEDS +'cularr': '↶', # ANTICLOCKWISE TOP SEMICIRCLE ARROW +'cularrp': '⤽', # TOP ARC ANTICLOCKWISE ARROW WITH PLUS +'cup': '∪', # UNION +'cupbrcap': '⩈', # UNION ABOVE BAR ABOVE INTERSECTION +'cupcap': '⩆', # UNION ABOVE INTERSECTION +'cupcup': '⩊', # UNION BESIDE AND JOINED WITH UNION +'cupdot': '⊍', # MULTISET MULTIPLICATION +'cupor': '⩅', # UNION WITH LOGICAL OR +'cups': '∪︀', # UNION with serifs +'curarr': '↷', # CLOCKWISE TOP SEMICIRCLE ARROW +'curarrm': '⤼', # TOP ARC CLOCKWISE ARROW WITH MINUS +'curlyeqprec': '⋞', # EQUAL TO OR PRECEDES +'curlyeqsucc': '⋟', # EQUAL TO OR SUCCEEDS +'curlyvee': '⋎', # CURLY LOGICAL OR +'curlywedge': '⋏', # CURLY LOGICAL AND +'curren': '¤', # CURRENCY SIGN +'curvearrowleft': '↶', # ANTICLOCKWISE TOP SEMICIRCLE ARROW +'curvearrowright': '↷', # CLOCKWISE TOP SEMICIRCLE ARROW +'cuvee': '⋎', # CURLY LOGICAL OR +'cuwed': '⋏', # CURLY LOGICAL AND +'cwconint': '∲', # CLOCKWISE CONTOUR INTEGRAL +'cwint': '∱', # CLOCKWISE INTEGRAL +'cylcty': '⌭', # CYLINDRICITY +'dArr': '⇓', # DOWNWARDS DOUBLE ARROW +'dHar': '⥥', # DOWNWARDS HARPOON WITH BARB LEFT BESIDE DOWNWARDS HARPOON WITH BARB RIGHT +'dagger': '†', # DAGGER +'daleth': 'ℸ', # DALET SYMBOL +'darr': '↓', # DOWNWARDS ARROW +'dash': '‐', # HYPHEN +'dashv': '⊣', # LEFT TACK +'dbkarow': '⤏', # RIGHTWARDS TRIPLE DASH ARROW +'dblac': '˝', # DOUBLE ACUTE ACCENT +'dcaron': 'ď', # LATIN SMALL LETTER D WITH CARON +'dcy': 'д', # CYRILLIC SMALL LETTER DE +'dd': 'ⅆ', # DOUBLE-STRUCK ITALIC SMALL D +'ddagger': '‡', # DOUBLE DAGGER +'ddarr': '⇊', # DOWNWARDS PAIRED ARROWS +'ddotseq': '⩷', # EQUALS SIGN WITH TWO DOTS ABOVE AND TWO DOTS BELOW +'deg': '°', # DEGREE SIGN +'delta': 'δ', # GREEK SMALL LETTER DELTA +'demptyv': '⦱', # EMPTY SET WITH OVERBAR +'dfisht': '⥿', # DOWN FISH TAIL +'dfr': '𝔡', # MATHEMATICAL FRAKTUR SMALL D +'dgr': 'δ', # GREEK SMALL LETTER DELTA +'dharl': '⇃', # DOWNWARDS HARPOON WITH BARB LEFTWARDS +'dharr': '⇂', # DOWNWARDS HARPOON WITH BARB RIGHTWARDS +'diam': '⋄', # DIAMOND OPERATOR +'diamond': '⋄', # DIAMOND OPERATOR +'diamondsuit': '♦', # BLACK DIAMOND SUIT +'diams': '♦', # BLACK DIAMOND SUIT +'die': '¨', # DIAERESIS +'digamma': 'ϝ', # GREEK SMALL LETTER DIGAMMA +'disin': '⋲', # ELEMENT OF WITH LONG HORIZONTAL STROKE +'div': '÷', # DIVISION SIGN +'divide': '÷', # DIVISION SIGN +'divideontimes': '⋇', # DIVISION TIMES +'divonx': '⋇', # DIVISION TIMES +'djcy': 'ђ', # CYRILLIC SMALL LETTER DJE +'dlcorn': '⌞', # BOTTOM LEFT CORNER +'dlcrop': '⌍', # BOTTOM LEFT CROP +'dollar': '$', # DOLLAR SIGN +'dopf': '𝕕', # MATHEMATICAL DOUBLE-STRUCK SMALL D +'dot': '˙', # DOT ABOVE +'doteq': '≐', # APPROACHES THE LIMIT +'doteqdot': '≑', # GEOMETRICALLY EQUAL TO +'dotminus': '∸', # DOT MINUS +'dotplus': '∔', # DOT PLUS +'dotsquare': '⊡', # SQUARED DOT OPERATOR +'doublebarwedge': '⌆', # PERSPECTIVE +'downarrow': '↓', # DOWNWARDS ARROW +'downdownarrows': '⇊', # DOWNWARDS PAIRED ARROWS +'downharpoonleft': '⇃', # DOWNWARDS HARPOON WITH BARB LEFTWARDS +'downharpoonright': '⇂', # DOWNWARDS HARPOON WITH BARB RIGHTWARDS +'drbkarow': '⤐', # RIGHTWARDS TWO-HEADED TRIPLE DASH ARROW +'drcorn': '⌟', # BOTTOM RIGHT CORNER +'drcrop': '⌌', # BOTTOM RIGHT CROP +'dscr': '𝒹', # MATHEMATICAL SCRIPT SMALL D +'dscy': 'ѕ', # CYRILLIC SMALL LETTER DZE +'dsol': '⧶', # SOLIDUS WITH OVERBAR +'dstrok': 'đ', # LATIN SMALL LETTER D WITH STROKE +'dtdot': '⋱', # DOWN RIGHT DIAGONAL ELLIPSIS +'dtri': '▿', # WHITE DOWN-POINTING SMALL TRIANGLE +'dtrif': '▾', # BLACK DOWN-POINTING SMALL TRIANGLE +'duarr': '⇵', # DOWNWARDS ARROW LEFTWARDS OF UPWARDS ARROW +'duhar': '⥯', # DOWNWARDS HARPOON WITH BARB LEFT BESIDE UPWARDS HARPOON WITH BARB RIGHT +'dwangle': '⦦', # OBLIQUE ANGLE OPENING UP +'dzcy': 'џ', # CYRILLIC SMALL LETTER DZHE +'dzigrarr': '⟿', # LONG RIGHTWARDS SQUIGGLE ARROW +'eDDot': '⩷', # EQUALS SIGN WITH TWO DOTS ABOVE AND TWO DOTS BELOW +'eDot': '≑', # GEOMETRICALLY EQUAL TO +'eacgr': 'έ', # GREEK SMALL LETTER EPSILON WITH TONOS +'eacute': 'é', # LATIN SMALL LETTER E WITH ACUTE +'easter': '⩮', # EQUALS WITH ASTERISK +'ecaron': 'ě', # LATIN SMALL LETTER E WITH CARON +'ecir': '≖', # RING IN EQUAL TO +'ecirc': 'ê', # LATIN SMALL LETTER E WITH CIRCUMFLEX +'ecolon': '≕', # EQUALS COLON +'ecy': 'э', # CYRILLIC SMALL LETTER E +'edot': 'ė', # LATIN SMALL LETTER E WITH DOT ABOVE +'ee': 'ⅇ', # DOUBLE-STRUCK ITALIC SMALL E +'eeacgr': 'ή', # GREEK SMALL LETTER ETA WITH TONOS +'eegr': 'η', # GREEK SMALL LETTER ETA +'efDot': '≒', # APPROXIMATELY EQUAL TO OR THE IMAGE OF +'efr': '𝔢', # MATHEMATICAL FRAKTUR SMALL E +'eg': '⪚', # DOUBLE-LINE EQUAL TO OR GREATER-THAN +'egr': 'ε', # GREEK SMALL LETTER EPSILON +'egrave': 'è', # LATIN SMALL LETTER E WITH GRAVE +'egs': '⪖', # SLANTED EQUAL TO OR GREATER-THAN +'egsdot': '⪘', # SLANTED EQUAL TO OR GREATER-THAN WITH DOT INSIDE +'el': '⪙', # DOUBLE-LINE EQUAL TO OR LESS-THAN +'elinters': '⏧', # ELECTRICAL INTERSECTION +'ell': 'ℓ', # SCRIPT SMALL L +'els': '⪕', # SLANTED EQUAL TO OR LESS-THAN +'elsdot': '⪗', # SLANTED EQUAL TO OR LESS-THAN WITH DOT INSIDE +'emacr': 'ē', # LATIN SMALL LETTER E WITH MACRON +'empty': '∅', # EMPTY SET +'emptyset': '∅', # EMPTY SET +'emptyv': '∅', # EMPTY SET +'emsp': ' ', # EM SPACE +'emsp13': ' ', # THREE-PER-EM SPACE +'emsp14': ' ', # FOUR-PER-EM SPACE +'eng': 'ŋ', # LATIN SMALL LETTER ENG +'ensp': ' ', # EN SPACE +'eogon': 'ę', # LATIN SMALL LETTER E WITH OGONEK +'eopf': '𝕖', # MATHEMATICAL DOUBLE-STRUCK SMALL E +'epar': '⋕', # EQUAL AND PARALLEL TO +'eparsl': '⧣', # EQUALS SIGN AND SLANTED PARALLEL +'eplus': '⩱', # EQUALS SIGN ABOVE PLUS SIGN +'epsi': 'ε', # GREEK SMALL LETTER EPSILON +'epsilon': 'ε', # GREEK SMALL LETTER EPSILON +'epsiv': 'ϵ', # GREEK LUNATE EPSILON SYMBOL +'eqcirc': '≖', # RING IN EQUAL TO +'eqcolon': '≕', # EQUALS COLON +'eqsim': '≂', # MINUS TILDE +'eqslantgtr': '⪖', # SLANTED EQUAL TO OR GREATER-THAN +'eqslantless': '⪕', # SLANTED EQUAL TO OR LESS-THAN +'equals': '=', # EQUALS SIGN +'equest': '≟', # QUESTIONED EQUAL TO +'equiv': '≡', # IDENTICAL TO +'equivDD': '⩸', # EQUIVALENT WITH FOUR DOTS ABOVE +'eqvparsl': '⧥', # IDENTICAL TO AND SLANTED PARALLEL +'erDot': '≓', # IMAGE OF OR APPROXIMATELY EQUAL TO +'erarr': '⥱', # EQUALS SIGN ABOVE RIGHTWARDS ARROW +'escr': 'ℯ', # SCRIPT SMALL E +'esdot': '≐', # APPROACHES THE LIMIT +'esim': '≂', # MINUS TILDE +'eta': 'η', # GREEK SMALL LETTER ETA +'eth': 'ð', # LATIN SMALL LETTER ETH +'euml': 'ë', # LATIN SMALL LETTER E WITH DIAERESIS +'euro': '€', # EURO SIGN +'excl': '!', # EXCLAMATION MARK +'exist': '∃', # THERE EXISTS +'expectation': 'ℰ', # SCRIPT CAPITAL E +'exponentiale': 'ⅇ', # DOUBLE-STRUCK ITALIC SMALL E +'fallingdotseq': '≒', # APPROXIMATELY EQUAL TO OR THE IMAGE OF +'fcy': 'ф', # CYRILLIC SMALL LETTER EF +'female': '♀', # FEMALE SIGN +'ffilig': 'ffi', # LATIN SMALL LIGATURE FFI +'fflig': 'ff', # LATIN SMALL LIGATURE FF +'ffllig': 'ffl', # LATIN SMALL LIGATURE FFL +'ffr': '𝔣', # MATHEMATICAL FRAKTUR SMALL F +'filig': 'fi', # LATIN SMALL LIGATURE FI +'fjlig': 'fj', # fj ligature +'flat': '♭', # MUSIC FLAT SIGN +'fllig': 'fl', # LATIN SMALL LIGATURE FL +'fltns': '▱', # WHITE PARALLELOGRAM +'fnof': 'ƒ', # LATIN SMALL LETTER F WITH HOOK +'fopf': '𝕗', # MATHEMATICAL DOUBLE-STRUCK SMALL F +'forall': '∀', # FOR ALL +'fork': '⋔', # PITCHFORK +'forkv': '⫙', # ELEMENT OF OPENING DOWNWARDS +'fpartint': '⨍', # FINITE PART INTEGRAL +'frac12': '½', # VULGAR FRACTION ONE HALF +'frac13': '⅓', # VULGAR FRACTION ONE THIRD +'frac14': '¼', # VULGAR FRACTION ONE QUARTER +'frac15': '⅕', # VULGAR FRACTION ONE FIFTH +'frac16': '⅙', # VULGAR FRACTION ONE SIXTH +'frac18': '⅛', # VULGAR FRACTION ONE EIGHTH +'frac23': '⅔', # VULGAR FRACTION TWO THIRDS +'frac25': '⅖', # VULGAR FRACTION TWO FIFTHS +'frac34': '¾', # VULGAR FRACTION THREE QUARTERS +'frac35': '⅗', # VULGAR FRACTION THREE FIFTHS +'frac38': '⅜', # VULGAR FRACTION THREE EIGHTHS +'frac45': '⅘', # VULGAR FRACTION FOUR FIFTHS +'frac56': '⅚', # VULGAR FRACTION FIVE SIXTHS +'frac58': '⅝', # VULGAR FRACTION FIVE EIGHTHS +'frac78': '⅞', # VULGAR FRACTION SEVEN EIGHTHS +'frasl': '⁄', # FRACTION SLASH +'frown': '⌢', # FROWN +'fscr': '𝒻', # MATHEMATICAL SCRIPT SMALL F +'gE': '≧', # GREATER-THAN OVER EQUAL TO +'gEl': '⪌', # GREATER-THAN ABOVE DOUBLE-LINE EQUAL ABOVE LESS-THAN +'gacute': 'ǵ', # LATIN SMALL LETTER G WITH ACUTE +'gamma': 'γ', # GREEK SMALL LETTER GAMMA +'gammad': 'ϝ', # GREEK SMALL LETTER DIGAMMA +'gap': '⪆', # GREATER-THAN OR APPROXIMATE +'gbreve': 'ğ', # LATIN SMALL LETTER G WITH BREVE +'gcirc': 'ĝ', # LATIN SMALL LETTER G WITH CIRCUMFLEX +'gcy': 'г', # CYRILLIC SMALL LETTER GHE +'gdot': 'ġ', # LATIN SMALL LETTER G WITH DOT ABOVE +'ge': '≥', # GREATER-THAN OR EQUAL TO +'gel': '⋛', # GREATER-THAN EQUAL TO OR LESS-THAN +'geq': '≥', # GREATER-THAN OR EQUAL TO +'geqq': '≧', # GREATER-THAN OVER EQUAL TO +'geqslant': '⩾', # GREATER-THAN OR SLANTED EQUAL TO +'ges': '⩾', # GREATER-THAN OR SLANTED EQUAL TO +'gescc': '⪩', # GREATER-THAN CLOSED BY CURVE ABOVE SLANTED EQUAL +'gesdot': '⪀', # GREATER-THAN OR SLANTED EQUAL TO WITH DOT INSIDE +'gesdoto': '⪂', # GREATER-THAN OR SLANTED EQUAL TO WITH DOT ABOVE +'gesdotol': '⪄', # GREATER-THAN OR SLANTED EQUAL TO WITH DOT ABOVE LEFT +'gesl': '⋛︀', # GREATER-THAN slanted EQUAL TO OR LESS-THAN +'gesles': '⪔', # GREATER-THAN ABOVE SLANTED EQUAL ABOVE LESS-THAN ABOVE SLANTED EQUAL +'gfr': '𝔤', # MATHEMATICAL FRAKTUR SMALL G +'gg': '≫', # MUCH GREATER-THAN +'ggg': '⋙', # VERY MUCH GREATER-THAN +'ggr': 'γ', # GREEK SMALL LETTER GAMMA +'gimel': 'ℷ', # GIMEL SYMBOL +'gjcy': 'ѓ', # CYRILLIC SMALL LETTER GJE +'gl': '≷', # GREATER-THAN OR LESS-THAN +'glE': '⪒', # GREATER-THAN ABOVE LESS-THAN ABOVE DOUBLE-LINE EQUAL +'gla': '⪥', # GREATER-THAN BESIDE LESS-THAN +'glj': '⪤', # GREATER-THAN OVERLAPPING LESS-THAN +'gnE': '≩', # GREATER-THAN BUT NOT EQUAL TO +'gnap': '⪊', # GREATER-THAN AND NOT APPROXIMATE +'gnapprox': '⪊', # GREATER-THAN AND NOT APPROXIMATE +'gne': '⪈', # GREATER-THAN AND SINGLE-LINE NOT EQUAL TO +'gneq': '⪈', # GREATER-THAN AND SINGLE-LINE NOT EQUAL TO +'gneqq': '≩', # GREATER-THAN BUT NOT EQUAL TO +'gnsim': '⋧', # GREATER-THAN BUT NOT EQUIVALENT TO +'gopf': '𝕘', # MATHEMATICAL DOUBLE-STRUCK SMALL G +'grave': '`', # GRAVE ACCENT +'gscr': 'ℊ', # SCRIPT SMALL G +'gsim': '≳', # GREATER-THAN OR EQUIVALENT TO +'gsime': '⪎', # GREATER-THAN ABOVE SIMILAR OR EQUAL +'gsiml': '⪐', # GREATER-THAN ABOVE SIMILAR ABOVE LESS-THAN +'gt': '>', # GREATER-THAN SIGN +'gtcc': '⪧', # GREATER-THAN CLOSED BY CURVE +'gtcir': '⩺', # GREATER-THAN WITH CIRCLE INSIDE +'gtdot': '⋗', # GREATER-THAN WITH DOT +'gtlPar': '⦕', # DOUBLE LEFT ARC GREATER-THAN BRACKET +'gtquest': '⩼', # GREATER-THAN WITH QUESTION MARK ABOVE +'gtrapprox': '⪆', # GREATER-THAN OR APPROXIMATE +'gtrarr': '⥸', # GREATER-THAN ABOVE RIGHTWARDS ARROW +'gtrdot': '⋗', # GREATER-THAN WITH DOT +'gtreqless': '⋛', # GREATER-THAN EQUAL TO OR LESS-THAN +'gtreqqless': '⪌', # GREATER-THAN ABOVE DOUBLE-LINE EQUAL ABOVE LESS-THAN +'gtrless': '≷', # GREATER-THAN OR LESS-THAN +'gtrsim': '≳', # GREATER-THAN OR EQUIVALENT TO +'gvertneqq': '≩︀', # GREATER-THAN BUT NOT EQUAL TO - with vertical stroke +'gvnE': '≩︀', # GREATER-THAN BUT NOT EQUAL TO - with vertical stroke +'hArr': '⇔', # LEFT RIGHT DOUBLE ARROW +'hairsp': ' ', # HAIR SPACE +'half': '½', # VULGAR FRACTION ONE HALF +'hamilt': 'ℋ', # SCRIPT CAPITAL H +'hardcy': 'ъ', # CYRILLIC SMALL LETTER HARD SIGN +'harr': '↔', # LEFT RIGHT ARROW +'harrcir': '⥈', # LEFT RIGHT ARROW THROUGH SMALL CIRCLE +'harrw': '↭', # LEFT RIGHT WAVE ARROW +'hbar': 'ℏ', # PLANCK CONSTANT OVER TWO PI +'hcirc': 'ĥ', # LATIN SMALL LETTER H WITH CIRCUMFLEX +'hearts': '♥', # BLACK HEART SUIT +'heartsuit': '♥', # BLACK HEART SUIT +'hellip': '…', # HORIZONTAL ELLIPSIS +'hercon': '⊹', # HERMITIAN CONJUGATE MATRIX +'hfr': '𝔥', # MATHEMATICAL FRAKTUR SMALL H +'hksearow': '⤥', # SOUTH EAST ARROW WITH HOOK +'hkswarow': '⤦', # SOUTH WEST ARROW WITH HOOK +'hoarr': '⇿', # LEFT RIGHT OPEN-HEADED ARROW +'homtht': '∻', # HOMOTHETIC +'hookleftarrow': '↩', # LEFTWARDS ARROW WITH HOOK +'hookrightarrow': '↪', # RIGHTWARDS ARROW WITH HOOK +'hopf': '𝕙', # MATHEMATICAL DOUBLE-STRUCK SMALL H +'horbar': '―', # HORIZONTAL BAR +'hscr': '𝒽', # MATHEMATICAL SCRIPT SMALL H +'hslash': 'ℏ', # PLANCK CONSTANT OVER TWO PI +'hstrok': 'ħ', # LATIN SMALL LETTER H WITH STROKE +'hybull': '⁃', # HYPHEN BULLET +'hyphen': '‐', # HYPHEN +'iacgr': 'ί', # GREEK SMALL LETTER IOTA WITH TONOS +'iacute': 'í', # LATIN SMALL LETTER I WITH ACUTE +'ic': '⁣', # INVISIBLE SEPARATOR +'icirc': 'î', # LATIN SMALL LETTER I WITH CIRCUMFLEX +'icy': 'и', # CYRILLIC SMALL LETTER I +'idiagr': 'ΐ', # GREEK SMALL LETTER IOTA WITH DIALYTIKA AND TONOS +'idigr': 'ϊ', # GREEK SMALL LETTER IOTA WITH DIALYTIKA +'iecy': 'е', # CYRILLIC SMALL LETTER IE +'iexcl': '¡', # INVERTED EXCLAMATION MARK +'iff': '⇔', # LEFT RIGHT DOUBLE ARROW +'ifr': '𝔦', # MATHEMATICAL FRAKTUR SMALL I +'igr': 'ι', # GREEK SMALL LETTER IOTA +'igrave': 'ì', # LATIN SMALL LETTER I WITH GRAVE +'ii': 'ⅈ', # DOUBLE-STRUCK ITALIC SMALL I +'iiiint': '⨌', # QUADRUPLE INTEGRAL OPERATOR +'iiint': '∭', # TRIPLE INTEGRAL +'iinfin': '⧜', # INCOMPLETE INFINITY +'iiota': '℩', # TURNED GREEK SMALL LETTER IOTA +'ijlig': 'ij', # LATIN SMALL LIGATURE IJ +'imacr': 'ī', # LATIN SMALL LETTER I WITH MACRON +'image': 'ℑ', # BLACK-LETTER CAPITAL I +'imagline': 'ℐ', # SCRIPT CAPITAL I +'imagpart': 'ℑ', # BLACK-LETTER CAPITAL I +'imath': 'ı', # LATIN SMALL LETTER DOTLESS I +'imof': '⊷', # IMAGE OF +'imped': 'Ƶ', # LATIN CAPITAL LETTER Z WITH STROKE +'in': '∈', # ELEMENT OF +'incare': '℅', # CARE OF +'infin': '∞', # INFINITY +'infintie': '⧝', # TIE OVER INFINITY +'inodot': 'ı', # LATIN SMALL LETTER DOTLESS I +'int': '∫', # INTEGRAL +'intcal': '⊺', # INTERCALATE +'integers': 'ℤ', # DOUBLE-STRUCK CAPITAL Z +'intercal': '⊺', # INTERCALATE +'intlarhk': '⨗', # INTEGRAL WITH LEFTWARDS ARROW WITH HOOK +'intprod': '⨼', # INTERIOR PRODUCT +'iocy': 'ё', # CYRILLIC SMALL LETTER IO +'iogon': 'į', # LATIN SMALL LETTER I WITH OGONEK +'iopf': '𝕚', # MATHEMATICAL DOUBLE-STRUCK SMALL I +'iota': 'ι', # GREEK SMALL LETTER IOTA +'iprod': '⨼', # INTERIOR PRODUCT +'iquest': '¿', # INVERTED QUESTION MARK +'iscr': '𝒾', # MATHEMATICAL SCRIPT SMALL I +'isin': '∈', # ELEMENT OF +'isinE': '⋹', # ELEMENT OF WITH TWO HORIZONTAL STROKES +'isindot': '⋵', # ELEMENT OF WITH DOT ABOVE +'isins': '⋴', # SMALL ELEMENT OF WITH VERTICAL BAR AT END OF HORIZONTAL STROKE +'isinsv': '⋳', # ELEMENT OF WITH VERTICAL BAR AT END OF HORIZONTAL STROKE +'isinv': '∈', # ELEMENT OF +'it': '⁢', # INVISIBLE TIMES +'itilde': 'ĩ', # LATIN SMALL LETTER I WITH TILDE +'iukcy': 'і', # CYRILLIC SMALL LETTER BYELORUSSIAN-UKRAINIAN I +'iuml': 'ï', # LATIN SMALL LETTER I WITH DIAERESIS +'jcirc': 'ĵ', # LATIN SMALL LETTER J WITH CIRCUMFLEX +'jcy': 'й', # CYRILLIC SMALL LETTER SHORT I +'jfr': '𝔧', # MATHEMATICAL FRAKTUR SMALL J +'jmath': 'ȷ', # LATIN SMALL LETTER DOTLESS J +'jopf': '𝕛', # MATHEMATICAL DOUBLE-STRUCK SMALL J +'jscr': '𝒿', # MATHEMATICAL SCRIPT SMALL J +'jsercy': 'ј', # CYRILLIC SMALL LETTER JE +'jukcy': 'є', # CYRILLIC SMALL LETTER UKRAINIAN IE +'kappa': 'κ', # GREEK SMALL LETTER KAPPA +'kappav': 'ϰ', # GREEK KAPPA SYMBOL +'kcedil': 'ķ', # LATIN SMALL LETTER K WITH CEDILLA +'kcy': 'к', # CYRILLIC SMALL LETTER KA +'kfr': '𝔨', # MATHEMATICAL FRAKTUR SMALL K +'kgr': 'κ', # GREEK SMALL LETTER KAPPA +'kgreen': 'ĸ', # LATIN SMALL LETTER KRA +'khcy': 'х', # CYRILLIC SMALL LETTER HA +'khgr': 'χ', # GREEK SMALL LETTER CHI +'kjcy': 'ќ', # CYRILLIC SMALL LETTER KJE +'kopf': '𝕜', # MATHEMATICAL DOUBLE-STRUCK SMALL K +'kscr': '𝓀', # MATHEMATICAL SCRIPT SMALL K +'lAarr': '⇚', # LEFTWARDS TRIPLE ARROW +'lArr': '⇐', # LEFTWARDS DOUBLE ARROW +'lAtail': '⤛', # LEFTWARDS DOUBLE ARROW-TAIL +'lBarr': '⤎', # LEFTWARDS TRIPLE DASH ARROW +'lE': '≦', # LESS-THAN OVER EQUAL TO +'lEg': '⪋', # LESS-THAN ABOVE DOUBLE-LINE EQUAL ABOVE GREATER-THAN +'lHar': '⥢', # LEFTWARDS HARPOON WITH BARB UP ABOVE LEFTWARDS HARPOON WITH BARB DOWN +'lacute': 'ĺ', # LATIN SMALL LETTER L WITH ACUTE +'laemptyv': '⦴', # EMPTY SET WITH LEFT ARROW ABOVE +'lagran': 'ℒ', # SCRIPT CAPITAL L +'lambda': 'λ', # GREEK SMALL LETTER LAMDA +'lang': '⟨', # MATHEMATICAL LEFT ANGLE BRACKET +'langd': '⦑', # LEFT ANGLE BRACKET WITH DOT +'langle': '⟨', # MATHEMATICAL LEFT ANGLE BRACKET +'lap': '⪅', # LESS-THAN OR APPROXIMATE +'laquo': '«', # LEFT-POINTING DOUBLE ANGLE QUOTATION MARK +'larr': '←', # LEFTWARDS ARROW +'larrb': '⇤', # LEFTWARDS ARROW TO BAR +'larrbfs': '⤟', # LEFTWARDS ARROW FROM BAR TO BLACK DIAMOND +'larrfs': '⤝', # LEFTWARDS ARROW TO BLACK DIAMOND +'larrhk': '↩', # LEFTWARDS ARROW WITH HOOK +'larrlp': '↫', # LEFTWARDS ARROW WITH LOOP +'larrpl': '⤹', # LEFT-SIDE ARC ANTICLOCKWISE ARROW +'larrsim': '⥳', # LEFTWARDS ARROW ABOVE TILDE OPERATOR +'larrtl': '↢', # LEFTWARDS ARROW WITH TAIL +'lat': '⪫', # LARGER THAN +'latail': '⤙', # LEFTWARDS ARROW-TAIL +'late': '⪭', # LARGER THAN OR EQUAL TO +'lates': '⪭︀', # LARGER THAN OR slanted EQUAL +'lbarr': '⤌', # LEFTWARDS DOUBLE DASH ARROW +'lbbrk': '❲', # LIGHT LEFT TORTOISE SHELL BRACKET ORNAMENT +'lbrace': '{', # LEFT CURLY BRACKET +'lbrack': '[', # LEFT SQUARE BRACKET +'lbrke': '⦋', # LEFT SQUARE BRACKET WITH UNDERBAR +'lbrksld': '⦏', # LEFT SQUARE BRACKET WITH TICK IN BOTTOM CORNER +'lbrkslu': '⦍', # LEFT SQUARE BRACKET WITH TICK IN TOP CORNER +'lcaron': 'ľ', # LATIN SMALL LETTER L WITH CARON +'lcedil': 'ļ', # LATIN SMALL LETTER L WITH CEDILLA +'lceil': '⌈', # LEFT CEILING +'lcub': '{', # LEFT CURLY BRACKET +'lcy': 'л', # CYRILLIC SMALL LETTER EL +'ldca': '⤶', # ARROW POINTING DOWNWARDS THEN CURVING LEFTWARDS +'ldquo': '“', # LEFT DOUBLE QUOTATION MARK +'ldquor': '„', # DOUBLE LOW-9 QUOTATION MARK +'ldrdhar': '⥧', # LEFTWARDS HARPOON WITH BARB DOWN ABOVE RIGHTWARDS HARPOON WITH BARB DOWN +'ldrushar': '⥋', # LEFT BARB DOWN RIGHT BARB UP HARPOON +'ldsh': '↲', # DOWNWARDS ARROW WITH TIP LEFTWARDS +'le': '≤', # LESS-THAN OR EQUAL TO +'leftarrow': '←', # LEFTWARDS ARROW +'leftarrowtail': '↢', # LEFTWARDS ARROW WITH TAIL +'leftharpoondown': '↽', # LEFTWARDS HARPOON WITH BARB DOWNWARDS +'leftharpoonup': '↼', # LEFTWARDS HARPOON WITH BARB UPWARDS +'leftleftarrows': '⇇', # LEFTWARDS PAIRED ARROWS +'leftrightarrow': '↔', # LEFT RIGHT ARROW +'leftrightarrows': '⇆', # LEFTWARDS ARROW OVER RIGHTWARDS ARROW +'leftrightharpoons': '⇋', # LEFTWARDS HARPOON OVER RIGHTWARDS HARPOON +'leftrightsquigarrow': '↭', # LEFT RIGHT WAVE ARROW +'leftthreetimes': '⋋', # LEFT SEMIDIRECT PRODUCT +'leg': '⋚', # LESS-THAN EQUAL TO OR GREATER-THAN +'leq': '≤', # LESS-THAN OR EQUAL TO +'leqq': '≦', # LESS-THAN OVER EQUAL TO +'leqslant': '⩽', # LESS-THAN OR SLANTED EQUAL TO +'les': '⩽', # LESS-THAN OR SLANTED EQUAL TO +'lescc': '⪨', # LESS-THAN CLOSED BY CURVE ABOVE SLANTED EQUAL +'lesdot': '⩿', # LESS-THAN OR SLANTED EQUAL TO WITH DOT INSIDE +'lesdoto': '⪁', # LESS-THAN OR SLANTED EQUAL TO WITH DOT ABOVE +'lesdotor': '⪃', # LESS-THAN OR SLANTED EQUAL TO WITH DOT ABOVE RIGHT +'lesg': '⋚︀', # LESS-THAN slanted EQUAL TO OR GREATER-THAN +'lesges': '⪓', # LESS-THAN ABOVE SLANTED EQUAL ABOVE GREATER-THAN ABOVE SLANTED EQUAL +'lessapprox': '⪅', # LESS-THAN OR APPROXIMATE +'lessdot': '⋖', # LESS-THAN WITH DOT +'lesseqgtr': '⋚', # LESS-THAN EQUAL TO OR GREATER-THAN +'lesseqqgtr': '⪋', # LESS-THAN ABOVE DOUBLE-LINE EQUAL ABOVE GREATER-THAN +'lessgtr': '≶', # LESS-THAN OR GREATER-THAN +'lesssim': '≲', # LESS-THAN OR EQUIVALENT TO +'lfisht': '⥼', # LEFT FISH TAIL +'lfloor': '⌊', # LEFT FLOOR +'lfr': '𝔩', # MATHEMATICAL FRAKTUR SMALL L +'lg': '≶', # LESS-THAN OR GREATER-THAN +'lgE': '⪑', # LESS-THAN ABOVE GREATER-THAN ABOVE DOUBLE-LINE EQUAL +'lgr': 'λ', # GREEK SMALL LETTER LAMDA +'lhard': '↽', # LEFTWARDS HARPOON WITH BARB DOWNWARDS +'lharu': '↼', # LEFTWARDS HARPOON WITH BARB UPWARDS +'lharul': '⥪', # LEFTWARDS HARPOON WITH BARB UP ABOVE LONG DASH +'lhblk': '▄', # LOWER HALF BLOCK +'ljcy': 'љ', # CYRILLIC SMALL LETTER LJE +'ll': '≪', # MUCH LESS-THAN +'llarr': '⇇', # LEFTWARDS PAIRED ARROWS +'llcorner': '⌞', # BOTTOM LEFT CORNER +'llhard': '⥫', # LEFTWARDS HARPOON WITH BARB DOWN BELOW LONG DASH +'lltri': '◺', # LOWER LEFT TRIANGLE +'lmidot': 'ŀ', # LATIN SMALL LETTER L WITH MIDDLE DOT +'lmoust': '⎰', # UPPER LEFT OR LOWER RIGHT CURLY BRACKET SECTION +'lmoustache': '⎰', # UPPER LEFT OR LOWER RIGHT CURLY BRACKET SECTION +'lnE': '≨', # LESS-THAN BUT NOT EQUAL TO +'lnap': '⪉', # LESS-THAN AND NOT APPROXIMATE +'lnapprox': '⪉', # LESS-THAN AND NOT APPROXIMATE +'lne': '⪇', # LESS-THAN AND SINGLE-LINE NOT EQUAL TO +'lneq': '⪇', # LESS-THAN AND SINGLE-LINE NOT EQUAL TO +'lneqq': '≨', # LESS-THAN BUT NOT EQUAL TO +'lnsim': '⋦', # LESS-THAN BUT NOT EQUIVALENT TO +'loang': '⟬', # MATHEMATICAL LEFT WHITE TORTOISE SHELL BRACKET +'loarr': '⇽', # LEFTWARDS OPEN-HEADED ARROW +'lobrk': '⟦', # MATHEMATICAL LEFT WHITE SQUARE BRACKET +'longleftarrow': '⟵', # LONG LEFTWARDS ARROW +'longleftrightarrow': '⟷', # LONG LEFT RIGHT ARROW +'longmapsto': '⟼', # LONG RIGHTWARDS ARROW FROM BAR +'longrightarrow': '⟶', # LONG RIGHTWARDS ARROW +'looparrowleft': '↫', # LEFTWARDS ARROW WITH LOOP +'looparrowright': '↬', # RIGHTWARDS ARROW WITH LOOP +'lopar': '⦅', # LEFT WHITE PARENTHESIS +'lopf': '𝕝', # MATHEMATICAL DOUBLE-STRUCK SMALL L +'loplus': '⨭', # PLUS SIGN IN LEFT HALF CIRCLE +'lotimes': '⨴', # MULTIPLICATION SIGN IN LEFT HALF CIRCLE +'lowast': '∗', # ASTERISK OPERATOR +'lowbar': '_', # LOW LINE +'loz': '◊', # LOZENGE +'lozenge': '◊', # LOZENGE +'lozf': '⧫', # BLACK LOZENGE +'lpar': '(', # LEFT PARENTHESIS +'lparlt': '⦓', # LEFT ARC LESS-THAN BRACKET +'lrarr': '⇆', # LEFTWARDS ARROW OVER RIGHTWARDS ARROW +'lrcorner': '⌟', # BOTTOM RIGHT CORNER +'lrhar': '⇋', # LEFTWARDS HARPOON OVER RIGHTWARDS HARPOON +'lrhard': '⥭', # RIGHTWARDS HARPOON WITH BARB DOWN BELOW LONG DASH +'lrm': '‎', # LEFT-TO-RIGHT MARK +'lrtri': '⊿', # RIGHT TRIANGLE +'lsaquo': '‹', # SINGLE LEFT-POINTING ANGLE QUOTATION MARK +'lscr': '𝓁', # MATHEMATICAL SCRIPT SMALL L +'lsh': '↰', # UPWARDS ARROW WITH TIP LEFTWARDS +'lsim': '≲', # LESS-THAN OR EQUIVALENT TO +'lsime': '⪍', # LESS-THAN ABOVE SIMILAR OR EQUAL +'lsimg': '⪏', # LESS-THAN ABOVE SIMILAR ABOVE GREATER-THAN +'lsqb': '[', # LEFT SQUARE BRACKET +'lsquo': '‘', # LEFT SINGLE QUOTATION MARK +'lsquor': '‚', # SINGLE LOW-9 QUOTATION MARK +'lstrok': 'ł', # LATIN SMALL LETTER L WITH STROKE +'lt': '<', # LESS-THAN SIGN +'ltcc': '⪦', # LESS-THAN CLOSED BY CURVE +'ltcir': '⩹', # LESS-THAN WITH CIRCLE INSIDE +'ltdot': '⋖', # LESS-THAN WITH DOT +'lthree': '⋋', # LEFT SEMIDIRECT PRODUCT +'ltimes': '⋉', # LEFT NORMAL FACTOR SEMIDIRECT PRODUCT +'ltlarr': '⥶', # LESS-THAN ABOVE LEFTWARDS ARROW +'ltquest': '⩻', # LESS-THAN WITH QUESTION MARK ABOVE +'ltrPar': '⦖', # DOUBLE RIGHT ARC LESS-THAN BRACKET +'ltri': '◃', # WHITE LEFT-POINTING SMALL TRIANGLE +'ltrie': '⊴', # NORMAL SUBGROUP OF OR EQUAL TO +'ltrif': '◂', # BLACK LEFT-POINTING SMALL TRIANGLE +'lurdshar': '⥊', # LEFT BARB UP RIGHT BARB DOWN HARPOON +'luruhar': '⥦', # LEFTWARDS HARPOON WITH BARB UP ABOVE RIGHTWARDS HARPOON WITH BARB UP +'lvertneqq': '≨︀', # LESS-THAN BUT NOT EQUAL TO - with vertical stroke +'lvnE': '≨︀', # LESS-THAN BUT NOT EQUAL TO - with vertical stroke +'mDDot': '∺', # GEOMETRIC PROPORTION +'macr': '¯', # MACRON +'male': '♂', # MALE SIGN +'malt': '✠', # MALTESE CROSS +'maltese': '✠', # MALTESE CROSS +'map': '↦', # RIGHTWARDS ARROW FROM BAR +'mapsto': '↦', # RIGHTWARDS ARROW FROM BAR +'mapstodown': '↧', # DOWNWARDS ARROW FROM BAR +'mapstoleft': '↤', # LEFTWARDS ARROW FROM BAR +'mapstoup': '↥', # UPWARDS ARROW FROM BAR +'marker': '▮', # BLACK VERTICAL RECTANGLE +'mcomma': '⨩', # MINUS SIGN WITH COMMA ABOVE +'mcy': 'м', # CYRILLIC SMALL LETTER EM +'mdash': '—', # EM DASH +'measuredangle': '∡', # MEASURED ANGLE +'mfr': '𝔪', # MATHEMATICAL FRAKTUR SMALL M +'mgr': 'μ', # GREEK SMALL LETTER MU +'mho': '℧', # INVERTED OHM SIGN +'micro': 'µ', # MICRO SIGN +'mid': '∣', # DIVIDES +'midast': '*', # ASTERISK +'midcir': '⫰', # VERTICAL LINE WITH CIRCLE BELOW +'middot': '·', # MIDDLE DOT +'minus': '−', # MINUS SIGN +'minusb': '⊟', # SQUARED MINUS +'minusd': '∸', # DOT MINUS +'minusdu': '⨪', # MINUS SIGN WITH DOT BELOW +'mlcp': '⫛', # TRANSVERSAL INTERSECTION +'mldr': '…', # HORIZONTAL ELLIPSIS +'mnplus': '∓', # MINUS-OR-PLUS SIGN +'models': '⊧', # MODELS +'mopf': '𝕞', # MATHEMATICAL DOUBLE-STRUCK SMALL M +'mp': '∓', # MINUS-OR-PLUS SIGN +'mscr': '𝓂', # MATHEMATICAL SCRIPT SMALL M +'mstpos': '∾', # INVERTED LAZY S +'mu': 'μ', # GREEK SMALL LETTER MU +'multimap': '⊸', # MULTIMAP +'mumap': '⊸', # MULTIMAP +'nGg': '⋙̸', # VERY MUCH GREATER-THAN with slash +'nGt': '≫⃒', # MUCH GREATER THAN with vertical line +'nGtv': '≫̸', # MUCH GREATER THAN with slash +'nLeftarrow': '⇍', # LEFTWARDS DOUBLE ARROW WITH STROKE +'nLeftrightarrow': '⇎', # LEFT RIGHT DOUBLE ARROW WITH STROKE +'nLl': '⋘̸', # VERY MUCH LESS-THAN with slash +'nLt': '≪⃒', # MUCH LESS THAN with vertical line +'nLtv': '≪̸', # MUCH LESS THAN with slash +'nRightarrow': '⇏', # RIGHTWARDS DOUBLE ARROW WITH STROKE +'nVDash': '⊯', # NEGATED DOUBLE VERTICAL BAR DOUBLE RIGHT TURNSTILE +'nVdash': '⊮', # DOES NOT FORCE +'nabla': '∇', # NABLA +'nacute': 'ń', # LATIN SMALL LETTER N WITH ACUTE +'nang': '∠⃒', # ANGLE with vertical line +'nap': '≉', # NOT ALMOST EQUAL TO +'napE': '⩰̸', # APPROXIMATELY EQUAL OR EQUAL TO with slash +'napid': '≋̸', # TRIPLE TILDE with slash +'napos': 'ʼn', # LATIN SMALL LETTER N PRECEDED BY APOSTROPHE +'napprox': '≉', # NOT ALMOST EQUAL TO +'natur': '♮', # MUSIC NATURAL SIGN +'natural': '♮', # MUSIC NATURAL SIGN +'naturals': 'ℕ', # DOUBLE-STRUCK CAPITAL N +'nbsp': ' ', # NO-BREAK SPACE +'nbump': '≎̸', # GEOMETRICALLY EQUIVALENT TO with slash +'nbumpe': '≏̸', # DIFFERENCE BETWEEN with slash +'ncap': '⩃', # INTERSECTION WITH OVERBAR +'ncaron': 'ň', # LATIN SMALL LETTER N WITH CARON +'ncedil': 'ņ', # LATIN SMALL LETTER N WITH CEDILLA +'ncong': '≇', # NEITHER APPROXIMATELY NOR ACTUALLY EQUAL TO +'ncongdot': '⩭̸', # CONGRUENT WITH DOT ABOVE with slash +'ncup': '⩂', # UNION WITH OVERBAR +'ncy': 'н', # CYRILLIC SMALL LETTER EN +'ndash': '–', # EN DASH +'ne': '≠', # NOT EQUAL TO +'neArr': '⇗', # NORTH EAST DOUBLE ARROW +'nearhk': '⤤', # NORTH EAST ARROW WITH HOOK +'nearr': '↗', # NORTH EAST ARROW +'nearrow': '↗', # NORTH EAST ARROW +'nedot': '≐̸', # APPROACHES THE LIMIT with slash +'nequiv': '≢', # NOT IDENTICAL TO +'nesear': '⤨', # NORTH EAST ARROW AND SOUTH EAST ARROW +'nesim': '≂̸', # MINUS TILDE with slash +'nexist': '∄', # THERE DOES NOT EXIST +'nexists': '∄', # THERE DOES NOT EXIST +'nfr': '𝔫', # MATHEMATICAL FRAKTUR SMALL N +'ngE': '≧̸', # GREATER-THAN OVER EQUAL TO with slash +'nge': '≱', # NEITHER GREATER-THAN NOR EQUAL TO +'ngeq': '≱', # NEITHER GREATER-THAN NOR EQUAL TO +'ngeqq': '≧̸', # GREATER-THAN OVER EQUAL TO with slash +'ngeqslant': '⩾̸', # GREATER-THAN OR SLANTED EQUAL TO with slash +'nges': '⩾̸', # GREATER-THAN OR SLANTED EQUAL TO with slash +'ngr': 'ν', # GREEK SMALL LETTER NU +'ngsim': '≵', # NEITHER GREATER-THAN NOR EQUIVALENT TO +'ngt': '≯', # NOT GREATER-THAN +'ngtr': '≯', # NOT GREATER-THAN +'nhArr': '⇎', # LEFT RIGHT DOUBLE ARROW WITH STROKE +'nharr': '↮', # LEFT RIGHT ARROW WITH STROKE +'nhpar': '⫲', # PARALLEL WITH HORIZONTAL STROKE +'ni': '∋', # CONTAINS AS MEMBER +'nis': '⋼', # SMALL CONTAINS WITH VERTICAL BAR AT END OF HORIZONTAL STROKE +'nisd': '⋺', # CONTAINS WITH LONG HORIZONTAL STROKE +'niv': '∋', # CONTAINS AS MEMBER +'njcy': 'њ', # CYRILLIC SMALL LETTER NJE +'nlArr': '⇍', # LEFTWARDS DOUBLE ARROW WITH STROKE +'nlE': '≦̸', # LESS-THAN OVER EQUAL TO with slash +'nlarr': '↚', # LEFTWARDS ARROW WITH STROKE +'nldr': '‥', # TWO DOT LEADER +'nle': '≰', # NEITHER LESS-THAN NOR EQUAL TO +'nleftarrow': '↚', # LEFTWARDS ARROW WITH STROKE +'nleftrightarrow': '↮', # LEFT RIGHT ARROW WITH STROKE +'nleq': '≰', # NEITHER LESS-THAN NOR EQUAL TO +'nleqq': '≦̸', # LESS-THAN OVER EQUAL TO with slash +'nleqslant': '⩽̸', # LESS-THAN OR SLANTED EQUAL TO with slash +'nles': '⩽̸', # LESS-THAN OR SLANTED EQUAL TO with slash +'nless': '≮', # NOT LESS-THAN +'nlsim': '≴', # NEITHER LESS-THAN NOR EQUIVALENT TO +'nlt': '≮', # NOT LESS-THAN +'nltri': '⋪', # NOT NORMAL SUBGROUP OF +'nltrie': '⋬', # NOT NORMAL SUBGROUP OF OR EQUAL TO +'nmid': '∤', # DOES NOT DIVIDE +'nopf': '𝕟', # MATHEMATICAL DOUBLE-STRUCK SMALL N +'not': '¬', # NOT SIGN +'notin': '∉', # NOT AN ELEMENT OF +'notinE': '⋹̸', # ELEMENT OF WITH TWO HORIZONTAL STROKES with slash +'notindot': '⋵̸', # ELEMENT OF WITH DOT ABOVE with slash +'notinva': '∉', # NOT AN ELEMENT OF +'notinvb': '⋷', # SMALL ELEMENT OF WITH OVERBAR +'notinvc': '⋶', # ELEMENT OF WITH OVERBAR +'notni': '∌', # DOES NOT CONTAIN AS MEMBER +'notniva': '∌', # DOES NOT CONTAIN AS MEMBER +'notnivb': '⋾', # SMALL CONTAINS WITH OVERBAR +'notnivc': '⋽', # CONTAINS WITH OVERBAR +'npar': '∦', # NOT PARALLEL TO +'nparallel': '∦', # NOT PARALLEL TO +'nparsl': '⫽⃥', # DOUBLE SOLIDUS OPERATOR with reverse slash +'npart': '∂̸', # PARTIAL DIFFERENTIAL with slash +'npolint': '⨔', # LINE INTEGRATION NOT INCLUDING THE POLE +'npr': '⊀', # DOES NOT PRECEDE +'nprcue': '⋠', # DOES NOT PRECEDE OR EQUAL +'npre': '⪯̸', # PRECEDES ABOVE SINGLE-LINE EQUALS SIGN with slash +'nprec': '⊀', # DOES NOT PRECEDE +'npreceq': '⪯̸', # PRECEDES ABOVE SINGLE-LINE EQUALS SIGN with slash +'nrArr': '⇏', # RIGHTWARDS DOUBLE ARROW WITH STROKE +'nrarr': '↛', # RIGHTWARDS ARROW WITH STROKE +'nrarrc': '⤳̸', # WAVE ARROW POINTING DIRECTLY RIGHT with slash +'nrarrw': '↝̸', # RIGHTWARDS WAVE ARROW with slash +'nrightarrow': '↛', # RIGHTWARDS ARROW WITH STROKE +'nrtri': '⋫', # DOES NOT CONTAIN AS NORMAL SUBGROUP +'nrtrie': '⋭', # DOES NOT CONTAIN AS NORMAL SUBGROUP OR EQUAL +'nsc': '⊁', # DOES NOT SUCCEED +'nsccue': '⋡', # DOES NOT SUCCEED OR EQUAL +'nsce': '⪰̸', # SUCCEEDS ABOVE SINGLE-LINE EQUALS SIGN with slash +'nscr': '𝓃', # MATHEMATICAL SCRIPT SMALL N +'nshortmid': '∤', # DOES NOT DIVIDE +'nshortparallel': '∦', # NOT PARALLEL TO +'nsim': '≁', # NOT TILDE +'nsime': '≄', # NOT ASYMPTOTICALLY EQUAL TO +'nsimeq': '≄', # NOT ASYMPTOTICALLY EQUAL TO +'nsmid': '∤', # DOES NOT DIVIDE +'nspar': '∦', # NOT PARALLEL TO +'nsqsube': '⋢', # NOT SQUARE IMAGE OF OR EQUAL TO +'nsqsupe': '⋣', # NOT SQUARE ORIGINAL OF OR EQUAL TO +'nsub': '⊄', # NOT A SUBSET OF +'nsubE': '⫅̸', # SUBSET OF ABOVE EQUALS SIGN with slash +'nsube': '⊈', # NEITHER A SUBSET OF NOR EQUAL TO +'nsubset': '⊂⃒', # SUBSET OF with vertical line +'nsubseteq': '⊈', # NEITHER A SUBSET OF NOR EQUAL TO +'nsubseteqq': '⫅̸', # SUBSET OF ABOVE EQUALS SIGN with slash +'nsucc': '⊁', # DOES NOT SUCCEED +'nsucceq': '⪰̸', # SUCCEEDS ABOVE SINGLE-LINE EQUALS SIGN with slash +'nsup': '⊅', # NOT A SUPERSET OF +'nsupE': '⫆̸', # SUPERSET OF ABOVE EQUALS SIGN with slash +'nsupe': '⊉', # NEITHER A SUPERSET OF NOR EQUAL TO +'nsupset': '⊃⃒', # SUPERSET OF with vertical line +'nsupseteq': '⊉', # NEITHER A SUPERSET OF NOR EQUAL TO +'nsupseteqq': '⫆̸', # SUPERSET OF ABOVE EQUALS SIGN with slash +'ntgl': '≹', # NEITHER GREATER-THAN NOR LESS-THAN +'ntilde': 'ñ', # LATIN SMALL LETTER N WITH TILDE +'ntlg': '≸', # NEITHER LESS-THAN NOR GREATER-THAN +'ntriangleleft': '⋪', # NOT NORMAL SUBGROUP OF +'ntrianglelefteq': '⋬', # NOT NORMAL SUBGROUP OF OR EQUAL TO +'ntriangleright': '⋫', # DOES NOT CONTAIN AS NORMAL SUBGROUP +'ntrianglerighteq': '⋭', # DOES NOT CONTAIN AS NORMAL SUBGROUP OR EQUAL +'nu': 'ν', # GREEK SMALL LETTER NU +'num': '#', # NUMBER SIGN +'numero': '№', # NUMERO SIGN +'numsp': ' ', # FIGURE SPACE +'nvDash': '⊭', # NOT TRUE +'nvHarr': '⤄', # LEFT RIGHT DOUBLE ARROW WITH VERTICAL STROKE +'nvap': '≍⃒', # EQUIVALENT TO with vertical line +'nvdash': '⊬', # DOES NOT PROVE +'nvge': '≥⃒', # GREATER-THAN OR EQUAL TO with vertical line +'nvgt': '>⃒', # GREATER-THAN SIGN with vertical line +'nvinfin': '⧞', # INFINITY NEGATED WITH VERTICAL BAR +'nvlArr': '⤂', # LEFTWARDS DOUBLE ARROW WITH VERTICAL STROKE +'nvle': '≤⃒', # LESS-THAN OR EQUAL TO with vertical line +'nvlt': '<⃒', # LESS-THAN SIGN with vertical line +'nvltrie': '⊴⃒', # NORMAL SUBGROUP OF OR EQUAL TO with vertical line +'nvrArr': '⤃', # RIGHTWARDS DOUBLE ARROW WITH VERTICAL STROKE +'nvrtrie': '⊵⃒', # CONTAINS AS NORMAL SUBGROUP OR EQUAL TO with vertical line +'nvsim': '∼⃒', # TILDE OPERATOR with vertical line +'nwArr': '⇖', # NORTH WEST DOUBLE ARROW +'nwarhk': '⤣', # NORTH WEST ARROW WITH HOOK +'nwarr': '↖', # NORTH WEST ARROW +'nwarrow': '↖', # NORTH WEST ARROW +'nwnear': '⤧', # NORTH WEST ARROW AND NORTH EAST ARROW +'oS': 'Ⓢ', # CIRCLED LATIN CAPITAL LETTER S +'oacgr': 'ό', # GREEK SMALL LETTER OMICRON WITH TONOS +'oacute': 'ó', # LATIN SMALL LETTER O WITH ACUTE +'oast': '⊛', # CIRCLED ASTERISK OPERATOR +'ocir': '⊚', # CIRCLED RING OPERATOR +'ocirc': 'ô', # LATIN SMALL LETTER O WITH CIRCUMFLEX +'ocy': 'о', # CYRILLIC SMALL LETTER O +'odash': '⊝', # CIRCLED DASH +'odblac': 'ő', # LATIN SMALL LETTER O WITH DOUBLE ACUTE +'odiv': '⨸', # CIRCLED DIVISION SIGN +'odot': '⊙', # CIRCLED DOT OPERATOR +'odsold': '⦼', # CIRCLED ANTICLOCKWISE-ROTATED DIVISION SIGN +'oelig': 'œ', # LATIN SMALL LIGATURE OE +'ofcir': '⦿', # CIRCLED BULLET +'ofr': '𝔬', # MATHEMATICAL FRAKTUR SMALL O +'ogon': '˛', # OGONEK +'ogr': 'ο', # GREEK SMALL LETTER OMICRON +'ograve': 'ò', # LATIN SMALL LETTER O WITH GRAVE +'ogt': '⧁', # CIRCLED GREATER-THAN +'ohacgr': 'ώ', # GREEK SMALL LETTER OMEGA WITH TONOS +'ohbar': '⦵', # CIRCLE WITH HORIZONTAL BAR +'ohgr': 'ω', # GREEK SMALL LETTER OMEGA +'ohm': 'Ω', # GREEK CAPITAL LETTER OMEGA +'oint': '∮', # CONTOUR INTEGRAL +'olarr': '↺', # ANTICLOCKWISE OPEN CIRCLE ARROW +'olcir': '⦾', # CIRCLED WHITE BULLET +'olcross': '⦻', # CIRCLE WITH SUPERIMPOSED X +'oline': '‾', # OVERLINE +'olt': '⧀', # CIRCLED LESS-THAN +'omacr': 'ō', # LATIN SMALL LETTER O WITH MACRON +'omega': 'ω', # GREEK SMALL LETTER OMEGA +'omicron': 'ο', # GREEK SMALL LETTER OMICRON +'omid': '⦶', # CIRCLED VERTICAL BAR +'ominus': '⊖', # CIRCLED MINUS +'oopf': '𝕠', # MATHEMATICAL DOUBLE-STRUCK SMALL O +'opar': '⦷', # CIRCLED PARALLEL +'operp': '⦹', # CIRCLED PERPENDICULAR +'oplus': '⊕', # CIRCLED PLUS +'or': '∨', # LOGICAL OR +'orarr': '↻', # CLOCKWISE OPEN CIRCLE ARROW +'ord': '⩝', # LOGICAL OR WITH HORIZONTAL DASH +'order': 'ℴ', # SCRIPT SMALL O +'orderof': 'ℴ', # SCRIPT SMALL O +'ordf': 'ª', # FEMININE ORDINAL INDICATOR +'ordm': 'º', # MASCULINE ORDINAL INDICATOR +'origof': '⊶', # ORIGINAL OF +'oror': '⩖', # TWO INTERSECTING LOGICAL OR +'orslope': '⩗', # SLOPING LARGE OR +'orv': '⩛', # LOGICAL OR WITH MIDDLE STEM +'oscr': 'ℴ', # SCRIPT SMALL O +'oslash': 'ø', # LATIN SMALL LETTER O WITH STROKE +'osol': '⊘', # CIRCLED DIVISION SLASH +'otilde': 'õ', # LATIN SMALL LETTER O WITH TILDE +'otimes': '⊗', # CIRCLED TIMES +'otimesas': '⨶', # CIRCLED MULTIPLICATION SIGN WITH CIRCUMFLEX ACCENT +'ouml': 'ö', # LATIN SMALL LETTER O WITH DIAERESIS +'ovbar': '⌽', # APL FUNCTIONAL SYMBOL CIRCLE STILE +'par': '∥', # PARALLEL TO +'para': '¶', # PILCROW SIGN +'parallel': '∥', # PARALLEL TO +'parsim': '⫳', # PARALLEL WITH TILDE OPERATOR +'parsl': '⫽', # DOUBLE SOLIDUS OPERATOR +'part': '∂', # PARTIAL DIFFERENTIAL +'pcy': 'п', # CYRILLIC SMALL LETTER PE +'percnt': '%', # PERCENT SIGN +'period': '.', # FULL STOP +'permil': '‰', # PER MILLE SIGN +'perp': '⊥', # UP TACK +'pertenk': '‱', # PER TEN THOUSAND SIGN +'pfr': '𝔭', # MATHEMATICAL FRAKTUR SMALL P +'pgr': 'π', # GREEK SMALL LETTER PI +'phgr': 'φ', # GREEK SMALL LETTER PHI +'phi': 'φ', # GREEK SMALL LETTER PHI +'phiv': 'ϕ', # GREEK PHI SYMBOL +'phmmat': 'ℳ', # SCRIPT CAPITAL M +'phone': '☎', # BLACK TELEPHONE +'pi': 'π', # GREEK SMALL LETTER PI +'pitchfork': '⋔', # PITCHFORK +'piv': 'ϖ', # GREEK PI SYMBOL +'planck': 'ℏ', # PLANCK CONSTANT OVER TWO PI +'planckh': 'ℎ', # PLANCK CONSTANT +'plankv': 'ℏ', # PLANCK CONSTANT OVER TWO PI +'plus': '+', # PLUS SIGN +'plusacir': '⨣', # PLUS SIGN WITH CIRCUMFLEX ACCENT ABOVE +'plusb': '⊞', # SQUARED PLUS +'pluscir': '⨢', # PLUS SIGN WITH SMALL CIRCLE ABOVE +'plusdo': '∔', # DOT PLUS +'plusdu': '⨥', # PLUS SIGN WITH DOT BELOW +'pluse': '⩲', # PLUS SIGN ABOVE EQUALS SIGN +'plusmn': '±', # PLUS-MINUS SIGN +'plussim': '⨦', # PLUS SIGN WITH TILDE BELOW +'plustwo': '⨧', # PLUS SIGN WITH SUBSCRIPT TWO +'pm': '±', # PLUS-MINUS SIGN +'pointint': '⨕', # INTEGRAL AROUND A POINT OPERATOR +'popf': '𝕡', # MATHEMATICAL DOUBLE-STRUCK SMALL P +'pound': '£', # POUND SIGN +'pr': '≺', # PRECEDES +'prE': '⪳', # PRECEDES ABOVE EQUALS SIGN +'prap': '⪷', # PRECEDES ABOVE ALMOST EQUAL TO +'prcue': '≼', # PRECEDES OR EQUAL TO +'pre': '⪯', # PRECEDES ABOVE SINGLE-LINE EQUALS SIGN +'prec': '≺', # PRECEDES +'precapprox': '⪷', # PRECEDES ABOVE ALMOST EQUAL TO +'preccurlyeq': '≼', # PRECEDES OR EQUAL TO +'preceq': '⪯', # PRECEDES ABOVE SINGLE-LINE EQUALS SIGN +'precnapprox': '⪹', # PRECEDES ABOVE NOT ALMOST EQUAL TO +'precneqq': '⪵', # PRECEDES ABOVE NOT EQUAL TO +'precnsim': '⋨', # PRECEDES BUT NOT EQUIVALENT TO +'precsim': '≾', # PRECEDES OR EQUIVALENT TO +'prime': '′', # PRIME +'primes': 'ℙ', # DOUBLE-STRUCK CAPITAL P +'prnE': '⪵', # PRECEDES ABOVE NOT EQUAL TO +'prnap': '⪹', # PRECEDES ABOVE NOT ALMOST EQUAL TO +'prnsim': '⋨', # PRECEDES BUT NOT EQUIVALENT TO +'prod': '∏', # N-ARY PRODUCT +'profalar': '⌮', # ALL AROUND-PROFILE +'profline': '⌒', # ARC +'profsurf': '⌓', # SEGMENT +'prop': '∝', # PROPORTIONAL TO +'propto': '∝', # PROPORTIONAL TO +'prsim': '≾', # PRECEDES OR EQUIVALENT TO +'prurel': '⊰', # PRECEDES UNDER RELATION +'pscr': '𝓅', # MATHEMATICAL SCRIPT SMALL P +'psgr': 'ψ', # GREEK SMALL LETTER PSI +'psi': 'ψ', # GREEK SMALL LETTER PSI +'puncsp': ' ', # PUNCTUATION SPACE +'qfr': '𝔮', # MATHEMATICAL FRAKTUR SMALL Q +'qint': '⨌', # QUADRUPLE INTEGRAL OPERATOR +'qopf': '𝕢', # MATHEMATICAL DOUBLE-STRUCK SMALL Q +'qprime': '⁗', # QUADRUPLE PRIME +'qscr': '𝓆', # MATHEMATICAL SCRIPT SMALL Q +'quaternions': 'ℍ', # DOUBLE-STRUCK CAPITAL H +'quatint': '⨖', # QUATERNION INTEGRAL OPERATOR +'quest': '?', # QUESTION MARK +'questeq': '≟', # QUESTIONED EQUAL TO +'quot': '"', # QUOTATION MARK +'rAarr': '⇛', # RIGHTWARDS TRIPLE ARROW +'rArr': '⇒', # RIGHTWARDS DOUBLE ARROW +'rAtail': '⤜', # RIGHTWARDS DOUBLE ARROW-TAIL +'rBarr': '⤏', # RIGHTWARDS TRIPLE DASH ARROW +'rHar': '⥤', # RIGHTWARDS HARPOON WITH BARB UP ABOVE RIGHTWARDS HARPOON WITH BARB DOWN +'race': '∽̱', # REVERSED TILDE with underline +'racute': 'ŕ', # LATIN SMALL LETTER R WITH ACUTE +'radic': '√', # SQUARE ROOT +'raemptyv': '⦳', # EMPTY SET WITH RIGHT ARROW ABOVE +'rang': '⟩', # MATHEMATICAL RIGHT ANGLE BRACKET +'rangd': '⦒', # RIGHT ANGLE BRACKET WITH DOT +'range': '⦥', # REVERSED ANGLE WITH UNDERBAR +'rangle': '⟩', # MATHEMATICAL RIGHT ANGLE BRACKET +'raquo': '»', # RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK +'rarr': '→', # RIGHTWARDS ARROW +'rarrap': '⥵', # RIGHTWARDS ARROW ABOVE ALMOST EQUAL TO +'rarrb': '⇥', # RIGHTWARDS ARROW TO BAR +'rarrbfs': '⤠', # RIGHTWARDS ARROW FROM BAR TO BLACK DIAMOND +'rarrc': '⤳', # WAVE ARROW POINTING DIRECTLY RIGHT +'rarrfs': '⤞', # RIGHTWARDS ARROW TO BLACK DIAMOND +'rarrhk': '↪', # RIGHTWARDS ARROW WITH HOOK +'rarrlp': '↬', # RIGHTWARDS ARROW WITH LOOP +'rarrpl': '⥅', # RIGHTWARDS ARROW WITH PLUS BELOW +'rarrsim': '⥴', # RIGHTWARDS ARROW ABOVE TILDE OPERATOR +'rarrtl': '↣', # RIGHTWARDS ARROW WITH TAIL +'rarrw': '↝', # RIGHTWARDS WAVE ARROW +'ratail': '⤚', # RIGHTWARDS ARROW-TAIL +'ratio': '∶', # RATIO +'rationals': 'ℚ', # DOUBLE-STRUCK CAPITAL Q +'rbarr': '⤍', # RIGHTWARDS DOUBLE DASH ARROW +'rbbrk': '❳', # LIGHT RIGHT TORTOISE SHELL BRACKET ORNAMENT +'rbrace': '}', # RIGHT CURLY BRACKET +'rbrack': ']', # RIGHT SQUARE BRACKET +'rbrke': '⦌', # RIGHT SQUARE BRACKET WITH UNDERBAR +'rbrksld': '⦎', # RIGHT SQUARE BRACKET WITH TICK IN BOTTOM CORNER +'rbrkslu': '⦐', # RIGHT SQUARE BRACKET WITH TICK IN TOP CORNER +'rcaron': 'ř', # LATIN SMALL LETTER R WITH CARON +'rcedil': 'ŗ', # LATIN SMALL LETTER R WITH CEDILLA +'rceil': '⌉', # RIGHT CEILING +'rcub': '}', # RIGHT CURLY BRACKET +'rcy': 'р', # CYRILLIC SMALL LETTER ER +'rdca': '⤷', # ARROW POINTING DOWNWARDS THEN CURVING RIGHTWARDS +'rdldhar': '⥩', # RIGHTWARDS HARPOON WITH BARB DOWN ABOVE LEFTWARDS HARPOON WITH BARB DOWN +'rdquo': '”', # RIGHT DOUBLE QUOTATION MARK +'rdquor': '”', # RIGHT DOUBLE QUOTATION MARK +'rdsh': '↳', # DOWNWARDS ARROW WITH TIP RIGHTWARDS +'real': 'ℜ', # BLACK-LETTER CAPITAL R +'realine': 'ℛ', # SCRIPT CAPITAL R +'realpart': 'ℜ', # BLACK-LETTER CAPITAL R +'reals': 'ℝ', # DOUBLE-STRUCK CAPITAL R +'rect': '▭', # WHITE RECTANGLE +'reg': '®', # REGISTERED SIGN +'rfisht': '⥽', # RIGHT FISH TAIL +'rfloor': '⌋', # RIGHT FLOOR +'rfr': '𝔯', # MATHEMATICAL FRAKTUR SMALL R +'rgr': 'ρ', # GREEK SMALL LETTER RHO +'rhard': '⇁', # RIGHTWARDS HARPOON WITH BARB DOWNWARDS +'rharu': '⇀', # RIGHTWARDS HARPOON WITH BARB UPWARDS +'rharul': '⥬', # RIGHTWARDS HARPOON WITH BARB UP ABOVE LONG DASH +'rho': 'ρ', # GREEK SMALL LETTER RHO +'rhov': 'ϱ', # GREEK RHO SYMBOL +'rightarrow': '→', # RIGHTWARDS ARROW +'rightarrowtail': '↣', # RIGHTWARDS ARROW WITH TAIL +'rightharpoondown': '⇁', # RIGHTWARDS HARPOON WITH BARB DOWNWARDS +'rightharpoonup': '⇀', # RIGHTWARDS HARPOON WITH BARB UPWARDS +'rightleftarrows': '⇄', # RIGHTWARDS ARROW OVER LEFTWARDS ARROW +'rightleftharpoons': '⇌', # RIGHTWARDS HARPOON OVER LEFTWARDS HARPOON +'rightrightarrows': '⇉', # RIGHTWARDS PAIRED ARROWS +'rightsquigarrow': '↝', # RIGHTWARDS WAVE ARROW +'rightthreetimes': '⋌', # RIGHT SEMIDIRECT PRODUCT +'ring': '˚', # RING ABOVE +'risingdotseq': '≓', # IMAGE OF OR APPROXIMATELY EQUAL TO +'rlarr': '⇄', # RIGHTWARDS ARROW OVER LEFTWARDS ARROW +'rlhar': '⇌', # RIGHTWARDS HARPOON OVER LEFTWARDS HARPOON +'rlm': '‏', # RIGHT-TO-LEFT MARK +'rmoust': '⎱', # UPPER RIGHT OR LOWER LEFT CURLY BRACKET SECTION +'rmoustache': '⎱', # UPPER RIGHT OR LOWER LEFT CURLY BRACKET SECTION +'rnmid': '⫮', # DOES NOT DIVIDE WITH REVERSED NEGATION SLASH +'roang': '⟭', # MATHEMATICAL RIGHT WHITE TORTOISE SHELL BRACKET +'roarr': '⇾', # RIGHTWARDS OPEN-HEADED ARROW +'robrk': '⟧', # MATHEMATICAL RIGHT WHITE SQUARE BRACKET +'ropar': '⦆', # RIGHT WHITE PARENTHESIS +'ropf': '𝕣', # MATHEMATICAL DOUBLE-STRUCK SMALL R +'roplus': '⨮', # PLUS SIGN IN RIGHT HALF CIRCLE +'rotimes': '⨵', # MULTIPLICATION SIGN IN RIGHT HALF CIRCLE +'rpar': ')', # RIGHT PARENTHESIS +'rpargt': '⦔', # RIGHT ARC GREATER-THAN BRACKET +'rppolint': '⨒', # LINE INTEGRATION WITH RECTANGULAR PATH AROUND POLE +'rrarr': '⇉', # RIGHTWARDS PAIRED ARROWS +'rsaquo': '›', # SINGLE RIGHT-POINTING ANGLE QUOTATION MARK +'rscr': '𝓇', # MATHEMATICAL SCRIPT SMALL R +'rsh': '↱', # UPWARDS ARROW WITH TIP RIGHTWARDS +'rsqb': ']', # RIGHT SQUARE BRACKET +'rsquo': '’', # RIGHT SINGLE QUOTATION MARK +'rsquor': '’', # RIGHT SINGLE QUOTATION MARK +'rthree': '⋌', # RIGHT SEMIDIRECT PRODUCT +'rtimes': '⋊', # RIGHT NORMAL FACTOR SEMIDIRECT PRODUCT +'rtri': '▹', # WHITE RIGHT-POINTING SMALL TRIANGLE +'rtrie': '⊵', # CONTAINS AS NORMAL SUBGROUP OR EQUAL TO +'rtrif': '▸', # BLACK RIGHT-POINTING SMALL TRIANGLE +'rtriltri': '⧎', # RIGHT TRIANGLE ABOVE LEFT TRIANGLE +'ruluhar': '⥨', # RIGHTWARDS HARPOON WITH BARB UP ABOVE LEFTWARDS HARPOON WITH BARB UP +'rx': '℞', # PRESCRIPTION TAKE +'sacute': 'ś', # LATIN SMALL LETTER S WITH ACUTE +'sbquo': '‚', # SINGLE LOW-9 QUOTATION MARK +'sc': '≻', # SUCCEEDS +'scE': '⪴', # SUCCEEDS ABOVE EQUALS SIGN +'scap': '⪸', # SUCCEEDS ABOVE ALMOST EQUAL TO +'scaron': 'š', # LATIN SMALL LETTER S WITH CARON +'sccue': '≽', # SUCCEEDS OR EQUAL TO +'sce': '⪰', # SUCCEEDS ABOVE SINGLE-LINE EQUALS SIGN +'scedil': 'ş', # LATIN SMALL LETTER S WITH CEDILLA +'scirc': 'ŝ', # LATIN SMALL LETTER S WITH CIRCUMFLEX +'scnE': '⪶', # SUCCEEDS ABOVE NOT EQUAL TO +'scnap': '⪺', # SUCCEEDS ABOVE NOT ALMOST EQUAL TO +'scnsim': '⋩', # SUCCEEDS BUT NOT EQUIVALENT TO +'scpolint': '⨓', # LINE INTEGRATION WITH SEMICIRCULAR PATH AROUND POLE +'scsim': '≿', # SUCCEEDS OR EQUIVALENT TO +'scy': 'с', # CYRILLIC SMALL LETTER ES +'sdot': '⋅', # DOT OPERATOR +'sdotb': '⊡', # SQUARED DOT OPERATOR +'sdote': '⩦', # EQUALS SIGN WITH DOT BELOW +'seArr': '⇘', # SOUTH EAST DOUBLE ARROW +'searhk': '⤥', # SOUTH EAST ARROW WITH HOOK +'searr': '↘', # SOUTH EAST ARROW +'searrow': '↘', # SOUTH EAST ARROW +'sect': '§', # SECTION SIGN +'semi': ';', # SEMICOLON +'seswar': '⤩', # SOUTH EAST ARROW AND SOUTH WEST ARROW +'setminus': '∖', # SET MINUS +'setmn': '∖', # SET MINUS +'sext': '✶', # SIX POINTED BLACK STAR +'sfgr': 'ς', # GREEK SMALL LETTER FINAL SIGMA +'sfr': '𝔰', # MATHEMATICAL FRAKTUR SMALL S +'sfrown': '⌢', # FROWN +'sgr': 'σ', # GREEK SMALL LETTER SIGMA +'sharp': '♯', # MUSIC SHARP SIGN +'shchcy': 'щ', # CYRILLIC SMALL LETTER SHCHA +'shcy': 'ш', # CYRILLIC SMALL LETTER SHA +'shortmid': '∣', # DIVIDES +'shortparallel': '∥', # PARALLEL TO +'shy': '­', # SOFT HYPHEN +'sigma': 'σ', # GREEK SMALL LETTER SIGMA +'sigmaf': 'ς', # GREEK SMALL LETTER FINAL SIGMA +'sigmav': 'ς', # GREEK SMALL LETTER FINAL SIGMA +'sim': '∼', # TILDE OPERATOR +'simdot': '⩪', # TILDE OPERATOR WITH DOT ABOVE +'sime': '≃', # ASYMPTOTICALLY EQUAL TO +'simeq': '≃', # ASYMPTOTICALLY EQUAL TO +'simg': '⪞', # SIMILAR OR GREATER-THAN +'simgE': '⪠', # SIMILAR ABOVE GREATER-THAN ABOVE EQUALS SIGN +'siml': '⪝', # SIMILAR OR LESS-THAN +'simlE': '⪟', # SIMILAR ABOVE LESS-THAN ABOVE EQUALS SIGN +'simne': '≆', # APPROXIMATELY BUT NOT ACTUALLY EQUAL TO +'simplus': '⨤', # PLUS SIGN WITH TILDE ABOVE +'simrarr': '⥲', # TILDE OPERATOR ABOVE RIGHTWARDS ARROW +'slarr': '←', # LEFTWARDS ARROW +'smallsetminus': '∖', # SET MINUS +'smashp': '⨳', # SMASH PRODUCT +'smeparsl': '⧤', # EQUALS SIGN AND SLANTED PARALLEL WITH TILDE ABOVE +'smid': '∣', # DIVIDES +'smile': '⌣', # SMILE +'smt': '⪪', # SMALLER THAN +'smte': '⪬', # SMALLER THAN OR EQUAL TO +'smtes': '⪬︀', # SMALLER THAN OR slanted EQUAL +'softcy': 'ь', # CYRILLIC SMALL LETTER SOFT SIGN +'sol': '/', # SOLIDUS +'solb': '⧄', # SQUARED RISING DIAGONAL SLASH +'solbar': '⌿', # APL FUNCTIONAL SYMBOL SLASH BAR +'sopf': '𝕤', # MATHEMATICAL DOUBLE-STRUCK SMALL S +'spades': '♠', # BLACK SPADE SUIT +'spadesuit': '♠', # BLACK SPADE SUIT +'spar': '∥', # PARALLEL TO +'sqcap': '⊓', # SQUARE CAP +'sqcaps': '⊓︀', # SQUARE CAP with serifs +'sqcup': '⊔', # SQUARE CUP +'sqcups': '⊔︀', # SQUARE CUP with serifs +'sqsub': '⊏', # SQUARE IMAGE OF +'sqsube': '⊑', # SQUARE IMAGE OF OR EQUAL TO +'sqsubset': '⊏', # SQUARE IMAGE OF +'sqsubseteq': '⊑', # SQUARE IMAGE OF OR EQUAL TO +'sqsup': '⊐', # SQUARE ORIGINAL OF +'sqsupe': '⊒', # SQUARE ORIGINAL OF OR EQUAL TO +'sqsupset': '⊐', # SQUARE ORIGINAL OF +'sqsupseteq': '⊒', # SQUARE ORIGINAL OF OR EQUAL TO +'squ': '□', # WHITE SQUARE +'square': '□', # WHITE SQUARE +'squarf': '▪', # BLACK SMALL SQUARE +'squf': '▪', # BLACK SMALL SQUARE +'srarr': '→', # RIGHTWARDS ARROW +'sscr': '𝓈', # MATHEMATICAL SCRIPT SMALL S +'ssetmn': '∖', # SET MINUS +'ssmile': '⌣', # SMILE +'sstarf': '⋆', # STAR OPERATOR +'star': '☆', # WHITE STAR +'starf': '★', # BLACK STAR +'straightepsilon': 'ϵ', # GREEK LUNATE EPSILON SYMBOL +'straightphi': 'ϕ', # GREEK PHI SYMBOL +'strns': '¯', # MACRON +'sub': '⊂', # SUBSET OF +'subE': '⫅', # SUBSET OF ABOVE EQUALS SIGN +'subdot': '⪽', # SUBSET WITH DOT +'sube': '⊆', # SUBSET OF OR EQUAL TO +'subedot': '⫃', # SUBSET OF OR EQUAL TO WITH DOT ABOVE +'submult': '⫁', # SUBSET WITH MULTIPLICATION SIGN BELOW +'subnE': '⫋', # SUBSET OF ABOVE NOT EQUAL TO +'subne': '⊊', # SUBSET OF WITH NOT EQUAL TO +'subplus': '⪿', # SUBSET WITH PLUS SIGN BELOW +'subrarr': '⥹', # SUBSET ABOVE RIGHTWARDS ARROW +'subset': '⊂', # SUBSET OF +'subseteq': '⊆', # SUBSET OF OR EQUAL TO +'subseteqq': '⫅', # SUBSET OF ABOVE EQUALS SIGN +'subsetneq': '⊊', # SUBSET OF WITH NOT EQUAL TO +'subsetneqq': '⫋', # SUBSET OF ABOVE NOT EQUAL TO +'subsim': '⫇', # SUBSET OF ABOVE TILDE OPERATOR +'subsub': '⫕', # SUBSET ABOVE SUBSET +'subsup': '⫓', # SUBSET ABOVE SUPERSET +'succ': '≻', # SUCCEEDS +'succapprox': '⪸', # SUCCEEDS ABOVE ALMOST EQUAL TO +'succcurlyeq': '≽', # SUCCEEDS OR EQUAL TO +'succeq': '⪰', # SUCCEEDS ABOVE SINGLE-LINE EQUALS SIGN +'succnapprox': '⪺', # SUCCEEDS ABOVE NOT ALMOST EQUAL TO +'succneqq': '⪶', # SUCCEEDS ABOVE NOT EQUAL TO +'succnsim': '⋩', # SUCCEEDS BUT NOT EQUIVALENT TO +'succsim': '≿', # SUCCEEDS OR EQUIVALENT TO +'sum': '∑', # N-ARY SUMMATION +'sung': '♪', # EIGHTH NOTE +'sup': '⊃', # SUPERSET OF +'sup1': '¹', # SUPERSCRIPT ONE +'sup2': '²', # SUPERSCRIPT TWO +'sup3': '³', # SUPERSCRIPT THREE +'supE': '⫆', # SUPERSET OF ABOVE EQUALS SIGN +'supdot': '⪾', # SUPERSET WITH DOT +'supdsub': '⫘', # SUPERSET BESIDE AND JOINED BY DASH WITH SUBSET +'supe': '⊇', # SUPERSET OF OR EQUAL TO +'supedot': '⫄', # SUPERSET OF OR EQUAL TO WITH DOT ABOVE +'suphsol': '⟉', # SUPERSET PRECEDING SOLIDUS +'suphsub': '⫗', # SUPERSET BESIDE SUBSET +'suplarr': '⥻', # SUPERSET ABOVE LEFTWARDS ARROW +'supmult': '⫂', # SUPERSET WITH MULTIPLICATION SIGN BELOW +'supnE': '⫌', # SUPERSET OF ABOVE NOT EQUAL TO +'supne': '⊋', # SUPERSET OF WITH NOT EQUAL TO +'supplus': '⫀', # SUPERSET WITH PLUS SIGN BELOW +'supset': '⊃', # SUPERSET OF +'supseteq': '⊇', # SUPERSET OF OR EQUAL TO +'supseteqq': '⫆', # SUPERSET OF ABOVE EQUALS SIGN +'supsetneq': '⊋', # SUPERSET OF WITH NOT EQUAL TO +'supsetneqq': '⫌', # SUPERSET OF ABOVE NOT EQUAL TO +'supsim': '⫈', # SUPERSET OF ABOVE TILDE OPERATOR +'supsub': '⫔', # SUPERSET ABOVE SUBSET +'supsup': '⫖', # SUPERSET ABOVE SUPERSET +'swArr': '⇙', # SOUTH WEST DOUBLE ARROW +'swarhk': '⤦', # SOUTH WEST ARROW WITH HOOK +'swarr': '↙', # SOUTH WEST ARROW +'swarrow': '↙', # SOUTH WEST ARROW +'swnwar': '⤪', # SOUTH WEST ARROW AND NORTH WEST ARROW +'szlig': 'ß', # LATIN SMALL LETTER SHARP S +'target': '⌖', # POSITION INDICATOR +'tau': 'τ', # GREEK SMALL LETTER TAU +'tbrk': '⎴', # TOP SQUARE BRACKET +'tcaron': 'ť', # LATIN SMALL LETTER T WITH CARON +'tcedil': 'ţ', # LATIN SMALL LETTER T WITH CEDILLA +'tcy': 'т', # CYRILLIC SMALL LETTER TE +'tdot': '\u20DB', # COMBINING THREE DOTS ABOVE +'telrec': '⌕', # TELEPHONE RECORDER +'tfr': '𝔱', # MATHEMATICAL FRAKTUR SMALL T +'tgr': 'τ', # GREEK SMALL LETTER TAU +'there4': '∴', # THEREFORE +'therefore': '∴', # THEREFORE +'theta': 'θ', # GREEK SMALL LETTER THETA +'thetasym': 'ϑ', # GREEK THETA SYMBOL +'thetav': 'ϑ', # GREEK THETA SYMBOL +'thgr': 'θ', # GREEK SMALL LETTER THETA +'thickapprox': '≈', # ALMOST EQUAL TO +'thicksim': '∼', # TILDE OPERATOR +'thinsp': ' ', # THIN SPACE +'thkap': '≈', # ALMOST EQUAL TO +'thksim': '∼', # TILDE OPERATOR +'thorn': 'þ', # LATIN SMALL LETTER THORN +'tilde': '˜', # SMALL TILDE +'times': '×', # MULTIPLICATION SIGN +'timesb': '⊠', # SQUARED TIMES +'timesbar': '⨱', # MULTIPLICATION SIGN WITH UNDERBAR +'timesd': '⨰', # MULTIPLICATION SIGN WITH DOT ABOVE +'tint': '∭', # TRIPLE INTEGRAL +'toea': '⤨', # NORTH EAST ARROW AND SOUTH EAST ARROW +'top': '⊤', # DOWN TACK +'topbot': '⌶', # APL FUNCTIONAL SYMBOL I-BEAM +'topcir': '⫱', # DOWN TACK WITH CIRCLE BELOW +'topf': '𝕥', # MATHEMATICAL DOUBLE-STRUCK SMALL T +'topfork': '⫚', # PITCHFORK WITH TEE TOP +'tosa': '⤩', # SOUTH EAST ARROW AND SOUTH WEST ARROW +'tprime': '‴', # TRIPLE PRIME +'trade': '™', # TRADE MARK SIGN +'triangle': '▵', # WHITE UP-POINTING SMALL TRIANGLE +'triangledown': '▿', # WHITE DOWN-POINTING SMALL TRIANGLE +'triangleleft': '◃', # WHITE LEFT-POINTING SMALL TRIANGLE +'trianglelefteq': '⊴', # NORMAL SUBGROUP OF OR EQUAL TO +'triangleq': '≜', # DELTA EQUAL TO +'triangleright': '▹', # WHITE RIGHT-POINTING SMALL TRIANGLE +'trianglerighteq': '⊵', # CONTAINS AS NORMAL SUBGROUP OR EQUAL TO +'tridot': '◬', # WHITE UP-POINTING TRIANGLE WITH DOT +'trie': '≜', # DELTA EQUAL TO +'triminus': '⨺', # MINUS SIGN IN TRIANGLE +'triplus': '⨹', # PLUS SIGN IN TRIANGLE +'trisb': '⧍', # TRIANGLE WITH SERIFS AT BOTTOM +'tritime': '⨻', # MULTIPLICATION SIGN IN TRIANGLE +'trpezium': '⏢', # WHITE TRAPEZIUM +'tscr': '𝓉', # MATHEMATICAL SCRIPT SMALL T +'tscy': 'ц', # CYRILLIC SMALL LETTER TSE +'tshcy': 'ћ', # CYRILLIC SMALL LETTER TSHE +'tstrok': 'ŧ', # LATIN SMALL LETTER T WITH STROKE +'twixt': '≬', # BETWEEN +'twoheadleftarrow': '↞', # LEFTWARDS TWO HEADED ARROW +'twoheadrightarrow': '↠', # RIGHTWARDS TWO HEADED ARROW +'uArr': '⇑', # UPWARDS DOUBLE ARROW +'uHar': '⥣', # UPWARDS HARPOON WITH BARB LEFT BESIDE UPWARDS HARPOON WITH BARB RIGHT +'uacgr': 'ύ', # GREEK SMALL LETTER UPSILON WITH TONOS +'uacute': 'ú', # LATIN SMALL LETTER U WITH ACUTE +'uarr': '↑', # UPWARDS ARROW +'ubrcy': 'ў', # CYRILLIC SMALL LETTER SHORT U +'ubreve': 'ŭ', # LATIN SMALL LETTER U WITH BREVE +'ucirc': 'û', # LATIN SMALL LETTER U WITH CIRCUMFLEX +'ucy': 'у', # CYRILLIC SMALL LETTER U +'udarr': '⇅', # UPWARDS ARROW LEFTWARDS OF DOWNWARDS ARROW +'udblac': 'ű', # LATIN SMALL LETTER U WITH DOUBLE ACUTE +'udhar': '⥮', # UPWARDS HARPOON WITH BARB LEFT BESIDE DOWNWARDS HARPOON WITH BARB RIGHT +'udiagr': 'ΰ', # GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND TONOS +'udigr': 'ϋ', # GREEK SMALL LETTER UPSILON WITH DIALYTIKA +'ufisht': '⥾', # UP FISH TAIL +'ufr': '𝔲', # MATHEMATICAL FRAKTUR SMALL U +'ugr': 'υ', # GREEK SMALL LETTER UPSILON +'ugrave': 'ù', # LATIN SMALL LETTER U WITH GRAVE +'uharl': '↿', # UPWARDS HARPOON WITH BARB LEFTWARDS +'uharr': '↾', # UPWARDS HARPOON WITH BARB RIGHTWARDS +'uhblk': '▀', # UPPER HALF BLOCK +'ulcorn': '⌜', # TOP LEFT CORNER +'ulcorner': '⌜', # TOP LEFT CORNER +'ulcrop': '⌏', # TOP LEFT CROP +'ultri': '◸', # UPPER LEFT TRIANGLE +'umacr': 'ū', # LATIN SMALL LETTER U WITH MACRON +'uml': '¨', # DIAERESIS +'uogon': 'ų', # LATIN SMALL LETTER U WITH OGONEK +'uopf': '𝕦', # MATHEMATICAL DOUBLE-STRUCK SMALL U +'uparrow': '↑', # UPWARDS ARROW +'updownarrow': '↕', # UP DOWN ARROW +'upharpoonleft': '↿', # UPWARDS HARPOON WITH BARB LEFTWARDS +'upharpoonright': '↾', # UPWARDS HARPOON WITH BARB RIGHTWARDS +'uplus': '⊎', # MULTISET UNION +'upsi': 'υ', # GREEK SMALL LETTER UPSILON +'upsih': 'ϒ', # GREEK UPSILON WITH HOOK SYMBOL +'upsilon': 'υ', # GREEK SMALL LETTER UPSILON +'upuparrows': '⇈', # UPWARDS PAIRED ARROWS +'urcorn': '⌝', # TOP RIGHT CORNER +'urcorner': '⌝', # TOP RIGHT CORNER +'urcrop': '⌎', # TOP RIGHT CROP +'uring': 'ů', # LATIN SMALL LETTER U WITH RING ABOVE +'urtri': '◹', # UPPER RIGHT TRIANGLE +'uscr': '𝓊', # MATHEMATICAL SCRIPT SMALL U +'utdot': '⋰', # UP RIGHT DIAGONAL ELLIPSIS +'utilde': 'ũ', # LATIN SMALL LETTER U WITH TILDE +'utri': '▵', # WHITE UP-POINTING SMALL TRIANGLE +'utrif': '▴', # BLACK UP-POINTING SMALL TRIANGLE +'uuarr': '⇈', # UPWARDS PAIRED ARROWS +'uuml': 'ü', # LATIN SMALL LETTER U WITH DIAERESIS +'uwangle': '⦧', # OBLIQUE ANGLE OPENING DOWN +'vArr': '⇕', # UP DOWN DOUBLE ARROW +'vBar': '⫨', # SHORT UP TACK WITH UNDERBAR +'vBarv': '⫩', # SHORT UP TACK ABOVE SHORT DOWN TACK +'vDash': '⊨', # TRUE +'vangrt': '⦜', # RIGHT ANGLE VARIANT WITH SQUARE +'varepsilon': 'ϵ', # GREEK LUNATE EPSILON SYMBOL +'varkappa': 'ϰ', # GREEK KAPPA SYMBOL +'varnothing': '∅', # EMPTY SET +'varphi': 'ϕ', # GREEK PHI SYMBOL +'varpi': 'ϖ', # GREEK PI SYMBOL +'varpropto': '∝', # PROPORTIONAL TO +'varr': '↕', # UP DOWN ARROW +'varrho': 'ϱ', # GREEK RHO SYMBOL +'varsigma': 'ς', # GREEK SMALL LETTER FINAL SIGMA +'varsubsetneq': '⊊︀', # SUBSET OF WITH NOT EQUAL TO - variant with stroke through bottom members +'varsubsetneqq': '⫋︀', # SUBSET OF ABOVE NOT EQUAL TO - variant with stroke through bottom members +'varsupsetneq': '⊋︀', # SUPERSET OF WITH NOT EQUAL TO - variant with stroke through bottom members +'varsupsetneqq': '⫌︀', # SUPERSET OF ABOVE NOT EQUAL TO - variant with stroke through bottom members +'vartheta': 'ϑ', # GREEK THETA SYMBOL +'vartriangleleft': '⊲', # NORMAL SUBGROUP OF +'vartriangleright': '⊳', # CONTAINS AS NORMAL SUBGROUP +'vcy': 'в', # CYRILLIC SMALL LETTER VE +'vdash': '⊢', # RIGHT TACK +'vee': '∨', # LOGICAL OR +'veebar': '⊻', # XOR +'veeeq': '≚', # EQUIANGULAR TO +'vellip': '⋮', # VERTICAL ELLIPSIS +'verbar': '|', # VERTICAL LINE +'vert': '|', # VERTICAL LINE +'vfr': '𝔳', # MATHEMATICAL FRAKTUR SMALL V +'vltri': '⊲', # NORMAL SUBGROUP OF +'vnsub': '⊂⃒', # SUBSET OF with vertical line +'vnsup': '⊃⃒', # SUPERSET OF with vertical line +'vopf': '𝕧', # MATHEMATICAL DOUBLE-STRUCK SMALL V +'vprop': '∝', # PROPORTIONAL TO +'vrtri': '⊳', # CONTAINS AS NORMAL SUBGROUP +'vscr': '𝓋', # MATHEMATICAL SCRIPT SMALL V +'vsubnE': '⫋︀', # SUBSET OF ABOVE NOT EQUAL TO - variant with stroke through bottom members +'vsubne': '⊊︀', # SUBSET OF WITH NOT EQUAL TO - variant with stroke through bottom members +'vsupnE': '⫌︀', # SUPERSET OF ABOVE NOT EQUAL TO - variant with stroke through bottom members +'vsupne': '⊋︀', # SUPERSET OF WITH NOT EQUAL TO - variant with stroke through bottom members +'vzigzag': '⦚', # VERTICAL ZIGZAG LINE +'wcirc': 'ŵ', # LATIN SMALL LETTER W WITH CIRCUMFLEX +'wedbar': '⩟', # LOGICAL AND WITH UNDERBAR +'wedge': '∧', # LOGICAL AND +'wedgeq': '≙', # ESTIMATES +'weierp': '℘', # SCRIPT CAPITAL P +'wfr': '𝔴', # MATHEMATICAL FRAKTUR SMALL W +'wopf': '𝕨', # MATHEMATICAL DOUBLE-STRUCK SMALL W +'wp': '℘', # SCRIPT CAPITAL P +'wr': '≀', # WREATH PRODUCT +'wreath': '≀', # WREATH PRODUCT +'wscr': '𝓌', # MATHEMATICAL SCRIPT SMALL W +'xcap': '⋂', # N-ARY INTERSECTION +'xcirc': '◯', # LARGE CIRCLE +'xcup': '⋃', # N-ARY UNION +'xdtri': '▽', # WHITE DOWN-POINTING TRIANGLE +'xfr': '𝔵', # MATHEMATICAL FRAKTUR SMALL X +'xgr': 'ξ', # GREEK SMALL LETTER XI +'xhArr': '⟺', # LONG LEFT RIGHT DOUBLE ARROW +'xharr': '⟷', # LONG LEFT RIGHT ARROW +'xi': 'ξ', # GREEK SMALL LETTER XI +'xlArr': '⟸', # LONG LEFTWARDS DOUBLE ARROW +'xlarr': '⟵', # LONG LEFTWARDS ARROW +'xmap': '⟼', # LONG RIGHTWARDS ARROW FROM BAR +'xnis': '⋻', # CONTAINS WITH VERTICAL BAR AT END OF HORIZONTAL STROKE +'xodot': '⨀', # N-ARY CIRCLED DOT OPERATOR +'xopf': '𝕩', # MATHEMATICAL DOUBLE-STRUCK SMALL X +'xoplus': '⨁', # N-ARY CIRCLED PLUS OPERATOR +'xotime': '⨂', # N-ARY CIRCLED TIMES OPERATOR +'xrArr': '⟹', # LONG RIGHTWARDS DOUBLE ARROW +'xrarr': '⟶', # LONG RIGHTWARDS ARROW +'xscr': '𝓍', # MATHEMATICAL SCRIPT SMALL X +'xsqcup': '⨆', # N-ARY SQUARE UNION OPERATOR +'xuplus': '⨄', # N-ARY UNION OPERATOR WITH PLUS +'xutri': '△', # WHITE UP-POINTING TRIANGLE +'xvee': '⋁', # N-ARY LOGICAL OR +'xwedge': '⋀', # N-ARY LOGICAL AND +'yacute': 'ý', # LATIN SMALL LETTER Y WITH ACUTE +'yacy': 'я', # CYRILLIC SMALL LETTER YA +'ycirc': 'ŷ', # LATIN SMALL LETTER Y WITH CIRCUMFLEX +'ycy': 'ы', # CYRILLIC SMALL LETTER YERU +'yen': '¥', # YEN SIGN +'yfr': '𝔶', # MATHEMATICAL FRAKTUR SMALL Y +'yicy': 'ї', # CYRILLIC SMALL LETTER YI +'yopf': '𝕪', # MATHEMATICAL DOUBLE-STRUCK SMALL Y +'yscr': '𝓎', # MATHEMATICAL SCRIPT SMALL Y +'yucy': 'ю', # CYRILLIC SMALL LETTER YU +'yuml': 'ÿ', # LATIN SMALL LETTER Y WITH DIAERESIS +'zacute': 'ź', # LATIN SMALL LETTER Z WITH ACUTE +'zcaron': 'ž', # LATIN SMALL LETTER Z WITH CARON +'zcy': 'з', # CYRILLIC SMALL LETTER ZE +'zdot': 'ż', # LATIN SMALL LETTER Z WITH DOT ABOVE +'zeetrf': 'ℨ', # BLACK-LETTER CAPITAL Z +'zeta': 'ζ', # GREEK SMALL LETTER ZETA +'zfr': '𝔷', # MATHEMATICAL FRAKTUR SMALL Z +'zgr': 'ζ', # GREEK SMALL LETTER ZETA +'zhcy': 'ж', # CYRILLIC SMALL LETTER ZHE +'zigrarr': '⇝', # RIGHTWARDS SQUIGGLE ARROW +'zopf': '𝕫', # MATHEMATICAL DOUBLE-STRUCK SMALL Z +'zscr': '𝓏', # MATHEMATICAL SCRIPT SMALL Z +'zwj': '‍', # ZERO WIDTH JOINER +'zwnj': '‌', # ZERO WIDTH NON-JOINER +} + diff --git a/mallard/ducktype/extensions/__init__.py b/mallard/ducktype/extensions/__init__.py new file mode 100644 index 0000000..1e3a4b5 --- /dev/null +++ b/mallard/ducktype/extensions/__init__.py @@ -0,0 +1,21 @@ +# Copyright (c) 2018 Shaun McCance +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +__import__('pkg_resources').declare_namespace(__name__) diff --git a/mallard/ducktype/extensions/_test.py b/mallard/ducktype/extensions/_test.py new file mode 100644 index 0000000..8cd8431 --- /dev/null +++ b/mallard/ducktype/extensions/_test.py @@ -0,0 +1,200 @@ +# Copyright (c) 2018 Shaun McCance +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +################################################################################ +# This is a test extension. Its primary purpose is to fuel regression tests. +# Since it exercises all the extension points, it's heavily commented so you +# can learn from it. + +import mallard.ducktype + +# All extensions are a subclass of ParserExtension. When the parser encounters an +# extension declaration like foo/1.0, it imports mallard.ducktype.extensions.foo +# and tries to instantiate every ParserExtension subclass in it. It doesn't matter +# what you name your classes. + +class TestExtension(mallard.ducktype.parser.ParserExtension): + def __init__(self, parser, prefix, version): + # Usually you'd use this to specify a version to make sure this code is + # compatible with what the document expects. In this case, though, we're + # using the version to specify which parts of the test extension to use. + if version == 'block': + self.mode = 'block' + elif version == 'blocknode': + self.mode = 'blocknode' + elif version == 'directive': + self.mode = 'directive' + else: + raise mallard.ducktype.parser.SyntaxError( + 'Unsupported _test extension version: ' + version, + parser) + # It's important to bear in mind that parser might not always be a + # DuckParser object. Depending on the extension and where it's used, + # parser might be something like a DirectiveIncludeParser or an + # InlineParser. + self.parser = parser + self.prefix = prefix + self.version = version + # Feel free to do things to the parser or the document root here. + self.parser.document.add_namespace('test', 'http://projectmallard.org/test/') + + def parse_line_block(self, line): + # This is the function to implement to do things in a block context, + # like adding a shorthand notation for a block element. It gets + # called only in places where a regular block element could occur. + # Headers, comments, and fences have already been taken care of. + # If you want to add a block extension with a syntax that looks + # like a standard block declaration, use take_block_node instead. + # That method will handle a lot more things for you. + if self.mode != 'block': + return False + + indent = mallard.ducktype.parser.DuckParser.get_indent(line) + iline = line[indent:] + + # Return False to indicate you're not handling this line. For + # this test, we're doing something with lines that start with + # three asterisks and a space. + if not iline.startswith('*** '): + return False + + # In most cases when creating block elements, you'll want to start + # by calling push_text and unravel_for_block. push_text makes sure + # any text lines we just encountered get put into a block element. + # unravel_for_block gets you to the correct current element to start + # adding new block elements, based on indentation and the standard + # block nesting rules. There are other unravel functions for special + # nesting rules for tables and lists. + self.parser.push_text() + self.parser.unravel_for_block(indent) + + # Here's the meat of what this extension does. It creates a block + # element, adds an attribute to it, adds the element to the current + # element (which unravel_for_block got us to), then sets the new + # element as the current element. Setting the new element as the + # current element lets the parser add content to it. If you want + # to add something that doesn't take content, don't set it as + # current. + qnode = mallard.ducktype.parser.Block('test:TEST', indent, parser=self.parser) + qnode.attributes = mallard.ducktype.parser.Attributes() + qnode.attributes.add_attribute('line', iline[4:].strip()) + self.parser.current.add_child(qnode) + self.parser.current = qnode + + # This lets the parser know that we've just created a block element + # and it's ready to take on new content. This is important because + # the first child element will set the inner indent of our new block + # element. Don't bother with this if you're adding something that + # doesn't take content (and you didn't set as current). + self.parser.state = mallard.ducktype.parser.DuckParser.STATE_BLOCK_READY + + # Return True to indicate you have handled the line. The parser will + # stop trying to do anything else with this line. + return True + + def take_block_node(self, node): + # This is the function to implement to do things with extension + # elements that looks like block nodes. It gets called on a Node + # object that has alredy been parsed as if it were a block node, + # but it has not been added to the document. This will only be + # called for nodes with a prefix matching the base name of your + # extension. For example, this extension is _test.py, so it will + # be called for things like: + # [_test:block] + # [_test:frobnicate] + # It will not be called for things like: + # [test:block] + # [_test_frobnicate] + # If you want to add block syntax that doesn't look like a + # standard block declaration, use parse_line_block instead. + if self.mode != 'blocknode': + return False + + # Return False to indicate you're not handling this node. If no + # extensions handle the node, the parser will try to treat it + # as a regular block node, requiring a suitable namespace prefix + # binding. If it can't find one, it will raise an error. For this + # test, we're doing something with block declarations that look + # like [_test:block] + if node.name != '_test:block': + return False + + # If you read the comments on parse_line_block, you might be tempted + # to call push_text and unravel_for_block here. But you don't have + # to. The parser has already parsed this thing as if it were a block + # declaration, and that includes pushing text and unraveling. + + # Here's the meat of what this extension does. Instead of allowing + # the passed-in node to go into the document, it creates a new node. + # It copies over the attributes from the extension block element, + # and even adds its own attribute value. You could do completely + # different things with the attributes. If you want to add something + # that doesn't take content, don't set it as current. + qnode = mallard.ducktype.parser.Block('note', outer=node.outer, parser=self.parser) + qnode.attributes = mallard.ducktype.parser.Attributes() + # It's safe to add a style attribute and then add other attributes + # without checking their names. Attributes objects automatically + # join multiple style and type attributes into space-separated lists. + qnode.attributes.add_attribute('style', 'warning') + if node.attributes is not None: + for attr in node.attributes.get_attributes(): + qnode.attributes.add_attribute(attr, node.attributes.get_attribute(attr)) + self.parser.current.add_child(qnode) + self.parser.current = qnode + + # If you read the comments on parse_line_block, you might be tempted + # to set self.parser.state here. Don't bother, unless you actually + # really need to set it to something other than STATE_BLOCK_READY. + # The parser has already entered that state by the time extensions + # get a crack at block declarations. + + # Return True to indicate you have handled the node. The parser will + # stop trying to do anything else with this node. + return True + + def take_directive(self, directive): + # This is the function to implement to handle parser directives at + # the top of a file. This will only be called for directives with + # a prefix matching the base name of your extension. For example, + # this extension is _test.py, so it will be called for things like: + # @_test:defines + # @_test:frobnicate + # It will not be called for things like: + # @test:defines + # @_test_frobnicate + if self.mode != 'directive': + return False + + if directive.name == '_test:defines': + # This extension recognizes a simple directive like this: + # @_test:defines + # And treats it like it defined something lengthier. Just add + # that definition to the main document, and we're done. For a + # directive parser extension, the calling parser might be a + # DirectiveIncludeParser instead of a DuckParser. But that's + # OK, because DirectiveIncludeParser also has a document + # attribute that points to the right place. + self.parser.document.add_definition('TEST', + 'This is a $em(test). ' + + 'It is only a $em[.strong](test).') + # Return True to tell the parser we handled this directive. + return True + else: + return False diff --git a/mallard/ducktype/extensions/csv.py b/mallard/ducktype/extensions/csv.py new file mode 100644 index 0000000..8882761 --- /dev/null +++ b/mallard/ducktype/extensions/csv.py @@ -0,0 +1,73 @@ +# Copyright (c) 2019 Shaun McCance +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +import mallard.ducktype + +# FIXME: +# * Copy over attributes from ext node to table node +# * Except maybe we want some ext attrs: +# * Ext attr to change separator char? (csv:sep=tab) +# * Ext attr to control row and col headers? +# * Ext attr to parse lines inline? Or should that be default? +# * Set inner indent to allow newlines? + +class CsvExtension(mallard.ducktype.parser.ParserExtension): + def __init__(self, parser, prefix, version): + if version == 'experimental': + self.version = version + else: + raise mallard.ducktype.parser.SyntaxError( + 'Unsupported csv extension version: ' + version, + parser) + self.parser = parser + self.prefix = prefix + self.version = version + self.table = None + + def take_block_node(self, node): + if node.name != 'csv:table': + return False + self.table = mallard.ducktype.parser.Block('table') + # Normally table elements are "greedy", meaning they have special + # rules that allow them to consume more stuff at the same indent + # level. These tables, however, are different. Turn off greedy to + # let the parser do its job. + self.table.is_greedy = False + self.parser.current.add_child(self.table) + self.parser.current = self.table + return True + + def parse_line_block(self, line): + if self.table is None: + return False + else: + if self.table is not self.parser.current: + self.table = None + return False + tr = mallard.ducktype.parser.Block('tr') + self.parser.current.add_child(tr) + cells = line.split(',') + for cell in cells: + td = mallard.ducktype.parser.Block('td') + tr.add_child(td) + tdp = mallard.ducktype.parser.Block('p') + td.add_child(tdp) + tdp.add_text(cell) + return True diff --git a/mallard/ducktype/extensions/docbook.py b/mallard/ducktype/extensions/docbook.py new file mode 100644 index 0000000..cb6ff23 --- /dev/null +++ b/mallard/ducktype/extensions/docbook.py @@ -0,0 +1,122 @@ +# Copyright (c) 2019 Shaun McCance +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +import mallard.ducktype + +NSDB = 'http://docbook.org/ns/docbook' + +# FIXME: change output file extension + +leafs = ('abbrev', 'acronym', 'address', 'arg', 'artpagenums', 'authorinitials', + 'bibliocoverage', 'biblioid', 'bibliomisc', 'bibliomixed', 'bibliomset', + 'bibliorelation', 'bibliosource', 'bridgehead', 'caption', 'citation', + 'classsynopsisinfo', 'command', 'confdates', 'confnum', 'confsponsor', + 'conftitle', 'contractnum', 'contractsponsor', 'contrib', 'date', + 'edition', 'email', 'exceptionname', 'firstname', 'funcdef', 'funcparams', + 'funcsynopsisinfo', 'givenname', 'glosssee', 'glossseealso', 'glossterm', + 'holder', 'honorific', 'initializer', 'issuenum', 'jobtitle', 'keyword', + 'lhs', 'lineage', 'link', 'literallayout', 'manvolnum', 'member', + 'methodname', 'modifier', 'msgaud', 'msglevel', 'msgorig', 'option', + 'orgdiv', 'orgname', 'othername', 'pagenums', 'para', 'paramdef', + 'parameter', 'personname', 'phrase', 'primary', 'primaryie', 'productname', + 'productnumber', 'programlisting', 'pubdate', 'publishername', 'quote', + 'refclass', 'refdescriptor', 'refentrytitle', 'refmiscinfo', 'refname', + 'refpurpose', 'releaseinfo', 'remark', 'replaceable', 'revnumber', + 'revremark', 'rhs', 'screen', 'secondary', 'secondaryie', 'see', + 'seealso', 'seealsoie', 'seeie', 'seg', 'segtitle', 'seriesvolnums', + 'shortaffil', 'simpara', 'subjectterm', 'subtitle', 'surname', + 'synopfragmentref', 'synopsis', 'term', 'tertiary', 'tertiaryie', + 'title', 'titleabbrev', 'tocentry', 'type', 'uri', 'varname', + 'volumenum', 'year') + +class DocBookNodeFactory(mallard.ducktype.parser.NodeFactory): + def __init__(self, parser): + super().__init__(parser) + self.id_attribute = 'xml:id' + + def create_block_node(self, name, outer): + node = mallard.ducktype.parser.Block(name, outer=outer, parser=self.parser) + if name in leafs: + node.is_leaf = True + return node + + def create_block_paragraph_node(self, outer): + return self.create_block_node('para', outer=outer) + + def create_info_node(self, name, outer): + node = mallard.ducktype.parser.Info(name, outer=outer, parser=self.parser) + if name in leafs: + node.is_leaf = True + return node + + def create_info_paragraph_node(self, outer): + return self.create_info_node('para', outer=outer) + + def handle_division_title(self, depth, inner): + name = 'article' if (depth == 1) else 'section' + page = mallard.ducktype.parser.Division(name, depth=depth, parser=self.parser) + title = mallard.ducktype.parser.Block('title', inner=inner, parser=self.parser) + self.parser.current.add_child(page) + page.add_child(title) + self.parser.current = title + + def handle_info_container(self, outer): + info = mallard.ducktype.parser.Block('info', outer=outer, parser=self.parser) + self.parser.current.add_child(info) + self.parser.current.info = info + info.parent = self.parser.current + + def handle_block_item_content(self, outer, inner): + # bibliolist + # calloutlist/callout + # glosslist + # FIXME: procedure/step substeps/step + # qandaset + # segmentedlist + # simplelist + # tocentry + # variablelist + if self.parser.current.is_name(('itemizedlist', 'orderedlist')): + item = mallard.ducktype.parser.Block('listitem', outer=outer, inner=inner, parser=self.parser) + self.parser.current.add_child(item) + self.parser.current = item + return item + else: + node = mallard.ducktype.parser.Block('itemizedlist', outer=outer, parser=self.parser) + self.parser.current.add_child(node) + item = mallard.ducktype.parser.Block('listitem', outer=outer, inner=inner, parser=self.parser) + node.add_child(item) + self.parser.current = item + return item + +class DocBookExtension(mallard.ducktype.parser.ParserExtension): + def __init__(self, parser, prefix, version): + if version == 'experimental': + self.version = version + else: + raise mallard.ducktype.parser.SyntaxError( + 'Unsupported docbook extension version: ' + version, + parser) + self.parser = parser + self.prefix = prefix + self.version = version + self.parser.document.default_namespace = NSDB + + parser.factory = DocBookNodeFactory(parser) diff --git a/mallard/ducktype/extensions/if.py b/mallard/ducktype/extensions/if.py new file mode 100644 index 0000000..46cbd11 --- /dev/null +++ b/mallard/ducktype/extensions/if.py @@ -0,0 +1,76 @@ +# Copyright (c) 2018 Shaun McCance +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +import mallard.ducktype + +IFURI = 'http://projectmallard.org/if/1.0/' + +class IfExtension(mallard.ducktype.parser.ParserExtension): + def __init__(self, parser, prefix, version): + if version == 'experimental': + self.version = version + else: + raise mallard.ducktype.parser.SyntaxError( + 'Unsupported if extension version: ' + version, + parser) + self.parser = parser + self.prefix = prefix + self.version = version + self.parser.document.add_namespace('if', IFURI) + + def parse_line_block(self, line): + indent = mallard.ducktype.parser.DuckParser.get_indent(line) + iline = line[indent:] + + if iline.strip() == '??': + self.parser.push_text() + self.parser.unravel_for_block(indent) + + if self.parser.current.is_name('choose', IFURI): + elname = 'if:else' + else: + elname = 'if:choose' + + qnode = mallard.ducktype.parser.Block(elname, indent, parser=self.parser) + self.parser.current.add_child(qnode) + self.parser.current = qnode + + self.parser.state = mallard.ducktype.parser.DuckParser.STATE_BLOCK_READY + return True + + if iline.startswith('? '): + self.parser.push_text() + self.parser.unravel_for_block(indent) + + if self.parser.current.is_name('choose', IFURI): + elname = 'if:when' + else: + elname = 'if:if' + + qnode = mallard.ducktype.parser.Block(elname, indent, parser=self.parser) + qnode.attributes = mallard.ducktype.parser.Attributes() + qnode.attributes.add_attribute('test', iline[2:].strip()) + self.parser.current.add_child(qnode) + self.parser.current = qnode + + self.parser.state = mallard.ducktype.parser.DuckParser.STATE_BLOCK_READY + return True + + return False diff --git a/mallard/ducktype/parser.py b/mallard/ducktype/parser.py new file mode 100644 index 0000000..2e536d1 --- /dev/null +++ b/mallard/ducktype/parser.py @@ -0,0 +1,1791 @@ +# Copyright (c) 2014-2019 Shaun McCance +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +import collections +import importlib +import inspect +import os +import sys +import urllib.parse + +from . import entities + + +def FIXME(msg=None): + if msg is not None: + print('FIXME: %s' % msg) + else: + print('FIXME') + +def _escape_xml_attr(s): + return s.replace('&', '&').replace('<', '<').replace('"', '"') + +def _escape_xml(s): + return s.replace('&', '&').replace('<', '<') + +_escaped_chars = '$*=-.@[]()"\'' + + +class Attributes: + def __init__(self): + self._attrlist = [] + self._attrvals = {} + + def add_attribute(self, key, value): + if key not in self._attrlist: + self._attrlist.append(key) + if key in ('style', 'type'): + self._attrvals.setdefault(key, []) + self._attrvals[key].append(value) + else: + self._attrvals[key] = value + + def get_attribute(self, key): + val = self._attrvals.get(key) + if isinstance(val, list): + return ' '.join(val) + else: + return val + + def get_attributes(self): + return self._attrlist + + def __contains__(self, item): + return item in self._attrlist + + def _write_xml(self, fd): + for attr in self._attrlist: + fd.write(' ' + attr + '="') + val = self._attrvals[attr] + if isinstance(val, list): + fd.write(' '.join([_escape_xml_attr(s) for s in val])) + else: + fd.write(_escape_xml_attr(val)) + fd.write('"') + + +class Directive: + def __init__(self, name): + self.name = name + self.content = '' + + def set_content(self, content): + self.content = content + + @staticmethod + def parse_line(line, parser): + i = 1 + while i < len(line): + if line[i].isspace(): + break + i += 1 + if i == 1: + raise SyntaxError('Directive must start with a name', parser) + directive = Directive(line[1:i]) + directive.set_content(line[i:].lstrip().rstrip('\n')) + return directive + + +class Node: + def __init__(self, name, outer=0, inner=None, parser=None, linenum=None, extensions=False): + self.name = name + self.nsprefix = None + self.nsuri = None + self.localname = name + self.default_namespace = None + self.extension = None + self.is_external = False + if ':' in name: + self.nsprefix = name[:name.index(':')] + self.nsuri = parser.document.get_namespace(self.nsprefix) + self.localname = self.name[len(self.nsprefix)+1:] + if self.nsuri is not None and not self.nsuri.startswith('http://projectmallard.org/'): + self.is_external = True + if extensions and parser is not None: + if self.nsprefix in parser.extensions_by_module: + self.extension = self.nsprefix + if self.extension is None: + if self.nsuri is None: + if self.nsprefix == 'xml': + pass + elif self.nsprefix == 'its': + parser.document.add_namespace('its', 'http://www.w3.org/2005/11/its') + else: + raise SyntaxError('Unrecognized namespace prefix: ' + self.nsprefix, + parser) + else: + self.localname = name + self.outer = outer + if inner is None: + self.inner = outer + else: + self.inner = inner + self.info = None + self.children = [] + self.attributes = None + self.is_verbatim = (name in ('screen', 'code')) + self.is_list = (name in ('list', 'steps', 'terms', 'tree')) + self.is_greedy = self.is_name(( + 'list', 'steps', 'terms', 'tree', + 'table', 'thead', 'tfoot', 'tbody', 'tr')) + self._is_leaf = None + self.linenum = linenum + if self.linenum is None and parser is not None: + self.linenum = parser.linenum + self._namespaces = collections.OrderedDict() + self._definitions = {} + self._parent = None + self._softbreak = False # Help keep out pesky trailing newlines + + def is_name(self, localname, nsuri=None): + if nsuri in (None, 'http://projectmallard.org/1.0/'): + if self.nsuri not in (None, 'http://projectmallard.org/1.0/'): + return False + else: + if nsuri != self.nsuri: + return False + + if isinstance(localname, (list, tuple)): + for name in localname: + if name == self.localname: + return True + return False + else: + return localname == self.localname + + @property + def is_leaf(self): + if self._is_leaf is not None: + return self._is_leaf + leafs = ('p', 'screen', 'code', 'title', 'subtitle', 'desc', 'cite', 'name', 'email', 'years') + if self.is_name(leafs): + return True + if self.nsprefix is not None: + if self.nsuri is None: + return False + if self.nsuri == 'http://projectmallard.org/1.0/': + return self.localname in leafs + return False + + @is_leaf.setter + def is_leaf(self, is_leaf): + self._is_leaf = is_leaf + + @property + def is_tree_item(self): + if not self.is_name('item'): + return False + cur = self + while cur.is_name('item'): + cur = cur.parent + if cur.is_name('tree'): + return True + return False + + @property + def has_tree_items(self): + if self.is_tree_item: + for item in self.children: + if isinstance(item, Node) and item.is_name('item'): + return True + return False + + @property + def is_external_leaf(self): + if not self.is_external: + return False + if len(self.children) == 0: + return False + if isinstance(self.children[0], str) or isinstance(self.children[0], Inline): + return True + return False + + @property + def is_empty(self): + return len(self.children) == 0 and self.info is None + + @property + def available(self): + for child in self.children: + if not child.is_name(('info', 'title', 'desc', 'cite')): + return False + return True + + @property + def parent(self): + return self._parent + + @parent.setter + def parent(self, node): + self._parent = node + + def add_child(self, child): + if isinstance(child, str): + self.add_text(child) + return + if self._softbreak: + if len(self.children) > 0: + self.children[-1] += '\n' + self._softbreak = False + self.children.append(child) + child.parent = self + + def insert_child(self, index, child): + self.children.insert(index, child) + child.parent = self + + def add_text(self, text): + # We don't add newlines when we see them. Instead, we record that + # we saw one with _softbreak and output the newline if we add + # something afterwards. This prevents pesky trailing newlines on + # text in block elements. But we only do newline mangling at the + # block parse phase, so don't bother if self is an Inline. + if self._softbreak: + if len(self.children) > 0: + self.children[-1] += '\n' + self._softbreak = False + if not isinstance(self, Inline) and text.endswith('\n'): + text = text[:-1] + self._softbreak = True + if len(self.children) > 0 and isinstance(self.children[-1], str): + self.children[-1] += text + else: + self.children.append(text) + + def add_namespace(self, prefix, uri): + self._namespaces[prefix] =uri + + def get_namespace(self, prefix): + uri = self._namespaces.get(prefix) + if uri is not None: + return uri + if self._parent is not None: + return self._parent.get_namespace(prefix) + return None + + def add_definition(self, name, value): + self._definitions[name] = value + + def write_xml(self, outfile=None): + close = False + if outfile is None: + fd = sys.stdout + elif isinstance(outfile, str): + close = True + fd = open(outfile, 'w', encoding='utf-8') + else: + fd = outfile + self._write_xml(fd) + if close: + fd.close() + + def _write_xml(self, fd, *, depth=0, verbatim=False): + verbatim = verbatim or self.is_verbatim + if not isinstance(self, Inline): + fd.write(' ' * depth) + fd.write('<' + self.name) + if self.default_namespace is not None: + fd.write(' xmlns="' + self.default_namespace + '"') + for prefix in self._namespaces: + fd.write(' xmlns:' + prefix + '="' + self._namespaces[prefix] + '"') + if self.attributes is not None: + self.attributes._write_xml(fd) + if self.is_empty: + if isinstance(self, Inline): + fd.write('/>') + else: + fd.write('/>\n') + elif (isinstance(self.children[0], Block) or + isinstance(self.children[0], Info) ): + fd.write('>\n') + else: + fd.write('>') + + for i in range(len(self.children)): + child = self.children[i] + if isinstance(child, Inline): + child._write_xml(fd, depth=depth, verbatim=verbatim) + elif isinstance(child, Fence): + child._write_xml(fd, depth=depth, verbatim=verbatim) + if i + 1 < len(self.children): + fd.write('\n') + elif isinstance(child, Node): + child._write_xml(fd, depth=depth+1, verbatim=verbatim) + else: + if i > 0 and isinstance(self.children[i-1], Fence) and not verbatim: + fd.write(' ' * depth) + if '\n' in child: + nl = child.find('\n') + while nl >= 0: + if nl + 1 == len(child) and i + 1 == len(self.children): + fd.write(_escape_xml(child[:nl])) + elif verbatim or (nl + 1 < len(child) and child[nl + 1] == '\n'): + fd.write(_escape_xml(child[:nl]) + '\n') + elif self.is_tree_item: + fd.write(_escape_xml(child[:nl]) + '\n') + if nl + 1 < len(child): + fd.write(' ' * (depth + 1)) + else: + fd.write(_escape_xml(child[:nl]) + '\n' + (' ' * depth)) + child = child[nl + 1:] + nl = child.find('\n') + if child != '': + fd.write(_escape_xml(child)) + else: + fd.write(_escape_xml(child)) + if not self.is_empty: + leafy = self.is_leaf or self.is_external_leaf + for child in self.children: + if isinstance(child, (Block, Info)): + leafy = False + break + if isinstance(self, Inline): + fd.write('') + elif leafy: + fd.write('\n') + elif self.is_tree_item: + if self.has_tree_items: + fd.write((' ' * depth) + '\n') + else: + fd.write('\n') + else: + fd.write((' ' * depth) + '\n') + + +class Document(Node): + def __init__(self, parser=None): + Node.__init__(self, '_', parser=parser) + self.divdepth = 0 + self.default_namespace = 'http://projectmallard.org/1.0/' + + def _write_xml(self, fd, *args, depth=0, verbatim=False): + if len(self.children) == 1: + fd.write('\n') + for child in self.children: + if child.default_namespace is None: + child.default_namespace = self.default_namespace + for ns in self._namespaces: + child.add_namespace(ns, self._namespaces[ns]) + child._write_xml(fd) + + +class Division(Node): + def __init__(self, name, depth, **kwargs): + Node.__init__(self, name, **kwargs) + self.divdepth = depth + + +class Block(Node): + pass + + +class Info(Node): + pass + + +class Inline(Node): + pass + + +class Fence(Node): + def add_line(self, line): + self.add_text(line) + return + indent = DuckParser.get_indent(line) + if len(self.children) == 0: + self.inner = indent + self.children.append('') + self.children[0] += line[min(indent, self.inner):] + if not line.endswith('\n'): + self.children[0] += '\n' + + def _write_xml(self, fd, *, depth=0, verbatim=False): + lines = self.children[0].split('\n') + trim = min(self.inner, DuckParser.get_indent(lines[0])) + for i in range(len(lines)): + line = lines[i] + indent = DuckParser.get_indent(line) + if i != 0: + fd.write('\n') + fd.write(_escape_xml(line[min(indent, trim):])) + + +class NodeFactory: + def __init__(self, parser): + self.parser = parser + self.id_attribute = 'id' + + def create_info_node(self, name, outer): + node = Info(name, outer=outer, parser=self.parser, extensions=True) + return node + + def create_info_paragraph_node(self, outer): + node = Info('p', outer=outer, parser=self.parser) + return node + + def create_block_node(self, name, outer): + node = Block(name, outer=outer, parser=self.parser, extensions=True) + return node + + def create_block_paragraph_node(self, outer): + node = Block('p', outer=outer, parser=self.parser) + return node + + def handle_division_title(self, depth, inner): + name = 'page' if (depth == 1) else 'section' + page = Division(name, depth=depth, parser=self.parser) + title = Block('title', inner=inner, parser=self.parser) + self.parser.current.add_child(page) + page.add_child(title) + self.parser.current = title + + def handle_division_subtitle(self, depth, inner): + node = Block('subtitle', inner=inner, parser=self.parser) + self.parser.current.add_child(node) + self.parser.current = node + + def handle_info_container(self, outer): + info = Block('info', outer=outer, parser=self.parser) + self.parser.current.insert_child(0, info) + self.parser.current.info = info + info.parent = self.parser.current + + def handle_block_title(self, outer, inner): + # For lines starting with '. '. Creates a block title. + title = Block('title', outer, inner, parser=self.parser) + self.parser.current.add_child(title) + self.parser.current = title + + def handle_block_item_title(self, outer, inner): + # For lines starting with '- '. It might be a th element, + # or it might be a title in a terms item. It might also + # start a terms element. + if self.parser.current.is_name('tr'): + node = Block('th', outer, inner, parser=self.parser) + self.parser.current.add_child(node) + self.parser.current = node + return + + if not self.parser.current.is_name('terms'): + node = Block('terms', outer, parser=self.parser) + self.parser.current.add_child(node) + self.parser.current = node + # By now we've unwound to the terms element. If the preceding + # block was a title, then the last item will have only title + # elements, and we just keep appending there. + if (not self.parser.current.is_empty + and isinstance(self.parser.current.children[-1], Block) + and self.parser.current.children[-1].is_name('item')): + item = self.parser.current.children[-1] + if (not item.is_empty + and isinstance(self.parser.current.children[-1], Block) + and item.children[-1].is_name('title')): + self.parser.current = item + if not self.parser.current.is_name('item'): + item = Block('item', outer, inner, parser=self.parser) + self.parser.current.add_child(item) + self.parser.current = item + title = Block('title', outer, inner, parser=self.parser) + self.parser.current.add_child(title) + self.parser.current = title + + def handle_block_item_content(self, outer, inner): + # For lines starting with '* '. It might be a td element, + # it might be an item element in a list or steps, it might + # be a tree item, or it might start the content of an item + # in a terms. It might also start a list element. + if self.parser.current.is_name('tr'): + node = Block('td', outer=outer, inner=inner, parser=self.parser) + self.parser.current.add_child(node) + self.parser.current = node + return node + elif self.parser.current.is_name('terms'): + # All the logic above will have unraveled us from the item + # created by the title, so we have to step back into it. + if self.parser.current.is_empty or not self.parser.current.children[-1].is_name('item'): + raise SyntaxError('Missing item title in terms', self.parser) + self.parser.current = self.parser.current.children[-1] + return self.parser.current + elif self.parser.current.is_name('tree') or self.parser.current.is_tree_item: + item = Block('item', outer=outer, inner=inner, parser=self.parser) + self.parser.current.add_child(item) + self.parser.current = item + return item + elif self.parser.current.is_name(('list', 'steps')): + item = Block('item', outer=outer, inner=inner, parser=self.parser) + self.parser.current.add_child(item) + self.parser.current = item + return item + else: + node = Block('list', outer=outer, parser=self.parser) + self.parser.current.add_child(node) + item = Block('item', outer=outer, inner=inner, parser=self.parser) + node.add_child(item) + self.parser.current = item + return item + + +class SyntaxError(Exception): + def __init__(self, message, parser): + self.message = message + self.parser = parser + self.filename = parser.filename if parser else None + self.linenum = parser.linenum if parser else None + self.fullmessage = '' + if self.filename is not None: + self.fullmessage += os.path.basename(self.filename) + if self.linenum is not None: + self.fullmessage += ':' + str(self.linenum) + self.fullmessage += ': ' + self.fullmessage += self.message + + +class ParserExtension: + def __init__(self, parser, prefix, version): + pass + + def parse_line_block(self, line): + return False + + def take_directive(self, directive): + return False + + def take_block_node(self, node): + return False + + +class InlineParser: + def __init__(self, parent, linenum=1): + # Dummy node just to hold children while we parse + self.current = Inline('_', linenum=linenum) + self.document = parent.document + self.filename = parent.filename + self.linenum = linenum + self._parent = parent + + def lookup_entity(self, entity): + return self._parent.lookup_entity(entity) + + def parse_text(self, text): + self._parse_text(text) + while self.current.parent is not None: + self.current = self.current.parent + return self.current.children + + def _parse_text(self, text): + start = cur = 0 + parens = [] + while cur < len(text): + if self.current.parent is not None and text[cur] == ')': + if len(parens) > 0 and parens[-1] > 0: + parens[-1] -= 1 + cur += 1 + else: + self.current.add_text(text[start:cur]) + self.current = self.current.parent + parens.pop() + cur += 1 + start = cur + elif self.current.parent is not None and text[cur] == '(': + parens[-1] += 1 + cur += 1 + elif cur == len(text) - 1: + cur += 1 + self.current.add_text(text[start:cur]) + elif text[cur] == '$' and text[cur + 1] in _escaped_chars: + self.current.add_text(text[start:cur]) + self.current.add_text(text[cur + 1]) + cur += 2 + start = cur + elif text[cur] == '$' and _isnmtoken(text[cur + 1]): + end = cur + 1 + while end < len(text): + if not _isnmtoken(text[end]): + break + end += 1 + if end == len(text): + self.current.add_text(text[start:end]) + cur = end + elif text[end] == ';': + self.current.add_text(text[start:cur]) + entname = text[cur + 1:end] + entval = self._parent.lookup_entity(entname) + if entval is not None: + parser = InlineParser(self, + linenum=self.current.linenum) + for child in parser.parse_text(entval): + if isinstance(child, str): + self.current.add_text(child) + else: + self.current.add_child(child) + else: + raise SyntaxError('Unrecognized entity: ' + entname, self) + start = cur = end + 1 + elif text[end] == '[': + self.current.add_text(text[start:cur]) + node = Inline(text[cur + 1:end], parser=self) + self.current.add_child(node) + attrparser = AttributeParser(self) + attrparser.parse_line(text[end + 1:]) + if not attrparser.finished: + # We know we have all the text there could be, + # so this an unclosed attribute list. Do we make + # that an error, auto-close, or decide this was + # never really markup after all? + FIXME('unclosed attribute list') + node.attributes = attrparser.attributes + self.linenum = attrparser.linenum + start = cur = len(text) - len(attrparser.remainder) + if cur < len(text) and text[cur] == '(': + self.current = node + parens.append(0) + start = cur = cur + 1 + elif text[end] == '(': + self.current.add_text(text[start:cur]) + node = Inline(text[cur + 1:end], parser=self) + self.current.add_child(node) + self.current = node + parens.append(0) + start = cur = end + 1 + else: + cur = end + else: + if text[cur] == '\n': + self.linenum += 1 + cur += 1 + + +class AttributeParser: + def __init__(self, parent, node=None): + self.remainder = '' + self.node = node + self.attributes = Attributes() + self.finished = False + self.filename = parent.filename + self.linenum = parent.linenum + self._quote = None + self._value = '' + self._attrname = None + self._parent = parent + + def lookup_entity(self, entity): + return self._parent.lookup_entity(entity) + + def parse_value(self, text): + retval = '' + start = cur = 0 + while cur < len(text): + if text[cur] == '$': + if cur == len(text) - 1: + cur += 1 + retval += text[start:cur] + start = cur + elif text[cur] == '$' and text[cur + 1] in _escaped_chars: + retval += text[start:cur] + retval += text[cur + 1] + cur += 2 + start = cur + elif text[cur] == '$' and _isnmtoken(text[cur + 1]): + end = cur + 1 + while end < len(text): + if not _isnmtoken(text[end]): + break + end += 1 + if end == len(text): + retval += text[start:end] + start = cur = end + elif text[end] == ';': + retval += text[start:cur] + start = cur + entname = text[cur + 1:end] + entval = self.lookup_entity(entname) + if entval is not None: + parser = AttributeParser(self) + retval += parser.parse_value(entval) + else: + raise SyntaxError('Unrecognized entity: ' + entname, self) + start = cur = end + 1 + else: + cur = end + else: + cur += 1 + else: + if text[cur] == '\n': + self.linenum += 1 + cur += 1 + if cur != start: + retval += text[start:cur] + return retval + + def parse_line(self, line): + i = 0 + while i < len(line) and not self.finished: + if self._quote is not None: + j = i + while j < len(line): + if line[j] == '$': + # Will be parsed later. Just skip the escaped quote + # char so it doesn't close the attribute value. + if j + 1 < len(line) and line[j] in _escaped_chars: + j += 2 + else: + j += 1 + elif line[j] == self._quote: + self._value += line[i:j] + self._value = self.parse_value(self._value) + self.attributes.add_attribute(self._attrname, self._value) + self._value = '' + self._quote = None + i = j + break + else: + j += 1 + if self._quote is not None: + self._value += line[i:j] + i = j + 1 + elif line[i].isspace(): + if line[i] == '\n': + self.linenum += 1 + i += 1 + elif line[i] == ']': + self.finished = True + self.remainder = line[i + 1:] + elif line[i] in ('.', '#', '>'): + j = i + 1 + while j < len(line): + if line[j].isspace() or line[j] == ']': + break + j += 1 + word = self.parse_value(line[i + 1:j]) + if line[i] == '>': + if len(line) > i + 1 and line[i + 1] == '>': + self.attributes.add_attribute('href', word[1:]) + else: + self.attributes.add_attribute('xref', word) + elif line[i] == '.': + self.attributes.add_attribute('style', word) + else: + self.attributes.add_attribute('id', word) + i = j + else: + j = i + while j < len(line) and _isnmtoken(line[j]): + j += 1 + word = line[i:j] + if line[j] == '=' and word != '': + if ':' in word: + nsprefix, localname = word.split(':', maxsplit=1) + nsuri = self._parent.document.get_namespace(nsprefix) + if nsuri is None: + if nsprefix == 'xml': + pass + elif nsprefix == 'its': + self._parent.document.add_namespace('its', 'http://www.w3.org/2005/11/its') + else: + raise SyntaxError('Unrecognized namespace prefix: ' + nsprefix, + self) + if line[j + 1] in ('"', "'"): + self._quote = line[j + 1] + self._value = '' + i = j + 2 + self._attrname = word + else: + k = j + 1 + while k < len(line): + if line[k].isspace() or line[k] == ']': + break + k += 1 + value = self.parse_value(line[j + 1:k]) + self.attributes.add_attribute(word, value) + i = k + elif line[j].isspace() or line[j] == ']': + value = self.parse_value(line[i:j]) + self.attributes.add_attribute('type', value) + i = j + else: + raise SyntaxError('Invalid character ' + line[j] + + ' in attribute list', self) + + +class DirectiveIncludeParser: + def __init__(self, parent): + self.parent = parent + self.document = parent.document + self.extensions = [] + self.extensions_by_module = {} + self._start = True + self._comment = False + + def parse_file(self, filename): + self.filename = filename + self.absfilename = os.path.join(os.path.dirname(self.parent.absfilename), + filename) + if isinstance(self.parent, DuckParser): + self._parentfiles = [self.parent.absfilename, self.absfilename] + else: + self._parentfiles = self.parent._parentfiles + [self.absfilename] + self.linenum = 0 + try: + fd = open(self.absfilename, encoding='utf-8') + except: + raise SyntaxError('Missing included file ' + filename, self.parent) + for line in fd: + self.parse_line(line) + fd.close() + + def parse_line(self, line): + self.linenum += 1 + + if self._comment: + if line.strip() == '--]': + self._comment = False + return + indent = DuckParser.get_indent(line) + iline = line[indent:] + if iline.startswith('[-]'): + return + elif iline.startswith('[--'): + self._comment = True + return + + if line.strip() == '': + return + if not(line.startswith('@')): + raise SyntaxError('Directive includes can only include directives', self) + self._parse_line(line) + + def take_directive(self, directive): + if directive.name.startswith('ducktype/'): + if not self._start: + raise SyntaxError('Ducktype declaration must be first', self) + if directive.name != 'ducktype/1.0': + raise SyntaxError( + 'Unsupported ducktype version: ' + directive.name , + self) + for value in directive.content.split(): + try: + prefix, version = value.split('/', maxsplit=1) + extmod = importlib.import_module('mallard.ducktype.extensions.' + prefix) + for extclsname, extcls in inspect.getmembers(extmod, inspect.isclass): + if issubclass(extcls, ParserExtension): + extension = extcls(self, prefix, version) + self.extensions.append(extension) + self.extensions_by_module.setdefault(prefix, []) + self.extensions_by_module[prefix].append(extension) + except SyntaxError as e: + raise e + except: + raise SyntaxError( + 'Unsupported ducktype extension: ' + value, + self) + elif ':' in directive.name: + prefix, name = directive.name.split(':', maxsplit=1) + if prefix not in self.extensions_by_module: + raise SyntaxError('Unrecognized directive prefix: ' + prefix, self) + for extension in self.extensions_by_module[prefix]: + if extension.take_directive(directive): + return + raise SyntaxError('Unrecognized directive: ' + directive.name, self) + elif directive.name == 'define': + try: + self.parent.take_directive(directive) + except SyntaxError as e: + raise SyntaxError(e.message, self) + elif directive.name == 'encoding': + FIXME('encoding') + elif directive.name == 'include': + if ' ' in directive.content: + raise SyntaxError('Multiple values in include. URL encode file name?', self) + relfile = urllib.parse.unquote(directive.content) + absfile = os.path.join(os.path.dirname(self.absfilename), relfile) + if absfile in self._parentfiles: + raise SyntaxError('Recursive include detected: ' + directive.content, self) + incparser = DirectiveIncludeParser(self) + incparser.parse_file(relfile) + elif directive.name == 'namespace': + try: + self.parent.take_directive(directive) + except SyntaxError as e: + raise SyntaxError(e.message, self) + else: + raise SyntaxError('Unrecognized directive: ' + directive.name, self) + self._start = False + + def _parse_line(self, line): + directive = Directive.parse_line(line, self) + self.take_directive(directive) + + +class DuckParser: + STATE_START = 1 + STATE_TOP = 2 + STATE_HEADER = 3 + STATE_HEADER_POST = 4 + STATE_SUBHEADER = 5 + STATE_SUBHEADER_POST = 6 + STATE_HEADER_ATTR = 7 + STATE_HEADER_ATTR_POST = 8 + STATE_HEADER_INFO = 9 + STATE_BLOCK = 10 + STATE_BLOCK_ATTR = 11 + STATE_BLOCK_READY = 12 + STATE_BLOCK_INFO = 13 + + INFO_STATE_NONE = 101 + INFO_STATE_INFO = 102 + INFO_STATE_READY = 103 + INFO_STATE_BLOCK = 104 + INFO_STATE_ATTR = 105 + + def __init__(self): + self.state = DuckParser.STATE_START + self.info_state = DuckParser.INFO_STATE_NONE + self.linenum = 0 + self.document = Document(parser=self) + self.current = self.document + self.curinfo = None + self.extensions = [] + self.extensions_by_module = {} + self.factory = NodeFactory(self) + + self._text = '' + self._attrparser = None + self._defaultid = None + self._comment = False + self._fenced = False + self._fragments = False + + @staticmethod + def get_indent(line): + for i in range(len(line)): + if line[i] != ' ': + return i + return 0 + + def lookup_entity(self, entity): + cur = self.current + while cur is not None: + if entity in cur._definitions: + return cur._definitions[entity] + cur = cur.parent + if entity in entities.entities: + return entities.entities[entity] + else: + # Try to treat it as a hex numeric reference + hexnum = 0 + for c in entity: + if c in '0123456789': + hexnum = hexnum * 16 + (ord(c) - 48) + elif c in 'abcdef': + hexnum = hexnum * 16 + (ord(c) - 87) + elif c in 'ABCDEF': + hexnum = hexnum * 16 + (ord(c) - 55) + else: + hexnum = None + break + if hexnum is not None: + return chr(hexnum) + return None + + def parse_file(self, filename): + self.filename = filename + self.absfilename = os.path.abspath(filename) + self._defaultid = os.path.basename(filename) + if self._defaultid.endswith('.duck'): + self._defaultid = self._defaultid[:-5] + fd = open(filename, encoding='utf-8') + for line in fd: + self.parse_line(line) + fd.close() + + def parse_inline(self, node=None): + if node is None: + node = self.document + oldchildren = node.children + node.children = [] + if node.info is not None: + self.parse_inline(node.info) + for child in oldchildren: + if isinstance(child, str): + parser = InlineParser(self, linenum=node.linenum) + for c in parser.parse_text(child): + node.add_child(c) + elif isinstance(child, Fence): + node.add_child(child) + else: + self.parse_inline(child) + node.add_child(child) + + def take_directive(self, directive): + if directive.name.startswith('ducktype/'): + if self.state != DuckParser.STATE_START: + raise SyntaxError('Ducktype declaration must be first', self) + if directive.name != 'ducktype/1.0': + raise SyntaxError( + 'Unsupported ducktype version: ' + directive.name , + self) + for value in directive.content.split(): + if value == '__future__/fragments': + self._fragments = True + continue + try: + prefix, version = value.split('/', maxsplit=1) + extmod = importlib.import_module('mallard.ducktype.extensions.' + prefix) + for extclsname, extcls in inspect.getmembers(extmod, inspect.isclass): + if issubclass(extcls, ParserExtension): + extension = extcls(self, prefix, version) + self.extensions.append(extension) + self.extensions_by_module.setdefault(prefix, []) + self.extensions_by_module[prefix].append(extension) + except SyntaxError as e: + raise e + except: + raise SyntaxError( + 'Unsupported ducktype extension: ' + value, + self) + elif ':' in directive.name: + prefix, name = directive.name.split(':', maxsplit=1) + if prefix not in self.extensions_by_module: + raise SyntaxError('Unrecognized directive prefix: ' + prefix, self) + for extension in self.extensions_by_module[prefix]: + if extension.take_directive(directive): + return + raise SyntaxError('Unrecognized directive: ' + directive.name, self) + elif directive.name == 'define': + values = directive.content.split(maxsplit=1) + if len(values) != 2: + raise SyntaxError( + 'Entity definition takes exactly two values', + self) + self.current.add_definition(*values) + elif directive.name == 'encoding': + FIXME('encoding') + elif directive.name == 'include': + if ' ' in directive.content: + raise SyntaxError('Multiple values in include. URL encode file name?', self) + relfile = urllib.parse.unquote(directive.content) + incparser = DirectiveIncludeParser(self) + incparser.parse_file(relfile) + elif directive.name == 'namespace': + values = directive.content.split(maxsplit=1) + if len(values) != 2: + raise SyntaxError( + 'Namespace declaration takes exactly two values', + self) + if values[0] == 'xml': + if values[1] != 'http://www.w3.org/XML/1998/namespace': + raise SyntaxError('Wrong value of xml namespace prefix', self) + if values[0] == 'its': + if values[1] != 'http://www.w3.org/2005/11/its': + raise SyntaxError('Wrong value of its namespace prefix', self) + self.current.add_namespace(*values) + else: + raise SyntaxError('Unrecognized directive: ' + directive.name, self) + + def finish(self): + if (self.state in (DuckParser.STATE_HEADER_ATTR, DuckParser.STATE_BLOCK_ATTR) or + self.info_state == DuckParser.INFO_STATE_ATTR): + raise SyntaxError('Unterminated block declaration', self) + self.push_text() + if self._defaultid is not None and len(self.document.children) == 1: + root = self.document.children[0] + if isinstance(root, Division): + if root.attributes is None: + root.attributes = Attributes() + idattr = self.factory.id_attribute + if idattr not in root.attributes: + root.attributes.add_attribute(idattr, self._defaultid) + self.parse_inline() + + def parse_line(self, line): + self.linenum += 1 + self._parse_line(line) + + def _parse_line(self, line): + # If we're inside a comment or a no-parse fence, nothing else matters. + if self._comment: + if line.strip() == '--]': + self._comment = False + return + if self._fenced: + if line.strip() == ']]]': + self._fenced = False + self.current = self.current.parent + else: + self.current.add_line(line) + return + + indent = DuckParser.get_indent(line) + iline = line[indent:] + + if iline.startswith('[-]'): + return + elif iline.startswith('[--'): + self._comment = True + return + elif self.info_state == DuckParser.INFO_STATE_INFO: + self._parse_line_info(line) + elif self.info_state == DuckParser.INFO_STATE_READY: + self._parse_line_info(line) + elif self.info_state == DuckParser.INFO_STATE_BLOCK: + self._parse_line_info(line) + elif self.info_state == DuckParser.INFO_STATE_ATTR: + self._parse_line_info_attr(line) + elif self.state == DuckParser.STATE_START: + self._parse_line_top(line) + elif self.state == DuckParser.STATE_TOP: + self._parse_line_top(line) + elif self.state == DuckParser.STATE_HEADER: + self._parse_line_header(line) + elif self.state == DuckParser.STATE_HEADER_POST: + self._parse_line_header_post(line) + elif self.state == DuckParser.STATE_SUBHEADER: + self._parse_line_subheader(line) + elif self.state == DuckParser.STATE_SUBHEADER_POST: + self._parse_line_subheader_post(line) + elif self.state == DuckParser.STATE_HEADER_ATTR: + self._parse_line_header_attr(line) + elif self.state == DuckParser.STATE_HEADER_ATTR_POST: + self._parse_line_header_attr_post(line) + elif self.state == DuckParser.STATE_HEADER_INFO: + self._parse_line_header_info(line) + elif self.state == DuckParser.STATE_BLOCK: + self._parse_line_block(line) + elif self.state == DuckParser.STATE_BLOCK_ATTR: + self._parse_line_block_attr(line) + elif self.state == DuckParser.STATE_BLOCK_READY: + self._parse_line_block_ready(line) + else: + FIXME('unknown state') + + def _parse_line_top(self, line): + if line.strip() == '': + self.state = DuckParser.STATE_TOP + elif line.startswith('@'): + self._parse_line_directive(line) + elif line.startswith('= '): + self.factory.handle_division_title(depth=1, inner=2) + self.set_text(line[2:]) + self.state = DuckParser.STATE_HEADER + elif line.strip().startswith('[') or line.startswith('=='): + if self._fragments == False: + raise SyntaxError('Missing page header', self) + self.state = DuckParser.STATE_BLOCK + self._parse_line(line) + else: + raise SyntaxError('Missing page header', self) + + def _parse_line_directive(self, line): + directive = Directive.parse_line(line, self) + self.take_directive(directive) + if self.state == DuckParser.STATE_START: + self.state == DuckParser.STATE_TOP + + def _parse_line_header(self, line): + indent = DuckParser.get_indent(line) + iline = line[indent:] + if iline.startswith('@'): + self.push_text() + self.current = self.current.parent + self.state = DuckParser.STATE_BLOCK + self.info_state = DuckParser.INFO_STATE_INFO + self._parse_line(line) + elif indent > 0 and iline.startswith('['): + self._parse_line_header_attr_start(line) + elif indent >= self.current.inner: + self.add_text(line[self.current.inner:]) + else: + self.push_text() + self.current = self.current.parent + self.state = DuckParser.STATE_HEADER_POST + self._parse_line(line) + + def _parse_line_header_post(self, line): + depth = self.current.divdepth + if line.startswith(('-' * depth) + ' '): + self.factory.handle_division_subtitle(depth=depth, inner=depth+1) + self.set_text(line[depth + 1:]) + self.state = DuckParser.STATE_SUBHEADER + elif line.lstrip().startswith('@'): + self.state = DuckParser.STATE_BLOCK + self.info_state = DuckParser.INFO_STATE_INFO + self._parse_line(line) + elif line.strip() == '': + self.state = DuckParser.STATE_HEADER_INFO + else: + self.state = DuckParser.STATE_BLOCK + self._parse_line(line) + + def _parse_line_subheader(self, line): + indent = DuckParser.get_indent(line) + iline = line[indent:] + if iline.startswith('@'): + self.push_text() + self.current = self.current.parent + self.state = DuckParser.STATE_BLOCK + self.info_state = DuckParser.INFO_STATE_INFO + self._parse_line(line) + elif indent > 0 and iline.startswith('['): + self._parse_line_header_attr_start(line) + elif indent >= self.current.inner: + self.add_text(line[self.current.inner:]) + else: + self.push_text() + self.current = self.current.parent + self.state = DuckParser.STATE_SUBHEADER_POST + self._parse_line(line) + + def _parse_line_subheader_post(self, line): + if line.lstrip().startswith('@'): + self.state = DuckParser.STATE_BLOCK + self.info_state = DuckParser.INFO_STATE_INFO + self._parse_line(line) + elif line.strip() == '': + self.state = DuckParser.STATE_HEADER_INFO + else: + self.state = DuckParser.STATE_BLOCK + self._parse_line(line) + + def _parse_line_header_attr_start(self, line): + indent = DuckParser.get_indent(line) + if indent > 0 and line[indent:].startswith('['): + self.push_text() + self.current = self.current.parent + self._attrparser = AttributeParser(self) + self._attrparser.parse_line(line[indent + 1:]) + if self._attrparser.finished: + self.current.attributes = self._attrparser.attributes + self.state = DuckParser.STATE_HEADER_ATTR_POST + self._attrparser = None + else: + self.state = DuckParser.STATE_HEADER_ATTR + else: + self.push_text() + self.current = self.current.parent + self.state = DuckParser.STATE_HEADER_ATTR_POST + self._parse_line(line) + + def _parse_line_header_attr(self, line): + self._attrparser.parse_line(line) + if self._attrparser.finished: + self.current.attributes = self._attrparser.attributes + self.state = DuckParser.STATE_HEADER_ATTR_POST + self._attrparser = None + + def _parse_line_header_attr_post(self, line): + if line.lstrip().startswith('@'): + self.state = DuckParser.STATE_BLOCK + self.info_state = DuckParser.INFO_STATE_INFO + self._parse_line(line) + elif line.strip() == '': + self.state = DuckParser.STATE_HEADER_INFO + else: + self.state = DuckParser.STATE_BLOCK + self._parse_line(line) + + def _parse_line_header_info(self, line): + if line.lstrip().startswith('@'): + self.state = DuckParser.STATE_BLOCK + self.info_state = DuckParser.INFO_STATE_INFO + self._parse_line(line) + elif line.strip() == '': + self.state = DuckParser.STATE_HEADER_INFO + else: + self.state = DuckParser.STATE_BLOCK + self._parse_line(line) + + def _parse_line_info(self, line): + if line.strip() == '': + # If the info elements weren't indented past the indent + # level of the parent and the parent is a block, blank + # line terminates info, because it must terminate the + # block according to block processing rules. + if (self.current.outer == self.current.inner and not isinstance(self.current, Division)): + self.push_text() + self.info_state = DuckParser.INFO_STATE_NONE + self._parse_line(line) + return + # If we're inside a leaf element like a paragraph, break + # out of that. Unless it's an indented verbatim element, + # in which case the newline is just part of the content. + if self.curinfo.is_leaf: + if (self.curinfo.is_verbatim and + self.curinfo.inner > self.curinfo.outer): + self.add_text('\n') + else: + self.push_text() + self.curinfo = self.curinfo.parent + self.info_state = DuckParser.INFO_STATE_INFO + return + + indent = DuckParser.get_indent(line) + if self.current.info is None: + self.factory.handle_info_container(indent) + self.curinfo = self.current.info + if indent < self.current.info.outer: + self.push_text() + self.info_state = DuckParser.INFO_STATE_NONE + self._parse_line(line) + return + iline = line[indent:] + if iline.startswith('@'): + self._parse_line_info_info(iline, indent) + else: + # Block content at the same (or less) indent level as the + # info elements doesn't belong to info. It starts the body. + if indent <= self.current.info.outer: + self.push_text() + self.info_state = DuckParser.INFO_STATE_NONE + self._parse_line(line) + return + self._parse_line_info_block(iline, indent) + + def _parse_line_info_info(self, iline, indent): + # Unlike block elements, info elements are never children of + # preceding info elements at the same indent level. Unravel + # as long as the current info's outer indent is the same. + if indent <= self.curinfo.outer: + self.push_text() + while indent <= self.curinfo.outer: + if self.curinfo == self.current.info: + break + self.curinfo = self.curinfo.parent + # First line after an @info declaration? Set inner indent. + if self.info_state == DuckParser.INFO_STATE_READY: + self.curinfo.inner = indent + self.info_state = DuckParser.INFO_STATE_INFO + + for j in range(1, len(iline)): + if not _isnmtoken(iline[j]): + break + name = iline[1:j] + node = self.factory.create_info_node(name, indent) + self.curinfo.add_child(node) + self.curinfo = node + + if iline[j] == '[': + self.info_state = DuckParser.INFO_STATE_ATTR + self._attrparser = AttributeParser(self) + self._parse_line_info_attr(iline[j + 1:]) + else: + remainder = iline[j:].lstrip() + if remainder != '': + if not self.curinfo.is_leaf: + pnode = self.factory.create_info_paragraph_node(self.curinfo.outer) + self.curinfo.add_child(pnode) + self.curinfo = pnode + self.set_text(remainder) + else: + self.info_state = DuckParser.INFO_STATE_READY + + def _parse_line_info_block(self, iline, indent): + # If we're already inside a leaf element, we only break out + # if the indent is less than the inner indent. For example: + # @p + # Inside of p + if self.curinfo.is_leaf or self.curinfo.is_external: + if indent < self.curinfo.inner: + self.push_text() + self.curinfo = self.curinfo.parent + # If we're not in a leaf, we need to create an implicit + # info paragraph, but only after breaking out to the + # level of the outer indent. For example: + # @foo + # Not inside of foo, and in implicit p + else: + if indent <= self.curinfo.outer: + self.push_text() + while indent <= self.curinfo.outer: + if self.curinfo == self.current.info: + break + self.curinfo = self.curinfo.parent + + # After all that unraveling, if we're not in a leaf or external, + # and only if we have real text to add, create an implicit p. + if iline.strip() != '' and not ( + self.curinfo.is_leaf or self.curinfo.is_external): + node = self.factory.create_info_paragraph_node(indent) + self.curinfo.add_child(node) + self.curinfo = node + + # First line after an @info declaration? Set inner indent. + if self.info_state == DuckParser.INFO_STATE_READY: + self.curinfo.inner = indent + self.info_state = DuckParser.INFO_STATE_BLOCK + + self.info_state = DuckParser.INFO_STATE_BLOCK + + self.add_text(iline) + + def _parse_line_info_attr(self, line): + self._attrparser.parse_line(line) + if self._attrparser.finished: + self.curinfo.attributes = self._attrparser.attributes + + remainder = self._attrparser.remainder.lstrip() + if remainder != '': + if not self.curinfo.is_leaf: + pnode = self.factory.create_info_paragraph_node(self.curinfo.outer) + self.curinfo.add_child(pnode) + self.curinfo = pnode + self.set_text(remainder) + self._attrparser = None + if self._text == '': + self.info_state = DuckParser.INFO_STATE_READY + else: + self.info_state = DuckParser.INFO_STATE_INFO + + def _parse_line_block(self, line): + # Blank lines close off elements that have inline content (leaf) + # unless they're verbatim elements that have an inner indent. Only + # decreasing indent can break free of those. They also break out of + # unindented block container elements, except for a set of special + # elements that take lists of things instead of general blocks. + if line.strip() == '': + if self.current.is_leaf: + if (self.current.is_verbatim and + self.current.inner > self.current.outer): + self.add_text('\n') + else: + self.push_text() + self.current = self.current.parent + while self.current.inner == self.current.outer: + if isinstance(self.current, (Division, Document)): + break + if self.current.is_greedy: + break + if self.current.is_leaf: + self.push_text() + self.current = self.current.parent + return + + sectd = 0 + if line.startswith('=='): + i = 0 + while i < len(line) and line[i] == '=': + i += 1 + if i < len(line) and line[i] == ' ': + sectd = i + if sectd > 0: + self.push_text() + while not isinstance(self.current, (Division, Document)): + self.current = self.current.parent + while self.current.divdepth >= sectd: + self.current = self.current.parent + if sectd != self.current.divdepth + 1: + if isinstance(self.current, Document) and ( + self._fragments and( + len(self.current.children) == 0 or + sectd == self.current.children[0].divdepth)): + pass + else: + raise SyntaxError('Incorrect section depth', self) + self.factory.handle_division_title(depth=sectd, inner=sectd+1) + self.set_text(line[sectd + 1:]) + self.state = DuckParser.STATE_HEADER + return + + # If the indent is less than what we can append to the current + # node, unravel until we're at the same indent level. Note that + # this still might not be the right level. We may or may not be + # able to add children to a block at the same indent, but we'll + # handle that later, because it depends on stuff. We don't use + # unravel, because that always breaks out of leafs, and at this + # point we might still be adding text to a leaf. + indent = DuckParser.get_indent(line) + if indent < self.current.inner: + self.push_text() + while self.current.inner > indent: + if isinstance(self.current, (Division, Document)): + break + self.current = self.current.parent + + if self.current.is_verbatim: + iline = line[self.current.inner:] + else: + iline = line[indent:] + + # [[[ starts a no-parse fence that ends with ]]], either at the + # end of this line, or on its own line later. This just suppresses + # block and inline parsing. It has no additional semantics. So if + # we're not already in a leaf element, create a paragraph just as + # we would do if we encountered normal text. + if iline.startswith('[[['): + self.push_text() + node = Fence('_', indent, parser=self) + + if not (self.current.is_leaf or self.current.is_external or + (self.current.is_tree_item and not self.current.has_tree_items)): + if self.current.is_tree_item: + while self.current.is_name(('tree', 'item')): + self.current = self.current.parent + while self.current.outer == indent and not self.current.available: + if isinstance(self.current, (Division, Document)): + break + self.current = self.current.parent + pnode = self.factory.create_block_paragraph_node(indent) + self.current.add_child(pnode) + pnode.add_child(node) + else: + self.current.add_child(node) + + sline = iline.strip()[3:] + if sline.endswith(']]]'): + node.inner = 0 + node.add_line(sline[:-3] + '\n') + else: + if sline.strip() != '': + node.inner = 0 + node.add_line(sline + '\n') + self.current = node + self._fenced = True + return + + # Give all extensions a shot at this line. If any of them handles + # the line (returns True), we're done. + for extension in self.extensions: + if extension.parse_line_block(line): + return + + if iline.startswith('['): + # Start a block with a standard block declaration. + self.push_text() + + for j in range(1, len(iline)): + if not _isnmtoken(iline[j]): + break + name = iline[1:j] + node = self.factory.create_block_node(name, indent) + + if node.is_name('item'): + self.unravel_for_list_item(indent) + elif node.is_name(('td', 'th')): + self.unravel_for_table_cell(indent) + elif node.is_name('tr'): + self.unravel_for_table_row(indent) + elif node.is_name(('thead', 'tfoot', 'tbody')): + self.unravel_for_table_body(indent) + else: + self.unravel_for_block(indent) + + if iline[j] == ']': + self.state = DuckParser.STATE_BLOCK_READY + self._take_block_node(node) + else: + self._attrparser = AttributeParser(self, node=node) + self._attrparser.parse_line(iline[j:]) + if self._attrparser.finished: + node.attributes = self._attrparser.attributes + self.state = DuckParser.STATE_BLOCK_READY + self._attrparser = None + self._take_block_node(node) + else: + self.state = DuckParser.STATE_BLOCK_ATTR + elif iline.startswith('. '): + self._parse_line_block_title(iline, indent) + elif iline.startswith('- '): + self._parse_line_block_item_title(iline, indent) + elif iline.startswith('* '): + self._parse_line_block_item_content(iline, indent) + elif not (self.current.is_leaf or self.current.is_external or + (self.current.is_tree_item and not self.current.has_tree_items)): + if self.current.is_tree_item: + while self.current.is_name(('tree', 'item')): + self.current = self.current.parent + while self.current.outer == indent and not self.current.available: + if isinstance(self.current, (Division, Document)): + break + self.current = self.current.parent + node = self.factory.create_block_paragraph_node(indent) + self.current.add_child(node) + self.current = node + self.add_text(iline) + else: + self.add_text(iline) + + def _parse_line_block_title(self, iline, indent): + # For lines starting with '. '. Creates a block title. + self.push_text() + self.unravel_for_block(indent) + self.factory.handle_block_title(indent, indent + 2) + self._parse_line((' ' * self.current.inner) + iline[2:]) + + def _parse_line_block_item_title(self, iline, indent): + # For lines starting with '- '. It might be a th element, + # or it might be a title in a terms item. It might also + # start a terms element. + self.push_text() + self.unravel_for_indent(indent) + self.factory.handle_block_item_title(indent, indent + 2) + self._parse_line((' ' * self.current.inner) + iline[2:]) + + def _parse_line_block_item_content(self, iline, indent): + # For lines starting with '* '. It might be a td element, + # it might be an item element in a list or steps, it might + # be a tree item, or it might start the content of an item + # in a terms. It might also start a list element. + self.push_text() + self.unravel_for_indent(indent) + node = self.factory.handle_block_item_content(indent, indent + 2) + self._parse_line((' ' * node.inner) + iline[2:]) + + def _parse_line_block_attr(self, line): + self._attrparser.parse_line(line) + if self._attrparser.finished: + node = self._attrparser.node + node.attributes = self._attrparser.attributes + self.state = DuckParser.STATE_BLOCK_READY + self._attrparser = None + self._take_block_node(node) + + def _parse_line_block_ready(self, line): + indent = DuckParser.get_indent(line) + if indent < self.current.outer: + while self.current.outer > indent: + if isinstance(self.current, (Division, Document)): + break + self.current = self.current.parent + else: + if line.lstrip().startswith('@'): + self.info_state = DuckParser.INFO_STATE_INFO + self.current.inner = DuckParser.get_indent(line) + self.state = DuckParser.STATE_BLOCK + self._parse_line(line) + + def _take_block_node(self, node): + if node.extension: + for extension in self.extensions_by_module[node.extension]: + if extension.take_block_node(node): + return + # If no extension claimed it, but there's still a namespace + # binding, that's ok. You can have a namespace prefix with + # the same name as an extension, but the extension wins. + if node.nsuri is not None: + self.current.add_child(node) + self.current = node + else: + raise SyntaxError('Unrecognized extension element: ' + node.name, self) + else: + self.current.add_child(node) + self.current = node + + def set_text(self, text): + self._text = text + + def add_text(self, text): + self._text += text + + def push_text(self): + if self._text != '': + if self.info_state != DuckParser.INFO_STATE_NONE: + self.curinfo.add_text(self._text) + else: + self.current.add_text(self._text) + self.set_text('') + + # Call this if you have an item to insert + def unravel_for_list_item(self, indent): + self.unravel_for_indent(indent) + while self.current.outer == indent: + if isinstance(self.current, (Division, Document)): + break + if self.current.available: + break + if self.current.is_list: + break + self.current = self.current.parent + + # Call this if you have a td or th to insert + def unravel_for_table_cell(self, indent): + self.unravel_for_indent(indent) + while self.current.outer == indent: + if isinstance(self.current, (Division, Document)): + break + if self.current.available: + break + if self.current.is_name('tr'): + break + self.current = self.current.parent + if self.current.is_tree_item: + while self.current.is_name(('tree', 'item')): + self.current = self.current.parent + + # Call this if you have a tr to insert + def unravel_for_table_row(self, indent): + self.unravel_for_indent(indent) + while self.current.outer == indent: + if isinstance(self.current, (Division, Document)): + break + if self.current.available: + break + if self.current.is_name(('table', 'thead', 'tfoot', 'tbody')): + break + self.current = self.current.parent + if self.current.is_tree_item: + while self.current.is_name(('tree', 'item')): + self.current = self.current.parent + + # Call this if you have a tbody, thead, or tfoot to insert + def unravel_for_table_body(self, indent): + self.unravel_for_indent(indent) + while self.current.outer == indent: + if isinstance(self.current, (Division, Document)): + break + if self.current.available: + break + if self.current.is_name('table'): + break + self.current = self.current.parent + if self.current.is_tree_item: + while self.current.is_name(('tree', 'item')): + self.current = self.current.parent + + # Call this if you have any other block to insert + def unravel_for_block(self, indent): + self.unravel_for_indent(indent) + while self.current.outer == indent: + if isinstance(self.current, (Division, Document)): + break + if self.current.available: + break + self.current = self.current.parent + if self.current.is_tree_item: + while self.current.is_name(('tree', 'item')): + self.current = self.current.parent + + # This only unravels what indentation absolutely forces. + def unravel_for_indent(self, indent): + while self.current.outer > indent or self.current.is_leaf: + if isinstance(self.current, (Division, Document)): + break + self.current = self.current.parent + + +def _isnmtoken(c): + i = ord(c) + return (('A' <= c <= 'Z') or ('a' <= c <= 'z') or ('0' <= c <= '9') or + (c == ':' or c == '_' or c == '-' or c == '.' or i == 0xB7) or + (0xC0 <= i <= 0xD6) or (0xD8 <= i <= 0xF6) or + (0xF8 <= i <= 0x2FF) or (0x370 <= i <= 0x37D) or + (0x37F <= i <= 0x1FFF) or (0x200C <= i <= 0x200D) or + (0x2070 <= i <= 0x218F) or (0x2C00 <= i <= 0x2FEF) or + (0x3001 <= i <= 0xD7FF) or (0xF900 <= i <= 0xFDCF) or + (0xFDF0 <= i <= 0xFFFD) or (0x10000 <= i <= 0xEFFFF) or + (0x0300 <= i <= 0x036F) or (0x203F <= i <= 0x2040)) diff --git a/setup.py b/setup.py new file mode 100644 index 0000000..2328731 --- /dev/null +++ b/setup.py @@ -0,0 +1,28 @@ +#!/usr/bin/env python +from setuptools import setup + +setup( + name='mallard-ducktype', + version='1.0.2', + description='Parse Ducktype files and convert them to Mallard.', + packages=['mallard', 'mallard.ducktype', 'mallard.ducktype.extensions'], + scripts=['bin/ducktype'], + author='Shaun McCance', + author_email='shaunm@gnome.org', + license='MIT', + classifiers=[ + 'Development Status :: 3 - Alpha', + 'Environment :: Console', + 'Intended Audience :: Customer Service', + 'Intended Audience :: Developers', + 'Intended Audience :: Other Audience', + 'Intended Audience :: System Administrators', + 'Programming Language :: Python :: 3', + 'Programming Language :: Python :: 3 :: Only', + 'Topic :: Documentation', + 'Topic :: Software Development :: Documentation', + 'Topic :: Text Processing :: Markup', + 'Topic :: Text Processing :: Markup :: XML', + 'License :: OSI Approved :: MIT License', + ], +) diff --git a/tests/attr01.duck b/tests/attr01.duck new file mode 100644 index 0000000..4f1de1a --- /dev/null +++ b/tests/attr01.duck @@ -0,0 +1,4 @@ += Attribute Test + [type="topic" style="hint1 hint2"] + +This is a test. diff --git a/tests/attr01.page b/tests/attr01.page new file mode 100644 index 0000000..7d935a1 --- /dev/null +++ b/tests/attr01.page @@ -0,0 +1,5 @@ + + + Attribute Test +

This is a test.

+
diff --git a/tests/attr02.duck b/tests/attr02.duck new file mode 100644 index 0000000..cda4b6b --- /dev/null +++ b/tests/attr02.duck @@ -0,0 +1,4 @@ += Attribute Test + [.hint1 .hint2] + +This is a test. diff --git a/tests/attr02.page b/tests/attr02.page new file mode 100644 index 0000000..6d64f7f --- /dev/null +++ b/tests/attr02.page @@ -0,0 +1,5 @@ + + + Attribute Test +

This is a test.

+
diff --git a/tests/attr03.duck b/tests/attr03.duck new file mode 100644 index 0000000..193e6f5 --- /dev/null +++ b/tests/attr03.duck @@ -0,0 +1,5 @@ += Attribute Test + [type="topic" +style="hint1"] + +This is a test. diff --git a/tests/attr03.page b/tests/attr03.page new file mode 100644 index 0000000..cfe1724 --- /dev/null +++ b/tests/attr03.page @@ -0,0 +1,5 @@ + + + Attribute Test +

This is a test.

+
diff --git a/tests/attr04.duck b/tests/attr04.duck new file mode 100644 index 0000000..ec8f8d6 --- /dev/null +++ b/tests/attr04.duck @@ -0,0 +1,6 @@ += Attribute Test + [type="topic" #page1 +style="hint1" +.hint2] + +This is a test. diff --git a/tests/attr04.page b/tests/attr04.page new file mode 100644 index 0000000..55f1342 --- /dev/null +++ b/tests/attr04.page @@ -0,0 +1,5 @@ + + + Attribute Test +

This is a test.

+
diff --git a/tests/attr05.duck b/tests/attr05.duck new file mode 100644 index 0000000..818f972 --- /dev/null +++ b/tests/attr05.duck @@ -0,0 +1,5 @@ += Attribute Test + [type=topic +style=hint1 id=attr05] + +This is a test. diff --git a/tests/attr05.page b/tests/attr05.page new file mode 100644 index 0000000..725b36a --- /dev/null +++ b/tests/attr05.page @@ -0,0 +1,5 @@ + + + Attribute Test +

This is a test.

+
diff --git a/tests/attr06.duck b/tests/attr06.duck new file mode 100644 index 0000000..c916ea8 --- /dev/null +++ b/tests/attr06.duck @@ -0,0 +1,4 @@ += Attribute Test + [topic style=hint1] + +This is a test. diff --git a/tests/attr06.page b/tests/attr06.page new file mode 100644 index 0000000..57af9bf --- /dev/null +++ b/tests/attr06.page @@ -0,0 +1,5 @@ + + + Attribute Test +

This is a test.

+
diff --git a/tests/attr07.duck b/tests/attr07.duck new file mode 100644 index 0000000..96a8079 --- /dev/null +++ b/tests/attr07.duck @@ -0,0 +1,4 @@ += Attribute Test + [style=hint1 topic] + +This is a test. diff --git a/tests/attr07.page b/tests/attr07.page new file mode 100644 index 0000000..510386a --- /dev/null +++ b/tests/attr07.page @@ -0,0 +1,5 @@ + + + Attribute Test +

This is a test.

+
diff --git a/tests/attr08.duck b/tests/attr08.duck new file mode 100644 index 0000000..d7e53ce --- /dev/null +++ b/tests/attr08.duck @@ -0,0 +1,5 @@ += Attribute Test + [style="hint1 +hint2" topic] + +This is a test. diff --git a/tests/attr08.page b/tests/attr08.page new file mode 100644 index 0000000..a1b1df7 --- /dev/null +++ b/tests/attr08.page @@ -0,0 +1,6 @@ + + + Attribute Test +

This is a test.

+
diff --git a/tests/attr09.duck b/tests/attr09.duck new file mode 100644 index 0000000..4e89317 --- /dev/null +++ b/tests/attr09.duck @@ -0,0 +1,4 @@ += Attribute Test + +Let's test some escapes. +$app[style="$$ $* $= $- $. $@ $[ $] $( $) $" $'"]() diff --git a/tests/attr09.page b/tests/attr09.page new file mode 100644 index 0000000..c2921c4 --- /dev/null +++ b/tests/attr09.page @@ -0,0 +1,6 @@ + + + Attribute Test +

Let's test some escapes. +

+
diff --git a/tests/attr10.duck b/tests/attr10.duck new file mode 100644 index 0000000..561911c --- /dev/null +++ b/tests/attr10.duck @@ -0,0 +1,4 @@ += Attribute Test + +[code xml mallard] + diff --git a/tests/attr10.page b/tests/attr10.page new file mode 100644 index 0000000..9d83a42 --- /dev/null +++ b/tests/attr10.page @@ -0,0 +1,5 @@ + + + Attribute Test + <page/> + diff --git a/tests/attr11.duck b/tests/attr11.duck new file mode 100644 index 0000000..3782a68 --- /dev/null +++ b/tests/attr11.duck @@ -0,0 +1,4 @@ += Attribute Test + +[code no:style=xml] + diff --git a/tests/attr11.error b/tests/attr11.error new file mode 100644 index 0000000..3036404 --- /dev/null +++ b/tests/attr11.error @@ -0,0 +1 @@ +attr11.duck:3: Unrecognized namespace prefix: no diff --git a/tests/attr12.duck b/tests/attr12.duck new file mode 100644 index 0000000..0b68600 --- /dev/null +++ b/tests/attr12.duck @@ -0,0 +1,4 @@ += Attribute Test + +[code no:style="xml"] + diff --git a/tests/attr12.error b/tests/attr12.error new file mode 100644 index 0000000..0b0017f --- /dev/null +++ b/tests/attr12.error @@ -0,0 +1 @@ +attr12.duck:3: Unrecognized namespace prefix: no diff --git a/tests/block01.duck b/tests/block01.duck new file mode 100644 index 0000000..1bffa5c --- /dev/null +++ b/tests/block01.duck @@ -0,0 +1,4 @@ += Block Test + +[note] +This paragraph is in a note. diff --git a/tests/block01.page b/tests/block01.page new file mode 100644 index 0000000..8152146 --- /dev/null +++ b/tests/block01.page @@ -0,0 +1,7 @@ + + + Block Test + +

This paragraph is in a note.

+
+
diff --git a/tests/block02.duck b/tests/block02.duck new file mode 100644 index 0000000..9e75dfe --- /dev/null +++ b/tests/block02.duck @@ -0,0 +1,6 @@ += Block Test + +[note] + [note] + [note] + This paragraph is in a note in a note in a note. diff --git a/tests/block02.page b/tests/block02.page new file mode 100644 index 0000000..0f12b99 --- /dev/null +++ b/tests/block02.page @@ -0,0 +1,11 @@ + + + Block Test + + + +

This paragraph is in a note in a note in a note.

+
+
+
+
diff --git a/tests/block03.duck b/tests/block03.duck new file mode 100644 index 0000000..9d541a4 --- /dev/null +++ b/tests/block03.duck @@ -0,0 +1,9 @@ += Block Test + +[note] + [note] + This paragraph is in a note in a note. + This is still paragraph 1. + + This is still in the top note. + This is still pargraph 2. diff --git a/tests/block03.page b/tests/block03.page new file mode 100644 index 0000000..b9edfca --- /dev/null +++ b/tests/block03.page @@ -0,0 +1,12 @@ + + + Block Test + + +

This paragraph is in a note in a note. + This is still paragraph 1.

+
+

This is still in the top note. + This is still pargraph 2.

+
+
diff --git a/tests/block04.duck b/tests/block04.duck new file mode 100644 index 0000000..ab0a9ea --- /dev/null +++ b/tests/block04.duck @@ -0,0 +1,7 @@ += Block Test + +[note] + [note] + This paragraph is in a note in a note. + + This is a new paragraph in a note in a note. diff --git a/tests/block04.page b/tests/block04.page new file mode 100644 index 0000000..897c3e4 --- /dev/null +++ b/tests/block04.page @@ -0,0 +1,10 @@ + + + Block Test + + +

This paragraph is in a note in a note.

+

This is a new paragraph in a note in a note.

+
+
+
diff --git a/tests/block05.duck b/tests/block05.duck new file mode 100644 index 0000000..bbd1ce8 --- /dev/null +++ b/tests/block05.duck @@ -0,0 +1,8 @@ += Block Test + +[note] + This paragraph is in a note. + + + There is a double line break above and below this line. + diff --git a/tests/block05.page b/tests/block05.page new file mode 100644 index 0000000..8cac44e --- /dev/null +++ b/tests/block05.page @@ -0,0 +1,8 @@ + + + Block Test + +

This paragraph is in a note.

+

There is a double line break above and below this line.

+
+
diff --git a/tests/block06.duck b/tests/block06.duck new file mode 100644 index 0000000..6885a3e --- /dev/null +++ b/tests/block06.duck @@ -0,0 +1,7 @@ += Block Test + +[note] +[note] +This paragraph is in two notes. + +This paragraph breaks out of both. diff --git a/tests/block06.page b/tests/block06.page new file mode 100644 index 0000000..3fbb35f --- /dev/null +++ b/tests/block06.page @@ -0,0 +1,10 @@ + + + Block Test + + +

This paragraph is in two notes.

+
+
+

This paragraph breaks out of both.

+
diff --git a/tests/block07.duck b/tests/block07.duck new file mode 100644 index 0000000..4c455a0 --- /dev/null +++ b/tests/block07.duck @@ -0,0 +1,6 @@ += Block Test + +[note] + This is a paragraph in a note. + [note] + This is a paragraph in a note in a note. diff --git a/tests/block07.page b/tests/block07.page new file mode 100644 index 0000000..6537cda --- /dev/null +++ b/tests/block07.page @@ -0,0 +1,10 @@ + + + Block Test + +

This is a paragraph in a note.

+ +

This is a paragraph in a note in a note.

+
+
+
diff --git a/tests/block08.duck b/tests/block08.duck new file mode 100644 index 0000000..fc44110 --- /dev/null +++ b/tests/block08.duck @@ -0,0 +1,8 @@ += Block Test + +[figure] + [title] + This is a figure title. + [desc] + This is a figure desc. + This is a paragraph in a figure. diff --git a/tests/block08.page b/tests/block08.page new file mode 100644 index 0000000..2464804 --- /dev/null +++ b/tests/block08.page @@ -0,0 +1,9 @@ + + + Block Test +
+ This is a figure title. + This is a figure desc. +

This is a paragraph in a figure.

+
+
diff --git a/tests/block09.duck b/tests/block09.duck new file mode 100644 index 0000000..116fe4e --- /dev/null +++ b/tests/block09.duck @@ -0,0 +1,9 @@ += Block Test + +[figure] + [title] + This is a figure title. + [desc] + This is a figure desc. + [note] + This is a paragraph in a note in a figure. diff --git a/tests/block09.page b/tests/block09.page new file mode 100644 index 0000000..097be06 --- /dev/null +++ b/tests/block09.page @@ -0,0 +1,11 @@ + + + Block Test +
+ This is a figure title. + This is a figure desc. + +

This is a paragraph in a note in a figure.

+
+
+
diff --git a/tests/block10.duck b/tests/block10.duck new file mode 100644 index 0000000..5dd7aaa --- /dev/null +++ b/tests/block10.duck @@ -0,0 +1,9 @@ += Block Test + +[figure] + [title] + This is a figure title. + [desc] + This is a figure desc. + + This is a paragraph in a figure. diff --git a/tests/block10.page b/tests/block10.page new file mode 100644 index 0000000..7e1cb24 --- /dev/null +++ b/tests/block10.page @@ -0,0 +1,9 @@ + + + Block Test +
+ This is a figure title. + This is a figure desc. +

This is a paragraph in a figure.

+
+
diff --git a/tests/block11.duck b/tests/block11.duck new file mode 100644 index 0000000..c220a41 --- /dev/null +++ b/tests/block11.duck @@ -0,0 +1,4 @@ += Block Test + +[note style="tip"] +This is a note diff --git a/tests/block11.page b/tests/block11.page new file mode 100644 index 0000000..4784d11 --- /dev/null +++ b/tests/block11.page @@ -0,0 +1,7 @@ + + + Block Test + +

This is a note

+
+
diff --git a/tests/block12.duck b/tests/block12.duck new file mode 100644 index 0000000..6d388a5 --- /dev/null +++ b/tests/block12.duck @@ -0,0 +1,6 @@ += Block Test + +[note +.tip +] +This is a note diff --git a/tests/block12.page b/tests/block12.page new file mode 100644 index 0000000..d7bce54 --- /dev/null +++ b/tests/block12.page @@ -0,0 +1,7 @@ + + + Block Test + +

This is a note

+
+
diff --git a/tests/block13.duck b/tests/block13.duck new file mode 100644 index 0000000..74c47f7 --- /dev/null +++ b/tests/block13.duck @@ -0,0 +1,7 @@ += Block Test + +[note] +[note] +This is a note in a note. +[note] +This is a note. diff --git a/tests/block13.page b/tests/block13.page new file mode 100644 index 0000000..1169a36 --- /dev/null +++ b/tests/block13.page @@ -0,0 +1,12 @@ + + + Block Test + + +

This is a note in a note.

+
+
+ +

This is a note.

+
+
diff --git a/tests/block14.duck b/tests/block14.duck new file mode 100644 index 0000000..13006c8 --- /dev/null +++ b/tests/block14.duck @@ -0,0 +1,6 @@ += Block Test + +[note] +[p] + This is in a note. +This is not in a note. diff --git a/tests/block14.page b/tests/block14.page new file mode 100644 index 0000000..af94964 --- /dev/null +++ b/tests/block14.page @@ -0,0 +1,8 @@ + + + Block Test + +

This is in a note.

+
+

This is not in a note.

+
diff --git a/tests/block15.duck b/tests/block15.duck new file mode 100644 index 0000000..9d719c3 --- /dev/null +++ b/tests/block15.duck @@ -0,0 +1,5 @@ += Block Test + +[note] +. Note Title +This is a note. diff --git a/tests/block15.page b/tests/block15.page new file mode 100644 index 0000000..f8cc310 --- /dev/null +++ b/tests/block15.page @@ -0,0 +1,8 @@ + + + Block Test + + Note Title +

This is a note.

+
+
diff --git a/tests/block16.duck b/tests/block16.duck new file mode 100644 index 0000000..4dcd955 --- /dev/null +++ b/tests/block16.duck @@ -0,0 +1,11 @@ += Block Test + +[note] + . Note Title + + This is a note. + +[note] +. Note + Title +This is a note. diff --git a/tests/block16.page b/tests/block16.page new file mode 100644 index 0000000..286dcf1 --- /dev/null +++ b/tests/block16.page @@ -0,0 +1,13 @@ + + + Block Test + + Note Title +

This is a note.

+
+ + Note + Title +

This is a note.

+
+
diff --git a/tests/block17.duck b/tests/block17.duck new file mode 100644 index 0000000..cb8f9e4 --- /dev/null +++ b/tests/block17.duck @@ -0,0 +1,5 @@ += Block Test + +[note] + [media src="foo.png"] +This paragraph is out of the note. diff --git a/tests/block17.page b/tests/block17.page new file mode 100644 index 0000000..22a8451 --- /dev/null +++ b/tests/block17.page @@ -0,0 +1,8 @@ + + + Block Test + + + +

This paragraph is out of the note.

+
diff --git a/tests/block18.duck b/tests/block18.duck new file mode 100644 index 0000000..0158a8c --- /dev/null +++ b/tests/block18.duck @@ -0,0 +1,5 @@ += Block Test + +[media src="foo.png"] + +This paragraph is not in the media element. diff --git a/tests/block18.page b/tests/block18.page new file mode 100644 index 0000000..19a19c6 --- /dev/null +++ b/tests/block18.page @@ -0,0 +1,6 @@ + + + Block Test + +

This paragraph is not in the media element.

+
diff --git a/tests/block19.duck b/tests/block19.duck new file mode 100644 index 0000000..7087806 --- /dev/null +++ b/tests/block19.duck @@ -0,0 +1,8 @@ += Block Test + +[links section] + +[links topic groups="#first"] +. First + +[links topic] diff --git a/tests/block19.page b/tests/block19.page new file mode 100644 index 0000000..13c2fae --- /dev/null +++ b/tests/block19.page @@ -0,0 +1,9 @@ + + + Block Test + + + First + + + diff --git a/tests/block20.duck b/tests/block20.duck new file mode 100644 index 0000000..4d65afd --- /dev/null +++ b/tests/block20.duck @@ -0,0 +1,12 @@ +@namespace tt http://www.w3.org/ns/ttml + += Block Test + +This tests leaf nodes in other namespaces. + +[media video src=video.mp4] + [tt:tt] + [tt:body] + [tt:div begin="1s" end="3s"] + [tt:p] + This should not have a Mallard p element added. diff --git a/tests/block20.page b/tests/block20.page new file mode 100644 index 0000000..d0ebc8a --- /dev/null +++ b/tests/block20.page @@ -0,0 +1,14 @@ + + + Block Test +

This tests leaf nodes in other namespaces.

+ + + + + This should not have a Mallard p element added. + + + + +
diff --git a/tests/block21.duck b/tests/block21.duck new file mode 100644 index 0000000..6eaa7f8 --- /dev/null +++ b/tests/block21.duck @@ -0,0 +1,8 @@ +@namespace if http://projectmallard.org/if/1.0/ + += Block Test + +This tests leaf nodes in other namespaces. + +[if:if test=target:html] + This should have a Mallard p element added. diff --git a/tests/block21.page b/tests/block21.page new file mode 100644 index 0000000..3b270a5 --- /dev/null +++ b/tests/block21.page @@ -0,0 +1,8 @@ + + + Block Test +

This tests leaf nodes in other namespaces.

+ +

This should have a Mallard p element added.

+
+
diff --git a/tests/block22.duck b/tests/block22.duck new file mode 100644 index 0000000..d07b62d --- /dev/null +++ b/tests/block22.duck @@ -0,0 +1,8 @@ +@namespace mal http://projectmallard.org/1.0/ + += Block Test + +This tests leaf nodes in other namespaces. + +[mal:div] + This should have a Mallard p element added. diff --git a/tests/block22.page b/tests/block22.page new file mode 100644 index 0000000..5b55f90 --- /dev/null +++ b/tests/block22.page @@ -0,0 +1,8 @@ + + + Block Test +

This tests leaf nodes in other namespaces.

+ +

This should have a Mallard p element added.

+
+
diff --git a/tests/block23.duck b/tests/block23.duck new file mode 100644 index 0000000..0a9da3a --- /dev/null +++ b/tests/block23.duck @@ -0,0 +1,8 @@ +@namespace mal http://projectmallard.org/1.0/ + += Block Test + +This tests leaf nodes in other namespaces. + +[mal:screen] + This should not have a Mallard p element added. diff --git a/tests/block23.page b/tests/block23.page new file mode 100644 index 0000000..d42df42 --- /dev/null +++ b/tests/block23.page @@ -0,0 +1,6 @@ + + + Block Test +

This tests leaf nodes in other namespaces.

+ This should not have a Mallard p element added. +
diff --git a/tests/block24.duck b/tests/block24.duck new file mode 100644 index 0000000..212a5df --- /dev/null +++ b/tests/block24.duck @@ -0,0 +1,9 @@ +@namespace if http://projectmallard.org/if/1.0/ + += Block Test + +This tests leaf nodes in other namespaces. + +[if:choose] + [if:when test=target:html] + This should have a Mallard p element added. diff --git a/tests/block24.page b/tests/block24.page new file mode 100644 index 0000000..51555b6 --- /dev/null +++ b/tests/block24.page @@ -0,0 +1,10 @@ + + + Block Test +

This tests leaf nodes in other namespaces.

+ + +

This should have a Mallard p element added.

+
+
+
diff --git a/tests/block25.duck b/tests/block25.duck new file mode 100644 index 0000000..6a0c103 --- /dev/null +++ b/tests/block25.duck @@ -0,0 +1,10 @@ += Block Test + +[div] +[title] + Title +[desc] + Desc +[cite] + Cite +This paragraph is in the div diff --git a/tests/block25.page b/tests/block25.page new file mode 100644 index 0000000..53bc29c --- /dev/null +++ b/tests/block25.page @@ -0,0 +1,10 @@ + + + Block Test +
+ Title + Desc + Cite +

This paragraph is in the div

+
+
diff --git a/tests/block26.duck b/tests/block26.duck new file mode 100644 index 0000000..8192a4b --- /dev/null +++ b/tests/block26.duck @@ -0,0 +1,6 @@ += Block Test + +[example] +@title[ui:expanded] Expanded Title +[code] +code diff --git a/tests/block26.page b/tests/block26.page new file mode 100644 index 0000000..07cab78 --- /dev/null +++ b/tests/block26.page @@ -0,0 +1,10 @@ + + + Block Test + + + Expanded Title + + code + + diff --git a/tests/comment01.duck b/tests/comment01.duck new file mode 100644 index 0000000..f4a01f4 --- /dev/null +++ b/tests/comment01.duck @@ -0,0 +1,6 @@ += Comment Test +This is a paragraph. +[-- +This is commented out. +--] +This is still the first paragraph. diff --git a/tests/comment01.page b/tests/comment01.page new file mode 100644 index 0000000..87eb8e4 --- /dev/null +++ b/tests/comment01.page @@ -0,0 +1,6 @@ + + + Comment Test +

This is a paragraph. + This is still the first paragraph.

+
diff --git a/tests/comment02.duck b/tests/comment02.duck new file mode 100644 index 0000000..9ad1b36 --- /dev/null +++ b/tests/comment02.duck @@ -0,0 +1,8 @@ += Comment Test + +[note] + This is in the note. +[-- +This is commented out. +--] + This is still the first paragraph in the note. diff --git a/tests/comment02.page b/tests/comment02.page new file mode 100644 index 0000000..c04affc --- /dev/null +++ b/tests/comment02.page @@ -0,0 +1,8 @@ + + + Comment Test + +

This is in the note. + This is still the first paragraph in the note.

+
+
diff --git a/tests/comment03.duck b/tests/comment03.duck new file mode 100644 index 0000000..039f75a --- /dev/null +++ b/tests/comment03.duck @@ -0,0 +1,8 @@ += Comment Test + +[note] + This is in the note. + [-- + This is commented out. + --] + This is still the first paragraph in the note. diff --git a/tests/comment03.page b/tests/comment03.page new file mode 100644 index 0000000..2d63f12 --- /dev/null +++ b/tests/comment03.page @@ -0,0 +1,8 @@ + + + Comment Test + +

This is in the note. + This is still the first paragraph in the note.

+
+
diff --git a/tests/comment04.duck b/tests/comment04.duck new file mode 100644 index 0000000..cefcb10 --- /dev/null +++ b/tests/comment04.duck @@ -0,0 +1,9 @@ += Comment Test + +[note] + This is in the note. +[-- + This is commented out. + --] + + This is a new paragraph in the note. diff --git a/tests/comment04.page b/tests/comment04.page new file mode 100644 index 0000000..f192cbd --- /dev/null +++ b/tests/comment04.page @@ -0,0 +1,8 @@ + + + Comment Test + +

This is in the note.

+

This is a new paragraph in the note.

+
+
diff --git a/tests/comment05.duck b/tests/comment05.duck new file mode 100644 index 0000000..74f6bd5 --- /dev/null +++ b/tests/comment05.duck @@ -0,0 +1,9 @@ += Comment Test + +[note] + This is in the note. +[-] This is commented out. + + This is a new paragraph in the note. + [-] This is commented out. + This is still in that paragraph. diff --git a/tests/comment05.page b/tests/comment05.page new file mode 100644 index 0000000..e89b4e7 --- /dev/null +++ b/tests/comment05.page @@ -0,0 +1,9 @@ + + + Comment Test + +

This is in the note.

+

This is a new paragraph in the note. + This is still in that paragraph.

+
+
diff --git a/tests/comment06.duck b/tests/comment06.duck new file mode 100644 index 0000000..816e2b0 --- /dev/null +++ b/tests/comment06.duck @@ -0,0 +1,8 @@ += Comment Test + +[note] + This is in the note. +[-- This is commented out. + --] + + This is a new paragraph in the note. diff --git a/tests/comment06.page b/tests/comment06.page new file mode 100644 index 0000000..d2ec84f --- /dev/null +++ b/tests/comment06.page @@ -0,0 +1,8 @@ + + + Comment Test + +

This is in the note.

+

This is a new paragraph in the note.

+
+
diff --git a/tests/comment07.duck b/tests/comment07.duck new file mode 100644 index 0000000..752bbc6 --- /dev/null +++ b/tests/comment07.duck @@ -0,0 +1,9 @@ += Comment Test + +[note] + This is in the note. +[-- This is commented out. + This is still commented out. + --] This did not end the comment. + + This is still commented out. diff --git a/tests/comment07.page b/tests/comment07.page new file mode 100644 index 0000000..4b0702e --- /dev/null +++ b/tests/comment07.page @@ -0,0 +1,7 @@ + + + Comment Test + +

This is in the note.

+
+
diff --git a/tests/comment08.duck b/tests/comment08.duck new file mode 100644 index 0000000..f8f7ca4 --- /dev/null +++ b/tests/comment08.duck @@ -0,0 +1,11 @@ += Comment Test + +[note] + This is in the note. +[-- + This is commented out. +[-] This doesn't affect the block comment. + [-] This doesn't affect the block comment. + --] + + This is a new paragraph in the note. diff --git a/tests/comment08.page b/tests/comment08.page new file mode 100644 index 0000000..c402bb6 --- /dev/null +++ b/tests/comment08.page @@ -0,0 +1,8 @@ + + + Comment Test + +

This is in the note.

+

This is a new paragraph in the note.

+
+
diff --git a/tests/comment09.duck b/tests/comment09.duck new file mode 100644 index 0000000..8f907fc --- /dev/null +++ b/tests/comment09.duck @@ -0,0 +1,8 @@ +@ducktype/1.0 +[-] A comment +@namespace if http://projectmallard.org/if/1.0/ + += Comment Test + +[if:if test=target:html] +This is a test of comments. diff --git a/tests/comment09.page b/tests/comment09.page new file mode 100644 index 0000000..c2b6433 --- /dev/null +++ b/tests/comment09.page @@ -0,0 +1,7 @@ + + + Comment Test + +

This is a test of comments.

+
+
diff --git a/tests/comment10.duck b/tests/comment10.duck new file mode 100644 index 0000000..9ddd78d --- /dev/null +++ b/tests/comment10.duck @@ -0,0 +1,10 @@ +@ducktype/1.0 +[-- +A comment +--] +@namespace if http://projectmallard.org/if/1.0/ + += Comment Test + +[if:if test=target:html] +This is a test of comments. diff --git a/tests/comment10.page b/tests/comment10.page new file mode 100644 index 0000000..927e956 --- /dev/null +++ b/tests/comment10.page @@ -0,0 +1,7 @@ + + + Comment Test + +

This is a test of comments.

+
+
diff --git a/tests/comment11-1.txt b/tests/comment11-1.txt new file mode 100644 index 0000000..709aa26 --- /dev/null +++ b/tests/comment11-1.txt @@ -0,0 +1,4 @@ +[-- +A comment +--] +@namespace if http://projectmallard.org/if/1.0/ diff --git a/tests/comment11.duck b/tests/comment11.duck new file mode 100644 index 0000000..ce35dac --- /dev/null +++ b/tests/comment11.duck @@ -0,0 +1,7 @@ +@ducktype/1.0 +@include comment11-1.txt + += Comment Test + +[if:if test=target:html] +This is a test of comments. diff --git a/tests/comment11.page b/tests/comment11.page new file mode 100644 index 0000000..24bf381 --- /dev/null +++ b/tests/comment11.page @@ -0,0 +1,7 @@ + + + Comment Test + +

This is a test of comments.

+
+
diff --git a/tests/comment12-1.txt b/tests/comment12-1.txt new file mode 100644 index 0000000..510337d --- /dev/null +++ b/tests/comment12-1.txt @@ -0,0 +1,2 @@ +[-] A comment +@namespace if http://projectmallard.org/if/1.0/ diff --git a/tests/comment12.duck b/tests/comment12.duck new file mode 100644 index 0000000..1be429d --- /dev/null +++ b/tests/comment12.duck @@ -0,0 +1,7 @@ +@ducktype/1.0 +@include comment12-1.txt + += Comment Test + +[if:if test=target:html] +This is a test of comments. diff --git a/tests/comment12.page b/tests/comment12.page new file mode 100644 index 0000000..d49c81b --- /dev/null +++ b/tests/comment12.page @@ -0,0 +1,7 @@ + + + Comment Test + +

This is a test of comments.

+
+
diff --git a/tests/csv01.duck b/tests/csv01.duck new file mode 100644 index 0000000..281a23b --- /dev/null +++ b/tests/csv01.duck @@ -0,0 +1,9 @@ +@ducktype/1.0 csv/experimental + += CSV Test + +[csv:table] +1,2,3 +4,5,6 + +Out diff --git a/tests/csv01.page b/tests/csv01.page new file mode 100644 index 0000000..7b98529 --- /dev/null +++ b/tests/csv01.page @@ -0,0 +1,29 @@ + + + CSV Test + + + + + + + + + + + +
+

1

+
+

2

+
+

3

+
+

4

+
+

5

+
+

6

+
+

Out

+
diff --git a/tests/definition01.duck b/tests/definition01.duck new file mode 100644 index 0000000..83b2959 --- /dev/null +++ b/tests/definition01.duck @@ -0,0 +1,6 @@ +@ducktype/1.0 +@define foo bar + += Definition Test + +This should be bar: $foo;. diff --git a/tests/definition01.page b/tests/definition01.page new file mode 100644 index 0000000..96ea11e --- /dev/null +++ b/tests/definition01.page @@ -0,0 +1,5 @@ + + + Definition Test +

This should be bar: bar.

+
diff --git a/tests/definition02.duck b/tests/definition02.duck new file mode 100644 index 0000000..5fa5f65 --- /dev/null +++ b/tests/definition02.duck @@ -0,0 +1,7 @@ +@ducktype/1.0 +@define foo1 bar$000a; +@define foo2 baz$000a; + += Definition Test + +This should be bar\nbaz\n: $foo1;$foo2;. diff --git a/tests/definition02.page b/tests/definition02.page new file mode 100644 index 0000000..3c82b27 --- /dev/null +++ b/tests/definition02.page @@ -0,0 +1,7 @@ + + + Definition Test +

This should be bar\nbaz\n: bar + baz + .

+
diff --git a/tests/definition03.duck b/tests/definition03.duck new file mode 100644 index 0000000..2743c6d --- /dev/null +++ b/tests/definition03.duck @@ -0,0 +1,8 @@ +@ducktype/1.0 +@define foo1 bar$000a; +@define foo2 baz$000a; + += Definition Test + +[code] +This should be bar\nbaz\n: $foo1;$foo2;. diff --git a/tests/definition03.page b/tests/definition03.page new file mode 100644 index 0000000..318aca5 --- /dev/null +++ b/tests/definition03.page @@ -0,0 +1,7 @@ + + + Definition Test + This should be bar\nbaz\n: bar +baz +. + diff --git a/tests/definition04.duck b/tests/definition04.duck new file mode 100644 index 0000000..2f63ce6 --- /dev/null +++ b/tests/definition04.duck @@ -0,0 +1,7 @@ +@ducktype/1.0 +@define hello hello $world; +@define world world + += Definition Test + +This should be hello world: $hello;. diff --git a/tests/definition04.page b/tests/definition04.page new file mode 100644 index 0000000..a36bfab --- /dev/null +++ b/tests/definition04.page @@ -0,0 +1,5 @@ + + + Definition Test +

This should be hello world: hello world.

+
diff --git a/tests/definition05.duck b/tests/definition05.duck new file mode 100644 index 0000000..2080d0b --- /dev/null +++ b/tests/definition05.duck @@ -0,0 +1,7 @@ +@ducktype/1.0 +@define hello hello +@define hi $hello; world + += Definition Test + +This should be hello world: $hi;. diff --git a/tests/definition05.page b/tests/definition05.page new file mode 100644 index 0000000..772893b --- /dev/null +++ b/tests/definition05.page @@ -0,0 +1,5 @@ + + + Definition Test +

This should be hello world: hello world.

+
diff --git a/tests/definition06.duck b/tests/definition06.duck new file mode 100644 index 0000000..a0aca58 --- /dev/null +++ b/tests/definition06.duck @@ -0,0 +1,12 @@ +@ducktype/1.0 +@define foo bar + += Definition Test + +The style attribute should be $em[style="$foo;"](bar). + +The style attribute should be $em[style='$foo;'](bar). + +The style attribute should be $em[style=$foo;](bar). + +The style attribute should be $em[.$foo;](bar). diff --git a/tests/definition06.page b/tests/definition06.page new file mode 100644 index 0000000..028a440 --- /dev/null +++ b/tests/definition06.page @@ -0,0 +1,8 @@ + + + Definition Test +

The style attribute should be bar.

+

The style attribute should be bar.

+

The style attribute should be bar.

+

The style attribute should be bar.

+
diff --git a/tests/definition07.duck b/tests/definition07.duck new file mode 100644 index 0000000..8f9d863 --- /dev/null +++ b/tests/definition07.duck @@ -0,0 +1,14 @@ +@ducktype/1.0 +@define foo $fe; $fi; +@define fe fo +@define fi fum + += Definition Test + +The style attribute should be $em[style="$foo;"](fo fum). + +The style attribute should be $em[style='$foo;'](fo fum). + +The style attribute should be $em[style=$foo;](fo fum). + +The style attribute should be $em[.$foo;](fo fum). diff --git a/tests/definition07.page b/tests/definition07.page new file mode 100644 index 0000000..9273c07 --- /dev/null +++ b/tests/definition07.page @@ -0,0 +1,8 @@ + + + Definition Test +

The style attribute should be fo fum.

+

The style attribute should be fo fum.

+

The style attribute should be fo fum.

+

The style attribute should be fo fum.

+
diff --git a/tests/definition08.duck b/tests/definition08.duck new file mode 100644 index 0000000..7f88148 --- /dev/null +++ b/tests/definition08.duck @@ -0,0 +1,14 @@ +@ducktype/1.0 +@define fi $fo; +@define fe $fi; +@define fo fum + += Definition Test + +The style attribute should be $em[style="$fe;"](fum). + +The style attribute should be $em[style='$fe;'](fum). + +The style attribute should be $em[style=$fe;](fum). + +The style attribute should be $em[.$fe;](fum). diff --git a/tests/definition08.page b/tests/definition08.page new file mode 100644 index 0000000..1c0c9e1 --- /dev/null +++ b/tests/definition08.page @@ -0,0 +1,8 @@ + + + Definition Test +

The style attribute should be fum.

+

The style attribute should be fum.

+

The style attribute should be fum.

+

The style attribute should be fum.

+
diff --git a/tests/definition09.duck b/tests/definition09.duck new file mode 100644 index 0000000..5f7d11d --- /dev/null +++ b/tests/definition09.duck @@ -0,0 +1,6 @@ +@ducktype/1.0 +@define mallard http://projectmallard.org/ + += Definition Test + +Read more about $link[>>$mallard;](Mallard). diff --git a/tests/definition09.page b/tests/definition09.page new file mode 100644 index 0000000..cf2d8eb --- /dev/null +++ b/tests/definition09.page @@ -0,0 +1,5 @@ + + + Definition Test +

Read more about Mallard.

+
diff --git a/tests/definition10.duck b/tests/definition10.duck new file mode 100644 index 0000000..c17da61 --- /dev/null +++ b/tests/definition10.duck @@ -0,0 +1,6 @@ +@ducktype/1.0 +@define b strong + += Definition Test + +This is $em[.$b;](bold). diff --git a/tests/definition10.page b/tests/definition10.page new file mode 100644 index 0000000..821f92c --- /dev/null +++ b/tests/definition10.page @@ -0,0 +1,5 @@ + + + Definition Test +

This is bold.

+
diff --git a/tests/directive01.duck b/tests/directive01.duck new file mode 100644 index 0000000..bd290e0 --- /dev/null +++ b/tests/directive01.duck @@ -0,0 +1,5 @@ +@ducktype/1.0 + += Directive Test + +This is a test of directives. diff --git a/tests/directive01.page b/tests/directive01.page new file mode 100644 index 0000000..88325d1 --- /dev/null +++ b/tests/directive01.page @@ -0,0 +1,5 @@ + + + Directive Test +

This is a test of directives.

+
diff --git a/tests/directive02.duck b/tests/directive02.duck new file mode 100644 index 0000000..1f4a72a --- /dev/null +++ b/tests/directive02.duck @@ -0,0 +1,6 @@ +@ducktype/1.0 +@namespace if http://projectmallard.org/if/1.0/ + += Directive Test + +This is a test of directives. diff --git a/tests/directive02.page b/tests/directive02.page new file mode 100644 index 0000000..8cf5446 --- /dev/null +++ b/tests/directive02.page @@ -0,0 +1,5 @@ + + + Directive Test +

This is a test of directives.

+
diff --git a/tests/directive03-1.txt b/tests/directive03-1.txt new file mode 100644 index 0000000..e06c917 --- /dev/null +++ b/tests/directive03-1.txt @@ -0,0 +1 @@ +@namespace if http://projectmallard.org/if/1.0/ diff --git a/tests/directive03.duck b/tests/directive03.duck new file mode 100644 index 0000000..636895d --- /dev/null +++ b/tests/directive03.duck @@ -0,0 +1,7 @@ +@ducktype/1.0 +@include directive03-1.txt + += Directive Test + +[if:if test=target:html] +This is a test of directives. diff --git a/tests/directive03.page b/tests/directive03.page new file mode 100644 index 0000000..6050d95 --- /dev/null +++ b/tests/directive03.page @@ -0,0 +1,7 @@ + + + Directive Test + +

This is a test of directives.

+
+
diff --git a/tests/directive04.duck b/tests/directive04.duck new file mode 100644 index 0000000..ed83f9a --- /dev/null +++ b/tests/directive04.duck @@ -0,0 +1,6 @@ +@ducktype/1.0 +@wrong directive name + += Directive Test + +This is a test of directives. diff --git a/tests/directive04.error b/tests/directive04.error new file mode 100644 index 0000000..a3a9854 --- /dev/null +++ b/tests/directive04.error @@ -0,0 +1 @@ +directive04.duck:2: Unrecognized directive: wrong diff --git a/tests/directive05-1.txt b/tests/directive05-1.txt new file mode 100644 index 0000000..772847c --- /dev/null +++ b/tests/directive05-1.txt @@ -0,0 +1,2 @@ +@namespace if http://projectmallard.org/if/1.0/ +@wrong directive name diff --git a/tests/directive05.duck b/tests/directive05.duck new file mode 100644 index 0000000..0ddb452 --- /dev/null +++ b/tests/directive05.duck @@ -0,0 +1,7 @@ +@ducktype/1.0 +@include directive05-1.txt + += Directive Test + +[if:if test=target:html] +This is a test of directives. diff --git a/tests/directive05.error b/tests/directive05.error new file mode 100644 index 0000000..8986273 --- /dev/null +++ b/tests/directive05.error @@ -0,0 +1 @@ +directive05-1.txt:2: Unrecognized directive: wrong diff --git a/tests/directive06-1.txt b/tests/directive06-1.txt new file mode 100644 index 0000000..da269c9 --- /dev/null +++ b/tests/directive06-1.txt @@ -0,0 +1,3 @@ +@namespace if http://projectmallard.org/if/1.0/ + +@namespace e http://projectmallard.org/experimental/ diff --git a/tests/directive06.duck b/tests/directive06.duck new file mode 100644 index 0000000..379c331 --- /dev/null +++ b/tests/directive06.duck @@ -0,0 +1,7 @@ +@ducktype/1.0 +@include directive06-1.txt + += Directive Test + +[if:if test=target:html] +This is a test of $e:hi(directives). diff --git a/tests/directive06.page b/tests/directive06.page new file mode 100644 index 0000000..ff181e2 --- /dev/null +++ b/tests/directive06.page @@ -0,0 +1,7 @@ + + + Directive Test + +

This is a test of directives.

+
+
diff --git a/tests/directive07-1.txt b/tests/directive07-1.txt new file mode 100644 index 0000000..212bab3 --- /dev/null +++ b/tests/directive07-1.txt @@ -0,0 +1 @@ +@define directives $em(directives) diff --git a/tests/directive07.duck b/tests/directive07.duck new file mode 100644 index 0000000..278f2d7 --- /dev/null +++ b/tests/directive07.duck @@ -0,0 +1,6 @@ +@ducktype/1.0 +@include directive07-1.txt + += Directive Test + +This is a test of $directives;. diff --git a/tests/directive07.page b/tests/directive07.page new file mode 100644 index 0000000..f314bde --- /dev/null +++ b/tests/directive07.page @@ -0,0 +1,5 @@ + + + Directive Test +

This is a test of directives.

+
diff --git a/tests/directive08-1.txt b/tests/directive08-1.txt new file mode 100644 index 0000000..ffadb8b --- /dev/null +++ b/tests/directive08-1.txt @@ -0,0 +1 @@ +@include directive08-2.txt diff --git a/tests/directive08-2.txt b/tests/directive08-2.txt new file mode 100644 index 0000000..212bab3 --- /dev/null +++ b/tests/directive08-2.txt @@ -0,0 +1 @@ +@define directives $em(directives) diff --git a/tests/directive08.duck b/tests/directive08.duck new file mode 100644 index 0000000..ebfcb3f --- /dev/null +++ b/tests/directive08.duck @@ -0,0 +1,6 @@ +@ducktype/1.0 +@include directive08-1.txt + += Directive Test + +This is a test of $directives;. diff --git a/tests/directive08.page b/tests/directive08.page new file mode 100644 index 0000000..716ccdf --- /dev/null +++ b/tests/directive08.page @@ -0,0 +1,5 @@ + + + Directive Test +

This is a test of directives.

+
diff --git a/tests/directive09-1.txt b/tests/directive09-1.txt new file mode 100644 index 0000000..ef5bcc6 --- /dev/null +++ b/tests/directive09-1.txt @@ -0,0 +1 @@ +@include directive09-1.txt diff --git a/tests/directive09.duck b/tests/directive09.duck new file mode 100644 index 0000000..d562c02 --- /dev/null +++ b/tests/directive09.duck @@ -0,0 +1,5 @@ +@include directive09-1.txt + += Directive Test + +This is a test of directives. diff --git a/tests/directive09.error b/tests/directive09.error new file mode 100644 index 0000000..1fc8ee2 --- /dev/null +++ b/tests/directive09.error @@ -0,0 +1 @@ +directive09-1.txt:1: Recursive include detected: directive09-1.txt diff --git a/tests/directive10-1.txt b/tests/directive10-1.txt new file mode 100644 index 0000000..d625cae --- /dev/null +++ b/tests/directive10-1.txt @@ -0,0 +1 @@ +@include directive10-2.txt diff --git a/tests/directive10-2.txt b/tests/directive10-2.txt new file mode 100644 index 0000000..3afdf4c --- /dev/null +++ b/tests/directive10-2.txt @@ -0,0 +1 @@ +@include directive10-1.txt diff --git a/tests/directive10.duck b/tests/directive10.duck new file mode 100644 index 0000000..d533a9b --- /dev/null +++ b/tests/directive10.duck @@ -0,0 +1,5 @@ +@include directive10-1.txt + += Directive Test + +This is a test of directives. diff --git a/tests/directive10.error b/tests/directive10.error new file mode 100644 index 0000000..939e2c3 --- /dev/null +++ b/tests/directive10.error @@ -0,0 +1 @@ +directive10-2.txt:1: Recursive include detected: directive10-1.txt diff --git a/tests/directive11-1.txt b/tests/directive11-1.txt new file mode 100644 index 0000000..3219672 --- /dev/null +++ b/tests/directive11-1.txt @@ -0,0 +1 @@ +@define foo diff --git a/tests/directive11.duck b/tests/directive11.duck new file mode 100644 index 0000000..be3bc6f --- /dev/null +++ b/tests/directive11.duck @@ -0,0 +1,5 @@ +@include directive11-1.txt + += Directive Test + +This is a test of directives. diff --git a/tests/directive11.error b/tests/directive11.error new file mode 100644 index 0000000..71cc032 --- /dev/null +++ b/tests/directive11.error @@ -0,0 +1 @@ +directive11-1.txt:1: Entity definition takes exactly two values diff --git a/tests/directive12-1.txt b/tests/directive12-1.txt new file mode 100644 index 0000000..6e57915 --- /dev/null +++ b/tests/directive12-1.txt @@ -0,0 +1 @@ +@namespace foo diff --git a/tests/directive12.duck b/tests/directive12.duck new file mode 100644 index 0000000..0fac81d --- /dev/null +++ b/tests/directive12.duck @@ -0,0 +1,5 @@ +@include directive12-1.txt + += Directive Test + +This is a test of directives. diff --git a/tests/directive12.error b/tests/directive12.error new file mode 100644 index 0000000..09b7686 --- /dev/null +++ b/tests/directive12.error @@ -0,0 +1 @@ +directive12-1.txt:1: Namespace declaration takes exactly two values diff --git a/tests/directive13-1.txt b/tests/directive13-1.txt new file mode 100644 index 0000000..49c9c68 --- /dev/null +++ b/tests/directive13-1.txt @@ -0,0 +1,4 @@ +@namespace if http://projectmallard.org/if/1.0/ + +[wrong] +Directive includes can include only directives diff --git a/tests/directive13.duck b/tests/directive13.duck new file mode 100644 index 0000000..b6bef26 --- /dev/null +++ b/tests/directive13.duck @@ -0,0 +1,5 @@ +@include directive13-1.txt + += Directive Test + +This is a test of directives. diff --git a/tests/directive13.error b/tests/directive13.error new file mode 100644 index 0000000..9b19c0d --- /dev/null +++ b/tests/directive13.error @@ -0,0 +1 @@ +directive13-1.txt:3: Directive includes can only include directives diff --git a/tests/directive14-1.txt b/tests/directive14-1.txt new file mode 100644 index 0000000..48abe1f --- /dev/null +++ b/tests/directive14-1.txt @@ -0,0 +1,3 @@ +@ducktype/1.0 + +@namespace if http://projectmallard.org/if/1.0/ diff --git a/tests/directive14.duck b/tests/directive14.duck new file mode 100644 index 0000000..dabd867 --- /dev/null +++ b/tests/directive14.duck @@ -0,0 +1,6 @@ +@include directive14-1.txt + += Directive Test + +[if:if test=target:html] +This is a test of directives. diff --git a/tests/directive14.page b/tests/directive14.page new file mode 100644 index 0000000..0a030d4 --- /dev/null +++ b/tests/directive14.page @@ -0,0 +1,7 @@ + + + Directive Test + +

This is a test of directives.

+
+
diff --git a/tests/directive15-1.txt b/tests/directive15-1.txt new file mode 100644 index 0000000..ef219b1 --- /dev/null +++ b/tests/directive15-1.txt @@ -0,0 +1,3 @@ +@namespace if http://projectmallard.org/if/1.0/ + +@ducktype/1.0 diff --git a/tests/directive15.duck b/tests/directive15.duck new file mode 100644 index 0000000..6d4681b --- /dev/null +++ b/tests/directive15.duck @@ -0,0 +1,6 @@ +@include directive15-1.txt + += Directive Test + +[if:if test=target:html] +This is a test of directives. diff --git a/tests/directive15.error b/tests/directive15.error new file mode 100644 index 0000000..263fd40 --- /dev/null +++ b/tests/directive15.error @@ -0,0 +1 @@ +directive15-1.txt:3: Ducktype declaration must be first diff --git a/tests/directive16-1.txt b/tests/directive16-1.txt new file mode 100644 index 0000000..5cdd775 --- /dev/null +++ b/tests/directive16-1.txt @@ -0,0 +1,2 @@ +@ducktype/1.1 +@namespace if http://projectmallard.org/if/1.0/ diff --git a/tests/directive16.duck b/tests/directive16.duck new file mode 100644 index 0000000..bab1373 --- /dev/null +++ b/tests/directive16.duck @@ -0,0 +1,6 @@ +@include directive16-1.txt + += Directive Test + +[if:if test=target:html] +This is a test of directives. diff --git a/tests/directive16.error b/tests/directive16.error new file mode 100644 index 0000000..304740d --- /dev/null +++ b/tests/directive16.error @@ -0,0 +1 @@ +directive16-1.txt:1: Unsupported ducktype version: ducktype/1.1 diff --git a/tests/directive17-1.txt b/tests/directive17-1.txt new file mode 100644 index 0000000..9b0b61c --- /dev/null +++ b/tests/directive17-1.txt @@ -0,0 +1,2 @@ +@ducktype/1.0 foo/1.0 +@namespace if http://projectmallard.org/if/1.0/ diff --git a/tests/directive17.duck b/tests/directive17.duck new file mode 100644 index 0000000..eca2997 --- /dev/null +++ b/tests/directive17.duck @@ -0,0 +1,6 @@ +@include directive17-1.txt + += Directive Test + +[if:if test=target:html] +This is a test of directives. diff --git a/tests/directive17.error b/tests/directive17.error new file mode 100644 index 0000000..376c575 --- /dev/null +++ b/tests/directive17.error @@ -0,0 +1 @@ +directive17-1.txt:1: Unsupported ducktype extension: foo/1.0 diff --git a/tests/directive18 1.txt b/tests/directive18 1.txt new file mode 100644 index 0000000..e06c917 --- /dev/null +++ b/tests/directive18 1.txt @@ -0,0 +1 @@ +@namespace if http://projectmallard.org/if/1.0/ diff --git a/tests/directive18.duck b/tests/directive18.duck new file mode 100644 index 0000000..4ed5208 --- /dev/null +++ b/tests/directive18.duck @@ -0,0 +1,6 @@ +@include directive18%201.txt + += Directive Test + +[if:if test=target:html] +This is a test of directives. diff --git a/tests/directive18.page b/tests/directive18.page new file mode 100644 index 0000000..ecdcf0f --- /dev/null +++ b/tests/directive18.page @@ -0,0 +1,7 @@ + + + Directive Test + +

This is a test of directives.

+
+
diff --git a/tests/directive19 1.txt b/tests/directive19 1.txt new file mode 100644 index 0000000..9dbeb0d --- /dev/null +++ b/tests/directive19 1.txt @@ -0,0 +1 @@ +@include directive19%202.txt diff --git a/tests/directive19 2.txt b/tests/directive19 2.txt new file mode 100644 index 0000000..e06c917 --- /dev/null +++ b/tests/directive19 2.txt @@ -0,0 +1 @@ +@namespace if http://projectmallard.org/if/1.0/ diff --git a/tests/directive19.duck b/tests/directive19.duck new file mode 100644 index 0000000..4e17c05 --- /dev/null +++ b/tests/directive19.duck @@ -0,0 +1,6 @@ +@include directive19%201.txt + += Directive Test + +[if:if test=target:html] +This is a test of directives. diff --git a/tests/directive19.page b/tests/directive19.page new file mode 100644 index 0000000..19ed058 --- /dev/null +++ b/tests/directive19.page @@ -0,0 +1,7 @@ + + + Directive Test + +

This is a test of directives.

+
+
diff --git a/tests/directive20.duck b/tests/directive20.duck new file mode 100644 index 0000000..c12fb4c --- /dev/null +++ b/tests/directive20.duck @@ -0,0 +1,6 @@ +@include directive20 1.txt + += Directive Test + +[if:if test=target:html] +This is a test of directives. diff --git a/tests/directive20.error b/tests/directive20.error new file mode 100644 index 0000000..118a59c --- /dev/null +++ b/tests/directive20.error @@ -0,0 +1 @@ +directive20.duck:1: Multiple values in include. URL encode file name? diff --git a/tests/directive21 1.txt b/tests/directive21 1.txt new file mode 100644 index 0000000..acbedc8 --- /dev/null +++ b/tests/directive21 1.txt @@ -0,0 +1 @@ +@include directive21 2.txt diff --git a/tests/directive21.duck b/tests/directive21.duck new file mode 100644 index 0000000..1ee9381 --- /dev/null +++ b/tests/directive21.duck @@ -0,0 +1,6 @@ +@include directive21%201.txt + += Directive Test + +[if:if test=target:html] +This is a test of directives. diff --git a/tests/directive21.error b/tests/directive21.error new file mode 100644 index 0000000..e80ba7a --- /dev/null +++ b/tests/directive21.error @@ -0,0 +1 @@ +directive21 1.txt:1: Multiple values in include. URL encode file name? diff --git a/tests/docbook01.duck b/tests/docbook01.duck new file mode 100644 index 0000000..956b96c --- /dev/null +++ b/tests/docbook01.duck @@ -0,0 +1,5 @@ +@ducktype/1.0 docbook/experimental + += DocBook Test + +This is a DocBook test. diff --git a/tests/docbook01.page b/tests/docbook01.page new file mode 100644 index 0000000..39afe53 --- /dev/null +++ b/tests/docbook01.page @@ -0,0 +1,5 @@ + +
+ DocBook Test + This is a DocBook test. +
diff --git a/tests/docbook02.duck b/tests/docbook02.duck new file mode 100644 index 0000000..d0c4535 --- /dev/null +++ b/tests/docbook02.duck @@ -0,0 +1,7 @@ +@ducktype/1.0 docbook/experimental + += DocBook Test + +* Item 1 +* Item 2 +* Item 3 diff --git a/tests/docbook02.page b/tests/docbook02.page new file mode 100644 index 0000000..187ce42 --- /dev/null +++ b/tests/docbook02.page @@ -0,0 +1,15 @@ + +
+ DocBook Test + + + Item 1 + + + Item 2 + + + Item 3 + + +
diff --git a/tests/docbook03.duck b/tests/docbook03.duck new file mode 100644 index 0000000..2fb4da6 --- /dev/null +++ b/tests/docbook03.duck @@ -0,0 +1,8 @@ +@ducktype/1.0 docbook/experimental + += DocBook Test + +[itemizedlist] +* Item 1 +* Item 2 +* Item 3 diff --git a/tests/docbook03.page b/tests/docbook03.page new file mode 100644 index 0000000..28cf2c6 --- /dev/null +++ b/tests/docbook03.page @@ -0,0 +1,15 @@ + +
+ DocBook Test + + + Item 1 + + + Item 2 + + + Item 3 + + +
diff --git a/tests/docbook04.duck b/tests/docbook04.duck new file mode 100644 index 0000000..f33aa02 --- /dev/null +++ b/tests/docbook04.duck @@ -0,0 +1,8 @@ +@ducktype/1.0 docbook/experimental + += DocBook Test + +[orderedlist] +* Item 1 +* Item 2 +* Item 3 diff --git a/tests/docbook04.page b/tests/docbook04.page new file mode 100644 index 0000000..8bcbe93 --- /dev/null +++ b/tests/docbook04.page @@ -0,0 +1,15 @@ + +
+ DocBook Test + + + Item 1 + + + Item 2 + + + Item 3 + + +
diff --git a/tests/docbook05.duck b/tests/docbook05.duck new file mode 100644 index 0000000..8649077 --- /dev/null +++ b/tests/docbook05.duck @@ -0,0 +1,10 @@ +@ducktype/1.0 docbook/experimental + += DocBook Test + +[orderedlist] +* Item 1 + * Sub 1 + * Sub 2 +* Item 2 +* Item 3 diff --git a/tests/docbook05.page b/tests/docbook05.page new file mode 100644 index 0000000..d435668 --- /dev/null +++ b/tests/docbook05.page @@ -0,0 +1,23 @@ + +
+ DocBook Test + + + Item 1 + + + Sub 1 + + + Sub 2 + + + + + Item 2 + + + Item 3 + + +
diff --git a/tests/docbook06.duck b/tests/docbook06.duck new file mode 100644 index 0000000..eb6250f --- /dev/null +++ b/tests/docbook06.duck @@ -0,0 +1,13 @@ +@ducktype/1.0 docbook/experimental + += DocBook Test + +== Section 1 + +=== Section 1.1 +--- Subtitle 1.1 + +Hello + +== Section 2 +-- Subtitle 2 diff --git a/tests/docbook06.page b/tests/docbook06.page new file mode 100644 index 0000000..0088487 --- /dev/null +++ b/tests/docbook06.page @@ -0,0 +1,16 @@ + +
+ DocBook Test +
+ Section 1 +
+ Section 1.1 + Subtitle 1.1 + Hello +
+
+
+ Section 2 + Subtitle 2 +
+
diff --git a/tests/docbook07.duck b/tests/docbook07.duck new file mode 100644 index 0000000..c654cd0 --- /dev/null +++ b/tests/docbook07.duck @@ -0,0 +1,32 @@ +@ducktype/1.0 docbook/experimental + += DocBook Test +@abstract abstract +@abstract + abstract +@annotation annotation +@annotation + annotation +@cover + cover p1 + + cover p2 +@legalnotice + @title + LEGAL + NOTICE +@revhistory + @title + Revision History + @revision + @revnumber 1 + @date 1970-01-01 + @authorinitials SM + @revdescription + description + @revremark + remark +@subjectset + @subject + @subjectterm + subject diff --git a/tests/docbook07.page b/tests/docbook07.page new file mode 100644 index 0000000..9cb2635 --- /dev/null +++ b/tests/docbook07.page @@ -0,0 +1,43 @@ + +
+ DocBook Test + + + abstract + + + abstract + + + annotation + + + annotation + + + cover p1 + cover p2 + + + LEGAL + NOTICE + + + Revision History + + 1 + 1970-01-01 + SM + + description + + remark + + + + + subject + + + +
diff --git a/tests/docbook08.duck b/tests/docbook08.duck new file mode 100644 index 0000000..09b420e --- /dev/null +++ b/tests/docbook08.duck @@ -0,0 +1,11 @@ +@ducktype/1.0 docbook/experimental + += DocBook Test +@author + @personname Rupert Monkey +@author + @personname + Wanda the Fish +@authorinitials RM +@authorinitials + WF diff --git a/tests/docbook08.page b/tests/docbook08.page new file mode 100644 index 0000000..1fe3d9f --- /dev/null +++ b/tests/docbook08.page @@ -0,0 +1,14 @@ + +
+ DocBook Test + + + Rupert Monkey + + + Wanda the Fish + + RM + WF + +
diff --git a/tests/docbook09.duck b/tests/docbook09.duck new file mode 100644 index 0000000..ed705d3 --- /dev/null +++ b/tests/docbook09.duck @@ -0,0 +1,17 @@ +@ducktype/1.0 docbook/experimental + += DocBook Test +@author + @personname + @honorific Dr + @firstname Rupert + @surname Monkey + @lineage III +@author + @personname + @givenname + Wanda + @othername + the + @surname + Fish diff --git a/tests/docbook09.page b/tests/docbook09.page new file mode 100644 index 0000000..57552ea --- /dev/null +++ b/tests/docbook09.page @@ -0,0 +1,21 @@ + +
+ DocBook Test + + + + Dr + Rupert + Monkey + III + + + + + Wanda + the + Fish + + + +
diff --git a/tests/docbook10.duck b/tests/docbook10.duck new file mode 100644 index 0000000..aae5f95 --- /dev/null +++ b/tests/docbook10.duck @@ -0,0 +1,17 @@ +@ducktype/1.0 docbook/experimental + += DocBook Test +@authorgroup + @editor + @personname Rupert Monkey + @address 123 Monkey Lane + @affiliation + @shortaffil Simians + @jobtitle Code Monkey + @contrib monkeying around + @email rupert@example.com + @personblurb ooh ooh aah aah + @uri http://example.com/ + @editor + @orgname Primates + @orgdiv Simians diff --git a/tests/docbook10.page b/tests/docbook10.page new file mode 100644 index 0000000..8cf2e04 --- /dev/null +++ b/tests/docbook10.page @@ -0,0 +1,26 @@ + +
+ DocBook Test + + + + Rupert Monkey +
123 Monkey Lane
+ + Simians + Code Monkey + + monkeying around + rupert@example.com + + ooh ooh aah aah + + http://example.com/ +
+ + Primates + Simians + +
+
+
diff --git a/tests/docbook11.duck b/tests/docbook11.duck new file mode 100644 index 0000000..c5785b3 --- /dev/null +++ b/tests/docbook11.duck @@ -0,0 +1,32 @@ +@ducktype/1.0 docbook/experimental + += DocBook Test +@artpagenums 1-2 +@confgroup + @confdates 1970-01-01 + @confnum 42 + @confsponsor + Sponsor + @conftitle + Conference +@contractnum 1234 +@contractsponsor + Sponsor +@copyright + @year 2019 + @holder Shaun McCance +@edition first +@issuenum 42 +@keywordset + @keyword one + @keyword + two +@pagenums + 1-2 +@productname Product +@productnumber + Number +@pubdate 1970-01-01 +@releaseinfo test +@seriesvolnums 1-2 +@volumenum 1 diff --git a/tests/docbook11.page b/tests/docbook11.page new file mode 100644 index 0000000..1b59627 --- /dev/null +++ b/tests/docbook11.page @@ -0,0 +1,32 @@ + +
+ DocBook Test + + 1-2 + + 1970-01-01 + 42 + Sponsor + Conference + + 1234 + Sponsor + + 2019 + Shaun McCance + + first + 42 + + one + two + + 1-2 + Product + Number + 1970-01-01 + test + 1-2 + 1 + +
diff --git a/tests/error01.duck b/tests/error01.duck new file mode 100644 index 0000000..c59916e --- /dev/null +++ b/tests/error01.duck @@ -0,0 +1,3 @@ += Error Test + +[code diff --git a/tests/error01.error b/tests/error01.error new file mode 100644 index 0000000..17b4bfd --- /dev/null +++ b/tests/error01.error @@ -0,0 +1 @@ +error01.duck:3: Unterminated block declaration diff --git a/tests/error02.duck b/tests/error02.duck new file mode 100644 index 0000000..5b10d24 --- /dev/null +++ b/tests/error02.duck @@ -0,0 +1,4 @@ += Error Test + +[code +Somebody forgot to close the $code(code) element above. diff --git a/tests/error02.error b/tests/error02.error new file mode 100644 index 0000000..d2fd61c --- /dev/null +++ b/tests/error02.error @@ -0,0 +1 @@ +error02.duck:4: Invalid character $ in attribute list diff --git a/tests/error03.duck b/tests/error03.duck new file mode 100644 index 0000000..a999d0a --- /dev/null +++ b/tests/error03.duck @@ -0,0 +1,5 @@ += Error Test + +[listing +[code] + Somebody forgot to close the $code(listing) element above. diff --git a/tests/error03.error b/tests/error03.error new file mode 100644 index 0000000..a21606f --- /dev/null +++ b/tests/error03.error @@ -0,0 +1 @@ +error03.duck:4: Invalid character [ in attribute list diff --git a/tests/error04.duck b/tests/error04.duck new file mode 100644 index 0000000..891961d --- /dev/null +++ b/tests/error04.duck @@ -0,0 +1,3 @@ += Error Test + +[listing =foo] diff --git a/tests/error04.error b/tests/error04.error new file mode 100644 index 0000000..6691976 --- /dev/null +++ b/tests/error04.error @@ -0,0 +1 @@ +error04.duck:3: Invalid character = in attribute list diff --git a/tests/error05.duck b/tests/error05.duck new file mode 100644 index 0000000..e5cfb32 --- /dev/null +++ b/tests/error05.duck @@ -0,0 +1,3 @@ += Error Test + +This is a test of an $unknown; entity. diff --git a/tests/error05.error b/tests/error05.error new file mode 100644 index 0000000..d483e34 --- /dev/null +++ b/tests/error05.error @@ -0,0 +1 @@ +error05.duck:3: Unrecognized entity: unknown diff --git a/tests/error06.duck b/tests/error06.duck new file mode 100644 index 0000000..1d7fe1e --- /dev/null +++ b/tests/error06.duck @@ -0,0 +1,5 @@ += Error Test + +This is another test +of an $unknown; entity, +but not on the first or last line. diff --git a/tests/error06.error b/tests/error06.error new file mode 100644 index 0000000..2fec3a9 --- /dev/null +++ b/tests/error06.error @@ -0,0 +1 @@ +error06.duck:4: Unrecognized entity: unknown diff --git a/tests/error07.duck b/tests/error07.duck new file mode 100644 index 0000000..6827abb --- /dev/null +++ b/tests/error07.duck @@ -0,0 +1,7 @@ += Error Test + +This is another test with $em[.bold +.strong style="bold +and strong"](an +$unknown; entity) +after some line breaks in attributes. diff --git a/tests/error07.error b/tests/error07.error new file mode 100644 index 0000000..03c08fb --- /dev/null +++ b/tests/error07.error @@ -0,0 +1 @@ +error07.duck:6: Unrecognized entity: unknown diff --git a/tests/error08.duck b/tests/error08.duck new file mode 100644 index 0000000..4e8b93e --- /dev/null +++ b/tests/error08.duck @@ -0,0 +1,3 @@ += Error Test + +This is a test of an $em[style="$unknown;"](entity). diff --git a/tests/error08.error b/tests/error08.error new file mode 100644 index 0000000..00b9cae --- /dev/null +++ b/tests/error08.error @@ -0,0 +1 @@ +error08.duck:3: Unrecognized entity: unknown diff --git a/tests/error09.duck b/tests/error09.duck new file mode 100644 index 0000000..68083e6 --- /dev/null +++ b/tests/error09.duck @@ -0,0 +1,6 @@ += Error Test + +This is a test of an $em[.bold +style="strong +$unknown;" +](entity). diff --git a/tests/error09.error b/tests/error09.error new file mode 100644 index 0000000..1b7449f --- /dev/null +++ b/tests/error09.error @@ -0,0 +1 @@ +error09.duck:5: Unrecognized entity: unknown diff --git a/tests/error10.duck b/tests/error10.duck new file mode 100644 index 0000000..71d9c5a --- /dev/null +++ b/tests/error10.duck @@ -0,0 +1,3 @@ +-- Error Test + +This page doesn't start with a =. diff --git a/tests/error10.error b/tests/error10.error new file mode 100644 index 0000000..0aa01ca --- /dev/null +++ b/tests/error10.error @@ -0,0 +1 @@ +error10.duck:1: Missing page header diff --git a/tests/error11.duck b/tests/error11.duck new file mode 100644 index 0000000..67ed962 --- /dev/null +++ b/tests/error11.duck @@ -0,0 +1,5 @@ += Error Test + +== Section + +==== This is too deep diff --git a/tests/error11.error b/tests/error11.error new file mode 100644 index 0000000..73bc4a4 --- /dev/null +++ b/tests/error11.error @@ -0,0 +1 @@ +error11.duck:5: Incorrect section depth diff --git a/tests/error12.duck b/tests/error12.duck new file mode 100644 index 0000000..7985500 --- /dev/null +++ b/tests/error12.duck @@ -0,0 +1,4 @@ += Error Test + +[terms] +* Hello diff --git a/tests/error12.error b/tests/error12.error new file mode 100644 index 0000000..25c1429 --- /dev/null +++ b/tests/error12.error @@ -0,0 +1 @@ +error12.duck:4: Missing item title in terms diff --git a/tests/error13.duck b/tests/error13.duck new file mode 100644 index 0000000..ea99ca3 --- /dev/null +++ b/tests/error13.duck @@ -0,0 +1,7 @@ +@define foo bar + +@ducktype/1.0 + += Error Test + +Hello diff --git a/tests/error13.error b/tests/error13.error new file mode 100644 index 0000000..b86e173 --- /dev/null +++ b/tests/error13.error @@ -0,0 +1 @@ +error13.duck:3: Ducktype declaration must be first diff --git a/tests/error14.duck b/tests/error14.duck new file mode 100644 index 0000000..737bf77 --- /dev/null +++ b/tests/error14.duck @@ -0,0 +1,6 @@ + +@ducktype/1.0 + += Error Test + +Hello diff --git a/tests/error14.error b/tests/error14.error new file mode 100644 index 0000000..e1391ed --- /dev/null +++ b/tests/error14.error @@ -0,0 +1 @@ +error14.duck:2: Ducktype declaration must be first diff --git a/tests/error15.duck b/tests/error15.duck new file mode 100644 index 0000000..668e42b --- /dev/null +++ b/tests/error15.duck @@ -0,0 +1,5 @@ +@ducktype/4.0 + += Error Test + +Hello diff --git a/tests/error15.error b/tests/error15.error new file mode 100644 index 0000000..ba435e5 --- /dev/null +++ b/tests/error15.error @@ -0,0 +1 @@ +error15.duck:1: Unsupported ducktype version: ducktype/4.0 diff --git a/tests/error16.duck b/tests/error16.duck new file mode 100644 index 0000000..75a7c09 --- /dev/null +++ b/tests/error16.duck @@ -0,0 +1,5 @@ +@ducktype/1.0 badextension/0.1 + += Error Test + +Hello diff --git a/tests/error16.error b/tests/error16.error new file mode 100644 index 0000000..31d3db9 --- /dev/null +++ b/tests/error16.error @@ -0,0 +1 @@ +error16.duck:1: Unsupported ducktype extension: badextension/0.1 diff --git a/tests/error17.duck b/tests/error17.duck new file mode 100644 index 0000000..6e29781 --- /dev/null +++ b/tests/error17.duck @@ -0,0 +1,5 @@ +@ducktype/1.0 badextension="bar" + += Error Test + +Hello diff --git a/tests/error17.error b/tests/error17.error new file mode 100644 index 0000000..fe90d8b --- /dev/null +++ b/tests/error17.error @@ -0,0 +1 @@ +error17.duck:1: Unsupported ducktype extension: badextension="bar" diff --git a/tests/error18.duck b/tests/error18.duck new file mode 100644 index 0000000..5a14445 --- /dev/null +++ b/tests/error18.duck @@ -0,0 +1,5 @@ +@ducktype/1.0 badextension=bar + += Error Test + +Hello diff --git a/tests/error18.error b/tests/error18.error new file mode 100644 index 0000000..0808f61 --- /dev/null +++ b/tests/error18.error @@ -0,0 +1 @@ +error18.duck:1: Unsupported ducktype extension: badextension=bar diff --git a/tests/error19.duck b/tests/error19.duck new file mode 100644 index 0000000..1427ef6 --- /dev/null +++ b/tests/error19.duck @@ -0,0 +1,6 @@ +@ducktype/1.0 +@namespace badvalue + += Directive Test + +This is a test of directives. diff --git a/tests/error19.error b/tests/error19.error new file mode 100644 index 0000000..b954572 --- /dev/null +++ b/tests/error19.error @@ -0,0 +1 @@ +error19.duck:2: Namespace declaration takes exactly two values diff --git a/tests/extension01.duck b/tests/extension01.duck new file mode 100644 index 0000000..4751ede --- /dev/null +++ b/tests/extension01.duck @@ -0,0 +1,11 @@ +@ducktype/1.0 _test/block + += Extension Test + +This is before the test. +*** TESTING + This is a test. + + This is also a test. + + This is after the test. diff --git a/tests/extension01.page b/tests/extension01.page new file mode 100644 index 0000000..4afc154 --- /dev/null +++ b/tests/extension01.page @@ -0,0 +1,10 @@ + + + Extension Test +

This is before the test.

+ +

This is a test.

+

This is also a test.

+
+

This is after the test.

+
diff --git a/tests/extension02.duck b/tests/extension02.duck new file mode 100644 index 0000000..5b4c436 --- /dev/null +++ b/tests/extension02.duck @@ -0,0 +1,9 @@ +@ducktype/1.0 _test/block + += Extension Test + +This is before the test. +*** TESTING 1 +This in testing 1. +*** TESTING 2 +This in testing 2. diff --git a/tests/extension02.page b/tests/extension02.page new file mode 100644 index 0000000..cb29b04 --- /dev/null +++ b/tests/extension02.page @@ -0,0 +1,11 @@ + + + Extension Test +

This is before the test.

+ +

This in testing 1.

+
+ +

This in testing 2.

+
+
diff --git a/tests/extension03.duck b/tests/extension03.duck new file mode 100644 index 0000000..35258c0 --- /dev/null +++ b/tests/extension03.duck @@ -0,0 +1,8 @@ +@ducktype/1.0 _test/directive +@_test:defines + += Extension Test + +This is a test of directive extensions. + +$TEST; diff --git a/tests/extension03.page b/tests/extension03.page new file mode 100644 index 0000000..fc31f2b --- /dev/null +++ b/tests/extension03.page @@ -0,0 +1,6 @@ + + + Extension Test +

This is a test of directive extensions.

+

This is a test. It is only a test.

+
diff --git a/tests/extension04.duck b/tests/extension04.duck new file mode 100644 index 0000000..fd245a9 --- /dev/null +++ b/tests/extension04.duck @@ -0,0 +1,6 @@ +@ducktype/1.0 _test/directive +@test:defines + += Extension Test + +This is a test of directive extensions. diff --git a/tests/extension04.error b/tests/extension04.error new file mode 100644 index 0000000..a109ea8 --- /dev/null +++ b/tests/extension04.error @@ -0,0 +1 @@ +extension04.duck:2: Unrecognized directive prefix: test diff --git a/tests/extension05-1.txt b/tests/extension05-1.txt new file mode 100644 index 0000000..f5d0a05 --- /dev/null +++ b/tests/extension05-1.txt @@ -0,0 +1,2 @@ +@ducktype/1.0 _test/directive +@_test:defines diff --git a/tests/extension05.duck b/tests/extension05.duck new file mode 100644 index 0000000..5639a28 --- /dev/null +++ b/tests/extension05.duck @@ -0,0 +1,7 @@ +@include extension05-1.txt + += Extension Test + +This is a test of directive extensions. + +$TEST; diff --git a/tests/extension05.page b/tests/extension05.page new file mode 100644 index 0000000..ae51d57 --- /dev/null +++ b/tests/extension05.page @@ -0,0 +1,6 @@ + + + Extension Test +

This is a test of directive extensions.

+

This is a test. It is only a test.

+
diff --git a/tests/extension06.duck b/tests/extension06.duck new file mode 100644 index 0000000..397fbe1 --- /dev/null +++ b/tests/extension06.duck @@ -0,0 +1,8 @@ +@ducktype/1.0 _test/blocknode + += Extension Test + +This is a test of block node extensions. +[_test:block] + This is a test. +This is after the test. diff --git a/tests/extension06.page b/tests/extension06.page new file mode 100644 index 0000000..ea29e0a --- /dev/null +++ b/tests/extension06.page @@ -0,0 +1,9 @@ + + + Extension Test +

This is a test of block node extensions.

+ +

This is a test.

+
+

This is after the test.

+
diff --git a/tests/extension07.duck b/tests/extension07.duck new file mode 100644 index 0000000..df7ccf2 --- /dev/null +++ b/tests/extension07.duck @@ -0,0 +1,11 @@ +@ducktype/1.0 _test/blocknode + += Extension Test + +This is a test of block node extensions. +[_test:block .testing] + This is a test. + + This is also a test. + + This is after the test. diff --git a/tests/extension07.page b/tests/extension07.page new file mode 100644 index 0000000..1df77bf --- /dev/null +++ b/tests/extension07.page @@ -0,0 +1,10 @@ + + + Extension Test +

This is a test of block node extensions.

+ +

This is a test.

+

This is also a test.

+
+

This is after the test.

+
diff --git a/tests/extension08.duck b/tests/extension08.duck new file mode 100644 index 0000000..c3c0397 --- /dev/null +++ b/tests/extension08.duck @@ -0,0 +1,5 @@ +@ducktype/1.0 _test/blocknode + += Extension Test + +[_test:blocks .testing] diff --git a/tests/extension08.error b/tests/extension08.error new file mode 100644 index 0000000..cf4e852 --- /dev/null +++ b/tests/extension08.error @@ -0,0 +1 @@ +extension08.duck:5: Unrecognized extension element: _test:blocks diff --git a/tests/extension09.duck b/tests/extension09.duck new file mode 100644 index 0000000..f55fc42 --- /dev/null +++ b/tests/extension09.duck @@ -0,0 +1,6 @@ +@ducktype/1.0 _test/blocknode +@namespace _test http://projectmallard.org/experimental/_test + += Extension Test + +[_test:blocks .testing] diff --git a/tests/extension09.page b/tests/extension09.page new file mode 100644 index 0000000..c73d01c --- /dev/null +++ b/tests/extension09.page @@ -0,0 +1,5 @@ + + + Extension Test + <_test:blocks style="testing"/> + diff --git a/tests/fenced01.duck b/tests/fenced01.duck new file mode 100644 index 0000000..c3be21d --- /dev/null +++ b/tests/fenced01.duck @@ -0,0 +1,9 @@ += Fenced Test + +This tests fenced blocks. + +[code] +[[[ +This is some code. +This is some more code. +]]] diff --git a/tests/fenced01.page b/tests/fenced01.page new file mode 100644 index 0000000..3c62a6a --- /dev/null +++ b/tests/fenced01.page @@ -0,0 +1,7 @@ + + + Fenced Test +

This tests fenced blocks.

+ This is some code. +This is some more code. +
diff --git a/tests/fenced02.duck b/tests/fenced02.duck new file mode 100644 index 0000000..31e6419 --- /dev/null +++ b/tests/fenced02.duck @@ -0,0 +1,10 @@ += Fenced Test + +This tests fenced blocks. + +[code] +[[[ +[note] +This is some code. +This is some more code. +]]] diff --git a/tests/fenced02.page b/tests/fenced02.page new file mode 100644 index 0000000..44fe777 --- /dev/null +++ b/tests/fenced02.page @@ -0,0 +1,8 @@ + + + Fenced Test +

This tests fenced blocks.

+ [note] +This is some code. +This is some more code. +
diff --git a/tests/fenced03.duck b/tests/fenced03.duck new file mode 100644 index 0000000..d2996b1 --- /dev/null +++ b/tests/fenced03.duck @@ -0,0 +1,11 @@ += Fenced Test + +This tests fenced blocks. + +[code] +[[[ + +

This is some code. +This is some more code.

+
+]]] diff --git a/tests/fenced03.page b/tests/fenced03.page new file mode 100644 index 0000000..bfdd72a --- /dev/null +++ b/tests/fenced03.page @@ -0,0 +1,9 @@ + + + Fenced Test +

This tests fenced blocks.

+ <note> +<p>This is some code. +This is some more code.</p> +</note> +
diff --git a/tests/fenced04.duck b/tests/fenced04.duck new file mode 100644 index 0000000..ef46468 --- /dev/null +++ b/tests/fenced04.duck @@ -0,0 +1,9 @@ += Fenced Test + +This tests fenced blocks. + +[code] +[[[ +This is some $code(code). +This is some more code. +]]] diff --git a/tests/fenced04.page b/tests/fenced04.page new file mode 100644 index 0000000..77c9ae9 --- /dev/null +++ b/tests/fenced04.page @@ -0,0 +1,7 @@ + + + Fenced Test +

This tests fenced blocks.

+ This is some $code(code). +This is some more code. +
diff --git a/tests/fenced05.duck b/tests/fenced05.duck new file mode 100644 index 0000000..c16e028 --- /dev/null +++ b/tests/fenced05.duck @@ -0,0 +1,7 @@ += Fenced Test + +This tests fenced blocks. + +[code] +[[[This is some $code(code).]]] +[[[This is some more code.]]] diff --git a/tests/fenced05.page b/tests/fenced05.page new file mode 100644 index 0000000..84ea733 --- /dev/null +++ b/tests/fenced05.page @@ -0,0 +1,7 @@ + + + Fenced Test +

This tests fenced blocks.

+ This is some $code(code). +This is some more code. +
diff --git a/tests/fenced06.duck b/tests/fenced06.duck new file mode 100644 index 0000000..2c32d57 --- /dev/null +++ b/tests/fenced06.duck @@ -0,0 +1,10 @@ += Fenced Test + +This tests fenced blocks. + +[code] +1: This is some $var(code). +[[[2: This is some $code(code).]]] +$em(3: This is some $var(code).) +[[[4: This is some $code(code).]]] +5: This is some $var(code). diff --git a/tests/fenced06.page b/tests/fenced06.page new file mode 100644 index 0000000..447801c --- /dev/null +++ b/tests/fenced06.page @@ -0,0 +1,10 @@ + + + Fenced Test +

This tests fenced blocks.

+ 1: This is some code. +2: This is some $code(code). +3: This is some code. +4: This is some $code(code). +5: This is some code. +
diff --git a/tests/fenced07.duck b/tests/fenced07.duck new file mode 100644 index 0000000..19acecc --- /dev/null +++ b/tests/fenced07.duck @@ -0,0 +1,11 @@ += Fenced Test + +This tests fenced blocks. + +[code] + [[[ + +

This is some code. + This is some more code.

+
+]]] diff --git a/tests/fenced07.page b/tests/fenced07.page new file mode 100644 index 0000000..e38a821 --- /dev/null +++ b/tests/fenced07.page @@ -0,0 +1,9 @@ + + + Fenced Test +

This tests fenced blocks.

+ <note> +<p>This is some code. +This is some more code.</p> +</note> +
diff --git a/tests/fenced08.duck b/tests/fenced08.duck new file mode 100644 index 0000000..f5079e2 --- /dev/null +++ b/tests/fenced08.duck @@ -0,0 +1,10 @@ += Fenced Test + +This tests fenced blocks. + +[code] + [[[ + This sets the indent strip level. + This should be indented by 2. + This is an anomoloy, but should be at column 0. +]]] diff --git a/tests/fenced08.page b/tests/fenced08.page new file mode 100644 index 0000000..8286bd1 --- /dev/null +++ b/tests/fenced08.page @@ -0,0 +1,8 @@ + + + Fenced Test +

This tests fenced blocks.

+ This sets the indent strip level. + This should be indented by 2. +This is an anomoloy, but should be at column 0. +
diff --git a/tests/fenced10.duck b/tests/fenced10.duck new file mode 100644 index 0000000..add0770 --- /dev/null +++ b/tests/fenced10.duck @@ -0,0 +1,5 @@ += Fenced Test + +This tests fenced blocks. + +[[[This gets a paragraph.]]] diff --git a/tests/fenced10.page b/tests/fenced10.page new file mode 100644 index 0000000..41e2d63 --- /dev/null +++ b/tests/fenced10.page @@ -0,0 +1,6 @@ + + + Fenced Test +

This tests fenced blocks.

+

This gets a paragraph.

+
diff --git a/tests/fenced11.duck b/tests/fenced11.duck new file mode 100644 index 0000000..c8ea979 --- /dev/null +++ b/tests/fenced11.duck @@ -0,0 +1,7 @@ += Fenced Test + +This tests fenced blocks. + +[[[ +This gets a paragraph. +]]] diff --git a/tests/fenced11.page b/tests/fenced11.page new file mode 100644 index 0000000..05c4806 --- /dev/null +++ b/tests/fenced11.page @@ -0,0 +1,6 @@ + + + Fenced Test +

This tests fenced blocks.

+

This gets a paragraph.

+
diff --git a/tests/fenced12.duck b/tests/fenced12.duck new file mode 100644 index 0000000..476e6a8 --- /dev/null +++ b/tests/fenced12.duck @@ -0,0 +1,7 @@ += Fenced Test + +This tests fenced blocks. + +[note] + This is a paragraph in a note. + [[[This is the same paragraph.]]] diff --git a/tests/fenced12.page b/tests/fenced12.page new file mode 100644 index 0000000..d297079 --- /dev/null +++ b/tests/fenced12.page @@ -0,0 +1,9 @@ + + + Fenced Test +

This tests fenced blocks.

+ +

This is a paragraph in a note. + This is the same paragraph.

+
+
diff --git a/tests/fenced13.duck b/tests/fenced13.duck new file mode 100644 index 0000000..823b023 --- /dev/null +++ b/tests/fenced13.duck @@ -0,0 +1,10 @@ += Fenced Test + +This tests fenced blocks. + +[note] + This is a paragraph in a note. + [[[ + This is the same paragraph. +So is this, but without indent. +]]] diff --git a/tests/fenced13.page b/tests/fenced13.page new file mode 100644 index 0000000..7ac6680 --- /dev/null +++ b/tests/fenced13.page @@ -0,0 +1,10 @@ + + + Fenced Test +

This tests fenced blocks.

+ +

This is a paragraph in a note. + This is the same paragraph. +So is this, but without indent.

+
+
diff --git a/tests/fenced14.duck b/tests/fenced14.duck new file mode 100644 index 0000000..c2ff7af --- /dev/null +++ b/tests/fenced14.duck @@ -0,0 +1,12 @@ += Fenced Test + +This tests fenced blocks. + +[note] + This is a paragraph in a note. + [[[ + This is the same paragraph. + ]]] + This is still in that paragraph. + + [[[This is a new paragraph in the note.]]] diff --git a/tests/fenced14.page b/tests/fenced14.page new file mode 100644 index 0000000..86ad227 --- /dev/null +++ b/tests/fenced14.page @@ -0,0 +1,11 @@ + + + Fenced Test +

This tests fenced blocks.

+ +

This is a paragraph in a note. + This is the same paragraph. + This is still in that paragraph.

+

This is a new paragraph in the note.

+
+
diff --git a/tests/fenced15.duck b/tests/fenced15.duck new file mode 100644 index 0000000..f00869b --- /dev/null +++ b/tests/fenced15.duck @@ -0,0 +1,10 @@ += Fenced Test + +This tests fenced blocks. + +[code] +[[[ +This is code. + +The code has a line break. +]]] diff --git a/tests/fenced15.page b/tests/fenced15.page new file mode 100644 index 0000000..f3be7c3 --- /dev/null +++ b/tests/fenced15.page @@ -0,0 +1,8 @@ + + + Fenced Test +

This tests fenced blocks.

+ This is code. + +The code has a line break. +
diff --git a/tests/fenced16.duck b/tests/fenced16.duck new file mode 100644 index 0000000..3969ab5 --- /dev/null +++ b/tests/fenced16.duck @@ -0,0 +1,12 @@ += Fenced Test + +This tests fenced blocks. + +[code] +[[[ +This is code. +[-] This is not a comment. +[-- +This is not a comment. +--] +]]] diff --git a/tests/fenced16.page b/tests/fenced16.page new file mode 100644 index 0000000..46727da --- /dev/null +++ b/tests/fenced16.page @@ -0,0 +1,10 @@ + + + Fenced Test +

This tests fenced blocks.

+ This is code. +[-] This is not a comment. +[-- +This is not a comment. +--] +
diff --git a/tests/fenced17.duck b/tests/fenced17.duck new file mode 100644 index 0000000..8af7eb0 --- /dev/null +++ b/tests/fenced17.duck @@ -0,0 +1,8 @@ += Fenced Test + +[code] + [[[ + hello + world + ]]] + bye diff --git a/tests/fenced17.page b/tests/fenced17.page new file mode 100644 index 0000000..d43d7da --- /dev/null +++ b/tests/fenced17.page @@ -0,0 +1,7 @@ + + + Fenced Test + hello + world + bye + diff --git a/tests/fenced18.duck b/tests/fenced18.duck new file mode 100644 index 0000000..92aa553 --- /dev/null +++ b/tests/fenced18.duck @@ -0,0 +1,6 @@ += Fenced Test + +[code] + [[[]]] + hello + world diff --git a/tests/fenced18.page b/tests/fenced18.page new file mode 100644 index 0000000..6a813bc --- /dev/null +++ b/tests/fenced18.page @@ -0,0 +1,7 @@ + + + Fenced Test + + hello +world + diff --git a/tests/fenced19.duck b/tests/fenced19.duck new file mode 100644 index 0000000..81b2988 --- /dev/null +++ b/tests/fenced19.duck @@ -0,0 +1,7 @@ += Fenced Test + +[code] + [[[ +def no(): + return False +]]] diff --git a/tests/fenced19.page b/tests/fenced19.page new file mode 100644 index 0000000..b659b83 --- /dev/null +++ b/tests/fenced19.page @@ -0,0 +1,6 @@ + + + Fenced Test + def no(): + return False + diff --git a/tests/fenced20.duck b/tests/fenced20.duck new file mode 100644 index 0000000..a80bab0 --- /dev/null +++ b/tests/fenced20.duck @@ -0,0 +1,7 @@ += Fenced Test + +[code] + [[[ + def no(): + return False + ]]] diff --git a/tests/fenced20.page b/tests/fenced20.page new file mode 100644 index 0000000..2c23949 --- /dev/null +++ b/tests/fenced20.page @@ -0,0 +1,6 @@ + + + Fenced Test + def no(): + return False + diff --git a/tests/fenced21.duck b/tests/fenced21.duck new file mode 100644 index 0000000..77ae82f --- /dev/null +++ b/tests/fenced21.duck @@ -0,0 +1,6 @@ += Fenced Test + +[code] + [[[ def no(): + return False + ]]] diff --git a/tests/fenced21.page b/tests/fenced21.page new file mode 100644 index 0000000..faa73fc --- /dev/null +++ b/tests/fenced21.page @@ -0,0 +1,6 @@ + + + Fenced Test + def no(): + return False + diff --git a/tests/fenced22.duck b/tests/fenced22.duck new file mode 100644 index 0000000..869e11d --- /dev/null +++ b/tests/fenced22.duck @@ -0,0 +1,4 @@ += Fenced Test + +[code] + [[[ return False]]] diff --git a/tests/fenced22.page b/tests/fenced22.page new file mode 100644 index 0000000..ec91730 --- /dev/null +++ b/tests/fenced22.page @@ -0,0 +1,5 @@ + + + Fenced Test + return False + diff --git a/tests/fragment01.duck b/tests/fragment01.duck new file mode 100644 index 0000000..b7e05b1 --- /dev/null +++ b/tests/fragment01.duck @@ -0,0 +1,4 @@ +@ducktype/1.0 __future__/fragments + +[note] +This is a note. diff --git a/tests/fragment01.page b/tests/fragment01.page new file mode 100644 index 0000000..2099922 --- /dev/null +++ b/tests/fragment01.page @@ -0,0 +1,4 @@ + + +

This is a note.

+
diff --git a/tests/fragment02.duck b/tests/fragment02.duck new file mode 100644 index 0000000..47d4d21 --- /dev/null +++ b/tests/fragment02.duck @@ -0,0 +1,6 @@ +@ducktype/1.0 __future__/fragments + +[note] +This is a note. +[note] +This is another note. diff --git a/tests/fragment02.page b/tests/fragment02.page new file mode 100644 index 0000000..3ceb855 --- /dev/null +++ b/tests/fragment02.page @@ -0,0 +1,6 @@ + +

This is a note.

+
+ +

This is another note.

+
diff --git a/tests/fragment03.duck b/tests/fragment03.duck new file mode 100644 index 0000000..3f96862 --- /dev/null +++ b/tests/fragment03.duck @@ -0,0 +1,6 @@ +@ducktype/1.0 __future__/fragments + +[note] +This is a note. + +This is a paragraph. diff --git a/tests/fragment03.page b/tests/fragment03.page new file mode 100644 index 0000000..0427df0 --- /dev/null +++ b/tests/fragment03.page @@ -0,0 +1,4 @@ + +

This is a note.

+
+

This is a paragraph.

diff --git a/tests/fragment04.duck b/tests/fragment04.duck new file mode 100644 index 0000000..5d88210 --- /dev/null +++ b/tests/fragment04.duck @@ -0,0 +1,11 @@ +@ducktype/1.0 __future__/fragments + +[list] +* This is a list item. + +* This is a second list item. + + [note] + This is a note. + +* This is a third list item. diff --git a/tests/fragment04.page b/tests/fragment04.page new file mode 100644 index 0000000..314e416 --- /dev/null +++ b/tests/fragment04.page @@ -0,0 +1,15 @@ + + + +

This is a list item.

+
+ +

This is a second list item.

+ +

This is a note.

+
+
+ +

This is a third list item.

+
+
diff --git a/tests/fragment05.duck b/tests/fragment05.duck new file mode 100644 index 0000000..ef2fe93 --- /dev/null +++ b/tests/fragment05.duck @@ -0,0 +1,9 @@ +@ducktype/1.0 __future__/fragments + +[note] + This is a note. + + [example] + This is an example in a note. + + * This is a list item in an example in a note. diff --git a/tests/fragment05.page b/tests/fragment05.page new file mode 100644 index 0000000..c604ebd --- /dev/null +++ b/tests/fragment05.page @@ -0,0 +1,12 @@ + + +

This is a note.

+ +

This is an example in a note.

+ + +

This is a list item in an example in a note.

+
+
+
+
diff --git a/tests/fragment06.duck b/tests/fragment06.duck new file mode 100644 index 0000000..5880fae --- /dev/null +++ b/tests/fragment06.duck @@ -0,0 +1,5 @@ +@ducktype/1.0 __future__/fragments + +== Section Title + +This only has a section. diff --git a/tests/fragment06.page b/tests/fragment06.page new file mode 100644 index 0000000..07a5980 --- /dev/null +++ b/tests/fragment06.page @@ -0,0 +1,5 @@ + +
+ Section Title +

This only has a section.

+
diff --git a/tests/fragment07.duck b/tests/fragment07.duck new file mode 100644 index 0000000..2f643d2 --- /dev/null +++ b/tests/fragment07.duck @@ -0,0 +1,7 @@ +@ducktype/1.0 __future__/fragments + +== Section Title + +=== First Subsection + +=== Second Subsection diff --git a/tests/fragment07.page b/tests/fragment07.page new file mode 100644 index 0000000..c6d0b52 --- /dev/null +++ b/tests/fragment07.page @@ -0,0 +1,10 @@ + +
+ Section Title +
+ First Subsection +
+
+ Second Subsection +
+
diff --git a/tests/fragment08.duck b/tests/fragment08.duck new file mode 100644 index 0000000..2ff41a1 --- /dev/null +++ b/tests/fragment08.duck @@ -0,0 +1,9 @@ +@ducktype/1.0 __future__/fragments + +== First Section + +This is a paragraph. + +== Seconed Section + +This is another paragraph. diff --git a/tests/fragment08.page b/tests/fragment08.page new file mode 100644 index 0000000..5673098 --- /dev/null +++ b/tests/fragment08.page @@ -0,0 +1,8 @@ +
+ First Section +

This is a paragraph.

+
+
+ Seconed Section +

This is another paragraph.

+
diff --git a/tests/fragment09.duck b/tests/fragment09.duck new file mode 100644 index 0000000..42f8cb4 --- /dev/null +++ b/tests/fragment09.duck @@ -0,0 +1,11 @@ +@ducktype/1.0 __future__/fragments + +== First Section + +This is a paragraph. + +=== Subsection + +== Seconed Section + +This is another paragraph. diff --git a/tests/fragment09.page b/tests/fragment09.page new file mode 100644 index 0000000..d680bf6 --- /dev/null +++ b/tests/fragment09.page @@ -0,0 +1,11 @@ +
+ First Section +

This is a paragraph.

+
+ Subsection +
+
+
+ Seconed Section +

This is another paragraph.

+
diff --git a/tests/fragment10.duck b/tests/fragment10.duck new file mode 100644 index 0000000..e3217c6 --- /dev/null +++ b/tests/fragment10.duck @@ -0,0 +1,5 @@ +@ducktype/1.0 __future__/fragments +@namespace if http://projectmallard.org/1.0/ + +[if:if test="target:html"] + This is a conditional. diff --git a/tests/fragment10.page b/tests/fragment10.page new file mode 100644 index 0000000..6d78fa2 --- /dev/null +++ b/tests/fragment10.page @@ -0,0 +1,4 @@ + + +

This is a conditional.

+
diff --git a/tests/fragment11.duck b/tests/fragment11.duck new file mode 100644 index 0000000..9eb8a53 --- /dev/null +++ b/tests/fragment11.duck @@ -0,0 +1,7 @@ +@ducktype/1.0 __future__/fragments + + [note] + This note is indented. + +[note] +This note is not indented. diff --git a/tests/fragment11.page b/tests/fragment11.page new file mode 100644 index 0000000..83d92c7 --- /dev/null +++ b/tests/fragment11.page @@ -0,0 +1,6 @@ + +

This note is indented.

+
+ +

This note is not indented.

+
diff --git a/tests/fragment12.duck b/tests/fragment12.duck new file mode 100644 index 0000000..3372d3c --- /dev/null +++ b/tests/fragment12.duck @@ -0,0 +1,8 @@ +@ducktype/1.0 __future__/fragments +@namespace if http://projectmallard.org/1.0/ + + [if:if test="target:html"] + This conditional is indented. + +[note] +This note is not indented. diff --git a/tests/fragment12.page b/tests/fragment12.page new file mode 100644 index 0000000..ba9f11d --- /dev/null +++ b/tests/fragment12.page @@ -0,0 +1,6 @@ + +

This conditional is indented.

+
+ +

This note is not indented.

+
diff --git a/tests/fragment13.duck b/tests/fragment13.duck new file mode 100644 index 0000000..e62d736 --- /dev/null +++ b/tests/fragment13.duck @@ -0,0 +1,5 @@ +@ducktype/1.0 __future__/fragments + +=== Subsection + +== Error diff --git a/tests/fragment13.error b/tests/fragment13.error new file mode 100644 index 0000000..49007b1 --- /dev/null +++ b/tests/fragment13.error @@ -0,0 +1 @@ +fragment13.duck:5: Incorrect section depth diff --git a/tests/fragment14.duck b/tests/fragment14.duck new file mode 100644 index 0000000..b5413e6 --- /dev/null +++ b/tests/fragment14.duck @@ -0,0 +1,10 @@ +@ducktype/1.0 __future__/fragments + +== First Section +-- First Subtitle + +=== Subsection +--- Subsection Subtitle + +== Seconed Section +-- Second Subtitle diff --git a/tests/fragment14.page b/tests/fragment14.page new file mode 100644 index 0000000..dc4633c --- /dev/null +++ b/tests/fragment14.page @@ -0,0 +1,12 @@ +
+ First Section + First Subtitle +
+ Subsection + Subsection Subtitle +
+
+
+ Seconed Section + Second Subtitle +
diff --git a/tests/if01.duck b/tests/if01.duck new file mode 100644 index 0000000..01cc3ba --- /dev/null +++ b/tests/if01.duck @@ -0,0 +1,10 @@ +@ducktype/1.0 if/experimental + += If Extension Test + +This is before the test. +? target:html + This is displayed in HTML. + + This is also displayed in HTML. +This is not conditional. diff --git a/tests/if01.page b/tests/if01.page new file mode 100644 index 0000000..7a06d67 --- /dev/null +++ b/tests/if01.page @@ -0,0 +1,10 @@ + + + If Extension Test +

This is before the test.

+ +

This is displayed in HTML.

+

This is also displayed in HTML.

+
+

This is not conditional.

+
diff --git a/tests/if02.duck b/tests/if02.duck new file mode 100644 index 0000000..4b4be5b --- /dev/null +++ b/tests/if02.duck @@ -0,0 +1,8 @@ +@ducktype/1.0 if/experimental + += If Extension Test + +? target:html +This is displayed in HTML. + +This is not conditional. diff --git a/tests/if02.page b/tests/if02.page new file mode 100644 index 0000000..471c173 --- /dev/null +++ b/tests/if02.page @@ -0,0 +1,8 @@ + + + If Extension Test + +

This is displayed in HTML.

+
+

This is not conditional.

+
diff --git a/tests/if03.duck b/tests/if03.duck new file mode 100644 index 0000000..aaeda1e --- /dev/null +++ b/tests/if03.duck @@ -0,0 +1,11 @@ +@ducktype/1.0 if/experimental + += If Extension Test + +?? + ? target:html + This is displayed in HTML. + ? target:pdf + This is displayed in PDF. + ?? + This is displayed otherwise. diff --git a/tests/if03.page b/tests/if03.page new file mode 100644 index 0000000..39db37f --- /dev/null +++ b/tests/if03.page @@ -0,0 +1,15 @@ + + + If Extension Test + + +

This is displayed in HTML.

+
+ +

This is displayed in PDF.

+
+ +

This is displayed otherwise.

+
+
+
diff --git a/tests/info01.duck b/tests/info01.duck new file mode 100644 index 0000000..93d4ba2 --- /dev/null +++ b/tests/info01.duck @@ -0,0 +1,4 @@ += Info Test +@desc Test of info elements. + +This is a page with info elements. diff --git a/tests/info01.page b/tests/info01.page new file mode 100644 index 0000000..fb2576c --- /dev/null +++ b/tests/info01.page @@ -0,0 +1,8 @@ + + + + Test of info elements. + + Info Test +

This is a page with info elements.

+
diff --git a/tests/info02.duck b/tests/info02.duck new file mode 100644 index 0000000..e658cd1 --- /dev/null +++ b/tests/info02.duck @@ -0,0 +1,5 @@ += Info Test +- Info Subtitle +@desc Test of info elements. + +This is a page with info elements. diff --git a/tests/info02.page b/tests/info02.page new file mode 100644 index 0000000..16e8ed9 --- /dev/null +++ b/tests/info02.page @@ -0,0 +1,9 @@ + + + + Test of info elements. + + Info Test + Info Subtitle +

This is a page with info elements.

+
diff --git a/tests/info03.duck b/tests/info03.duck new file mode 100644 index 0000000..6ab95cd --- /dev/null +++ b/tests/info03.duck @@ -0,0 +1,6 @@ += Info Test +- Info Subtitle + [.style] +@desc Test of info elements. + +This is a page with info elements. diff --git a/tests/info03.page b/tests/info03.page new file mode 100644 index 0000000..f53ebad --- /dev/null +++ b/tests/info03.page @@ -0,0 +1,9 @@ + + + + Test of info elements. + + Info Test + Info Subtitle +

This is a page with info elements.

+
diff --git a/tests/info04.duck b/tests/info04.duck new file mode 100644 index 0000000..71f7d2e --- /dev/null +++ b/tests/info04.duck @@ -0,0 +1,5 @@ += Info Test +@desc + Test of info elements. + +This is a page with info elements. diff --git a/tests/info04.page b/tests/info04.page new file mode 100644 index 0000000..b30e584 --- /dev/null +++ b/tests/info04.page @@ -0,0 +1,8 @@ + + + + Test of info elements. + + Info Test +

This is a page with info elements.

+
diff --git a/tests/info05.duck b/tests/info05.duck new file mode 100644 index 0000000..8b977dd --- /dev/null +++ b/tests/info05.duck @@ -0,0 +1,4 @@ += Info Test +@title[sort] A Sort Title + +This is a page with info elements. diff --git a/tests/info05.page b/tests/info05.page new file mode 100644 index 0000000..b179077 --- /dev/null +++ b/tests/info05.page @@ -0,0 +1,8 @@ + + + + A Sort Title + + Info Test +

This is a page with info elements.

+
diff --git a/tests/info06.duck b/tests/info06.duck new file mode 100644 index 0000000..6bb547b --- /dev/null +++ b/tests/info06.duck @@ -0,0 +1,5 @@ += Info Test +@title[sort] A Sort Title +@title[text] A Text Title + +This is a page with info elements. diff --git a/tests/info06.page b/tests/info06.page new file mode 100644 index 0000000..42d1d94 --- /dev/null +++ b/tests/info06.page @@ -0,0 +1,9 @@ + + + + A Sort Title + A Text Title + + Info Test +

This is a page with info elements.

+
diff --git a/tests/info07.duck b/tests/info07.duck new file mode 100644 index 0000000..66f3710 --- /dev/null +++ b/tests/info07.duck @@ -0,0 +1,7 @@ += Info Test +@title[sort] A Sort + Title +@title[text] + A Text Title + +This is a page with info elements. diff --git a/tests/info07.page b/tests/info07.page new file mode 100644 index 0000000..b7cedf4 --- /dev/null +++ b/tests/info07.page @@ -0,0 +1,10 @@ + + + + A Sort + Title + A Text Title + + Info Test +

This is a page with info elements.

+
diff --git a/tests/info08.duck b/tests/info08.duck new file mode 100644 index 0000000..0f0bd1d --- /dev/null +++ b/tests/info08.duck @@ -0,0 +1,6 @@ += Info Test +@title[link + role=topic] + A Topic Link Title + +This is a page with info elements. diff --git a/tests/info08.page b/tests/info08.page new file mode 100644 index 0000000..fccdd1b --- /dev/null +++ b/tests/info08.page @@ -0,0 +1,8 @@ + + + + A Topic Link Title + + Info Test +

This is a page with info elements.

+
diff --git a/tests/info09.duck b/tests/info09.duck new file mode 100644 index 0000000..18e1bf4 --- /dev/null +++ b/tests/info09.duck @@ -0,0 +1,5 @@ += Info Test +@license + This is the license. + + This is still the license. diff --git a/tests/info09.page b/tests/info09.page new file mode 100644 index 0000000..d9d5311 --- /dev/null +++ b/tests/info09.page @@ -0,0 +1,10 @@ + + + + +

This is the license.

+

This is still the license.

+
+
+ Info Test +
diff --git a/tests/info10.duck b/tests/info10.duck new file mode 100644 index 0000000..e053585 --- /dev/null +++ b/tests/info10.duck @@ -0,0 +1,7 @@ += Info Test + @license + This is the license. + + This is still the license. + + This is not the license. diff --git a/tests/info10.page b/tests/info10.page new file mode 100644 index 0000000..8589d07 --- /dev/null +++ b/tests/info10.page @@ -0,0 +1,11 @@ + + + + +

This is the license.

+

This is still the license.

+
+
+ Info Test +

This is not the license.

+
diff --git a/tests/info11.duck b/tests/info11.duck new file mode 100644 index 0000000..90c09ff --- /dev/null +++ b/tests/info11.duck @@ -0,0 +1,15 @@ += Info Test + @license + This is the license. + + @screen + This is verbatim text in a license. + + This is a new paragraph in a license. + + @code + This is verbatim text in a license. + + This is still verbatim text in a license. + + This is not the license. diff --git a/tests/info11.page b/tests/info11.page new file mode 100644 index 0000000..ee7366e --- /dev/null +++ b/tests/info11.page @@ -0,0 +1,15 @@ + + + + +

This is the license.

+ This is verbatim text in a license. +

This is a new paragraph in a license.

+ This is verbatim text in a license. + +This is still verbatim text in a license. +
+
+ Info Test +

This is not the license.

+
diff --git a/tests/info12.duck b/tests/info12.duck new file mode 100644 index 0000000..663ec00 --- /dev/null +++ b/tests/info12.duck @@ -0,0 +1,6 @@ += Info Test +@credit + @name Shaun McCance + @email shaunm@gnome.org +@desc A page description +This paragraph is not in the info. diff --git a/tests/info12.page b/tests/info12.page new file mode 100644 index 0000000..c86657e --- /dev/null +++ b/tests/info12.page @@ -0,0 +1,12 @@ + + + + + Shaun McCance + shaunm@gnome.org + + A page description + + Info Test +

This paragraph is not in the info.

+
diff --git a/tests/info13.duck b/tests/info13.duck new file mode 100644 index 0000000..3912028 --- /dev/null +++ b/tests/info13.duck @@ -0,0 +1,3 @@ += Info Test + @desc A page description +@Not part of the info, even if it does start with an @ diff --git a/tests/info13.page b/tests/info13.page new file mode 100644 index 0000000..15ea6a7 --- /dev/null +++ b/tests/info13.page @@ -0,0 +1,8 @@ + + + + A page description + + Info Test +

@Not part of the info, even if it does start with an @

+
diff --git a/tests/info14.duck b/tests/info14.duck new file mode 100644 index 0000000..10c7513 --- /dev/null +++ b/tests/info14.duck @@ -0,0 +1,9 @@ += Info Test + @license + This is the license. + + @media[src=foo.png] + + This is a new paragraph in a license. + + This is not the license. diff --git a/tests/info14.page b/tests/info14.page new file mode 100644 index 0000000..bd15d32 --- /dev/null +++ b/tests/info14.page @@ -0,0 +1,12 @@ + + + + +

This is the license.

+ +

This is a new paragraph in a license.

+
+
+ Info Test +

This is not the license.

+
diff --git a/tests/info15.duck b/tests/info15.duck new file mode 100644 index 0000000..740fad1 --- /dev/null +++ b/tests/info15.duck @@ -0,0 +1,10 @@ += Info Test + @license + This is the license. + + @media[src=foo.svg] + @media[src=foo.png] + + This is a new paragraph in a license. + + This is not the license. diff --git a/tests/info15.page b/tests/info15.page new file mode 100644 index 0000000..2ba8d53 --- /dev/null +++ b/tests/info15.page @@ -0,0 +1,14 @@ + + + + +

This is the license.

+ + + +

This is a new paragraph in a license.

+
+
+ Info Test +

This is not the license.

+
diff --git a/tests/info16.duck b/tests/info16.duck new file mode 100644 index 0000000..ef5eedf --- /dev/null +++ b/tests/info16.duck @@ -0,0 +1,8 @@ += Info Test + @license + This is the license. + @media[src=foo.svg] + @media[src=foo.png] + This is a new paragraph in a license. + + This is not the license. diff --git a/tests/info16.page b/tests/info16.page new file mode 100644 index 0000000..64ae2f8 --- /dev/null +++ b/tests/info16.page @@ -0,0 +1,14 @@ + + + + +

This is the license.

+ + + +

This is a new paragraph in a license.

+
+
+ Info Test +

This is not the license.

+
diff --git a/tests/info17.duck b/tests/info17.duck new file mode 100644 index 0000000..2f9deba --- /dev/null +++ b/tests/info17.duck @@ -0,0 +1,5 @@ += Info Test + +[figure] +@license + This is the figure lincense. diff --git a/tests/info17.page b/tests/info17.page new file mode 100644 index 0000000..99f85fc --- /dev/null +++ b/tests/info17.page @@ -0,0 +1,11 @@ + + + Info Test +
+ + +

This is the figure lincense.

+
+
+
+
diff --git a/tests/info18.duck b/tests/info18.duck new file mode 100644 index 0000000..31fab36 --- /dev/null +++ b/tests/info18.duck @@ -0,0 +1,7 @@ += Info Test + +[figure] +@license + This is the figure lincense. + +This is not in the figure. diff --git a/tests/info18.page b/tests/info18.page new file mode 100644 index 0000000..b2ca0bb --- /dev/null +++ b/tests/info18.page @@ -0,0 +1,12 @@ + + + Info Test +
+ + +

This is the figure lincense.

+
+
+
+

This is not in the figure.

+
diff --git a/tests/info19.duck b/tests/info19.duck new file mode 100644 index 0000000..ff5eed8 --- /dev/null +++ b/tests/info19.duck @@ -0,0 +1,7 @@ += Info Test + +[figure] +@license + This is the figure lincense. + + This is not in the figure. diff --git a/tests/info19.page b/tests/info19.page new file mode 100644 index 0000000..d707794 --- /dev/null +++ b/tests/info19.page @@ -0,0 +1,12 @@ + + + Info Test +
+ + +

This is the figure lincense.

+
+
+
+

This is not in the figure.

+
diff --git a/tests/info20.duck b/tests/info20.duck new file mode 100644 index 0000000..e04673b --- /dev/null +++ b/tests/info20.duck @@ -0,0 +1,8 @@ += Info Test + +[figure] + @license + This is the figure lincense. + + This is still in the figure license. + This is in the figure. diff --git a/tests/info20.page b/tests/info20.page new file mode 100644 index 0000000..d294b15 --- /dev/null +++ b/tests/info20.page @@ -0,0 +1,13 @@ + + + Info Test +
+ + +

This is the figure lincense.

+

This is still in the figure license.

+
+
+

This is in the figure.

+
+
diff --git a/tests/info21.duck b/tests/info21.duck new file mode 100644 index 0000000..fd15d5e --- /dev/null +++ b/tests/info21.duck @@ -0,0 +1,8 @@ += Info Test + +[figure] + @license + This is the figure lincense. + + This is still in the figure license. +This is not in the figure. diff --git a/tests/info21.page b/tests/info21.page new file mode 100644 index 0000000..5a91e2e --- /dev/null +++ b/tests/info21.page @@ -0,0 +1,13 @@ + + + Info Test +
+ + +

This is the figure lincense.

+

This is still in the figure license.

+
+
+
+

This is not in the figure.

+
diff --git a/tests/info22.duck b/tests/info22.duck new file mode 100644 index 0000000..3f60d4a --- /dev/null +++ b/tests/info22.duck @@ -0,0 +1,10 @@ += Info Test + +[figure] + @license + This is the figure lincense. + + @screen + This is a screen in a figure license. + + This is no longer in the screen. diff --git a/tests/info22.page b/tests/info22.page new file mode 100644 index 0000000..0e6baae --- /dev/null +++ b/tests/info22.page @@ -0,0 +1,13 @@ + + + Info Test +
+ + +

This is the figure lincense.

+ This is a screen in a figure license. +

This is no longer in the screen.

+
+
+
+
diff --git a/tests/info23.duck b/tests/info23.duck new file mode 100644 index 0000000..46ed64a --- /dev/null +++ b/tests/info23.duck @@ -0,0 +1,10 @@ += Info Test + +[figure] + @license + This is the figure lincense. + + @screen + This is a screen in a figure license. + + This is still in the screen. diff --git a/tests/info23.page b/tests/info23.page new file mode 100644 index 0000000..1693bcb --- /dev/null +++ b/tests/info23.page @@ -0,0 +1,14 @@ + + + Info Test +
+ + +

This is the figure lincense.

+ This is a screen in a figure license. + +This is still in the screen. +
+
+
+
diff --git a/tests/info24.duck b/tests/info24.duck new file mode 100644 index 0000000..8d649ce --- /dev/null +++ b/tests/info24.duck @@ -0,0 +1,11 @@ += Info Test + @license + This is the license. + This is the same license paragraph. + + @media[src=foo.png] + @media[src=foo.png] + + This is a new paragraph in a license. + + This is not the license. diff --git a/tests/info24.page b/tests/info24.page new file mode 100644 index 0000000..a322b59 --- /dev/null +++ b/tests/info24.page @@ -0,0 +1,14 @@ + + + + +

This is the license. + This is the same license paragraph.

+ + +

This is a new paragraph in a license.

+
+
+ Info Test +

This is not the license.

+
diff --git a/tests/info25.duck b/tests/info25.duck new file mode 100644 index 0000000..7a6a2da --- /dev/null +++ b/tests/info25.duck @@ -0,0 +1,10 @@ +@namespace tt http://www.w3.org/ns/ttml + += Info Test +@tt:tt + @tt:body + @tt:div[begin="1s" end="3s"] + @tt:p + This should not have a Mallard p element added. + +This tests leaf nodes in other namespaces. diff --git a/tests/info25.page b/tests/info25.page new file mode 100644 index 0000000..02d28cd --- /dev/null +++ b/tests/info25.page @@ -0,0 +1,14 @@ + + + + + + + This should not have a Mallard p element added. + + + + + Info Test +

This tests leaf nodes in other namespaces.

+
diff --git a/tests/info26.duck b/tests/info26.duck new file mode 100644 index 0000000..9fe87da --- /dev/null +++ b/tests/info26.duck @@ -0,0 +1,8 @@ +@namespace if http://projectmallard.org/if/1.0/ + += Info Test +@if:if[test=target:html] + This should have a Mallard p element added. + +This tests leaf nodes in other namespaces. + diff --git a/tests/info26.page b/tests/info26.page new file mode 100644 index 0000000..3f7cc2f --- /dev/null +++ b/tests/info26.page @@ -0,0 +1,10 @@ + + + + +

This should have a Mallard p element added.

+
+
+ Info Test +

This tests leaf nodes in other namespaces.

+
diff --git a/tests/info27.duck b/tests/info27.duck new file mode 100644 index 0000000..5f6e5e8 --- /dev/null +++ b/tests/info27.duck @@ -0,0 +1,8 @@ +@namespace mal http://projectmallard.org/1.0/ + += Info Test +@mal:div + This should have a Mallard p element added. + +This tests leaf nodes in other namespaces. + diff --git a/tests/info27.page b/tests/info27.page new file mode 100644 index 0000000..781c7d6 --- /dev/null +++ b/tests/info27.page @@ -0,0 +1,10 @@ + + + + +

This should have a Mallard p element added.

+
+
+ Info Test +

This tests leaf nodes in other namespaces.

+
diff --git a/tests/info28.duck b/tests/info28.duck new file mode 100644 index 0000000..61d69dd --- /dev/null +++ b/tests/info28.duck @@ -0,0 +1,7 @@ +@namespace mal http://projectmallard.org/1.0/ + += Info Test +@mal:screen + This should not have a Mallard p element added. + +This tests leaf nodes in other namespaces. diff --git a/tests/info28.page b/tests/info28.page new file mode 100644 index 0000000..aedcdd7 --- /dev/null +++ b/tests/info28.page @@ -0,0 +1,8 @@ + + + + This should not have a Mallard p element added. + + Info Test +

This tests leaf nodes in other namespaces.

+
diff --git a/tests/info29.duck b/tests/info29.duck new file mode 100644 index 0000000..0fa7ff2 --- /dev/null +++ b/tests/info29.duck @@ -0,0 +1,8 @@ +@namespace if http://projectmallard.org/if/1.0/ + += Info Test +@if:choose + @if:when[test=target:html] + This should have a Mallard p element added. + +This tests leaf nodes in other namespaces. diff --git a/tests/info29.page b/tests/info29.page new file mode 100644 index 0000000..d2a164f --- /dev/null +++ b/tests/info29.page @@ -0,0 +1,12 @@ + + + + + +

This should have a Mallard p element added.

+
+
+
+ Info Test +

This tests leaf nodes in other namespaces.

+
diff --git a/tests/info30.duck b/tests/info30.duck new file mode 100644 index 0000000..1df2d63 --- /dev/null +++ b/tests/info30.duck @@ -0,0 +1,3 @@ += Info Test + @license + This is the license with a $link[>index](link). diff --git a/tests/info30.page b/tests/info30.page new file mode 100644 index 0000000..be438ff --- /dev/null +++ b/tests/info30.page @@ -0,0 +1,9 @@ + + + + +

This is the license with a link.

+
+
+ Info Test +
diff --git a/tests/info31.duck b/tests/info31.duck new file mode 100644 index 0000000..cee763d --- /dev/null +++ b/tests/info31.duck @@ -0,0 +1,4 @@ += Info Test + @credit + @name Shaun McCance + @years 2017 diff --git a/tests/info31.page b/tests/info31.page new file mode 100644 index 0000000..79f2158 --- /dev/null +++ b/tests/info31.page @@ -0,0 +1,10 @@ + + + + + Shaun McCance + 2017 + + + Info Test + diff --git a/tests/info32.duck b/tests/info32.duck new file mode 100644 index 0000000..9ccfe2b --- /dev/null +++ b/tests/info32.duck @@ -0,0 +1,5 @@ += Info Test + +@desc Test of info elements. + +Info elements can have a blank line before them. diff --git a/tests/info32.page b/tests/info32.page new file mode 100644 index 0000000..cffd67e --- /dev/null +++ b/tests/info32.page @@ -0,0 +1,8 @@ + + + + Test of info elements. + + Info Test +

Info elements can have a blank line before them.

+
diff --git a/tests/info33.duck b/tests/info33.duck new file mode 100644 index 0000000..dbcf857 --- /dev/null +++ b/tests/info33.duck @@ -0,0 +1,3 @@ += Info Test + +$@This is a way to escape elements that look like info diff --git a/tests/info33.page b/tests/info33.page new file mode 100644 index 0000000..c4a5bab --- /dev/null +++ b/tests/info33.page @@ -0,0 +1,5 @@ + + + Info Test +

@This is a way to escape elements that look like info

+
diff --git a/tests/info34.duck b/tests/info34.duck new file mode 100644 index 0000000..2d4c0b4 --- /dev/null +++ b/tests/info34.duck @@ -0,0 +1,5 @@ += Info Test + +[[[ +@This is a way to escape elements that look like info +]]] diff --git a/tests/info34.page b/tests/info34.page new file mode 100644 index 0000000..2974d17 --- /dev/null +++ b/tests/info34.page @@ -0,0 +1,5 @@ + + + Info Test +

@This is a way to escape elements that look like info

+
diff --git a/tests/info35.duck b/tests/info35.duck new file mode 100644 index 0000000..a0973c0 --- /dev/null +++ b/tests/info35.duck @@ -0,0 +1,6 @@ += Info Test +- Subtitle + +@desc Test of info elements. + +Info elements can have a blank line before them. diff --git a/tests/info35.page b/tests/info35.page new file mode 100644 index 0000000..6a0f060 --- /dev/null +++ b/tests/info35.page @@ -0,0 +1,9 @@ + + + + Test of info elements. + + Info Test + Subtitle +

Info elements can have a blank line before them.

+
diff --git a/tests/info36.duck b/tests/info36.duck new file mode 100644 index 0000000..6efbed3 --- /dev/null +++ b/tests/info36.duck @@ -0,0 +1,7 @@ += Info Test +- Subtitle + [topic] + +@desc Test of info elements. + +Info elements can have a blank line before them. diff --git a/tests/info36.page b/tests/info36.page new file mode 100644 index 0000000..835b707 --- /dev/null +++ b/tests/info36.page @@ -0,0 +1,9 @@ + + + + Test of info elements. + + Info Test + Subtitle +

Info elements can have a blank line before them.

+
diff --git a/tests/info37.duck b/tests/info37.duck new file mode 100644 index 0000000..c7ca3fe --- /dev/null +++ b/tests/info37.duck @@ -0,0 +1,3 @@ += Info Test +@license[] This is the license with a $link[>index](link). +@license This is the license with a $link[>index](link). diff --git a/tests/info37.page b/tests/info37.page new file mode 100644 index 0000000..0f7241c --- /dev/null +++ b/tests/info37.page @@ -0,0 +1,12 @@ + + + + +

This is the license with a link.

+
+ +

This is the license with a link.

+
+
+ Info Test +
diff --git a/tests/info38.duck b/tests/info38.duck new file mode 100644 index 0000000..5bfe4c1 --- /dev/null +++ b/tests/info38.duck @@ -0,0 +1,3 @@ += Info Test +@license[] +@license diff --git a/tests/info38.page b/tests/info38.page new file mode 100644 index 0000000..7930e4b --- /dev/null +++ b/tests/info38.page @@ -0,0 +1,8 @@ + + + + + + + Info Test + diff --git a/tests/info39.duck b/tests/info39.duck new file mode 100644 index 0000000..62bcf68 --- /dev/null +++ b/tests/info39.duck @@ -0,0 +1,5 @@ += Info Test +@license[] This is the license + with a $link[>index](link). +@license This is the license + with a $link[>index](link). diff --git a/tests/info39.page b/tests/info39.page new file mode 100644 index 0000000..1a1058e --- /dev/null +++ b/tests/info39.page @@ -0,0 +1,14 @@ + + + + +

This is the license + with a link.

+
+ +

This is the license + with a link.

+
+
+ Info Test +
diff --git a/tests/info40.duck b/tests/info40.duck new file mode 100644 index 0000000..77befb7 --- /dev/null +++ b/tests/info40.duck @@ -0,0 +1,9 @@ += Info Test +@license[] This is the license + with a $link[>index](link). + + This is another paragraph. +@license This is the license + with a $link[>index](link). + + This is another paragraph. diff --git a/tests/info40.page b/tests/info40.page new file mode 100644 index 0000000..3f6c725 --- /dev/null +++ b/tests/info40.page @@ -0,0 +1,16 @@ + + + + +

This is the license + with a link.

+

This is another paragraph.

+
+ +

This is the license + with a link.

+

This is another paragraph.

+
+
+ Info Test +
diff --git a/tests/info41.duck b/tests/info41.duck new file mode 100644 index 0000000..e925a69 --- /dev/null +++ b/tests/info41.duck @@ -0,0 +1,5 @@ += Info Test +@license + @p + This is the license. + This is a new paragraph. diff --git a/tests/info41.page b/tests/info41.page new file mode 100644 index 0000000..77af7ad --- /dev/null +++ b/tests/info41.page @@ -0,0 +1,10 @@ + + + + +

This is the license.

+

This is a new paragraph.

+
+
+ Info Test +
diff --git a/tests/inline01.duck b/tests/inline01.duck new file mode 100644 index 0000000..49cad4a --- /dev/null +++ b/tests/inline01.duck @@ -0,0 +1,3 @@ += Inline Test + +This paragraph has $em(emphasized) text. diff --git a/tests/inline01.page b/tests/inline01.page new file mode 100644 index 0000000..b5240be --- /dev/null +++ b/tests/inline01.page @@ -0,0 +1,5 @@ + + + Inline Test +

This paragraph has emphasized text.

+
diff --git a/tests/inline02.duck b/tests/inline02.duck new file mode 100644 index 0000000..69caf36 --- /dev/null +++ b/tests/inline02.duck @@ -0,0 +1,3 @@ += Inline Test + +This is $not actually $markup. diff --git a/tests/inline02.page b/tests/inline02.page new file mode 100644 index 0000000..99c257c --- /dev/null +++ b/tests/inline02.page @@ -0,0 +1,5 @@ + + + Inline Test +

This is $not actually $markup.

+
diff --git a/tests/inline03.duck b/tests/inline03.duck new file mode 100644 index 0000000..e447df0 --- /dev/null +++ b/tests/inline03.duck @@ -0,0 +1,3 @@ += Inline Test + +This element is empty: $em() diff --git a/tests/inline03.page b/tests/inline03.page new file mode 100644 index 0000000..923ca4d --- /dev/null +++ b/tests/inline03.page @@ -0,0 +1,5 @@ + + + Inline Test +

This element is empty:

+
diff --git a/tests/inline04.duck b/tests/inline04.duck new file mode 100644 index 0000000..b15a652 --- /dev/null +++ b/tests/inline04.duck @@ -0,0 +1,3 @@ += Inline Test + +This element is $em[.bold](bold). diff --git a/tests/inline04.page b/tests/inline04.page new file mode 100644 index 0000000..20f7499 --- /dev/null +++ b/tests/inline04.page @@ -0,0 +1,5 @@ + + + Inline Test +

This element is bold.

+
diff --git a/tests/inline05.duck b/tests/inline05.duck new file mode 100644 index 0000000..3a47385 --- /dev/null +++ b/tests/inline05.duck @@ -0,0 +1,3 @@ += Inline Test + +Here is a $link[xref=another_page] without content. diff --git a/tests/inline05.page b/tests/inline05.page new file mode 100644 index 0000000..54cbda3 --- /dev/null +++ b/tests/inline05.page @@ -0,0 +1,5 @@ + + + Inline Test +

Here is a without content.

+
diff --git a/tests/inline06.duck b/tests/inline06.duck new file mode 100644 index 0000000..1d2ad2f --- /dev/null +++ b/tests/inline06.duck @@ -0,0 +1,3 @@ += Inline Test + +We can $em(nest $gui(inline $key(content))). diff --git a/tests/inline06.page b/tests/inline06.page new file mode 100644 index 0000000..39ea965 --- /dev/null +++ b/tests/inline06.page @@ -0,0 +1,5 @@ + + + Inline Test +

We can nest inline content.

+
diff --git a/tests/inline07.duck b/tests/inline07.duck new file mode 100644 index 0000000..4ced0de --- /dev/null +++ b/tests/inline07.duck @@ -0,0 +1,3 @@ += Inline Test + +We can $em(nest $gui($key(inline) content)). diff --git a/tests/inline07.page b/tests/inline07.page new file mode 100644 index 0000000..f7a117f --- /dev/null +++ b/tests/inline07.page @@ -0,0 +1,5 @@ + + + Inline Test +

We can nest inline content.

+
diff --git a/tests/inline08.duck b/tests/inline08.duck new file mode 100644 index 0000000..93645c7 --- /dev/null +++ b/tests/inline08.duck @@ -0,0 +1,5 @@ += Inline Test + +This element is empty: $em[] + +This element is empty: $em[] and has stuff after it. diff --git a/tests/inline08.page b/tests/inline08.page new file mode 100644 index 0000000..8412b0b --- /dev/null +++ b/tests/inline08.page @@ -0,0 +1,6 @@ + + + Inline Test +

This element is empty:

+

This element is empty: and has stuff after it.

+
diff --git a/tests/inline09.duck b/tests/inline09.duck new file mode 100644 index 0000000..8e7fd55 --- /dev/null +++ b/tests/inline09.duck @@ -0,0 +1,5 @@ += Inline Test + +This page has an entity reference $eacute; + +And another one $eacute; with content after it. diff --git a/tests/inline09.page b/tests/inline09.page new file mode 100644 index 0000000..026010c --- /dev/null +++ b/tests/inline09.page @@ -0,0 +1,6 @@ + + + Inline Test +

This page has an entity reference é

+

And another one é with content after it.

+
diff --git a/tests/inline10.duck b/tests/inline10.duck new file mode 100644 index 0000000..5f07fb9 --- /dev/null +++ b/tests/inline10.duck @@ -0,0 +1,3 @@ += Inline Test + +This page has a combining entity o$tdot;. diff --git a/tests/inline10.page b/tests/inline10.page new file mode 100644 index 0000000..9b529ea --- /dev/null +++ b/tests/inline10.page @@ -0,0 +1,5 @@ + + + Inline Test +

This page has a combining entity o⃛.

+
diff --git a/tests/inline11.duck b/tests/inline11.duck new file mode 100644 index 0000000..f054bb2 --- /dev/null +++ b/tests/inline11.duck @@ -0,0 +1,5 @@ += Inline Test + +This page has numeric entity refs: $e9;. + +These look numeric, but aren't: $ac; $acE;. diff --git a/tests/inline11.page b/tests/inline11.page new file mode 100644 index 0000000..e04f183 --- /dev/null +++ b/tests/inline11.page @@ -0,0 +1,6 @@ + + + Inline Test +

This page has numeric entity refs: é.

+

These look numeric, but aren't: ∾ ∾̳.

+
diff --git a/tests/inline12.duck b/tests/inline12.duck new file mode 100644 index 0000000..4c4f09e --- /dev/null +++ b/tests/inline12.duck @@ -0,0 +1,4 @@ += Inline Test + +This is a link: $link[>index]. This is a $link[>index](with +content). diff --git a/tests/inline12.page b/tests/inline12.page new file mode 100644 index 0000000..4713d21 --- /dev/null +++ b/tests/inline12.page @@ -0,0 +1,6 @@ + + + Inline Test +

This is a link: . This is a with + content.

+
diff --git a/tests/inline13.duck b/tests/inline13.duck new file mode 100644 index 0000000..06feef2 --- /dev/null +++ b/tests/inline13.duck @@ -0,0 +1,5 @@ += Inline Test + +This is a link: $link[>>http://projectmallard.org/]. + +This is a link: $link[>>http://projectmallard.org/ ](Mallard). diff --git a/tests/inline13.page b/tests/inline13.page new file mode 100644 index 0000000..7e58e97 --- /dev/null +++ b/tests/inline13.page @@ -0,0 +1,6 @@ + + + Inline Test +

This is a link: .

+

This is a link: Mallard.

+
diff --git a/tests/inline14.duck b/tests/inline14.duck new file mode 100644 index 0000000..c3f1d38 --- /dev/null +++ b/tests/inline14.duck @@ -0,0 +1,7 @@ += Inline Test + +This is a test of escaping in attribute values. +$em[style="$quot;quoted style$quot;"](quoted style). +$em[style='$apos;quoted style$apos;'](quoted style). +$link[>$dollar;sigils](dollar). +$link[>>http://$dollar;sigils.example.com/](dollar). diff --git a/tests/inline14.page b/tests/inline14.page new file mode 100644 index 0000000..a3eaf66 --- /dev/null +++ b/tests/inline14.page @@ -0,0 +1,9 @@ + + + Inline Test +

This is a test of escaping in attribute values. + quoted style. + quoted style. + dollar. + dollar.

+
diff --git a/tests/inline15.duck b/tests/inline15.duck new file mode 100644 index 0000000..7d6e397 --- /dev/null +++ b/tests/inline15.duck @@ -0,0 +1,4 @@ += Inline Test + +Let's escape $em[style="$"mystyle$""](stuff) and then not +escape $em[style="$$"](other stuff). diff --git a/tests/inline15.page b/tests/inline15.page new file mode 100644 index 0000000..be736a8 --- /dev/null +++ b/tests/inline15.page @@ -0,0 +1,6 @@ + + + Inline Test +

Let's escape stuff and then not + escape other stuff.

+
diff --git a/tests/inline16.duck b/tests/inline16.duck new file mode 100644 index 0000000..36a77b6 --- /dev/null +++ b/tests/inline16.duck @@ -0,0 +1,5 @@ += Inline Test + +Testing nested parenthesis with $gui(File(s)) (and $gui(File)). + +This is ($em(more $em((complicated) stuff)).) diff --git a/tests/inline16.page b/tests/inline16.page new file mode 100644 index 0000000..eab4031 --- /dev/null +++ b/tests/inline16.page @@ -0,0 +1,6 @@ + + + Inline Test +

Testing nested parenthesis with File(s) (and File).

+

This is (more (complicated) stuff.)

+
diff --git a/tests/inline17.duck b/tests/inline17.duck new file mode 100644 index 0000000..536a7a6 --- /dev/null +++ b/tests/inline17.duck @@ -0,0 +1,3 @@ += Inline Test + +This $em(has $em(some$) escapes)$( in it.) diff --git a/tests/inline17.page b/tests/inline17.page new file mode 100644 index 0000000..943cd61 --- /dev/null +++ b/tests/inline17.page @@ -0,0 +1,5 @@ + + + Inline Test +

This has some) escapes( in it.

+
diff --git a/tests/inline18.duck b/tests/inline18.duck new file mode 100644 index 0000000..28a44e8 --- /dev/null +++ b/tests/inline18.duck @@ -0,0 +1,4 @@ += Inline Test + +Let's test some escapes. +$$ $* $= $- $. $@ $[ $] $( $) $" $' diff --git a/tests/inline18.page b/tests/inline18.page new file mode 100644 index 0000000..8a051ce --- /dev/null +++ b/tests/inline18.page @@ -0,0 +1,6 @@ + + + Inline Test +

Let's test some escapes. + $ * = - . @ [ ] ( ) " '

+
diff --git a/tests/list01.duck b/tests/list01.duck new file mode 100644 index 0000000..460fd62 --- /dev/null +++ b/tests/list01.duck @@ -0,0 +1,4 @@ += List Test + +* List item 1 +* List item 2 diff --git a/tests/list01.page b/tests/list01.page new file mode 100644 index 0000000..d57ea5c --- /dev/null +++ b/tests/list01.page @@ -0,0 +1,12 @@ + + + List Test + + +

List item 1

+
+ +

List item 2

+
+
+
diff --git a/tests/list02.duck b/tests/list02.duck new file mode 100644 index 0000000..3d7b29a --- /dev/null +++ b/tests/list02.duck @@ -0,0 +1,7 @@ += List Test + +* List item 1 + Continuing list item 1 +* List item 2 + + Another paragraph in a list item 2 diff --git a/tests/list02.page b/tests/list02.page new file mode 100644 index 0000000..ddc1781 --- /dev/null +++ b/tests/list02.page @@ -0,0 +1,14 @@ + + + List Test + + +

List item 1 + Continuing list item 1

+
+ +

List item 2

+

Another paragraph in a list item 2

+
+
+
diff --git a/tests/list03.duck b/tests/list03.duck new file mode 100644 index 0000000..eb576ba --- /dev/null +++ b/tests/list03.duck @@ -0,0 +1,8 @@ += List Test + +[list numbered] +* List item 1 + Continuing list item 1 +* List item 2 + + Another paragraph in a list item 2 diff --git a/tests/list03.page b/tests/list03.page new file mode 100644 index 0000000..cfc7397 --- /dev/null +++ b/tests/list03.page @@ -0,0 +1,14 @@ + + + List Test + + +

List item 1 + Continuing list item 1

+
+ +

List item 2

+

Another paragraph in a list item 2

+
+
+
diff --git a/tests/list04.duck b/tests/list04.duck new file mode 100644 index 0000000..94bbdd9 --- /dev/null +++ b/tests/list04.duck @@ -0,0 +1,10 @@ += List Test + +[list] +[item] +First Item +[item] +Second Item +[list] +[item] +Second List diff --git a/tests/list04.page b/tests/list04.page new file mode 100644 index 0000000..f03af16 --- /dev/null +++ b/tests/list04.page @@ -0,0 +1,17 @@ + + + List Test + + +

First Item

+
+ +

Second Item

+
+
+ + +

Second List

+
+
+
diff --git a/tests/list05.duck b/tests/list05.duck new file mode 100644 index 0000000..8441620 --- /dev/null +++ b/tests/list05.duck @@ -0,0 +1,10 @@ += List Test + +* List item 1 + Continuing list item 1 +* List item 2 + +* List item 3 still in the same list + +[list] +* List item 1 in a new list diff --git a/tests/list05.page b/tests/list05.page new file mode 100644 index 0000000..58f7d7c --- /dev/null +++ b/tests/list05.page @@ -0,0 +1,21 @@ + + + List Test + + +

List item 1 + Continuing list item 1

+
+ +

List item 2

+
+ +

List item 3 still in the same list

+
+
+ + +

List item 1 in a new list

+
+
+
diff --git a/tests/list06.duck b/tests/list06.duck new file mode 100644 index 0000000..2e0cfe8 --- /dev/null +++ b/tests/list06.duck @@ -0,0 +1,13 @@ += List Test + +[steps] +* List item 1 + * Sublist item 1 + Continuing item 1 + * Sublist item 2 +* List item 2 + [steps] + * Substep 2.1 + * Substep 2.2 + [note] + A note in substep 2.2 diff --git a/tests/list06.page b/tests/list06.page new file mode 100644 index 0000000..b29ccb3 --- /dev/null +++ b/tests/list06.page @@ -0,0 +1,32 @@ + + + List Test + + +

List item 1

+ + +

Sublist item 1 + Continuing item 1

+
+ +

Sublist item 2

+
+
+
+ +

List item 2

+ + +

Substep 2.1

+
+ +

Substep 2.2

+ +

A note in substep 2.2

+
+
+
+
+
+
diff --git a/tests/list07.duck b/tests/list07.duck new file mode 100644 index 0000000..dc127e9 --- /dev/null +++ b/tests/list07.duck @@ -0,0 +1,18 @@ += List Test + +[terms] +[item] +[title] + Term 1 +Definition 1 +[item] +[title] + Term 2 +[p] +Definition 2 + +[item] +[title] +Term 3 + +Not in the terms list because the newline breaks free of the item. diff --git a/tests/list07.page b/tests/list07.page new file mode 100644 index 0000000..939c389 --- /dev/null +++ b/tests/list07.page @@ -0,0 +1,18 @@ + + + List Test + + + Term 1 +

Definition 1

+
+ + Term 2 +

Definition 2

+
+ + Term 3 + +
+

Not in the terms list because the newline breaks free of the item.

+
diff --git a/tests/list08.duck b/tests/list08.duck new file mode 100644 index 0000000..1a8283c --- /dev/null +++ b/tests/list08.duck @@ -0,0 +1,11 @@ += List Test + +[terms] +- Term 1 +* Definition 1 +- Term 2 +* Definition 2 + +- Term 3 + +* Definition 3 diff --git a/tests/list08.page b/tests/list08.page new file mode 100644 index 0000000..043e128 --- /dev/null +++ b/tests/list08.page @@ -0,0 +1,18 @@ + + + List Test + + + Term 1 +

Definition 1

+
+ + Term 2 +

Definition 2

+
+ + Term 3 +

Definition 3

+
+
+
diff --git a/tests/list09.duck b/tests/list09.duck new file mode 100644 index 0000000..bbbe79c --- /dev/null +++ b/tests/list09.duck @@ -0,0 +1,18 @@ += List Test + +[terms] +- Item 1 Term 1 +- Item 1 Term 2 +* Definition 1 + +- Item 2 Term 1 + +- Item 2 + Term 2 + +* Definition 2 + Cointinuing definition 2 + + New paragraph in definition 2 + +Out of the terms list diff --git a/tests/list09.page b/tests/list09.page new file mode 100644 index 0000000..30ce057 --- /dev/null +++ b/tests/list09.page @@ -0,0 +1,20 @@ + + + List Test + + + Item 1 Term 1 + Item 1 Term 2 +

Definition 1

+
+ + Item 2 Term 1 + Item 2 + Term 2 +

Definition 2 + Cointinuing definition 2

+

New paragraph in definition 2

+
+
+

Out of the terms list

+
diff --git a/tests/list10.duck b/tests/list10.duck new file mode 100644 index 0000000..963e27f --- /dev/null +++ b/tests/list10.duck @@ -0,0 +1,7 @@ += List Test + +[terms] +. Terms Title +- Item 1 Term 1 +- Item 1 Term 2 +* Definition 1 diff --git a/tests/list10.page b/tests/list10.page new file mode 100644 index 0000000..851779c --- /dev/null +++ b/tests/list10.page @@ -0,0 +1,12 @@ + + + List Test + + Terms Title + + Item 1 Term 1 + Item 1 Term 2 +

Definition 1

+
+
+
diff --git a/tests/list11.duck b/tests/list11.duck new file mode 100644 index 0000000..5d5c3f6 --- /dev/null +++ b/tests/list11.duck @@ -0,0 +1,9 @@ += List Test + +[tree] +* List item 1 + * Sublist item 1 + Continuing item 1 + * Sublist item 2 + * Subsublist item 1 +* List item 2 diff --git a/tests/list11.page b/tests/list11.page new file mode 100644 index 0000000..6e2027b --- /dev/null +++ b/tests/list11.page @@ -0,0 +1,14 @@ + + + List Test + + List item 1 + Sublist item 1 + Continuing item 1 + Sublist item 2 + Subsublist item 1 + + + List item 2 + + diff --git a/tests/list12.duck b/tests/list12.duck new file mode 100644 index 0000000..94b3d6f --- /dev/null +++ b/tests/list12.duck @@ -0,0 +1,11 @@ += List Test + +[tree] +* List item 1 + * Sublist item 1 + [[[ + Continuing item 1 + ]]] + * Sublist item 2 + * Subsublist item 1 +* List item 2 diff --git a/tests/list12.page b/tests/list12.page new file mode 100644 index 0000000..09f43b3 --- /dev/null +++ b/tests/list12.page @@ -0,0 +1,14 @@ + + + List Test + + List item 1 + Sublist item 1 +Continuing item 1 + Sublist item 2 + Subsublist item 1 + + + List item 2 + + diff --git a/tests/list13.duck b/tests/list13.duck new file mode 100644 index 0000000..afa3a86 --- /dev/null +++ b/tests/list13.duck @@ -0,0 +1,18 @@ += List Test + +[tree] +* List item 1 + +* List item 2 + + * Sublist item 1 + + + * Sublist item 2 + + + * Subsublist item 1 + + * Subsublist item 2 + +* List item 3 diff --git a/tests/list13.page b/tests/list13.page new file mode 100644 index 0000000..b1b5a1b --- /dev/null +++ b/tests/list13.page @@ -0,0 +1,15 @@ + + + List Test + + List item 1 + List item 2 + Sublist item 1 + Sublist item 2 + Subsublist item 1 + Subsublist item 2 + + + List item 3 + + diff --git a/tests/list14.duck b/tests/list14.duck new file mode 100644 index 0000000..dbe6ccd --- /dev/null +++ b/tests/list14.duck @@ -0,0 +1,12 @@ += List Test + +[tree] +* List item 1 + +* List item 2 + + * Sublist item 1 + + This must break out of the tree + + * Sublist item 2 diff --git a/tests/list14.page b/tests/list14.page new file mode 100644 index 0000000..9319894 --- /dev/null +++ b/tests/list14.page @@ -0,0 +1,16 @@ + + + List Test + + List item 1 + List item 2 + Sublist item 1 + + +

This must break out of the tree

+ + +

Sublist item 2

+
+
+
diff --git a/tests/list15.duck b/tests/list15.duck new file mode 100644 index 0000000..719148f --- /dev/null +++ b/tests/list15.duck @@ -0,0 +1,14 @@ += List Test + +[tree] +* List item 1 + +* List item 2 + + * Sublist item 1 + + [[[ + This must break out of the tree + ]]] + + * Sublist item 2 diff --git a/tests/list15.page b/tests/list15.page new file mode 100644 index 0000000..24a1b83 --- /dev/null +++ b/tests/list15.page @@ -0,0 +1,16 @@ + + + List Test + + List item 1 + List item 2 + Sublist item 1 + + +

This must break out of the tree

+ + +

Sublist item 2

+
+
+
diff --git a/tests/list16.duck b/tests/list16.duck new file mode 100644 index 0000000..1a620cc --- /dev/null +++ b/tests/list16.duck @@ -0,0 +1,13 @@ += List Test + +[tree] +* List item 1 + +* List item 2 + + * Sublist item 1 + + [note] + This must break out of the tree + + * Sublist item 2 diff --git a/tests/list16.page b/tests/list16.page new file mode 100644 index 0000000..3d7af31 --- /dev/null +++ b/tests/list16.page @@ -0,0 +1,18 @@ + + + List Test + + List item 1 + List item 2 + Sublist item 1 + + + +

This must break out of the tree

+
+ + +

Sublist item 2

+
+
+
diff --git a/tests/list17.duck b/tests/list17.duck new file mode 100644 index 0000000..1adc892 --- /dev/null +++ b/tests/list17.duck @@ -0,0 +1,4 @@ += List Test + +- Implicit Term +* This creates an implicit terms element diff --git a/tests/list17.page b/tests/list17.page new file mode 100644 index 0000000..41cd436 --- /dev/null +++ b/tests/list17.page @@ -0,0 +1,10 @@ + + + List Test + + + Implicit Term +

This creates an implicit terms element

+
+
+
diff --git a/tests/namespace01.duck b/tests/namespace01.duck new file mode 100644 index 0000000..4f8adfd --- /dev/null +++ b/tests/namespace01.duck @@ -0,0 +1,6 @@ +@ducktype/1.0 +@namespace if http://projectmallard.org/if/1.0/ + += Namespace Test + +This is a test of namespaces. diff --git a/tests/namespace01.page b/tests/namespace01.page new file mode 100644 index 0000000..40a3c80 --- /dev/null +++ b/tests/namespace01.page @@ -0,0 +1,5 @@ + + + Namespace Test +

This is a test of namespaces.

+
diff --git a/tests/namespace02.duck b/tests/namespace02.duck new file mode 100644 index 0000000..3b57fcd --- /dev/null +++ b/tests/namespace02.duck @@ -0,0 +1,10 @@ +@ducktype/1.0 +@namespace if http://projectmallard.org/if/1.0/ + += Namespace Test + +[if:if test=target:mobile] +This is a test of namespaces. + +[p if:test=target:mobile] +This is a test of namespaces. diff --git a/tests/namespace02.page b/tests/namespace02.page new file mode 100644 index 0000000..a16f7d3 --- /dev/null +++ b/tests/namespace02.page @@ -0,0 +1,8 @@ + + + Namespace Test + +

This is a test of namespaces.

+
+

This is a test of namespaces.

+
diff --git a/tests/namespace03.duck b/tests/namespace03.duck new file mode 100644 index 0000000..184d85a --- /dev/null +++ b/tests/namespace03.duck @@ -0,0 +1,11 @@ +@ducktype/1.0 +@namespace if http://projectmallard.org/if/1.0/ +@namespace if http://projectmallard.org/if/2.0/ + += Namespace Test + +[if:if test=target:mobile] +This is a test of namespaces. + +[p if:test=target:mobile] +This is a test of namespaces. diff --git a/tests/namespace03.page b/tests/namespace03.page new file mode 100644 index 0000000..c864694 --- /dev/null +++ b/tests/namespace03.page @@ -0,0 +1,8 @@ + + + Namespace Test + +

This is a test of namespaces.

+
+

This is a test of namespaces.

+
diff --git a/tests/namespace04.duck b/tests/namespace04.duck new file mode 100644 index 0000000..6128af6 --- /dev/null +++ b/tests/namespace04.duck @@ -0,0 +1,5 @@ +@ducktype/1.0 + += Namespace Test + +This is a test of undefined $e:hi(namespaces). diff --git a/tests/namespace04.error b/tests/namespace04.error new file mode 100644 index 0000000..03de5dd --- /dev/null +++ b/tests/namespace04.error @@ -0,0 +1 @@ +namespace04.duck:5: Unrecognized namespace prefix: e diff --git a/tests/namespace05.duck b/tests/namespace05.duck new file mode 100644 index 0000000..9012661 --- /dev/null +++ b/tests/namespace05.duck @@ -0,0 +1,6 @@ +@ducktype/1.0 + += Namespace Test + +[e:nope] +This is a test of undefined namespaces. diff --git a/tests/namespace05.error b/tests/namespace05.error new file mode 100644 index 0000000..4df66fc --- /dev/null +++ b/tests/namespace05.error @@ -0,0 +1 @@ +namespace05.duck:5: Unrecognized namespace prefix: e diff --git a/tests/namespace06.duck b/tests/namespace06.duck new file mode 100644 index 0000000..e627305 --- /dev/null +++ b/tests/namespace06.duck @@ -0,0 +1,6 @@ +@ducktype/1.0 + += Namespace Test +@e:nope Fail on this line + +This is a test of undefined namespaces. diff --git a/tests/namespace06.error b/tests/namespace06.error new file mode 100644 index 0000000..852751a --- /dev/null +++ b/tests/namespace06.error @@ -0,0 +1 @@ +namespace06.duck:4: Unrecognized namespace prefix: e diff --git a/tests/namespace07.duck b/tests/namespace07.duck new file mode 100644 index 0000000..1894ccc --- /dev/null +++ b/tests/namespace07.duck @@ -0,0 +1,6 @@ +@ducktype/1.0 +@define undefined undefined $e:hi(namespace) + += Namespace Test + +This is a test of $undefined;. diff --git a/tests/namespace07.error b/tests/namespace07.error new file mode 100644 index 0000000..c0df516 --- /dev/null +++ b/tests/namespace07.error @@ -0,0 +1 @@ +namespace07.duck:6: Unrecognized namespace prefix: e diff --git a/tests/namespace08.duck b/tests/namespace08.duck new file mode 100644 index 0000000..b1006f7 --- /dev/null +++ b/tests/namespace08.duck @@ -0,0 +1,7 @@ +@ducktype/1.0 +@namespace xml http://www.w3.org/XML/1998/namespace + += Namespace Test + +[code xml:space=preserve] +This is a test of namespaces. diff --git a/tests/namespace08.page b/tests/namespace08.page new file mode 100644 index 0000000..85784ed --- /dev/null +++ b/tests/namespace08.page @@ -0,0 +1,5 @@ + + + Namespace Test + This is a test of namespaces. + diff --git a/tests/namespace09.duck b/tests/namespace09.duck new file mode 100644 index 0000000..1b65d1b --- /dev/null +++ b/tests/namespace09.duck @@ -0,0 +1,6 @@ +@ducktype/1.0 + += Namespace Test + +[code xml:space=preserve] +This is a test of namespaces. diff --git a/tests/namespace09.page b/tests/namespace09.page new file mode 100644 index 0000000..c775672 --- /dev/null +++ b/tests/namespace09.page @@ -0,0 +1,5 @@ + + + Namespace Test + This is a test of namespaces. + diff --git a/tests/namespace10.duck b/tests/namespace10.duck new file mode 100644 index 0000000..8d33bdd --- /dev/null +++ b/tests/namespace10.duck @@ -0,0 +1,7 @@ +@ducktype/1.0 +@namespace xml http://www.w3.org/XML/1998/wrongnamespace + += Namespace Test + +[code xml:space=preserve] +This is a test of namespaces. diff --git a/tests/namespace10.error b/tests/namespace10.error new file mode 100644 index 0000000..d346034 --- /dev/null +++ b/tests/namespace10.error @@ -0,0 +1 @@ +namespace10.duck:2: Wrong value of xml namespace prefix diff --git a/tests/namespace11.duck b/tests/namespace11.duck new file mode 100644 index 0000000..696ea3c --- /dev/null +++ b/tests/namespace11.duck @@ -0,0 +1,7 @@ +@ducktype/1.0 +@namespace its http://www.w3.org/2005/11/its + += Namespace Test + +[code its:translate=yes] +This is a test of namespaces. diff --git a/tests/namespace11.page b/tests/namespace11.page new file mode 100644 index 0000000..d7619db --- /dev/null +++ b/tests/namespace11.page @@ -0,0 +1,5 @@ + + + Namespace Test + This is a test of namespaces. + diff --git a/tests/namespace12.duck b/tests/namespace12.duck new file mode 100644 index 0000000..8b9317e --- /dev/null +++ b/tests/namespace12.duck @@ -0,0 +1,6 @@ +@ducktype/1.0 + += Namespace Test + +[code its:translate=yes] +This is a test of namespaces. diff --git a/tests/namespace12.page b/tests/namespace12.page new file mode 100644 index 0000000..9a1e63c --- /dev/null +++ b/tests/namespace12.page @@ -0,0 +1,5 @@ + + + Namespace Test + This is a test of namespaces. + diff --git a/tests/namespace13.duck b/tests/namespace13.duck new file mode 100644 index 0000000..5b2d8ad --- /dev/null +++ b/tests/namespace13.duck @@ -0,0 +1,7 @@ +@ducktype/1.0 +@namespace its http://www.w3.org/2005/11/its/wrongnamespace + += Namespace Test + +[code its:translate=yes] +This is a test of namespaces. diff --git a/tests/namespace13.error b/tests/namespace13.error new file mode 100644 index 0000000..302dbb9 --- /dev/null +++ b/tests/namespace13.error @@ -0,0 +1 @@ +namespace13.duck:2: Wrong value of its namespace prefix diff --git a/tests/namespace14.duck b/tests/namespace14.duck new file mode 100644 index 0000000..843d5d3 --- /dev/null +++ b/tests/namespace14.duck @@ -0,0 +1,7 @@ +@ducktype/1.0 + += Namespace Test +@its:rules[version=2.0] + +[code its:translate=yes] +This is a test of namespaces. diff --git a/tests/namespace14.page b/tests/namespace14.page new file mode 100644 index 0000000..f02ea68 --- /dev/null +++ b/tests/namespace14.page @@ -0,0 +1,8 @@ + + + + + + Namespace Test + This is a test of namespaces. + diff --git a/tests/page01.duck b/tests/page01.duck new file mode 100644 index 0000000..580f858 --- /dev/null +++ b/tests/page01.duck @@ -0,0 +1,5 @@ += Page Title + +This is a simple page. + +This is another paragraph. diff --git a/tests/page01.page b/tests/page01.page new file mode 100644 index 0000000..b11bd28 --- /dev/null +++ b/tests/page01.page @@ -0,0 +1,6 @@ + + + Page Title +

This is a simple page.

+

This is another paragraph.

+
diff --git a/tests/page02.duck b/tests/page02.duck new file mode 100644 index 0000000..3a367cb --- /dev/null +++ b/tests/page02.duck @@ -0,0 +1,4 @@ += Page + Title + +This is a paragraph. diff --git a/tests/page02.page b/tests/page02.page new file mode 100644 index 0000000..11debc0 --- /dev/null +++ b/tests/page02.page @@ -0,0 +1,6 @@ + + + Page + Title +

This is a paragraph.

+
diff --git a/tests/page03.duck b/tests/page03.duck new file mode 100644 index 0000000..0ebf1ab --- /dev/null +++ b/tests/page03.duck @@ -0,0 +1,5 @@ += Page + Title +- Subtitle + +This is a paragraph. diff --git a/tests/page03.page b/tests/page03.page new file mode 100644 index 0000000..2bdde9c --- /dev/null +++ b/tests/page03.page @@ -0,0 +1,7 @@ + + + Page + Title + Subtitle +

This is a paragraph.

+
diff --git a/tests/page04.duck b/tests/page04.duck new file mode 100644 index 0000000..3828182 --- /dev/null +++ b/tests/page04.duck @@ -0,0 +1,6 @@ += Page + Title +- Page + Subtitle + +This is a paragraph. diff --git a/tests/page04.page b/tests/page04.page new file mode 100644 index 0000000..3f7c734 --- /dev/null +++ b/tests/page04.page @@ -0,0 +1,8 @@ + + + Page + Title + Page + Subtitle +

This is a paragraph.

+
diff --git a/tests/page05.duck b/tests/page05.duck new file mode 100644 index 0000000..8d77e6a --- /dev/null +++ b/tests/page05.duck @@ -0,0 +1,8 @@ += Page + Title +- Page + Subtitle + [#pageid + .pagestyle] + +This is a paragraph. diff --git a/tests/page05.page b/tests/page05.page new file mode 100644 index 0000000..4e0e24b --- /dev/null +++ b/tests/page05.page @@ -0,0 +1,8 @@ + + + Page + Title + Page + Subtitle +

This is a paragraph.

+
diff --git a/tests/runtest.py b/tests/runtest.py new file mode 100755 index 0000000..4b79b0a --- /dev/null +++ b/tests/runtest.py @@ -0,0 +1,17 @@ +#!/usr/bin/env python3 + +import os +import sys + +sys.path.insert(0, (os.path.dirname(os.path.abspath(os.path.dirname(sys.argv[0]))))) + +import mallard.ducktype + +try: + parser = mallard.ducktype.DuckParser() + parser.parse_file(sys.argv[1]) + parser.finish() +except mallard.ducktype.SyntaxError as e: + print(e.fullmessage) + sys.exit(1) +parser.document.write_xml(sys.stdout) diff --git a/tests/runtests b/tests/runtests new file mode 100755 index 0000000..43597e6 --- /dev/null +++ b/tests/runtests @@ -0,0 +1,59 @@ +#!/bin/sh + +set -e +set -u + +count=0 +any_failed=0 +silent=0 +glob="" + +for arg in $@; do + if [ "x$arg" = "x-s" ]; then + silent=1 + elif [ "x$arg" != "x" ]; then + glob="$arg" + fi +done + +for duck in *$glob*.duck; do + count=$(( count + 1 )) + out=$(echo $duck | sed -e 's/\.duck$/.out/') + page=$(echo $duck | sed -e 's/\.duck$/.page/') + error=$(echo $duck | sed -e 's/\.duck$/.error/') + fail="" + if [ -f "$page" ]; then + python3 runtest.py "$duck" > "$out" || fail="exit status $?" + if ! cmp "$out" "$page" >&2; then + fail="${fail:+${fail}, }unexpected output" + diff -u "$out" "$page" >&2 || : + fi + elif [ -f "$error" ]; then + status=0 + python3 runtest.py "$duck" > "$out" || : + if ! cmp "$out" "$error" >&2; then + fail="unexpected error message" + diff -u "$out" "$error" >&2 || : + fi + else + fail="neither $page nor $error exists" + fi + if [ -z "$fail" ]; then + if [ $silent = 0 ]; then + echo "ok $count - $duck" + fi + else + any_failed=1 + echo "not ok $count - $duck: $fail" + fi +done + +echo "1..$count" + +if [ "$any_failed" = 0 ]; then + echo "# All tests successful" +else + echo "# At least one test failed" +fi + +exit $any_failed diff --git a/tests/section01.duck b/tests/section01.duck new file mode 100644 index 0000000..7d1eafc --- /dev/null +++ b/tests/section01.duck @@ -0,0 +1,5 @@ += Section Test + +== This is a section + +This is a paragraph. diff --git a/tests/section01.page b/tests/section01.page new file mode 100644 index 0000000..195597a --- /dev/null +++ b/tests/section01.page @@ -0,0 +1,8 @@ + + + Section Test +
+ This is a section +

This is a paragraph.

+
+
diff --git a/tests/section02.duck b/tests/section02.duck new file mode 100644 index 0000000..ff1076d --- /dev/null +++ b/tests/section02.duck @@ -0,0 +1,8 @@ += Section Test + +== This is a section + with a long title + +== This is another section + +This is a paragraph. diff --git a/tests/section02.page b/tests/section02.page new file mode 100644 index 0000000..436fc71 --- /dev/null +++ b/tests/section02.page @@ -0,0 +1,12 @@ + + + Section Test +
+ This is a section + with a long title +
+
+ This is another section +

This is a paragraph.

+
+
diff --git a/tests/section03.duck b/tests/section03.duck new file mode 100644 index 0000000..248781c --- /dev/null +++ b/tests/section03.duck @@ -0,0 +1,23 @@ += Section Test + +This is a paragraph. + +== First section + +This paragraph is in the first section + +=== First subsection + +==== First subsubsection + +=== Second subsection + +This paragraph is in subsection 2. + +==== Secont subsubsection + +This paragraph is in subsubsection 2. + +== Breaking out to a top-level section. + +And a final paragraph. diff --git a/tests/section03.page b/tests/section03.page new file mode 100644 index 0000000..0308567 --- /dev/null +++ b/tests/section03.page @@ -0,0 +1,27 @@ + + + Section Test +

This is a paragraph.

+
+ First section +

This paragraph is in the first section

+
+ First subsection +
+ First subsubsection +
+
+
+ Second subsection +

This paragraph is in subsection 2.

+
+ Secont subsubsection +

This paragraph is in subsubsection 2.

+
+
+
+
+ Breaking out to a top-level section. +

And a final paragraph.

+
+
diff --git a/tests/section04.duck b/tests/section04.duck new file mode 100644 index 0000000..45cc661 --- /dev/null +++ b/tests/section04.duck @@ -0,0 +1,17 @@ += Section Test + +== Section One + [#sect1 + .sect1style] + +=== Section One Point One + [ + #sect1-1 + style="sect1style" + ] + +== Section Two + [ + id="sect2"] + +This is in section two. diff --git a/tests/section04.page b/tests/section04.page new file mode 100644 index 0000000..ac80d28 --- /dev/null +++ b/tests/section04.page @@ -0,0 +1,14 @@ + + + Section Test +
+ Section One +
+ Section One Point One +
+
+
+ Section Two +

This is in section two.

+
+
diff --git a/tests/section05.duck b/tests/section05.duck new file mode 100644 index 0000000..ef4d30d --- /dev/null +++ b/tests/section05.duck @@ -0,0 +1,16 @@ += Section Test + +== Section One +-- Section One Subtitle + +=== Section One + Point One +--- Section 1.1 + Subtitle + +== Section Two +-- Subtitle Two + [ + id="sect2"] + +This is in section two. diff --git a/tests/section05.page b/tests/section05.page new file mode 100644 index 0000000..5f943fc --- /dev/null +++ b/tests/section05.page @@ -0,0 +1,19 @@ + + + Section Test +
+ Section One + Section One Subtitle +
+ Section One + Point One + Section 1.1 + Subtitle +
+
+
+ Section Two + Subtitle Two +

This is in section two.

+
+
diff --git a/tests/section06.duck b/tests/section06.duck new file mode 100644 index 0000000..5aa2a3a --- /dev/null +++ b/tests/section06.duck @@ -0,0 +1,10 @@ += Section Test + +== Section One + +[code] + Some code + +== Section Two + +Some text diff --git a/tests/section06.page b/tests/section06.page new file mode 100644 index 0000000..eeab124 --- /dev/null +++ b/tests/section06.page @@ -0,0 +1,12 @@ + + + Section Test +
+ Section One + Some code +
+
+ Section Two +

Some text

+
+
diff --git a/tests/section07.duck b/tests/section07.duck new file mode 100644 index 0000000..272bd60 --- /dev/null +++ b/tests/section07.duck @@ -0,0 +1,27 @@ += Section Test + +== Section One +-- Section One Subtitle + [#sect1] + +[screen] +This is section one. + +== Section + Two +-- Section + Two Subtitle + [#sect2] + +This is section two. + +== Section + Three + [#sect3] + +This is section three. + +== Section + Four + +Four is a paragraph. diff --git a/tests/section07.page b/tests/section07.page new file mode 100644 index 0000000..326b628 --- /dev/null +++ b/tests/section07.page @@ -0,0 +1,26 @@ + + + Section Test +
+ Section One + Section One Subtitle + This is section one. +
+
+ Section + Two + Section + Two Subtitle +

This is section two.

+
+
+ Section + Three +

This is section three.

+
+
+ Section +

Four

+

Four is a paragraph.

+
+
diff --git a/tests/table01.duck b/tests/table01.duck new file mode 100644 index 0000000..8941060 --- /dev/null +++ b/tests/table01.duck @@ -0,0 +1,15 @@ += Table Test + +[table] +[tr] +[th] +Northwest +[th] +Northeast +[tr] +[td] +Southwest +[td] +Southeast + +Out of the table diff --git a/tests/table01.page b/tests/table01.page new file mode 100644 index 0000000..57044c0 --- /dev/null +++ b/tests/table01.page @@ -0,0 +1,23 @@ + + + Table Test + + + + + + + + + +
+

Northwest

+
+

Northeast

+
+

Southwest

+
+

Southeast

+
+

Out of the table

+
diff --git a/tests/table02.duck b/tests/table02.duck new file mode 100644 index 0000000..9dfdfdb --- /dev/null +++ b/tests/table02.duck @@ -0,0 +1,38 @@ += Table Test + +[table] +[thead] +[tr] +[td] +One +[td] +Two +[tr] +[td] +Three +[td] +Four +[tbody] +[tr] +[td] +One +[td] +Two +[tr] +[td] +Three +[td] +Four +[tfoot] +[tr] +[td] +One +[td] +Two +[tr] +[td] +Three +[td] +Four + +Out of the table diff --git a/tests/table02.page b/tests/table02.page new file mode 100644 index 0000000..1167eea --- /dev/null +++ b/tests/table02.page @@ -0,0 +1,61 @@ + + + Table Test + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+

One

+
+

Two

+
+

Three

+
+

Four

+
+

One

+
+

Two

+
+

Three

+
+

Four

+
+

One

+
+

Two

+
+

Three

+
+

Four

+
+

Out of the table

+
diff --git a/tests/table03.duck b/tests/table03.duck new file mode 100644 index 0000000..296f742 --- /dev/null +++ b/tests/table03.duck @@ -0,0 +1,38 @@ += Table Test + +[table] +[tbody] +[tr] +[td] +One +[td] +Two +[tr] +[td] +Three +[td] +Four +[tbody] +[tr] +[td] +One +[td] +Two +[tr] +[td] +Three +[td] +Four +[tbody] +[tr] +[td] +One +[td] +Two +[tr] +[td] +Three +[td] +Four + +Out of the table diff --git a/tests/table03.page b/tests/table03.page new file mode 100644 index 0000000..edd92ad --- /dev/null +++ b/tests/table03.page @@ -0,0 +1,61 @@ + + + Table Test + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+

One

+
+

Two

+
+

Three

+
+

Four

+
+

One

+
+

Two

+
+

Three

+
+

Four

+
+

One

+
+

Two

+
+

Three

+
+

Four

+
+

Out of the table

+
diff --git a/tests/table04.duck b/tests/table04.duck new file mode 100644 index 0000000..2821166 --- /dev/null +++ b/tests/table04.duck @@ -0,0 +1,11 @@ += Table Test + +[table] +[tr] +- Northwest +- Northeast +[tr] +* Southwest +* Southeast + +Out of the table diff --git a/tests/table04.page b/tests/table04.page new file mode 100644 index 0000000..a9cf590 --- /dev/null +++ b/tests/table04.page @@ -0,0 +1,23 @@ + + + Table Test + + + + + + + + + +
+

Northwest

+
+

Northeast

+
+

Southwest

+
+

Southeast

+
+

Out of the table

+
diff --git a/tests/table05.duck b/tests/table05.duck new file mode 100644 index 0000000..56868a7 --- /dev/null +++ b/tests/table05.duck @@ -0,0 +1,18 @@ += Table Test + +[table] +[tr] +- North + west +- North + + east +[tr] +* South + + west + +* South + east + +Out of the table diff --git a/tests/table05.page b/tests/table05.page new file mode 100644 index 0000000..8b9c849 --- /dev/null +++ b/tests/table05.page @@ -0,0 +1,27 @@ + + + Table Test + + + + + + + + + +
+

North + west

+
+

North

+

east

+
+

South

+

west

+
+

South + east

+
+

Out of the table

+
diff --git a/tests/verbatim01.duck b/tests/verbatim01.duck new file mode 100644 index 0000000..1436fee --- /dev/null +++ b/tests/verbatim01.duck @@ -0,0 +1,7 @@ += Verbatim Test + +[screen] +This is in a verbatim environment +This is still in it. + +This is in its own paragraph. diff --git a/tests/verbatim01.page b/tests/verbatim01.page new file mode 100644 index 0000000..f41e43e --- /dev/null +++ b/tests/verbatim01.page @@ -0,0 +1,7 @@ + + + Verbatim Test + This is in a verbatim environment +This is still in it. +

This is in its own paragraph.

+
diff --git a/tests/verbatim02.duck b/tests/verbatim02.duck new file mode 100644 index 0000000..34fb7de --- /dev/null +++ b/tests/verbatim02.duck @@ -0,0 +1,9 @@ += Verbatim Test + +[screen] + This is in a verbatim environment + This is still in it. + + This is also still in the verbatim. + +This is in its own paragraph. diff --git a/tests/verbatim02.page b/tests/verbatim02.page new file mode 100644 index 0000000..57b6b4b --- /dev/null +++ b/tests/verbatim02.page @@ -0,0 +1,9 @@ + + + Verbatim Test + This is in a verbatim environment +This is still in it. + +This is also still in the verbatim. +

This is in its own paragraph.

+
diff --git a/tests/verbatim03.duck b/tests/verbatim03.duck new file mode 100644 index 0000000..70a198c --- /dev/null +++ b/tests/verbatim03.duck @@ -0,0 +1,15 @@ += Verbatim Test + +[note] + [code] + This is in code in a note. + So is this. + + This is in a new paragraph in the note. + + [screen] + This is in a screen in a note. + + This is still in that screen. + +This breaks out of the note. diff --git a/tests/verbatim03.page b/tests/verbatim03.page new file mode 100644 index 0000000..cf88d35 --- /dev/null +++ b/tests/verbatim03.page @@ -0,0 +1,13 @@ + + + Verbatim Test + + This is in code in a note. +So is this. +

This is in a new paragraph in the note.

+ This is in a screen in a note. + +This is still in that screen. +
+

This breaks out of the note.

+
diff --git a/tests/verbatim04.duck b/tests/verbatim04.duck new file mode 100644 index 0000000..cec399c --- /dev/null +++ b/tests/verbatim04.duck @@ -0,0 +1,14 @@ += Verbatim Test + +[note] + [code] + This is in code in a note. + So is this, and it's indented. + + This is still in the code at the original indent. + + This is indented after a line break. + This is indented even further. + + This is no longer indented. + This is no longer in the code, but still in the note. diff --git a/tests/verbatim04.page b/tests/verbatim04.page new file mode 100644 index 0000000..5e2515b --- /dev/null +++ b/tests/verbatim04.page @@ -0,0 +1,16 @@ + + + Verbatim Test + + This is in code in a note. + So is this, and it's indented. + +This is still in the code at the original indent. + + This is indented after a line break. + This is indented even further. + +This is no longer indented. +

This is no longer in the code, but still in the note.

+
+