2023-02-23 00:11:49 +01:00
""" ================================== |
| This file is part of |
| staticoso |
| Just a simple Static Site Generator |
| |
| Licensed under the AGPLv3 license |
| Copyright ( C ) 2022 - 2023 , OctoSpacc |
| == == == == == == == == == == == == == == == == == """
2022-07-14 20:38:45 +02:00
2022-08-23 17:25:05 +02:00
from datetime import datetime
2023-02-24 15:29:36 +01:00
from multiprocessing import cpu_count
2022-07-28 16:27:37 +02:00
from Modules . Config import *
2022-08-30 21:10:45 +02:00
from Modules . Elements import *
2022-12-20 13:05:41 +01:00
from Modules . Globals import *
2022-07-18 17:16:21 +02:00
from Modules . HTML import *
2022-09-03 17:48:39 +02:00
from Modules . Logging import *
2022-07-14 20:38:45 +02:00
from Modules . Markdown import *
2023-02-23 00:11:49 +01:00
from Modules . Meta import *
2022-07-14 20:38:45 +02:00
from Modules . Pug import *
from Modules . Utils import *
2023-02-27 18:11:16 +01:00
def HandleStaticParts ( Html : str , Snippets : dict ) :
for e in Snippets [ ' StaticParts ' ] :
Html = ReplWithEsc ( Html , f " [staticoso:StaticPart: { e } ] " , Snippets [ ' StaticParts ' ] [ e ] )
Html = ReplWithEsc ( Html , f " <staticoso:StaticPart: { e } > " , Snippets [ ' StaticParts ' ] [ e ] )
return Html
def HandleDynamicParts ( Flags : dict , Html : str , Snippets : dict ) :
2023-02-24 15:29:36 +01:00
f = NameSpace ( Flags )
2023-02-27 18:11:16 +01:00
Key = ' staticoso:dynamicpart '
if f ' { Key } : ' in Html . lower ( ) : # Reduce unnecessary cycles
for Line in Html . splitlines ( ) :
Line = Line . lstrip ( ) . rstrip ( )
LineLow = Line . lower ( )
if ( LineLow . startswith ( f ' [ { Key } : ' ) and LineLow . endswith ( ' ] ' ) ) or ( LineLow . startswith ( f ' < { Key } : ' ) and LineLow . endswith ( ' > ' ) ) :
Path = Line [ len ( f ' < { Key } : ' ) : - 1 ]
Section = Path . split ( ' / ' ) [ - 1 ]
if Section in f . DynamicParts :
Parts = f . DynamicParts [ Section ]
Text = ' '
Parts = SureList ( Parts )
for Part in Parts :
Text + = Snippets [ ' DynamicParts ' ] [ f ' { Path } / { Part } ' ] + ' \n '
else :
Text = ' '
Html = ReplWithEsc ( Html , f ' [staticoso:DynamicPart: { Path } ] ' , Text )
Html = ReplWithEsc ( Html , f ' <staticoso:DynamicPart: { Path } > ' , Text )
return Html
# TODO: This would need to be handled either fully before or fully after after all pages' content has been transformed to HTML, else other markups end up in HTML and the page is broken
def HandleTransclusions ( Html : str , Caller : str , Pages : list ) :
#if Type == 'Evals': # [% cmd %] | {% cmd %}
Targets = [ ]
Finding = Html
Start = Finding . find ( ' {{ ' )
while Start != - 1 :
Start = Start + 2
Finding = Finding [ Start : ]
Stop = Finding . find ( ' }} ' )
if Stop != - 1 :
Targets + = [ Finding [ : Stop ] ]
Start = Finding . find ( ' {{ ' )
for Target in Targets :
# Maybe we should show an error message on possible recursive transclusion, as currently this doesn't handle escaped tokens
if Target != Caller :
for File , Content , _ , _ in Pages :
if File == Target :
Html = ReplWithEsc ( Html , ' {{ ' + Target + ' }} ' , Content )
break
return Html
2023-02-23 17:05:36 +01:00
2023-02-27 18:11:16 +01:00
def PatchHtml ( Flags : dict , Pages : list , Page : dict , Context : dict , Snippets : dict , Locale : dict , LightRun ) :
f = NameSpace ( Flags )
File , PagePath , Content , Titles , Meta = tuple ( Page . values ( ) )
Html , HtmlPagesList , Categories = tuple ( Context . values ( ) )
HtmlTitles = FormatTitles ( Titles )
2022-07-14 20:38:45 +02:00
BodyDescription , BodyImage = ' ' , ' '
2022-08-14 17:35:58 +02:00
if not File . lower ( ) . endswith ( ' .txt ' ) :
2022-12-20 13:05:41 +01:00
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
2022-08-14 17:35:58 +02:00
if not BodyImage and Soup . img and Soup . img [ ' src ' ] :
BodyImage = Soup . img [ ' src ' ]
2022-07-29 18:12:13 +02:00
2022-08-14 17:35:58 +02:00
#Content = SquareFnrefs(Content)
2022-12-20 13:05:41 +01:00
if ' <a class= " footnote-ref " ' in Content :
Content = AddToTagStartEnd ( Content , ' <a class= " footnote-ref " ' , ' </a> ' , ' [ ' , ' ] ' )
2022-07-14 20:38:45 +02:00
2022-10-26 11:01:17 +02:00
if any ( _ in Content for _ in ( ' <!-- noprocess /> ' , ' <!--noprocess/> ' , ' </ noprocess --> ' , ' </ noprocess ---> ' , ' </noprocess--> ' , ' </noprocess---> ' ) ) :
2022-09-03 17:48:39 +02:00
Content = DictReplWithEsc (
Content , {
2022-12-20 13:05:41 +01:00
' <!--< % noprocess> ' : ' ' ,
' <noprocess % >--> ' : ' ' ,
' <noprocess % >---> ' : ' ' ,
2022-10-26 11:01:17 +02:00
' <!-- noprocess /> ' : ' ' ,
' <!--noprocess/> ' : ' ' ,
' </ noprocess --> ' : ' ' ,
' </ noprocess ---> ' : ' ' ,
' </noprocess--> ' : ' ' ,
' </noprocess---> ' : ' ' } )
2022-09-03 17:48:39 +02:00
2023-02-24 15:29:36 +01:00
Title = GetTitle ( File . split ( ' / ' ) [ - 1 ] , Meta , Titles , ' MetaTitle ' , f . BlogName )
2022-07-14 20:38:45 +02:00
Description = GetDescription ( Meta , BodyDescription , ' MetaDescription ' )
Image = GetImage ( Meta , BodyImage , ' MetaImage ' )
2022-10-19 11:27:51 +02:00
ContentHeader = MakeContentHeader ( Meta , Locale , MakeCategoryLine ( File , Meta ) )
TimeNow = datetime . now ( ) . strftime ( ' % Y- % m- %d % H: % M ' )
2022-11-04 11:03:43 +01:00
RelativeRoot = GetPathLevels ( PagePath )
2022-07-14 20:38:45 +02:00
2023-02-27 18:11:16 +01:00
Html = WhileFuncResultChanges ( HandleDynamicParts , { " Flags " : Flags , " Html " : Html , " Snippets " : Snippets } , ' Html ' )
Html = WhileFuncResultChanges ( HandleStaticParts , { " Html " : Html , " Snippets " : Snippets } , ' Html ' )
2022-08-29 20:28:12 +02:00
if LightRun :
2023-02-27 18:11:16 +01:00
Html = None
2022-08-29 20:28:12 +02:00
else :
2023-02-27 18:11:16 +01:00
Html = WrapDictReplWithEsc ( Html , {
2022-12-20 13:05:41 +01:00
#'[staticoso:PageHead]': Meta['Head'],
#'<staticoso:PageHead>': Meta['Head'],
# #DEPRECATION #
2023-02-27 18:11:16 +01:00
' staticoso:Site:Menu ' : HtmlPagesList ,
2023-02-24 15:29:36 +01:00
' staticoso:Page:Lang ' : Meta [ ' Language ' ] if Meta [ ' Language ' ] else f . SiteLang ,
2023-02-27 18:11:16 +01:00
' staticoso:Page:Chapters ' : HtmlTitles ,
2022-12-20 13:05:41 +01:00
' staticoso:Page:Title ' : Title ,
' staticoso:Page:Description ' : Description ,
' staticoso:Page:Image ' : Image ,
' staticoso:Page:Path ' : PagePath ,
' staticoso:Page:Style ' : Meta [ ' Style ' ] ,
################
2023-02-27 18:11:16 +01:00
' staticoso:SiteMenu ' : HtmlPagesList ,
2023-02-24 15:29:36 +01:00
' staticoso:PageLang ' : Meta [ ' Language ' ] if Meta [ ' Language ' ] else f . SiteLang ,
' staticoso:PageLanguage ' : Meta [ ' Language ' ] if Meta [ ' Language ' ] else f . SiteLang ,
2023-02-27 18:11:16 +01:00
' staticoso:PageSections ' : HtmlTitles ,
2022-12-20 13:05:41 +01:00
' staticoso:PageTitle ' : Title ,
' staticoso:PageDescription ' : Description ,
' staticoso:PageImage ' : Image ,
' staticoso:PagePath ' : PagePath ,
' staticoso:PageHead ' : Meta [ ' Head ' ] ,
' staticoso:PageStyle ' : Meta [ ' Style ' ] ,
2022-11-04 11:03:43 +01:00
# NOTE: Content is injected in page only at this point! Keep in mind for other substitutions
2022-12-20 13:05:41 +01:00
# #DEPRECATION #
' staticoso:Page:Content ' : Content ,
' staticoso:Page:ContentInfo ' : ContentHeader ,
2023-02-24 15:29:36 +01:00
' staticoso:Site:Name ' : f . SiteName ,
' staticoso:Site:AbsoluteRoot ' : f . SiteRoot ,
2022-12-20 13:05:41 +01:00
' staticoso:Site:RelativeRoot ' : RelativeRoot ,
################
' staticoso:PageContent ' : Content ,
' staticoso:PageContentInfo ' : ContentHeader ,
' staticoso:BuildTime ' : TimeNow ,
2023-02-24 15:29:36 +01:00
' staticoso:SiteDomain ' : f . SiteDomain ,
' staticoso:SiteName ' : f . SiteName ,
' staticoso:BlogName ' : f . BlogName ,
' staticoso:SiteAbsoluteRoot ' : f . SiteRoot ,
2022-12-20 13:05:41 +01:00
' staticoso:SiteRelativeRoot ' : RelativeRoot ,
} , InternalMacrosWraps )
2023-02-27 18:11:16 +01:00
#Html = WhileFuncResultChanges(HandleTransclusions, {"Html": Html, "Caller": File, "Pages": Pages}, 'Html')
2022-11-04 11:03:43 +01:00
for e in Meta [ ' Macros ' ] :
2023-02-27 18:11:16 +01:00
Html = ReplWithEsc ( Html , f " [: { e } :] " , Meta [ ' Macros ' ] [ e ] )
2023-02-24 15:29:36 +01:00
for e in f . FolderRoots :
2023-02-27 18:11:16 +01:00
Html = WrapDictReplWithEsc ( Html , {
2023-02-24 15:29:36 +01:00
f ' staticoso:CustomPath: { e } ' : f . FolderRoots [ e ] ,
f ' staticoso:Folder: { e } :AbsoluteRoot ' : f . FolderRoots [ e ] , #DEPRECATED
2022-12-20 13:05:41 +01:00
} , InternalMacrosWraps )
2022-11-04 11:03:43 +01:00
for e in Categories :
2023-02-27 18:11:16 +01:00
Html = WrapDictReplWithEsc ( Html , {
2022-12-20 13:05:41 +01:00
f ' staticoso:Category: { e } ' : Categories [ e ] ,
f ' staticoso:CategoryList: { e } ' : Categories [ e ] ,
} , InternalMacrosWraps )
2023-02-27 18:11:16 +01:00
Html = ReplWithEsc ( Html , f ' <span>[staticoso:Category: { e } ]</span> ' , Categories [ e ] ) #DEPRECATED
2022-11-04 11:03:43 +01:00
# TODO: Clean this doubling?
2023-02-27 18:11:16 +01:00
ContentHtml = Content
ContentHtml = WrapDictReplWithEsc ( ContentHtml , {
2022-12-20 13:05:41 +01:00
# #DEPRECATION #
2022-11-04 11:03:43 +01:00
' [staticoso:Page:Title] ' : Title ,
' [staticoso:Page:Description] ' : Description ,
2023-02-24 15:29:36 +01:00
' [staticoso:Site:Name] ' : f . SiteName ,
' [staticoso:Site:AbsoluteRoot] ' : f . SiteRoot ,
2022-12-20 13:05:41 +01:00
' [staticoso:Site:RelativeRoot] ' : RelativeRoot ,
################
' <staticoso:PageTitle> ' : Title ,
2022-11-04 11:03:43 +01:00
' <staticoso:PageDescription> ' : Description ,
2023-02-24 15:29:36 +01:00
' <staticoso:SiteDomain> ' : f . SiteDomain ,
' <staticoso:SiteName> ' : f . SiteName ,
' <staticoso:SiteAbsoluteRoot> ' : f . SiteRoot ,
2022-12-20 13:05:41 +01:00
' <staticoso:SiteRelativeRoot> ' : RelativeRoot ,
} , InternalMacrosWraps )
2023-02-27 18:11:16 +01:00
#Html = WhileFuncResultChanges(HandleTransclusions, {"Html": Html, "Caller": File, "Pages": Pages}, 'Html')
2022-07-28 16:27:37 +02:00
for e in Meta [ ' Macros ' ] :
2023-02-27 18:11:16 +01:00
ContentHtml = ReplWithEsc ( ContentHtml , f " [: { e } :] " , Meta [ ' Macros ' ] [ e ] )
2023-02-24 15:29:36 +01:00
for e in f . FolderRoots :
2023-02-27 18:11:16 +01:00
ContentHtml = WrapDictReplWithEsc ( ContentHtml , {
2023-02-24 15:29:36 +01:00
f ' staticoso:CustomPath: { e } ' : f . FolderRoots [ e ] ,
f ' staticoso:Folder: { e } :AbsoluteRoot ' : f . FolderRoots [ e ] , #DEPRECATED
2022-12-20 13:05:41 +01:00
} , InternalMacrosWraps )
2022-07-28 16:27:37 +02:00
for e in Categories :
2023-02-27 18:11:16 +01:00
ContentHtml = WrapDictReplWithEsc ( ContentHtml , {
2022-12-20 13:05:41 +01:00
f ' staticoso:Category: { e } ' : Categories [ e ] ,
f ' staticoso:CategoryList: { e } ' : Categories [ e ] ,
} , InternalMacrosWraps )
2023-02-27 18:11:16 +01:00
ContentHtml = ReplWithEsc ( ContentHtml , f ' <span>[staticoso:Category: { e } ]</span> ' , Categories [ e ] ) #DEPRECATED
2022-07-14 20:38:45 +02:00
2023-02-27 18:11:16 +01:00
return Html , ContentHtml , Description , Image
2022-07-14 20:38:45 +02:00
2023-02-24 15:29:36 +01:00
def BuildPagesSearch ( Flags : dict , Pages : list , Template : str , Snippets : dict , Locale : dict ) :
SearchContent = ' '
with open ( f ' { staticosoBaseDir ( ) } Assets/PagesSearch.html ' , ' r ' ) as File :
Base = File . read ( ) . split ( ' {{ PagesInject}} ' )
for Page in Pages :
SearchContent + = f '''
< div
class = " staticoso-HtmlSearch-Page "
data - staticoso - htmlsearch - name = " { html.escape(html.unescape(Page[ " Titles " ][0]), quote=True)} "
data - staticoso - htmlsearch - href = " { StripExt(Page[ " File " ])}.html "
>
{ Page [ " ContentHtml " ] }
< / div >
'''
2023-02-27 18:11:16 +01:00
return PatchHtml (
2023-02-24 15:29:36 +01:00
Flags = Flags ,
2023-02-27 18:11:16 +01:00
Pages = [ ] ,
Page = { " File " : " Search.html " , " PagePath " : " Search.html " , " Content " : Base [ 0 ] + SearchContent + Base [ 1 ] , " Titles " : [ ] , " Meta " : PageMetaDefault } ,
Context = { " Html " : Template , " HtmlPagesList " : " " , " Categories " : [ ] } ,
2023-02-24 15:29:36 +01:00
Snippets = Snippets ,
Locale = Locale ,
LightRun = False ) [ 0 ]
2023-02-27 18:11:16 +01:00
def HandlePage ( Flags : dict , Page : list , Pages : list , Categories , LimitFiles , Snippets : dict , ConfMenu , Locale : dict ) :
2022-08-30 21:10:45 +02:00
File , Content , Titles , Meta = Page
2023-02-24 15:29:36 +01:00
f = NameSpace ( Flags )
TemplatesText = Snippets [ ' Templates ' ]
2022-08-30 21:10:45 +02:00
FileLower = File . lower ( )
2023-02-24 15:29:36 +01:00
PagePath = f ' { f . OutDir } / { StripExt ( File ) } .html '
ContentPagePath = f ' { f . OutDir } .Content/ { StripExt ( File ) } .html '
2022-08-30 21:10:45 +02:00
LightRun = False if LimitFiles == False or File in LimitFiles else True
if FileLower . endswith ( FileExtensions [ ' Markdown ' ] ) :
2023-02-24 15:29:36 +01:00
Content = markdown ( PagePostprocessor ( ' md ' , Content , Meta ) , extensions = f . MarkdownExts )
2022-08-30 21:10:45 +02:00
elif FileLower . endswith ( ( ' .pug ' ) ) :
Content = PagePostprocessor ( ' pug ' , ReadFile ( PagePath ) , Meta )
elif FileLower . endswith ( ( ' .txt ' ) ) :
Content = ' <pre> ' + html . escape ( Content ) + ' </pre> '
2023-02-22 22:46:04 +01:00
#elif FileLower.endswith(FileExtensions['HTML']):
# Content = ReadFile(PagePath)
2022-08-30 21:10:45 +02:00
if LightRun :
HTMLPagesList = None
else :
TemplateMeta = TemplatePreprocessor ( TemplatesText [ Meta [ ' Template ' ] ] )
HTMLPagesList = GetHTMLPagesList (
2023-02-23 17:05:36 +01:00
Flags ,
2022-08-30 21:10:45 +02:00
Pages = Pages ,
PathPrefix = GetPathLevels ( File ) ,
Unite = ConfMenu ,
Type = ' Page ' ,
For = ' Menu ' ,
MenuStyle = TemplateMeta [ ' MenuStyle ' ] )
2022-08-31 00:18:23 +02:00
2023-02-27 18:11:16 +01:00
HTML , ContentHTML , Description , Image = PatchHtml (
2023-02-23 17:05:36 +01:00
Flags ,
2023-02-27 18:11:16 +01:00
Pages = Pages ,
Page = { " File " : File , " PagePath " : PagePath [ len ( f " { f . OutDir } / " ) : ] , " Content " : Content , " Titles " : Titles , " Meta " : Meta } ,
Context = { " Html " : TemplatesText [ Meta [ ' Template ' ] ] , " HtmlPagesList " : HTMLPagesList , " Categories " : Categories } ,
2023-02-24 15:29:36 +01:00
Snippets = Snippets ,
2022-08-30 21:10:45 +02:00
Locale = Locale ,
LightRun = LightRun )
2022-10-26 11:01:17 +02:00
HTML = ReplWithEsc ( HTML , f " <staticoso:Feed> " , GetHTMLPagesList (
2023-02-23 17:05:36 +01:00
Flags ,
2022-10-26 11:01:17 +02:00
Limit = Flags [ ' FeedEntries ' ] ,
Type = ' Post ' ,
Category = None if Flags [ ' FeedCategoryFilter ' ] == ' * ' else Flags [ ' FeedCategoryFilter ' ] ,
Pages = Pages ,
PathPrefix = GetPathLevels ( File ) ,
For = ' Categories ' ,
2022-10-31 22:05:16 +01:00
MenuStyle = ' Flat ' ,
ShowPaths = False ) )
2022-10-25 10:13:00 +02:00
if ' staticoso:DirectoryList: ' in HTML : # Reduce risk of unnecessary cycles
for Line in HTML . splitlines ( ) :
Line = Line . lstrip ( ) . rstrip ( )
if Line . startswith ( ' <staticoso:DirectoryList: ' ) and Line . endswith ( ' > ' ) :
Path = Line [ len ( ' <staticoso:DirectoryList: ' ) : - 1 ]
DirectoryList = GetHTMLPagesList (
2023-02-23 17:05:36 +01:00
Flags ,
2022-10-25 12:04:17 +02:00
CallbackFile = File ,
2022-10-25 10:13:00 +02:00
Pages = Pages ,
PathPrefix = GetPathLevels ( File ) ,
PathFilter = Path ,
For = ' Categories ' ,
MenuStyle = ' Flat ' )
HTML = ReplWithEsc ( HTML , f " <staticoso:DirectoryList: { Path } > " , DirectoryList )
2022-11-05 12:17:23 +01:00
if Flags [ ' MinifyOutput ' ] :
2022-08-30 21:10:45 +02:00
if not LightRun :
2023-02-24 15:29:36 +01:00
HTML = DoMinifyHTML ( HTML , f . MinifyKeepComments )
ContentHTML = DoMinifyHTML ( ContentHTML , f . MinifyKeepComments )
2022-11-17 13:03:17 +01:00
if Flags [ ' NoScripts ' ] and ( ' <script ' in ContentHTML . lower ( ) or ' <script ' in HTML . lower ( ) ) :
2022-08-30 21:10:45 +02:00
if not LightRun :
HTML = StripTags ( HTML , [ ' script ' ] )
ContentHTML = StripTags ( ContentHTML , [ ' script ' ] )
2023-02-24 15:29:36 +01:00
if f . ImgAltToTitle or f . ImgTitleToAlt :
2022-08-30 21:10:45 +02:00
if not LightRun :
2023-02-24 15:29:36 +01:00
HTML = WriteImgAltAndTitle ( HTML , f . ImgAltToTitle , f . ImgTitleToAlt )
ContentHTML = WriteImgAltAndTitle ( ContentHTML , f . ImgAltToTitle , f . ImgTitleToAlt )
2022-09-03 17:48:39 +02:00
if Flags [ ' HTMLFixPre ' ] :
if not LightRun :
HTML = DoHTMLFixPre ( HTML )
ContentHTML = DoHTMLFixPre ( ContentHTML )
2022-08-31 00:18:23 +02:00
2022-08-30 21:10:45 +02:00
if LightRun :
SlimHTML = None
else :
SlimHTML = HTMLPagesList + ContentHTML
if not LightRun :
WriteFile ( PagePath , HTML )
2023-02-22 22:46:04 +01:00
WriteFile ( ContentPagePath , ContentHTML )
2022-08-31 00:18:23 +02:00
2022-11-18 20:51:54 +01:00
if not LightRun and ' htmljournal ' in ContentHTML . lower ( ) : # Avoid extra cycles
2023-02-27 18:11:16 +01:00
HTML , _ , _ , _ = PatchHtml (
2023-02-23 17:05:36 +01:00
Flags ,
2023-02-27 18:11:16 +01:00
Pages = Pages ,
Page = { " File " : File , " PagePath " : f ' { StripExt ( File ) } .Journal.html ' , " Content " : MakeHTMLJournal ( Flags , Locale , f ' { StripExt ( File ) } .html ' , ContentHTML ) , " Titles " : " " , " Meta " : Meta } ,
Context = { " Html " : TemplatesText [ Meta [ ' Template ' ] ] , " HtmlPagesList " : HTMLPagesList , " Categories " : Categories } ,
2023-02-24 15:29:36 +01:00
Snippets = Snippets ,
2022-11-18 20:51:54 +01:00
Locale = Locale ,
LightRun = LightRun )
if Flags [ " JournalRedirect " ] :
HTML = HTML . replace ( ' </head> ' , f """ <meta http-equiv= " refresh " content= " 0; url= ' ./ { PagePath . split ( ''' / ''' ) [ - 1 ] } ' " ></head> """ )
WriteFile ( StripExt ( PagePath ) + ' .Journal.html ' , HTML )
2023-02-24 15:29:36 +01:00
return { " File " : File , " Content " : Content , " Titles " : Titles , " Meta " : Meta , " ContentHtml " : ContentHTML , " SlimHtml " : SlimHTML , " Description " : Description , " Image " : Image }
2022-08-30 21:10:45 +02:00
2023-02-23 17:05:36 +01:00
def MultiprocPagePreprocessor ( d : dict ) :
2023-02-24 15:29:36 +01:00
return PagePreprocessor ( d [ ' Flags ' ] , d [ ' Page ' ] , d [ ' GlobalMacros ' ] , d [ ' LightRun ' ] )
2022-08-30 21:10:45 +02:00
2023-02-23 17:05:36 +01:00
def MultiprocHandlePage ( d : dict ) :
2022-10-17 15:53:07 +02:00
return HandlePage ( d [ ' Flags ' ] , d [ ' Page ' ] , d [ ' Pages ' ] , d [ ' Categories ' ] , d [ ' LimitFiles ' ] , d [ ' Snippets ' ] , d [ ' ConfMenu ' ] , d [ ' Locale ' ] )
2023-02-23 17:05:36 +01:00
def FindPagesPaths ( ) :
Paths = { " Pages " : [ ] , " Posts " : [ ] }
for Ext in FileExtensions [ ' Pages ' ] :
for Type in ( ' Pages ' , ' Posts ' ) :
for File in Path ( Type ) . rglob ( f ' *. { Ext } ' ) :
Paths [ Type ] + = [ FileToStr ( File , f ' { Type } / ' ) ]
return Paths
def ReorderPagesPaths ( Paths : dict , Sorting : dict ) :
for Type in ( ' Pages ' , ' Posts ' ) :
Paths [ Type ] = FileNameDateSort ( Paths [ Type ] )
if Sorting [ Type ] in ( ' Inverse ' , ' Reverse ' ) :
Paths [ Type ] . reverse ( )
return Paths
2023-02-27 18:11:16 +01:00
def PopulateCategoryLists ( Flags : dict , Pages : list , Categories : dict ) :
2023-02-23 17:05:36 +01:00
for Cat in Categories :
for Type in ( ' Page ' , ' Post ' ) :
Categories [ Cat ] + = GetHTMLPagesList (
Flags ,
Pages = Pages ,
PathPrefix = GetPathLevels ( ' Categories/ ' ) ,
Type = Type ,
Category = Cat ,
For = ' Categories ' ,
MenuStyle = ' Flat ' )
return Categories
def MakeAutoCategories ( Flags : dict , Categories ) :
Pages = [ ]
if Flags [ ' CategoriesAutomatic ' ] :
OutDir = Flags [ ' OutDir ' ]
Dir = f ' { OutDir } /Categories '
for Cat in Categories :
Exists = False
for File in Path ( Dir ) . rglob ( str ( Cat ) + ' .* ' ) :
Exists = True
break
if not Exists :
File = f ' Categories/ { Cat } .md '
FilePath = f ' { OutDir } / { File } '
WriteFile ( FilePath , CategoryPageTemplate . format ( Name = Cat ) )
2023-02-24 15:29:36 +01:00
_ , Content , Titles , Meta = PagePreprocessor ( Flags , [ FilePath , FilePath , Type , None ] , GlobalMacros , LightRun = LightRun )
2023-02-23 17:05:36 +01:00
Pages + = [ File , Content , Titles , Meta ]
return Pages
2023-02-24 15:29:36 +01:00
def PreprocessSourcePages ( Flags : dict , PagesPaths : dict , LimitFiles , GlobalMacros : dict , PoolSize : int ) :
2023-02-23 17:05:36 +01:00
MultiprocPages = [ ]
for Type in ( ' Page ' , ' Post ' ) :
Files , PathPrefix = { " Page " : [ PagesPaths [ ' Pages ' ] , ' ' ] , " Post " : [ PagesPaths [ ' Posts ' ] , ' Posts/ ' ] } [ Type ]
for i , File in enumerate ( Files ) :
TempPath = f " { PathPrefix } { File } "
LightRun = False if LimitFiles == False or TempPath in LimitFiles else True
2023-02-24 15:29:36 +01:00
MultiprocPages + = [ { ' Flags ' : Flags , ' Page ' : [ f " { Type } s/ { File } " , TempPath , Type , None ] , ' GlobalMacros ' : GlobalMacros , ' LightRun ' : LightRun } ]
2023-02-23 17:05:36 +01:00
return DoMultiProc ( MultiprocPagePreprocessor , MultiprocPages , PoolSize , True )
def WriteProcessedPages ( Flags : dict , Pages : list , Categories , ConfMenu , Snippets , LimitFiles , PoolSize : int , Locale : dict ) :
MultiprocPages = [ ]
for i , Page in enumerate ( Pages ) :
MultiprocPages + = [ { ' Flags ' : Flags , ' Page ' : Page , ' Pages ' : Pages , ' Categories ' : Categories , ' LimitFiles ' : LimitFiles , ' Snippets ' : Snippets , ' ConfMenu ' : ConfMenu , ' Locale ' : Locale } ]
return DoMultiProc ( MultiprocHandlePage , MultiprocPages , PoolSize , True )
2023-02-24 15:29:36 +01:00
def MakeSite ( Flags : dict , LimitFiles , Snippets , ConfMenu , GlobalMacros : dict , Locale : dict , Threads : int ) :
2023-02-23 17:05:36 +01:00
Pages , MadePages , Categories = [ ] , [ ] , { }
2022-09-03 17:48:39 +02:00
PoolSize = cpu_count ( ) if Threads < = 0 else Threads
2023-02-23 17:05:36 +01:00
f = NameSpace ( Flags )
2022-08-30 16:31:33 +02:00
2023-02-23 17:05:36 +01:00
logging . info ( " Finding Pages " )
PagesPaths = FindPagesPaths ( )
logging . info ( f " Pages Found: { len ( PagesPaths [ ' Pages ' ] + PagesPaths [ ' Posts ' ] ) } " )
logging . info ( " Reordering Pages " )
PagesPaths = ReorderPagesPaths ( PagesPaths , f . Sorting )
2022-07-14 20:38:45 +02:00
2022-09-03 17:48:39 +02:00
logging . info ( " Preprocessing Source Pages " )
2023-02-24 15:29:36 +01:00
Pages = PreprocessSourcePages ( Flags , PagesPaths , LimitFiles , GlobalMacros , PoolSize )
PugCompileList ( f . OutDir , Pages , LimitFiles )
2022-10-17 15:53:07 +02:00
2023-02-24 15:29:36 +01:00
logging . info ( " Parsing Categories " )
2022-08-31 00:18:23 +02:00
for File , Content , Titles , Meta in Pages :
for Cat in Meta [ ' Categories ' ] :
Categories . update ( { Cat : ' ' } )
2023-02-23 17:05:36 +01:00
if Categories or f . CategoriesAutomatic :
2022-09-03 17:48:39 +02:00
logging . info ( " Generating Category Lists " )
2023-02-23 17:05:36 +01:00
Categories = PopulateCategoryLists ( Flags , Pages , Categories )
Pages + = MakeAutoCategories ( Flags , Categories )
2022-07-14 20:38:45 +02:00
2023-02-22 22:46:04 +01:00
#logging.info("Building the HTML Search Page")
2023-02-23 17:05:36 +01:00
#Pages += [PagePreprocessor(Flags, Path='Search.html', TempPath='Search.html', Type='Page', SiteTemplate=SiteTemplate, GlobalMacros=GlobalMacros, LightRun=LightRun, Content=BuildPagesSearch(Flags, Pages))]
2023-02-22 22:46:04 +01:00
2022-07-15 00:12:58 +02:00
for i , e in enumerate ( ConfMenu ) :
for File , Content , Titles , Meta in Pages :
File = StripExt ( File ) + ' .html '
if e == File :
ConfMenu [ i ] = None
2022-09-03 17:48:39 +02:00
logging . info ( " Writing Pages " )
2023-02-23 17:05:36 +01:00
MadePages = WriteProcessedPages ( Flags , Pages , Categories , ConfMenu , Snippets , LimitFiles , PoolSize , Locale )
2022-07-14 20:38:45 +02:00
return MadePages