Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

GH-72: Standardize markdown support #85

Merged
merged 10 commits into from
Dec 30, 2023
2 changes: 1 addition & 1 deletion examples/basic_site.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
Rule(
REMatcher(r'.*\.md'),
[OutputDirPathCalc('.html'), None],
JinjaMarkdownStep()
JinjaMarkdownStep(frontmatter_parser='simple')
),
# Copy everything else in static/ directories through.
Rule(
Expand Down
2 changes: 2 additions & 0 deletions examples/basic_site/index.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
---
template: base.jinja.html
footnote: Generated with Anchovy!
---

# Welcome to Example Site 1!

Expand Down
4 changes: 2 additions & 2 deletions examples/code_index.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,8 @@


MARKDOWN_TEMPLATE = """---
template = "base.jinja.html"
footnote = "Generated from {path} by Anchovy."
template: base.jinja.html
footnote: Generated from {path} by Anchovy.
---
# {path}

Expand Down
2 changes: 1 addition & 1 deletion examples/gallery.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
Rule(
REMatcher(r'.*\.md'),
[OutputDirPathCalc('.html'), None],
JinjaMarkdownStep()
JinjaMarkdownStep(frontmatter_parser='toml')
),
# Convert JPG files to WebP...
Rule(
Expand Down
14 changes: 8 additions & 6 deletions examples/gallery/index.md
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
template: base.jinja.html
footnote: Generated with Anchovy!
---
template = "base.jinja.html"
footnote = "Generated with Anchovy!"
---

# Photo Gallery

<div class="gallery">
<a href="static/images/home-sweet-home-cdk.webp"><img src="static/images/home-sweet-home-cdk.thumb.png" alt="A Vintage Automobile"></a>
<a href="static/images/nice-wheels-cdk.webp"><img src="static/images/nice-wheels-cdk.thumb.png" alt="A Old Wood-Sided House"></a>
<a href="static/images/stormy-cdk.webp"><img src="static/images/stormy-cdk.thumb.png" alt="A Boardwalk and Damaged Pines During a Storm"></a>
<a href="static/images/quayside-newcastle.webp"><img src="static/images/quayside-newcastle.thumb.png" alt="A Quay in Newcastle, England"></a>
<a href="static/images/home-sweet-home-cdk.webp"><img src="static/images/home-sweet-home-cdk.thumb.webp" alt="A Vintage Automobile"></a>
<a href="static/images/nice-wheels-cdk.webp"><img src="static/images/nice-wheels-cdk.thumb.webp" alt="A Old Wood-Sided House"></a>
<a href="static/images/stormy-cdk.webp"><img src="static/images/stormy-cdk.thumb.webp" alt="A Boardwalk and Damaged Pines During a Storm"></a>
<a href="static/images/quayside-newcastle.webp"><img src="static/images/quayside-newcastle.thumb.webp" alt="A Quay in Newcastle, England"></a>
</div>
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -71,9 +71,9 @@ all = ["anchovy[base]"]
# ignore this option.
cq = [
"anchovy[all]",
"commonmark>=0.9.1", "markdown>=3.4.3", "mistletoe>=1.1.0",
"tqdm>=4.65.0",
"minify-html>=0.11.1",
"ruamel.yaml>=0.18.5",
"pylint",
"pyright",
"pytest",
Expand Down
51 changes: 51 additions & 0 deletions src/anchovy/components/md_frontmatter.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import sys
import typing as t


def simple_frontmatter_parser(content: str) -> dict:
"""
Read metadata from the front of a markdown-formatted text in a very simple
YAML-like format, without value parsing.
"""
meta = {}
lines = content.splitlines()

for line in lines:
if ':' not in line:
break

Check warning on line 15 in src/anchovy/components/md_frontmatter.py

View check run for this annotation

Codecov / codecov/patch

src/anchovy/components/md_frontmatter.py#L15

Added line #L15 was not covered by tests
key, value = line.split(':', 1)
if not key.isidentifier():
break

Check warning on line 18 in src/anchovy/components/md_frontmatter.py

View check run for this annotation

Codecov / codecov/patch

src/anchovy/components/md_frontmatter.py#L18

Added line #L18 was not covered by tests
meta[key.strip()] = value.strip()

print(meta, '...')
return meta


def get_toml_frontmatter_parser():
if sys.version_info < (3, 11):
import tomli as tomllib
else:
import tomllib
return tomllib.loads


def get_yaml_frontmatter_parser():
from ruamel.yaml import YAML
return YAML(typ='safe').load


FrontMatterParser = t.Callable[[str], dict]
FrontMatterParserName = t.Literal['simple', 'toml', 'yaml']

FRONTMATTER_PARSER_FACTORIES: dict[FrontMatterParserName, t.Callable[[], FrontMatterParser]] = {
'simple': lambda: simple_frontmatter_parser,
'toml': get_toml_frontmatter_parser,
'yaml': get_yaml_frontmatter_parser,
}


def get_frontmatter_parser(parser) -> FrontMatterParser:
if callable(parser):
return parser

Check warning on line 50 in src/anchovy/components/md_frontmatter.py

View check run for this annotation

Codecov / codecov/patch

src/anchovy/components/md_frontmatter.py#L50

Added line #L50 was not covered by tests
return FRONTMATTER_PARSER_FACTORIES[parser]()
15 changes: 9 additions & 6 deletions src/anchovy/components/md_rendering.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,12 @@
"""
from __future__ import annotations

import sys
import typing as t

from markdown_it.common.utils import escapeHtml, unescapeAll
from markdown_it.renderer import RendererHTML

if sys.version_info < (3, 11):
import tomli as tomllib
else:
import tomllib
from .md_frontmatter import simple_frontmatter_parser, FrontMatterParser

if t.TYPE_CHECKING:
from collections.abc import Sequence
Expand Down Expand Up @@ -60,6 +56,10 @@ class AnchovyRendererHTML(RendererHTML):
A customized markdown-it-py HTML renderer, with hooks for better pygments
integration and toml frontmatter support.
"""
def __init__(self, parser: t.Any = None):
super().__init__(parser)
self.front_matter_parser: FrontMatterParser = simple_frontmatter_parser

# https://github.com/executablebooks/markdown-it-py/issues/256
def fence(self, tokens: Sequence[Token], idx: int, options: OptionsDict, env: EnvType):
"""
Expand All @@ -76,10 +76,13 @@ def fence(self, tokens: Sequence[Token], idx: int, options: OptionsDict, env: En
or escapeHtml(token.content)
)

def set_front_matter_parser(self, parser: FrontMatterParser):
self.front_matter_parser = parser

def front_matter(self, tokens: Sequence[Token], idx: int, _options: OptionsDict, env: EnvType):
"""
Handles parsing markdown frontmatter using TOML.
"""
parsed = tomllib.loads(tokens[idx].content)
parsed = self.front_matter_parser(tokens[idx].content)
env['anchovy_meta'].update(parsed)
return ''
3 changes: 2 additions & 1 deletion src/anchovy/custody.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ class Custodian:
Class for managing custody info and intelligent rebuilds.
"""
encoding = 'utf-8'
newline = '\n'
context: 'Context'

def __init__(self,
Expand Down Expand Up @@ -193,7 +194,7 @@ def dump_file(self, path: Path):
'graph': self.graph,
'meta': self.meta,
}
with path.open('w', encoding=self.encoding) as file:
with path.open('w', encoding=self.encoding, newline=self.newline) as file:
json.dump(data, file, indent=2)

def update_meta(self, entry: CustodyEntry):
Expand Down
Loading