├── docs ├── config.py ├── inc │ └── menu.stx ├── out │ ├── assets │ │ ├── code.js │ │ ├── fonts.css │ │ ├── fonts │ │ │ ├── CrimsonText-Bold.ttf │ │ │ ├── CrimsonText-Bold.woff2 │ │ │ ├── CrimsonText-BoldItalic.ttf │ │ │ ├── CrimsonText-BoldItalic.woff2 │ │ │ ├── CrimsonText-Italic.ttf │ │ │ ├── CrimsonText-Italic.woff2 │ │ │ ├── CrimsonText-Regular.ttf │ │ │ ├── CrimsonText-Regular.woff2 │ │ │ ├── CrimsonText-SemiBold.ttf │ │ │ ├── CrimsonText-SemiBold.woff2 │ │ │ ├── CrimsonText-SemiBoldItalic.ttf │ │ │ ├── CrimsonText-SemiBoldItalic.woff2 │ │ │ └── OFL.txt │ │ ├── graphite.css │ │ └── pygments.css │ ├── block-syntax.html │ ├── changelog.html │ ├── index.html │ ├── inline-syntax.html │ ├── license.html │ ├── miscellanea.html │ ├── raw-html.html │ ├── shorthand-html.html │ └── tagged-blocks.html └── src │ ├── block-syntax.stx │ ├── changelog.stx │ ├── index.stx │ ├── inline-syntax.stx │ ├── license.stx │ ├── miscellanea.stx │ ├── raw-html.stx │ ├── shorthand-html.stx │ └── tagged-blocks.stx ├── license.txt ├── makefile ├── readme.md ├── setup.py ├── syntext ├── __init__.py ├── __main__.py ├── inline.py ├── interface.py ├── nodes.py ├── parsers.py ├── shorthand.py ├── tags.py ├── toc.py └── utils.py ├── test_syntext.py └── unittests ├── blank ├── empty.html ├── empty.txt ├── newline.html ├── newline.txt ├── spaces-with-newline.html ├── spaces-with-newline.txt ├── spaces.html └── spaces.txt ├── blocks ├── boxed-headings.html ├── boxed-headings.txt ├── dl.html ├── dl.txt ├── fancy-h1.html ├── fancy-h1.txt ├── fancy-h2.html ├── fancy-h2.txt ├── generic-block.html ├── generic-block.txt ├── headings-with-trailing-symbols.html ├── headings-with-trailing-symbols.txt ├── headings.html ├── headings.txt ├── html-multi-line.html ├── html-multi-line.txt ├── html-single-line.html ├── html-single-line.txt ├── indented-code-with-blanks.html ├── indented-code-with-blanks.txt ├── indented-code-with-escapes.html ├── indented-code-with-escapes.txt ├── indented-code.html ├── indented-code.txt ├── numeric-heading.html ├── numeric-heading.txt ├── ol-block-nested-compact-ol.html ├── ol-block-nested-compact-ol.txt ├── ol-block-paragraphs-multiple.html ├── ol-block-paragraphs-multiple.txt ├── ol-block-paragraphs.html ├── ol-block-paragraphs.txt ├── ol-compact-blanklines.html ├── ol-compact-blanklines.txt ├── ol-compact-multiline.html ├── ol-compact-multiline.txt ├── ol-compact-nested-ol.html ├── ol-compact-nested-ol.txt ├── ol-marker-custom-start.html ├── ol-marker-custom-start.txt ├── ol-marker-hash.html ├── ol-marker-hash.txt ├── ol-marker-indented-1.html ├── ol-marker-indented-1.txt ├── ol-marker-indented-2.html ├── ol-marker-indented-2.txt ├── ol-marker-indented-3.html ├── ol-marker-indented-3.txt ├── ol-marker-int.html ├── ol-marker-int.txt ├── paragraph-multiline.html ├── paragraph-multiline.txt ├── paragraph-multiple.html ├── paragraph-multiple.txt ├── paragraph-single.html ├── paragraph-single.txt ├── ul-block-nested-compact-ul.html ├── ul-block-nested-compact-ul.txt ├── ul-block-paragraphs-multiple.html ├── ul-block-paragraphs-multiple.txt ├── ul-block-paragraphs.html ├── ul-block-paragraphs.txt ├── ul-compact-blanklines.html ├── ul-compact-blanklines.txt ├── ul-compact-multiline.html ├── ul-compact-multiline.txt ├── ul-compact-nested-ul.html ├── ul-compact-nested-ul.txt ├── ul-marker-asterisk.html ├── ul-marker-asterisk.txt ├── ul-marker-bullet.html ├── ul-marker-bullet.txt ├── ul-marker-change.html ├── ul-marker-change.txt ├── ul-marker-dash.html ├── ul-marker-dash.txt ├── ul-marker-indented-1.html ├── ul-marker-indented-1.txt ├── ul-marker-indented-2.html ├── ul-marker-indented-2.txt ├── ul-marker-indented-3.html ├── ul-marker-indented-3.txt ├── ul-marker-plus.html ├── ul-marker-plus.txt └── ul-plus.html ├── compound ├── autofootnotes.html ├── autofootnotes.txt ├── footnotes.html ├── footnotes.txt ├── fulltoc.html ├── fulltoc.txt ├── linked-image.html ├── linked-image.txt ├── links.html ├── links.txt ├── toc.html └── toc.txt ├── inline ├── adjacent-footnotes.html ├── adjacent-footnotes.txt ├── backticks-escaping-formatting.html ├── backticks-escaping-formatting.txt ├── backticks-escaping-html.html ├── backticks-escaping-html.txt ├── backticks.html ├── backticks.txt ├── bold-italic.html ├── bold-italic.txt ├── bold.html ├── bold.txt ├── bracketed-url.html ├── bracketed-url.txt ├── footnote-autonumbered.html ├── footnote-autonumbered.txt ├── footnote.html ├── footnote.txt ├── html-entities.html ├── html-entities.txt ├── html-special-chars.html ├── html-special-chars.txt ├── html.html ├── html.txt ├── image.html ├── image.txt ├── italic.html ├── italic.txt ├── link-followed-by-bracket.html ├── link-followed-by-bracket.txt ├── link-in-bracket.html ├── link-in-bracket.txt ├── link.html ├── link.txt ├── mdash.html ├── mdash.txt ├── ndash.html ├── ndash.txt ├── ref-image-fallback-alt.html ├── ref-image-fallback-alt.txt ├── ref-image-no-ref.html ├── ref-image-no-ref.txt ├── ref-image-with-title.html ├── ref-image-with-title.txt ├── ref-image.html ├── ref-image.txt ├── ref-link-fallback-text.html ├── ref-link-fallback-text.txt ├── ref-link-no-ref.html ├── ref-link-no-ref.txt ├── ref-link-with-title.html ├── ref-link-with-title.txt ├── ref-link.html ├── ref-link.txt ├── subscripts.html ├── subscripts.txt ├── superscripts.html ├── superscripts.txt ├── verbatim.html └── verbatim.txt ├── shorthand ├── a.html ├── a.txt ├── blockquote.html ├── blockquote.txt ├── div.html ├── div.txt ├── hr.html ├── hr.txt ├── img.html ├── img.txt ├── nl2br.html ├── nl2br.txt ├── p.html ├── p.txt ├── pre.html ├── pre.txt ├── raw.html ├── raw.txt ├── script.html ├── script.txt ├── span.html ├── span.txt ├── style.html └── style.txt ├── tables ├── alignment.html ├── alignment.txt ├── header-and-footer-boxed.html ├── header-and-footer-boxed.txt ├── header-and-footer.html ├── header-and-footer.txt ├── no-header-no-footer-boxed.html ├── no-header-no-footer-boxed.txt ├── no-header-no-footer.html └── no-header-no-footer.txt └── tags ├── code.html ├── code.txt ├── comment.html ├── comment.txt ├── div.html ├── div.txt ├── hr.html ├── hr.txt ├── image-with-alt.html ├── image-with-alt.txt ├── image.html ├── image.txt ├── infobox.html ├── infobox.txt ├── linked-image.html ├── linked-image.txt ├── nested-div.html ├── nested-div.txt ├── quote.html ├── quote.txt ├── raw.html └── raw.txt /docs/config.py: -------------------------------------------------------------------------------- 1 | title = "Syntext" 2 | tagline = "A lightweight, markdownish markup language for generating HTML." 3 | version = "Version 3.1.0" 4 | -------------------------------------------------------------------------------- /docs/inc/menu.stx: -------------------------------------------------------------------------------- 1 | 2 | * [Home](@root/) 3 | * [Block Syntax](@root/block-syntax//) 4 | * [Inline Syntax](@root/inline-syntax//) 5 | * [Shorthand HTML](@root/shorthand-html//) 6 | * [Tagged Blocks](@root/tagged-blocks//) 7 | * [Raw HTML](@root/raw-html//) 8 | * [Miscellanea](@root/miscellanea//) 9 | * [Changelog](@root/changelog//) 10 | * [License](@root/license//) 11 | * [Github](https://github.com/dmulholl/syntext) 12 | -------------------------------------------------------------------------------- /docs/out/assets/code.js: -------------------------------------------------------------------------------- 1 | // Add a copy button to
 tags unless they have a 'no-copy' class.
 2 | document.addEventListener("DOMContentLoaded", function() {
 3 |     if (!navigator.clipboard) {
 4 |         return;
 5 |     }
 6 | 
 7 |     document.querySelectorAll("pre").forEach(node => {
 8 |         if (node.classList.contains("no-copy")) {
 9 |             return;
10 |         }
11 | 
12 |         var wrapper = document.createElement('div');
13 |         wrapper.classList.add("pre-copy-wrapper");
14 |         node.parentNode.insertBefore(wrapper, node);
15 |         wrapper.appendChild(node);
16 | 
17 |         let copyBtn = document.createElement("button");
18 |         copyBtn.innerText = "[COPY]";
19 |         wrapper.appendChild(copyBtn);
20 | 
21 |         copyBtn.addEventListener("click", async () => {
22 |             let text = node.innerText;
23 |             await navigator.clipboard.writeText(text);
24 |             copyBtn.innerText = "[COPIED]";
25 |             setTimeout(() => copyBtn.innerText = "[COPY]", 1000);
26 |         })
27 |     })
28 | });
29 | 


--------------------------------------------------------------------------------
/docs/out/assets/fonts.css:
--------------------------------------------------------------------------------
 1 | /**
 2 |  * -------------------------------------------------------------------------
 3 |  *  Google fonts served locally.
 4 |  * -------------------------------------------------------------------------
 5 |  */
 6 | 
 7 | @font-face {
 8 |   font-family: 'Crimson Text';
 9 |   font-style: normal;
10 |   font-weight: 400;
11 |   src: local('Crimson Text Regular'),
12 |        local('CrimsonText-Regular'),
13 |        url(fonts/CrimsonText-Regular.woff2) format('woff2'),
14 |        url(fonts/CrimsonText-Regular.ttf) format('truetype');
15 | }
16 | 
17 | @font-face {
18 |   font-family: 'Crimson Text';
19 |   font-style: italic;
20 |   font-weight: 400;
21 |   src: local('Crimson Text Italic'),
22 |        local('CrimsonText-Italic'),
23 |        url(fonts/CrimsonText-Italic.woff2) format('woff2'),
24 |        url(fonts/CrimsonText-Italic.ttf) format('truetype');
25 | }
26 | 
27 | @font-face {
28 |   font-family: 'Crimson Text';
29 |   font-style: normal;
30 |   font-weight: 700;
31 |   src: local('Crimson Text Bold'),
32 |        local('CrimsonText-Bold'),
33 |        url(fonts/CrimsonText-Bold.woff2) format('woff2'),
34 |        url(fonts/CrimsonText-Bold.ttf) format('truetype');
35 | }
36 | 
37 | /*
38 |     The fonts below are packaged with the theme and can be uncommented
39 |     if needed.
40 |  */
41 | 
42 | /*
43 | @font-face {
44 |   font-family: 'Crimson Text';
45 |   font-style: italic;
46 |   font-weight: 700;
47 |   src: local('Crimson Text Bold Italic'),
48 |        local('CrimsonText-BoldItalic'),
49 |        url(fonts/CrimsonText-BoldItalic.woff2) format('woff2'),
50 |        url(fonts/CrimsonText-BoldItalic.ttf) format('truetype');
51 | }
52 | 
53 | @font-face {
54 |   font-family: 'Crimson Text';
55 |   font-style: normal;
56 |   font-weight: 600;
57 |   src: local('Crimson Text SemiBold'),
58 |        local('CrimsonText-SemiBold'),
59 |        url(fonts/CrimsonText-SemiBold.woff2) format('woff2'),
60 |        url(fonts/CrimsonText-SemiBold.ttf) format('truetype');
61 | }
62 | 
63 | @font-face {
64 |   font-family: 'Crimson Text';
65 |   font-style: italic;
66 |   font-weight: 600;
67 |   src: local('Crimson Text SemiBold Italic'),
68 |        local('CrimsonText-SemiBoldItalic'),
69 |        url(fonts/CrimsonText-SemiBoldItalic.woff2) format('woff2'),
70 |        url(fonts/CrimsonText-SemiBoldItalic.ttf) format('truetype');
71 | }
72 | */
73 | 


--------------------------------------------------------------------------------
/docs/out/assets/fonts/CrimsonText-Bold.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dmulholl/syntext/41187f7a5db9458c557d991357cb70dbfd85c18e/docs/out/assets/fonts/CrimsonText-Bold.ttf


--------------------------------------------------------------------------------
/docs/out/assets/fonts/CrimsonText-Bold.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dmulholl/syntext/41187f7a5db9458c557d991357cb70dbfd85c18e/docs/out/assets/fonts/CrimsonText-Bold.woff2


--------------------------------------------------------------------------------
/docs/out/assets/fonts/CrimsonText-BoldItalic.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dmulholl/syntext/41187f7a5db9458c557d991357cb70dbfd85c18e/docs/out/assets/fonts/CrimsonText-BoldItalic.ttf


--------------------------------------------------------------------------------
/docs/out/assets/fonts/CrimsonText-BoldItalic.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dmulholl/syntext/41187f7a5db9458c557d991357cb70dbfd85c18e/docs/out/assets/fonts/CrimsonText-BoldItalic.woff2


--------------------------------------------------------------------------------
/docs/out/assets/fonts/CrimsonText-Italic.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dmulholl/syntext/41187f7a5db9458c557d991357cb70dbfd85c18e/docs/out/assets/fonts/CrimsonText-Italic.ttf


--------------------------------------------------------------------------------
/docs/out/assets/fonts/CrimsonText-Italic.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dmulholl/syntext/41187f7a5db9458c557d991357cb70dbfd85c18e/docs/out/assets/fonts/CrimsonText-Italic.woff2


--------------------------------------------------------------------------------
/docs/out/assets/fonts/CrimsonText-Regular.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dmulholl/syntext/41187f7a5db9458c557d991357cb70dbfd85c18e/docs/out/assets/fonts/CrimsonText-Regular.ttf


--------------------------------------------------------------------------------
/docs/out/assets/fonts/CrimsonText-Regular.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dmulholl/syntext/41187f7a5db9458c557d991357cb70dbfd85c18e/docs/out/assets/fonts/CrimsonText-Regular.woff2


--------------------------------------------------------------------------------
/docs/out/assets/fonts/CrimsonText-SemiBold.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dmulholl/syntext/41187f7a5db9458c557d991357cb70dbfd85c18e/docs/out/assets/fonts/CrimsonText-SemiBold.ttf


--------------------------------------------------------------------------------
/docs/out/assets/fonts/CrimsonText-SemiBold.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dmulholl/syntext/41187f7a5db9458c557d991357cb70dbfd85c18e/docs/out/assets/fonts/CrimsonText-SemiBold.woff2


--------------------------------------------------------------------------------
/docs/out/assets/fonts/CrimsonText-SemiBoldItalic.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dmulholl/syntext/41187f7a5db9458c557d991357cb70dbfd85c18e/docs/out/assets/fonts/CrimsonText-SemiBoldItalic.ttf


--------------------------------------------------------------------------------
/docs/out/assets/fonts/CrimsonText-SemiBoldItalic.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dmulholl/syntext/41187f7a5db9458c557d991357cb70dbfd85c18e/docs/out/assets/fonts/CrimsonText-SemiBoldItalic.woff2


--------------------------------------------------------------------------------
/docs/out/assets/fonts/OFL.txt:
--------------------------------------------------------------------------------
 1 | Copyright (c) 2010, Sebastian Kosch (sebastian@aldusleaf.org),
 2 | with Reserved Font Name "Crimson" and "Crimson Text".
 3 | This Font Software is licensed under the SIL Open Font License, Version 1.1.
 4 | This license is copied below, and is also available with a FAQ at:
 5 | http://scripts.sil.org/OFL
 6 | 
 7 | 
 8 | -----------------------------------------------------------
 9 | SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
10 | -----------------------------------------------------------
11 | 
12 | PREAMBLE
13 | The goals of the Open Font License (OFL) are to stimulate worldwide
14 | development of collaborative font projects, to support the font creation
15 | efforts of academic and linguistic communities, and to provide a free and
16 | open framework in which fonts may be shared and improved in partnership
17 | with others.
18 | 
19 | The OFL allows the licensed fonts to be used, studied, modified and
20 | redistributed freely as long as they are not sold by themselves. The
21 | fonts, including any derivative works, can be bundled, embedded, 
22 | redistributed and/or sold with any software provided that any reserved
23 | names are not used by derivative works. The fonts and derivatives,
24 | however, cannot be released under any other type of license. The
25 | requirement for fonts to remain under this license does not apply
26 | to any document created using the fonts or their derivatives.
27 | 
28 | DEFINITIONS
29 | "Font Software" refers to the set of files released by the Copyright
30 | Holder(s) under this license and clearly marked as such. This may
31 | include source files, build scripts and documentation.
32 | 
33 | "Reserved Font Name" refers to any names specified as such after the
34 | copyright statement(s).
35 | 
36 | "Original Version" refers to the collection of Font Software components as
37 | distributed by the Copyright Holder(s).
38 | 
39 | "Modified Version" refers to any derivative made by adding to, deleting,
40 | or substituting -- in part or in whole -- any of the components of the
41 | Original Version, by changing formats or by porting the Font Software to a
42 | new environment.
43 | 
44 | "Author" refers to any designer, engineer, programmer, technical
45 | writer or other person who contributed to the Font Software.
46 | 
47 | PERMISSION & CONDITIONS
48 | Permission is hereby granted, free of charge, to any person obtaining
49 | a copy of the Font Software, to use, study, copy, merge, embed, modify,
50 | redistribute, and sell modified and unmodified copies of the Font
51 | Software, subject to the following conditions:
52 | 
53 | 1) Neither the Font Software nor any of its individual components,
54 | in Original or Modified Versions, may be sold by itself.
55 | 
56 | 2) Original or Modified Versions of the Font Software may be bundled,
57 | redistributed and/or sold with any software, provided that each copy
58 | contains the above copyright notice and this license. These can be
59 | included either as stand-alone text files, human-readable headers or
60 | in the appropriate machine-readable metadata fields within text or
61 | binary files as long as those fields can be easily viewed by the user.
62 | 
63 | 3) No Modified Version of the Font Software may use the Reserved Font
64 | Name(s) unless explicit written permission is granted by the corresponding
65 | Copyright Holder. This restriction only applies to the primary font name as
66 | presented to the users.
67 | 
68 | 4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
69 | Software shall not be used to promote, endorse or advertise any
70 | Modified Version, except to acknowledge the contribution(s) of the
71 | Copyright Holder(s) and the Author(s) or with their explicit written
72 | permission.
73 | 
74 | 5) The Font Software, modified or unmodified, in part or in whole,
75 | must be distributed entirely under this license, and must not be
76 | distributed under any other license. The requirement for fonts to
77 | remain under this license does not apply to any document created
78 | using the Font Software.
79 | 
80 | TERMINATION
81 | This license becomes null and void if any of the above conditions are
82 | not met.
83 | 
84 | DISCLAIMER
85 | THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
86 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
87 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
88 | OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
89 | COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
90 | INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
91 | DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
92 | FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
93 | OTHER DEALINGS IN THE FONT SOFTWARE.
94 | 


--------------------------------------------------------------------------------
/docs/out/assets/graphite.css:
--------------------------------------------------------------------------------
  1 | /**
  2 |  * -------------------------------------------------------------------------
  3 |  *  Micro Reset
  4 |  * -------------------------------------------------------------------------
  5 |  */
  6 | 
  7 | *, *:before, *:after {
  8 |     box-sizing: inherit;
  9 | }
 10 | 
 11 | html {
 12 |     box-sizing: border-box;
 13 |     font-size: 100%;
 14 |     -webkit-text-size-adjust: none;
 15 |             text-size-adjust: none;
 16 | }
 17 | 
 18 | body {
 19 |     margin: 0;
 20 |     padding: 0;
 21 | }
 22 | 
 23 | form, fieldset, legend {
 24 |     margin: 0;
 25 |     padding: 0;
 26 | }
 27 | 
 28 | button, input, select, textarea, label {
 29 |     margin: 0;
 30 |     padding: 0;
 31 |     font-family: inherit;
 32 |     font-size: inherit;
 33 | }
 34 | 
 35 | img {
 36 |     border: 0;
 37 |     max-width: 100%;
 38 | }
 39 | 
 40 | /**
 41 |  * -------------------------------------------------------------------------
 42 |  *  Typography
 43 |  * -------------------------------------------------------------------------
 44 |  */
 45 | 
 46 | body {
 47 |     font-size: 17px;
 48 |     color: black;
 49 |     font-family: 'Crimson Text', Georgia, serif;
 50 |     line-height: 1.75;
 51 | }
 52 | 
 53 | h1 {
 54 |     padding: 0;
 55 |     margin: 80px 0 30px;
 56 |     line-height: 1.25;
 57 |     text-align: center;
 58 |     font-size: 32px;
 59 |     font-weight: normal;
 60 | }
 61 | 
 62 | h2 {
 63 |     padding: 0;
 64 |     margin: 80px 0 30px;
 65 |     line-height: 1.25;
 66 |     text-align: center;
 67 |     font-size: 22px;
 68 |     font-weight: bold;
 69 | }
 70 | 
 71 | h2.underline {
 72 |     padding: 0;
 73 |     margin: 80px 0 35px;
 74 |     line-height: 1.25;
 75 |     text-align: left;
 76 |     font-size: 22px;
 77 |     font-weight: bold;
 78 |     padding-bottom: 5px;
 79 |     border-bottom: 1px solid #ccc;
 80 | }
 81 | 
 82 | h3, h4, h5, h6 {
 83 |     padding: 0;
 84 |     margin: 80px 0 30px;
 85 |     line-height: 1.25;
 86 |     text-align: left;
 87 |     font-size: 19px;
 88 |     font-weight: bold;
 89 | }
 90 | 
 91 | p {
 92 |     margin: 25px 0;
 93 |     padding: 0;
 94 |     overflow-wrap: break-word;
 95 | }
 96 | 
 97 | blockquote {
 98 |     margin: 40px 0px;
 99 |     padding: 0 20px;
100 |     border-left: 3px solid #ddd;
101 |     font-style: italic;
102 | }
103 | 
104 | .blockquote-caption {
105 |     margin: -10px 20px 40px;
106 |     text-align: right;
107 | }
108 | 
109 | abbr[title] {
110 |     border-bottom: 1px dotted;
111 |     cursor: help;
112 | }
113 | 
114 | sup, sub {
115 |     font-size: 75%;
116 |     line-height: 0;
117 |     position: relative;
118 |     vertical-align: baseline;
119 | }
120 | 
121 | sup {
122 |     bottom: 1.5ex;
123 |     padding: 0 0.5ex;
124 | }
125 | 
126 | sub {
127 |     top: .5ex;
128 | }
129 | 
130 | /**
131 |  * Code
132 |  */
133 | 
134 | pre, code {
135 |     font-size: 13px;
136 |     font-family: Courier, monospace;
137 | }
138 | 
139 | code {
140 |     margin: 0 2px;
141 |     padding: 1px 5px;
142 |     white-space: nowrap;
143 |     border: 1px solid #e8e8e8;
144 |     border-radius: 3px;
145 |     background-color: #f8f8f8;
146 | }
147 | 
148 | pre {
149 |     margin: 40px 0;
150 |     padding: 16px 20px;
151 |     border-top: 1px dotted #bbb;
152 |     border-bottom: 1px dotted #bbb;
153 |     background-color: #f8f8f8;
154 |     overflow: auto;
155 |     line-height: 1.4;
156 | }
157 | 
158 | /* Markdown renderers tend to wrap code blocks in 
 ... 
blocks. */ 159 | pre code { 160 | margin: 0; 161 | padding: 0; 162 | white-space: pre; 163 | border: none; 164 | border-radius: 0; 165 | background-color: #f8f8f8; 166 | } 167 | 168 | h1 code { 169 | font-size: 26px; 170 | } 171 | 172 | dt pre { 173 | margin: 0 2px; 174 | padding: 1px 5px; 175 | border: 1px solid #e8e8e8; 176 | border-radius: 3px; 177 | background-color: #f8f8f8; 178 | } 179 | 180 | .pre-copy-wrapper { 181 | position: relative; 182 | } 183 | 184 | .pre-copy-wrapper button { 185 | padding: 6px; 186 | background: transparent; 187 | border: none; 188 | position: absolute; 189 | top: 10px; 190 | right: 10px; 191 | opacity: 0.3; 192 | cursor: pointer; 193 | color: black; 194 | font-size: 12px; 195 | font-family: Consolas, monospace; 196 | display: none; 197 | } 198 | 199 | .pre-copy-wrapper:hover button { 200 | display: block;; 201 | } 202 | 203 | .pre-copy-wrapper button:hover { 204 | opacity: 0.6; 205 | } 206 | 207 | 208 | /** 209 | * Lists 210 | */ 211 | 212 | ul, ol { 213 | margin: 35px 0; 214 | padding: 0 0 0 20px; 215 | } 216 | 217 | ul ul, ol ol, ul ol, ol ul { 218 | margin: 10px 10px; 219 | } 220 | 221 | li { 222 | margin: 4px 0; 223 | padding: 0; 224 | } 225 | 226 | dl { 227 | margin: 40px 0; 228 | padding: 0; 229 | } 230 | 231 | dt { 232 | margin: 45px 0 25px; 233 | padding: 0; 234 | font-weight: bold; 235 | } 236 | 237 | dd { 238 | margin: 25px 0px; 239 | padding: 0 25px; 240 | border-left: 1px solid #ddd; 241 | } 242 | 243 | /** 244 | * Links 245 | */ 246 | 247 | a { 248 | color: black; 249 | text-decoration: none; 250 | padding-bottom: 2px; 251 | border-bottom: 1px solid; 252 | } 253 | 254 | sup a { 255 | border-bottom: none; 256 | } 257 | 258 | dt a { 259 | padding-bottom: 0; 260 | } 261 | 262 | 263 | /** 264 | * Miscellanea 265 | */ 266 | 267 | hr { 268 | display: block; 269 | height: 1px; 270 | border: 0; 271 | border-top: 1px solid; 272 | margin: 60px auto; 273 | padding: 0; 274 | max-width: 300px; 275 | } 276 | 277 | img { 278 | margin: 40px auto; 279 | display: block; 280 | } 281 | 282 | /** 283 | * ------------------------------------------------------------------------- 284 | * Layout 285 | * ------------------------------------------------------------------------- 286 | */ 287 | 288 | body { 289 | width: 960px; 290 | margin: 0 auto; 291 | padding: 40px 0; 292 | } 293 | 294 | .masthead { 295 | width: 360px; 296 | padding: 20px 50px; 297 | float: left; 298 | } 299 | 300 | .main { 301 | width: 600px; 302 | padding: 32px 50px 40px 50px; 303 | margin-left: 360px; 304 | border-left: 3px solid black; 305 | min-height: calc(100vh - 80px); 306 | } 307 | 308 | /** 309 | * ------------------------------------------------------------------------- 310 | * Masthead 311 | * ------------------------------------------------------------------------- 312 | */ 313 | 314 | .masthead h1 { 315 | margin-top: 0; 316 | margin-bottom: 34px; 317 | padding: 0; 318 | text-align: right; 319 | font-size: 46px; 320 | line-height: 58px; 321 | } 322 | 323 | .masthead h1 a { 324 | border-bottom: none; 325 | } 326 | 327 | .masthead .tagline { 328 | font-style: italic; 329 | text-align: right; 330 | } 331 | 332 | .masthead .version { 333 | font-style: italic; 334 | text-align: right; 335 | } 336 | 337 | .masthead .menu { 338 | margin-right: 20px; 339 | direction: rtl; 340 | } 341 | 342 | .masthead .menu a { 343 | direction: ltr; 344 | } 345 | 346 | .masthead .menu ul ul { 347 | list-style: none; 348 | margin-left: 10px; 349 | margin-right: 10px; 350 | } 351 | 352 | .masthead .menu li li::before { 353 | content: "•\00a\000a0\00a0" 354 | } 355 | 356 | #menu-check { 357 | display: none; 358 | } 359 | 360 | #menu-label { 361 | display: none; 362 | } 363 | 364 | /** 365 | * ------------------------------------------------------------------------- 366 | * Main 367 | * ------------------------------------------------------------------------- 368 | */ 369 | 370 | .main .title h1 { 371 | margin-top: 0; 372 | margin-bottom: 40px; 373 | } 374 | 375 | .main .title .subtitle { 376 | font-style: italic; 377 | text-align: center; 378 | width: 90%; 379 | margin-left: auto; 380 | margin-right: auto; 381 | } 382 | 383 | .main .title hr { 384 | margin: 50px auto 60px; 385 | } 386 | 387 | .main > :last-child { 388 | margin-bottom: 0; 389 | } 390 | 391 | /** 392 | * Info Boxes 393 | */ 394 | 395 | .infobox, .alertbox { 396 | margin: 40px 20px; 397 | border: 1px solid; 398 | padding: 0 25px; 399 | border-radius: 3px; 400 | border-color: #bbb; 401 | background-color: #f8f8f8; 402 | } 403 | 404 | .infobox.blue, .alertbox.info { 405 | border-color: #bac6d3; 406 | background-color: #e2eef9; 407 | } 408 | 409 | .infobox.yellow, .alertbox.warning { 410 | border-color: #dfd8c2; 411 | background-color: #fff9ea; 412 | } 413 | 414 | .infobox.red, .alertbox.error { 415 | border-color: #d2b2b2; 416 | background-color: #fcdede; 417 | } 418 | 419 | .infobox.green, .alertbox.success { 420 | border-color: #B2C2AB; 421 | background-color: #DEF2D6; 422 | } 423 | 424 | /** 425 | * Footnotes 426 | */ 427 | 428 | .footnote a::before { 429 | content: "["; 430 | } 431 | 432 | .footnote a::after { 433 | content: "]"; 434 | } 435 | 436 | .footnote a { 437 | border: none; 438 | } 439 | 440 | .footnotes dt { 441 | display: table-cell; 442 | width: 30px; 443 | text-align: right; 444 | font-weight: normal; 445 | } 446 | 447 | .footnotes dt a { 448 | padding: 0; 449 | border: none; 450 | } 451 | 452 | .footnotes dt a::before { 453 | content: "["; 454 | } 455 | 456 | .footnotes dt a::after { 457 | content: "]"; 458 | } 459 | 460 | .footnotes dd { 461 | display: table-cell; 462 | padding-left: 20px; 463 | padding-right: 0px; 464 | border: none 465 | } 466 | 467 | .footnotes dd :first-child { 468 | margin-top: 0; 469 | } 470 | 471 | .footnotes div:last-child dd :last-child { 472 | margin-bottom: 0; 473 | } 474 | 475 | .footnotes pre { 476 | margin: 30px 0; 477 | } 478 | 479 | /** 480 | * Tables 481 | */ 482 | 483 | table { 484 | font-size: 16px; 485 | border-collapse: collapse; 486 | border-spacing: 0; 487 | margin: 50px 0px; 488 | width: 100%; 489 | } 490 | 491 | thead, tfoot { 492 | background-color: #f8f8f8; 493 | } 494 | 495 | th, td { 496 | border: 1px solid #ccc; 497 | padding: 14px 20px; 498 | text-align: left; 499 | } 500 | 501 | /** 502 | * Utility Styles 503 | */ 504 | 505 | .small { 506 | font-size: 16px; 507 | } 508 | 509 | .left { 510 | text-align: left; 511 | } 512 | 513 | .right { 514 | text-align: right; 515 | } 516 | 517 | .center { 518 | text-align: center; 519 | } 520 | 521 | .justify { 522 | text-align: justify; 523 | } 524 | 525 | .bold { 526 | font-weight: bold; 527 | } 528 | 529 | .italic { 530 | font-style: italic; 531 | } 532 | 533 | .indent { 534 | padding-left: 30px; 535 | padding-right: 30px; 536 | } 537 | 538 | .unselectable { 539 | -webkit-user-select: none; 540 | -moz-user-select: none; 541 | -ms-user-select: none; 542 | user-select: none; 543 | } 544 | 545 | /** 546 | * Custom Classes 547 | */ 548 | 549 | body.extra-deflist-vspace dt { 550 | margin-top: 80px; 551 | } 552 | 553 | /** 554 | * ------------------------------------------------------------------------- 555 | * Media Queries 556 | * ------------------------------------------------------------------------- 557 | */ 558 | 559 | /* Tablet screens and smaller. */ 560 | 561 | @media screen and (max-width: 960px) { 562 | body { 563 | width: auto; 564 | max-width: 680px; 565 | padding-top: 60px; 566 | } 567 | 568 | .masthead { 569 | width: auto; 570 | float: none; 571 | padding: 60px 20px 60px 20px; 572 | text-align: center; 573 | margin-left: 40px; 574 | margin-right: 40px; 575 | border-top: 3px solid black; 576 | border-bottom: 3px solid black; 577 | } 578 | 579 | .main { 580 | width: auto; 581 | padding: 40px 40px; 582 | margin-left: 0; 583 | border-left: none; 584 | min-height: auto; 585 | } 586 | 587 | .masthead h1 { 588 | text-align: center; 589 | } 590 | 591 | .masthead .tagline { 592 | text-align: center; 593 | max-width: 450px; 594 | margin-left: auto; 595 | margin-right: auto; 596 | display: none; 597 | } 598 | 599 | .homepage .masthead .tagline { 600 | display: block; 601 | } 602 | 603 | .masthead .version { 604 | text-align: center; 605 | } 606 | 607 | .masthead .menu { 608 | direction: ltr; 609 | max-width: 300px; 610 | margin-left: auto; 611 | margin-right: auto; 612 | } 613 | 614 | .masthead .menu ul { 615 | text-align: left; 616 | margin: 0; 617 | padding: 0; 618 | } 619 | 620 | .masthead .menu ul ul { 621 | margin: 0; 622 | } 623 | 624 | .masthead .menu li { 625 | border-bottom: 1px solid; 626 | list-style: none; 627 | margin: 0; 628 | padding: 0; 629 | } 630 | 631 | .masthead .menu li:first-child { 632 | border-top: 1px solid; 633 | } 634 | 635 | .masthead .menu li li:last-child { 636 | border-bottom: none; 637 | } 638 | 639 | .masthead .menu a { 640 | display: block; 641 | padding: 15px 20px; 642 | border-bottom: none; 643 | } 644 | 645 | .masthead .menu li li a { 646 | padding-left: 30px; 647 | } 648 | 649 | .masthead .menu li li::before { 650 | content: none; 651 | } 652 | 653 | .masthead .menu li li a::before { 654 | content: "•\00a0\00a0\00a0"; 655 | } 656 | 657 | #menu-label { 658 | display: inline-block; 659 | padding: 0 20px; 660 | height: 50px; 661 | border: 1px solid #ddd; 662 | cursor: pointer; 663 | line-height: 50px; 664 | color: #333; 665 | font-size: 20px; 666 | margin-top: 10px; 667 | } 668 | 669 | #menu-label:hover, #menu-label:focus { 670 | border: 1px solid #888; 671 | } 672 | 673 | #menu-label .icon { 674 | padding-right: 8px; 675 | width: 30px; 676 | } 677 | 678 | #menu-check ~ label .close-icon { 679 | display: none; 680 | } 681 | 682 | #menu-check ~ label .open-icon { 683 | display: inline-block; 684 | } 685 | 686 | #menu-check:checked ~ label .close-icon { 687 | display: inline-block; 688 | } 689 | 690 | #menu-check:checked ~ label .open-icon { 691 | display: none; 692 | } 693 | 694 | #menu-check ~ ul { 695 | display: none; 696 | } 697 | 698 | #menu-check:checked ~ ul { 699 | display: block; 700 | margin-top: 50px; 701 | margin-bottom: 0; 702 | } 703 | } 704 | 705 | /* Landscape phone screens and smaller. */ 706 | 707 | @media screen and (max-width: 720px) { 708 | } 709 | 710 | /* Portrait phone screens. */ 711 | 712 | @media screen and (max-width: 480px) { 713 | body { 714 | font-size: 16px; 715 | padding-top: 40px; 716 | } 717 | 718 | h1 { 719 | font-size: 28px; 720 | } 721 | 722 | h2 { 723 | font-size: 18px; 724 | } 725 | 726 | h3, h4, h5, h6 { 727 | font-size: 16px; 728 | } 729 | 730 | h1 code { 731 | font-size: 24px; 732 | } 733 | 734 | pre, code { 735 | font-size: 12px; 736 | } 737 | 738 | .pre-copy-wrapper button { 739 | font-size: 11px; 740 | } 741 | 742 | .small { 743 | font-size: 15px; 744 | } 745 | 746 | .main .title .subtitle { 747 | width: auto; 748 | } 749 | } 750 | -------------------------------------------------------------------------------- /docs/out/assets/pygments.css: -------------------------------------------------------------------------------- 1 | /** 2 | * ------------------------------------------------------------------------- 3 | * Pygments Theme 4 | * ------------------------------------------------------------------------- 5 | */ 6 | 7 | pre .bp { color: #3465a4 } /* Name.Builtin.Pseudo */ 8 | pre .c { color: #8f5902 } /* Comment */ 9 | pre .c1 { color: #8f5902 } /* Comment.Single */ 10 | pre .cm { color: #8f5902 } /* Comment.Multiline */ 11 | pre .cp { color: #540e8a; font-weight: bold } /* Comment.Preproc */ 12 | pre .cs { color: #8f5902 } /* Comment.Special */ 13 | pre .g { color: #222222 } /* Generic */ 14 | pre .gd { color: #a40000 } /* Generic.Deleted */ 15 | pre .ge { color: #222222 } /* Generic.Emph */ 16 | pre .gr { color: #ef2929 } /* Generic.Error */ 17 | pre .gh { color: #000080; font-weight: bold } /* Generic.Heading */ 18 | pre .gi { color: #00A000 } /* Generic.Inserted */ 19 | pre .go { color: #222222 } /* Generic.Output */ 20 | pre .gp { color: #8f5902 } /* Generic.Prompt */ 21 | pre .gs { color: #222222; font-weight: bold } /* Generic.Strong */ 22 | pre .gu { color: #800080; font-weight: bold } /* Generic.Subheading */ 23 | pre .gt { color: #a40000; font-weight: bold } /* Generic.Traceback */ 24 | pre .il { color: #000088 } /* Literal.Number.Integer.Long */ 25 | pre .k { color: #204a87; font-weight: bold } /* Keyword */ 26 | pre .kc { color: #204a87; font-weight: bold } /* Keyword.Constant */ 27 | pre .kd { color: #204a87; font-weight: bold } /* Keyword.Declaration */ 28 | pre .kn { color: #540e8a; font-weight: bold } /* Keyword.Namespace */ 29 | pre .kp { color: #204a87; font-weight: bold } /* Keyword.Pseudo */ 30 | pre .kr { color: #204a87; font-weight: bold } /* Keyword.Reserved */ 31 | pre .kt { color: #204a87; font-weight: bold } /* Keyword.Type */ 32 | pre .l { color: #222222 } /* Literal */ 33 | pre .ld { color: #222222 } /* Literal.Date */ 34 | pre .m { color: #000088 } /* Literal.Number */ 35 | pre .mf { color: #000088 } /* Literal.Number.Float */ 36 | pre .mh { color: #000088 } /* Literal.Number.Hex */ 37 | pre .mi { color: #000088 } /* Literal.Number.Integer */ 38 | pre .mo { color: #000088 } /* Literal.Number.Oct */ 39 | pre .mb { color: #000088 } /* Literal.Number.Bin */ 40 | pre .n { color: #222222 } /* Name */ 41 | pre .na { color: #8f5902 } /* Name.Attribute */ 42 | pre .nb { color: #204a87 } /* Name.Builtin */ 43 | pre .nc { color: #222222 } /* Name.Class */ 44 | pre .no { color: #222222 } /* Name.Constant */ 45 | pre .nd { color: #000088 } /* Name.Decorator */ 46 | pre .ni { color: #ce5c00 } /* Name.Entity */ 47 | pre .ne { color: #cc0000; font-weight: bold } /* Name.Exception */ 48 | pre .nf { color: #222222 } /* Name.Function */ 49 | pre .nl { color: #880000 } /* Name.Label */ 50 | pre .nn { color: #222222 } /* Name.Namespace */ 51 | pre .nt { color: #204a87; font-weight: bold } /* Name.Tag */ 52 | pre .nv { color: #222222 } /* Name.Variable */ 53 | pre .nx { color: #222222 } /* Name.Other */ 54 | pre .o { color: #000088 } /* Operator */ 55 | pre .ow { color: #204a87; font-weight: bold } /* Operator.Word */ 56 | pre .p { color: #222222 } /* Punctuation */ 57 | pre .py { color: #222222 } /* Name.Property */ 58 | pre .s { color: #880000 } /* Literal.String */ 59 | pre .s1 { color: #880000 } /* Literal.String.Single */ 60 | pre .s2 { color: #880000 } /* Literal.String.Double */ 61 | pre .sb { color: #880000 } /* Literal.String.Backtick */ 62 | pre .sc { color: #880000 } /* Literal.String.Char */ 63 | pre .sd { color: #880000 } /* Literal.String.Doc */ 64 | pre .se { color: #880000 } /* Literal.String.Escape */ 65 | pre .sh { color: #880000 } /* Literal.String.Heredoc */ 66 | pre .si { color: #880000 } /* Literal.String.Interpol */ 67 | pre .sr { color: #880000 } /* Literal.String.Regex */ 68 | pre .ss { color: #880000 } /* Literal.String.Symbol */ 69 | pre .sx { color: #880000 } /* Literal.String.Other */ 70 | pre .vc { color: #222222 } /* Name.Variable.Class */ 71 | pre .vg { color: #222222 } /* Name.Variable.Global */ 72 | pre .vi { color: #222222 } /* Name.Variable.Instance */ 73 | pre .x { color: #222222 } /* Other */ 74 | 75 | pre .w { color: #f8f8f8; text-decoration: underline } /* Text.Whitespace */ 76 | pre .err { color: #a40000; border: 1px solid #ef2929 } /* Error */ 77 | -------------------------------------------------------------------------------- /docs/out/block-syntax.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Syntext — Block Syntax 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 |

Syntext

25 | 26 |

A lightweight, markdownish markup language for generating HTML.

27 | 28 | 29 |

Version 3.1.0

30 | 31 | 71 |
72 | 73 |
74 |
75 |

Block Syntax

76 | 77 |
78 |
79 | 99 |

100 | Paragraphs 101 |

102 |

103 | A paragraph is a group of adjacent lines separated by one or more blank lines: 104 |

105 |
106 | This is a paragraph. Note that it includes
107 | all adjacent lines of text.
108 | 
109 | This is a second paragraph.
110 | 
111 |

112 | Headings 113 |

114 |

115 | Headings are indicated by hash symbols. The number of hash symbols indicates the level of the heading. 116 |

117 |
118 | # H1 Heading
119 | 
120 | ## H2 Heading
121 | 
122 |

123 | Trailing symbols are optional: 124 |

125 |
126 | ### H3 Heading ###
127 | 
128 |

129 | A heading consisting entirely of dashes will be ignored. You can use this feature to create 'boxed' headings: 130 |

131 |
132 | # --------------- #
133 | #  Boxed Heading  #
134 | # --------------- #
135 | 
136 |

137 | Lists 138 |

139 |

140 | An unordered list can use an asterisk *, dash -, plus-symbol +, or unicode bullet-symbol \u2022 as its list-item marker: 141 |

142 |
143 | * foo           - foo           + foo           • foo
144 | * bar           - bar           + bar           • bar
145 | * baz           - baz           + baz           • baz
146 | 
147 |

148 | An ordered list uses either integer-period <int>. or hash-period #. as its list-item marker: 149 |

150 |
151 | 1. foo         #. foo
152 | 2. bar         #. bar
153 | 3. baz         #. baz
154 | 
155 |

156 | Ordered lists are numbered according to their opening integer: 157 |

158 |
159 | 5. This list starts.
160 | 6. With list item 5.
161 | 
162 |

163 | List-item markers can be indented by up to three spaces. A list-item consists of its opening line plus all subsequent blank or indented lines: 164 |

165 |
166 | * This list item is split
167 |   over two lines.
168 | 
169 |

170 | List items can contain nested lists: 171 |

172 |
173 | * foo
174 |   1. bar
175 |   2. baz
176 | * bam
177 | 
178 |

179 | Note that switching to a different list-item marker will begin a new list, i.e. the following markup will create two separate lists each containing a single item: 180 |

181 |
182 | - foo
183 | + bar
184 | 
185 |

186 | Block Lists 187 |

188 |

189 | Block lists use bracketed list-item markers: 190 |

191 |
192 | (*) Unordered block list item.
193 | 
194 | (#) Ordered block list item.
195 | 
196 |

197 | Each list-item in a block list is parsed as a new block-level context and can contain any number of block-level elements, including paragraphs, headings, and nested lists. 198 |

199 |
200 | (1) This list item contains a paragraph
201 |     and a compact list.
202 | 
203 |     1. foo
204 |     2. bar
205 | 
206 | (2) This list item contains two paragraphs.
207 |     This is the first.
208 | 
209 |     And this is the second.
210 | 
211 |

212 | A list-item consists of its opening line plus all subsequent blank or indented lines. 213 |

214 |

215 | Definition Lists 216 |

217 |

218 | Syntext supports definition lists with terms enclosed in double braces: 219 |

220 |
221 | [[  Term 1  ]]
222 | 
223 |     This is the definition of the first term.
224 | 
225 | [[  Term 2  ]]
226 | 
227 |     This is the definition of the second term.
228 | 
229 |

230 | A term's definition consists of all subsequent blank or indented lines and can contain any number of block-level elements. 231 |

232 |

233 | Code Blocks 234 |

235 |

236 | A block of text indented by one tab or four spaces is treated as a code block and wrapped in <pre> tags in the HTML output. The code block can contain blank lines and is ended by the first non-indented line. 237 |

238 |
239 | This paragraph is followed by a code block.
240 | 
241 |     <p>Hello world!</p>
242 | 
243 |

244 | HTML in code blocks is automatically escaped. To specify the language, use an explicit code tag. 245 |

246 |
247 | 248 | 249 | 250 | 251 | -------------------------------------------------------------------------------- /docs/out/changelog.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Syntext — Changelog 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 |

Syntext

25 | 26 |

A lightweight, markdownish markup language for generating HTML.

27 | 28 | 29 |

Version 3.1.0

30 | 31 | 71 |
72 | 73 |
74 |
75 |

Changelog

76 | 77 |
78 |
79 |

80 | 3.1.0 81 |

82 | 87 |

88 | 3.0.0 89 |

90 | 98 |

99 | 2.10.0 100 |

101 | 106 |

107 | 2.9.0 108 |

109 | 114 |

115 | 2.8.0 116 |

117 | 122 |

123 | 2.7.0 124 |

125 | 130 |

131 | 2.6.0 132 |

133 | 141 |

142 | 2.5.0 143 |

144 | 167 |

168 | 2.4.0 169 |

170 | 184 |

185 | 2.3.0 186 |

187 | 195 |

196 | 2.2.0 197 |

198 | 206 |

207 | 2.1.0 208 |

209 | 214 |

215 | 2.0.0 216 |

217 | 222 |

223 | 1.4.0 224 |

225 | 230 |

231 | 1.2.0 232 |

233 | 238 |

239 | 1.1.0 240 |

241 | 246 |

247 | 1.0.0 248 |

249 | 254 |
255 | 256 | 257 | 258 | 259 | -------------------------------------------------------------------------------- /docs/out/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Syntext — a markdownish markup language 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 |

Syntext

25 | 26 |

A lightweight, markdownish markup language for generating HTML.

27 | 28 | 29 |

Version 3.1.0

30 | 31 | 71 |
72 | 73 |
74 |
75 |

Home

76 | 77 |
78 |
79 |

80 | Syntext is a lightweight, markdownish markup language for generating HTML. It's implemented in Python and can be used as both a command line utility and a Python library. 81 |

82 |

83 | When used on the command line Syntext reads from stdin and prints to stdout: 84 |

85 |
 86 | $ syntext < input.txt > output.html
 87 | 
88 |

89 | To use Syntext as a Python library call its render() function with a string of input: 90 |

91 |
 92 | >>> import syntext
 93 | >>> html = syntext.render(text)
 94 | 
95 |

96 | Overview 97 |

98 |

99 | Syntext shares much of its basic syntax with Markdown: 100 |

101 |
102 | This paragraph contains *italic* and **bold** text.
103 | It also contains a `code sample` in backticks.
104 | 
105 | This paragraph contains a [link](http://example.com).
106 | 
107 |

108 | Syntext differs from Markdown in supporting an indentation-based shorthand syntax for generating arbitrary HTML: 109 |

110 |
111 | :div .outer
112 |     :div .inner
113 |         This is a paragraph.
114 | 
115 |

116 | Syntext also includes out-of-the-box support for tables, tables-of-contents, definition lists, syntax highlighting, and footnotes. 117 |

118 |

119 | Installation 120 |

121 |

122 | Install directly from the Python Package Index using pip: 123 |

124 |
125 | $ pip install syntext
126 | 
127 |

128 | Syntext requires Python 3.6 or later. 129 |

130 |

131 | Command Line Interface 132 |

133 |

134 | Use the syntext --help flag to view the utility's command line help: 135 |

136 |
137 | Usage: syntext [FLAGS]
138 | 
139 |   Renders input text in Syntext format into HTML. Reads
140 |   from stdin and prints to stdout.
141 | 
142 |   Example:
143 | 
144 |       $ syntext < input.txt > output.html
145 | 
146 | Flags:
147 |   -d, --debug       Run in debug mode.
148 |   -h, --help        Print the application's help text.
149 |   -p, --pygmentize  Add syntax highlighting to code.
150 |   -v, --version     Print the application's version.
151 | 
152 |

153 | Syntext can use the Pygments package to add syntax highlighting to code blocks; this feature can be enabled via the --pygmentize flag. (Pygments is installed automatically when you install Syntext using pip). 154 |

155 |

156 | Only code blocks with a language attribute will have syntax highlighting applied. 157 |

158 | 161 | 169 |

170 | License 171 |

172 |

173 | Zero-Clause BSD (0BSD). 174 |

175 |
176 | 177 | 178 | 179 | 180 | -------------------------------------------------------------------------------- /docs/out/inline-syntax.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Syntext — Inline Syntax 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 |

Syntext

25 | 26 |

A lightweight, markdownish markup language for generating HTML.

27 | 28 | 29 |

Version 3.1.0

30 | 31 | 71 |
72 | 73 |
74 |
75 |

Inline Syntax

76 | 77 |
78 |
79 | 99 |

100 | Formatting 101 |

102 |

103 | Single asterisks indicate italic text, double asterisks indicate bold text, triple asterisks indicate bold italic text: 104 |

105 |
106 | This text is *italic*.
107 | This text is **bold**.
108 | This text is ***bold and italic***.
109 | 
110 |

111 | Backticks are used to enclose code samples: 112 |

113 |
114 | This is a `code sample`.
115 | 
116 |

117 | HTML in code samples is automatically escaped. 118 |

119 | 122 |

123 | Link syntax is borrowed directly from Markdown: 124 |

125 |
126 | [link text](http://example.com)
127 | 
128 |

129 | Syntext also supports Markdown-style reference links: 130 |

131 |
132 | [link text][ref]
133 | 
134 |

135 | Link references can be specified anywhere in the document: 136 |

137 |
138 | [ref]: http://example.com
139 | 
140 |

141 | If the reference text is omitted from the link, the link text will be used instead when searching for link references. 142 |

143 |

144 | Images 145 |

146 |

147 | Image syntax is borrowed directly from Markdown: 148 |

149 |
150 | ![alt text](http://example.com/image.jpg)
151 | 
152 |

153 | Syntext also supports Markdown-style reference images: 154 |

155 |
156 | ![alt text][ref]
157 | 
158 |

159 | Image references can be specified anywhere in the document. Their form is identical to that of link references. If the reference text is omitted from the image, the alt text will be used instead when searching for references. 160 |

161 |

162 | Dashes 163 |

164 |

165 | Double hyphens -- are converted into en-dashes, &ndash;; triple hyphens --- are converted into em-dashes, &mdash;. 166 |

167 |

168 | Superscripts & Subscripts 169 |

170 |

171 | Superscripts are indicated using a caret: 172 |

173 |
174 | X^{2}
175 | 
176 |

177 | Subscripts are indicated using an underscore: 178 |

179 |
180 | H_{2}O
181 | 
182 |

183 | Text to be super or subscripted should be wrapped in curly braces. 184 |

185 |

186 | Verbatim Quotes 187 |

188 |

189 | Double backticks create a verbatim environment: 190 |

191 |
192 | ``verbatim``
193 | 
194 |

195 | The content of a verbatim environment is passed through in its raw state without any further processing. 196 |

197 |

198 | This can be useful for escaping elements that would otherwise be parsed as formatting instructions by Syntext, e.g. inline LaTeX markup: 199 |

200 |
201 | ``\( x^{2} + y^{2} = z^{2} \)``
202 | 
203 |
204 | 205 | 206 | 207 | 208 | -------------------------------------------------------------------------------- /docs/out/license.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Syntext — License 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 |

Syntext

25 | 26 |

A lightweight, markdownish markup language for generating HTML.

27 | 28 | 29 |

Version 3.1.0

30 | 31 | 71 |
72 | 73 |
74 |
75 |

License

76 | 77 |
78 |
79 |

80 | This library is released under the Zero-Clause BSD licence (0BSD): 81 |

82 |
 83 | Permission to use, copy, modify, and/or distribute this
 84 | software for any purpose with or without fee is hereby
 85 | granted.
 86 | 
 87 | THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS
 88 | ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
 89 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO
 90 | EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
 91 | INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 92 | WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
 93 | WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
 94 | TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE
 95 | USE OR PERFORMANCE OF THIS SOFTWARE.
 96 | 
97 |

98 | Reference: https://opensource.org/licenses/0BSD. 99 |

100 |
101 | 102 | 103 | 104 | 105 | -------------------------------------------------------------------------------- /docs/out/miscellanea.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Syntext — Miscellanea 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 |

Syntext

25 | 26 |

A lightweight, markdownish markup language for generating HTML.

27 | 28 | 29 |

Version 3.1.0

30 | 31 | 71 |
72 | 73 |
74 |
75 |

Miscellanea

76 | 77 |
78 |
79 | 96 |

97 | Tables of Contents 98 |

99 |

100 | Syntext can automatically generate a table of contents for a document. This table can be inserted using the insert tag: 101 |

102 |
103 | ::: insert toc
104 | 
105 |

106 | The default listing skips H1 headings to avoid including the document title itself. A full listing of all the document's headings can be inserted using the fulltoc keyword: 107 |

108 |
109 | ::: insert fulltoc
110 | 
111 |

112 | The table of contents is generated as an unordered list of links. 113 |

114 |

115 | Footnotes 116 |

117 |

118 | Syntext includes built-in support for footnotes: 119 |

120 |
121 | This sentence ends with a footnote reference.[^1]
122 | 
123 |

124 | Footnote references can omit their index to take advantage of automatic numbering: 125 |

126 |
127 | This sentence ends with an automatically-numbered
128 | reference.[^]
129 | 
130 |

131 | Footnotes themselves can be specified anywhere in the document using the footnote tag: 132 |

133 |
134 | ::: footnote 1
135 |     This is a footnote. It can contain any kind of
136 |     block-level markup.
137 | 
138 |

139 | Footnotes can also omit their index to take advantage of automatic numbering: 140 |

141 |
142 | ::: footnote
143 |     This is an automatically-numbered footnote.
144 | 
145 |

146 | Note that footnote indices do not have to be numeric — any sequence of non-whitespace characters can be used. 147 |

148 |

149 | You can specify the insertion point for your footnotes using the insert tag: 150 |

151 |
152 | ::: insert footnotes
153 | 
154 |

155 | Footnote references are wrapped in the following markup: 156 |

157 |
158 | <sup class="footnote" id="fnref:1">
159 |     <a href="#fn:1">1</a>
160 | </sup>
161 | 
162 |

163 | Footnotes are output as items in a description list: 164 |

165 |
166 | <dl class="footnotes">
167 |     <div id="fn:1">
168 |         <dt><a href="#fnref:1">1</a></dt>
169 |         <dd> ... </dd>
170 |     </div>
171 |     ...
172 | </dl>
173 | 
174 |

175 | Each footnote index is backlinked to its reference in the document. 176 |

177 |

178 | Alternate Footnote Styles 179 |

180 |

181 | Syntext supports two alternate styles for footnote references: superscripted1 and inline 2. 182 |

183 |

184 | Superscripted references look like this [^1] while inline references look like this [fn:2]. The only difference in markup is that superscripted references are wrapped in a <sup> tag while inline references are wrapped in a <span>. 185 |

186 |

187 | Tab Translation Size 188 |

189 |

190 | Tab characters in input text are translated into spaces — by default, 4 spaces per tab. This value can be customized via the tabsize argument: 191 |

192 |
193 | html = syntext.render(text, tabsize=8)
194 | 
195 |

196 | This argument is also available on the command line: 197 |

198 |
199 | $ syntext --tabsize 8 < input.txt > output.html
200 | 
201 |

202 | Notes 203 |

204 |
205 |
206 |
207 | 208 | 1 209 | 210 |
211 |
212 |

213 | This is a sample footnote. Footnotes can contain any kind of block-level markup including multiple paragraphs. 214 |

215 |
216 |
217 |
218 |
219 | 220 | 2 221 | 222 |
223 |
224 |

225 | And this is another sample footnote. 226 |

227 |
228 |
229 |
230 |
231 | 232 | 233 | 234 | 235 | -------------------------------------------------------------------------------- /docs/out/raw-html.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Syntext — Raw HTML 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 |

Syntext

25 | 26 |

A lightweight, markdownish markup language for generating HTML.

27 | 28 | 29 |

Version 3.1.0

30 | 31 | 71 |
72 | 73 |
74 |
75 |

Raw HTML

76 | 77 |
78 |
79 |

80 | Block HTML 81 |

82 |

83 | Syntext can recognise and ignore block-level HTML in its input so you can freely mix and match Syntext markup and raw HTML. 84 |

85 |
 86 | :div .outer
 87 |     This is a paragraph.
 88 | 
 89 |     <div class="inner">
 90 |         <p>This is raw HTML.</p>
 91 |     </div>
 92 | 
 93 |     This is another paragraph.
 94 | 
95 |

96 | Syntext treats the content of block-level HTML tags as raw text and passes it through without any further processing. 97 |

98 |

99 | Inline HTML 100 |

101 |

102 | Syntext ignores inline HTML tags so it's fine to mix and match inline HTML and Syntext markup. 103 |

104 |

105 | The HTML syntax characters <, >, and & are automatically escaped unless they form part of a HTML tag or character entity. 106 |

107 |
108 | 109 | 110 | 111 | 112 | -------------------------------------------------------------------------------- /docs/out/shorthand-html.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Syntext — Shorthand HTML 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 |

Syntext

25 | 26 |

A lightweight, markdownish markup language for generating HTML.

27 | 28 | 29 |

Version 3.1.0

30 | 31 | 71 |
72 | 73 |
74 |
75 |

Shorthand HTML

76 | 77 |
78 |
79 | 93 |
94 |

95 | Syntext supports an indentation-based shorthand syntax for generating arbitrary HTML: 96 |

97 |
 98 | :tag [arguments] [.class] [#id] [&attr] [attr="value"]
 99 |     block content
100 |     ...
101 | 
102 |

103 | A shorthand block opens with a header line containing a colon, a HTML tag, and, optionally, a set of attributes. The block's content consists of all subsequent blank or indented lines following the header. 104 |

105 |

106 | The block's content can be indented by any number of spaces; the common indent is stripped and the first non-indented line ends the block. Leading and trailing blank lines are also trimmed from the content. 107 |

108 |

109 | To take a simple example, the markup below: 110 |

111 |
112 | :div
113 |     This is a paragraph.
114 | 
115 |

116 | generates the following HTML: 117 |

118 |
119 | <div>
120 |     <p>This is a paragraph.</p>
121 | </div>
122 | 
123 |

124 | Header Meta 125 |

126 |

127 | A block header can contain a single ID, any number of classes, and any number of named attributes, e.g: 128 |

129 |
130 | :div .foo .bar #baz
131 |     This is a paragraph.
132 | 
133 |

134 | generates the following HTML: 135 |

136 |
137 | <div class="foo bar" id="baz">
138 |     <p>This is a paragraph.</p>
139 | </div>
140 | 
141 |

142 | Boolean attributes can be specified using an & symbol, e.g. &checked. Attributes with values can be specified without quotes as long as the value does not contain spaces, e.g. 143 |

144 |
145 | :div attr1=foo attr2="bar baz"
146 | 
147 |

148 | Nesting 149 |

150 |

151 | Blocks can be nested to any depth, e.g: 152 |

153 |
154 | :div .outer
155 |     :div .inner
156 |         This is a paragraph.
157 | 
158 |

159 | will generate the following HTML: 160 |

161 |
162 | <div class="outer">
163 |     <div class="inner">
164 |         <p>This is a paragraph.</p>
165 |     </div>
166 | </div>
167 | 
168 |

169 | Linebreak Mode 170 |

171 |

172 | A nl2lb argument can be added to any block to turn on newline-to-linebreak mode for all nested content: 173 |

174 |
175 | :div nl2lb
176 |     Linebreaks in this paragraph
177 |     will be preserved.
178 | 
179 |

180 | This argument has an alias, nl2br, which is exactly equivalent. 181 |

182 |

183 | Raw Mode 184 |

185 |

186 | You can add a raw argument to any block. This instructs Syntext to preserve the block's content as-is without any further processing. 187 |

188 |
189 | :div raw
190 |     This content will be preserved in its raw state.
191 | 
192 |
193 | 194 | 195 | 196 | 197 | -------------------------------------------------------------------------------- /docs/out/tagged-blocks.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Syntext — Tagged Blocks 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 |

Syntext

25 | 26 |

A lightweight, markdownish markup language for generating HTML.

27 | 28 | 29 |

Version 3.1.0

30 | 31 | 71 |
72 | 73 |
74 |
75 |

Tagged Blocks

76 | 77 |
78 |
79 |

80 | Syntext supports an indentation-based tagged-block syntax for custom elements: 81 |

82 |
 83 | ::: tag [arguments] [.class] [#id] [&attr] [attr="value"]
 84 |     block content
 85 |     ...
 86 | 
87 |

88 | A block header can contain a single ID, any number of classes, and any number of named attributes. Block syntax also allows for one or more arguments to be supplied (how these are interpreted depends on the tag). 89 |

90 |

91 | Boolean attributes can be specified using an & symbol, e.g. &checked. Attributes with values can be specified without quotes as long as the value does not contain spaces. 92 |

93 |

94 | A block's tag determines how its content is processed. In general blocks can be nested to any depth and can contain any block-level content. 95 |

96 |

97 | Although a block's content is determined solely by its indentation an optional end marker can be added to support syntax highlighting in editors which struggle with indentation-based syntax: 98 |

99 |
100 | ::: tag
101 |     block content
102 |     ...
103 | ::: end
104 | 
105 |

106 | Trailing colons in the header line are optional: 107 |

108 |
109 | ::: hr :::
110 | 
111 |

112 | is equivalent to: 113 |

114 |
115 | ::: hr
116 | 
117 |

118 | A nl2lb / nl2br argument can be added to any block to turn on newline-to-linebreak mode for all nested content. 119 |

120 |

121 | Tag Reference 122 |

123 |

124 | •   code 125 |

126 |
127 | ::: code python
128 |     def hello():
129 |         print('hello world')
130 | 
131 |

132 | Wraps a code sample in <pre> tags. Automatically escapes the HTML syntax characters <, >, and &. 133 |

134 |

135 | This tag accepts an optional argument specifying the language of the code. If a language is specified then a lang-<language> class and a data-lang="<language>" attribute are added to the <pre> element. 136 |

137 |

138 | If a language is specified and the Pygments package is installed then syntax highlighting can be applied to the code sample. This feature is turned off by default but can be enabled by supplying a pygmentize=True keyword argument to the render() function: 139 |

140 |
141 | >>> html = syntext.render(text, pygmentize=True)
142 | 
143 |

144 | •   comment 145 |

146 |
147 | ::: comment
148 |     This is a comment.
149 | 
150 |

151 | Creates a HTML comment. The block's content is not processed any further but is included in the output in its raw state. 152 |

153 |

154 | •   hr 155 |

156 |
157 | ::: hr :::
158 | 
159 |

160 | Inserts a horizontal rule. Any number of dashes can be used in place of the hr tag, e.g. 161 |

162 |
163 | ::: ------ :::
164 | 
165 |

166 | •   image, !image 167 |

168 |
169 | ::: image http://example.com/image.jpg
170 |     [Optional alt text.]
171 |     Optional image caption.
172 | 
173 |

174 | Inserts an <img> element. The first argument is used as the source url. 175 |

176 | 187 |

188 | Classes, attributes, etc. are attached to the outermost element. 189 |

190 |

191 | •   infobox 192 |

193 |
194 | ::: infobox .warning
195 |     Careful now!
196 | 
197 |

198 | Creates an info box — a <div> element with the class infobox which can be styled appropriately using CSS. 199 |

200 | 203 |
204 | ::: link http://example.com/
205 |     Link text or any other inline content.
206 | 
207 |

208 | Inserts a link. The first argument is used as the url. 209 |

210 |

211 | •   quote 212 |

213 |
214 | ::: quote "Oscar Wilde"
215 |     Work is the curse of the drinking classes.
216 | 
217 |

218 | Inserts a <blockquote> element. If a caption argument is provided it will follow the blockquote element wrapped in a <p> element with the class .blockquote-caption. 219 |

220 |

221 | •   raw 222 |

223 |
224 | ::: raw
225 |     This content will be passed through in its raw state.
226 | 
227 |

228 | Content inside a raw tag will be passed through in its raw state without any further processing. 229 |

230 |

231 | •   table 232 |

233 |

234 | Indicates that the block contains a table: 235 |

236 |
237 | ::: table
238 | 
239 |     foo | bar | baz
240 |     ---------------
241 |     aaa | bbb | ccc
242 |     ddd | eee | fff
243 |     ---------------
244 |     foo | bar | baz
245 | 
246 |

247 | Header and footer lines are optional. All three tables below are valid: 248 |

249 |
250 | foo | bar | baz
251 | ---------------
252 | aaa | bbb | ccc      aaa | bbb | ccc      aaa | bbb | ccc
253 | ddd | eee | fff      ddd | eee | fff      ddd | eee | fff
254 |                      ---------------
255 |                      foo | bar | baz
256 | 
257 |

258 | Note that all the tables above can be 'boxed' with decorative outer lines of pipes and dashes, e.g.: 259 |

260 |
261 | ---------------      -------------------
262 | foo | bar | baz      | foo | bar | baz |
263 | ---------------      -------------------
264 | aaa | bbb | ccc      | aaa | bbb | ccc |
265 | ddd | eee | fff      | ddd | eee | fff |
266 | ---------------      -------------------
267 | 
268 |

269 | Column alignment can be specified using colons as below: 270 |

271 |
272 | default | left | center | right
273 | ------- | :--- | :----: | ----:
274 |  aaaaa  |  bb  |  cccc  |  ddd
275 |  eeeee  |  ff  |  gggg  |  hhh
276 | 
277 |

278 | Cells in the left column above receive the class left, cells in the center column receive the class center, and cells in the right column receive the class right. 279 |

280 |

281 | Attributes specified in the block header will be applied to the <table> element. 282 |

283 |

284 | Note that you can't use the | symbol inside table literals — use the HTML escape code &#124; instead. 285 |

286 |
287 | 288 | 289 | 290 | 291 | -------------------------------------------------------------------------------- /docs/src/block-syntax.stx: -------------------------------------------------------------------------------- 1 | --- 2 | title: Block Syntax 3 | meta_title: Syntext — Block Syntax 4 | --- 5 | 6 | ::: insert toc ::: 7 | 8 | 9 | 10 | ### Paragraphs 11 | 12 | A paragraph is a group of adjacent lines separated by one or more blank lines: 13 | 14 | This is a paragraph. Note that it includes 15 | all adjacent lines of text. 16 | 17 | This is a second paragraph. 18 | 19 | 20 | 21 | ### Headings 22 | 23 | Headings are indicated by hash symbols. The number of hash symbols indicates the level of the heading. 24 | 25 | # H1 Heading 26 | 27 | ## H2 Heading 28 | 29 | Trailing symbols are optional: 30 | 31 | ### H3 Heading ### 32 | 33 | A heading consisting entirely of dashes will be ignored. You can use this feature to create 'boxed' headings: 34 | 35 | # --------------- # 36 | # Boxed Heading # 37 | # --------------- # 38 | 39 | 40 | 41 | ### Lists 42 | 43 | An unordered list can use an asterisk `*`, dash `-`, plus-symbol `+`, or unicode bullet-symbol `\u2022` as its list-item marker: 44 | 45 | * foo - foo + foo • foo 46 | * bar - bar + bar • bar 47 | * baz - baz + baz • baz 48 | 49 | An ordered list uses either integer-period `.` or hash-period `#.` as its list-item marker: 50 | 51 | 1. foo #. foo 52 | 2. bar #. bar 53 | 3. baz #. baz 54 | 55 | Ordered lists are numbered according to their opening integer: 56 | 57 | 5. This list starts. 58 | 6. With list item 5. 59 | 60 | List-item markers can be indented by up to three spaces. A list-item consists of its opening line plus all subsequent blank or indented lines: 61 | 62 | * This list item is split 63 | over two lines. 64 | 65 | List items can contain nested lists: 66 | 67 | * foo 68 | 1. bar 69 | 2. baz 70 | * bam 71 | 72 | Note that switching to a different list-item marker will begin a new list, i.e. the following markup will create two separate lists each containing a single item: 73 | 74 | - foo 75 | + bar 76 | 77 | 78 | 79 | ### Block Lists 80 | 81 | Block lists use bracketed list-item markers: 82 | 83 | (*) Unordered block list item. 84 | 85 | (#) Ordered block list item. 86 | 87 | Each list-item in a block list is parsed as a new block-level context and can contain any number of block-level elements, including paragraphs, headings, and nested lists. 88 | 89 | (1) This list item contains a paragraph 90 | and a compact list. 91 | 92 | 1. foo 93 | 2. bar 94 | 95 | (2) This list item contains two paragraphs. 96 | This is the first. 97 | 98 | And this is the second. 99 | 100 | A list-item consists of its opening line plus all subsequent blank or indented lines. 101 | 102 | 103 | 104 | ### Definition Lists 105 | 106 | Syntext supports definition lists with terms enclosed in double braces: 107 | 108 | [[ Term 1 ]] 109 | 110 | This is the definition of the first term. 111 | 112 | [[ Term 2 ]] 113 | 114 | This is the definition of the second term. 115 | 116 | A term's definition consists of all subsequent blank or indented lines and can contain any number of block-level elements. 117 | 118 | 119 | 120 | ### Code Blocks 121 | 122 | A block of text indented by one tab or four spaces is treated as a code block and wrapped in `
` tags in the HTML output. The code block can contain blank lines and is ended by the first non-indented line.
123 | 
124 |     This paragraph is followed by a code block.
125 | 
126 |         

Hello world!

127 | 128 | HTML in code blocks is automatically escaped. To specify the language, use an explicit [code tag](@root/tagged-blocks//#code). 129 | 130 | 131 | 132 | -------------------------------------------------------------------------------- /docs/src/changelog.stx: -------------------------------------------------------------------------------- 1 | --- 2 | title: Changelog 3 | meta_title: Syntext — Changelog 4 | --- 5 | 6 | ### 3.1.0 7 | 8 | * Add support for a `raw` argument to all shorthand HTML tags. 9 | 10 | 11 | 12 | ### 3.0.0 13 | 14 | * This release removes support for backslashed character escapes. This feature was overly aggressive and could lead to unexpected and unintuitive changes in content. Use ``verbatim`` quotes or HTML instead to stop Syntext parsing characters as formatting instructions --- Syntext ignores inline HTML tags and all content inside block-level HTML. Consider using HTML escape codes for particularly problematic characters, e.g. `|` for the `|` symbol inside tables. 15 | 16 | * Add support for a `::: raw` tag that passes its content through without any further processing. 17 | 18 | 19 | 20 | ### 2.10.0 21 | 22 | * A missing block-level closing HTML tag now raises a `SyntextError` exception. 23 | 24 | 25 | 26 | ### 2.9.0 27 | 28 | * Add support for boxed headings. 29 | 30 | 31 | 32 | ### 2.8.0 33 | 34 | * The parser for recognising and ignoring block-level HTML in the input has been upgraded. 35 | 36 | 37 | 38 | ### 2.7.0 39 | 40 | * Inline bold, italic, code, and verbatim delimiters can now be split over multiple lines. 41 | 42 | 43 | 44 | ### 2.6.0 45 | 46 | * Add support for linked images, image alt text, and image captions. 47 | 48 | * Add documentation for inline footnote references. 49 | 50 | 51 | 52 | ### 2.5.0 53 | 54 | * Add support for blockquote captions. 55 | 56 | * Add `::: link`, `::: div`, and `::: span` tags. 57 | 58 | * Remove deprecated support for inline link and image titles. 59 | 60 | * Deprecate support for reference link titles. 61 | 62 | * Add `::$` as an alias for `::: end`. 63 | 64 | * Add `:$` as an alias for `:end`. 65 | 66 | * Make the tab translation size customizable. 67 | 68 | 69 | 70 | ### 2.4.0 71 | 72 | * Prune the list of escapable characters. 73 | 74 | * Add support for inline verbatim environments. 75 | 76 | * Fix bug recognising raw block-level HTML with attributes. 77 | 78 | * Fix bold/italic bug for consecutive single character blocks. 79 | 80 | 81 | 82 | ### 2.3.0 83 | 84 | * Add support for inline footnote references. 85 | 86 | * Add `infobox` tag. 87 | 88 | 89 | 90 | ### 2.2.0 91 | 92 | * Revised markup for footnotes and footnote references. 93 | 94 | * Add wrapper divs to definition list items. 95 | 96 | 97 | 98 | ### 2.1.0 99 | 100 | * Use `` and `` tags for bold and italic text instead of `` and ``. 101 | 102 | 103 | 104 | ### 2.0.0 105 | 106 | * Full revision incorporating multiple breaking changes. See the V2 documentation for details. 107 | 108 | 109 | 110 | ### 1.4.0 111 | 112 | * Rename the package to Syntext. 113 | 114 | 115 | 116 | ### 1.2.0 117 | 118 | * New custom syntax for definition lists. Support for the older syntax is deprecated. 119 | 120 | 121 | 122 | ### 1.1.0 123 | 124 | * Code blocks and backticks now escape quotes. 125 | 126 | 127 | 128 | ### 1.0.0 129 | 130 | * First stable release. 131 | -------------------------------------------------------------------------------- /docs/src/index.stx: -------------------------------------------------------------------------------- 1 | --- 2 | title: Home 3 | meta title: Syntext — a markdownish markup language 4 | --- 5 | 6 | Syntext is a lightweight, markdownish markup language for generating HTML. It's implemented in Python and can be used as both a command line utility and a Python library. 7 | 8 | When used on the command line Syntext reads from `stdin` and prints to `stdout`: 9 | 10 | $ syntext < input.txt > output.html 11 | 12 | To use Syntext as a Python library call its `render()` function with a string of input: 13 | 14 | ::: code python 15 | 16 | >>> import syntext 17 | >>> html = syntext.render(text) 18 | 19 | 20 | 21 | ### Overview 22 | 23 | Syntext shares much of its basic syntax with Markdown: 24 | 25 | This paragraph contains *italic* and **bold** text. 26 | It also contains a `code sample` in backticks. 27 | 28 | This paragraph contains a [link](http://example.com). 29 | 30 | Syntext differs from Markdown in supporting an indentation-based shorthand syntax for generating arbitrary HTML: 31 | 32 | :div .outer 33 | :div .inner 34 | This is a paragraph. 35 | 36 | Syntext also includes out-of-the-box support for tables, tables-of-contents, definition lists, syntax highlighting, and footnotes. 37 | 38 | 39 | 40 | ### Installation 41 | 42 | Install directly from the Python Package Index using `pip`: 43 | 44 | $ pip install syntext 45 | 46 | Syntext requires Python 3.6 or later. 47 | 48 | 49 | 50 | ### Command Line Interface 51 | 52 | Use the `syntext --help` flag to view the utility's command line help: 53 | 54 | Usage: syntext [FLAGS] 55 | 56 | Renders input text in Syntext format into HTML. Reads 57 | from stdin and prints to stdout. 58 | 59 | Example: 60 | 61 | $ syntext < input.txt > output.html 62 | 63 | Flags: 64 | -d, --debug Run in debug mode. 65 | -h, --help Print the application's help text. 66 | -p, --pygmentize Add syntax highlighting to code. 67 | -v, --version Print the application's version. 68 | 69 | Syntext can use the [Pygments][] package to add syntax highlighting to code blocks; this feature can be enabled via the `--pygmentize` flag. (Pygments is installed automatically when you install Syntext using `pip`). 70 | 71 | Only code blocks with a language attribute will have syntax highlighting applied. 72 | 73 | [pygments]: http://pygments.org/ 74 | 75 | 76 | 77 | ### Links 78 | 79 | * [Github Homepage](https://github.com/dmulholl/syntext) 80 | * [Python Package Index](https://pypi.python.org/pypi/syntext/) 81 | 82 | 83 | 84 | ### License 85 | 86 | Zero-Clause BSD (0BSD). 87 | -------------------------------------------------------------------------------- /docs/src/inline-syntax.stx: -------------------------------------------------------------------------------- 1 | --- 2 | title: Inline Syntax 3 | meta_title: Syntext — Inline Syntax 4 | --- 5 | 6 | ::: insert toc ::: 7 | 8 | 9 | 10 | ### Formatting 11 | 12 | Single asterisks indicate italic text, double asterisks indicate bold text, triple asterisks indicate bold italic text: 13 | 14 | This text is *italic*. 15 | This text is **bold**. 16 | This text is ***bold and italic***. 17 | 18 | Backticks are used to enclose code samples: 19 | 20 | This is a `code sample`. 21 | 22 | HTML in code samples is automatically escaped. 23 | 24 | 25 | 26 | ### Links 27 | 28 | Link syntax is borrowed directly from Markdown: 29 | 30 | [link text](http://example.com) 31 | 32 | Syntext also supports Markdown-style reference links: 33 | 34 | [link text][ref] 35 | 36 | Link references can be specified anywhere in the document: 37 | 38 | [ref]: http://example.com 39 | 40 | If the reference text is omitted from the link, the link text will be used instead when searching for link references. 41 | 42 | 43 | 44 | ### Images 45 | 46 | Image syntax is borrowed directly from Markdown: 47 | 48 | ![alt text](http://example.com/image.jpg) 49 | 50 | Syntext also supports Markdown-style reference images: 51 | 52 | ![alt text][ref] 53 | 54 | Image references can be specified anywhere in the document. Their form is identical to that of link references. If the reference text is omitted from the image, the alt text will be used instead when searching for references. 55 | 56 | 57 | 58 | ### Dashes 59 | 60 | Double hyphens `--` are converted into en-dashes, `–`; triple hyphens `---` are converted into em-dashes, `—`. 61 | 62 | 63 | 64 | ### Superscripts & Subscripts 65 | 66 | Superscripts are indicated using a caret: 67 | 68 | X^{2} 69 | 70 | Subscripts are indicated using an underscore: 71 | 72 | H_{2}O 73 | 74 | Text to be super or subscripted should be wrapped in curly braces. 75 | 76 | 77 | 78 | ### Verbatim Quotes 79 | 80 | Double backticks create a verbatim environment: 81 | 82 | ``verbatim`` 83 | 84 | The content of a verbatim environment is passed through in its raw state without any further processing. 85 | 86 | This can be useful for escaping elements that would otherwise be parsed as formatting instructions by Syntext, e.g. inline LaTeX markup: 87 | 88 | ``\( x^{2} + y^{2} = z^{2} \)`` 89 | -------------------------------------------------------------------------------- /docs/src/license.stx: -------------------------------------------------------------------------------- 1 | --- 2 | title: License 3 | meta_title: Syntext — License 4 | --- 5 | 6 | This library is released under the Zero-Clause BSD licence (0BSD): 7 | 8 | Permission to use, copy, modify, and/or distribute this 9 | software for any purpose with or without fee is hereby 10 | granted. 11 | 12 | THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS 13 | ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL 14 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO 15 | EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, 16 | INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 17 | WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, 18 | WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 19 | TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE 20 | USE OR PERFORMANCE OF THIS SOFTWARE. 21 | 22 | Reference: . 23 | -------------------------------------------------------------------------------- /docs/src/miscellanea.stx: -------------------------------------------------------------------------------- 1 | --- 2 | title: Miscellanea 3 | meta_title: Syntext — Miscellanea 4 | --- 5 | 6 | ::: insert toc ::: 7 | 8 | 9 | ### Tables of Contents 10 | 11 | Syntext can automatically generate a table of contents for a document. This table can be inserted using the `insert` tag: 12 | 13 | ::: insert toc 14 | 15 | The default listing skips H1 headings to avoid including the document title itself. A full listing of all the document's headings can be inserted using the `fulltoc` keyword: 16 | 17 | ::: insert fulltoc 18 | 19 | The table of contents is generated as an unordered list of links. 20 | 21 | 22 | 23 | ### Footnotes 24 | 25 | Syntext includes built-in support for footnotes: 26 | 27 | This sentence ends with a footnote reference.[^1] 28 | 29 | Footnote references can omit their index to take advantage of automatic numbering: 30 | 31 | This sentence ends with an automatically-numbered 32 | reference.[^] 33 | 34 | Footnotes themselves can be specified anywhere in the document using the `footnote` tag: 35 | 36 | ::: footnote 1 37 | This is a footnote. It can contain any kind of 38 | block-level markup. 39 | 40 | Footnotes can also omit their index to take advantage of automatic numbering: 41 | 42 | ::: footnote 43 | This is an automatically-numbered footnote. 44 | 45 | Note that footnote indices do not have to be numeric --- any sequence of non-whitespace characters can be used. 46 | 47 | You can specify the insertion point for your footnotes using the `insert` tag: 48 | 49 | ::: insert footnotes 50 | 51 | Footnote references are wrapped in the following markup: 52 | 53 | ::: code html 54 | 55 | 56 | 1 57 | 58 | 59 | Footnotes are output as items in a description list: 60 | 61 | ::: code html 62 | 63 |
64 |
65 |
1
66 |
...
67 |
68 | ... 69 |
70 | 71 | Each footnote index is backlinked to its reference in the document. 72 | 73 | 74 | 75 | ### Alternate Footnote Styles 76 | 77 | Syntext supports two alternate styles for footnote references: superscripted[^1] and inline [fn:2]. 78 | 79 | Superscripted references look like this `[^1]` while inline references look like this `[fn:2]`. The only difference in markup is that superscripted references are wrapped in a `` tag while inline references are wrapped in a ``. 80 | 81 | ::: footnote 1 82 | This is a sample footnote. Footnotes can contain any kind of block-level markup including multiple paragraphs. 83 | 84 | ::: footnote 2 85 | And this is another sample footnote. 86 | 87 | 88 | 89 | ### Tab Translation Size 90 | 91 | Tab characters in input text are translated into spaces --- by default, 4 spaces per tab. This value can be customized via the `tabsize` argument: 92 | 93 | ::: code python 94 | 95 | html = syntext.render(text, tabsize=8) 96 | 97 | This argument is also available on the command line: 98 | 99 | $ syntext --tabsize 8 < input.txt > output.html 100 | 101 | 102 | 103 | ### Notes 104 | 105 | ::: insert footnotes 106 | -------------------------------------------------------------------------------- /docs/src/raw-html.stx: -------------------------------------------------------------------------------- 1 | --- 2 | title: Raw HTML 3 | meta_title: Syntext — Raw HTML 4 | --- 5 | 6 | ### Block HTML 7 | 8 | Syntext can recognise and ignore block-level HTML in its input so you can freely mix and match Syntext markup and raw HTML. 9 | 10 | :div .outer 11 | This is a paragraph. 12 | 13 |
14 |

This is raw HTML.

15 |
16 | 17 | This is another paragraph. 18 | 19 | Syntext treats the content of block-level HTML tags as raw text and passes it through without any further processing. 20 | 21 | 22 | ### Inline HTML 23 | 24 | Syntext ignores inline HTML tags so it's fine to mix and match inline HTML and Syntext markup. 25 | 26 | The HTML syntax characters `<`, `>`, and `&` are automatically escaped unless they form part of a HTML tag or character entity. 27 | -------------------------------------------------------------------------------- /docs/src/shorthand-html.stx: -------------------------------------------------------------------------------- 1 | --- 2 | title: Shorthand HTML 3 | meta_title: Syntext — Shorthand HTML 4 | --- 5 | 6 | ::: insert toc 7 | ::: hr 8 | 9 | Syntext supports an indentation-based shorthand syntax for generating arbitrary HTML: 10 | 11 | :tag [arguments] [.class] [#id] [&attr] [attr="value"] 12 | block content 13 | ... 14 | 15 | A shorthand block opens with a header line containing a colon, a HTML tag, and, optionally, a set of attributes. The block's content consists of all subsequent blank or indented lines following the header. 16 | 17 | The block's content can be indented by any number of spaces; the common indent is stripped and the first non-indented line ends the block. Leading and trailing blank lines are also trimmed from the content. 18 | 19 | To take a simple example, the markup below: 20 | 21 | :div 22 | This is a paragraph. 23 | 24 | generates the following HTML: 25 | 26 |
27 |

This is a paragraph.

28 |
29 | 30 | 31 | 32 | ### Header Meta 33 | 34 | A block header can contain a single ID, any number of classes, and any number of named attributes, e.g: 35 | 36 | :div .foo .bar #baz 37 | This is a paragraph. 38 | 39 | generates the following HTML: 40 | 41 |
42 |

This is a paragraph.

43 |
44 | 45 | Boolean attributes can be specified using an `&` symbol, e.g. `&checked`. Attributes with values can be specified without quotes as long as the value does not contain spaces, e.g. 46 | 47 | :div attr1=foo attr2="bar baz" 48 | 49 | 50 | 51 | ### Nesting 52 | 53 | Blocks can be nested to any depth, e.g: 54 | 55 | :div .outer 56 | :div .inner 57 | This is a paragraph. 58 | 59 | will generate the following HTML: 60 | 61 |
62 |
63 |

This is a paragraph.

64 |
65 |
66 | 67 | 68 | 69 | ### Linebreak Mode 70 | 71 | A `nl2lb` argument can be added to any block to turn on newline-to-linebreak mode for all nested content: 72 | 73 | :div nl2lb 74 | Linebreaks in this paragraph 75 | will be preserved. 76 | 77 | This argument has an alias, `nl2br`, which is exactly equivalent. 78 | 79 | 80 | 81 | ### Raw Mode 82 | 83 | You can add a `raw` argument to any block. This instructs Syntext to preserve the block's content as-is without any further processing. 84 | 85 | :div raw 86 | This content will be preserved in its raw state. 87 | -------------------------------------------------------------------------------- /docs/src/tagged-blocks.stx: -------------------------------------------------------------------------------- 1 | --- 2 | title: Tagged Blocks 3 | meta_title: Syntext — Tagged Blocks 4 | --- 5 | 6 | Syntext supports an indentation-based tagged-block syntax for custom elements: 7 | 8 | ::: tag [arguments] [.class] [#id] [&attr] [attr="value"] 9 | block content 10 | ... 11 | 12 | A block header can contain a single ID, any number of classes, and any number of named attributes. Block syntax also allows for one or more arguments to be supplied (how these are interpreted depends on the tag). 13 | 14 | Boolean attributes can be specified using an `&` symbol, e.g. `&checked`. Attributes with values can be specified without quotes as long as the value does not contain spaces. 15 | 16 | A block's tag determines how its content is processed. In general blocks can be nested to any depth and can contain any block-level content. 17 | 18 | Although a block's content is determined solely by its indentation an optional end marker can be added to support syntax highlighting in editors which struggle with indentation-based syntax: 19 | 20 | ::: tag 21 | block content 22 | ... 23 | ::: end 24 | 25 | Trailing colons in the header line are optional: 26 | 27 | ::: hr ::: 28 | 29 | is equivalent to: 30 | 31 | ::: hr 32 | 33 | A `nl2lb` / `nl2br` argument can be added to any block to turn on newline-to-linebreak mode for all nested content. 34 | 35 | 36 | 37 | ## Tag Reference 38 | 39 | 40 | ### •   `code` 41 | 42 | ::: code python 43 | def hello(): 44 | print('hello world') 45 | 46 | Wraps a code sample in `
` tags. Automatically escapes the HTML syntax characters `<`, `>`, and `&`.
 47 | 
 48 | This tag accepts an optional argument specifying the language of the code. If a language is specified then a `lang-` class and a `data-lang=""` attribute are added to the `
` element.
 49 | 
 50 | If a language is specified and the [Pygments](http://pygments.org) package is installed then syntax highlighting can be applied to the code sample. This feature is turned off by default but can be enabled by supplying a `pygmentize=True` keyword argument to the `render()` function:
 51 | 
 52 | ::: code python
 53 |     >>> html = syntext.render(text, pygmentize=True)
 54 | 
 55 | 
 56 | 
 57 | ### •   `comment`
 58 | 
 59 |     ::: comment
 60 |         This is a comment.
 61 | 
 62 | Creates a HTML comment. The block's content is not processed any further but is included in the output in its raw state.
 63 | 
 64 | 
 65 | 
 66 | ### •   `hr`
 67 | 
 68 |     ::: hr :::
 69 | 
 70 | Inserts a horizontal rule. Any number of dashes can be used in place of the `hr` tag, e.g.
 71 | 
 72 |     ::: ------ :::
 73 | 
 74 | 
 75 | 
 76 | ### •   `image`, `!image`
 77 | 
 78 |     ::: image http://example.com/image.jpg
 79 |         [Optional alt text.]
 80 |         Optional image caption.
 81 | 
 82 | Inserts an `` element. The first argument is used as the source url.
 83 | 
 84 | * If the first line of the block's content is wrapped in square brackets it will be treated as the image's alt text.
 85 | * If a caption is provided, it will be wrapped in a `
` element and the image and caption together will be wrapped in a `
` element. 86 | * If the `!image` tag is used, the image will be wrapped in a link to itself. 87 | 88 | Classes, attributes, etc. are attached to the outermost element. 89 | 90 | 91 | 92 | ### •   `infobox` 93 | 94 | ::: infobox .warning 95 | Careful now! 96 | 97 | Creates an info box --- a `
` element with the class `infobox` which can be styled appropriately using CSS. 98 | 99 | 100 | 101 | ### •   `link` 102 | 103 | ::: link http://example.com/ 104 | Link text or any other inline content. 105 | 106 | Inserts a link. The first argument is used as the url. 107 | 108 | 109 | 110 | ### •   `quote` 111 | 112 | ::: quote "Oscar Wilde" 113 | Work is the curse of the drinking classes. 114 | 115 | Inserts a `
` element. If a caption argument is provided it will follow the blockquote element wrapped in a `

` element with the class `.blockquote-caption`. 116 | 117 | 118 | 119 | ### •   `raw` 120 | 121 | ::: raw 122 | This content will be passed through in its raw state. 123 | 124 | Content inside a `raw` tag will be passed through in its raw state without any further processing. 125 | 126 | 127 | 128 | ### •   `table` 129 | 130 | Indicates that the block contains a table: 131 | 132 | ::: table 133 | 134 | foo | bar | baz 135 | --------------- 136 | aaa | bbb | ccc 137 | ddd | eee | fff 138 | --------------- 139 | foo | bar | baz 140 | 141 | Header and footer lines are optional. All three tables below are valid: 142 | 143 | foo | bar | baz 144 | --------------- 145 | aaa | bbb | ccc aaa | bbb | ccc aaa | bbb | ccc 146 | ddd | eee | fff ddd | eee | fff ddd | eee | fff 147 | --------------- 148 | foo | bar | baz 149 | 150 | Note that all the tables above can be 'boxed' with decorative outer lines of pipes and dashes, e.g.: 151 | 152 | --------------- ------------------- 153 | foo | bar | baz | foo | bar | baz | 154 | --------------- ------------------- 155 | aaa | bbb | ccc | aaa | bbb | ccc | 156 | ddd | eee | fff | ddd | eee | fff | 157 | --------------- ------------------- 158 | 159 | Column alignment can be specified using colons as below: 160 | 161 | default | left | center | right 162 | ------- | :--- | :----: | ----: 163 | aaaaa | bb | cccc | ddd 164 | eeeee | ff | gggg | hhh 165 | 166 | Cells in the left column above receive the class `left`, cells in the center column receive the class `center`, and cells in the right column receive the class `right`. 167 | 168 | Attributes specified in the block header will be applied to the `` element. 169 | 170 | Note that you can't use the `|` symbol inside table literals --- use the HTML escape code `|` instead. 171 | -------------------------------------------------------------------------------- /license.txt: -------------------------------------------------------------------------------- 1 | Permission to use, copy, modify, and/or distribute this software for any purpose 2 | with or without fee is hereby granted. 3 | 4 | THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH 5 | REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND 6 | FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, 7 | INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS 8 | OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 9 | TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF 10 | THIS SOFTWARE. 11 | -------------------------------------------------------------------------------- /makefile: -------------------------------------------------------------------------------- 1 | help: 2 | @cat ./makefile 3 | 4 | test: 5 | @./test_syntext.py 6 | 7 | build: 8 | ./setup.py sdist bdist_wheel 9 | 10 | publish: 11 | ./setup.py sdist bdist_wheel 12 | twine upload dist/* 13 | 14 | clean: 15 | rm -rf ./build 16 | rm -rf ./dist 17 | rm -rf ./*.egg-info 18 | -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | # Syntext 2 | 3 | Syntext is a lightweight, Markdownish markup language for generating HTML. It shares many basic features with Markdown but adds an extensible, indentation-based syntax for generating arbitrary HTML: 4 | 5 | :div .outer 6 | :div .inner 7 | This is a paragraph. 8 | 9 | See the [documentation](http://www.dmulholl.com/docs/syntext/master/) for details. 10 | -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | """ 3 | Syntext is a lightweight, markdownish markup language for generating HTML from 4 | plain text. This package can be used as both a command line tool and an importable library. 5 | 6 | On the command line:: 7 | 8 | $ syntext < input.txt > output.html 9 | 10 | As a library:: 11 | 12 | >>> import syntext 13 | >>> html = syntext.render(text) 14 | 15 | See the `package documentation `_ or the 16 | project's `Github homepage `_ for 17 | further details. 18 | 19 | """ 20 | 21 | import os 22 | import re 23 | import io 24 | import setuptools 25 | 26 | 27 | filepath = os.path.join(os.path.dirname(__file__), 'syntext', '__init__.py') 28 | with io.open(filepath, encoding='utf-8') as metafile: 29 | regex = r'''^__([a-z]+)__ = ["'](.*)["']''' 30 | meta = dict(re.findall(regex, metafile.read(), flags=re.MULTILINE)) 31 | 32 | 33 | setuptools.setup( 34 | name = 'syntext', 35 | version = meta['version'], 36 | packages = setuptools.find_packages(), 37 | entry_points = { 38 | 'console_scripts': [ 39 | 'syntext = syntext:main', 40 | ], 41 | }, 42 | install_requires = [ 43 | 'pygments', 44 | ], 45 | author = 'Darren Mulholland', 46 | url = 'http://www.dmulholl.com/docs/syntext/master/', 47 | license = 'Public Domain', 48 | description = ('A markdownish markup language.'), 49 | long_description = __doc__, 50 | classifiers = [ 51 | 'Programming Language :: Python :: 3', 52 | 'Operating System :: OS Independent', 53 | 'License :: Public Domain', 54 | 'Topic :: Text Processing :: Markup :: HTML', 55 | ], 56 | ) 57 | -------------------------------------------------------------------------------- /syntext/__init__.py: -------------------------------------------------------------------------------- 1 | # --------------------------------------------------------- 2 | # Syntext: a lightweight, markdownish markup language. 3 | # --------------------------------------------------------- 4 | 5 | __version__ = "3.1.2" 6 | 7 | from .interface import render 8 | from .interface import main 9 | from .utils import SyntextError 10 | 11 | from . import tags 12 | from . import nodes 13 | from . import parsers 14 | from . import utils 15 | from . import shorthand 16 | -------------------------------------------------------------------------------- /syntext/__main__.py: -------------------------------------------------------------------------------- 1 | # --------------------------------------------------------- 2 | # This module makes the package directly executable. To 3 | # run a syntext package located on Python's import search 4 | # path: 5 | # 6 | # $ python -m syntext 7 | # 8 | # To run an arbitrary syntext package: 9 | # 10 | # $ python /path/to/syntext/package 11 | # 12 | # --------------------------------------------------------- 13 | 14 | import os 15 | import sys 16 | 17 | 18 | # Python doesn't automatically add the package's parent directory to the 19 | # module search path so we need to do so manually before we can import 20 | # syntext. 21 | sys.path.insert(0, os.path.dirname(os.path.dirname(__file__))) 22 | 23 | 24 | import syntext 25 | syntext.main() 26 | -------------------------------------------------------------------------------- /syntext/inline.py: -------------------------------------------------------------------------------- 1 | # ------------------------------------------------------------------------------ 2 | # Functions for parsing and rendering inline markup. 3 | # ------------------------------------------------------------------------------ 4 | 5 | import html 6 | import hashlib 7 | import re 8 | 9 | 10 | # ------------------------------------------------------------------------------ 11 | # Regular expressions for identifying inline markup. 12 | # ------------------------------------------------------------------------------ 13 | 14 | # *x* 15 | re_italic_sc = re.compile(r"\*(\S)\*") 16 | 17 | # *foo bar* 18 | re_italic_mc = re.compile(r"\*(\S.*?\S)\*", re.DOTALL) 19 | 20 | # **x** 21 | re_bold_sc = re.compile(r"\*{2}(\S)\*{2}") 22 | 23 | # **foo bar** 24 | re_bold_mc = re.compile(r"\*{2}(\S.*?\S)\*{2}", re.DOTALL) 25 | 26 | # ***x*** 27 | re_bolditalic_sc = re.compile(r"\*{3}(\S)\*{3}") 28 | 29 | # ***foo bar*** 30 | re_bolditalic_mc = re.compile(r"\*{3}(\S.*?\S)\*{3}", re.DOTALL) 31 | 32 | # `foo bar` 33 | re_backticks = re.compile(r"`(.+?)`", re.DOTALL) 34 | 35 | # [link text](http://example.com) 36 | re_link = re.compile(r"\[([^\]]+)\]\(([^\)]+)\)") 37 | 38 | # [link text][ref] 39 | re_ref_link = re.compile(r"\[([^\]]+)\]\[([^\]]*)\]") 40 | 41 | # ![alt text](http://example.com) 42 | re_img = re.compile(r"!\[([^\]]*)\]\(([^\)]+)\)") 43 | 44 | # ![alt text][ref] 45 | re_ref_img = re.compile(r"!\[([^\]]*)\]\[([^\]]*)\]") 46 | 47 | # [^ref] or [^] 48 | re_footnote_super = re.compile(r"\[\^([^\]]*?)\]") 49 | 50 | # [fn:ref] or [fn] 51 | re_footnote_span = re.compile(r"\[fn:?([^\]]*?)\]") 52 | 53 | # & ' 54 | re_entity = re.compile(r"&[#a-zA-Z0-9]+;") 55 | 56 | # html tags: , , , etc. 57 | re_html_tag = re.compile(r"<([a-zA-Z/][^>]*?|!--.*?--)>") 58 | 59 | # 60 | re_bracketed_url = re.compile(r"<((?:https?|ftp)://[^>]+)>") 61 | 62 | # http://example.com 63 | re_bare_url = re.compile(r""" 64 | (^|\s) 65 | (https?|ftp) 66 | (://[-A-Z0-9+&@#/%?=~_|\[\]\(\)!:,\.;]*[-A-Z0-9+&@#/%=~_|\[\]]) 67 | ($|\W) 68 | """, re.VERBOSE | re.MULTILINE | re.IGNORECASE) 69 | 70 | # n-dash 71 | re_ndash = re.compile(r"((?<=\s)|\b|^)--(?=[ ]|\b|$)", re.MULTILINE) 72 | 73 | # m-dash 74 | re_mdash = re.compile(r"((?<=\s)|\b|^)---(?=[ ]|\b|$)", re.MULTILINE) 75 | 76 | # x^{2} 77 | re_superscript = re.compile(r"\^\{(.+?)\}") 78 | 79 | # H_{2}O 80 | re_subscript = re.compile(r"_\{(.+?)\}") 81 | 82 | # ``foo bar`` 83 | re_verbatim = re.compile(r"``(.+?)``", re.DOTALL) 84 | 85 | 86 | # ------------------------------------------------------------------------------ 87 | # Renderers. 88 | # ------------------------------------------------------------------------------ 89 | 90 | 91 | # Entry point. 92 | def render(text, meta): 93 | hashes = {} 94 | 95 | text = render_verbatim(text, hashes) 96 | text = render_backticks(text, hashes) 97 | text = render_bracketed_urls(text, hashes) 98 | text = render_inline_html(text, hashes) 99 | text = render_html_entities(text, hashes) 100 | text = render_dashes(text, hashes) 101 | 102 | text = html.escape(text, False) 103 | 104 | text = render_bolditalic(text) 105 | text = render_bold(text) 106 | text = render_italic(text) 107 | text = render_footnotes(text, meta) 108 | text = render_images(text) 109 | text = render_ref_images(text, meta) 110 | text = render_links(text) 111 | text = render_ref_links(text, meta) 112 | text = render_superscripts(text) 113 | text = render_subscripts(text) 114 | 115 | if 'nl2br' in meta.get('context', []): 116 | text = text.replace('\n', '
\n') 117 | 118 | for key, value in hashes.items(): 119 | text = text.replace(key, value) 120 | 121 | return text 122 | 123 | 124 | # Hashes a string, stores it as a {digest: string} pair in 'hashes', and 125 | # returns the digest. 126 | def hashstr(text, hashes): 127 | digest = hashlib.sha1(text.encode()).hexdigest() 128 | hashes[digest] = text 129 | return digest 130 | 131 | 132 | def render_backticks(text, hashes): 133 | def callback(match): 134 | content = html.escape(match.group(1)) 135 | return hashstr('%s' % content, hashes) 136 | return re_backticks.sub(callback, text) 137 | 138 | 139 | def render_bracketed_urls(text, hashes): 140 | def callback(match): 141 | url = '%s' % (match.group(1), match.group(1)) 142 | return hashstr(url, hashes) 143 | return re_bracketed_url.sub(callback, text) 144 | 145 | 146 | def render_inline_html(text, hashes): 147 | return re_html_tag.sub(lambda match: hashstr(match.group(), hashes), text) 148 | 149 | 150 | def render_verbatim(text, hashes): 151 | return re_verbatim.sub(lambda match: hashstr(match.group(1), hashes), text) 152 | 153 | 154 | def render_html_entities(text, hashes): 155 | return re_entity.sub(lambda match: hashstr(match.group(), hashes), text) 156 | 157 | 158 | def render_dashes(text, hashes): 159 | text = re_ndash.sub(hashstr("–", hashes), text) 160 | text = re_mdash.sub(hashstr("—", hashes), text) 161 | return text 162 | 163 | 164 | def render_bold(text): 165 | text = re_bold_sc.sub(r"\1", text) 166 | text = re_bold_mc.sub(r"\1", text) 167 | return text 168 | 169 | 170 | def render_italic(text): 171 | text = re_italic_sc.sub(r"\1", text) 172 | text = re_italic_mc.sub(r"\1", text) 173 | return text 174 | 175 | 176 | def render_bolditalic(text): 177 | text = re_bolditalic_sc.sub(r"\1", text) 178 | text = re_bolditalic_mc.sub(r"\1", text) 179 | return text 180 | 181 | 182 | def render_superscripts(text): 183 | return re_superscript.sub(r"\1", text) 184 | 185 | 186 | def render_subscripts(text): 187 | return re_subscript.sub(r"\1", text) 188 | 189 | 190 | def render_images(text): 191 | def callback(match): 192 | alt = html.escape(match.group(1)) 193 | url = match.group(2) 194 | return f'{alt}' 195 | return re_img.sub(callback, text) 196 | 197 | 198 | def render_ref_images(text, meta): 199 | def callback(match): 200 | alt = html.escape(match.group(1)) 201 | ref = match.group(2).lower() if match.group(2) else alt.lower() 202 | url, title = meta.get('linkrefs', {}).get(ref, ('', '')) 203 | if title: 204 | title = html.escape(title) 205 | return '%s' % (alt, url, title) 206 | else: 207 | return '%s' % (alt, url) 208 | return re_ref_img.sub(callback, text) 209 | 210 | 211 | def render_links(text): 212 | def callback(match): 213 | text = match.group(1) 214 | url = match.group(2) 215 | return f'{text}' 216 | return re_link.sub(callback, text) 217 | 218 | 219 | def render_ref_links(text, meta): 220 | def callback(match): 221 | text = match.group(1) 222 | ref = match.group(2).lower() if match.group(2) else text.lower() 223 | url, title = meta.get('linkrefs', {}).get(ref, ('', '')) 224 | if title: 225 | title = html.escape(title) 226 | return '%s' % (url, title, text) 227 | else: 228 | return '%s' % (url, text) 229 | return re_ref_link.sub(callback, text) 230 | 231 | 232 | def render_footnotes(text, meta): 233 | def callback(match): 234 | if match.group(1): 235 | ref = match.group(1) 236 | else: 237 | ref = meta.setdefault('footnote-ref-index', 1) 238 | meta['footnote-ref-index'] += 1 239 | link = f'{ref}' 240 | return f'<{tag} class="footnote" id="fnref:{ref}">{link}' 241 | 242 | tag = "sup" 243 | text = re_footnote_super.sub(callback, text) 244 | tag = "span" 245 | text = re_footnote_span.sub(callback, text) 246 | return text 247 | -------------------------------------------------------------------------------- /syntext/interface.py: -------------------------------------------------------------------------------- 1 | # ------------------------------------------------------------------------------ 2 | # This module defines the package's API. 3 | # ------------------------------------------------------------------------------ 4 | 5 | import argparse 6 | import sys 7 | import os 8 | import pprint 9 | import syntext 10 | 11 | from . import utils 12 | from . import parsers 13 | from . import nodes 14 | from . import toc 15 | 16 | 17 | # ------------------------------------------------------------------------------ 18 | # Internal interface. 19 | # ------------------------------------------------------------------------------ 20 | 21 | 22 | def parse(text, meta): 23 | expanded_text = text.expandtabs(meta.get('tabsize', 4)) 24 | line_stream = utils.LineStream(expanded_text) 25 | root = nodes.Node() 26 | root.children = parsers.BlockParser().parse(line_stream, meta) 27 | tocbuilder = toc.TOCBuilder(root) 28 | meta['toc'] = tocbuilder.toc() 29 | meta['fulltoc'] = tocbuilder.fulltoc() 30 | html = root.render(meta) 31 | return html.strip(), root, meta 32 | 33 | 34 | # ------------------------------------------------------------------------------ 35 | # Library interface. 36 | # ------------------------------------------------------------------------------ 37 | 38 | 39 | def render(text, **meta): 40 | html, _, _ = parse(text, meta) 41 | return html 42 | 43 | 44 | # ------------------------------------------------------------------------------ 45 | # Command line interface. 46 | # ------------------------------------------------------------------------------ 47 | 48 | 49 | # Command line helptext. 50 | helptext = """ 51 | Usage: %s [FLAGS] [OPTIONS] 52 | 53 | Renders input text in Syntext format into HTML. Reads from stdin and 54 | prints to stdout. 55 | 56 | Example: 57 | 58 | $ syntext < input.txt > output.html 59 | 60 | Options: 61 | -t, --tabsize Set tab translation size (default: 4). 62 | 63 | Flags: 64 | -d, --debug Run in debug mode. 65 | -h, --help Print the application's help text and exit. 66 | -p, --pygmentize Add syntax highlighting to code samples. 67 | -v, --version Print the application's version number and exit. 68 | """ % os.path.basename(sys.argv[0]) 69 | 70 | 71 | # Custom argparse action to override the default help text. 72 | class HelpAction(argparse.Action): 73 | def __call__(self, parser, namespace, values, option_string=None): 74 | print(helptext.strip()) 75 | sys.exit() 76 | 77 | 78 | # Entry point for the command line utility. 79 | def main(): 80 | parser = argparse.ArgumentParser(add_help=False) 81 | parser.add_argument('-v', '--version', 82 | action="version", 83 | version=syntext.__version__, 84 | ) 85 | parser.add_argument('-h', '--help', 86 | action = HelpAction, 87 | nargs=0, 88 | ) 89 | parser.add_argument('-d', '--debug', 90 | action="store_true", 91 | help="run in debug mode", 92 | ) 93 | parser.add_argument('-p', '--pygmentize', 94 | action="store_true", 95 | help="add syntax highlighting to code samples", 96 | ) 97 | parser.add_argument('-t', '--tabsize', 98 | type=int, 99 | default=4, 100 | help="set tabsize", 101 | ) 102 | args = parser.parse_args() 103 | 104 | text = sys.stdin.read() 105 | meta = { 106 | 'pygmentize': args.pygmentize, 107 | 'tabsize': args.tabsize, 108 | } 109 | html, root, meta = parse(text, meta) 110 | 111 | if args.debug: 112 | print(utils.title('AST')) 113 | print(root) 114 | print(utils.title('META')) 115 | print(pprint.pformat(meta) + '\n') 116 | print(utils.title('HTML')) 117 | print(html) 118 | else: 119 | print(html) 120 | 121 | -------------------------------------------------------------------------------- /syntext/nodes.py: -------------------------------------------------------------------------------- 1 | # ------------------------------------------------------------------------------ 2 | # Node classes for the package's AST. 3 | # ------------------------------------------------------------------------------ 4 | 5 | import sys 6 | from . import inline 7 | 8 | 9 | # Input text is parsed into a tree of nodes. 10 | class Node: 11 | 12 | def __init__(self, tag=None, attributes=None, text=None, is_void=False): 13 | self.tag = tag 14 | self.text = text or '' 15 | self.children = [] 16 | self.attributes = attributes or {} 17 | self.is_void = is_void 18 | 19 | def __str__(self): 20 | return self.str() 21 | 22 | def str(self, depth=0): 23 | output = ["· " * depth] 24 | output.append('%s' % self.__class__.__name__) 25 | if self.tag: 26 | output.append(' ' + self.opening_tag()) 27 | if self.text: 28 | text = repr(self.text) 29 | if len(text) < 40: 30 | output.append(' ' + text) 31 | else: 32 | output.append(' ' + text[:18] + "..." + text[-18:]) 33 | output.append('\n') 34 | for child in self.children: 35 | output.append(child.str(depth + 1)) 36 | return ''.join(output) 37 | 38 | def render(self, meta): 39 | output = [] 40 | 41 | if self.tag: 42 | output.append(self.opening_tag() + '\n') 43 | 44 | if self.children: 45 | output.append(''.join(child.render(meta) for child in self.children)) 46 | elif self.text: 47 | output.append(self.text.rstrip() + '\n') 48 | 49 | if self.tag and not self.is_void: 50 | output.append(self.closing_tag() + '\n') 51 | 52 | return ''.join(output) 53 | 54 | def opening_tag(self): 55 | attributes = [] 56 | for key, value in sorted(self.attributes.items()): 57 | if value is None: 58 | attributes.append(' %s' % key) 59 | else: 60 | attributes.append(' %s="%s"' % (key, value)) 61 | return '<%s%s>' % (self.tag, ''.join(attributes)) 62 | 63 | def closing_tag(self): 64 | return '' % self.tag 65 | 66 | def append_child(self, node): 67 | self.children.append(node) 68 | return self 69 | 70 | def add_class(self, newclass): 71 | classes = self.attributes.get('class', '').split() 72 | if newclass not in classes: 73 | classes.append(newclass) 74 | self.attributes['class'] = ' '.join(sorted(classes)) 75 | 76 | 77 | # Text nodes contain only text, they have no children. Their content is 78 | # processed for inline markup. 79 | class TextNode(Node): 80 | 81 | def __init__(self, text): 82 | Node.__init__(self) 83 | self.text = text 84 | 85 | def render(self, meta): 86 | return inline.render(self.text, meta) + '\n' 87 | 88 | 89 | # Comment nodes represent HTML comments. 90 | class CommentNode(Node): 91 | 92 | def render(self, meta): 93 | html = [] 94 | html.append('\n') 98 | return ''.join(html) 99 | 100 | 101 | # Insert nodes provide a mechanism for inserting generated content, 102 | # e.g. tables of contents or footnotes. 103 | class InsertNode(Node): 104 | 105 | def render(self, meta): 106 | if self.text in meta: 107 | return meta[self.text].render(meta) 108 | else: 109 | sys.stderr.write('Error: missing insert %s.\n' % repr(self.text)) 110 | return '' 111 | 112 | 113 | # Turns on newline-to-linebreak mode for all children. 114 | class LinebreakNode(Node): 115 | 116 | def render(self, meta): 117 | context = meta.setdefault('context', []) 118 | context.append('nl2br') 119 | rendered = ''.join(child.render(meta) for child in self.children) 120 | context.pop() 121 | return rendered 122 | -------------------------------------------------------------------------------- /syntext/shorthand.py: -------------------------------------------------------------------------------- 1 | # ------------------------------------------------------------------------------ 2 | # Functions for processing shorthand html tags. 3 | # ------------------------------------------------------------------------------ 4 | 5 | import html 6 | import re 7 | 8 | from . import nodes 9 | from . import parsers 10 | from . import utils 11 | 12 | 13 | # Void elements have no content or closing tag. 14 | html_void_tags = set(""" 15 | area base br col embed hr img input link meta param source track wbr 16 | """.split()) 17 | 18 | 19 | # Leaf elements cannot contain nested block-level content. 20 | html_leaf_tags = set(""" 21 | dt h1 h2 h3 h4 h5 h6 p title 22 | a abbr acronyn audio b bdi bdo big button canvas cite code data datalist 23 | del dfn em i iframe ins kbd label map mark meter noscript 24 | object output picture progress q ruby s samp select slot small span 25 | strong sub sup svg template textarea time u tt var video 26 | """.split()) 27 | 28 | 29 | # Raw elements contain text which should be included in the output as-is. 30 | html_raw_tags = set("script style".split()) 31 | 32 | 33 | # Process a tagged block. 34 | def process(header, line_stream, meta): 35 | match = re.fullmatch(r':([^ ]+)([ ].+)?', header) 36 | tag = match.group(1) 37 | argstring = match.group(2) or '' 38 | pargs, kwargs = utils.ArgParser().parse(argstring) 39 | 40 | if 'raw' in pargs: 41 | return nodes.Node(tag, kwargs, text=str(line_stream)) 42 | 43 | if tag in html_void_tags: 44 | node = nodes.Node(tag, kwargs, is_void=True) 45 | elif tag in html_leaf_tags: 46 | node = nodes.Node(tag, kwargs) 47 | node.children = parsers.InlineParser().parse(line_stream, meta) 48 | elif tag in html_raw_tags: 49 | node = nodes.Node(tag, kwargs, text=str(line_stream)) 50 | else: 51 | node = nodes.Node(tag, kwargs) 52 | node.children = parsers.BlockParser().parse(line_stream, meta) 53 | 54 | if 'nl2lb' in pargs or 'nl2br' in pargs: 55 | node = nodes.LinebreakNode().append_child(node) 56 | 57 | return node 58 | -------------------------------------------------------------------------------- /syntext/tags.py: -------------------------------------------------------------------------------- 1 | # ------------------------------------------------------------------------------ 2 | # Functions for registering and processing tags. 3 | # ------------------------------------------------------------------------------ 4 | 5 | import html 6 | import re 7 | 8 | from . import nodes 9 | from . import parsers 10 | from . import utils 11 | 12 | 13 | # Use the Pygments module for syntax highlighting, if it's available. 14 | try: 15 | import pygments 16 | import pygments.lexers 17 | import pygments.formatters 18 | except ImportError: 19 | pygments = None 20 | 21 | 22 | # Map tags to registered handler functions. 23 | tagmap = {} 24 | 25 | 26 | # Decorator function for registering tag handlers. 27 | def register(*tags): 28 | 29 | def register_tag_handler(func): 30 | for tag in tags: 31 | tagmap[tag] = func 32 | return func 33 | 34 | return register_tag_handler 35 | 36 | 37 | # Process a tag. 38 | def process(tag, pargs, kwargs, line_stream, meta): 39 | if tag in tagmap: 40 | node = tagmap[tag](tag, pargs, kwargs, line_stream, meta) 41 | elif tag == 'hr' or re.fullmatch(r'-+', tag): 42 | node = nodes.Node('hr', kwargs, is_void=True) 43 | else: 44 | raise utils.SyntextError("Unrecognized tag '%s'." % tag) 45 | 46 | if 'nl2lb' in pargs or 'nl2br' in pargs: 47 | node = nodes.LinebreakNode().append_child(node) 48 | return node 49 | 50 | 51 | # Handler for the 'div' tag - useful as a test for tags with block-level content. 52 | @register('div') 53 | def div_tag_handler(tag, pargs, kwargs, line_stream, meta): 54 | node = nodes.Node('div', kwargs) 55 | node.children = parsers.BlockParser().parse(line_stream, meta) 56 | return node 57 | 58 | 59 | # Handler for the 'span' tag - useful as a test for tags with inline-level content. 60 | @register('span') 61 | def span_tag_handler(tag, pargs, kwargs, line_stream, meta): 62 | node = nodes.Node('span', kwargs) 63 | node.children = parsers.InlineParser().parse(line_stream, meta) 64 | return node 65 | 66 | 67 | # Handler for the 'link' tag. Uses the first keyword argument as the url. 68 | @register('link') 69 | def link_tag_handler(tag, pargs, kwargs, line_stream, meta): 70 | node = nodes.Node('a', kwargs) 71 | node.children = parsers.InlineParser().parse(line_stream, meta) 72 | if not 'href' in kwargs: 73 | node.attributes['href'] = pargs[0] if pargs else '' 74 | return node 75 | 76 | 77 | # Handler for blockquotes. 78 | @register('quote') 79 | def quote_tag_handler(tag, pargs, kwargs, line_stream, meta): 80 | quote = nodes.Node('blockquote', kwargs) 81 | quote.children = parsers.BlockParser().parse(line_stream, meta) 82 | if pargs: 83 | caption = nodes.Node('p') 84 | caption.add_class('blockquote-caption') 85 | caption.append_child(nodes.TextNode(pargs[0])) 86 | wrapper = nodes.Node() 87 | wrapper.append_child(quote) 88 | wrapper.append_child(caption) 89 | return wrapper 90 | return quote 91 | 92 | 93 | # Handler for infobox tags. Supports alertbox as deprecated alias. 94 | @register('infobox', 'alertbox') 95 | def infobox_tag_handler(tag, pargs, kwargs, line_stream, meta): 96 | node = nodes.Node('div', kwargs) 97 | node.add_class(tag) 98 | node.children = parsers.BlockParser().parse(line_stream, meta) 99 | return node 100 | 101 | 102 | # Handler for image tags. Uses the first keyword argument as the src. 103 | @register('image', '!image') 104 | def image_tag_handler(tag, pargs, kwargs, line_stream, meta): 105 | image = nodes.Node('img', is_void=True) 106 | image.attributes['src'] = pargs[0] if pargs else '' 107 | outernode = image 108 | 109 | if line_stream.has_next() and line_stream.peek().startswith('[') and line_stream.peek().endswith(']'): 110 | image.attributes['alt'] = html.escape(line_stream.next()[1:-1]) 111 | 112 | if tag == '!image': 113 | link = nodes.Node('a') 114 | link.attributes['href'] = pargs[0] if pargs else '' 115 | link.append_child(image) 116 | outernode = link 117 | 118 | if line_stream.has_next(): 119 | figcaption = nodes.Node('figcaption') 120 | figcaption.append_child(nodes.TextNode(str(line_stream).strip())) 121 | figure = nodes.Node('figure') 122 | figure.append_child(outernode) 123 | figure.append_child(figcaption) 124 | outernode = figure 125 | 126 | outernode.attributes.update(kwargs) 127 | return outernode 128 | 129 | 130 | # Handler for the 'comment' tag; creates a HTML comment. 131 | @register('comment') 132 | def comment_tag_handler(tag, pargs, kwargs, line_stream, meta): 133 | return nodes.CommentNode(text=str(line_stream.indent(4))) 134 | 135 | 136 | # Handler for the 'raw' tag. 137 | @register('raw') 138 | def raw_tag_handler(tag, pargs, kwargs, line_stream, meta): 139 | return nodes.Node(text=str(line_stream)) 140 | 141 | 142 | # Handler for code samples. 143 | @register('code') 144 | def code_tag_handler(tag, pargs, kwargs, line_stream, meta): 145 | node = nodes.Node('pre', kwargs) 146 | lang = pargs[0] if pargs else None 147 | text = str(line_stream) 148 | 149 | if lang: 150 | node.attributes['data-lang'] = lang 151 | node.add_class('lang-%s' % lang) 152 | 153 | if meta.get('pygmentize') and pygments and lang: 154 | try: 155 | lexer = pygments.lexers.get_lexer_by_name(lang) 156 | except pygments.util.ClassNotFound: 157 | try: 158 | lexer = pygments.lexers.guess_lexer(text) 159 | except pygments.util.ClassNotFound: 160 | lexer = None 161 | if lexer: 162 | node.add_class('pygments') 163 | formatter = pygments.formatters.HtmlFormatter(nowrap=True) 164 | node.text = pygments.highlight(text, lexer, formatter).strip('\n') 165 | return node 166 | 167 | node.text = html.escape(text, quote=False) 168 | return node 169 | 170 | 171 | # Handler for the 'insert' tag. This tag is used to insert generated elements, 172 | # e.g. a table of contents or block of footnotes. 173 | @register('insert') 174 | def insert_tag_handler(tag, pargs, kwargs, line_stream, meta): 175 | node = nodes.InsertNode() 176 | node.text = pargs[0] if pargs else '' 177 | return node 178 | 179 | 180 | # Handler for the 'table' tag. 181 | @register('table') 182 | def table_tag_handler(tag, pargs, kwargs, line_stream, meta): 183 | 184 | # Strip any outer pipes and discard any blank lines. 185 | lines = [line.strip('|') for line in line_stream.lines if line] 186 | 187 | # Check for a line with colons specifying cell alignment. 188 | alignment = [] 189 | for line in lines: 190 | match = re.fullmatch(r'[ |-]*[:][ |:-]*', line) 191 | if match: 192 | for cell in [cell.strip() for cell in line.split('|')]: 193 | if cell.startswith(':') and cell.endswith(':'): 194 | alignment.append('center') 195 | elif cell.startswith(':'): 196 | alignment.append('left') 197 | elif cell.endswith(':'): 198 | alignment.append('right') 199 | else: 200 | alignment.append(None) 201 | break 202 | 203 | # If we have a decorative top line, strip it. 204 | if lines and re.fullmatch(r'[ |:-]+', lines[0]): 205 | lines.pop(0) 206 | 207 | # If we have a decorative bottom line, strip it. 208 | if lines and re.fullmatch(r'[ |:-]+', lines[-1]): 209 | lines.pop() 210 | 211 | # Do we have a header? 212 | header = None 213 | if len(lines) > 2 and re.fullmatch(r'[ |:-]+', lines[1]): 214 | header = [cell.strip() for cell in lines[0].split('|')] 215 | lines = lines[2:] 216 | 217 | # Do we have a footer? 218 | footer = None 219 | if len(lines) > 2 and re.fullmatch(r'[ |:-]+', lines[-2]): 220 | footer = [cell.strip() for cell in lines[-1].split('|')] 221 | lines = lines[:-2] 222 | 223 | # Assemble the table body. 224 | body = [[cell.strip() for cell in line.split('|')] for line in lines] 225 | 226 | # Make a row of cells using the specified tag. 227 | def make_row(cells, tag): 228 | tr = nodes.Node('tr') 229 | for index, text in enumerate(cells): 230 | cell = nodes.Node(tag) 231 | cell.append_child(nodes.TextNode(text)) 232 | if len(alignment) > index and alignment[index]: 233 | cell.add_class(alignment[index]) 234 | tr.append_child(cell) 235 | return tr 236 | 237 | # Assemble the table node. 238 | table = nodes.Node('table', kwargs) 239 | 240 | if header: 241 | thead = nodes.Node('thead') 242 | thead.append_child(make_row(header, 'th')) 243 | table.append_child(thead) 244 | 245 | if footer: 246 | tfoot = nodes.Node('tfoot') 247 | tfoot.append_child(make_row(footer, 'th')) 248 | table.append_child(tfoot) 249 | 250 | tbody = nodes.Node('tbody') 251 | for row in body: 252 | tbody.append_child(make_row(row, 'td')) 253 | table.append_child(tbody) 254 | 255 | return table 256 | 257 | 258 | # Handler for the 'footnote' tag. 259 | @register('footnote') 260 | def footnote_tag_handler(tag, pargs, kwargs, line_stream, meta): 261 | 262 | # Autogenerate a footnote index if the user hasn't specified one. 263 | ref = pargs[0] if pargs else '' 264 | if not ref: 265 | ref = str(meta.setdefault('footnote-index', 1)) 266 | meta['footnote-index'] += 1 267 | 268 | # Wrap each footnote in a
. 269 | footnote = nodes.Node('div', {'id': 'fn:%s' % ref}) 270 | 271 | # Generate a backlink node. 272 | link = nodes.Node('a', {'href': '#fnref:%s' % ref}) 273 | link.append_child(nodes.TextNode(ref)) 274 | 275 | # Generate a
node for the footnote index. 276 | index = nodes.Node('dt') 277 | index.append_child(link) 278 | footnote.append_child(index) 279 | 280 | # Generate a
node containing the parsed footnote body. 281 | body = nodes.Node('dd') 282 | body.children = parsers.BlockParser().parse(line_stream, meta) 283 | footnote.append_child(body) 284 | 285 | # Generate a footnotes
node if we haven't done so already. 286 | if not 'footnotes' in meta: 287 | meta['footnotes'] = nodes.Node('dl', {'class': 'footnotes'}) 288 | 289 | meta['footnotes'].append_child(footnote) 290 | return None 291 | -------------------------------------------------------------------------------- /syntext/toc.py: -------------------------------------------------------------------------------- 1 | # ------------------------------------------------------------------------------ 2 | # Table of Contents builder. 3 | # ------------------------------------------------------------------------------ 4 | 5 | from . import nodes 6 | from . import utils 7 | 8 | 9 | # Table of Contents Builder 10 | # 11 | # Processes a tree of block elements to produce a table of contents with links 12 | # to each heading in the document. Note that this process modifies the tree in 13 | # place by adding an automatically generated ID to any heading element that 14 | # lacks one. 15 | # 16 | # The table is returned as a Node tree representing an unordered list with 17 | # nested sublists. 18 | # 19 | # toc = TOCBuilder(root).toc() 20 | # 21 | class TOCBuilder: 22 | 23 | def __init__(self, node): 24 | self.root = dict(level=0, text='ROOT', id='', subs=[]) 25 | self.stack = [self.root] 26 | self.ids = [] 27 | self._process_node(node) 28 | 29 | def _process_node(self, node): 30 | if node.tag in ('h1', 'h2', 'h3', 'h4', 'h5', 'h6'): 31 | heading = self._make_toc_node(node) 32 | while heading['level'] <= self.stack[-1]['level']: 33 | self.stack.pop() 34 | self.stack[-1]['subs'].append(heading) 35 | self.stack.append(heading) 36 | else: 37 | for child in node.children: 38 | self._process_node(child) 39 | 40 | def _make_toc_node(self, node): 41 | level = int(node.tag[1]) 42 | html = node.render({}) 43 | text = utils.strip_tags(html).strip() 44 | if 'id' in node.attributes: 45 | id = node.attributes['id'] 46 | else: 47 | index = 2 48 | slug = utils.idify(text) 49 | id = slug 50 | while id in self.ids: 51 | id = '%s-%s' % (slug, index) 52 | index += 1 53 | node.attributes['id'] = id 54 | self.ids.append(id) 55 | return dict(level=level, text=text, id=id, subs=[]) 56 | 57 | def _make_li_node(self, node): 58 | li = nodes.Node('li') 59 | li.append_child(nodes.TextNode('[%s](#%s)' % (node['text'], node['id']))) 60 | if node['subs']: 61 | ul = nodes.Node('ul') 62 | li.append_child(ul) 63 | for child in node['subs']: 64 | ul.append_child(self._make_li_node(child)) 65 | return li 66 | 67 | # Returns the table of contents as an unordered list. Skips over root-level 68 | # H1 headings. 69 | def toc(self): 70 | ul = nodes.Node('ul', {'class': 'stx-toc'}) 71 | for node in self.root['subs']: 72 | if node['level'] == 1: 73 | for subnode in node['subs']: 74 | ul.append_child(self._make_li_node(subnode)) 75 | else: 76 | ul.append_child(self._make_li_node(node)) 77 | return ul 78 | 79 | # Returns the table of contents as an unordered list. Includes root-level 80 | # H1 headings. 81 | def fulltoc(self): 82 | ul = nodes.Node('ul', {'class': 'stx-toc'}) 83 | for node in self.root['subs']: 84 | ul.append_child(self._make_li_node(node)) 85 | return ul 86 | -------------------------------------------------------------------------------- /syntext/utils.py: -------------------------------------------------------------------------------- 1 | # ------------------------------------------------------------------------------ 2 | # Utility functions and classes. 3 | # ------------------------------------------------------------------------------ 4 | 5 | import re 6 | import unicodedata 7 | import shutil 8 | 9 | 10 | # Deprecated error class. 11 | class Error(Exception): 12 | pass 13 | 14 | 15 | # Exception class for reporting errors. 16 | class SyntextError(Error): 17 | pass 18 | 19 | 20 | # Makes input text available as a stream of lines. Strips newlines. 21 | class LineStream: 22 | 23 | # A stream can be initialized with a string or a list of lines. 24 | def __init__(self, text=None): 25 | if isinstance(text, str): 26 | self.lines = [line.rstrip() for line in text.splitlines()] 27 | else: 28 | self.lines = text or [] 29 | self.index = 0 30 | 31 | def __str__(self): 32 | return '\n'.join(self.lines[self.index:]) 33 | 34 | def __len__(self): 35 | return len(self.lines) 36 | 37 | # Appends a line to the end of the stream. 38 | def append(self, line): 39 | self.lines.append(line) 40 | return self 41 | 42 | # Prepends a line to the beginning of the stream. 43 | def prepend(self, line): 44 | self.lines.insert(0, line) 45 | 46 | # Strips the common leading indent from all lines in the stream. 47 | def dedent(self): 48 | 49 | def countspaces(line): 50 | for index, char in enumerate(line): 51 | if char != ' ': 52 | return index 53 | 54 | mindent = min((countspaces(l) for l in self.lines if l), default=0) 55 | 56 | for index, line in enumerate(self.lines): 57 | if line: 58 | self.lines[index] = line[mindent:] 59 | 60 | return self 61 | 62 | # Indents all non-blank lines in the stream by n spaces. 63 | def indent(self, n=4): 64 | for index, line in enumerate(self.lines): 65 | if line: 66 | self.lines[index] = ' ' * n + line 67 | return self 68 | 69 | # Strips leading and trailing blank lines. 70 | def trim(self): 71 | while self.lines and self.lines[0] == '': 72 | self.lines.pop(0) 73 | while self.lines and self.lines[-1] == '': 74 | self.lines.pop() 75 | return self 76 | 77 | # Returns the next item in the stream without consuming it. 78 | def peek(self): 79 | return self.lines[self.index] 80 | 81 | # Consumes and returns the next item in the stream. 82 | def next(self): 83 | self.index += 1 84 | return self.lines[self.index - 1] 85 | 86 | # Rewinds the stream index by n lines. 87 | def rewind(self, n): 88 | self.index -= n 89 | 90 | # Returns true if the stream contains at least one more item. 91 | def has_next(self): 92 | return self.index < len(self.lines) 93 | 94 | # Returns true if the stream ends with one or more blank lines. 95 | def has_trailing_blank(self): 96 | if self.lines and self.lines[-1] == '': 97 | return True 98 | return False 99 | 100 | # Returns true if the stream contains at least one blank line. 101 | def contains_blank(self): 102 | for line in self.lines: 103 | if line == '': 104 | return True 105 | return False 106 | 107 | 108 | # Utility class for parsing argument strings. 109 | class ArgParser: 110 | 111 | args_regex = re.compile(r""" 112 | (?:([^\s'"=]+)=)? # an optional key, followed by... 113 | ( 114 | "((?:[^\\"]|\\.)*)" # a double-quoted value, or 115 | | 116 | '((?:[^\\']|\\.)*)' # a single-quoted value 117 | ) 118 | | 119 | ([^\s'"=]+)=(\S+) # a key followed by an unquoted value 120 | | 121 | (\S+) # an unkeyed, unquoted value 122 | """, re.VERBOSE) 123 | 124 | def parse(self, argstr): 125 | pargs, kwargs, classes = [], {}, [] 126 | 127 | # Parse the argument string into a list of positional and dictionary 128 | # of keyword arguments. 129 | for match in self.args_regex.finditer(argstr): 130 | if match.group(2) or match.group(5): 131 | key = match.group(1) or match.group(5) 132 | value = match.group(3) or match.group(4) or match.group(6) 133 | if match.group(3) or match.group(4): 134 | value = bytes(value, 'utf-8').decode('unicode_escape') 135 | if key: 136 | kwargs[key] = value 137 | else: 138 | pargs.append(value) 139 | else: 140 | pargs.append(match.group(7)) 141 | 142 | # Parse any .classes, #ids, or &attributes from the list of 143 | # positional arguments. 144 | for arg in pargs[:]: 145 | if arg.startswith('.'): 146 | classes.append(arg[1:]) 147 | pargs.remove(arg) 148 | if arg.startswith('#'): 149 | kwargs['id'] = arg[1:] 150 | pargs.remove(arg) 151 | if arg.startswith('&'): 152 | kwargs[arg.lstrip('&')] = None 153 | pargs.remove(arg) 154 | 155 | # Convert the classes list into a space-separated string. 156 | # We need to keep an eye out for a named 'class' attribute. 157 | if 'class' in kwargs: 158 | classes.extend(kwargs['class'].split()) 159 | if classes: 160 | kwargs['class'] = ' '.join(sorted(classes)) 161 | 162 | return pargs, kwargs 163 | 164 | 165 | # Formats title text for output on the command line. 166 | def title(text): 167 | cols, _ = shutil.get_terminal_size() 168 | line = '\u001B[90m' + '─' * cols + '\u001B[0m' 169 | return line + '\n' + text.center(cols) + '\n' + line 170 | 171 | 172 | # Strips all angle-bracket-enclosed substrings. 173 | def strip_tags(text): 174 | return re.sub(r'<[^>]*>', '', text) 175 | 176 | 177 | # Processes a string for use as an #id. 178 | def idify(s): 179 | s = unicodedata.normalize('NFKD', s) 180 | s = s.encode('ascii', 'ignore').decode('ascii') 181 | s = s.lower() 182 | s = s.replace("'", '') 183 | s = re.sub(r'&[#a-zA-Z0-9]+;', '-', s) 184 | s = re.sub(r'[^a-z0-9-]+', '-', s) 185 | s = re.sub(r'--+', '-', s).strip('-') 186 | s = re.sub(r'^(\d)', r'id-\1', s) 187 | return s or 'id' 188 | -------------------------------------------------------------------------------- /test_syntext.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # ------------------------------------------------------------------------------ 3 | # Unit tests for the syntext package. This is a custom test harness; to run the 4 | # tests just run this file directly. 5 | # ------------------------------------------------------------------------------ 6 | 7 | import syntext 8 | import os 9 | import sys 10 | 11 | 12 | # Path to the tests directory. 13 | testdir = os.path.join(os.path.dirname(__file__), 'unittests') 14 | 15 | 16 | # Load a file and return its content as a string. 17 | def load(filepath): 18 | with open(filepath, encoding='utf-8') as file: 19 | return file.read() 20 | 21 | 22 | # Load and render the suite of test-input files. 23 | def main(): 24 | oks, fails = 0, 0 25 | 26 | print(''' 27 | -------------------------------------------------------------------------------- 28 | Directory | File | Result 29 | -------------------------------------------------------------------------------- 30 | '''.strip()) 31 | 32 | directories = [dn for dn in os.listdir(testdir) if not dn.startswith('.')] 33 | directories.sort() 34 | for directory in directories: 35 | files = os.listdir(os.path.join(testdir, directory)) 36 | files = [fn for fn in files if fn.endswith('.txt')] 37 | for filename in sorted(files): 38 | textfile = os.path.join(testdir, directory, filename) 39 | htmlfile = textfile.replace('.txt', '.html') 40 | if os.path.isfile(htmlfile): 41 | text = load(textfile) 42 | html = load(htmlfile) 43 | if syntext.render(text).strip() == html.strip(): 44 | oks += 1 45 | result = 'ok' 46 | else: 47 | fails += 1 48 | result = 'fail' 49 | else: 50 | fails += 1 51 | result = '??????' 52 | output = ' ' 53 | output += directory.ljust(18) 54 | output += filename.replace('.txt', '').ljust(48) 55 | output += result.center(6) 56 | print(output) 57 | 58 | result = 'FAIL' if fails else 'OK' 59 | print('-' * 80) 60 | output = (' %s/%s' % (oks, oks + fails)).ljust(70) 61 | output += result.center(6) 62 | print(output) 63 | print('-' * 80) 64 | if fails: 65 | sys.exit(1) 66 | 67 | 68 | if __name__ == '__main__': 69 | main() 70 | -------------------------------------------------------------------------------- /unittests/blank/empty.html: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dmulholl/syntext/41187f7a5db9458c557d991357cb70dbfd85c18e/unittests/blank/empty.html -------------------------------------------------------------------------------- /unittests/blank/empty.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dmulholl/syntext/41187f7a5db9458c557d991357cb70dbfd85c18e/unittests/blank/empty.txt -------------------------------------------------------------------------------- /unittests/blank/newline.html: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dmulholl/syntext/41187f7a5db9458c557d991357cb70dbfd85c18e/unittests/blank/newline.html -------------------------------------------------------------------------------- /unittests/blank/newline.txt: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /unittests/blank/spaces-with-newline.html: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dmulholl/syntext/41187f7a5db9458c557d991357cb70dbfd85c18e/unittests/blank/spaces-with-newline.html -------------------------------------------------------------------------------- /unittests/blank/spaces-with-newline.txt: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /unittests/blank/spaces.html: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dmulholl/syntext/41187f7a5db9458c557d991357cb70dbfd85c18e/unittests/blank/spaces.html -------------------------------------------------------------------------------- /unittests/blank/spaces.txt: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /unittests/blocks/boxed-headings.html: -------------------------------------------------------------------------------- 1 |

2 | Heading 1 3 |

4 |

5 | Heading 2 6 |

7 | -------------------------------------------------------------------------------- /unittests/blocks/boxed-headings.txt: -------------------------------------------------------------------------------- 1 | # --------- # 2 | # Heading 1 # 3 | # --------- # 4 | 5 | # ========= # 6 | # Heading 2 # 7 | # ========= # 8 | 9 | -------------------------------------------------------------------------------- /unittests/blocks/dl.html: -------------------------------------------------------------------------------- 1 |
2 |
3 |
4 | Term 1 5 |
6 |
7 |

8 | This is the definition of the term. 9 |

10 |
11 |
12 |
13 |
14 | Term 2 15 |
16 |
17 |

18 | This is the definition of the term. 19 |

20 |
21 |
22 |
23 | -------------------------------------------------------------------------------- /unittests/blocks/dl.txt: -------------------------------------------------------------------------------- 1 | [[ Term 1 ]] 2 | 3 | This is the definition of the term. 4 | 5 | [[ Term 2 ]] 6 | 7 | This is the definition of the term. 8 | -------------------------------------------------------------------------------- /unittests/blocks/fancy-h1.html: -------------------------------------------------------------------------------- 1 |

2 | Heading Text 3 |

4 | 5 | -------------------------------------------------------------------------------- /unittests/blocks/fancy-h1.txt: -------------------------------------------------------------------------------- 1 | ------------------ 2 | # Heading Text # 3 | ------------------ 4 | 5 | -------------------------------------------------------------------------------- /unittests/blocks/fancy-h2.html: -------------------------------------------------------------------------------- 1 |

2 | Heading Text 3 |

4 | 5 | -------------------------------------------------------------------------------- /unittests/blocks/fancy-h2.txt: -------------------------------------------------------------------------------- 1 | -------------------- 2 | ## Heading Text ## 3 | -------------------- 4 | -------------------------------------------------------------------------------- /unittests/blocks/generic-block.html: -------------------------------------------------------------------------------- 1 | 2 |

3 | foo 4 |

5 |

6 | bar 7 | baz 8 |

9 |
10 | -------------------------------------------------------------------------------- /unittests/blocks/generic-block.txt: -------------------------------------------------------------------------------- 1 | :tag #tagid .class1 .class2 class="class3" &attr1 attr2="somevalue" 2 | foo 3 | 4 | bar 5 | baz 6 | -------------------------------------------------------------------------------- /unittests/blocks/headings-with-trailing-symbols.html: -------------------------------------------------------------------------------- 1 |

2 | H1 Heading 3 |

4 |

5 | H2 Heading 6 |

7 |

8 | H3 Heading 9 |

10 |

11 | H4 Heading 12 |

13 |
14 | H5 Heading 15 |
16 |
17 | H6 Heading 18 |
19 | -------------------------------------------------------------------------------- /unittests/blocks/headings-with-trailing-symbols.txt: -------------------------------------------------------------------------------- 1 | # H1 Heading # 2 | 3 | ## H2 Heading ## 4 | 5 | ### H3 Heading ### 6 | 7 | #### H4 Heading #### 8 | 9 | ##### H5 Heading ##### 10 | 11 | ###### H6 Heading ###### 12 | -------------------------------------------------------------------------------- /unittests/blocks/headings.html: -------------------------------------------------------------------------------- 1 |

2 | H1 Heading 3 |

4 |

5 | H2 Heading 6 |

7 |

8 | H3 Heading 9 |

10 |

11 | H4 Heading 12 |

13 |
14 | H5 Heading 15 |
16 |
17 | H6 Heading 18 |
19 | -------------------------------------------------------------------------------- /unittests/blocks/headings.txt: -------------------------------------------------------------------------------- 1 | # H1 Heading 2 | 3 | ## H2 Heading 4 | 5 | ### H3 Heading 6 | 7 | #### H4 Heading 8 | 9 | ##### H5 Heading 10 | 11 | ###### H6 Heading 12 | -------------------------------------------------------------------------------- /unittests/blocks/html-multi-line.html: -------------------------------------------------------------------------------- 1 |
2 |

bar

3 |
4 | -------------------------------------------------------------------------------- /unittests/blocks/html-multi-line.txt: -------------------------------------------------------------------------------- 1 |
2 |

bar

3 |
4 | -------------------------------------------------------------------------------- /unittests/blocks/html-single-line.html: -------------------------------------------------------------------------------- 1 |

bar

2 | -------------------------------------------------------------------------------- /unittests/blocks/html-single-line.txt: -------------------------------------------------------------------------------- 1 |

bar

2 | -------------------------------------------------------------------------------- /unittests/blocks/indented-code-with-blanks.html: -------------------------------------------------------------------------------- 1 |
2 | foo
3 | 
4 | bar
5 | 
6 | -------------------------------------------------------------------------------- /unittests/blocks/indented-code-with-blanks.txt: -------------------------------------------------------------------------------- 1 | foo 2 | 3 | bar 4 | -------------------------------------------------------------------------------- /unittests/blocks/indented-code-with-escapes.html: -------------------------------------------------------------------------------- 1 |
2 | <p>foo & bar</p>
3 | 
4 | -------------------------------------------------------------------------------- /unittests/blocks/indented-code-with-escapes.txt: -------------------------------------------------------------------------------- 1 |

foo & bar

2 | -------------------------------------------------------------------------------- /unittests/blocks/indented-code.html: -------------------------------------------------------------------------------- 1 |
2 | foo
3 | bar
4 | 
5 | -------------------------------------------------------------------------------- /unittests/blocks/indented-code.txt: -------------------------------------------------------------------------------- 1 | foo 2 | bar 3 | -------------------------------------------------------------------------------- /unittests/blocks/numeric-heading.html: -------------------------------------------------------------------------------- 1 |

2 | 1.2.3 3 |

4 | -------------------------------------------------------------------------------- /unittests/blocks/numeric-heading.txt: -------------------------------------------------------------------------------- 1 | # 1.2.3 2 | -------------------------------------------------------------------------------- /unittests/blocks/ol-block-nested-compact-ol.html: -------------------------------------------------------------------------------- 1 |
    2 |
  1. 3 |

    4 | foo 5 |

    6 |
      7 |
    1. 8 | baz 9 |
    2. 10 |
    3. 11 | bam 12 |
    4. 13 |
    14 |
  2. 15 |
  3. 16 |

    17 | bar 18 |

    19 |
  4. 20 |
21 | -------------------------------------------------------------------------------- /unittests/blocks/ol-block-nested-compact-ol.txt: -------------------------------------------------------------------------------- 1 | (#) foo 2 | 3 | #. baz 4 | #. bam 5 | 6 | (#) bar 7 | -------------------------------------------------------------------------------- /unittests/blocks/ol-block-paragraphs-multiple.html: -------------------------------------------------------------------------------- 1 |
    2 |
  1. 3 |

    4 | foo 5 |

    6 |
  2. 7 |
  3. 8 |

    9 | bar 10 |

    11 |

    12 | bam 13 |

    14 |
  4. 15 |
  5. 16 |

    17 | baz 18 |

    19 |
  6. 20 |
21 | -------------------------------------------------------------------------------- /unittests/blocks/ol-block-paragraphs-multiple.txt: -------------------------------------------------------------------------------- 1 | (#) foo 2 | 3 | (#) bar 4 | 5 | bam 6 | 7 | (#) baz 8 | 9 | -------------------------------------------------------------------------------- /unittests/blocks/ol-block-paragraphs.html: -------------------------------------------------------------------------------- 1 |
    2 |
  1. 3 |

    4 | foo 5 |

    6 |
  2. 7 |
  3. 8 |

    9 | bar 10 |

    11 |
  4. 12 |
  5. 13 |

    14 | baz 15 |

    16 |
  6. 17 |
18 | -------------------------------------------------------------------------------- /unittests/blocks/ol-block-paragraphs.txt: -------------------------------------------------------------------------------- 1 | (1) foo 2 | 3 | (2) bar 4 | 5 | (3) baz 6 | 7 | -------------------------------------------------------------------------------- /unittests/blocks/ol-compact-blanklines.html: -------------------------------------------------------------------------------- 1 |
    2 |
  1. 3 | foo 4 | 5 | bar 6 |
  2. 7 |
  3. 8 | baz 9 |
  4. 10 |
11 | -------------------------------------------------------------------------------- /unittests/blocks/ol-compact-blanklines.txt: -------------------------------------------------------------------------------- 1 | 1. foo 2 | 3 | bar 4 | 2. baz 5 | -------------------------------------------------------------------------------- /unittests/blocks/ol-compact-multiline.html: -------------------------------------------------------------------------------- 1 |
    2 |
  1. 3 | foo 4 | bar 5 |
  2. 6 |
  3. 7 | baz 8 |
  4. 9 |
10 | -------------------------------------------------------------------------------- /unittests/blocks/ol-compact-multiline.txt: -------------------------------------------------------------------------------- 1 | 1. foo 2 | bar 3 | 2. baz 4 | -------------------------------------------------------------------------------- /unittests/blocks/ol-compact-nested-ol.html: -------------------------------------------------------------------------------- 1 |
    2 |
  1. 3 | foo 4 |
      5 |
    1. 6 | baz 7 |
    2. 8 |
    3. 9 | bam 10 |
    4. 11 |
    12 |
  2. 13 |
  3. 14 | bar 15 |
  4. 16 |
17 | -------------------------------------------------------------------------------- /unittests/blocks/ol-compact-nested-ol.txt: -------------------------------------------------------------------------------- 1 | 1. foo 2 | 1. baz 3 | 2. bam 4 | 2. bar 5 | -------------------------------------------------------------------------------- /unittests/blocks/ol-marker-custom-start.html: -------------------------------------------------------------------------------- 1 |
    2 |
  1. 3 | foo 4 |
  2. 5 |
  3. 6 | bar 7 |
  4. 8 |
9 | -------------------------------------------------------------------------------- /unittests/blocks/ol-marker-custom-start.txt: -------------------------------------------------------------------------------- 1 | 2. foo 2 | 3. bar 3 | -------------------------------------------------------------------------------- /unittests/blocks/ol-marker-hash.html: -------------------------------------------------------------------------------- 1 |
    2 |
  1. 3 | foo 4 |
  2. 5 |
  3. 6 | bar 7 |
  4. 8 |
9 | -------------------------------------------------------------------------------- /unittests/blocks/ol-marker-hash.txt: -------------------------------------------------------------------------------- 1 | #. foo 2 | #. bar 3 | -------------------------------------------------------------------------------- /unittests/blocks/ol-marker-indented-1.html: -------------------------------------------------------------------------------- 1 |
    2 |
  1. 3 | foo 4 |
  2. 5 |
  3. 6 | bar 7 |
  4. 8 |
9 | -------------------------------------------------------------------------------- /unittests/blocks/ol-marker-indented-1.txt: -------------------------------------------------------------------------------- 1 | 1. foo 2 | 2. bar 3 | -------------------------------------------------------------------------------- /unittests/blocks/ol-marker-indented-2.html: -------------------------------------------------------------------------------- 1 |
    2 |
  1. 3 | foo 4 |
  2. 5 |
  3. 6 | bar 7 |
  4. 8 |
9 | -------------------------------------------------------------------------------- /unittests/blocks/ol-marker-indented-2.txt: -------------------------------------------------------------------------------- 1 | 1. foo 2 | 2. bar 3 | -------------------------------------------------------------------------------- /unittests/blocks/ol-marker-indented-3.html: -------------------------------------------------------------------------------- 1 |
    2 |
  1. 3 | foo 4 |
  2. 5 |
  3. 6 | bar 7 |
  4. 8 |
9 | -------------------------------------------------------------------------------- /unittests/blocks/ol-marker-indented-3.txt: -------------------------------------------------------------------------------- 1 | 1. foo 2 | 2. bar 3 | -------------------------------------------------------------------------------- /unittests/blocks/ol-marker-int.html: -------------------------------------------------------------------------------- 1 |
    2 |
  1. 3 | foo 4 |
  2. 5 |
  3. 6 | bar 7 |
  4. 8 |
9 | -------------------------------------------------------------------------------- /unittests/blocks/ol-marker-int.txt: -------------------------------------------------------------------------------- 1 | 1. foo 2 | 2. bar 3 | -------------------------------------------------------------------------------- /unittests/blocks/paragraph-multiline.html: -------------------------------------------------------------------------------- 1 |

2 | foo 3 | bar 4 |

5 | -------------------------------------------------------------------------------- /unittests/blocks/paragraph-multiline.txt: -------------------------------------------------------------------------------- 1 | foo 2 | bar 3 | -------------------------------------------------------------------------------- /unittests/blocks/paragraph-multiple.html: -------------------------------------------------------------------------------- 1 |

2 | foo 3 |

4 |

5 | bar 6 |

7 | -------------------------------------------------------------------------------- /unittests/blocks/paragraph-multiple.txt: -------------------------------------------------------------------------------- 1 | foo 2 | 3 | bar 4 | -------------------------------------------------------------------------------- /unittests/blocks/paragraph-single.html: -------------------------------------------------------------------------------- 1 |

2 | foo 3 |

4 | -------------------------------------------------------------------------------- /unittests/blocks/paragraph-single.txt: -------------------------------------------------------------------------------- 1 | foo 2 | -------------------------------------------------------------------------------- /unittests/blocks/ul-block-nested-compact-ul.html: -------------------------------------------------------------------------------- 1 |
    2 |
  • 3 |

    4 | foo 5 |

    6 |
      7 |
    • 8 | baz 9 |
    • 10 |
    • 11 | bam 12 |
    • 13 |
    14 |
  • 15 |
  • 16 |

    17 | bar 18 |

    19 |
  • 20 |
21 | -------------------------------------------------------------------------------- /unittests/blocks/ul-block-nested-compact-ul.txt: -------------------------------------------------------------------------------- 1 | (*) foo 2 | 3 | * baz 4 | * bam 5 | 6 | (*) bar 7 | -------------------------------------------------------------------------------- /unittests/blocks/ul-block-paragraphs-multiple.html: -------------------------------------------------------------------------------- 1 |
    2 |
  • 3 |

    4 | foo 5 |

    6 |
  • 7 |
  • 8 |

    9 | bar 10 |

    11 |

    12 | bam 13 |

    14 |
  • 15 |
  • 16 |

    17 | baz 18 |

    19 |
  • 20 |
21 | -------------------------------------------------------------------------------- /unittests/blocks/ul-block-paragraphs-multiple.txt: -------------------------------------------------------------------------------- 1 | (*) foo 2 | 3 | (*) bar 4 | 5 | bam 6 | 7 | (*) baz 8 | -------------------------------------------------------------------------------- /unittests/blocks/ul-block-paragraphs.html: -------------------------------------------------------------------------------- 1 |
    2 |
  • 3 |

    4 | foo 5 |

    6 |
  • 7 |
  • 8 |

    9 | bar 10 |

    11 |
  • 12 |
  • 13 |

    14 | baz 15 |

    16 |
  • 17 |
18 | -------------------------------------------------------------------------------- /unittests/blocks/ul-block-paragraphs.txt: -------------------------------------------------------------------------------- 1 | (*) foo 2 | 3 | (*) bar 4 | 5 | (*) baz 6 | -------------------------------------------------------------------------------- /unittests/blocks/ul-compact-blanklines.html: -------------------------------------------------------------------------------- 1 |
    2 |
  • 3 | foo 4 | 5 | bar 6 |
  • 7 |
  • 8 | baz 9 |
  • 10 |
11 | -------------------------------------------------------------------------------- /unittests/blocks/ul-compact-blanklines.txt: -------------------------------------------------------------------------------- 1 | * foo 2 | 3 | bar 4 | * baz 5 | -------------------------------------------------------------------------------- /unittests/blocks/ul-compact-multiline.html: -------------------------------------------------------------------------------- 1 |
    2 |
  • 3 | foo 4 | bar 5 |
  • 6 |
  • 7 | baz 8 |
  • 9 |
10 | -------------------------------------------------------------------------------- /unittests/blocks/ul-compact-multiline.txt: -------------------------------------------------------------------------------- 1 | * foo 2 | bar 3 | * baz 4 | -------------------------------------------------------------------------------- /unittests/blocks/ul-compact-nested-ul.html: -------------------------------------------------------------------------------- 1 |
    2 |
  • 3 | foo 4 |
      5 |
    • 6 | baz 7 |
    • 8 |
    • 9 | bam 10 |
    • 11 |
    12 |
  • 13 |
  • 14 | bar 15 |
  • 16 |
17 | -------------------------------------------------------------------------------- /unittests/blocks/ul-compact-nested-ul.txt: -------------------------------------------------------------------------------- 1 | * foo 2 | * baz 3 | * bam 4 | * bar 5 | -------------------------------------------------------------------------------- /unittests/blocks/ul-marker-asterisk.html: -------------------------------------------------------------------------------- 1 |
    2 |
  • 3 | foo 4 |
  • 5 |
  • 6 | bar 7 |
  • 8 |
9 | -------------------------------------------------------------------------------- /unittests/blocks/ul-marker-asterisk.txt: -------------------------------------------------------------------------------- 1 | * foo 2 | * bar 3 | -------------------------------------------------------------------------------- /unittests/blocks/ul-marker-bullet.html: -------------------------------------------------------------------------------- 1 |
    2 |
  • 3 | foo 4 |
  • 5 |
  • 6 | bar 7 |
  • 8 |
9 | -------------------------------------------------------------------------------- /unittests/blocks/ul-marker-bullet.txt: -------------------------------------------------------------------------------- 1 | • foo 2 | • bar 3 | -------------------------------------------------------------------------------- /unittests/blocks/ul-marker-change.html: -------------------------------------------------------------------------------- 1 |
    2 |
  • 3 | foo 4 |
  • 5 |
  • 6 | bar 7 |
  • 8 |
9 |
    10 |
  • 11 | baz 12 |
  • 13 |
  • 14 | bam 15 |
  • 16 |
17 | -------------------------------------------------------------------------------- /unittests/blocks/ul-marker-change.txt: -------------------------------------------------------------------------------- 1 | * foo 2 | * bar 3 | + baz 4 | + bam 5 | -------------------------------------------------------------------------------- /unittests/blocks/ul-marker-dash.html: -------------------------------------------------------------------------------- 1 |
    2 |
  • 3 | foo 4 |
  • 5 |
  • 6 | bar 7 |
  • 8 |
9 | -------------------------------------------------------------------------------- /unittests/blocks/ul-marker-dash.txt: -------------------------------------------------------------------------------- 1 | - foo 2 | - bar 3 | -------------------------------------------------------------------------------- /unittests/blocks/ul-marker-indented-1.html: -------------------------------------------------------------------------------- 1 |
    2 |
  • 3 | foo 4 |
  • 5 |
  • 6 | bar 7 |
  • 8 |
9 | -------------------------------------------------------------------------------- /unittests/blocks/ul-marker-indented-1.txt: -------------------------------------------------------------------------------- 1 | * foo 2 | * bar 3 | -------------------------------------------------------------------------------- /unittests/blocks/ul-marker-indented-2.html: -------------------------------------------------------------------------------- 1 |
    2 |
  • 3 | foo 4 |
  • 5 |
  • 6 | bar 7 |
  • 8 |
9 | -------------------------------------------------------------------------------- /unittests/blocks/ul-marker-indented-2.txt: -------------------------------------------------------------------------------- 1 | * foo 2 | * bar 3 | -------------------------------------------------------------------------------- /unittests/blocks/ul-marker-indented-3.html: -------------------------------------------------------------------------------- 1 |
    2 |
  • 3 | foo 4 |
  • 5 |
  • 6 | bar 7 |
  • 8 |
9 | -------------------------------------------------------------------------------- /unittests/blocks/ul-marker-indented-3.txt: -------------------------------------------------------------------------------- 1 | * foo 2 | * bar 3 | -------------------------------------------------------------------------------- /unittests/blocks/ul-marker-plus.html: -------------------------------------------------------------------------------- 1 |
    2 |
  • 3 | foo 4 |
  • 5 |
  • 6 | bar 7 |
  • 8 |
9 | -------------------------------------------------------------------------------- /unittests/blocks/ul-marker-plus.txt: -------------------------------------------------------------------------------- 1 | + foo 2 | + bar 3 | -------------------------------------------------------------------------------- /unittests/blocks/ul-plus.html: -------------------------------------------------------------------------------- 1 |
    2 |
  • 3 | foo 4 |
  • 5 |
  • 6 | bar 7 |
  • 8 |
9 | -------------------------------------------------------------------------------- /unittests/compound/autofootnotes.html: -------------------------------------------------------------------------------- 1 |

2 | This line contains a footnote.1 3 |

4 |

5 | This line contains a footnote 2. 6 |

7 |
8 |
9 |
10 | 11 | 1 12 | 13 |
14 |
15 |

16 | This is footnote 1. 17 |

18 |
19 |
20 |
21 |
22 | 23 | 2 24 | 25 |
26 |
27 |

28 | This footnote has two paragraphs. 29 | This is the first. 30 |

31 |

32 | And this is the second. 33 |

34 |
35 |
36 |
37 | -------------------------------------------------------------------------------- /unittests/compound/autofootnotes.txt: -------------------------------------------------------------------------------- 1 | This line contains a footnote.[^] 2 | 3 | This line contains a footnote [fn]. 4 | 5 | ::: insert footnotes ::: 6 | 7 | ::: footnote 1 8 | This is footnote 1. 9 | ::: end 10 | 11 | ::: footnote 2 12 | This footnote has two paragraphs. 13 | This is the first. 14 | 15 | And this is the second. 16 | ::: end 17 | -------------------------------------------------------------------------------- /unittests/compound/footnotes.html: -------------------------------------------------------------------------------- 1 |

2 | This line contains a footnote.1 3 |

4 |

5 | This line contains a footnote 2. 6 |

7 |
8 |
9 |
10 | 11 | 1 12 | 13 |
14 |
15 |

16 | This is footnote 1. 17 |

18 |
19 |
20 |
21 |
22 | 23 | 2 24 | 25 |
26 |
27 |

28 | This footnote has two paragraphs. 29 | This is the first. 30 |

31 |

32 | And this is the second. 33 |

34 |
35 |
36 |
37 | -------------------------------------------------------------------------------- /unittests/compound/footnotes.txt: -------------------------------------------------------------------------------- 1 | This line contains a footnote.[^1] 2 | 3 | This line contains a footnote [fn:2]. 4 | 5 | ::: insert footnotes ::: 6 | 7 | ::: footnote 1 8 | This is footnote 1. 9 | ::: end 10 | 11 | ::: footnote 2 12 | This footnote has two paragraphs. 13 | This is the first. 14 | 15 | And this is the second. 16 | ::: end 17 | -------------------------------------------------------------------------------- /unittests/compound/fulltoc.html: -------------------------------------------------------------------------------- 1 | 22 |

23 | H1 Header 24 |

25 |

26 | H2 Header I 27 |

28 |

29 | H3 Header I 30 |

31 |

32 | H3 Header II 33 |

34 |

35 | H2 Header II 36 |

37 | -------------------------------------------------------------------------------- /unittests/compound/fulltoc.txt: -------------------------------------------------------------------------------- 1 | ::: insert fulltoc ::: 2 | 3 | # H1 Header 4 | 5 | ## H2 Header I 6 | 7 | ### H3 Header I 8 | 9 | ### H3 Header II 10 | 11 | ## H2 Header II 12 | -------------------------------------------------------------------------------- /unittests/compound/linked-image.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /unittests/compound/linked-image.txt: -------------------------------------------------------------------------------- 1 | :a href=http://example.com/link 2 | :img src=http://example.com/image 3 | -------------------------------------------------------------------------------- /unittests/compound/links.html: -------------------------------------------------------------------------------- 1 |

2 | This paragraph contains a link. 3 |

4 |

5 | This link has a title. 6 |

7 |

8 | Here's a reference link. 9 |

10 |

11 | This is a reference link too. 12 |

13 |

14 | This reference link has a title. 15 |

16 |

17 | The case of the reference is not important. 18 |

19 |

20 | The case of the reference is not IMPORTANT. 21 |

22 | -------------------------------------------------------------------------------- /unittests/compound/links.txt: -------------------------------------------------------------------------------- 1 | This paragraph contains a [link](http://example.com). 2 | 3 | This link has [a title](http://example.com). 4 | 5 | Here's a reference [link][1]. 6 | 7 | This is a [reference][] link too. 8 | 9 | This reference [link][with title] has a title. 10 | 11 | The case of the reference is not [important][CAPSREF]. 12 | 13 | The case of the reference is not [IMPORTANT][]. 14 | 15 | [1]: http://example.com 16 | [reference]: http://example.com 17 | [with title]: 18 | http://example.com 19 | link title 20 | [capsref]: http://example.com 21 | [ImpoRTanT]: http://example.com 22 | -------------------------------------------------------------------------------- /unittests/compound/toc.html: -------------------------------------------------------------------------------- 1 | 17 |

18 | H1 Header 19 |

20 |

21 | H2 Header I 22 |

23 |

24 | H3 Header I 25 |

26 |

27 | H3 Header II 28 |

29 |

30 | H2 Header II 31 |

32 | -------------------------------------------------------------------------------- /unittests/compound/toc.txt: -------------------------------------------------------------------------------- 1 | ::: insert toc ::: 2 | 3 | # H1 Header 4 | 5 | ## H2 Header I 6 | 7 | ### H3 Header I 8 | 9 | ### H3 Header II 10 | 11 | ## H2 Header II 12 | -------------------------------------------------------------------------------- /unittests/inline/adjacent-footnotes.html: -------------------------------------------------------------------------------- 1 |

2 | foo12 3 |

4 | -------------------------------------------------------------------------------- /unittests/inline/adjacent-footnotes.txt: -------------------------------------------------------------------------------- 1 | foo[^1][^2] 2 | -------------------------------------------------------------------------------- /unittests/inline/backticks-escaping-formatting.html: -------------------------------------------------------------------------------- 1 |

2 | foo foo *baz* bar bar 3 |

4 | -------------------------------------------------------------------------------- /unittests/inline/backticks-escaping-formatting.txt: -------------------------------------------------------------------------------- 1 | foo `foo *baz* bar` bar 2 | -------------------------------------------------------------------------------- /unittests/inline/backticks-escaping-html.html: -------------------------------------------------------------------------------- 1 |

2 | foo foo <div> bar bar 3 |

4 | -------------------------------------------------------------------------------- /unittests/inline/backticks-escaping-html.txt: -------------------------------------------------------------------------------- 1 | foo `foo
bar` bar 2 | -------------------------------------------------------------------------------- /unittests/inline/backticks.html: -------------------------------------------------------------------------------- 1 |

2 | foo foo bar bar 3 |

4 | -------------------------------------------------------------------------------- /unittests/inline/backticks.txt: -------------------------------------------------------------------------------- 1 | foo `foo bar` bar 2 | -------------------------------------------------------------------------------- /unittests/inline/bold-italic.html: -------------------------------------------------------------------------------- 1 |

2 | foo foo bar bar 3 | foo x bar 4 | a b 5 |

6 | -------------------------------------------------------------------------------- /unittests/inline/bold-italic.txt: -------------------------------------------------------------------------------- 1 | foo ***foo bar*** bar 2 | foo ***x*** bar 3 | ***a*** ***b*** 4 | -------------------------------------------------------------------------------- /unittests/inline/bold.html: -------------------------------------------------------------------------------- 1 |

2 | foo foo bar bar 3 | foo x bar 4 | a b 5 |

6 | -------------------------------------------------------------------------------- /unittests/inline/bold.txt: -------------------------------------------------------------------------------- 1 | foo **foo bar** bar 2 | foo **x** bar 3 | **a** **b** 4 | -------------------------------------------------------------------------------- /unittests/inline/bracketed-url.html: -------------------------------------------------------------------------------- 1 |

2 | http://example.com 3 |

4 | -------------------------------------------------------------------------------- /unittests/inline/bracketed-url.txt: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /unittests/inline/footnote-autonumbered.html: -------------------------------------------------------------------------------- 1 |

2 | 1 3 |

4 |

5 | 2 6 |

7 |

8 | 3 9 |

10 | -------------------------------------------------------------------------------- /unittests/inline/footnote-autonumbered.txt: -------------------------------------------------------------------------------- 1 | [^] 2 | 3 | [fn] 4 | 5 | [^] 6 | -------------------------------------------------------------------------------- /unittests/inline/footnote.html: -------------------------------------------------------------------------------- 1 |

2 | 123 3 |

4 |

5 | 456 6 |

7 | -------------------------------------------------------------------------------- /unittests/inline/footnote.txt: -------------------------------------------------------------------------------- 1 | [^123] 2 | 3 | [fn:456] 4 | -------------------------------------------------------------------------------- /unittests/inline/html-entities.html: -------------------------------------------------------------------------------- 1 |

2 | © 3 |

4 | -------------------------------------------------------------------------------- /unittests/inline/html-entities.txt: -------------------------------------------------------------------------------- 1 | © 2 | -------------------------------------------------------------------------------- /unittests/inline/html-special-chars.html: -------------------------------------------------------------------------------- 1 |

2 | foo < bar > baz 3 |

4 |

5 | foo & bar 6 |

7 | -------------------------------------------------------------------------------- /unittests/inline/html-special-chars.txt: -------------------------------------------------------------------------------- 1 | foo < bar > baz 2 | 3 | foo & bar -------------------------------------------------------------------------------- /unittests/inline/html.html: -------------------------------------------------------------------------------- 1 |

2 | foo bar baz 3 |

4 | -------------------------------------------------------------------------------- /unittests/inline/html.txt: -------------------------------------------------------------------------------- 1 | foo bar baz 2 | -------------------------------------------------------------------------------- /unittests/inline/image.html: -------------------------------------------------------------------------------- 1 |

2 | alt text 3 |

4 | -------------------------------------------------------------------------------- /unittests/inline/image.txt: -------------------------------------------------------------------------------- 1 | ![alt text](http://example.com) 2 | -------------------------------------------------------------------------------- /unittests/inline/italic.html: -------------------------------------------------------------------------------- 1 |

2 | foo foo bar bar 3 | foo x bar 4 | a b 5 |

6 | -------------------------------------------------------------------------------- /unittests/inline/italic.txt: -------------------------------------------------------------------------------- 1 | foo *foo bar* bar 2 | foo *x* bar 3 | *a* *b* 4 | -------------------------------------------------------------------------------- /unittests/inline/link-followed-by-bracket.html: -------------------------------------------------------------------------------- 1 |

2 | foo link text (bar baz) bam 3 |

4 | -------------------------------------------------------------------------------- /unittests/inline/link-followed-by-bracket.txt: -------------------------------------------------------------------------------- 1 | foo [link text](http://example.com) (bar baz) bam 2 | -------------------------------------------------------------------------------- /unittests/inline/link-in-bracket.html: -------------------------------------------------------------------------------- 1 |

2 | foo (bar link text baz) bam 3 |

4 | -------------------------------------------------------------------------------- /unittests/inline/link-in-bracket.txt: -------------------------------------------------------------------------------- 1 | foo (bar [link text](http://example.com) baz) bam 2 | -------------------------------------------------------------------------------- /unittests/inline/link.html: -------------------------------------------------------------------------------- 1 |

2 | text 3 |

4 | -------------------------------------------------------------------------------- /unittests/inline/link.txt: -------------------------------------------------------------------------------- 1 | [text](http://example.com) 2 | -------------------------------------------------------------------------------- /unittests/inline/mdash.html: -------------------------------------------------------------------------------- 1 |

2 | — foo — bar — 3 |

4 |

5 | —foo—bar— 6 |

7 | -------------------------------------------------------------------------------- /unittests/inline/mdash.txt: -------------------------------------------------------------------------------- 1 | --- foo --- bar --- 2 | 3 | ---foo---bar--- 4 | -------------------------------------------------------------------------------- /unittests/inline/ndash.html: -------------------------------------------------------------------------------- 1 |

2 | – foo – bar – 3 |

4 |

5 | –foo–bar– 6 |

7 | -------------------------------------------------------------------------------- /unittests/inline/ndash.txt: -------------------------------------------------------------------------------- 1 | -- foo -- bar -- 2 | 3 | --foo--bar-- 4 | -------------------------------------------------------------------------------- /unittests/inline/ref-image-fallback-alt.html: -------------------------------------------------------------------------------- 1 |

2 | alt text 3 |

4 | -------------------------------------------------------------------------------- /unittests/inline/ref-image-fallback-alt.txt: -------------------------------------------------------------------------------- 1 | ![alt text][] 2 | 3 | [alt text]: http://example.com 4 | -------------------------------------------------------------------------------- /unittests/inline/ref-image-no-ref.html: -------------------------------------------------------------------------------- 1 |

2 | alt text 3 |

4 | -------------------------------------------------------------------------------- /unittests/inline/ref-image-no-ref.txt: -------------------------------------------------------------------------------- 1 | ![alt text][] 2 | -------------------------------------------------------------------------------- /unittests/inline/ref-image-with-title.html: -------------------------------------------------------------------------------- 1 |

2 | alt text 3 |

4 | -------------------------------------------------------------------------------- /unittests/inline/ref-image-with-title.txt: -------------------------------------------------------------------------------- 1 | ![alt text][ref] 2 | 3 | [ref]: http://example.com 4 | title text 5 | -------------------------------------------------------------------------------- /unittests/inline/ref-image.html: -------------------------------------------------------------------------------- 1 |

2 | alt text 3 |

4 | -------------------------------------------------------------------------------- /unittests/inline/ref-image.txt: -------------------------------------------------------------------------------- 1 | ![alt text][ref] 2 | 3 | [ref]: http://example.com 4 | -------------------------------------------------------------------------------- /unittests/inline/ref-link-fallback-text.html: -------------------------------------------------------------------------------- 1 |

2 | link text 3 |

4 | -------------------------------------------------------------------------------- /unittests/inline/ref-link-fallback-text.txt: -------------------------------------------------------------------------------- 1 | [link text][] 2 | 3 | [link text]: http://example.com 4 | -------------------------------------------------------------------------------- /unittests/inline/ref-link-no-ref.html: -------------------------------------------------------------------------------- 1 |

2 | link text 3 |

4 | -------------------------------------------------------------------------------- /unittests/inline/ref-link-no-ref.txt: -------------------------------------------------------------------------------- 1 | [link text][] 2 | -------------------------------------------------------------------------------- /unittests/inline/ref-link-with-title.html: -------------------------------------------------------------------------------- 1 |

2 | link text 3 |

4 | -------------------------------------------------------------------------------- /unittests/inline/ref-link-with-title.txt: -------------------------------------------------------------------------------- 1 | [link text][ref] 2 | 3 | [ref]: http://example.com 4 | title text 5 | -------------------------------------------------------------------------------- /unittests/inline/ref-link.html: -------------------------------------------------------------------------------- 1 |

2 | link text 3 |

4 | -------------------------------------------------------------------------------- /unittests/inline/ref-link.txt: -------------------------------------------------------------------------------- 1 | [link text][ref] 2 | 3 | [ref]: http://example.com 4 | -------------------------------------------------------------------------------- /unittests/inline/subscripts.html: -------------------------------------------------------------------------------- 1 |

2 | H2O 3 |

4 | -------------------------------------------------------------------------------- /unittests/inline/subscripts.txt: -------------------------------------------------------------------------------- 1 | H_{2}O 2 | -------------------------------------------------------------------------------- /unittests/inline/superscripts.html: -------------------------------------------------------------------------------- 1 |

2 | x2 3 |

4 | -------------------------------------------------------------------------------- /unittests/inline/superscripts.txt: -------------------------------------------------------------------------------- 1 | x^{2} 2 | -------------------------------------------------------------------------------- /unittests/inline/verbatim.html: -------------------------------------------------------------------------------- 1 |

2 | **foo** 3 |

4 |

5 | -`foo`- 6 |

7 | -------------------------------------------------------------------------------- /unittests/inline/verbatim.txt: -------------------------------------------------------------------------------- 1 | ``**foo**`` 2 | 3 | ``-`foo`-`` 4 | -------------------------------------------------------------------------------- /unittests/shorthand/a.html: -------------------------------------------------------------------------------- 1 | 2 | foobar 3 | 4 | -------------------------------------------------------------------------------- /unittests/shorthand/a.txt: -------------------------------------------------------------------------------- 1 | :a href=http://www.example.com 2 | foobar 3 | -------------------------------------------------------------------------------- /unittests/shorthand/blockquote.html: -------------------------------------------------------------------------------- 1 |
2 |

3 | foo 4 |

5 |
6 | -------------------------------------------------------------------------------- /unittests/shorthand/blockquote.txt: -------------------------------------------------------------------------------- 1 | :blockquote 2 | foo 3 | -------------------------------------------------------------------------------- /unittests/shorthand/div.html: -------------------------------------------------------------------------------- 1 |
2 |

3 | foo 4 |

5 |
6 | -------------------------------------------------------------------------------- /unittests/shorthand/div.txt: -------------------------------------------------------------------------------- 1 | :div 2 | foo 3 | -------------------------------------------------------------------------------- /unittests/shorthand/hr.html: -------------------------------------------------------------------------------- 1 |
2 | -------------------------------------------------------------------------------- /unittests/shorthand/hr.txt: -------------------------------------------------------------------------------- 1 | :hr 2 | This content should be ignored. 3 | -------------------------------------------------------------------------------- /unittests/shorthand/img.html: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /unittests/shorthand/img.txt: -------------------------------------------------------------------------------- 1 | :img src=http://example.com 2 | -------------------------------------------------------------------------------- /unittests/shorthand/nl2br.html: -------------------------------------------------------------------------------- 1 |

2 | foo
3 | bar
4 |
5 | baz 6 |

7 |
8 |

9 | foo
10 | bar 11 |

12 |
13 |
14 |

15 | foo
16 |
17 | bar 18 |

19 |
20 | -------------------------------------------------------------------------------- /unittests/shorthand/nl2br.txt: -------------------------------------------------------------------------------- 1 | :p nl2br 2 | foo 3 | bar 4 | 5 | baz 6 | 7 | :div nl2br 8 | :p 9 | foo 10 | bar 11 | 12 | :div nl2br 13 | :p 14 | foo 15 | 16 | bar 17 | -------------------------------------------------------------------------------- /unittests/shorthand/p.html: -------------------------------------------------------------------------------- 1 |

2 | foo 3 |

4 |

5 | foo 6 | bar 7 |

8 |

9 | foo 10 | 11 | bar 12 |

13 | -------------------------------------------------------------------------------- /unittests/shorthand/p.txt: -------------------------------------------------------------------------------- 1 | :p 2 | foo 3 | 4 | :p 5 | foo 6 | bar 7 | 8 | :p 9 | foo 10 | 11 | bar 12 | 13 | -------------------------------------------------------------------------------- /unittests/shorthand/pre.html: -------------------------------------------------------------------------------- 1 |
2 | foobar
3 | 
4 | -------------------------------------------------------------------------------- /unittests/shorthand/pre.txt: -------------------------------------------------------------------------------- 1 | :pre raw 2 | foobar 3 | -------------------------------------------------------------------------------- /unittests/shorthand/raw.html: -------------------------------------------------------------------------------- 1 |
2 | :p 3 | This is *not* a paragraph. 4 |
5 |

6 | * foo 7 | * bar 8 |

9 | -------------------------------------------------------------------------------- /unittests/shorthand/raw.txt: -------------------------------------------------------------------------------- 1 | :div .raw-div raw 2 | :p 3 | This is *not* a paragraph. 4 | 5 | :p raw 6 | * foo 7 | * bar 8 | -------------------------------------------------------------------------------- /unittests/shorthand/script.html: -------------------------------------------------------------------------------- 1 | 4 | -------------------------------------------------------------------------------- /unittests/shorthand/script.txt: -------------------------------------------------------------------------------- 1 | :script 2 | 3 | -------------------------------------------------------------------------------- /unittests/shorthand/span.html: -------------------------------------------------------------------------------- 1 | 2 | foobar 3 | 4 | -------------------------------------------------------------------------------- /unittests/shorthand/span.txt: -------------------------------------------------------------------------------- 1 | :span 2 | foobar 3 | -------------------------------------------------------------------------------- /unittests/shorthand/style.html: -------------------------------------------------------------------------------- 1 | 4 | -------------------------------------------------------------------------------- /unittests/shorthand/style.txt: -------------------------------------------------------------------------------- 1 | :style 2 | 3 | -------------------------------------------------------------------------------- /unittests/tables/alignment.html: -------------------------------------------------------------------------------- 1 |
2 | 3 | 4 | 7 | 10 | 13 | 14 | 15 | 16 | 17 | 20 | 23 | 26 | 27 | 28 | 31 | 34 | 37 | 38 | 39 |
5 | foo 6 | 8 | bar 9 | 11 | baz 12 |
18 | aaa 19 | 21 | bbb 22 | 24 | ccc 25 |
29 | ddd 30 | 32 | eee 33 | 35 | fff 36 |
40 | -------------------------------------------------------------------------------- /unittests/tables/alignment.txt: -------------------------------------------------------------------------------- 1 | ::: table 2 | 3 | foo | bar | baz 4 | :-- | :-: | --: 5 | aaa | bbb | ccc 6 | ddd | eee | fff 7 | 8 | ::: end 9 | 10 | -------------------------------------------------------------------------------- /unittests/tables/header-and-footer-boxed.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 7 | 10 | 13 | 14 | 15 | 16 | 17 | 20 | 23 | 26 | 27 | 28 | 29 | 30 | 33 | 36 | 39 | 40 | 41 | 44 | 47 | 50 | 51 | 52 |
5 | foo 6 | 8 | bar 9 | 11 | baz 12 |
18 | oof 19 | 21 | rab 22 | 24 | zab 25 |
31 | aaa 32 | 34 | bbb 35 | 37 | ccc 38 |
42 | ddd 43 | 45 | eee 46 | 48 | fff 49 |
53 | -------------------------------------------------------------------------------- /unittests/tables/header-and-footer-boxed.txt: -------------------------------------------------------------------------------- 1 | ::: table 2 | 3 | ------------------- 4 | | foo | bar | baz | 5 | ------------------- 6 | | aaa | bbb | ccc | 7 | | ddd | eee | fff | 8 | ------------------- 9 | | oof | rab | zab | 10 | ------------------- 11 | 12 | ::: end 13 | 14 | -------------------------------------------------------------------------------- /unittests/tables/header-and-footer.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 7 | 10 | 13 | 14 | 15 | 16 | 17 | 20 | 23 | 26 | 27 | 28 | 29 | 30 | 33 | 36 | 39 | 40 | 41 | 44 | 47 | 50 | 51 | 52 |
5 | foo 6 | 8 | bar 9 | 11 | baz 12 |
18 | oof 19 | 21 | rab 22 | 24 | zab 25 |
31 | aaa 32 | 34 | bbb 35 | 37 | ccc 38 |
42 | ddd 43 | 45 | eee 46 | 48 | fff 49 |
53 | -------------------------------------------------------------------------------- /unittests/tables/header-and-footer.txt: -------------------------------------------------------------------------------- 1 | ::: table 2 | 3 | foo | bar | baz 4 | --------------- 5 | aaa | bbb | ccc 6 | ddd | eee | fff 7 | --------------- 8 | oof | rab | zab 9 | 10 | ::: end 11 | 12 | -------------------------------------------------------------------------------- /unittests/tables/no-header-no-footer-boxed.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 7 | 10 | 13 | 14 | 15 | 18 | 21 | 24 | 25 | 26 |
5 | aaa 6 | 8 | bbb 9 | 11 | ccc 12 |
16 | ddd 17 | 19 | eee 20 | 22 | fff 23 |
27 | -------------------------------------------------------------------------------- /unittests/tables/no-header-no-footer-boxed.txt: -------------------------------------------------------------------------------- 1 | ::: table 2 | 3 | ------------------- 4 | | aaa | bbb | ccc | 5 | | ddd | eee | fff | 6 | ------------------- 7 | 8 | ::: end 9 | 10 | -------------------------------------------------------------------------------- /unittests/tables/no-header-no-footer.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 7 | 10 | 13 | 14 | 15 | 18 | 21 | 24 | 25 | 26 |
5 | aaa 6 | 8 | bbb 9 | 11 | ccc 12 |
16 | ddd 17 | 19 | eee 20 | 22 | fff 23 |
27 | -------------------------------------------------------------------------------- /unittests/tables/no-header-no-footer.txt: -------------------------------------------------------------------------------- 1 | ::: table 2 | 3 | aaa | bbb | ccc 4 | ddd | eee | fff 5 | 6 | ::: end 7 | 8 | -------------------------------------------------------------------------------- /unittests/tags/code.html: -------------------------------------------------------------------------------- 1 |

2 | <escaped text>
3 | 
4 | -------------------------------------------------------------------------------- /unittests/tags/code.txt: -------------------------------------------------------------------------------- 1 | ::: code foo 2 | 3 | ::: end 4 | 5 | -------------------------------------------------------------------------------- /unittests/tags/comment.html: -------------------------------------------------------------------------------- 1 | 5 | -------------------------------------------------------------------------------- /unittests/tags/comment.txt: -------------------------------------------------------------------------------- 1 | ::: comment 2 | foo bar 3 | baz 4 | ::: end 5 | 6 | -------------------------------------------------------------------------------- /unittests/tags/div.html: -------------------------------------------------------------------------------- 1 |
2 |

3 | foo bar 4 |

5 |
6 | 7 | -------------------------------------------------------------------------------- /unittests/tags/div.txt: -------------------------------------------------------------------------------- 1 | ::: div .foo .bar #baz 2 | foo bar 3 | ::: end 4 | -------------------------------------------------------------------------------- /unittests/tags/hr.html: -------------------------------------------------------------------------------- 1 |
2 | -------------------------------------------------------------------------------- /unittests/tags/hr.txt: -------------------------------------------------------------------------------- 1 | ::: ---- ::: 2 | -------------------------------------------------------------------------------- /unittests/tags/image-with-alt.html: -------------------------------------------------------------------------------- 1 | alt text 2 | 3 | -------------------------------------------------------------------------------- /unittests/tags/image-with-alt.txt: -------------------------------------------------------------------------------- 1 | ::: image http://example.com/image.png 2 | [alt text] 3 | 4 | -------------------------------------------------------------------------------- /unittests/tags/image.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /unittests/tags/image.txt: -------------------------------------------------------------------------------- 1 | ::: image http://example.com/image.png 2 | 3 | -------------------------------------------------------------------------------- /unittests/tags/infobox.html: -------------------------------------------------------------------------------- 1 |
2 |

3 | foo bar 4 |

5 |
6 | -------------------------------------------------------------------------------- /unittests/tags/infobox.txt: -------------------------------------------------------------------------------- 1 | ::: infobox .someclass 2 | foo bar 3 | ::: end 4 | 5 | -------------------------------------------------------------------------------- /unittests/tags/linked-image.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /unittests/tags/linked-image.txt: -------------------------------------------------------------------------------- 1 | ::: !image http://example.com/foo.jpg 2 | -------------------------------------------------------------------------------- /unittests/tags/nested-div.html: -------------------------------------------------------------------------------- 1 |
2 |
3 |

4 | foo bar 5 |

6 |
7 |
8 | 9 | -------------------------------------------------------------------------------- /unittests/tags/nested-div.txt: -------------------------------------------------------------------------------- 1 | ::: div .foo 2 | ::: div .bar 3 | foo bar 4 | ::: end 5 | ::: end 6 | 7 | -------------------------------------------------------------------------------- /unittests/tags/quote.html: -------------------------------------------------------------------------------- 1 |
2 |

3 | Work is the curse of the drinking classes. 4 |

5 |
6 |

7 | Oscar Wilde 8 |

9 | -------------------------------------------------------------------------------- /unittests/tags/quote.txt: -------------------------------------------------------------------------------- 1 | ::: quote "Oscar Wilde" 2 | Work is the curse of the drinking classes. -------------------------------------------------------------------------------- /unittests/tags/raw.html: -------------------------------------------------------------------------------- 1 |

2 | Paragraph 1. 3 |

4 | * foo 5 | * bar 6 |

7 | Paragraph 2. 8 |

9 | Not a paragraph 1. 10 | 11 | Not a paragraph 1. 12 |

13 | Paragraph 3. 14 |

15 | -------------------------------------------------------------------------------- /unittests/tags/raw.txt: -------------------------------------------------------------------------------- 1 | Paragraph 1. 2 | 3 | ::: raw 4 | * foo 5 | * bar 6 | 7 | Paragraph 2. 8 | 9 | ::: raw 10 | Not a paragraph 1. 11 | 12 | Not a paragraph 1. 13 | 14 | Paragraph 3. 15 | --------------------------------------------------------------------------------