diff --git a/Source/Build.py b/Source/Build.py
index 23ef59b..629cf51 100755
--- a/Source/Build.py
+++ b/Source/Build.py
@@ -101,6 +101,21 @@ def GetModifiedFiles(OutDir):
Mod += [File['Tmp']]
return Mod
+def WriteRedirects(Flags, Pages, FinalPaths, Locale):
+ OutDir, SiteName, SiteDomain = Flags['OutDir'], Flags['SiteName'], Flags['SiteDomain']
+ for File, Content, Titles, Meta, ContentHTML, SlimHTML, Description, Image in Pages:
+ for URL in Meta['URLs']:
+ DestFile = f"{OutDir}/{URL}"
+ if DestFile not in FinalPaths:
+ DestURL = f"{GetPathLevels(URL)}{StripExt(File)}.html"
+ mkdirps(os.path.dirname(DestFile))
+ WriteFile(DestFile, RedirectPageTemplate.format(
+ SiteDomain=SiteDomain,
+ DestURL=DestURL,
+ TitlePrefix=f"{SiteName} - " if SiteName else '',
+ StrClick=Locale['ClickHere'],
+ StrRedirect=Locale['IfNotRedirected']))
+
def Main(Args, FeedEntries):
Flags, Snippets, FinalPaths = {}, {}, []
HavePages, HavePosts = False, False
@@ -238,21 +253,8 @@ def Main(Args, FeedEntries):
WriteFile(File, Content)
FinalPaths += [File]
- logging.info("Creating Redirects")
- for File, Content, Titles, Meta, ContentHTML, SlimHTML, Description, Image in Pages:
- for URL in Meta['URLs']:
- DestFile = f"{OutDir}/{URL}"
- if DestFile not in FinalPaths:
- DestURL = f"{GetPathLevels(URL)}{StripExt(File)}.html"
- mkdirps(os.path.dirname(DestFile))
- WriteFile(
- DestFile,
- RedirectPageTemplate.format(
- SiteDomain=SiteDomain,
- DestURL=DestURL,
- TitlePrefix=f"{SiteName} - " if SiteName else '',
- StrClick=Locale['ClickHere'],
- StrRedirect=Locale['IfNotRedirected']))
+ logging.debug("Creating Redirects")
+ WriteRedirects(Flags, Pages, FinalPaths, Locale)
if Flags['GemtextOutput']:
logging.info("Generating Gemtext")
diff --git a/Source/Modules/Elements.py b/Source/Modules/Elements.py
index 25ab7aa..0118575 100644
--- a/Source/Modules/Elements.py
+++ b/Source/Modules/Elements.py
@@ -10,8 +10,8 @@
from Modules.HTML import *
from Modules.Utils import *
-HTMLSectionTitleLine = '» {Title}'
-#PugSectionTitleLine = "{Line[:Index]}{Line[Index:Index+2]}.SectionHeading #[span.SectionLink #[a(href='#{DashTitle}') #[span »]] ]#[span#{DashTitle}.SectionTitle {Line[Index+2:]}]"
+HTMLSectionTitleLine = '» {Title}'
+PugSectionTitleLine = "{Start}{Heading}.SectionHeading.staticoso-SectionHeading #[span.SectionLink.staticoso-SectionLink #[a(href='#{DashTitle}') #[span »]] ]#[span#{DashTitle}.SectionTitle.staticoso-SectionTitle {Rest}]"
CategoryPageTemplate = """\
// Title: {Name}
// Type: Page
@@ -48,7 +48,11 @@ def MakeLinkableTitle(Line, Title, DashTitle, Type):
Title=Title[Index+1:])
elif Type == 'pug':
Index = Line.find('h')
- return f"{Line[:Index]}{Line[Index:Index+2]}.SectionHeading #[span.SectionLink #[a(href='#{DashTitle}') #[span »]] ]#[span#{DashTitle}.SectionTitle {Line[Index+2:]}]"
+ return PugSectionTitleLine.format(
+ Start=Line[:Index],
+ Heading=Line[Index:Index+2],
+ Rest=Line[Index+2:],
+ DashTitle=DashTitle)
def GetTitle(FileName, Meta, Titles, Prefer='MetaTitle', BlogName=None):
if Prefer == 'BodyTitle':
@@ -86,18 +90,16 @@ def MakeContentHeader(Meta, Locale, Categories=''):
def MakeCategoryLine(File, Meta):
Categories = ''
- if Meta['Categories']:
- for Cat in Meta['Categories']:
- Categories += f' {html.escape(Cat)} '
+ for Cat in Meta['Categories']:
+ Categories += f' {html.escape(Cat)} '
return Categories
def MakeListTitle(File, Meta, Titles, Prefer, SiteRoot, BlogName, PathPrefix=''):
Title = GetTitle(File.split('/')[-1], Meta, Titles, Prefer, BlogName).lstrip().rstrip()
Link = False if Meta['Index'] == 'Unlinked' else True
if Link:
- Title = '[{}]({})'.format(
- Title,
- '{}{}.html'.format(PathPrefix, StripExt(File)))
+ Href = f'{PathPrefix}{StripExt(File)}.html'
+ Title = f'{Title}'
if Meta['Type'] == 'Post':
CreatedOn = Meta['CreatedOn'] if Meta['CreatedOn'] else '?'
Title = f"[{CreatedOn}] {Title}"
diff --git a/Source/Modules/Site.py b/Source/Modules/Site.py
index dde920f..5888727 100644
--- a/Source/Modules/Site.py
+++ b/Source/Modules/Site.py
@@ -18,8 +18,33 @@ from Modules.Markdown import *
from Modules.Pug import *
from Modules.Utils import *
+# Generate HTML tree/nested list from our internal metaformat, such as:
+# :Item 1 \\
Item 1
+# .:Item 2 ============\\ - Item 2
+# ..:Item 3 ============// - Item 3
+# :Item 4 // Item 4
+def GenHTMLTreeList(MetaList:str, Type:str='ul'):
+ HTML = ''
+ Lines = MetaList.splitlines()
+ CurDepth, NextDepth, PrevDepth = 0, 0, 0
+ for i,e in enumerate(Lines):
+ CurDepth = e.find(':')
+ NextDepth = Lines[i+1].find(':') if i+1 < len(Lines) else 0
+ HTML += '\n' + e[CurDepth+1:]
+ if NextDepth == CurDepth:
+ HTML += ''
+ elif NextDepth > CurDepth:
+ HTML += f'\n<{Type}>' * (NextDepth - CurDepth)
+ elif NextDepth < CurDepth:
+ HTML += f'\n{Type}>' * (CurDepth - NextDepth) + ''
+ PrevDepth = CurDepth
+ return f'<{Type}>{HTML}\n{Type}>'
+
+# Menu styles:
+# - Simple: Default, Flat, Line
+# - Others: Excerpt, Image, Preview (Excerpt + Image), Full
def GetHTMLPagesList(Pages, BlogName, SiteRoot, PathPrefix, CallbackFile=None, Unite=[], Type=None, Limit=None, PathFilter='', Category=None, For='Menu', MarkdownExts=(), MenuStyle='Default', ShowPaths=True):
- Flatten, SingleLine, DoneCount = False, False, 0
+ Flatten, SingleLine, DoneCount, PrevDepth = False, False, 0, 0
if MenuStyle == 'Flat':
Flatten = True
elif MenuStyle == 'Line':
@@ -50,12 +75,13 @@ def GetHTMLPagesList(Pages, BlogName, SiteRoot, PathPrefix, CallbackFile=None, U
if (not Type or (Meta['Type'] == Type and CanIndex(Meta['Index'], For))) and (not Category or Category in Meta['Categories']) and File.startswith(TmpPathFilter) and File != CallbackFile and (not Limit or Limit > DoneCount):
Depth = (File.count('/') + 1) if Meta['Order'] != 'Unite' else 1
- if Depth > 1 and Meta['Order'] != 'Unite': # Folder names are handled here
+ # Folder names are handled here
+ if Depth > 1 and Meta['Order'] != 'Unite':
CurParent = File.split('/')[:-1]
for i,s in enumerate(CurParent):
if LastParent != CurParent and ShowPaths:
LastParent = CurParent
- Levels = '- ' * ((Depth-1+i) if not Flatten else 1)
+ Levels = '.' * ((Depth-2+i) if not Flatten else 0) + ':'
# If search node endswith index, it's a page; else, it's a folder
if StripExt(File).endswith('index'):
Title = MakeListTitle(File, Meta, Titles, 'HTMLTitle', SiteRoot, BlogName, PathPrefix)
@@ -69,10 +95,10 @@ def GetHTMLPagesList(Pages, BlogName, SiteRoot, PathPrefix, CallbackFile=None, U
# Pages with any other path
if not (Depth > 1 and StripExt(File).split('/')[-1] == 'index'):
- Levels = '- ' * (Depth if not Flatten else 1)
+ Levels = '.' * ((Depth-1) if not Flatten else 0) + ':'
DoneCount += 1
if Meta['Order'] == 'Unite':
- Title = File
+ Title = markdown(MarkdownHTMLEscape(File, MarkdownExts), extensions=MarkdownExts).removeprefix('').removesuffix('
')
else:
Title = MakeListTitle(File, Meta, Titles, 'HTMLTitle', SiteRoot, BlogName, PathPrefix)
if SingleLine:
@@ -80,7 +106,10 @@ def GetHTMLPagesList(Pages, BlogName, SiteRoot, PathPrefix, CallbackFile=None, U
else:
List += Levels + Title + '\n'
- return markdown(MarkdownHTMLEscape(List, MarkdownExts), extensions=MarkdownExts)
+ if MenuStyle in ('Default', 'Flat'):
+ return GenHTMLTreeList(List)
+ elif MenuStyle in ('Line', 'Excerpt', 'Image', 'Preview', 'Full'):
+ return List
def CheckHTMLCommentLine(Line):
if Line.startswith('