670 lines
16 KiB
Python
Executable File
670 lines
16 KiB
Python
Executable File
#!/usr/bin/env python
|
|
|
|
from dataclasses import dataclass, field
|
|
import sys, re, os, enum, itertools
|
|
from functools import partial, partialmethod
|
|
from time import sleep
|
|
from operator import itemgetter
|
|
from defl import log, cl, Path, Undefined, Null, Assert, Time, Obj, Dunder
|
|
from defl import CLIError
|
|
from defl._typing_ import *
|
|
import defl
|
|
from defl.configFormats_ import *
|
|
from defl.markdown_ import *
|
|
from defl.testing_ import Test, Tester, TestState
|
|
|
|
tester = Tester(name=__file__)
|
|
testData = '''
|
|
|
|
# Markdown: Syntax
|
|
|
|
* [Overview](#overview)
|
|
* [Philosophy](#philosophy)
|
|
* [Inline HTML](#html)
|
|
* [Automatic Escaping for Special Characters](#autoescape)
|
|
* [Block Elements](#block)
|
|
* [Paragraphs and Line Breaks](#p)
|
|
* [Headers](#header)
|
|
* [Blockquotes](#blockquote)
|
|
* [Lists](#list)
|
|
* [Code Blocks](#precode)
|
|
* [Horizontal Rules](#hr)
|
|
* [Span Elements](#span)
|
|
* [Links](#link)
|
|
* [Emphasis](#em)
|
|
* [Code](#code)
|
|
* [Images](#img)
|
|
* [Miscellaneous](#misc)
|
|
* [Backslash Escapes](#backslash)
|
|
* [Automatic Links](#autolink)
|
|
|
|
|
|
**Note:** This document is itself written using Markdown; you
|
|
can [see the source for it by adding '.text' to the URL](/projects/markdown/syntax.text).
|
|
|
|
----
|
|
|
|
## Overview
|
|
|
|
### Philosophy
|
|
|
|
Markdown is intended to be as easy-to-read and easy-to-write as is feasible.
|
|
|
|
Readability, however, is emphasized above all else. A Markdown-formatted
|
|
document should be publishable as-is, as plain text, without looking
|
|
like it's been marked up with tags or formatting instructions. While
|
|
Markdown's syntax has been influenced by several existing text-to-HTML
|
|
filters -- including [Setext](http://docutils.sourceforge.net/mirror/setext.html), [atx](http://www.aaronsw.com/2002/atx/), [Textile](http://textism.com/tools/textile/), [reStructuredText](http://docutils.sourceforge.net/rst.html),
|
|
[Grutatext](http://www.triptico.com/software/grutatxt.html), and [EtText](http://ettext.taint.org/doc/) -- the single biggest source of
|
|
inspiration for Markdown's syntax is the format of plain text email.
|
|
|
|
## Block Elements
|
|
|
|
### Paragraphs and Line Breaks
|
|
|
|
A paragraph is simply one or more consecutive lines of text, separated
|
|
by one or more blank lines. (A blank line is any line that looks like a
|
|
blank line -- a line containing nothing but spaces or tabs is considered
|
|
blank.) Normal paragraphs should not be indented with spaces or tabs.
|
|
|
|
The implication of the "one or more consecutive lines of text" rule is
|
|
that Markdown supports "hard-wrapped" text paragraphs. This differs
|
|
significantly from most other text-to-HTML formatters (including Movable
|
|
Type's "Convert Line Breaks" option) which translate every line break
|
|
character in a paragraph into a `<br />` tag.
|
|
|
|
When you *do* want to insert a `<br />` break tag using Markdown, you
|
|
end a line with two or more spaces, then type return.
|
|
|
|
### Headers
|
|
|
|
Markdown supports two styles of headers, [Setext] [1] and [atx] [2].
|
|
|
|
Optionally, you may "close" atx-style headers. This is purely
|
|
cosmetic -- you can use this if you think it looks better. The
|
|
closing hashes don't even need to match the number of hashes
|
|
used to open the header. (The number of opening hashes
|
|
determines the header level.)
|
|
|
|
|
|
### Blockquotes
|
|
|
|
Markdown uses email-style `>` characters for blockquoting. If you're
|
|
familiar with quoting passages of text in an email message, then you
|
|
know how to create a blockquote in Markdown. It looks best if you hard
|
|
wrap the text and put a `>` before every line:
|
|
|
|
> This is a blockquote with two paragraphs. Lorem ipsum dolor sit amet,
|
|
> consectetuer adipiscing elit. Aliquam hendrerit mi posuere lectus.
|
|
> Vestibulum enim wisi, viverra nec, fringilla in, laoreet vitae, risus.
|
|
>
|
|
> Donec sit amet nisl. Aliquam semper ipsum sit amet velit. Suspendisse
|
|
> id sem consectetuer libero luctus adipiscing.
|
|
|
|
Markdown allows you to be lazy and only put the `>` before the first
|
|
line of a hard-wrapped paragraph:
|
|
|
|
> This is a blockquote with two paragraphs. Lorem ipsum dolor sit amet,
|
|
consectetuer adipiscing elit. Aliquam hendrerit mi posuere lectus.
|
|
Vestibulum enim wisi, viverra nec, fringilla in, laoreet vitae, risus.
|
|
|
|
> Donec sit amet nisl. Aliquam semper ipsum sit amet velit. Suspendisse
|
|
id sem consectetuer libero luctus adipiscing.
|
|
|
|
Blockquotes can be nested (i.e. a blockquote-in-a-blockquote) by
|
|
adding additional levels of `>`:
|
|
|
|
> This is the first level of quoting.
|
|
>
|
|
> > This is nested blockquote.
|
|
>
|
|
> Back to the first level.
|
|
|
|
Blockquotes can contain other Markdown elements, including headers, lists,
|
|
and code blocks:
|
|
|
|
> ## This is a header.
|
|
>
|
|
> 1. This is the first list item.
|
|
> 2. This is the second list item.
|
|
>
|
|
> Here's some example code:
|
|
>
|
|
> return shell_exec("echo $input | $markdown_script");
|
|
|
|
Any decent text editor should make email-style quoting easy. For
|
|
example, with BBEdit, you can make a selection and choose Increase
|
|
Quote Level from the Text menu.
|
|
|
|
|
|
### Lists
|
|
|
|
Markdown supports ordered (numbered) and unordered (bulleted) lists.
|
|
|
|
Unordered lists use asterisks, pluses, and hyphens -- interchangably
|
|
-- as list markers:
|
|
|
|
* Red
|
|
* Red
|
|
* Green
|
|
* Blue
|
|
* Green
|
|
- Red
|
|
1. Bird
|
|
2. McHale
|
|
3. Parish
|
|
- Green
|
|
- Blue
|
|
* Blue
|
|
1. Bird
|
|
2. McHale
|
|
3. Parish
|
|
|
|
|
|
is equivalent to:
|
|
|
|
+ Red
|
|
+ Green
|
|
+ Blue
|
|
|
|
and:
|
|
|
|
- Red
|
|
- Green
|
|
- Blue
|
|
|
|
Ordered lists use numbers followed by periods:
|
|
|
|
1. Bird
|
|
2. McHale
|
|
3. Parish
|
|
|
|
It's important to note that the actual numbers you use to mark the
|
|
list have no effect on the HTML output Markdown produces. The HTML
|
|
Markdown produces from the above list is:
|
|
|
|
If you instead wrote the list in Markdown like this:
|
|
|
|
1. Bird
|
|
1. McHale
|
|
1. Parish
|
|
|
|
or even:
|
|
|
|
3. Bird
|
|
1. McHale
|
|
8. Parish
|
|
|
|
you'd get the exact same HTML output. The point is, if you want to,
|
|
you can use ordinal numbers in your ordered Markdown lists, so that
|
|
the numbers in your source match the numbers in your published HTML.
|
|
But if you want to be lazy, you don't have to.
|
|
|
|
To make lists look nice, you can wrap items with hanging indents:
|
|
|
|
* Lorem ipsum dolor sit amet, consectetuer adipiscing elit.
|
|
Aliquam hendrerit mi posuere lectus. Vestibulum enim wisi,
|
|
viverra nec, fringilla in, laoreet vitae, risus.
|
|
* Donec sit amet nisl. Aliquam semper ipsum sit amet velit.
|
|
Suspendisse id sem consectetuer libero luctus adipiscing.
|
|
|
|
But if you want to be lazy, you don't have to:
|
|
|
|
* Lorem ipsum dolor sit amet, consectetuer adipiscing elit.
|
|
Aliquam hendrerit mi posuere lectus. Vestibulum enim wisi,
|
|
viverra nec, fringilla in, laoreet vitae, risus.
|
|
* Donec sit amet nisl. Aliquam semper ipsum sit amet velit.
|
|
Suspendisse id sem consectetuer libero luctus adipiscing.
|
|
|
|
List items may consist of multiple paragraphs. Each subsequent
|
|
paragraph in a list item must be indented by either 4 spaces
|
|
or one tab:
|
|
|
|
1. This is a list item with two paragraphs. Lorem ipsum dolor
|
|
sit amet, consectetuer adipiscing elit. Aliquam hendrerit
|
|
mi posuere lectus.
|
|
|
|
Vestibulum enim wisi, viverra nec, fringilla in, laoreet
|
|
vitae, risus. Donec sit amet nisl. Aliquam semper ipsum
|
|
sit amet velit.
|
|
|
|
2. Suspendisse id sem consectetuer libero luctus adipiscing.
|
|
|
|
It looks nice if you indent every line of the subsequent
|
|
paragraphs, but here again, Markdown will allow you to be
|
|
lazy:
|
|
|
|
* This is a list item with two paragraphs.
|
|
|
|
This is the second paragraph in the list item. You're
|
|
only required to indent the first line. Lorem ipsum dolor
|
|
sit amet, consectetuer adipiscing elit.
|
|
|
|
* Another item in the same list.
|
|
|
|
To put a blockquote within a list item, the blockquote's `>`
|
|
delimiters need to be indented:
|
|
|
|
* A list item with a blockquote:
|
|
|
|
> This is a blockquote
|
|
> inside a list item.
|
|
|
|
To put a code block within a list item, the code block needs
|
|
to be indented *twice* -- 8 spaces or two tabs:
|
|
|
|
* A list item with a code block:
|
|
|
|
<code goes here>
|
|
|
|
### Code Blocks
|
|
|
|
Pre-formatted code blocks are used for writing about programming or
|
|
markup source code. Rather than forming normal paragraphs, the lines
|
|
of a code block are interpreted literally. Markdown wraps a code block
|
|
in both `<pre>` and `<code>` tags.
|
|
|
|
To produce a code block in Markdown, simply indent every line of the
|
|
block by at least 4 spaces or 1 tab.
|
|
|
|
This is a normal paragraph:
|
|
|
|
This is a code block.
|
|
|
|
Here is an example of AppleScript:
|
|
|
|
tell application "Foo"
|
|
beep
|
|
end tell
|
|
|
|
A code block continues until it reaches a line that is not indented
|
|
(or the end of the article).
|
|
|
|
Within a code block, ampersands (`&`) and angle brackets (`<` and `>`)
|
|
are automatically converted into HTML entities. This makes it very
|
|
easy to include example HTML source code using Markdown -- just paste
|
|
it and indent it, and Markdown will handle the hassle of encoding the
|
|
ampersands and angle brackets. For example, this:
|
|
|
|
<div class="footer">
|
|
© 2004 Foo Corporation
|
|
</div>
|
|
|
|
Regular Markdown syntax is not processed within code blocks. E.g.,
|
|
asterisks are just literal asterisks within a code block. This means
|
|
it's also easy to use Markdown to write about Markdown's own syntax.
|
|
|
|
```
|
|
tell application "Foo"
|
|
beep
|
|
end tell
|
|
```
|
|
|
|
## Span Elements
|
|
|
|
### Links
|
|
|
|
Markdown supports two style of links: *inline* and *reference*.
|
|
|
|
In both styles, the link text is delimited by [square brackets].
|
|
|
|
To create an inline link, use a set of regular parentheses immediately
|
|
after the link text's closing square bracket. Inside the parentheses,
|
|
put the URL where you want the link to point, along with an *optional*
|
|
title for the link, surrounded in quotes. For example:
|
|
|
|
This is [an example](http://example.com/) inline link.
|
|
|
|
[This link](http://example.net/) has no title attribute.
|
|
|
|
### Emphasis
|
|
|
|
Markdown treats asterisks (`*`) and underscores (`_`) as indicators of
|
|
emphasis. Text wrapped with one `*` or `_` will be wrapped with an
|
|
HTML `<em>` tag; double `*`'s or `_`'s will be wrapped with an HTML
|
|
`<strong>` tag. E.g., this input:
|
|
|
|
*single asterisks*
|
|
|
|
_single underscores_
|
|
|
|
**double asterisks**
|
|
|
|
__double underscores__
|
|
|
|
### Code
|
|
|
|
To indicate a span of code, wrap it with backtick quotes (`` ` ``).
|
|
Unlike a pre-formatted code block, a code span indicates code within a
|
|
normal paragraph. For example:
|
|
|
|
Use the `printf()` function.
|
|
|
|
|
|
---
|
|
__Advertisement :)__
|
|
|
|
- __[pica](https://nodeca.github.io/pica/demo/)__ - high quality and fast image
|
|
resize in browser.
|
|
- __[babelfish](https://github.com/nodeca/babelfish/)__ - developer friendly
|
|
i18n with plurals support and easy syntax.
|
|
|
|
You will like those projects!
|
|
|
|
---
|
|
|
|
# h1 Heading 8-)
|
|
## h2 Heading
|
|
### h3 Heading
|
|
#### h4 Heading
|
|
##### h5 Heading
|
|
###### h6 Heading
|
|
|
|
|
|
## Horizontal Rules
|
|
|
|
___
|
|
|
|
---
|
|
|
|
***
|
|
|
|
|
|
## Typographic replacements
|
|
|
|
Enable typographer option to see result.
|
|
|
|
(c) (C) (r) (R) (tm) (TM) (p) (P) +-
|
|
|
|
test.. test... test..... test?..... test!....
|
|
|
|
!!!!!! ???? ,, -- ---
|
|
|
|
"Smartypants, double quotes" and 'single quotes'
|
|
|
|
|
|
## Emphasis
|
|
|
|
**This is bold text**
|
|
|
|
__This is bold text__
|
|
|
|
*This is italic text*
|
|
|
|
_This is italic text_
|
|
|
|
~~Strikethrough~~
|
|
|
|
|
|
## Blockquotes
|
|
|
|
|
|
> Blockquotes can also be nested...
|
|
>> ...by using additional greater-than signs right next to each other...
|
|
> > > ...or with spaces between arrows.
|
|
|
|
|
|
## Lists
|
|
|
|
Unordered
|
|
|
|
+ Create a list by starting a line with `+`, `-`, or `*`
|
|
+ Sub-lists are made by indenting 2 spaces:
|
|
- Marker character change forces new list start:
|
|
* Ac tristique libero volutpat at
|
|
+ Facilisis in pretium nisl aliquet
|
|
- Nulla volutpat aliquam velit
|
|
+ Very easy!
|
|
|
|
Ordered
|
|
|
|
1. Lorem ipsum dolor sit amet
|
|
2. Consectetur adipiscing elit
|
|
3. Integer molestie lorem at massa
|
|
|
|
|
|
1. You can use sequential numbers...
|
|
1. ...or keep all the numbers as `1.`
|
|
|
|
Start numbering with offset:
|
|
|
|
57. foo
|
|
1. bar
|
|
|
|
|
|
## Code
|
|
|
|
Inline `code`
|
|
|
|
Indented code
|
|
|
|
// Some comments
|
|
line 1 of code
|
|
line 2 of code
|
|
line 3 of code
|
|
|
|
|
|
Block code "fences"
|
|
|
|
```
|
|
Sample text here...
|
|
```
|
|
|
|
Syntax highlighting
|
|
|
|
``` js
|
|
var foo = function (bar) {
|
|
return bar++;
|
|
};
|
|
|
|
console.log(foo(5));
|
|
```
|
|
|
|
## Tables
|
|
|
|
| Option | Description |
|
|
| ------ | ----------- |
|
|
| data | path to data files to supply the data that will be passed into templates. |
|
|
| engine | engine to be used for processing templates. Handlebars is the default. |
|
|
| ext | extension to be used for dest files. |
|
|
|
|
Right aligned columns
|
|
|
|
| Option | Description |
|
|
| ------:| -----------:|
|
|
| data | path to data files to supply the data that will be passed into templates. |
|
|
| engine | engine to be used for processing templates. Handlebars is the default. |
|
|
| ext | extension to be used for dest files. |
|
|
|
|
|
|
## Links
|
|
|
|
[link text](http://dev.nodeca.com)
|
|
|
|
[link with title](http://nodeca.github.io/pica/demo/ "title text!")
|
|
|
|
Autoconverted link https://github.com/nodeca/pica (enable linkify to see)
|
|
|
|
|
|
## Images
|
|
|
|

|
|

|
|
|
|
Like links, Images also have a footnote style syntax
|
|
|
|
![Alt text][id]
|
|
|
|
With a reference later in the document defining the URL location:
|
|
|
|
[id]: https://octodex.github.com/images/dojocat.jpg "The Dojocat"
|
|
|
|
|
|
## Plugins
|
|
|
|
The killer feature of `markdown-it` is very effective support of
|
|
[syntax plugins](https://www.npmjs.org/browse/keyword/markdown-it-plugin).
|
|
|
|
|
|
### [Emojies](https://github.com/markdown-it/markdown-it-emoji)
|
|
|
|
> Classic markup: :wink: :cry: :laughing: :yum:
|
|
>
|
|
> Shortcuts (emoticons): :-) :-( 8-) ;)
|
|
|
|
see [how to change output](https://github.com/markdown-it/markdown-it-emoji#change-output) with twemoji.
|
|
|
|
|
|
### [Subscript](https://github.com/markdown-it/markdown-it-sub) / [Superscript](https://github.com/markdown-it/markdown-it-sup)
|
|
|
|
- 19^th^
|
|
- H~2~O
|
|
|
|
|
|
### [<ins>](https://github.com/markdown-it/markdown-it-ins)
|
|
|
|
++Inserted text++
|
|
|
|
|
|
### [<mark>](https://github.com/markdown-it/markdown-it-mark)
|
|
|
|
==Marked text==
|
|
|
|
|
|
### [Footnotes](https://github.com/markdown-it/markdown-it-footnote)
|
|
|
|
Footnote 1 link[^first].
|
|
|
|
Footnote 2 link[^second].
|
|
|
|
Inline footnote^[Text of inline footnote] definition.
|
|
|
|
Duplicated footnote reference[^second].
|
|
|
|
[^first]: Footnote **can have markup**
|
|
|
|
and multiple paragraphs.
|
|
|
|
[^second]: Footnote text.
|
|
|
|
|
|
### [Definition lists](https://github.com/markdown-it/markdown-it-deflist)
|
|
|
|
Term 1
|
|
|
|
: Definition 1
|
|
with lazy continuation.
|
|
|
|
Term 2 with *inline markup*
|
|
|
|
: Definition 2
|
|
|
|
{ some code, part of Definition 2 }
|
|
|
|
Third paragraph of definition 2.
|
|
|
|
_Compact style:_
|
|
|
|
Term 1
|
|
~ Definition 1
|
|
|
|
Term 2
|
|
~ Definition 2a
|
|
~ Definition 2b
|
|
|
|
|
|
### [Abbreviations](https://github.com/markdown-it/markdown-it-abbr)
|
|
|
|
This is HTML abbreviation example.
|
|
|
|
It converts "HTML", but keep intact partial entries like "xxxHTMLyyy" and so on.
|
|
|
|
*[HTML]: Hyper Text Markup Language
|
|
|
|
### [Custom containers](https://github.com/markdown-it/markdown-it-container)
|
|
|
|
::: warning
|
|
*here be dragons*
|
|
:::
|
|
|
|
'''
|
|
|
|
def genny(text):
|
|
yield defl.formatMultiLineStr(text, dedent=True, filt=True, join=False)
|
|
confIn = ConfigInput(text).markdown()
|
|
# print(defl.jdumps(confIn, colorize=True))
|
|
yield confIn
|
|
confOut = ConfigOutput(confIn).markdown()
|
|
# print(confOut)
|
|
assert isinstance(confOut, str)
|
|
yield defl.formatMultiLineStr(confOut, dedent=True, filt=True, join=False)
|
|
|
|
@tester.add()
|
|
def mdList():
|
|
gen = genny('''
|
|
- 1
|
|
- 2
|
|
- 3
|
|
- 4
|
|
''')
|
|
dedent = next(gen)
|
|
outp = ["- 1", " - 2", " - 3", " - 4"]
|
|
Assert(dedent) == outp
|
|
|
|
Assert(next(gen)) == [{
|
|
"typ": "list",
|
|
"lines": ["1"],
|
|
"children": [{
|
|
"typ": "list",
|
|
"lines": ["2"]
|
|
}, {
|
|
"typ": "list",
|
|
"lines": ["3"]
|
|
}, {
|
|
"typ": "list",
|
|
"lines": ["4"]
|
|
}]
|
|
}]
|
|
|
|
Assert(next(gen)) == a
|
|
|
|
# @tester.add()
|
|
def mdTable():
|
|
gen = genny(
|
|
'''
|
|
| a | bb |ccc |
|
|
| ------ | -----------|---|
|
|
| 1| 444| aaa|
|
|
| 22|55 |bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb|
|
|
| 333|6|c|
|
|
'''
|
|
)
|
|
dedent = next(gen)
|
|
outp = [
|
|
"| a | bb |ccc |", "| ------ | -----------|---|", "| 1| 444| aaa|",
|
|
"| 22|55 |bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb|", "| 333|6|c|"
|
|
]
|
|
Assert(dedent) == outp
|
|
|
|
Assert(next(gen)) == [{
|
|
"typ": "table",
|
|
"lines": [{
|
|
"a": "1",
|
|
"bb": "444",
|
|
"ccc": "aaa"
|
|
}, {
|
|
"a": "22",
|
|
"bb": "55",
|
|
"ccc": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
|
|
}, {
|
|
"a": "333",
|
|
"bb": "6",
|
|
"ccc": "c"
|
|
}],
|
|
}]
|
|
|
|
Assert(next(gen)) == outp
|
|
|
|
log.info(tester.run())
|
|
tester.exitWithStatus()
|