|
|
|
@ -17,11 +17,12 @@ from docutils import nodes
|
|
|
|
|
|
|
|
|
|
import ablog |
|
|
|
|
|
|
|
|
|
from ablog.blog import Blog, os_path_join, revise_pending_xrefs |
|
|
|
|
from ablog.blog import Post, Blog, os_path_join, revise_pending_xrefs |
|
|
|
|
|
|
|
|
|
logger = logging.getLogger(__name__) |
|
|
|
|
text_type = str |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class Page: |
|
|
|
|
""" Mini translator for gemini """ |
|
|
|
|
|
|
|
|
@ -31,8 +32,11 @@ class Page:
|
|
|
|
|
self.builder = builder |
|
|
|
|
|
|
|
|
|
def add_title(self, text: str, level: int = 1) -> None: |
|
|
|
|
self.body += '# ' * level |
|
|
|
|
self.body += text + '\n' |
|
|
|
|
self.body += '#' * level |
|
|
|
|
self.body += ' ' + text + '\n' |
|
|
|
|
|
|
|
|
|
def add_item(self, text: str) -> None: |
|
|
|
|
self.body += '* %s\n' % text |
|
|
|
|
|
|
|
|
|
def add_link(self, uri: str, desc: str = None) -> None: |
|
|
|
|
self.body += '=> %s' % uri |
|
|
|
@ -40,6 +44,9 @@ class Page:
|
|
|
|
|
self.body += ' %s' % desc |
|
|
|
|
self.body += '\n' |
|
|
|
|
|
|
|
|
|
def add_raw(self, text: str) -> None: |
|
|
|
|
self.body += text |
|
|
|
|
|
|
|
|
|
def end_block(self) -> None: |
|
|
|
|
self.body += '\n' |
|
|
|
|
|
|
|
|
@ -48,7 +55,7 @@ class Page:
|
|
|
|
|
self.body += '\n\n' |
|
|
|
|
|
|
|
|
|
def write(self): |
|
|
|
|
path = os.path.join(self.builder.outdir, self.docname) |
|
|
|
|
path = os.path.join(self.builder.outdir, self.docname + self.builder.out_suffix) |
|
|
|
|
folder = os.path.dirname(path) |
|
|
|
|
if not os.path.exists(folder): |
|
|
|
|
os.makedirs(folder) |
|
|
|
@ -57,7 +64,7 @@ class Page:
|
|
|
|
|
out.write(self.body) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def to_gemini(builder, post, pagename, fulltext=False): |
|
|
|
|
def to_gemini(builder, post, pagename: str, fulltext: bool = False): |
|
|
|
|
""" |
|
|
|
|
Convert post to gemini format |
|
|
|
|
""" |
|
|
|
@ -86,6 +93,61 @@ def to_gemini(builder, post, pagename, fulltext=False):
|
|
|
|
|
return gemini |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def add_post_to_page(builder, doc: Page, post) -> None: |
|
|
|
|
doc.add_title(post.title, 2) |
|
|
|
|
doc.add_link( |
|
|
|
|
builder.config.gemini_baseurl + post.docname + builder.out_suffix, |
|
|
|
|
_("Read post") |
|
|
|
|
) |
|
|
|
|
doc.end_block() |
|
|
|
|
if post.published: |
|
|
|
|
doc.add_item(_("Date: %s") % post.date.strftime(builder.config.post_date_format)) |
|
|
|
|
else: |
|
|
|
|
doc.add_item(_("Draft")) |
|
|
|
|
|
|
|
|
|
if post.date != post.update: |
|
|
|
|
doc.add_item(_("Update: %s") % post.update.strftime(ablog.post_date_format)) |
|
|
|
|
|
|
|
|
|
for author in post.author: |
|
|
|
|
doc.add_link( |
|
|
|
|
builder.config.gemini_baseurl + author.docname, |
|
|
|
|
_("Author: %s" % str(author)) |
|
|
|
|
) |
|
|
|
|
|
|
|
|
|
for location in post.location: |
|
|
|
|
doc.add_link( |
|
|
|
|
builder.config.gemini_baseurl + location.docname, |
|
|
|
|
_("Location: %s" % str(location)) |
|
|
|
|
) |
|
|
|
|
|
|
|
|
|
for language in post.language: |
|
|
|
|
doc.add_link( |
|
|
|
|
builder.config.gemini_baseurl + language.docname, |
|
|
|
|
_("Language: %s" % str(language)) |
|
|
|
|
) |
|
|
|
|
|
|
|
|
|
for category in post.category: |
|
|
|
|
doc.add_link( |
|
|
|
|
builder.config.gemini_baseurl + category.docname, |
|
|
|
|
_("Category: %s" % str(category)) |
|
|
|
|
) |
|
|
|
|
|
|
|
|
|
for tag in post.tags: |
|
|
|
|
doc.add_link( |
|
|
|
|
builder.config.gemini_baseurl + tag.docname, |
|
|
|
|
_("Tag: %s" % str(tag)) |
|
|
|
|
) |
|
|
|
|
|
|
|
|
|
doc.end_block() |
|
|
|
|
|
|
|
|
|
builder.footer_enabled = False |
|
|
|
|
builder.header_enabled = False |
|
|
|
|
doc.add_paragraph(to_gemini(builder, post, post.docname, fulltext=False)) |
|
|
|
|
|
|
|
|
|
builder.footer_enabled = True |
|
|
|
|
builder.header_enabled = True |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def generate_archive_pages(builder): |
|
|
|
|
""" |
|
|
|
|
Generate archive pages for all posts, categories, tags, authors, and |
|
|
|
@ -177,12 +239,34 @@ def generate_archive_pages(builder):
|
|
|
|
|
doc.add_title(str(collection)) |
|
|
|
|
if context["atom_feed"]: |
|
|
|
|
doc.add_link( |
|
|
|
|
collection.path+"/atom.xml", |
|
|
|
|
builder.config.gemini_baseurl+collection.path+"/atom.xml", |
|
|
|
|
_("Atom feed") |
|
|
|
|
) |
|
|
|
|
|
|
|
|
|
doc.end_block() |
|
|
|
|
for subcoll in collection: |
|
|
|
|
if isinstance(subcoll, Post): |
|
|
|
|
add_post_to_page(builder, doc, subcoll) |
|
|
|
|
continue |
|
|
|
|
|
|
|
|
|
doc.add_title(str(subcoll), 2) |
|
|
|
|
doc.add_link( |
|
|
|
|
builder.get_target_uri(post.docname), |
|
|
|
|
_("Go to collection") |
|
|
|
|
) |
|
|
|
|
doc.end_block() |
|
|
|
|
for post in subcoll: |
|
|
|
|
doc.add_link( |
|
|
|
|
builder.config.gemini_baseurl + post.docname + builder.out_suffix, |
|
|
|
|
_("Read post") |
|
|
|
|
) |
|
|
|
|
|
|
|
|
|
doc.end_block() |
|
|
|
|
doc.write() |
|
|
|
|
|
|
|
|
|
doc.add_raw(ablog_footer(builder)) |
|
|
|
|
doc.add_paragraph(builder.config.gemini_footer) |
|
|
|
|
|
|
|
|
|
doc.write() |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def generate_atom_feeds(builder): |
|
|
|
@ -190,6 +274,8 @@ def generate_atom_feeds(builder):
|
|
|
|
|
Generate archive pages for all posts, categories, tags, authors, and |
|
|
|
|
drafts (from ablog). |
|
|
|
|
""" |
|
|
|
|
builder.footer_enabled = False |
|
|
|
|
builder.header_enabled = False |
|
|
|
|
blog = Blog(builder.app) |
|
|
|
|
|
|
|
|
|
url = builder.config.gemini_baseurl |
|
|
|
@ -277,3 +363,57 @@ def generate_atom_feeds(builder):
|
|
|
|
|
with open(feed_path, "w", encoding="utf-8") as out: |
|
|
|
|
feed_str = feed.atom_str(pretty=True) |
|
|
|
|
out.write(feed_str.decode()) |
|
|
|
|
|
|
|
|
|
builder.footer_enabled = True |
|
|
|
|
builder.header_enabled = True |
|
|
|
|
|
|
|
|
|
def ablog_header(builder) -> str: |
|
|
|
|
""" Generate header for Atom """ |
|
|
|
|
header = '' |
|
|
|
|
blog = Blog(builder.app) |
|
|
|
|
if builder.current_docname in blog.posts: |
|
|
|
|
post = blog.posts[builder.current_docname] |
|
|
|
|
header = _('By %s') % ', '.join([str(author) for author in post.author]) + '\n' |
|
|
|
|
header += post.date.strftime(builder.config.post_date_format) |
|
|
|
|
header += '\n' |
|
|
|
|
|
|
|
|
|
if post.date != post.update: |
|
|
|
|
header += _('Updated on %s') % \ |
|
|
|
|
post.update.strftime(builder.config.post_date_format) |
|
|
|
|
header += '\n' |
|
|
|
|
header += '\n' |
|
|
|
|
|
|
|
|
|
return header |
|
|
|
|
|
|
|
|
|
def ablog_footer(builder) -> str: |
|
|
|
|
""" Generate footer for Atom """ |
|
|
|
|
blog = Blog(builder.app) |
|
|
|
|
|
|
|
|
|
baseurl = builder.config.gemini_baseurl |
|
|
|
|
if not baseurl: |
|
|
|
|
return |
|
|
|
|
|
|
|
|
|
footer = '\n\n' |
|
|
|
|
footer += _('# Blog menu') |
|
|
|
|
footer += '\n' |
|
|
|
|
for title, catalog in [ |
|
|
|
|
(_("Authors"), blog.author), |
|
|
|
|
(_("Locations"), blog.location), |
|
|
|
|
(_("Languages"), blog.language), |
|
|
|
|
(_("Categories"), blog.category), |
|
|
|
|
]: |
|
|
|
|
footer += '## %s\n' % title |
|
|
|
|
footer += '=> %s %s\n' % (baseurl + catalog.docname + builder.out_suffix, _("All")) |
|
|
|
|
for coll in catalog: |
|
|
|
|
footer += '=> %s %s\n' % (baseurl + coll.docname + builder.out_suffix, str(coll)) |
|
|
|
|
footer += '\n' |
|
|
|
|
|
|
|
|
|
footer += '## %s\n' % _("All posts") |
|
|
|
|
footer += '=> %s %s\n' % (baseurl + blog.archive.docname + builder.out_suffix, _("All posts")) |
|
|
|
|
footer += '\n' |
|
|
|
|
|
|
|
|
|
footer += '## %s\n' % _("Tags") |
|
|
|
|
footer += '=> %s %s\n' % (baseurl + blog.tags.docname + builder.out_suffix, _("Tags")) |
|
|
|
|
footer += '\n' |
|
|
|
|
|
|
|
|
|
return footer |
|
|
|
|