Misc. fixes/improvements; Fixed DiffBuild

This commit is contained in:
octospacc 2022-08-29 20:28:12 +02:00
parent a1e77b8f91
commit c4224e65a3
6 changed files with 115 additions and 69 deletions

View File

@ -71,7 +71,7 @@ Needed for Gemtext output support:
- [x] Generation of global website menu as a tree or as a line
- [x] Generation of page (titles) menu as a tree
- [x] Auto-detection of titles in a page
- [x] _HTML_, TXT, _Extended Markdown_, and _Pug_ supported for input page files
- [x] **HTML**, **TXT**, **Extended Markdown**, and **Pug** supported as input page files
- [ ] Out of heavy-WIP state
## Known issues (might need further investigation)

View File

@ -117,36 +117,44 @@ def Main(Args, FeedEntries):
OutputDir = OptionChoose('public', Args.OutputDir, ReadConf(SiteConf, 'Site', 'OutputDir'))
OutputDir = OutputDir.removesuffix('/')
CheckSafeOutputDir(OutputDir)
print(f"[I] Outputting to {OutputDir}/")
print(f"[I] Outputting to: {OutputDir}/")
DiffBuild = Args.DiffBuild
BlogName = OptionChoose('', Args.BlogName, ReadConf(SiteConf, 'Site', 'BlogName'))
SiteTagline = OptionChoose('', Args.SiteTagline, ReadConf(SiteConf, 'Site', 'Tagline'))
SiteTemplate = OptionChoose('Default.html', Args.SiteTemplate, ReadConf(SiteConf, 'Site', 'Template'))
SiteDomain = OptionChoose('', Args.SiteDomain, ReadConf(SiteConf, 'Site', 'Domain'))
SiteDomain = SiteDomain.removesuffix('/')
SiteRoot = OptionChoose('/', Args.SiteRoot, ReadConf(SiteConf, 'Site', 'Root'))
SiteLang = OptionChoose('en', Args.SiteLang, ReadConf(SiteConf, 'Site', 'Lang'))
Locale = LoadLocale(SiteLang)
MastodonURL = OptionChoose('', Args.MastodonURL, ReadConf(SiteConf, 'Mastodon', 'URL'))
MastodonToken = OptionChoose('', Args.MastodonToken, ReadConf(SiteConf, 'Mastodon', 'Token'))
Sorting = literal_eval(OptionChoose('{}', Args.Sorting, ReadConf(SiteConf, 'Site', 'Sorting')))
DynamicParts = literal_eval(OptionChoose('{}', Args.DynamicParts, ReadConf(SiteConf, 'Site', 'DynamicParts')))
MarkdownExts = literal_eval(OptionChoose(str(MarkdownExtsDefault), Args.MarkdownExts, ReadConf(SiteConf, 'Markdown', 'Exts')))
NoScripts = StringBoolChoose(False, Args.NoScripts, ReadConf(SiteConf, 'Site', 'NoScripts'))
ActivityPubTypeFilter = OptionChoose('Post', Args.ActivityPubTypeFilter, ReadConf(SiteConf, 'ActivityPub', 'TypeFilter'))
ActivityPubHoursLimit = OptionChoose(168, Args.ActivityPubHoursLimit, ReadConf(SiteConf, 'ActivityPub', 'HoursLimit'))
FeedCategoryFilter = OptionChoose('Blog', Args.FeedCategoryFilter, ReadConf(SiteConf, 'Feed', 'CategoryFilter'))
MastodonURL = OptionChoose('', Args.MastodonURL, ReadConf(SiteConf, 'Mastodon', 'URL'))
MastodonToken = OptionChoose('', Args.MastodonToken, ReadConf(SiteConf, 'Mastodon', 'Token'))
MarkdownExts = literal_eval(OptionChoose(str(MarkdownExtsDefault), Args.MarkdownExts, ReadConf(SiteConf, 'Markdown', 'Exts')))
SitemapOutput = StringBoolChoose(True, Args.SitemapOutput, ReadConf(SiteConf, 'Sitemap', 'Output'))
Minify = StringBoolChoose(False, Args.Minify, ReadConf(SiteConf, 'Minify', 'Minify'))
MinifyKeepComments = StringBoolChoose(False, Args.MinifyKeepComments, ReadConf(SiteConf, 'Minify', 'KeepComments'))
NoScripts = StringBoolChoose(False, Args.NoScripts, ReadConf(SiteConf, 'Site', 'NoScripts'))
ImgAltToTitle = StringBoolChoose(True, Args.ImgAltToTitle, ReadConf(SiteConf, 'Site', 'ImgAltToTitle'))
ImgTitleToAlt = StringBoolChoose(False, Args.ImgTitleToAlt, ReadConf(SiteConf, 'Site', 'ImgTitleToAlt'))
CategoriesAutomatic = StringBoolChoose(False, Args.CategoriesAutomatic, ReadConf(SiteConf, 'Categories', 'Automatic'))
CategoriesUncategorized = OptionChoose('Uncategorized', Args.CategoriesUncategorized, ReadConf(SiteConf, 'Categories', 'Uncategorized'))
GemtextOutput = StringBoolChoose(False, Args.GemtextOutput, ReadConf(SiteConf, 'Gemtext', 'Output'))
GemtextHeader = Args.GemtextHeader if Args.GemtextHeader else ReadConf(SiteConf, 'Gemtext', 'Header') if ReadConf(SiteConf, 'Gemtext', 'Header') else f"# {SiteName}\n\n" if SiteName else ''
SitemapOutput = StringBoolChoose(True, Args.SitemapOutput, ReadConf(SiteConf, 'Sitemap', 'Output'))
FeedEntries = int(FeedEntries) if (FeedEntries or FeedEntries == 0) and FeedEntries != 'Default' else int(ReadConf(SiteConf, 'Site', 'FeedEntries')) if ReadConf(SiteConf, 'Site', 'FeedEntries') else 10
Sorting = literal_eval(OptionChoose('{}', Args.Sorting, ReadConf(SiteConf, 'Site', 'Sorting')))
FeedCategoryFilter = OptionChoose('Blog', Args.FeedCategoryFilter, ReadConf(SiteConf, 'Feed', 'CategoryFilter'))
FeedEntries = int(FeedEntries) if (FeedEntries or FeedEntries == 0) and FeedEntries != 'Default' else int(ReadConf(SiteConf, 'Feed', 'Entries')) if ReadConf(SiteConf, 'Feed', 'Entries') else 10
MenuEntries = ReadConf(SiteConf, 'Menu')
if MenuEntries:
@ -154,6 +162,9 @@ def Main(Args, FeedEntries):
else:
ConfMenu = []
SiteDomain = SiteDomain.removesuffix('/')
Locale = LoadLocale(SiteLang)
if DiffBuild:
print("[I] Build mode: Differential")
LimitFiles = GetModifiedFiles(OutputDir)
@ -202,7 +213,8 @@ def Main(Args, FeedEntries):
ImgAltToTitle=ImgAltToTitle, ImgTitleToAlt=ImgTitleToAlt,
Sorting=SetSorting(Sorting),
MarkdownExts=MarkdownExts,
AutoCategories=CategoriesAutomatic)
AutoCategories=CategoriesAutomatic,
CategoryUncategorized=CategoriesUncategorized)
if FeedEntries != 0:
print("[I] Generating Feeds")
@ -235,6 +247,8 @@ def Main(Args, FeedEntries):
MastodonPosts = []
for File, Content, Titles, Meta, ContentHTML, SlimHTML, Description, Image in Pages:
if IsLightRun(File, LimitFiles):
continue
File = f"{OutputDir}/{StripExt(File)}.html"
Content = ReadFile(File)
Post = ''
@ -250,7 +264,7 @@ def Main(Args, FeedEntries):
if GemtextOutput:
print("[I] Generating Gemtext")
GemtextCompileList(OutputDir, Pages, GemtextHeader)
GemtextCompileList(OutputDir, Pages, LimitFiles, GemtextHeader)
print("[I] Cleaning Temporary Files")
DelTmp(OutputDir)
@ -292,8 +306,8 @@ if __name__ == '__main__':
Parser.add_argument('--FeedCategoryFilter', type=str)
Parser.add_argument('--ActivityPubTypeFilter', type=str, help=argparse.SUPPRESS)
Parser.add_argument('--ActivityPubHoursLimit', type=int)
Parser.add_argument('--CategoriesUncategorized', type=str)
Parser.add_argument('--CategoriesAutomatic', type=str)
Parser.add_argument('--CategoriesUncategorized', type=str)
Args = Parser.parse_args()
try:

View File

@ -22,9 +22,11 @@ def FixGemlogDateLine(Line):
Line = Words[0] + '\n' + Words[1][1:] + ' ' + ' '.join(Words[2:])
return Line
def GemtextCompileList(OutputDir, Pages, Header=''):
def GemtextCompileList(OutputDir, Pages, LimitFiles, Header=''):
Cmd = ''
for File, Content, Titles, Meta, ContentHTML, SlimHTML, Description, Image in Pages:
if IsLightRun(File, LimitFiles):
continue
Src = f"{OutputDir}.gmi/{StripExt(File)}.html.tmp"
Dst = f"{OutputDir}.gmi/{StripExt(File)}.gmi"
SlimHTML = StripAttrs(SlimHTML)
@ -33,8 +35,11 @@ def GemtextCompileList(OutputDir, Pages, Header=''):
SlimHTML = SlimHTML.replace(j, '')
WriteFile(Src, SlimHTML.replace('</a>', '</a><br>').replace('.html', '.gmi')) # TODO: Adjust links properly..
Cmd += f'cat "{Src}" | html2gmi > "{Dst}"; '
if Cmd:
os.system(Cmd)
for File, Content, Titles, Meta, ContentHTML, SlimHTML, Description, Image in Pages:
if IsLightRun(File, LimitFiles):
continue
Dst = f"{OutputDir}.gmi/{StripExt(File)}.gmi"
Gemtext = ''
for Line in ReadFile(Dst).splitlines():

View File

@ -149,7 +149,7 @@ def TemplatePreprocessor(Text):
Meta.update({i:MetaDefault[i]})
return Meta
def PagePreprocessor(Path, Type, SiteTemplate, SiteRoot, GlobalMacros, LightRun=False):
def PagePreprocessor(Path, Type, SiteTemplate, SiteRoot, GlobalMacros, CategoryUncategorized, LightRun=False):
File = ReadFile(Path)
Path = Path.lower()
Content, Titles, DashyTitles, HTMLTitlesFound, Macros, Meta, MetaDefault = '', [], [], False, '', '', {
@ -236,7 +236,7 @@ def PagePreprocessor(Path, Type, SiteTemplate, SiteRoot, GlobalMacros, LightRun=
Meta.update({i:MetaDefault[i]})
if Meta['Index'] in ('Default', 'Unspecified'):
if not Meta['Categories']:
Meta['Categories'] = ['Uncategorized']
Meta['Categories'] = [CategoryUncategorized]
if Meta['Type'] == 'Page':
Meta['Index'] = 'False'
elif Meta['Type'] == 'Post':
@ -302,7 +302,7 @@ def CanIndex(Index, For):
else:
return True if Index == For else False
def PatchHTML(File, HTML, StaticPartsText, DynamicParts, DynamicPartsText, HTMLPagesList, PagePath, Content, Titles, Meta, SiteRoot, SiteName, BlogName, FolderRoots, Categories, SiteLang, Locale):
def PatchHTML(File, HTML, StaticPartsText, DynamicParts, DynamicPartsText, HTMLPagesList, PagePath, Content, Titles, Meta, SiteRoot, SiteName, BlogName, FolderRoots, Categories, SiteLang, Locale, LightRun):
HTMLTitles = FormatTitles(Titles)
BodyDescription, BodyImage = '', ''
if not File.lower().endswith('.txt'):
@ -339,6 +339,10 @@ def PatchHTML(File, HTML, StaticPartsText, DynamicParts, DynamicPartsText, HTMLP
for e in StaticPartsText:
HTML = ReplWithEsc(HTML, f"[staticoso:StaticPart:{e}]", StaticPartsText[e])
if LightRun:
HTML = None
else:
HTML = DictReplWithEsc(
HTML, {
'[staticoso:Site:Menu]': HTMLPagesList,
@ -368,6 +372,9 @@ def PatchHTML(File, HTML, StaticPartsText, DynamicParts, DynamicPartsText, HTMLP
ContentHTML = Content
ContentHTML = DictReplWithEsc(
ContentHTML, {
'[staticoso:Page:Title]': Title,
'[staticoso:Page:Description]': Description,
'[staticoso:Site:Name]': SiteName,
'[staticoso:Site:AbsoluteRoot]': SiteRoot,
'[staticoso:Site:RelativeRoot]': GetPathLevels(PagePath)
})
@ -378,11 +385,10 @@ def PatchHTML(File, HTML, StaticPartsText, DynamicParts, DynamicPartsText, HTMLP
for e in Categories:
ContentHTML = ReplWithEsc(ContentHTML, f"<span>[staticoso:Category:{e}]</span>", Categories[e])
ContentHTML = ReplWithEsc(ContentHTML, f"[staticoso:Category:{e}]", Categories[e])
SlimHTML = HTMLPagesList + ContentHTML
return HTML, ContentHTML, SlimHTML, Description, Image
return HTML, ContentHTML, Description, Image
def MakeSite(OutputDir, LimitFiles, TemplatesText, StaticPartsText, DynamicParts, DynamicPartsText, ConfMenu, GlobalMacros, SiteName, BlogName, SiteTagline, SiteTemplate, SiteDomain, SiteRoot, FolderRoots, SiteLang, Locale, Minify, MinifyKeepComments, NoScripts, ImgAltToTitle, ImgTitleToAlt, Sorting, MarkdownExts, AutoCategories):
def MakeSite(OutputDir, LimitFiles, TemplatesText, StaticPartsText, DynamicParts, DynamicPartsText, ConfMenu, GlobalMacros, SiteName, BlogName, SiteTagline, SiteTemplate, SiteDomain, SiteRoot, FolderRoots, SiteLang, Locale, Minify, MinifyKeepComments, NoScripts, ImgAltToTitle, ImgTitleToAlt, Sorting, MarkdownExts, AutoCategories, CategoryUncategorized):
PagesPaths, PostsPaths, Pages, MadePages, Categories = [], [], [], [], {}
for Ext in FileExtensions['Pages']:
for File in Path('Pages').rglob(f"*.{Ext}"):
@ -408,7 +414,7 @@ def MakeSite(OutputDir, LimitFiles, TemplatesText, StaticPartsText, DynamicParts
for File in Files:
TempPath = f"{PathPrefix}{File}"
LightRun = False if LimitFiles == False or TempPath in LimitFiles else True
Content, Titles, Meta = PagePreprocessor(f"{Type}s/{File}", Type, SiteTemplate, SiteRoot, GlobalMacros, LightRun=LightRun)
Content, Titles, Meta = PagePreprocessor(f"{Type}s/{File}", Type, SiteTemplate, SiteRoot, GlobalMacros, CategoryUncategorized, LightRun=LightRun)
Pages += [[TempPath, Content, Titles, Meta]]
for Cat in Meta['Categories']:
Categories.update({Cat:''})
@ -440,7 +446,7 @@ def MakeSite(OutputDir, LimitFiles, TemplatesText, StaticPartsText, DynamicParts
File = f"Categories/{Cat}.md"
FilePath = f"{OutputDir}/{File}"
WriteFile(FilePath, CategoryPageTemplate.format(Title=Cat))
Content, Titles, Meta = PagePreprocessor(FilePath, SiteRoot)
Content, Titles, Meta = PagePreprocessor(FilePath, 'Page', SiteTemplate, SiteRoot, GlobalMacros, CategoryUncategorized, LightRun=LightRun)
Pages += [[File, Content, Titles, Meta]]
for i,e in enumerate(ConfMenu):
@ -451,6 +457,8 @@ def MakeSite(OutputDir, LimitFiles, TemplatesText, StaticPartsText, DynamicParts
print("[I] Writing Pages")
for File, Content, Titles, Meta in Pages:
LightRun = False if LimitFiles == False or File in LimitFiles else True
PagePath = f"{OutputDir}/{StripExt(File)}.html"
if File.lower().endswith(FileExtensions['Markdown']):
Content = markdown(PagePostprocessor('md', Content, Meta), extensions=MarkdownExts)
@ -461,6 +469,9 @@ def MakeSite(OutputDir, LimitFiles, TemplatesText, StaticPartsText, DynamicParts
elif File.lower().endswith(FileExtensions['HTML']):
Content = ReadFile(PagePath)
if LightRun:
HTMLPagesList = None
else:
TemplateMeta = TemplatePreprocessor(TemplatesText[Meta['Template']])
HTMLPagesList = GetHTMLPagesList(
Pages=Pages,
@ -473,7 +484,7 @@ def MakeSite(OutputDir, LimitFiles, TemplatesText, StaticPartsText, DynamicParts
MarkdownExts=MarkdownExts,
MenuStyle=TemplateMeta['MenuStyle'])
HTML, ContentHTML, SlimHTML, Description, Image = PatchHTML(
HTML, ContentHTML, Description, Image = PatchHTML(
File=File,
HTML=TemplatesText[Meta['Template']],
StaticPartsText=StaticPartsText,
@ -490,16 +501,30 @@ def MakeSite(OutputDir, LimitFiles, TemplatesText, StaticPartsText, DynamicParts
FolderRoots=FolderRoots,
Categories=Categories,
SiteLang=SiteLang,
Locale=Locale)
Locale=Locale,
LightRun=LightRun)
if Minify:
if not LightRun:
HTML = DoMinifyHTML(HTML, MinifyKeepComments)
ContentHTML = DoMinifyHTML(ContentHTML, MinifyKeepComments)
if NoScripts:
if not LightRun:
HTML = StripTags(HTML, ['script'])
ContentHTML = StripTags(ContentHTML, ['script'])
if ImgAltToTitle or ImgTitleToAlt:
if not LightRun:
HTML = WriteImgAltAndTitle(HTML, ImgAltToTitle, ImgTitleToAlt)
ContentHTML = WriteImgAltAndTitle(ContentHTML, ImgAltToTitle, ImgTitleToAlt)
if LightRun:
SlimHTML = None
else:
SlimHTML = HTMLPagesList + ContentHTML
if not LightRun:
WriteFile(PagePath, HTML)
MadePages += [[File, Content, Titles, Meta, ContentHTML, SlimHTML, Description, Image]]
return MadePages

View File

@ -154,3 +154,6 @@ def LoadLocale(Lang):
return json.loads(File)
else:
return json.loads(ReadFile(Folder + 'en.json'))
def IsLightRun(File, LimitFiles):
return False if LimitFiles == False or File in LimitFiles else True

3
TODO
View File

@ -1,9 +1,8 @@
- Check if external tools (pug-cli, html2gmi) are installed
- Fix and optimize differential building
- Static code syntax highlighing
- Override internal HTML snippets (with config file in Templates/NAME.ini)
- Override internal HTML snippets (meta lines, page lists, ...) with config file in Templates/NAME.ini
- Specify input folder(s)
- Customize HTML source code for Meta lines / page lists
- Show page size/words/time in meta line
- Add feed support for diary-like pages
- Fix excess whitespace in some section/menu titles