Add show unlisted status for pages, clean code, fix misc issues

This commit is contained in:
octospacc 2022-12-20 13:05:41 +01:00
parent 09eb85be6c
commit 9551342b74
10 changed files with 197 additions and 104 deletions

View File

@ -1,6 +1,7 @@
{
"CreatedOn": "Created on",
"EditedOn": "Edited on",
"Unlisted": "Unlisted",
"Categories": "Categories",
"ReadFullPost": "Read the full post",
"Comments": "Comments",

View File

@ -1,6 +1,7 @@
{
"CreatedOn": "Creato in data",
"EditedOn": "Modificato in data",
"Unlisted": "Non in elenco",
"Categories": "Categorie",
"ReadFullPost": "Leggi il post intero",
"Comments": "Commenti",

View File

@ -17,6 +17,7 @@ from datetime import datetime
from pathlib import Path
from Modules.Config import *
from Modules.Gemini import *
from Modules.Globals import *
from Modules.Logging import *
from Modules.Markdown import *
from Modules.Site import *

View File

@ -4,7 +4,7 @@ https://github.com/tootsuite/mastodon/blob/master/docs/Using-the-API/Streaming-A
"""
import json
import six
from .. import six
from . import Mastodon
from .Mastodon import MastodonMalformedEventError, MastodonNetworkError, MastodonReadTimeout
from requests.exceptions import ChunkedEncodingError, ReadTimeout

View File

@ -8,6 +8,7 @@
| ================================= """
from base64 import b64encode
from Modules.Globals import *
from Modules.HTML import *
from Modules.Utils import *
@ -32,6 +33,8 @@ RedirectPageTemplate = """\
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{TitlePrefix}Redirect</title>
<link rel="canonical" href="{SiteDomain}/{DestURL}">
<meta http-equiv="refresh" content="0; url='{DestURL}'">
@ -68,7 +71,7 @@ def GenHTMLTreeList(MetaList:str, Type:str='ul'):
PrevDepth = CurDepth
return f'<{Type}>{HTML}\n</{Type}>'
def MakeLinkableTitle(Line, Title, DashTitle, Type):
def MakeLinkableTitle(Line:str, Title:str, DashTitle:str, Type:str):
if Type == 'md':
Index = Title.split(' ')[0].count('#')
return HTMLSectionTitleLine.format(
@ -83,7 +86,7 @@ def MakeLinkableTitle(Line, Title, DashTitle, Type):
Rest=Line[Index+2:],
DashTitle=DashTitle)
def GetTitle(FileName, Meta, Titles, Prefer='MetaTitle', BlogName=None):
def GetTitle(FileName:str, Meta:dict, Titles:list, Prefer='MetaTitle', BlogName=None):
if Prefer == 'BodyTitle':
Title = Titles[0].lstrip('#') if Titles else Meta['Title'] if Meta['Title'] else FileName
elif Prefer == 'MetaTitle':
@ -94,27 +97,29 @@ def GetTitle(FileName, Meta, Titles, Prefer='MetaTitle', BlogName=None):
Title += ' - ' + BlogName
return Title
def GetDescription(Meta, BodyDescription, Prefer='MetaDescription'):
def GetDescription(Meta:dict, BodyDescription, Prefer='MetaDescription'):
if Prefer == 'BodyDescription':
Description = BodyDescription if BodyDescription else Meta['Description'] if Meta['Description'] else ''
elif Prefer == 'MetaDescription':
Description = Meta['Description'] if Meta['Description'] else BodyDescription if BodyDescription else ''
return Description
def GetImage(Meta, BodyImage, Prefer='MetaImage'):
def GetImage(Meta:dict, BodyImage, Prefer='MetaImage'):
if Prefer == 'BodyImage':
Image = BodyImage if BodyImage else Meta['Image'] if Meta['Image'] else ''
elif Prefer == 'MetaImage':
Image = Meta['Image'] if Meta['Image'] else BodyImage if BodyImage else ''
return Image
def MakeContentHeader(Meta, Locale, Categories=''):
def MakeContentHeader(Meta:dict, Locale:dict, Categories=''):
Header = ''
for e in ['CreatedOn', 'EditedOn']:
if Meta[e]:
Header += f'<span class="staticoso-ContentHeader-{e}"><span class="staticoso-Label">{Locale[e]}</span>: <span class="staticoso-Value">{Meta[e]}</span></span><br>'
Header += f'<span class="staticoso-ContentHeader-{e}" id="staticoso-ContentHeader-{e}"><span class="staticoso-Label">{Locale[e]}</span>: <span class="staticoso-Value">{Meta[e]}</span></span><br>'
if Categories:
Header += f'<span class="staticoso-ContentHeader-Categories"><span class="staticoso-Label">{Locale["Categories"]}</span>:<span class="staticoso-Value">{Categories.removesuffix(" ")}</span></span><br>'
Header += f'<span class="staticoso-ContentHeader-Categories" id="staticoso-ContentHeader-Categories"><span class="staticoso-Label">{Locale["Categories"]}</span>:<span class="staticoso-Value">{Categories.removesuffix(" ")}</span></span><br>'
if Meta['Index'].lower() in PageIndexStrNeg:
Header += f'<span class="staticoso-ContentHeader-Index" id="staticoso-ContentHeader-Index"><span class="staticoso-Value">{Locale["Unlisted"]}</span></span><br>'
return f'<p>{Header}</p>'
def MakeCategoryLine(File, Meta):

23
Source/Modules/Globals.py Normal file
View File

@ -0,0 +1,23 @@
""" ================================= |
| This file is part of |
| staticoso |
| Just a simple Static Site Generator |
| |
| Licensed under the AGPLv3 license |
| Copyright (C) 2022, OctoSpacc |
| ================================= """
ReservedPaths = ('Site.ini', 'Assets', 'Pages', 'Posts', 'Templates', 'StaticParts', 'DynamicParts')
FileExtensions = {
'Pages': ('htm', 'html', 'markdown', 'md', 'pug', 'txt'),
'HTML': ('.htm', '.html'),
'Markdown': ('.markdown', '.md'),
'Tmp': ('htm', 'markdown', 'md', 'pug', 'txt')}
PosStrBools = ('true', 'yes', 'on', '1', 'enabled')
NegStrBools = ('false', 'no', 'off', '0', 'disabled')
PageIndexStrPos = tuple(list(PosStrBools) + ['all', 'listed', 'indexed', 'unlinked'])
PageIndexStrNeg = tuple(list(NegStrBools) + ['none', 'unlisted', 'unindexed', 'hidden'])
InternalMacrosWraps = [['[', ']'], ['<', '>']]

View File

@ -58,21 +58,24 @@ def WriteImgAltAndTitle(HTML, AltToTitle, TitleToAlt): # Adds alt or title attr.
return str(Soup)
def AddToTagStartEnd(HTML, MatchStart, MatchEnd, AddStart, AddEnd): # This doesn't handle nested tags
StartPos = None
StartPos, DidStart, DidEnd = None, 0, 0
for i,e in enumerate(HTML):
FilterStart = HTML[i:i+len(MatchStart)]
FilterEnd = HTML[i:i+len(MatchEnd)]
if not AddStart and not AddEnd:
break
if FilterStart == MatchStart:
if DidStart == 0 and FilterStart == MatchStart:
StartPos = i
if AddStart:
HTML = HTML[:i] + AddStart + HTML[i:]
AddStart = None
if FilterEnd == MatchEnd and StartPos and i > StartPos:
DidStart = 2
if DidEnd == 0 and FilterEnd == MatchEnd and StartPos and i > StartPos:
StartPos = None
if AddEnd:
HTML = HTML[:i+len(MatchEnd)] + AddEnd + HTML[i+len(MatchEnd):]
AddEnd = None
DidEnd = 2
if DidStart > 0:
DidStart -= 1
if DidEnd > 0:
DidEnd -= 1
return HTML
def SquareFnrefs(HTML): # Different combinations of formatting for Soup .prettify, .encode, .decode break different page elements, don't use this for now

View File

@ -13,6 +13,7 @@ from multiprocessing import Pool, cpu_count
from Libs.bs4 import BeautifulSoup
from Modules.Config import *
from Modules.Elements import *
from Modules.Globals import *
from Modules.HTML import *
from Modules.Logging import *
from Modules.Markdown import *
@ -31,7 +32,7 @@ def GetHTMLPagesList(Pages, BlogName, SiteRoot, PathPrefix, CallbackFile=None, U
List, ToPop, LastParent = '', [], []
IndexPages = Pages.copy()
for e in IndexPages:
if e[3]['Index'] == 'False' or e[3]['Index'] == 'None':
if e[3]['Index'].lower() in PageIndexStrNeg:
IndexPages.remove(e)
for i,e in enumerate(IndexPages):
if Type and e[3]['Type'] != Type:
@ -43,7 +44,7 @@ def GetHTMLPagesList(Pages, BlogName, SiteRoot, PathPrefix, CallbackFile=None, U
IndexPages = OrderPages(IndexPages)
for i,e in enumerate(Unite):
if e:
IndexPages.insert(i,[e,None,None,{'Type':Type,'Index':'True','Order':'Unite'}])
IndexPages.insert(i, [e, None, None, {'Type':Type, 'Index':'True', 'Order':'Unite'}])
for File, Content, Titles, Meta in IndexPages:
# Allow for the virtual "Pages/" prefix to be used in path filtering
TmpPathFilter = PathFilter
@ -128,11 +129,12 @@ def FindPreprocLine(Line, Meta, Macros):
# IgnoreBlocksStart += [l]
return (Meta, Macros, Changed)
def PagePreprocessor(Path, TempPath, Type, SiteTemplate, SiteRoot, GlobalMacros, CategoryUncategorized, LightRun=False):
def PagePreprocessor(Path:str, TempPath:str, Type, SiteTemplate, SiteRoot, GlobalMacros, CategoryUncategorized, LightRun=False):
File = ReadFile(Path)
Path = Path.lower()
Content, Titles, DashyTitles, HTMLTitlesFound, Macros, Meta, MetaDefault = '', [], [], False, '', '', {
'Template': SiteTemplate,
'Head': '',
'Style': '',
'Type': Type,
'Index': 'Unspecified',
@ -250,24 +252,24 @@ def PagePreprocessor(Path, TempPath, Type, SiteTemplate, SiteRoot, GlobalMacros,
Meta.update({i:MetaDefault[i]})
if Meta['UpdatedOn']:
Meta['EditedOn'] = Meta['UpdatedOn']
if Meta['Index'] in ('Default', 'Unspecified', 'Categories'):
if Meta['Index'].lower() in ('default', 'unspecified', 'categories'):
if not Meta['Categories']:
Meta['Categories'] = [CategoryUncategorized]
if Meta['Type'] == 'Page':
if Meta['Type'].lower() == 'page':
Meta['Index'] = 'Categories'
elif Meta['Type'] == 'Post':
elif Meta['Type'].lower() == 'post':
Meta['Index'] = 'True'
if GlobalMacros:
Meta['Macros'].update(GlobalMacros)
Meta['Macros'].update(ReadConf(LoadConfStr('[Macros]\n' + Macros), 'Macros'))
return [TempPath, Content, Titles, Meta]
def PagePostprocessor(FileType, Text, Meta):
def PagePostprocessor(FileType, Text:str, Meta:dict):
for e in Meta['Macros']:
Text = ReplWithEsc(Text, f"[: {e} :]", f"[:{e}:]")
return Text
def OrderPages(Old):
def OrderPages(Old:list):
New, NoOrder, Max = [], [], 0
for i,e in enumerate(Old):
Curr = e[3]['Order']
@ -285,10 +287,10 @@ def OrderPages(Old):
New.remove(None)
return New + NoOrder
def CanIndex(Index, For):
if Index in ('False', 'None'):
def CanIndex(Index:str, For:str):
if Index.lower() in PageIndexStrNeg:
return False
elif Index in ('True', 'All', 'Unlinked'):
elif Index.lower() in PageIndexStrPos:
return True
else:
return True if Index == For else False
@ -297,20 +299,26 @@ def PatchHTML(File, HTML, StaticPartsText, DynamicParts, DynamicPartsText, HTMLP
HTMLTitles = FormatTitles(Titles)
BodyDescription, BodyImage = '', ''
if not File.lower().endswith('.txt'):
Soup = BeautifulSoup(Content, 'html.parser')
if not BodyDescription and Soup.p:
BodyDescription = Soup.p.get_text()[:150].replace('\n', ' ').replace('"', "'") + '...'
Soup = MkSoup(Content)
if not BodyDescription:# and Soup.p:
#BodyDescription = Soup.p.get_text()[:150].replace('\n', ' ').replace('"', "'") + '...'
for t in Soup.find_all('p'):
if t.get_text():
BodyDescription = t.get_text()[:150].replace('\n', ' ').replace('"', "'") + '...'
break
if not BodyImage and Soup.img and Soup.img['src']:
BodyImage = Soup.img['src']
#Content = SquareFnrefs(Content)
if '<a class="footnote-ref"' in Content:
Content = AddToTagStartEnd(Content, '<a class="footnote-ref"', '</a>', '[', ']')
if '<a class="footnote-ref" ' in Content:
Content = AddToTagStartEnd(Content, '<a class="footnote-ref" ', '</a>', '[', ']')
if any(_ in Content for _ in ('<!-- noprocess />', '<!--noprocess/>', '</ noprocess -->', '</ noprocess --->', '</noprocess-->', '</noprocess--->')):
Content = DictReplWithEsc(
Content, {
'<!--<%noprocess>': '',
'<noprocess%>-->': '',
'<noprocess%>--->': '',
'<!-- noprocess />': '',
'<!--noprocess/>': '',
'</ noprocess -->': '',
@ -352,85 +360,130 @@ def PatchHTML(File, HTML, StaticPartsText, DynamicParts, DynamicPartsText, HTMLP
if LightRun:
HTML = None
else:
HTML = DictReplWithEsc(HTML, {
'[staticoso:Site:Menu]': HTMLPagesList,
'<staticoso:SiteMenu>': HTMLPagesList,
'[staticoso:Page:Lang]': Meta['Language'] if Meta['Language'] else SiteLang,
'<staticoso:PageLang>': Meta['Language'] if Meta['Language'] else SiteLang,
'<staticoso:PageLanguage>': Meta['Language'] if Meta['Language'] else SiteLang,
'[staticoso:Page:Chapters]': HTMLTitles,
'<staticoso:PageSections>': HTMLTitles,
'[staticoso:Page:Title]': Title,
'<staticoso:PageTitle>': Title,
'[staticoso:Page:Description]': Description,
'<staticoso:PageDescription>': Description,
'[staticoso:Page:Image]': Image,
'<staticoso:PageImage>': Image,
'[staticoso:Page:Path]': PagePath,
'<staticoso:PagePath>': PagePath,
'[staticoso:Page:Style]': Meta['Style'],
'<staticoso:PageStyle>': Meta['Style'],
HTML = WrapDictReplWithEsc(HTML, {
#'[staticoso:Site:Menu]': HTMLPagesList,
#'<staticoso:SiteMenu>': HTMLPagesList,
#'[staticoso:Page:Lang]': Meta['Language'] if Meta['Language'] else SiteLang,
#'<staticoso:PageLang>': Meta['Language'] if Meta['Language'] else SiteLang,
#'<staticoso:PageLanguage>': Meta['Language'] if Meta['Language'] else SiteLang,
#'[staticoso:Page:Chapters]': HTMLTitles,
#'<staticoso:PageSections>': HTMLTitles,
#'[staticoso:Page:Title]': Title,
#'<staticoso:PageTitle>': Title,
#'[staticoso:Page:Description]': Description,
#'<staticoso:PageDescription>': Description,
#'[staticoso:Page:Image]': Image,
#'<staticoso:PageImage>': Image,
#'[staticoso:Page:Path]': PagePath,
#'<staticoso:PagePath>': PagePath,
#'[staticoso:PageHead]': Meta['Head'],
#'<staticoso:PageHead>': Meta['Head'],
#'[staticoso:Page:Style]': Meta['Style'],
#'<staticoso:PageStyle>': Meta['Style'],
# #DEPRECATION #
'staticoso:Site:Menu': HTMLPagesList,
'staticoso:Page:Lang': Meta['Language'] if Meta['Language'] else SiteLang,
'staticoso:Page:Chapters': HTMLTitles,
'staticoso:Page:Title': Title,
'staticoso:Page:Description': Description,
'staticoso:Page:Image': Image,
'staticoso:Page:Path': PagePath,
'staticoso:Page:Style': Meta['Style'],
################
'staticoso:SiteMenu': HTMLPagesList,
'staticoso:PageLang': Meta['Language'] if Meta['Language'] else SiteLang,
'staticoso:PageLanguage': Meta['Language'] if Meta['Language'] else SiteLang,
'staticoso:PageSections': HTMLTitles,
'staticoso:PageTitle': Title,
'staticoso:PageDescription': Description,
'staticoso:PageImage': Image,
'staticoso:PagePath': PagePath,
'staticoso:PageHead': Meta['Head'],
'staticoso:PageStyle': Meta['Style'],
# NOTE: Content is injected in page only at this point! Keep in mind for other substitutions
'[staticoso:Page:Content]': Content,
'<staticoso:PageContent>': Content,
'[staticoso:Page:ContentInfo]': ContentHeader,
'<staticoso:PageContentInfo>': ContentHeader,
'[staticoso:BuildTime]': TimeNow,
'<staticoso:BuildTime>': TimeNow,
'<staticoso:SiteDomain>': SiteDomain,
'[staticoso:Site:Name]': SiteName,
'<staticoso:SiteName>': SiteName,
'[staticoso:Site:AbsoluteRoot]': SiteRoot,
'<staticoso:SiteAbsoluteRoot>': SiteRoot,
'[staticoso:Site:RelativeRoot]': RelativeRoot,
'<staticoso:SiteRelativeRoot>': RelativeRoot})
#'[staticoso:Page:Content]': Content,
#'<staticoso:PageContent>': Content,
#'[staticoso:Page:ContentInfo]': ContentHeader,
#'<staticoso:PageContentInfo>': ContentHeader,
#'[staticoso:BuildTime]': TimeNow,
#'<staticoso:BuildTime>': TimeNow,
#'<staticoso:SiteDomain>': SiteDomain,
#'[staticoso:Site:Name]': SiteName,
#'<staticoso:SiteName>': SiteName,
#'[staticoso:Site:AbsoluteRoot]': SiteRoot,
#'<staticoso:SiteAbsoluteRoot>': SiteRoot,
#'[staticoso:Site:RelativeRoot]': RelativeRoot,
#'<staticoso:SiteRelativeRoot>': RelativeRoot,
# #DEPRECATION #
'staticoso:Page:Content': Content,
'staticoso:Page:ContentInfo': ContentHeader,
'staticoso:Site:Name': SiteName,
'staticoso:Site:AbsoluteRoot': SiteRoot,
'staticoso:Site:RelativeRoot': RelativeRoot,
################
'staticoso:PageContent': Content,
'staticoso:PageContentInfo': ContentHeader,
'staticoso:BuildTime': TimeNow,
'staticoso:SiteDomain': SiteDomain,
'staticoso:SiteName': SiteName,
'staticoso:SiteAbsoluteRoot': SiteRoot,
'staticoso:SiteRelativeRoot': RelativeRoot,
}, InternalMacrosWraps)
for e in Meta['Macros']:
HTML = ReplWithEsc(HTML, f"[:{e}:]", Meta['Macros'][e])
for e in FolderRoots:
HTML = DictReplWithEsc(HTML, {
f"[staticoso:CustomPath:{e}]": FolderRoots[e],
f"<staticoso:CustomPath:{e}>": FolderRoots[e],
#DEPRECATED
f"[staticoso:Folder:{e}:AbsoluteRoot]": FolderRoots[e],
f"<staticoso:Folder:{e}:AbsoluteRoot>": FolderRoots[e]})
HTML = WrapDictReplWithEsc(HTML, {
f'staticoso:CustomPath:{e}': FolderRoots[e],
f'staticoso:Folder:{e}:AbsoluteRoot': FolderRoots[e], #DEPRECATED
}, InternalMacrosWraps)
for e in Categories:
HTML = DictReplWithEsc(HTML, {
f"[staticoso:Category:{e}]": Categories[e],
f"<staticoso:Category:{e}>": Categories[e],
f"<staticoso:CategoryList:{e}>": Categories[e],
#DEPRECATED
f"<span>[staticoso:Category:{e}]</span>": Categories[e]})
HTML = WrapDictReplWithEsc(HTML, {
f'staticoso:Category:{e}': Categories[e],
f'staticoso:CategoryList:{e}': Categories[e],
}, InternalMacrosWraps)
HTML = ReplWithEsc(HTML, f'<span>[staticoso:Category:{e}]</span>', Categories[e]) #DEPRECATED
# TODO: Clean this doubling?
ContentHTML = Content
ContentHTML = DictReplWithEsc(ContentHTML, {
ContentHTML = WrapDictReplWithEsc(ContentHTML, {
#'[staticoso:Page:Title]': Title,
#'<staticoso:PageTitle>': Title,
#'[staticoso:Page:Description]': Description,
#'<staticoso:PageDescription>': Description,
#'<staticoso:SiteDomain>': SiteDomain,
#'[staticoso:Site:Name]': SiteName,
#'<staticoso:SiteName>': SiteName,
#'[staticoso:Site:AbsoluteRoot]': SiteRoot,
#'<staticoso:SiteAbsoluteRoot>': SiteRoot,
#'[staticoso:Site:RelativeRoot]': RelativeRoot,
#'<staticoso:SiteRelativeRoot>': RelativeRoot,
# #DEPRECATION #
'[staticoso:Page:Title]': Title,
'<staticoso:PageTitle>': Title,
'[staticoso:Page:Description]': Description,
'[staticoso:Site:Name]': SiteName,
'[staticoso:Site:AbsoluteRoot]': SiteRoot,
'[staticoso:Site:RelativeRoot]': RelativeRoot,
################
'<staticoso:PageTitle>': Title,
'<staticoso:PageDescription>': Description,
'<staticoso:SiteDomain>': SiteDomain,
'[staticoso:Site:Name]': SiteName,
'<staticoso:SiteName>': SiteName,
'[staticoso:Site:AbsoluteRoot]': SiteRoot,
'<staticoso:SiteAbsoluteRoot>': SiteRoot,
'[staticoso:Site:RelativeRoot]': RelativeRoot,
'<staticoso:SiteRelativeRoot>': RelativeRoot})
'<staticoso:SiteRelativeRoot>': RelativeRoot,
}, InternalMacrosWraps)
for e in Meta['Macros']:
ContentHTML = ReplWithEsc(ContentHTML, f"[:{e}:]", Meta['Macros'][e])
for e in FolderRoots:
ContentHTML = DictReplWithEsc(ContentHTML, {
f"[staticoso:CustomPath:{e}]": FolderRoots[e],
f"<staticoso:CustomPath:{e}>": FolderRoots[e],
#DEPRECATED
f"[staticoso:Folder:{e}:AbsoluteRoot]": FolderRoots[e],
f"<staticoso:Folder:{e}:AbsoluteRoot>": FolderRoots[e]})
ContentHTML = WrapDictReplWithEsc(ContentHTML, {
f'staticoso:CustomPath:{e}': FolderRoots[e],
f'staticoso:Folder:{e}:AbsoluteRoot': FolderRoots[e], #DEPRECATED
}, InternalMacrosWraps)
for e in Categories:
ContentHTML = DictReplWithEsc(ContentHTML, {
f"[staticoso:Category:{e}]": Categories[e],
f"<staticoso:Category:{e}>": Categories[e],
f"<staticoso:CategoryList:{e}>": Categories[e],
#DEPRECATED
f"<span>[staticoso:Category:{e}]</span>": Categories[e]})
ContentHTML = WrapDictReplWithEsc(ContentHTML, {
f'staticoso:Category:{e}': Categories[e],
f'staticoso:CategoryList:{e}': Categories[e],
}, InternalMacrosWraps)
ContentHTML = ReplWithEsc(ContentHTML, f'<span>[staticoso:Category:{e}]</span>', Categories[e]) #DEPRECATED
return HTML, ContentHTML, Description, Image

View File

@ -12,13 +12,7 @@ import json
import os
from datetime import datetime
from pathlib import Path
ReservedPaths = ('Site.ini', 'Assets', 'Pages', 'Posts', 'Templates', 'StaticParts', 'DynamicParts')
FileExtensions = {
'Pages': ('htm', 'html', 'markdown', 'md', 'pug', 'txt'),
'HTML': ('.htm', '.html'),
'Markdown': ('.markdown', '.md'),
'Tmp': ('htm', 'markdown', 'md', 'pug', 'txt')}
from Modules.Globals import *
def SureList(e):
return e if type(e) == list else [e]
@ -111,11 +105,18 @@ def ReplWithEsc(Str, Find, Repl, Esc='\\'):
New += Repl + e
return New
def DictReplWithEsc(Str, Dict, Esc='\\'):
def DictReplWithEsc(Str:str, Dict:dict, Esc:str='\\'):
for Item in Dict:
Str = ReplWithEsc(Str, Item, Dict[Item], Esc='\\')
return Str
def WrapDictReplWithEsc(Str:str, Dict:dict, Wraps:list=[], Esc:str='\\'):
NewDict = {}
for Item in Dict:
for Wrap in Wraps:
NewDict.update({f'{Wrap[0]}{Item}{Wrap[1]}': Dict[Item]})
return DictReplWithEsc(Str, NewDict, Esc)
def NumsFromFileName(Path):
Name = Path.split('/')[-1]
Split = len(Name)

11
TODO
View File

@ -1,5 +1,10 @@
- .html input pages bug: // metadata lines not being removed from final file after parsing
- Multi-line metadata flags
- Category-based feeds
- Meta tag generator showing software version (git commit hash)
- Customize date format
- Misskey for ActivityPub
- Section marking in pages (for use with external translators)
- Section marking in pages? (for use with external translators)
- Choosing to use HTML or CSS styling for default internal snippets
- Pages transclusion + probably drop StaticParts (would be redundant)
- User macros with arguments
@ -17,8 +22,8 @@
- Custom path for Posts and Categories
- Support for YAML header in Markdown
- Support for HTML comment lines (<!-- -->) in any format
- Support for rST and AsciiDoc (?)
- Posts in draft state (will not be compiled) / show unlisted status for posts with Index = False
- Support for Wikitext, rST, AsciiDoc (?)
- Posts in draft state (will not be compiled) (?)
- Check if external tools (pug-cli, html2gmi) are installed
- Static code syntax highlighing
- Override internal HTML snippets (meta lines, page lists, redirects, ...) with config file in Templates/NAME.ini