Parse content files twice – for gemini and www with different 'mode' variable (see NOTES.md). Fixed bug (in abs2rel) causing lack of link labels. Few other minor fixes.
This commit is contained in:
parent
b52648c5e7
commit
35a7c14c1a
6
NOTES.md
6
NOTES.md
|
@ -2,9 +2,9 @@ build.py
|
|||
|
||||
# Configs
|
||||
|
||||
* **\[defaults\]** – default frontmatter fields values (i.e. `author=faildev_mode`)
|
||||
* **\[defaults\]** – default frontmatter fields values (i.e. `author=faildev_mode`)
|
||||
* **\[variables\]** – project-wide variables (i.e. `root=rawtext.club/~faildev_mode`)
|
||||
* **\[variables.gemini\]** – project-wide variables gemini-exclusive
|
||||
* **\[variables.gemini\]** – project-wide variables gemini-exclusive
|
||||
* **\[variables.www\]** – project-wide variables www-exclusive
|
||||
* **\[redirections\]** – redirection table (i.e. `youtube.com=invidious.citizen4.eu`)
|
||||
* **\[templates\]** – template routing table (i.e. `articles/*.gmi=articles`)
|
||||
|
@ -32,7 +32,7 @@ for path in content_files:
|
|||
if item.mode == 'www' or not item.mode:
|
||||
content = evaluate(item.content, {mode='www'})
|
||||
content = evaluate(item.template, {mode='www', item=item})
|
||||
content = gemini2html(content)
|
||||
content = gemtext2html(content)
|
||||
content = evaluate(item.html_template, {item=item})
|
||||
save_this(f'html/{item.location}.html', content)
|
||||
```
|
||||
|
|
132
_src/build.py
132
_src/build.py
|
@ -12,7 +12,7 @@ from functools import partial
|
|||
import apis # from itself
|
||||
import traceback
|
||||
from item import Item # from itself
|
||||
from files import read_this, save_this, link_this, scan_dir # from itself
|
||||
from files import save_this, link_this, scan_dir # from itself
|
||||
from config import config # from itself
|
||||
|
||||
def template_for(path: str) -> str:
|
||||
|
@ -28,9 +28,8 @@ def template_for(path: str) -> str:
|
|||
for pattern in config['templates'].keys():
|
||||
if fnmatch(path, pattern):
|
||||
template = config['templates'][pattern]
|
||||
template_data = read_this('templates/'+template)
|
||||
|
||||
return template_data
|
||||
return template
|
||||
|
||||
def namespace_from(*extensions) -> dict:
|
||||
"""Generates global namespace for evaluation derrived from provided
|
||||
|
@ -167,9 +166,9 @@ def gemtext2html(gemtext: str) -> str:
|
|||
def abs2rel(match: re.Match, path: str) -> str:
|
||||
"""Callable for re.sub, converts absolute link to relative to current document (path argument)."""
|
||||
|
||||
url = os.path.relpath(match.group(1), start=os.path.dirname(path))
|
||||
text = match.group(2).strip() if len(match.groups()) > 2 else url
|
||||
return f'=> {url} {text}'
|
||||
url = os.path.relpath(match.group(2), start=os.path.dirname(path))
|
||||
print(' M', url)
|
||||
return match.group(1) + url
|
||||
|
||||
if __name__ == '__main__':
|
||||
os.chdir(sys.path[0])
|
||||
|
@ -201,51 +200,92 @@ if __name__ == '__main__':
|
|||
|
||||
item = Item(path)
|
||||
|
||||
# parse content
|
||||
namespace = namespace_from(
|
||||
{'path': path},
|
||||
apis.Content,
|
||||
config['variables'],
|
||||
item.frontmatter_data
|
||||
)
|
||||
|
||||
content = evaluate_this(item.content, namespace)
|
||||
|
||||
# load template
|
||||
if template := template_for(path):
|
||||
# apply template
|
||||
# parsing in gemini mode
|
||||
if not 'mode' in item or item.mode == 'gemini':
|
||||
# preparing namespace
|
||||
namespace = namespace_from(
|
||||
{'path': path},
|
||||
apis.Content,
|
||||
config['variables'],
|
||||
config['variables.gemini'],
|
||||
item.frontmatter_data,
|
||||
{'content': content}
|
||||
{'mode': 'gemini'}
|
||||
)
|
||||
content = evaluate_this(template, namespace)
|
||||
|
||||
# do redirections
|
||||
if 'redirections' in config:
|
||||
content = re.sub(r'(https?://)([-\w]+[-\w.]*)(/\S*)?', partial(
|
||||
redirect,
|
||||
domains=dict(config['redirections'])
|
||||
), content)
|
||||
|
||||
# convert absolute links to relative
|
||||
if path.endswith('.gmi'):
|
||||
content = re.sub(r'=>\s+/(\S+)(\s+.*)?', partial(
|
||||
abs2rel, path=path
|
||||
), content)
|
||||
# evaluation
|
||||
content = evaluate_this(item.content, namespace)
|
||||
# determining and applying template (optional)
|
||||
if template := template_for(path):
|
||||
tpl_item = Item(template, prefix='templates/')
|
||||
if not 'mode' in tpl_item or tpl_item.mode == 'gemini':
|
||||
namespace = namespace_from(
|
||||
{'path': path},
|
||||
apis.Content,
|
||||
config['variables'],
|
||||
config['variables.gemini'],
|
||||
item.frontmatter_data,
|
||||
{'mode': 'gemini', 'content': content}
|
||||
)
|
||||
content = evaluate_this(tpl_item.content, namespace)
|
||||
|
||||
# produce HTML version
|
||||
html_path = os.path.splitext(path)[0]+'.html'
|
||||
html_content = gemtext2html(content)
|
||||
# determine which template to use
|
||||
if template := template_for(html_path):
|
||||
...
|
||||
save_this('../html/'+html_path, html_content)
|
||||
# do redirections (http/https only!)
|
||||
if 'redirections' in config:
|
||||
content = re.sub(r'(https?://)([-\w]+[-\w.]*)(/\S*)?', partial(
|
||||
redirect,
|
||||
domains=dict(config['redirections'])
|
||||
), content)
|
||||
|
||||
# convert absolute links to relative (gemtext only!)
|
||||
if path.endswith('.gmi'):
|
||||
content = re.sub(r'(=>[ \t]+)/(\S+)', partial(
|
||||
abs2rel, path=path
|
||||
), content)
|
||||
|
||||
# save results
|
||||
save_this('../'+path, content)
|
||||
else:
|
||||
print(' ! skipped for gemini')
|
||||
# TODO: delete from gemini output
|
||||
|
||||
# save results
|
||||
save_this('../'+path, content)
|
||||
|
||||
if not path.endswith('.gmi'):
|
||||
link_this('../'+path, '../html/'+path)
|
||||
# parsing in www mode
|
||||
if not 'mode' in item or item.mode == 'www':
|
||||
namespace = namespace_from(
|
||||
{'path': path},
|
||||
apis.Content,
|
||||
config['variables'],
|
||||
config['variables.www'],
|
||||
item.frontmatter_data,
|
||||
{'mode': 'www'}
|
||||
)
|
||||
|
||||
content = evaluate_this(item.content, namespace)
|
||||
|
||||
if template := template_for(path):
|
||||
tpl_item = Item(template, prefix='templates/')
|
||||
if not 'mode' in tpl_item or tpl_item.mode == 'www':
|
||||
namespace = namespace_from(
|
||||
{'path': path},
|
||||
apis.Content,
|
||||
config['variables'],
|
||||
config['variables.www'],
|
||||
item.frontmatter_data,
|
||||
{'mode': 'www', 'content': content}
|
||||
)
|
||||
content = evaluate_this(tpl_item.content, namespace)
|
||||
|
||||
# convert to html
|
||||
html_path = path
|
||||
if path.endswith('.gmi'):
|
||||
content = gemtext2html(content)
|
||||
html_path = os.path.splitext(path)[0]+'.html'
|
||||
|
||||
if html_path.endswith('.html'):
|
||||
# TODO: html template
|
||||
if template := template_for(html_path):
|
||||
...
|
||||
|
||||
# TODO: redirections, path conversion
|
||||
|
||||
save_this('../html/'+html_path, content)
|
||||
else:
|
||||
print(' ! skipped for www')
|
||||
# TODO: delete from www output
|
||||
|
|
|
@ -14,13 +14,13 @@ class Item(AttrDict):
|
|||
source = None
|
||||
author = None
|
||||
|
||||
def __init__(self, path: str):
|
||||
def __init__(self, path: str, prefix: str = 'content/'):
|
||||
# initialize parent
|
||||
super().__init__()
|
||||
|
||||
self.path = path
|
||||
self.path, self.prefix = path, prefix
|
||||
|
||||
frontmatter_data, content = frontmatter.parse(read_this('content/'+path))
|
||||
frontmatter_data, content = frontmatter.parse(read_this(prefix + path))
|
||||
self.content = content
|
||||
self.frontmatter_data = frontmatter_data
|
||||
|
||||
|
|
Loading…
Reference in New Issue