-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
9 changed files
with
612 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,178 @@ | ||
from __future__ import annotations | ||
|
||
from pathlib import Path | ||
import typing as t | ||
|
||
from anchovy import ( | ||
AnchovyCSSStep, | ||
AssetMinifierStep, | ||
CSSMinifierStep, | ||
DirectCopyStep, | ||
Matcher, | ||
InputBuildSettings, | ||
JinjaExtendedMarkdownStep, | ||
JinjaRenderStep, | ||
OutputDirPathCalc, | ||
PathCalc, | ||
REMatcher, | ||
ResourcePackerStep, | ||
Rule, | ||
Step, | ||
UnpackArchiveStep, | ||
WorkingDirPathCalc, | ||
) | ||
from anchovy.custody import CustodyEntry | ||
|
||
if t.TYPE_CHECKING: | ||
from jinja2 import Environment | ||
|
||
|
||
MARKDOWN_TEMPLATE = """--- | ||
template = "base.jinja.html" | ||
footnote = "Generated from {path} by Anchovy." | ||
--- | ||
# {path} | ||
```py | ||
{code} | ||
``` | ||
""" | ||
|
||
|
||
class Code2MarkdownStep(Step): | ||
encoding = 'utf-8' | ||
newline = '\n' | ||
template = MARKDOWN_TEMPLATE | ||
def __call__(self, path: Path, output_paths: list[Path]): | ||
code = path.read_text(self.encoding) | ||
processed = self.template.format(path=path.name, code=code) | ||
for target_path in output_paths: | ||
target_path.parent.mkdir(parents=True, exist_ok=True) | ||
target_path.write_text(processed, self.encoding, newline=self.newline) | ||
|
||
|
||
class CodeIndexStep(JinjaRenderStep): | ||
encoding = 'utf-8' | ||
|
||
def __init__(self, | ||
leaf_matcher: Matcher, | ||
leaf_calc: PathCalc, | ||
env: Environment | None = None, | ||
extra_globals: dict[str, t.Any] | None = None): | ||
super().__init__(env, extra_globals) | ||
self.leaf_matcher = leaf_matcher | ||
self.leaf_calc = leaf_calc | ||
|
||
@classmethod | ||
def get_dependencies(cls): | ||
return super().get_dependencies() | ||
|
||
def __call__(self, path: Path, output_paths: list[Path]): | ||
matched_paths: list[Path] = [path] | ||
leaves: list[tuple[Path, Path]] = [] | ||
for sibling in path.parent.iterdir(): | ||
print('sibling:', sibling) | ||
if sibling == path or sibling.is_dir(): | ||
continue | ||
print('sibling matched thus') | ||
if match := self.leaf_matcher(self.context, sibling): | ||
print('sibling matched', match) | ||
matched_paths.append(sibling) | ||
leaves.append(( | ||
sibling, | ||
self.leaf_calc(self.context, sibling, match).relative_to(self.context['output_dir']), | ||
)) | ||
|
||
print('leaves:', leaves) | ||
self.render_template( | ||
path.relative_to(self.context['working_dir']).as_posix(), | ||
{'leaves': leaves}, | ||
output_paths | ||
) | ||
return matched_paths, output_paths | ||
|
||
|
||
# Optional, and can be overridden with CLI arguments. | ||
SETTINGS = InputBuildSettings( | ||
input_dir=Path(__file__).parent / 'code_index', | ||
working_dir=Path('working/code_index'), | ||
output_dir=Path('output/code_index'), | ||
custody_cache=Path('output/code_index.json'), | ||
) | ||
RULES = [ | ||
# Ignore dotfiles found in either the input_dir or the working dir. | ||
Rule( | ||
( | ||
REMatcher(r'(.*/)*\..*', parent_dir='input_dir') | ||
| REMatcher(r'(.*/)*\..*', parent_dir='working_dir') | ||
), | ||
None | ||
), | ||
# Unpack archives. | ||
Rule( | ||
REMatcher(r'.*\.zip'), | ||
[WorkingDirPathCalc(transform=lambda p: p.parent), None], | ||
UnpackArchiveStep() | ||
), | ||
# Embed Python files in Markdown. | ||
Rule( | ||
REMatcher(r'.*\.py'), | ||
[WorkingDirPathCalc('.md')], | ||
Code2MarkdownStep() | ||
), | ||
# Render markdown files and stop processing. | ||
Rule( | ||
REMatcher(r'.*\.md'), | ||
[WorkingDirPathCalc('.html'), None], | ||
JinjaExtendedMarkdownStep( | ||
default_template='base.j.html', | ||
pygments_params={'classprefix': 'pyg-'}, | ||
) | ||
), | ||
# Render Jinja indices through working dir (so there's time for the archive | ||
# to unpack) and stop processing. | ||
Rule( | ||
REMatcher(r'index\.jinja\.html', parent_dir='input_dir'), | ||
[WorkingDirPathCalc(), None], | ||
DirectCopyStep() | ||
), | ||
Rule( | ||
REMatcher(r'index(?P<ext>\.jinja\.html)', parent_dir='working_dir'), | ||
[WorkingDirPathCalc('.html'), None], | ||
CodeIndexStep( | ||
REMatcher(r'.*\.py'), | ||
OutputDirPathCalc('.html') | ||
) | ||
), | ||
# Ignore all other Jinja templates. | ||
Rule(REMatcher(r'.*\.jinja\.html'), None), | ||
# Preprocess Anchovy CSS and stop processing. | ||
Rule( | ||
REMatcher(r'.*(?P<ext>\.anchovy\.css)'), | ||
[WorkingDirPathCalc('.css'), None], | ||
AnchovyCSSStep() | ||
), | ||
# Pack CSS. Have to wait for working dir so Anchovy CSS processing is done. | ||
Rule( | ||
REMatcher(r'.*/css_pack.txt', parent_dir='input_dir'), | ||
[WorkingDirPathCalc(), None], | ||
DirectCopyStep() | ||
), | ||
Rule( | ||
REMatcher(r'.*/css_pack.txt', parent_dir='working_dir'), | ||
[WorkingDirPathCalc('.css'), None], | ||
ResourcePackerStep('working_dir') | ||
), | ||
# Minify packed CSS and stop processing. | ||
Rule( | ||
REMatcher(r'.*/css_pack\.css', parent_dir='working_dir'), | ||
[OutputDirPathCalc(), None], | ||
CSSMinifierStep() | ||
), | ||
# Minify HTML/JS and stop processing. | ||
Rule( | ||
REMatcher(r'.*\.(html|js)', parent_dir='working_dir'), | ||
[OutputDirPathCalc(), None], | ||
AssetMinifierStep() | ||
), | ||
] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
<!doctype html> | ||
<html lang="en"> | ||
<head> | ||
<link rel="stylesheet" type="text/css" href="static/css_pack.css"> | ||
</head> | ||
<body> | ||
{% block content %} | ||
<main> | ||
{{ rendered_markdown | safe }} | ||
</main> | ||
{% endblock %} | ||
<footer> | ||
{{ footnote }} | ||
</footer> | ||
</body> | ||
</html> |
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
{% set footnote = "An index of Anchovy example configuration code." %} | ||
{% extends "base.jinja.html" %} | ||
{% block content %} | ||
<main> | ||
<h1>Examples</h1> | ||
{% for source, target in leaves %} | ||
<a href="{{target.as_posix()}}"><h2>{{ source.name }}</h2></a> | ||
{% endfor %} | ||
</main> | ||
{% endblock %} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
body { | ||
font-family: 'Arial Narrow', sans-serif; | ||
color: #eee; | ||
background-color: #333; | ||
padding: 10px; | ||
} | ||
|
||
main, footer { | ||
margin: 0 auto; | ||
max-width: 800px; | ||
} | ||
|
||
footer { | ||
border-top: 1px #eee dotted; | ||
padding-top: 10px; | ||
} | ||
|
||
.highlight { | ||
padding: 10px; | ||
border-radius: 5px; | ||
} | ||
|
||
a { | ||
color: #eee; | ||
:hover { | ||
color: #aaf; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
static/core.css | ||
static/pygments.css |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,85 @@ | ||
.highlight { | ||
line-height: 1.2em; | ||
background: #272822; color: #f8f8f2; | ||
span.linenos { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; } | ||
.linenos.special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; } | ||
.hll { background-color: #49483e } | ||
.pyg-c { color: #959077 } /* Comment */ | ||
.pyg-err { color: #ed007e; background-color: #1e0010 } /* Error */ | ||
.pyg-esc { color: #f8f8f2 } /* Escape */ | ||
.pyg-g { color: #f8f8f2 } /* Generic */ | ||
.pyg-k { color: #66d9ef } /* Keyword */ | ||
.pyg-l { color: #ae81ff } /* Literal */ | ||
.pyg-n { color: #f8f8f2 } /* Name */ | ||
.pyg-o { color: #ff4689 } /* Operator */ | ||
.pyg-x { color: #f8f8f2 } /* Other */ | ||
.pyg-p { color: #f8f8f2 } /* Punctuation */ | ||
.pyg-ch { color: #959077 } /* Comment.Hashbang */ | ||
.pyg-cm { color: #959077 } /* Comment.Multiline */ | ||
.pyg-cp { color: #959077 } /* Comment.Preproc */ | ||
.pyg-cpf { color: #959077 } /* Comment.PreprocFile */ | ||
.pyg-c1 { color: #959077 } /* Comment.Single */ | ||
.pyg-cs { color: #959077 } /* Comment.Special */ | ||
.pyg-gd { color: #ff4689 } /* Generic.Deleted */ | ||
.pyg-ge { color: #f8f8f2; font-style: italic } /* Generic.Emph */ | ||
.pyg-ges { color: #f8f8f2; font-weight: bold; font-style: italic } /* Generic.EmphStrong */ | ||
.pyg-gr { color: #f8f8f2 } /* Generic.Error */ | ||
.pyg-gh { color: #f8f8f2 } /* Generic.Heading */ | ||
.pyg-gi { color: #a6e22e } /* Generic.Inserted */ | ||
.pyg-go { color: #66d9ef } /* Generic.Output */ | ||
.pyg-gp { color: #ff4689; font-weight: bold } /* Generic.Prompt */ | ||
.pyg-gs { color: #f8f8f2; font-weight: bold } /* Generic.Strong */ | ||
.pyg-gu { color: #959077 } /* Generic.Subheading */ | ||
.pyg-gt { color: #f8f8f2 } /* Generic.Traceback */ | ||
.pyg-kc { color: #66d9ef } /* Keyword.Constant */ | ||
.pyg-kd { color: #66d9ef } /* Keyword.Declaration */ | ||
.pyg-kn { color: #ff4689 } /* Keyword.Namespace */ | ||
.pyg-kp { color: #66d9ef } /* Keyword.Pseudo */ | ||
.pyg-kr { color: #66d9ef } /* Keyword.Reserved */ | ||
.pyg-kt { color: #66d9ef } /* Keyword.Type */ | ||
.pyg-ld { color: #e6db74 } /* Literal.Date */ | ||
.pyg-m { color: #ae81ff } /* Literal.Number */ | ||
.pyg-s { color: #e6db74 } /* Literal.String */ | ||
.pyg-na { color: #a6e22e } /* Name.Attribute */ | ||
.pyg-nb { color: #f8f8f2 } /* Name.Builtin */ | ||
.pyg-nc { color: #a6e22e } /* Name.Class */ | ||
.pyg-no { color: #66d9ef } /* Name.Constant */ | ||
.pyg-nd { color: #a6e22e } /* Name.Decorator */ | ||
.pyg-ni { color: #f8f8f2 } /* Name.Entity */ | ||
.pyg-ne { color: #a6e22e } /* Name.Exception */ | ||
.pyg-nf { color: #a6e22e } /* Name.Function */ | ||
.pyg-nl { color: #f8f8f2 } /* Name.Label */ | ||
.pyg-nn { color: #f8f8f2 } /* Name.Namespace */ | ||
.pyg-nx { color: #a6e22e } /* Name.Other */ | ||
.pyg-py { color: #f8f8f2 } /* Name.Property */ | ||
.pyg-nt { color: #ff4689 } /* Name.Tag */ | ||
.pyg-nv { color: #f8f8f2 } /* Name.Variable */ | ||
.pyg-ow { color: #ff4689 } /* Operator.Word */ | ||
.pyg-pm { color: #f8f8f2 } /* Punctuation.Marker */ | ||
.pyg-w { color: #f8f8f2 } /* Text.Whitespace */ | ||
.pyg-mb { color: #ae81ff } /* Literal.Number.Bin */ | ||
.pyg-mf { color: #ae81ff } /* Literal.Number.Float */ | ||
.pyg-mh { color: #ae81ff } /* Literal.Number.Hex */ | ||
.pyg-mi { color: #ae81ff } /* Literal.Number.Integer */ | ||
.pyg-mo { color: #ae81ff } /* Literal.Number.Oct */ | ||
.pyg-sa { color: #e6db74 } /* Literal.String.Affix */ | ||
.pyg-sb { color: #e6db74 } /* Literal.String.Backtick */ | ||
.pyg-sc { color: #e6db74 } /* Literal.String.Char */ | ||
.pyg-dl { color: #e6db74 } /* Literal.String.Delimiter */ | ||
.pyg-sd { color: #e6db74 } /* Literal.String.Doc */ | ||
.pyg-s2 { color: #e6db74 } /* Literal.String.Double */ | ||
.pyg-se { color: #ae81ff } /* Literal.String.Escape */ | ||
.pyg-sh { color: #e6db74 } /* Literal.String.Heredoc */ | ||
.pyg-si { color: #e6db74 } /* Literal.String.Interpol */ | ||
.pyg-sx { color: #e6db74 } /* Literal.String.Other */ | ||
.pyg-sr { color: #e6db74 } /* Literal.String.Regex */ | ||
.pyg-s1 { color: #e6db74 } /* Literal.String.Single */ | ||
.pyg-ss { color: #e6db74 } /* Literal.String.Symbol */ | ||
.pyg-bp { color: #f8f8f2 } /* Name.Builtin.Pseudo */ | ||
.pyg-fm { color: #a6e22e } /* Name.Function.Magic */ | ||
.pyg-vc { color: #f8f8f2 } /* Name.Variable.Class */ | ||
.pyg-vg { color: #f8f8f2 } /* Name.Variable.Global */ | ||
.pyg-vi { color: #f8f8f2 } /* Name.Variable.Instance */ | ||
.pyg-vm { color: #f8f8f2 } /* Name.Variable.Magic */ | ||
.pyg-il { color: #ae81ff } /* Literal.Number.Integer.Long */ | ||
} |
Oops, something went wrong.