diff options
Diffstat (limited to 'mdit_py_plugins/front_matter')
-rw-r--r-- | mdit_py_plugins/front_matter/LICENSE | 22 | ||||
-rw-r--r-- | mdit_py_plugins/front_matter/__init__.py | 1 | ||||
-rw-r--r-- | mdit_py_plugins/front_matter/index.py | 138 | ||||
-rw-r--r-- | mdit_py_plugins/front_matter/port.yaml | 4 |
4 files changed, 165 insertions, 0 deletions
diff --git a/mdit_py_plugins/front_matter/LICENSE b/mdit_py_plugins/front_matter/LICENSE new file mode 100644 index 0000000..54c0b84 --- /dev/null +++ b/mdit_py_plugins/front_matter/LICENSE @@ -0,0 +1,22 @@ +Copyright (c) 2016-2020 ParkSB. + +Permission is hereby granted, free of charge, to any person +obtaining a copy of this software and associated documentation +files (the "Software"), to deal in the Software without +restriction, including without limitation the rights to use, +copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. diff --git a/mdit_py_plugins/front_matter/__init__.py b/mdit_py_plugins/front_matter/__init__.py new file mode 100644 index 0000000..26bce1d --- /dev/null +++ b/mdit_py_plugins/front_matter/__init__.py @@ -0,0 +1 @@ +from .index import front_matter_plugin # noqa: F401 diff --git a/mdit_py_plugins/front_matter/index.py b/mdit_py_plugins/front_matter/index.py new file mode 100644 index 0000000..2077925 --- /dev/null +++ b/mdit_py_plugins/front_matter/index.py @@ -0,0 +1,138 @@ +# Process front matter and pass to cb +from math import floor + +from markdown_it import MarkdownIt +from markdown_it.common.utils import charCodeAt +from markdown_it.rules_block import StateBlock + + +def front_matter_plugin(md: MarkdownIt): + """Plugin ported from + `markdown-it-front-matter <https://github.com/ParkSB/markdown-it-front-matter>`__. + + It parses initial metadata, stored between opening/closing dashes: + + .. code-block:: md + + --- + valid-front-matter: true + --- + + """ + frontMatter = make_front_matter_rule() + md.block.ruler.before( + "table", + "front_matter", + frontMatter, + {"alt": ["paragraph", "reference", "blockquote", "list"]}, + ) + + +def make_front_matter_rule(): + min_markers = 3 + marker_str = "-" + marker_char = charCodeAt(marker_str, 0) + marker_len = len(marker_str) + + def frontMatter(state: StateBlock, startLine: int, endLine: int, silent: bool): + auto_closed = False + start = state.bMarks[startLine] + state.tShift[startLine] + maximum = state.eMarks[startLine] + src_len = len(state.src) + + # Check out the first character of the first line quickly, + # this should filter out non-front matter + if startLine != 0 or marker_char != state.srcCharCode[0]: + return False + + # Check out the rest of the marker string + # while pos <= 3 + pos = start + 1 + while pos <= maximum and pos < src_len: + if marker_str[(pos - start) % marker_len] != state.src[pos]: + break + pos += 1 + + marker_count = floor((pos - start) / marker_len) + + if marker_count < min_markers: + return False + + pos -= (pos - start) % marker_len + + # Since start is found, we can report success here in validation mode + if silent: + return True + + # Search for the end of the block + nextLine = startLine + + while True: + nextLine += 1 + if nextLine >= endLine: + # unclosed block should be autoclosed by end of document. + return False + + if state.src[start:maximum] == "...": + break + + start = state.bMarks[nextLine] + state.tShift[nextLine] + maximum = state.eMarks[nextLine] + + if start < maximum and state.sCount[nextLine] < state.blkIndent: + # non-empty line with negative indent should stop the list: + # - ``` + # test + break + + if marker_char != state.srcCharCode[start]: + continue + + if state.sCount[nextLine] - state.blkIndent >= 4: + # closing fence should be indented less than 4 spaces + continue + + pos = start + 1 + while pos < maximum: + if marker_str[(pos - start) % marker_len] != state.src[pos]: + break + pos += 1 + + # closing code fence must be at least as long as the opening one + if floor((pos - start) / marker_len) < marker_count: + continue + + # make sure tail has spaces only + pos -= (pos - start) % marker_len + pos = state.skipSpaces(pos) + + if pos < maximum: + continue + + # found! + auto_closed = True + break + + old_parent = state.parentType + old_line_max = state.lineMax + state.parentType = "container" + + # this will prevent lazy continuations from ever going past our end marker + state.lineMax = nextLine + + token = state.push("front_matter", "", 0) + token.hidden = True + token.markup = marker_str * min_markers + token.content = state.src[ + state.bMarks[startLine + 1] : state.eMarks[nextLine - 1] + ] + token.block = True + + state.parentType = old_parent + state.lineMax = old_line_max + state.line = nextLine + (1 if auto_closed else 0) + token.map = [startLine, state.line] + + return True + + return frontMatter diff --git a/mdit_py_plugins/front_matter/port.yaml b/mdit_py_plugins/front_matter/port.yaml new file mode 100644 index 0000000..f7d145f --- /dev/null +++ b/mdit_py_plugins/front_matter/port.yaml @@ -0,0 +1,4 @@ +- package: markdown-it-front-matter + commit: b404f5d8fd536e7e9ddb276267ae0b6f76e9cf9d + date: Feb 7, 2020 + version: 0.2.1 |