diff --git a/.metadock/content_schematics/jinja_helpers/global.yml b/.metadock/content_schematics/jinja_helpers/global.yml
index dcf5aeb..06bf6a6 100644
--- a/.metadock/content_schematics/jinja_helpers/global.yml
+++ b/.metadock/content_schematics/jinja_helpers/global.yml
@@ -1,8 +1,23 @@
global:
- info: |
- The global namespace contains helpful macros and filters for manipulating data in the Jinja
- context. It also provides access to more specific namespaces through their respective identifiers,
- such as `md` and `html`.
+ docstring: |
+ Jinja namespace for the global Metadock environment, including all global exports, filters, and namespaces.
+
+ **Macros**:
+
+ debug
+
+ **Namespaces**:
+
+ html
+ md
+
+ **Filters**:
+
+ chain
+ inline
+ with_prefix
+ with_suffix
+ zip
macros:
debug:
diff --git a/.metadock/content_schematics/jinja_helpers/html.yml b/.metadock/content_schematics/jinja_helpers/html.yml
index 46ac1e4..2c9131c 100644
--- a/.metadock/content_schematics/jinja_helpers/html.yml
+++ b/.metadock/content_schematics/jinja_helpers/html.yml
@@ -1,4 +1,22 @@
html:
+ docstring: |
+ Jinja namespace which owns HTML-related functions and filters.
+
+ **Macros**:
+
+ bold
+ code
+ codeblock
+ details
+ italic
+ summary
+ underline
+
+ **Filters**:
+
+ escape
+ inline
+
macros:
bold:
docstring: |
@@ -97,3 +115,52 @@ html:
snippet_key: HTML summary
snippet_body:
- html.summary($1)
+
+ underline:
+ docstring: |
+ Wraps a string in HTML underline tags ().
+ example: |
+ >>> from metadock.env import MetadockEnv
+ >>> env = MetadockEnv().jinja_environment()
+ >>> env.from_string("{{ html.underline('This is underlined text.') }}").render()
+ 'This is underlined text.'
+ source_file: metadock/env.py
+ method_name: metadock.env.MetadockHtmlNamespace.underline
+ signature: "(self, content: str) -> str"
+ intellisense:
+ snippet_key: HTML underline
+ snippet_body:
+ - html.underline($1)
+
+ filters:
+ escape:
+ docstring: |
+ Filter which escapes a string by replacing all HTML special characters with their HTML entity equivalents.
+ example: |
+ >>> from metadock.env import MetadockEnv
+ >>> env = MetadockEnv().jinja_environment()
+ >>> env.from_string("{{ '
This is a paragraph.
' | html.escape }}").render()
+ '<p>This is a paragraph.</p>'
+ source_file: metadock/env.py
+ method_name: metadock.env.MetadockHtmlNamespace.escape_filter
+ signature: "(self, content: str) -> str"
+ intellisense:
+ snippet_key: HTML escape
+ snippet_body:
+ - html.escape
+
+ inline:
+ docstring: |
+ Filter which inlines a string by replacing all newlines with HTML line-breaks
singleton tags.
+ example: |
+ >>> from metadock.env import MetadockEnv
+ >>> env = MetadockEnv().jinja_environment()
+ >>> env.from_string("{{ 'This is a multi-line string.\nThis is the second line.\nAnd the third.' | html.inline }}").render()
+ 'This is a multi-line string.
This is the second line.
And the third.'
+ source_file: metadock/env.py
+ method_name: metadock.env.MetadockHtmlNamespace.inline_filter
+ signature: "(self, content: str) -> str"
+ intellisense:
+ snippet_key: HTML inline
+ snippet_body:
+ - html.inline
diff --git a/.metadock/content_schematics/jinja_helpers/md.yml b/.metadock/content_schematics/jinja_helpers/md.yml
index 16a0c7c..b3f3f12 100644
--- a/.metadock/content_schematics/jinja_helpers/md.yml
+++ b/.metadock/content_schematics/jinja_helpers/md.yml
@@ -1,4 +1,162 @@
md:
- macros: {}
+ docstring: |
+ Jinja Namespace for Markdown-related functions and filters.
- filters: {}
+ **Macros**:
+
+ blockquote
+ code
+ codeblock
+ list
+ tablehead
+ tablerow
+
+ **Filters**:
+
+ convert
+ list
+
+ macros:
+ blockquote:
+ docstring: |
+ Produces a Markdown blockquote from the given content by prepending each line with a gt symbol ("> ").
+ example: |
+ >>> from metadock.env import MetadockEnv
+ >>> env = MetadockEnv().jinja_environment()
+ >>> env.from_string("{{ md.blockquote('This is a blockquote.') }}").render()
+ '> This is a blockquote.'
+ source_file: metadock/env.py
+ method_name: metadock.env.MetadockMdNamespace.blockquote
+ signature: "(self, content: str) -> str"
+ intellisense:
+ snippet_key: Markdown blockquote
+ snippet_body:
+ - md.blockquote($1)
+
+ code:
+ docstring: |
+ Produces a Markdown inline code block from the given content by wrapping the string in graves ("\`").
+ example: |
+ >>> from metadock.env import MetadockEnv
+ >>> env = MetadockEnv().jinja_environment()
+ >>> env.from_string("{{ md.code('This is an inline code block.') }}").render()
+ '`This is an inline code block.`'
+ source_file: metadock/env.py
+ method_name: metadock.env.MetadockMdNamespace.code
+ signature: "(self, content: str) -> str"
+ intellisense:
+ snippet_key: Markdown inline code
+ snippet_body:
+ - md.code($1)
+
+ codeblock:
+ docstring: |
+ Produces a Markdown codeblock from the given content by wrapping the string in triple-graves ("\`\`\`"),
+ and optionally specifies a language.
+ example: |
+ >>> from metadock.env import MetadockEnv
+ >>> env = MetadockEnv().jinja_environment()
+ >>> env.from_string("{{ md.codeblock('This is a codeblock.', language = 'sh') }}").render()
+ '```sh\nThis is a codeblock.\n```'
+ source_file: metadock/env.py
+ method_name: metadock.env.MetadockMdNamespace.codeblock
+ signature: "(self, content: str, language: str = '') -> str"
+ intellisense:
+ snippet_key: Markdown codeblock
+ snippet_body:
+ - md.codeblock($1)
+
+ list:
+ docstring: |
+ Produces a Markdown list from the given content by prepending each line with a dash ("- "). If any of its
+ arguments are, themselves, formatted as Markdown lists, then they are simply indented as sublists.
+ example: |
+ >>> from metadock.env import MetadockEnv
+ >>> env = MetadockEnv().jinja_environment()
+ >>> env.from_string(
+ ... "{{ md.list('This is a list.', md.list('This is a sublist,', 'in two pieces.')) }}"
+ ... ).render()
+ '- This is a list.\n - This is a sublist,\n - in two pieces.'
+ source_file: metadock/env.py
+ method_name: metadock.env.MetadockMdNamespace.list
+ signature: "(self, *items: str) -> str"
+ intellisense:
+ snippet_key: Markdown list
+ snippet_body:
+ - md.list($1)
+
+ tablehead:
+ docstring: |
+ Produces a Markdown table header from the given cells by joining each cell with pipes ("|") and wrapping the
+ result in pipes, plus adding a header divider row. Cell contents have their pipes escaped with a backslash
+ ("\\"). To bold the header cell contents, supply `bold = true`.
+ example: |
+ >>> from metadock.env import MetadockEnv
+ >>> env = MetadockEnv().jinja_environment()
+ >>> env.from_string(
+ ... "{{ md.tablehead('Column 1', 'Column 2', 'Column 3', bold = true) }}"
+ ... ).render()
+ '| Column 1 | Column 2 | Column 3 |\n| --- | --- | --- |'
+ source_file: metadock/env.py
+ method_name: metadock.env.MetadockMdNamespace.tablehead
+ signature: "(self, *header_cells: str, bold: bool = False) -> str"
+ intellisense:
+ snippet_key: Markdown table head
+ snippet_body:
+ - md.tablehead($1)
+
+ tablerow:
+ docstring: |
+ Produces a Markdown table row from the given cells by joining each cell with pipes ("|") and wrapping the
+ result in pipes. Cell contents have their pipes escaped with a backslash ("\\").
+ example: |
+ >>> from metadock.env import MetadockEnv
+ >>> env = MetadockEnv().jinja_environment()
+ >>> env.from_string(
+ ... "{{ md.tablehead('Column 1', 'Column 2', 'Column 3') }}\n"
+ ... "{{ md.tablerow('Value 1', 'Value 2', 'Value 3') }}"
+ ... ).render()
+ '| Column 1 | Column 2 | Column 3 |\n| --- | --- | --- |\n| Value 1 | Value 2 | Value 3 |'
+ source_file: metadock/env.py
+ method_name: metadock.env.MetadockMdNamespace.tablerow
+ signature: "(self, *row_cells: str) -> str"
+ intellisense:
+ snippet_key: Markdown table row
+ snippet_body:
+ - md.tablerow($1)
+
+ filters:
+ convert:
+ docstring: |
+ Filter which converts Markdown content to HTML, by invoking `marko.convert`.
+ example: |
+ >>> from metadock.env import MetadockEnv
+ >>> env = MetadockEnv().jinja_environment()
+ >>> env.from_string("{{ '# This is a heading\n\n> And a block quote.' | md.convert }}").render()
+ 'This is a heading
\n\nAnd a block quote.
\n
\n'
+ source_file: metadock/env.py
+ method_name: metadock.env.MetadockMdNamespace.convert_filter
+ signature: "(self, md_content: str) -> str"
+ intellisense:
+ snippet_key: Markdown convert
+ snippet_body:
+ - md.convert($1)
+
+ list:
+ docstring: |
+ Filter which unpacks an iterable of values into a Markdown list, or formats a single value as a Markdown list
+ element.
+ example: |
+ >>> from metadock.env import MetadockEnv
+ >>> env = MetadockEnv().jinja_environment()
+ >>> env.from_string(
+ ... "{{ ['This is a list.', 'This is a second element'] | md.list }}\n"
+ ... ).render()
+ '- This is a list.\n- This is a second element\n'
+ source_file: metadock/env.py
+ method_name: metadock.env.MetadockMdNamespace.list_filter
+ signature: "(self, values: str | Iterable[str]) -> str"
+ intellisense:
+ snippet_key: Markdown list
+ snippet_body:
+ - md.list
diff --git a/.metadock/generated_documents/README.html b/.metadock/generated_documents/README.html
index be69dc9..bc6ba97 100644
--- a/.metadock/generated_documents/README.html
+++ b/.metadock/generated_documents/README.html
@@ -249,9 +249,21 @@ Jinja Templating Helpers
and filters which can be used to make formatting content easier. The macros and filters are segregated into
3 namespaces, documented below:
Global namespace
-The global namespace contains helpful macros and filters for manipulating data in the Jinja
-context. It also provides access to more specific namespaces through their respective identifiers,
-such as md
and html
.
+Jinja namespace for the global Metadock environment, including all global exports, filters, and namespaces.
+Macros:
+debug
+
+Namespaces:
+html
+md
+
+Filters:
+chain
+inline
+with_prefix
+with_suffix
+zip
+
Jinja macro reference
@@ -311,7 +323,19 @@ Global namespace
md
namespace
-None
+Jinja Namespace for Markdown-related functions and filters.
+Macros:
+blockquote
+code
+codeblock
+list
+tablehead
+tablerow
+
+Filters:
+convert
+list
+
Jinja macro reference
@@ -323,7 +347,39 @@ md
namespace
Signature |
Doc |
-
+
+
+
+md.blockquote |
+metadock.env.MetadockMdNamespace.blockquote: (self, content: str) -> str |
+Produces a Markdown blockquote from the given content by prepending each line with a gt symbol ("> ").
>>> from metadock.env import MetadockEnv >>> env = MetadockEnv().jinja_environment() >>> env.from_string("{{ md.blockquote('This is a blockquote.') }}").render() '> This is a blockquote.'
|
+
+
+md.code |
+metadock.env.MetadockMdNamespace.code: (self, content: str) -> str |
+Produces a Markdown inline code block from the given content by wrapping the string in graves ("`").
>>> from metadock.env import MetadockEnv >>> env = MetadockEnv().jinja_environment() >>> env.from_string("{{ md.code('This is an inline code block.') }}").render() '`This is an inline code block.`'
|
+
+
+md.codeblock |
+metadock.env.MetadockMdNamespace.codeblock: (self, content: str, language: str = '') -> str |
+Produces a Markdown codeblock from the given content by wrapping the string in triple-graves ("```"), and optionally specifies a language.
>>> from metadock.env import MetadockEnv >>> env = MetadockEnv().jinja_environment() >>> env.from_string("{{ md.codeblock('This is a codeblock.', language = 'sh') }}").render() 'sh\nThis is a codeblock.\n '
|
+
+
+md.list |
+metadock.env.MetadockMdNamespace.list: (self, *items: str) -> str |
+Produces a Markdown list from the given content by prepending each line with a dash ("- "). If any of its arguments are, themselves, formatted as Markdown lists, then they are simply indented as sublists.
>>> from metadock.env import MetadockEnv >>> env = MetadockEnv().jinja_environment() >>> env.from_string( ... "{{ md.list('This is a list.', md.list('This is a sublist,', 'in two pieces.')) }}" ... ).render() '- This is a list.\n - This is a sublist,\n - in two pieces.'
|
+
+
+md.tablehead |
+metadock.env.MetadockMdNamespace.tablehead: (self, *header_cells: str, bold: bool = False) -> str |
+Produces a Markdown table header from the given cells by joining each cell with pipes ("|") and wrapping the result in pipes, plus adding a header divider row. Cell contents have their pipes escaped with a backslash ("\"). To bold the header cell contents, supply bold = true .
>>> from metadock.env import MetadockEnv >>> env = MetadockEnv().jinja_environment() >>> env.from_string( ... "{{ md.tablehead('Column 1', 'Column 2', 'Column 3', bold = true) }}" ... ).render() '| <b>Column 1</b> | <b>Column 2</b> | <b>Column 3</b> |\n| --- | --- | --- |'
|
+
+
+md.tablerow |
+metadock.env.MetadockMdNamespace.tablerow: (self, *row_cells: str) -> str |
+Produces a Markdown table row from the given cells by joining each cell with pipes ("|") and wrapping the result in pipes. Cell contents have their pipes escaped with a backslash ("\").
>>> from metadock.env import MetadockEnv >>> env = MetadockEnv().jinja_environment() >>> env.from_string( ... "{{ md.tablehead('Column 1', 'Column 2', 'Column 3') }}\n" ... "{{ md.tablerow('Value 1', 'Value 2', 'Value 3') }}" ... ).render() '| Column 1 | Column 2 | Column 3 |\n| --- | --- | --- |\n| Value 1 | Value 2 | Value 3 |'
|
+
+
Jinja filter reference
@@ -335,9 +391,34 @@ md
namespace
Signature |
Doc |
-
+
+
+
+md.convert |
+metadock.env.MetadockMdNamespace.convert_filter: (self, md_content: str) -> str |
+Filter which converts Markdown content to HTML, by invoking marko.convert .
>>> from metadock.env import MetadockEnv >>> env = MetadockEnv().jinja_environment() >>> env.from_string("{{ '# This is a heading\n\n> And a block quote.' | md.convert }}").render() '<h1>This is a heading</h1>\n<blockquote>\n<p>And a block quote.</p>\n</blockquote>\n'
|
+
+
+md.list |
+metadock.env.MetadockMdNamespace.list_filter: (self, values: str | Iterable[str]) -> str |
+Filter which unpacks an iterable of values into a Markdown list, or formats a single value as a Markdown list element.
>>> from metadock.env import MetadockEnv >>> env = MetadockEnv().jinja_environment() >>> env.from_string( ... "{{ ['This is a list.', 'This is a second element'] | md.list }}\n" ... ).render() '- This is a list.\n- This is a second element\n'
|
+
+
html
namespace
-None
+Jinja namespace which owns HTML-related functions and filters.
+Macros:
+bold
+code
+codeblock
+details
+italic
+summary
+underline
+
+Filters:
+escape
+inline
+
Jinja macro reference
@@ -381,6 +462,11 @@ html
namespace
metadock.env.MetadockHtmlNamespace.summary: (self, content: str) -> str |
Wraps a string in line-broken HTML summary tags (<summary>\n\n</summary>).
>>> from metadock.env import MetadockEnv >>> env = MetadockEnv().jinja_environment() >>> env.from_string("{{ html.summary('This is summary text.') }}").render() '<summary>\nThis is summary text.\n</summary>'
|
+
+html.underline |
+metadock.env.MetadockHtmlNamespace.underline: (self, content: str) -> str |
+Wraps a string in HTML underline tags (<u></u>).
>>> from metadock.env import MetadockEnv >>> env = MetadockEnv().jinja_environment() >>> env.from_string("{{ html.underline('This is underlined text.') }}").render() '<u>This is underlined text.</u>'
|
+
@@ -393,7 +479,19 @@ html
namespace
Signature |
Doc |
-
+
+
+
+html.escape |
+metadock.env.MetadockHtmlNamespace.escape_filter: (self, content: str) -> str |
+Filter which escapes a string by replacing all HTML special characters with their HTML entity equivalents.
>>> from metadock.env import MetadockEnv >>> env = MetadockEnv().jinja_environment() >>> env.from_string("{{ '<p>This is a paragraph.</p>' | html.escape }}").render() '<p>This is a paragraph.</p>'
|
+
+
+html.inline |
+metadock.env.MetadockHtmlNamespace.inline_filter: (self, content: str) -> str |
+Filter which inlines a string by replacing all newlines with HTML line-breaks <br> singleton tags.
>>> from metadock.env import MetadockEnv >>> env = MetadockEnv().jinja_environment() >>> env.from_string("{{ 'This is a multi-line string.\nThis is the second line.\nAnd the third.' | html.inline }}").render() 'This is a multi-line string.<br>This is the second line.<br>And the third.'
|
+
+
Acknowledgements
Author:
diff --git a/.metadock/generated_documents/README.md b/.metadock/generated_documents/README.md
index eb965fe..5ad7a7a 100644
--- a/.metadock/generated_documents/README.md
+++ b/.metadock/generated_documents/README.md
@@ -277,9 +277,24 @@ and filters which can be used to make formatting content easier. The macros and
### Global namespace
-The global namespace contains helpful macros and filters for manipulating data in the Jinja
-context. It also provides access to more specific namespaces through their respective identifiers,
-such as `md` and `html`.
+Jinja namespace for the global Metadock environment, including all global exports, filters, and namespaces.
+
+**Macros**:
+
+ debug
+
+**Namespaces**:
+
+ html
+ md
+
+**Filters**:
+
+ chain
+ inline
+ with_prefix
+ with_suffix
+ zip
@@ -311,7 +326,22 @@ Jinja filter reference
### `md` namespace
-None
+Jinja Namespace for Markdown-related functions and filters.
+
+**Macros**:
+
+ blockquote
+ code
+ codeblock
+ list
+ tablehead
+ tablerow
+
+**Filters**:
+
+ convert
+ list
+
@@ -321,6 +351,12 @@ Jinja macro reference
| Macro | Signature | Doc |
| --- | --- | --- |
+| md.blockquote
| metadock.env.MetadockMdNamespace.blockquote: (self, content: str) -> str
| Produces a Markdown blockquote from the given content by prepending each line with a gt symbol ("> ").
>>> from metadock.env import MetadockEnv
>>> env = MetadockEnv().jinja_environment()
>>> env.from_string("{{ md.blockquote('This is a blockquote.') }}").render()
'> This is a blockquote.'
|
+| md.code
| metadock.env.MetadockMdNamespace.code: (self, content: str) -> str
| Produces a Markdown inline code block from the given content by wrapping the string in graves ("\`").
>>> from metadock.env import MetadockEnv
>>> env = MetadockEnv().jinja_environment()
>>> env.from_string("{{ md.code('This is an inline code block.') }}").render()
'`This is an inline code block.`'
|
+| md.codeblock
| metadock.env.MetadockMdNamespace.codeblock: (self, content: str, language: str = '') -> str
| Produces a Markdown codeblock from the given content by wrapping the string in triple-graves ("\`\`\`"), and optionally specifies a language.
>>> from metadock.env import MetadockEnv
>>> env = MetadockEnv().jinja_environment()
>>> env.from_string("{{ md.codeblock('This is a codeblock.', language = 'sh') }}").render()
'```sh\nThis is a codeblock.\n```'
|
+| md.list
| metadock.env.MetadockMdNamespace.list: (self, *items: str) -> str
| Produces a Markdown list from the given content by prepending each line with a dash ("- "). If any of its arguments are, themselves, formatted as Markdown lists, then they are simply indented as sublists.
>>> from metadock.env import MetadockEnv
>>> env = MetadockEnv().jinja_environment()
>>> env.from_string(
... "{{ md.list('This is a list.', md.list('This is a sublist,', 'in two pieces.')) }}"
... ).render()
'- This is a list.\n - This is a sublist,\n - in two pieces.'
|
+| md.tablehead
| metadock.env.MetadockMdNamespace.tablehead: (self, *header_cells: str, bold: bool = False) -> str
| Produces a Markdown table header from the given cells by joining each cell with pipes ("\|") and wrapping the result in pipes, plus adding a header divider row. Cell contents have their pipes escaped with a backslash ("\\"). To bold the header cell contents, supply `bold = true`.
>>> from metadock.env import MetadockEnv
>>> env = MetadockEnv().jinja_environment()
>>> env.from_string(
... "{{ md.tablehead('Column 1', 'Column 2', 'Column 3', bold = true) }}"
... ).render()
'\| <b>Column 1</b> \| <b>Column 2</b> \| <b>Column 3</b> \|\n\| --- \| --- \| --- \|'
|
+| md.tablerow
| metadock.env.MetadockMdNamespace.tablerow: (self, *row_cells: str) -> str
| Produces a Markdown table row from the given cells by joining each cell with pipes ("\|") and wrapping the result in pipes. Cell contents have their pipes escaped with a backslash ("\\").
>>> from metadock.env import MetadockEnv
>>> env = MetadockEnv().jinja_environment()
>>> env.from_string(
... "{{ md.tablehead('Column 1', 'Column 2', 'Column 3') }}\n"
... "{{ md.tablerow('Value 1', 'Value 2', 'Value 3') }}"
... ).render()
'\| Column 1 \| Column 2 \| Column 3 \|\n\| --- \| --- \| --- \|\n\| Value 1 \| Value 2 \| Value 3 \|'
|
@@ -331,12 +367,30 @@ Jinja filter reference
| Filter | Signature | Doc |
| --- | --- | --- |
+| md.convert
| metadock.env.MetadockMdNamespace.convert_filter: (self, md_content: str) -> str
| Filter which converts Markdown content to HTML, by invoking `marko.convert`.
>>> from metadock.env import MetadockEnv
>>> env = MetadockEnv().jinja_environment()
>>> env.from_string("{{ '# This is a heading\n\n> And a block quote.' \| md.convert }}").render()
'<h1>This is a heading</h1>\n<blockquote>\n<p>And a block quote.</p>\n</blockquote>\n'
|
+| md.list
| metadock.env.MetadockMdNamespace.list_filter: (self, values: str \| Iterable[str]) -> str
| Filter which unpacks an iterable of values into a Markdown list, or formats a single value as a Markdown list element.
>>> from metadock.env import MetadockEnv
>>> env = MetadockEnv().jinja_environment()
>>> env.from_string(
... "{{ ['This is a list.', 'This is a second element'] \| md.list }}\n"
... ).render()
'- This is a list.\n- This is a second element\n'
|
### `html` namespace
-None
+Jinja namespace which owns HTML-related functions and filters.
+
+**Macros**:
+
+ bold
+ code
+ codeblock
+ details
+ italic
+ summary
+ underline
+
+**Filters**:
+
+ escape
+ inline
+
@@ -352,6 +406,7 @@ Jinja macro reference
| html.details
| metadock.env.MetadockHtmlNamespace.details: (self, *contents: str) -> str
| Wraps a string in line-broken HTML details tags (<details></details>). Multiple arguments get separated by two line breaks.
>>> from metadock.env import MetadockEnv
>>> env = MetadockEnv().jinja_environment()
>>> env.from_string("{{ html.details('This is details text.') }}").render()
'<details>\nThis is details text.\n</details>'
|
| html.italic
| metadock.env.MetadockHtmlNamespace.italic: (self, content: str) -> str
| Wraps a string in HTML italic tags (<i></i>).
>>> from metadock.env import MetadockEnv
>>> env = MetadockEnv().jinja_environment()
>>> env.from_string("{{ html.italic('This is italic text.') }}").render()
'<i>This is italic text.</i>'
|
| html.summary
| metadock.env.MetadockHtmlNamespace.summary: (self, content: str) -> str
| Wraps a string in line-broken HTML summary tags (<summary>\n\n</summary>).
>>> from metadock.env import MetadockEnv
>>> env = MetadockEnv().jinja_environment()
>>> env.from_string("{{ html.summary('This is summary text.') }}").render()
'<summary>\nThis is summary text.\n</summary>'
|
+| html.underline
| metadock.env.MetadockHtmlNamespace.underline: (self, content: str) -> str
| Wraps a string in HTML underline tags (<u></u>).
>>> from metadock.env import MetadockEnv
>>> env = MetadockEnv().jinja_environment()
>>> env.from_string("{{ html.underline('This is underlined text.') }}").render()
'<u>This is underlined text.</u>'
|
@@ -362,6 +417,8 @@ Jinja filter reference
| Filter | Signature | Doc |
| --- | --- | --- |
+| html.escape
| metadock.env.MetadockHtmlNamespace.escape_filter: (self, content: str) -> str
| Filter which escapes a string by replacing all HTML special characters with their HTML entity equivalents.
>>> from metadock.env import MetadockEnv
>>> env = MetadockEnv().jinja_environment()
>>> env.from_string("{{ '<p>This is a paragraph.</p>' \| html.escape }}").render()
'<p>This is a paragraph.</p>'
|
+| html.inline
| metadock.env.MetadockHtmlNamespace.inline_filter: (self, content: str) -> str
| Filter which inlines a string by replacing all newlines with HTML line-breaks <br> singleton tags.
>>> from metadock.env import MetadockEnv
>>> env = MetadockEnv().jinja_environment()
>>> env.from_string("{{ 'This is a multi-line string.\nThis is the second line.\nAnd the third.' \| html.inline }}").render()
'This is a multi-line string.<br>This is the second line.<br>And the third.'
|
diff --git a/.metadock/generated_documents/jinja-md.code-snippets b/.metadock/generated_documents/jinja-md.code-snippets
index 1a30c26..6c9e6e2 100644
--- a/.metadock/generated_documents/jinja-md.code-snippets
+++ b/.metadock/generated_documents/jinja-md.code-snippets
@@ -53,6 +53,76 @@
// Metadock snippets for macros and filters in md namespace
+ "(macro) Markdown blockquote": {
+ "scope": "jinja-md,md",
+ "prefix": "md.blockquote",
+ "body": [
+ "md.blockquote($1)"
+ ],
+ "description": "Markdown blockquote macro"
+ },
+
+ "(macro) Markdown inline code": {
+ "scope": "jinja-md,md",
+ "prefix": "md.code",
+ "body": [
+ "md.code($1)"
+ ],
+ "description": "Markdown inline code macro"
+ },
+
+ "(macro) Markdown codeblock": {
+ "scope": "jinja-md,md",
+ "prefix": "md.codeblock",
+ "body": [
+ "md.codeblock($1)"
+ ],
+ "description": "Markdown codeblock macro"
+ },
+
+ "(macro) Markdown list": {
+ "scope": "jinja-md,md",
+ "prefix": "md.list",
+ "body": [
+ "md.list($1)"
+ ],
+ "description": "Markdown list macro"
+ },
+
+ "(macro) Markdown table head": {
+ "scope": "jinja-md,md",
+ "prefix": "md.tablehead",
+ "body": [
+ "md.tablehead($1)"
+ ],
+ "description": "Markdown table head macro"
+ },
+
+ "(macro) Markdown table row": {
+ "scope": "jinja-md,md",
+ "prefix": "md.tablerow",
+ "body": [
+ "md.tablerow($1)"
+ ],
+ "description": "Markdown table row macro"
+ },
+ "(filter) Markdown convert": {
+ "scope": "jinja-md,md",
+ "prefix": "md.convert",
+ "body": [
+ "md.convert($1)"
+ ],
+ "description": "Markdown convert filter"
+ },
+ "(filter) Markdown list": {
+ "scope": "jinja-md,md",
+ "prefix": "md.list",
+ "body": [
+ "md.list"
+ ],
+ "description": "Markdown list filter"
+ },
+
// Metadock snippets for macros and filters in html namespace
"(macro) HTML bold": {
@@ -109,4 +179,29 @@
"description": "HTML summary macro"
},
+ "(macro) HTML underline": {
+ "scope": "jinja-md,md",
+ "prefix": "html.underline",
+ "body": [
+ "html.underline($1)"
+ ],
+ "description": "HTML underline macro"
+ },
+ "(filter) HTML escape": {
+ "scope": "jinja-md,md",
+ "prefix": "html.escape",
+ "body": [
+ "html.escape"
+ ],
+ "description": "HTML escape filter"
+ },
+ "(filter) HTML inline": {
+ "scope": "jinja-md,md",
+ "prefix": "html.inline",
+ "body": [
+ "html.inline"
+ ],
+ "description": "HTML inline filter"
+ },
+
}
\ No newline at end of file
diff --git a/.metadock/metadock-build-docs.sh b/.metadock/metadock-build-docs.sh
index bf95620..bece6e4 100644
--- a/.metadock/metadock-build-docs.sh
+++ b/.metadock/metadock-build-docs.sh
@@ -8,13 +8,11 @@ poetry install
echo "Metadock-building README.md..."
poetry run metadock build -s README
cp .metadock/generated_documents/README.md README.md
+git add README.md
# metadock build Intellisense snippets
echo "Metadock-building Intellisense snippets..."
poetry run metadock build -s jinja-md
cp .metadock/generated_documents/jinja-md.code-snippets .vscode/jinja-md.code-snippets
-
-# capture all changes
-
-git add -A
\ No newline at end of file
+git add .vscode/jinja-md.code-snippets
\ No newline at end of file
diff --git a/.metadock/templated_documents/repo_readme_template.md b/.metadock/templated_documents/repo_readme_template.md
index 6970428..503a4d9 100644
--- a/.metadock/templated_documents/repo_readme_template.md
+++ b/.metadock/templated_documents/repo_readme_template.md
@@ -100,7 +100,7 @@ and filters which can be used to make formatting content easier. The macros and
{%- set namespace_intro -%}
### {{ namespace_title_prefix }} namespace
-{{ namespace_spec.get("info") }}
+{{ namespace_spec.get("docstring") }}
{% endset -%}
{%- set ns_macro_table -%}
{{ md.tablehead("Macro", "Signature", "Doc", bold=true) }}
diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
index 0be73a1..9f75820 100644
--- a/.pre-commit-config.yaml
+++ b/.pre-commit-config.yaml
@@ -1,13 +1,13 @@
repos:
-- repo: https://github.com/psf/black
- rev: 22.10.0
- hooks:
- - id: black
- args: [--line-length=120]
+ - repo: https://github.com/psf/black
+ rev: 22.10.0
+ hooks:
+ - id: black
+ args: [--line-length=120]
-- repo: local
- hooks:
- - id: metadock-build
- name: Metadock-build README
- entry: bash .metadock/metadock-build-docs.sh
- language: system
\ No newline at end of file
+ - repo: local
+ hooks:
+ - id: metadock-build
+ name: Metadock-build documents
+ entry: bash -c "bash .metadock/metadock-build-docs.sh" --
+ language: system
diff --git a/.vscode/jinja-md.code-snippets b/.vscode/jinja-md.code-snippets
index 1a30c26..6c9e6e2 100644
--- a/.vscode/jinja-md.code-snippets
+++ b/.vscode/jinja-md.code-snippets
@@ -53,6 +53,76 @@
// Metadock snippets for macros and filters in md namespace
+ "(macro) Markdown blockquote": {
+ "scope": "jinja-md,md",
+ "prefix": "md.blockquote",
+ "body": [
+ "md.blockquote($1)"
+ ],
+ "description": "Markdown blockquote macro"
+ },
+
+ "(macro) Markdown inline code": {
+ "scope": "jinja-md,md",
+ "prefix": "md.code",
+ "body": [
+ "md.code($1)"
+ ],
+ "description": "Markdown inline code macro"
+ },
+
+ "(macro) Markdown codeblock": {
+ "scope": "jinja-md,md",
+ "prefix": "md.codeblock",
+ "body": [
+ "md.codeblock($1)"
+ ],
+ "description": "Markdown codeblock macro"
+ },
+
+ "(macro) Markdown list": {
+ "scope": "jinja-md,md",
+ "prefix": "md.list",
+ "body": [
+ "md.list($1)"
+ ],
+ "description": "Markdown list macro"
+ },
+
+ "(macro) Markdown table head": {
+ "scope": "jinja-md,md",
+ "prefix": "md.tablehead",
+ "body": [
+ "md.tablehead($1)"
+ ],
+ "description": "Markdown table head macro"
+ },
+
+ "(macro) Markdown table row": {
+ "scope": "jinja-md,md",
+ "prefix": "md.tablerow",
+ "body": [
+ "md.tablerow($1)"
+ ],
+ "description": "Markdown table row macro"
+ },
+ "(filter) Markdown convert": {
+ "scope": "jinja-md,md",
+ "prefix": "md.convert",
+ "body": [
+ "md.convert($1)"
+ ],
+ "description": "Markdown convert filter"
+ },
+ "(filter) Markdown list": {
+ "scope": "jinja-md,md",
+ "prefix": "md.list",
+ "body": [
+ "md.list"
+ ],
+ "description": "Markdown list filter"
+ },
+
// Metadock snippets for macros and filters in html namespace
"(macro) HTML bold": {
@@ -109,4 +179,29 @@
"description": "HTML summary macro"
},
+ "(macro) HTML underline": {
+ "scope": "jinja-md,md",
+ "prefix": "html.underline",
+ "body": [
+ "html.underline($1)"
+ ],
+ "description": "HTML underline macro"
+ },
+ "(filter) HTML escape": {
+ "scope": "jinja-md,md",
+ "prefix": "html.escape",
+ "body": [
+ "html.escape"
+ ],
+ "description": "HTML escape filter"
+ },
+ "(filter) HTML inline": {
+ "scope": "jinja-md,md",
+ "prefix": "html.inline",
+ "body": [
+ "html.inline"
+ ],
+ "description": "HTML inline filter"
+ },
+
}
\ No newline at end of file
diff --git a/README.md b/README.md
index eb965fe..5ad7a7a 100644
--- a/README.md
+++ b/README.md
@@ -277,9 +277,24 @@ and filters which can be used to make formatting content easier. The macros and
### Global namespace
-The global namespace contains helpful macros and filters for manipulating data in the Jinja
-context. It also provides access to more specific namespaces through their respective identifiers,
-such as `md` and `html`.
+Jinja namespace for the global Metadock environment, including all global exports, filters, and namespaces.
+
+**Macros**:
+
+ debug
+
+**Namespaces**:
+
+ html
+ md
+
+**Filters**:
+
+ chain
+ inline
+ with_prefix
+ with_suffix
+ zip
@@ -311,7 +326,22 @@ Jinja filter reference
### `md` namespace
-None
+Jinja Namespace for Markdown-related functions and filters.
+
+**Macros**:
+
+ blockquote
+ code
+ codeblock
+ list
+ tablehead
+ tablerow
+
+**Filters**:
+
+ convert
+ list
+
@@ -321,6 +351,12 @@ Jinja macro reference
| Macro | Signature | Doc |
| --- | --- | --- |
+| md.blockquote
| metadock.env.MetadockMdNamespace.blockquote: (self, content: str) -> str
| Produces a Markdown blockquote from the given content by prepending each line with a gt symbol ("> ").
>>> from metadock.env import MetadockEnv
>>> env = MetadockEnv().jinja_environment()
>>> env.from_string("{{ md.blockquote('This is a blockquote.') }}").render()
'> This is a blockquote.'
|
+| md.code
| metadock.env.MetadockMdNamespace.code: (self, content: str) -> str
| Produces a Markdown inline code block from the given content by wrapping the string in graves ("\`").
>>> from metadock.env import MetadockEnv
>>> env = MetadockEnv().jinja_environment()
>>> env.from_string("{{ md.code('This is an inline code block.') }}").render()
'`This is an inline code block.`'
|
+| md.codeblock
| metadock.env.MetadockMdNamespace.codeblock: (self, content: str, language: str = '') -> str
| Produces a Markdown codeblock from the given content by wrapping the string in triple-graves ("\`\`\`"), and optionally specifies a language.
>>> from metadock.env import MetadockEnv
>>> env = MetadockEnv().jinja_environment()
>>> env.from_string("{{ md.codeblock('This is a codeblock.', language = 'sh') }}").render()
'```sh\nThis is a codeblock.\n```'
|
+| md.list
| metadock.env.MetadockMdNamespace.list: (self, *items: str) -> str
| Produces a Markdown list from the given content by prepending each line with a dash ("- "). If any of its arguments are, themselves, formatted as Markdown lists, then they are simply indented as sublists.
>>> from metadock.env import MetadockEnv
>>> env = MetadockEnv().jinja_environment()
>>> env.from_string(
... "{{ md.list('This is a list.', md.list('This is a sublist,', 'in two pieces.')) }}"
... ).render()
'- This is a list.\n - This is a sublist,\n - in two pieces.'
|
+| md.tablehead
| metadock.env.MetadockMdNamespace.tablehead: (self, *header_cells: str, bold: bool = False) -> str
| Produces a Markdown table header from the given cells by joining each cell with pipes ("\|") and wrapping the result in pipes, plus adding a header divider row. Cell contents have their pipes escaped with a backslash ("\\"). To bold the header cell contents, supply `bold = true`.
>>> from metadock.env import MetadockEnv
>>> env = MetadockEnv().jinja_environment()
>>> env.from_string(
... "{{ md.tablehead('Column 1', 'Column 2', 'Column 3', bold = true) }}"
... ).render()
'\| <b>Column 1</b> \| <b>Column 2</b> \| <b>Column 3</b> \|\n\| --- \| --- \| --- \|'
|
+| md.tablerow
| metadock.env.MetadockMdNamespace.tablerow: (self, *row_cells: str) -> str
| Produces a Markdown table row from the given cells by joining each cell with pipes ("\|") and wrapping the result in pipes. Cell contents have their pipes escaped with a backslash ("\\").
>>> from metadock.env import MetadockEnv
>>> env = MetadockEnv().jinja_environment()
>>> env.from_string(
... "{{ md.tablehead('Column 1', 'Column 2', 'Column 3') }}\n"
... "{{ md.tablerow('Value 1', 'Value 2', 'Value 3') }}"
... ).render()
'\| Column 1 \| Column 2 \| Column 3 \|\n\| --- \| --- \| --- \|\n\| Value 1 \| Value 2 \| Value 3 \|'
|
@@ -331,12 +367,30 @@ Jinja filter reference
| Filter | Signature | Doc |
| --- | --- | --- |
+| md.convert
| metadock.env.MetadockMdNamespace.convert_filter: (self, md_content: str) -> str
| Filter which converts Markdown content to HTML, by invoking `marko.convert`.
>>> from metadock.env import MetadockEnv
>>> env = MetadockEnv().jinja_environment()
>>> env.from_string("{{ '# This is a heading\n\n> And a block quote.' \| md.convert }}").render()
'<h1>This is a heading</h1>\n<blockquote>\n<p>And a block quote.</p>\n</blockquote>\n'
|
+| md.list
| metadock.env.MetadockMdNamespace.list_filter: (self, values: str \| Iterable[str]) -> str
| Filter which unpacks an iterable of values into a Markdown list, or formats a single value as a Markdown list element.
>>> from metadock.env import MetadockEnv
>>> env = MetadockEnv().jinja_environment()
>>> env.from_string(
... "{{ ['This is a list.', 'This is a second element'] \| md.list }}\n"
... ).render()
'- This is a list.\n- This is a second element\n'
|
### `html` namespace
-None
+Jinja namespace which owns HTML-related functions and filters.
+
+**Macros**:
+
+ bold
+ code
+ codeblock
+ details
+ italic
+ summary
+ underline
+
+**Filters**:
+
+ escape
+ inline
+
@@ -352,6 +406,7 @@ Jinja macro reference
| html.details
| metadock.env.MetadockHtmlNamespace.details: (self, *contents: str) -> str
| Wraps a string in line-broken HTML details tags (<details></details>). Multiple arguments get separated by two line breaks.
>>> from metadock.env import MetadockEnv
>>> env = MetadockEnv().jinja_environment()
>>> env.from_string("{{ html.details('This is details text.') }}").render()
'<details>\nThis is details text.\n</details>'
|
| html.italic
| metadock.env.MetadockHtmlNamespace.italic: (self, content: str) -> str
| Wraps a string in HTML italic tags (<i></i>).
>>> from metadock.env import MetadockEnv
>>> env = MetadockEnv().jinja_environment()
>>> env.from_string("{{ html.italic('This is italic text.') }}").render()
'<i>This is italic text.</i>'
|
| html.summary
| metadock.env.MetadockHtmlNamespace.summary: (self, content: str) -> str
| Wraps a string in line-broken HTML summary tags (<summary>\n\n</summary>).
>>> from metadock.env import MetadockEnv
>>> env = MetadockEnv().jinja_environment()
>>> env.from_string("{{ html.summary('This is summary text.') }}").render()
'<summary>\nThis is summary text.\n</summary>'
|
+| html.underline
| metadock.env.MetadockHtmlNamespace.underline: (self, content: str) -> str
| Wraps a string in HTML underline tags (<u></u>).
>>> from metadock.env import MetadockEnv
>>> env = MetadockEnv().jinja_environment()
>>> env.from_string("{{ html.underline('This is underlined text.') }}").render()
'<u>This is underlined text.</u>'
|
@@ -362,6 +417,8 @@ Jinja filter reference
| Filter | Signature | Doc |
| --- | --- | --- |
+| html.escape
| metadock.env.MetadockHtmlNamespace.escape_filter: (self, content: str) -> str
| Filter which escapes a string by replacing all HTML special characters with their HTML entity equivalents.
>>> from metadock.env import MetadockEnv
>>> env = MetadockEnv().jinja_environment()
>>> env.from_string("{{ '<p>This is a paragraph.</p>' \| html.escape }}").render()
'<p>This is a paragraph.</p>'
|
+| html.inline
| metadock.env.MetadockHtmlNamespace.inline_filter: (self, content: str) -> str
| Filter which inlines a string by replacing all newlines with HTML line-breaks <br> singleton tags.
>>> from metadock.env import MetadockEnv
>>> env = MetadockEnv().jinja_environment()
>>> env.from_string("{{ 'This is a multi-line string.\nThis is the second line.\nAnd the third.' \| html.inline }}").render()
'This is a multi-line string.<br>This is the second line.<br>And the third.'
|
diff --git a/metadock/env.py b/metadock/env.py
index 5267f93..97892aa 100644
--- a/metadock/env.py
+++ b/metadock/env.py
@@ -70,7 +70,8 @@ def jinja_environment(self) -> jinja2.Environment:
class MetadockMdNamespace(MetadockNamespace):
"""Jinja Namespace for Markdown-related functions and filters.
- Exports:
+ **Macros**:
+
blockquote
code
codeblock
@@ -78,7 +79,8 @@ class MetadockMdNamespace(MetadockNamespace):
tablehead
tablerow
- Filters:
+ **Filters**:
+
convert
list
"""
@@ -87,7 +89,7 @@ class MetadockMdNamespace(MetadockNamespace):
filters = ["convert", "list"]
def blockquote(self, content: str) -> str:
- """Produces a Markdown blockquote from the given content.
+ """Produces a Markdown blockquote from the given content by prepending each line with a gt symbol ("> ").
Args:
content (str): The content of the blockquote.
@@ -98,8 +100,20 @@ def blockquote(self, content: str) -> str:
_blockquoted = content.strip().replace("\n", "\n> ")
return f"> {_blockquoted}"
+ def code(self, content: str) -> str:
+ """Produces a Markdown inline code block from the given content by wrapping the string in graves ("`").
+
+ Args:
+ content (str): The content of the inline code block.
+
+ Returns:
+ str: The Markdown inline code block.
+ """
+ return f"`{content.strip()}`"
+
def codeblock(self, content: str, language: str = "") -> str:
- """Produces a Markdown codeblock from the given content.
+ """Produces a Markdown codeblock from the given content by wrapping the string in triple-graves ("```"),
+ and optionally specifies a language.
Args:
content (str): The content of the codeblock.
@@ -110,19 +124,32 @@ def codeblock(self, content: str, language: str = "") -> str:
"""
return f"```{language}\n{content.strip()}\n```"
- def code(self, content: str) -> str:
- """Produces a Markdown inline code block from the given content.
+ def list(self, *items: str) -> str:
+ """Produces a Markdown list from the given content by prepending each line with a dash ("- "). If any of its
+ arguments are, themselves, formatted as Markdown lists, then they are simply indented as sublists.
Args:
- content (str): The content of the inline code block.
+ *items (str): The individual items and/or sub-lists which compose the list.
Returns:
- str: The Markdown inline code block.
+ str: The composite Markdown list.
"""
- return f"`{content.strip()}`"
+ _list_prefixes = ("-", "*", "+")
+
+ def _is_md_list(item: str):
+ return item.lstrip().startswith(_list_prefixes)
+
+ listed_items = [list(map(str, item)) if _is_nonstr_iter(item) else [str(item)] for item in items]
+ flat_items = list(itertools.chain.from_iterable(listed_items))
+ indented_items = [item.replace("\n", "\n ") for item in flat_items if isinstance(item, str)]
+ return "\n".join(
+ (f"- {flat_item}" if not _is_md_list(flat_item) else f" {indented_item}")
+ for flat_item, indented_item in zip(flat_items, indented_items)
+ )
def tablerow(self, *cells: str) -> str:
- """Produces a Markdown table row from the given cells.
+ """Produces a Markdown table row from the given cells by joining each cell with pipes ("|") and wrapping the
+ result in pipes. Cell contents have their pipes escaped with a backslash ("\\").
Args:
*cells (str): The cells of the table row.
@@ -134,7 +161,9 @@ def tablerow(self, *cells: str) -> str:
return "| " + " | ".join(_pipe_escaped_cells) + " |"
def tablehead(self, *header_cells: str, bold: bool = False) -> str:
- """Produces a Markdown table header row from the given header cells.
+ """Produces a Markdown table header from the given cells by joining each cell with pipes ("|") and wrapping the
+ result in pipes, plus adding a header divider row. Cell contents have their pipes escaped with a backslash
+ ("\\"). To bold the header cell contents, supply `bold = true`.
Args:
*header_cells (str): The header cells of the table header row.
@@ -148,29 +177,6 @@ def tablehead(self, *header_cells: str, bold: bool = False) -> str:
_pipe_escaped_cells = tuple(MetadockHtmlNamespace().bold(cell) for cell in _pipe_escaped_cells)
return self.tablerow(*_pipe_escaped_cells) + "\n" + self.tablerow(*(["---"] * len(_pipe_escaped_cells)))
- def list(self, *items: str) -> str:
- """Produces a Markdown list from the given items, even when those items themselves may be formatted as Markdown
- lists.
-
- Args:
- *items (str): The individual items and/or sub-lists which compose the list.
-
- Returns:
- str: The composite Markdown list.
- """
- _list_prefixes = ("-", "*", "+")
-
- def _is_md_list(item: str):
- return item.lstrip().startswith(_list_prefixes)
-
- listed_items = [list(map(str, item)) if _is_nonstr_iter(item) else [str(item)] for item in items]
- flat_items = list(itertools.chain.from_iterable(listed_items))
- indented_items = [item.replace("\n", "\n ") for item in flat_items if isinstance(item, str)]
- return "\n".join(
- (f"- {flat_item}" if not _is_md_list(flat_item) else f" {indented_item}")
- for flat_item, indented_item in zip(flat_items, indented_items)
- )
-
def convert_filter(self, md_content: str) -> str:
"""Filter which converts Markdown content to HTML, by invoking `marko.convert`.
@@ -200,7 +206,8 @@ def list_filter(self, values: str | Iterable[str]) -> str:
class MetadockHtmlNamespace(MetadockNamespace):
"""Jinja namespace which owns HTML-related functions and filters.
- Exports:
+ **Macros**:
+
bold
code
codeblock
@@ -208,6 +215,11 @@ class MetadockHtmlNamespace(MetadockNamespace):
italic
summary
underline
+
+ **Filters**:
+
+ escape
+ inline
"""
exports = ["bold", "code", "codeblock", "details", "italic", "summary", "underline"]
@@ -308,7 +320,7 @@ def escape_filter(self, content: str) -> str:
return html.escape(content)
def inline_filter(self, content: str) -> str:
- """Filter which inlines a string by replacing all newlines with HTML line-break
singleton tags.
+ """Filter which inlines a string by replacing all newlines with HTML line-break
singleton tags.
Args:
content (str): Piped input string to be HTML-inlined.
@@ -322,14 +334,17 @@ def inline_filter(self, content: str) -> str:
class MetadockEnv(MetadockNamespace):
"""Jinja namespace for the global Metadock environment, including all global exports, filters, and namespaces.
- Exports:
+ **Macros**:
+
debug
- Namespaces:
+ **Namespaces**:
+
html
md
- Filters:
+ **Filters**:
+
chain
inline
with_prefix