added the basic template rendering loop at the end
This commit is contained in:
parent
7c65e021e7
commit
b293684fb7
2
.gitignore
vendored
2
.gitignore
vendored
|
@ -160,3 +160,5 @@ cython_debug/
|
||||||
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
|
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
|
||||||
#.idea/
|
#.idea/
|
||||||
|
|
||||||
|
# Test directory
|
||||||
|
blort/
|
||||||
|
|
6
doc/configuration.yaml
Normal file
6
doc/configuration.yaml
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
# The prefix to apply to all internally-generated URLs. Default is "/".
|
||||||
|
url_prefix: /
|
||||||
|
# The template directory name under the Obsidian vault. Default is ".dragonglass.tmpl".
|
||||||
|
template_directory: .dragonglass.tmpl
|
||||||
|
# The default template name. Default is "default.html".
|
||||||
|
default_template: default.html
|
|
@ -9,12 +9,18 @@ import yaml
|
||||||
from .tree import SourceIndex, SourceNode
|
from .tree import SourceIndex, SourceNode
|
||||||
|
|
||||||
|
|
||||||
|
DEFAULT_TEMPLATE_DIRECTORY = ".dragonglass.tmpl"
|
||||||
|
DEFAULT_TEMPLATE_NAME = "default.html"
|
||||||
|
|
||||||
|
|
||||||
class Context:
|
class Context:
|
||||||
def __init__(self) -> None:
|
def __init__(self) -> None:
|
||||||
self.source_dir: Path | None = None
|
self.source_dir: Path | None = None
|
||||||
|
self.template_dir: Path | None = None
|
||||||
self.config: dict[str, Any] = {}
|
self.config: dict[str, Any] = {}
|
||||||
self.src_index: SourceIndex | None = None
|
self.src_index: SourceIndex | None = None
|
||||||
self.current_node: SourceNode | None = None
|
self.current_node: SourceNode | None = None
|
||||||
|
self._default_template_name: str | None = None
|
||||||
|
|
||||||
def load_config(self, args: Namespace) -> None:
|
def load_config(self, args: Namespace) -> None:
|
||||||
config_filename: str = str(args.config) if args.config else ".dragonglass"
|
config_filename: str = str(args.config) if args.config else ".dragonglass"
|
||||||
|
@ -23,10 +29,15 @@ class Context:
|
||||||
if config_path.exists() and config_path.is_file():
|
if config_path.exists() and config_path.is_file():
|
||||||
with open(config_path, "r") as f:
|
with open(config_path, "r") as f:
|
||||||
self.config = yaml.full_load(f)
|
self.config = yaml.full_load(f)
|
||||||
|
self.template_dir = self.source_dir / self.config.get("template_directory", DEFAULT_TEMPLATE_DIRECTORY)
|
||||||
|
self._default_template_name = self.config.get("default_template", DEFAULT_TEMPLATE_NAME)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def url_prefix(self) -> str:
|
def url_prefix(self) -> str:
|
||||||
rc = self.config.get("url_prefix", "/")
|
rc = self.config.get("url_prefix", "/")
|
||||||
return rc if rc.endswith("/") else rc + '/'
|
return rc if rc.endswith("/") else rc + '/'
|
||||||
|
|
||||||
|
def get_template_name_for_node(self, node: SourceNode) -> str:
|
||||||
|
if not self.template_dir.is_dir():
|
||||||
|
return DEFAULT_TEMPLATE_NAME
|
||||||
|
return self._default_template_name
|
||||||
|
|
|
@ -1,10 +1,12 @@
|
||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
import argparse
|
import argparse
|
||||||
|
import shutil
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
||||||
from .config import Context
|
from .config import Context
|
||||||
from .mparse import create_markdown_parser
|
from .mparse import create_markdown_parser
|
||||||
|
from .template import create_template_environment
|
||||||
from .tree import SourceIndex, generate_list
|
from .tree import SourceIndex, generate_list
|
||||||
|
|
||||||
# The command line parser
|
# The command line parser
|
||||||
|
@ -29,6 +31,7 @@ def main() -> int:
|
||||||
return 1
|
return 1
|
||||||
|
|
||||||
context.load_config(args)
|
context.load_config(args)
|
||||||
|
tenv = create_template_environment(context)
|
||||||
|
|
||||||
nodes = generate_list(context.source_dir)
|
nodes = generate_list(context.source_dir)
|
||||||
for node in nodes:
|
for node in nodes:
|
||||||
|
@ -52,4 +55,19 @@ def main() -> int:
|
||||||
print(node.text)
|
print(node.text)
|
||||||
print("------ END TEXT ------")
|
print("------ END TEXT ------")
|
||||||
|
|
||||||
|
if not dest_dir.exists():
|
||||||
|
dest_dir.mkdir()
|
||||||
|
|
||||||
|
for node in nodes:
|
||||||
|
p = node.target_file(dest_dir)
|
||||||
|
if node.is_dir:
|
||||||
|
p.mkdir(exist_ok=True)
|
||||||
|
elif node.is_md:
|
||||||
|
tmpl = tenv.get_template(context.get_template_name_for_node(node))
|
||||||
|
data = tmpl.render(node.make_vars())
|
||||||
|
with p.open("wt") as f:
|
||||||
|
f.write(data)
|
||||||
|
else:
|
||||||
|
shutil.copyfile(context.source_dir / node.path, p)
|
||||||
|
|
||||||
return 0
|
return 0
|
||||||
|
|
28
src/dragonglass/template.py
Normal file
28
src/dragonglass/template.py
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
from jinja2 import Environment, BaseLoader, ChoiceLoader, FunctionLoader, FileSystemLoader
|
||||||
|
|
||||||
|
from .config import Context, DEFAULT_TEMPLATE_NAME
|
||||||
|
|
||||||
|
DEFAULT_TEMPLATE = """
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>{{ title }}</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h1>{{ title }}</h1>
|
||||||
|
{{ text }}
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
def _create_loader(ctxt: Context) -> BaseLoader:
|
||||||
|
return ChoiceLoader([
|
||||||
|
FileSystemLoader(ctxt.template_dir),
|
||||||
|
FunctionLoader(lambda n: DEFAULT_TEMPLATE if n == DEFAULT_TEMPLATE_NAME else None)
|
||||||
|
])
|
||||||
|
|
||||||
|
|
||||||
|
def create_template_environment(ctxt: Context) -> Environment:
|
||||||
|
return Environment(loader=_create_loader(ctxt))
|
|
@ -40,6 +40,12 @@ class SourceNode:
|
||||||
def path(self) -> Path:
|
def path(self) -> Path:
|
||||||
return self._path
|
return self._path
|
||||||
|
|
||||||
|
def target_file(self, dest_dir: Path) -> Path:
|
||||||
|
p = self._path
|
||||||
|
if self._is_md:
|
||||||
|
p = p.with_suffix('.html')
|
||||||
|
return dest_dir / p
|
||||||
|
|
||||||
def link_target(self, prefix: str = "/") -> str:
|
def link_target(self, prefix: str = "/") -> str:
|
||||||
xpath = self._path.with_suffix('.html') if self._is_md else self._path
|
xpath = self._path.with_suffix('.html') if self._is_md else self._path
|
||||||
return urlquote(prefix + xpath.as_posix())
|
return urlquote(prefix + xpath.as_posix())
|
||||||
|
@ -62,6 +68,12 @@ class SourceNode:
|
||||||
with open(source_dir / self._path, "r", encoding="utf-8") as f:
|
with open(source_dir / self._path, "r", encoding="utf-8") as f:
|
||||||
self.text = markdown_parser.convert(f.read())
|
self.text = markdown_parser.convert(f.read())
|
||||||
|
|
||||||
|
def make_vars(self) -> dict[str, Any]:
|
||||||
|
return {
|
||||||
|
"text": self.text,
|
||||||
|
"title": self._path.stem
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
def generate_list(source_root: Path) -> list[SourceNode]:
|
def generate_list(source_root: Path) -> list[SourceNode]:
|
||||||
nodes: list[SourceNode] = []
|
nodes: list[SourceNode] = []
|
||||||
|
|
Loading…
Reference in New Issue
Block a user