import re
import subprocess
import yaml
+import zoneinfo
from markdown2html import markdown2html
from pathlib import Path
def context(self):
return collections.ChainMap(self, self.blog)
-class Static(Templatable):
- use_layout = False
- def __init__(self, path, blog):
- super().__init__(blog)
- self.path = path
- def content(self):
- with open(self.path, "rb") as f:
- return f.read()
- @property
- def relative_path(self):
- return self.path.relative_to(self.blog.static_dir)
-
class Post(Templatable):
def __init__(self, parsed, blog, comments):
super().__init__(blog)
for k, v in parsed.items():
if k in {"tags", "author", "categories"}:
k = "_" + k
+ if isinstance(v, datetime.date):
+ tz = zoneinfo.ZoneInfo(blog.timezone)
+ time = datetime.time(18,0,0)
+ v = datetime.datetime.combine(v, time, tz)
self[k] = v
self.post_title = self.title # Avoids a dumb thing with str.title in a template
def type(self):
return self.page_name
+class Static(Templatable):
+ use_layout = False
+ def __init__(self, path, blog):
+ super().__init__(blog)
+ self.path = path
+ def content(self):
+ with open(self.path, "rb") as f:
+ return f.read()
+ @property
+ def relative_path(self):
+ return self.path.relative_to(self.blog.static_dir)
+
class Image(Templatable):
use_layout = False
- pass # TODO
+ def __init__(self, path, blog):
+ super().__init__(blog)
+ self.path = path
+ def content(self):
+ with open(self.path, "rb") as f:
+ return f.read()
+ @property
+ def filename(self):
+ return self.path.name
class Blog(PseudoMap):
- def __init__(self, config):
+ def __init__(self, configs):
self.tags = {} # Tag -> str
self.categories = {}
self.authors = {}
self.now = datetime.datetime.now(datetime.timezone.utc)
self.now_rfc822 = self.now.strftime(RFC822)
- self.config = os.path.abspath(config)
- self.load_config(config)
+ for config in configs:
+ self.load_config(os.path.abspath(config))
self.load_posts()
def load_config(self, path):
for post_input_path in Path(self.post_dir).iterdir():
fm = frontmatter.load(post_input_path)
comments = self.load_comments(post_input_path.stem)
- assert fm["has-comments"] == (comments is not None)
self.add_post(Post(fm, self, comments))
self.posts = sorted(self.posts, key=lambda post: post.date, reverse=True)
@property
def images(self):
- return [] # TODO
+ for dirpath, dirnames, filenames in os.walk(str(self.image_dir)):
+ for name in filenames:
+ path = Path(dirpath) / name
+ yield Image(path, self)
def generate_all(blog):
for image in blog.images:
description="Generate za3k's blog from markdown files with YAML frontmatter and some templates",
)
parser.add_argument("-l", "--local", action='store_true', help="use relative paths for links")
- parser.add_argument("-c", "--config", help="location of config file", default="config.yaml")
+ parser.add_argument("-c", "--config", help="location of config file", default=["config.yaml"], action='append')
args = parser.parse_args()
- blog = Blog(config=args.config)
+ blog = Blog(configs=args.config)
blog.local = args.local
if args.local:
blog.web_root = "file://" + blog.destination
# These two properties are always first, and always absolute paths
source: "/var/www/blog-src"
destination: "/var/www/blog"
-
-web_root: "https://blog.za3k.com"
-title: 'blog of zachary "za3k" vance'
-# For search bar
-domain: "blog.za3k.com"
-posts_per_page: 10
-
-post_dir: "posts"
-comments_dir: "comments"
-page_dir: "page"
-image_dir: "images"
-static_dir: "static"
-
-author_template: "templates/author.mustache.html"
-category_template: "templates/category.mustache.html"
-index_template: "templates/index.mustache.html"
-feed_template: "templates/feed.mustache.html"
-layout_template: "templates/layout.mustache.html"
-pagination_template: "templates/pagination.mustache.html"
-post_template: "templates/post.mustache.html"
-tag_template: "templates/tag.mustache.html"
-tagcloud_template: "templates/tagcloud.mustache.html"
-
-# Non-local mode, preferred link address
-author_url: "{{web_root}}/author/{{slug}}/"
-author_paginated_url: "{{web_root}}/author/{{slug}}/{{page_num}}/"
-category_url: "{{web_root}}/category/{{slug}}/"
-category_paginated_url: "{{web_root}}/category/{{slug}}/{{page_num}}/"
-tag_url: "{{web_root}}/tag/{{slug}}/"
-tag_paginated_url: "{{web_root}}/tag/{{slug}}/{{page_num}}/"
-index_url: "{{web_root}}"
-index_paginated_url: "{{web_root}}/page/{{page_num}}"
-post_url: "{{web_root}}/{{id}}/"
-feed_url: "{{web_root}}/feed/"
-
-author_destination: "{{destination}}/author/{{slug}}.html"
-author_paginated_destination: "{{destination}}/author/{{slug}}.{{page_num}}.html"
-category_destination: "{{destination}}/category/{{slug}}.html"
-category_paginated_destination: "{{destination}}/category/{{slug}}.{{page_num}}.html"
-index_destination: "{{destination}}/page/index.html"
-index_paginated_destination: "{{destination}}/page/index.{{page_num}}.html"
-feed_destination: "{{destination}}/page/feed.xml"
-image_destination: "{{destination}}/images/{{image}}"
-page_destination: "{{destination}}/{{page}}"
-post_destination: "{{destination}}/posts/{{id}}.html"
-static_destination: "{{destination}}/{{relative_path}}"
-tag_destination: "{{destination}}/tag/{{slug}}.html"
-tag_paginated_destination: "{{destination}}/tag/{{slug}}.{{page_num}}.html"
-
-category_destination: "{{destination}}/category/{{slug}}.html"
-index_destination: "{{destination}}/page/index.html"
-tag_destination: "{{destination}}/tag/{{slug}}.html"
source: "/home/zachary/blog"
destination: "/home/zachary/blog/public"
-web_root: "https://blog2.za3k.com"
+web_root: "https://blog.za3k.com"
title: 'blog of zachary "za3k" vance'
# For search bar
-domain: "blog2.za3k.com"
+domain: "blog.za3k.com"
posts_per_page: 10
+timezone: "America/New_York"
post_dir: "posts"
comments_dir: "comments"
index_destination: "{{destination}}/page/index.html"
index_paginated_destination: "{{destination}}/page/index.{{page_num}}.html"
feed_destination: "{{destination}}/page/feed.xml"
-image_destination: "{{destination}}/images/{{image}}"
+image_destination: "{{destination}}/images/{{filename}}"
page_destination: "{{destination}}/{{page}}"
post_destination: "{{destination}}/posts/{{id}}.html"
static_destination: "{{destination}}/{{relative_path}}"
img['alt'] = img['alt'].removeprefix('caption:')
caption = img['alt']
+ if "/" not in img["src"]:
+ img["src"] = "/images/" + img["src"]
+
if img.parent.name == "a":
img = img.parent
img.wrap(figure)
.wp-block-audio {
box-sizing: border-box;
}
-.wp-block-audio figcaption {
- margin-bottom: 1em;
- margin-top: 0.5em;
-}
.wp-block-audio audio {
min-width: 300px;
width: 100%;
.wp-block-embed {
overflow-wrap: break-word;
}
+.wp-block-audio figcaption,
+.wp-block-image figcaption,
.wp-block-embed figcaption {
- margin-bottom: 1em;
- margin-top: 0.5em;
+ /* Za3k */
+ width: 100%;
+ text-align: center;
+ background: #F9F9F9;
+ padding: 10px 5px 5px 5px;
+ font-family: "Segoe UI", Arial, sans-serif;
+ font-size: 12.6px;
}
.wp-block-embed iframe {
max-width: 100%;
margin-left: auto;
margin-right: auto;
}
-.wp-block-image figcaption {
- margin-bottom: 1em;
- margin-top: 0.5em;
-}
.wp-block-image .is-style-rounded img,
.wp-block-image.is-style-circle-mask img,
.wp-block-image.is-style-rounded img {
--- /dev/null
+---
+author: admin
+categories:
+- Uncategorized
+date: 2024-08-09
+tags:
+- untagged
+title: 'TITLE'
+---