Snippet include file brefore/after label #2296
-
DescriptionI am converting my 5000 pages (yes, 5k pages) Python training materials from ReST to Markdown and I would like to replicate behavior of
So, that I can include file content from the first line until the desired label (in this case comment "# Solution"). I cannot use numeric slices, because solution lengths are variable for each assignment I have in my materials. BenefitsAbility to include only part of the file. Solution Idea--8<-- "myfile.py" before:"# Solution" or --8<-- "myfile.py">"# Solution" or --8<-- "myfile.py":>"# Solution" Also mind, that one-liner (including fence) syntax for Snippets would be nice:
|
Beta Was this translation helpful? Give feedback.
Replies: 2 comments
-
I wrote small extension for SuperFences: File import re
from pathlib import Path
from pymdownx.superfences import SuperFencesException
def formatter(source, language, css_class, options, md, **kwargs):
file = re.search(r'file="(.+)"', source).group(1)
before = re.search(r'before="(.+)"', source).group(1)
path = Path(__file__).parent.parent / 'docs' / file
if not path.exists():
raise SuperFencesException(f'File {path} does not exist')
content = path.read_text()
if before not in content:
raise SuperFencesException(f'File {path} does not contain {before}')
assignment, solution = content.split(before)
return f"<pre><code>{assignment}</code></pre>" File - pymdownx.superfences:
custom_fences:
- name: include
class: include
format: !!python/name:extensions.include.formatter File
Of course without escaping the ` (ticks, fences) characters. It works, but I am struggling with code highlighting, adding title (to work the same as regular title for fence) and getting an absolute path of a file which triggered my function. If I do: <div class="language-python highlight">
<span class="filename">{path.stem}</span>
<pre>
<code>{assignment}</code>
</pre>
</div> Then in output HTML there is a blank line between title and code block. Any help appreciated :) |
Beta Was this translation helpful? Give feedback.
-
Just wrap your logic around the default highlighter.
import re
from pathlib import Path
from pymdownx.superfences import SuperFencesException, highlight_validator
import markdown
MD = """
```include title="Title"
file="myfile.py"
before="# Solution"
```
"""
def formatter(source, language, css_class, options, md, **kwargs):
file = re.search(r'file="(.+)"', source).group(1)
before = re.search(r'before="(.+)"', source).group(1)
path = Path(__file__).parent / file
if not path.exists():
raise SuperFencesException(f'File {path} does not exist')
content = path.read_text()
if before not in content:
raise SuperFencesException(f'File {path} does not contain {before}')
assignment, solution = content.split(before)
return md.preprocessors['fenced_code_block'].highlight(
src=assignment,
class_name=css_class,
language='python',
md=md,
options=options,
**kwargs
)
html = markdown.markdown(
MD,
extensions=['pymdownx.superfences'],
extension_configs={
'pymdownx.superfences': {
'custom_fences': [
{
'name': 'include',
'class': 'inlcude',
'format': formatter,
'validator': highlight_validator
}
]
}
}
)
print(html) myfile.py print('hello world') # Solution Results <div class="highlight"><span class="filename">Title</span><pre><span></span><code><span class="nb">print</span><span class="p">(</span><span class="s1">'hello world'</span><span class="p">)</span>
</code></pre></div> |
Beta Was this translation helpful? Give feedback.
@astromatt
Just wrap your logic around the default highlighter.