---
@@ -433,7 +448,7 @@ class Theme(Enum):
---
''',
'slide': '''
-
---
@@ -473,16 +489,17 @@ class Theme(Enum):
---
''',
'section': '''
-
+
# {title}
+{slide_number}
---
''',
'text': '''
-
+
## {title}
@@ -492,6 +509,7 @@ class Theme(Enum):
+{slide_number}
---
@@ -537,6 +555,7 @@ class Theme(Enum):
height: 600px;
display: flex;
flex-direction: column;
+ position: relative;
}}
/* Stacked content */
@@ -711,6 +730,7 @@ class Theme(Enum):
/* Text Slide */
.textSlide {{
background: white;
+ position: relative;
}}
.textTitle {{
@@ -729,6 +749,15 @@ class Theme(Enum):
text-align: justify;
}}
+ /* Slide Number */
+ .slideNumber {{
+ position: absolute;
+ bottom: 15px;
+ right: 30px;
+ font-size: 1.3rem;
+ color: #888;
+ }}
+
/* Blank Slide */
.blankSlide {{
background: white;
@@ -808,6 +837,7 @@ class Theme(Enum):
height: 600px;
display: flex;
flex-direction: column;
+ position: relative;
}}
.slideContent, .textContent, .blankContent {{
@@ -993,6 +1023,15 @@ class Theme(Enum):
text-align: justify;
}}
+ /* Slide Number */
+ .slideNumber {{
+ position: absolute;
+ bottom: 15px;
+ right: 30px;
+ font-size: 1.3rem;
+ color: #888;
+ }}
+
/* Blank Slide */
.blankSlide {{
background: #fefefe;
@@ -1071,6 +1110,7 @@ class Theme(Enum):
height: 600px;
display: flex;
flex-direction: column;
+ position: relative;
}}
.slideContent, .textContent, .blankContent {{
@@ -1236,6 +1276,15 @@ class Theme(Enum):
color: {text};
}}
+ /* Slide Number */
+ .slideNumber {{
+ position: absolute;
+ bottom: 15px;
+ right: 30px;
+ font-size: 1.3rem;
+ color: #888;
+ }}
+
/* Blank Slide */
.blankSlide {{
background: white;
@@ -1413,7 +1462,7 @@ def _get_image_data_url(self, image_path, base_dir: str = None):
print(f"Warning: Could not convert image to base64 ({image_path}): {e}")
return image_path
- def ToHtml(self, palette: Palette = Palette.BLUE, theme: Theme = Theme.MODERN, embed: bool = False):
+ def ToHtml(self, palette: Palette = Palette.BLUE, theme: Theme = Theme.MODERN, embed: bool = False, slide_number=None, slide_total=None):
template = HTML_TEMPLATES[theme]['slide']
colors = PALETTE_COLORS[palette]
base_dir = self.BaseDir
@@ -1421,16 +1470,17 @@ def ToHtml(self, palette: Palette = Palette.BLUE, theme: Theme = Theme.MODERN, e
image_src = self._get_image_data_url(self.ImagePath, base_dir=base_dir)
else:
image_src = self.ImagePath or ""
-
+ slide_number_str = f'
{slide_number} / {slide_total}
' if (slide_number and slide_total) else ""
return template.format(
title=self.Title,
image=image_src,
alt=self.Title,
description=self.Description,
+ slide_number=slide_number_str,
**colors
)
- def ToMarkdown(self, palette: Palette = Palette.BLUE, theme: Theme = Theme.MODERN, embed: bool = False):
+ def ToMarkdown(self, palette: Palette = Palette.BLUE, theme: Theme = Theme.MODERN, embed: bool = False, slide_number=None, slide_total=None):
template = MARKDOWN_TEMPLATES[theme]['slide']
colors = PALETTE_COLORS[palette]
base_dir = self.BaseDir
@@ -1438,12 +1488,13 @@ def ToMarkdown(self, palette: Palette = Palette.BLUE, theme: Theme = Theme.MODER
image_src = self._get_image_data_url(self.ImagePath, base_dir=base_dir)
else:
image_src = self.ImagePath or ""
-
+ slide_number_str = f"
{slide_number} / {slide_total}
" if (slide_number and slide_total) else ""
return template.format(
title=self.Title,
image=image_src,
alt=self.Title,
description=self.Description,
+ slide_number=slide_number_str,
**colors
)
@@ -1451,19 +1502,23 @@ class SimpleSection():
def __init__(self, Title: str):
self.Title = Title
- def ToHtml(self, palette: Palette = Palette.BLUE, theme: Theme = Theme.MODERN, embed: bool = False):
+ def ToHtml(self, palette: Palette = Palette.BLUE, theme: Theme = Theme.MODERN, embed: bool = False, slide_number=None, slide_total=None):
template = HTML_TEMPLATES[theme]['section']
colors = PALETTE_COLORS[palette]
+ slide_number_str = f'
{slide_number} / {slide_total}
' if (slide_number and slide_total) else ""
return template.format(
title=self.Title,
+ slide_number=slide_number_str,
**colors
)
- def ToMarkdown(self, palette: Palette = Palette.BLUE, theme: Theme = Theme.MODERN, embed: bool = False):
+ def ToMarkdown(self, palette: Palette = Palette.BLUE, theme: Theme = Theme.MODERN, embed: bool = False, slide_number=None, slide_total=None):
template = MARKDOWN_TEMPLATES[theme]['section']
colors = PALETTE_COLORS[palette]
+ slide_number_str = f"
{slide_number} / {slide_total}
" if (slide_number and slide_total) else ""
return template.format(
title=self.Title,
+ slide_number=slide_number_str,
**colors
)
@@ -1472,21 +1527,25 @@ def __init__(self, Title: str, Body: str):
self.Title = Title
self.Body = Body
- def ToHtml(self, palette: Palette = Palette.BLUE, theme: Theme = Theme.MODERN, embed: bool = False):
+ def ToHtml(self, palette: Palette = Palette.BLUE, theme: Theme = Theme.MODERN, embed: bool = False, slide_number=None, slide_total=None):
template = HTML_TEMPLATES[theme]['text']
colors = PALETTE_COLORS[palette]
+ slide_number_str = f'
{slide_number} / {slide_total}
' if (slide_number and slide_total) else ""
return template.format(
title=self.Title,
body=self.Body,
+ slide_number=slide_number_str,
**colors
)
- def ToMarkdown(self, palette: Palette = Palette.BLUE, theme: Theme = Theme.MODERN, embed: bool = False):
+ def ToMarkdown(self, palette: Palette = Palette.BLUE, theme: Theme = Theme.MODERN, embed: bool = False, slide_number=None, slide_total=None):
template = MARKDOWN_TEMPLATES[theme]['text']
colors = PALETTE_COLORS[palette]
+ slide_number_str = f"
{slide_number} / {slide_total}
" if (slide_number and slide_total) else ""
return template.format(
title=self.Title,
body=self.Body,
+ slide_number=slide_number_str,
**colors
)
@@ -1626,13 +1685,35 @@ def __init__(self, Slides: list[SlidePage], Title: str, html_dir: str = None):
self.Markdown = ""
def ToHtml(self, palette: Palette = Palette.BLUE, theme: Theme = Theme.MODERN, embed: bool = False):
- body = "".join([slide.Model.ToHtml(palette=palette, theme=theme, embed=embed) for slide in self.Slides])
+ numberable_indices = [i for i, slide in enumerate(self.Slides)
+ if hasattr(slide.Model, 'ToHtml') and type(slide.Model).__name__ in ['SimpleSlide', 'SimpleText', 'SimpleSection']]
+ total = len(numberable_indices)
+ body = ""
+ for idx, slide in enumerate(self.Slides):
+ model = slide.Model
+ if hasattr(model, 'ToHtml') and type(model).__name__ in ['SimpleSlide', 'SimpleText', 'SimpleSection']:
+ slide_number = numberable_indices.index(idx) + 1
+ body += model.ToHtml(palette=palette, theme=theme, embed=embed, slide_number=slide_number, slide_total=total)
+ else:
+ body += model.ToHtml(palette=palette, theme=theme, embed=embed)
colors = PALETTE_COLORS[palette]
css = CSS_TEMPLATES[theme].format(**colors)
return self.Html.format(self.Title, body, css)
def ToMarkdown(self, palette: Palette = Palette.BLUE, theme: Theme = Theme.MODERN, embed: bool = False):
- md = "".join([slide.Model.ToMarkdown(palette=palette, theme=theme, embed=embed) for slide in self.Slides])
+ # Identify which slides are numberable (not cover or backcover)
+ numberable_indices = [i for i, slide in enumerate(self.Slides)
+ if hasattr(slide.Model, 'ToMarkdown') and type(slide.Model).__name__ in ['SimpleSlide', 'SimpleText', 'SimpleSection']]
+ total = len(numberable_indices)
+ md = ""
+ for idx, slide in enumerate(self.Slides):
+ model = slide.Model
+ if hasattr(model, 'ToMarkdown') and type(model).__name__ in ['SimpleSlide', 'SimpleText', 'SimpleSection']:
+ # Slide number is 1-based index in numberable slides
+ slide_number = numberable_indices.index(idx) + 1
+ md += model.ToMarkdown(palette=palette, theme=theme, embed=embed, slide_number=slide_number, slide_total=total)
+ else:
+ md += model.ToMarkdown(palette=palette, theme=theme, embed=embed)
self.Markdown = md
return md