diff --git a/TutorialMaker/Lib/TutorialExporter.py b/TutorialMaker/Lib/TutorialExporter.py index c554af5..a9e038e 100644 --- a/TutorialMaker/Lib/TutorialExporter.py +++ b/TutorialMaker/Lib/TutorialExporter.py @@ -534,11 +534,26 @@ class Theme(Enum): overflow: hidden; page-break-after: always; page-break-inside: avoid; - min-height: 600px; + height: 600px; + display: flex; + flex-direction: column; + }} + + /* Stacked content */ + .slideContent, .textContent, .blankContent {{ + flex: 1 1 0; + min-height: 0; + display: flex; + flex-direction: column; + overflow: hidden; + padding: 40px; }} - /* Content Wrappers */ - .slideContent, .coverContent, .backCoverContent, .sectionContent, .textContent, .blankContent {{ + /* Centered content */ + .coverContent, .backCoverContent, .sectionContent {{ + flex: 0 1 auto; + min-height: 0; + overflow: hidden; padding: 40px; }} @@ -546,7 +561,6 @@ class Theme(Enum): .cover {{ background: linear-gradient(135deg, {primary} 0%, {secondary} 100%); color: white; - display: flex; align-items: center; justify-content: center; }} @@ -589,45 +603,54 @@ class Theme(Enum): /* Regular Slides */ .slideTitle {{ + flex-shrink: 0; font-size: 2.2rem; font-weight: 600; color: {primary}; - margin-bottom: 30px; + margin-bottom: 20px; padding-bottom: 15px; border-bottom: 3px solid {primary}; }} .containerImage {{ - text-align: center; - margin: 30px 0; + flex: 1 1 0; + min-height: 0; + display: flex; + align-items: center; + justify-content: center; + overflow: hidden; background: #fafafa; - padding: 20px; + padding: 10px; border-radius: 4px; }} .slideImage {{ - max-width: 90%; + max-width: 100%; + max-height: 100%; + width: auto; height: auto; + object-fit: contain; border-radius: 4px; box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); }} .slideDescription {{ - font-size: 1.2rem; - line-height: 1.8; + flex-shrink: 1; + min-height: 0; + overflow: hidden; + font-size: 1.1rem; + line-height: 1.6; color: #444; text-align: justify; - margin-top: 25px; + margin-top: 10px; }} /* Back Cover */ .backCover {{ background: linear-gradient(135deg, {secondary} 0%, {primary} 100%); color: white; - min-height: 600px; - display: flex; - flex-direction: column; align-items: center; + justify-content: center; }} .backCoverContent {{ @@ -677,8 +700,6 @@ class Theme(Enum): .sectionSlide {{ background: linear-gradient(135deg, {primary} 0%, {secondary} 100%); color: white; - min-height: 600px; - display: flex; align-items: center; justify-content: center; }} @@ -697,17 +718,21 @@ class Theme(Enum): }} .textTitle {{ + flex-shrink: 0; font-size: 2.2rem; font-weight: 600; color: {primary}; - margin-bottom: 30px; + margin-bottom: 20px; padding-bottom: 15px; border-bottom: 3px solid {primary}; }} .textBody {{ - font-size: 1.2rem; - line-height: 1.8; + flex-shrink: 1; + min-height: 0; + overflow: hidden; + font-size: 1.1rem; + line-height: 1.6; color: #444; text-align: justify; }} @@ -717,40 +742,48 @@ class Theme(Enum): background: white; }} - .blankTitle {{ - font-size: 2.2rem; - font-weight: 600; - color: {primary}; - margin-bottom: 30px; - padding-bottom: 15px; - border-bottom: 3px solid {primary}; - }} - .blankBody {{ - font-size: 1.2rem; - line-height: 1.8; + flex-shrink: 1; + min-height: 0; + overflow: hidden; + font-size: 1.1rem; + line-height: 1.6; color: #444; - text-align: justify; + }} + + .slideContent p, .textContent p, .blankContent p {{ + margin: 0 0 0.4em; }} /* Print Styles */ @media print {{ + * {{ + print-color-adjust: exact; + -webkit-print-color-adjust: exact; + }} + body {{ background: white; padding: 0; }} .slide, .cover, .backCover, .sectionSlide, .textSlide, .blankSlide {{ + max-width: none; + width: 297mm; + height: 148.5mm; margin: 0; box-shadow: none; border-radius: 0; - min-height: 100vh; - height: auto; + overflow: hidden; + }} + + .slideContent, .textContent, .blankContent {{ + overflow: hidden; }} }} @page {{ - size: A4 landscape; + size: 297mm 148.5mm; margin: 0; }} """, @@ -777,16 +810,29 @@ class Theme(Enum): overflow: hidden; page-break-after: always; page-break-inside: avoid; - min-height: 600px; + height: 600px; + display: flex; + flex-direction: column; + }} + + .slideContent, .textContent, .blankContent {{ + flex: 1 1 0; + min-height: 0; + display: flex; + flex-direction: column; + overflow: hidden; + padding: 50px; }} - .slideContent, .coverContent, .backCoverContent, .sectionContent, .textContent, .blankContent {{ + .coverContent, .backCoverContent, .sectionContent {{ + flex: 0 1 auto; + min-height: 0; + overflow: hidden; padding: 50px; }} .cover {{ background: white; - display: flex; align-items: center; justify-content: center; }} @@ -828,10 +874,11 @@ class Theme(Enum): }} .slideTitle {{ + flex-shrink: 0; font-size: 2.5rem; font-weight: 600; color: {primary}; - margin-bottom: 30px; + margin-bottom: 20px; padding-bottom: 15px; border-bottom: 2px solid {primary}; text-align: center; @@ -839,31 +886,40 @@ class Theme(Enum): }} .containerImage {{ - text-align: center; - margin: 30px 0; - padding: 20px; + flex: 1 1 0; + min-height: 0; + display: flex; + align-items: center; + justify-content: center; + overflow: hidden; + padding: 10px; border: 1px solid #ddd; }} .slideImage {{ - max-width: 85%; + max-width: 100%; + max-height: 100%; + width: auto; height: auto; + object-fit: contain; border: 1px solid {primary}; }} .slideDescription {{ - font-size: 1.15rem; - line-height: 1.9; + flex-shrink: 1; + min-height: 0; + overflow: hidden; + font-size: 1.1rem; + line-height: 1.6; color: {text}; text-align: justify; - margin-top: 25px; + margin-top: 10px; }} .backCover {{ background: white; - display: flex; - flex-direction: column; align-items: center; + justify-content: center; }} .backCover .coverTitle {{ @@ -905,8 +961,6 @@ class Theme(Enum): /* Section Slide */ .sectionSlide {{ background: #fefefe; - min-height: 600px; - display: flex; align-items: center; justify-content: center; }} @@ -931,10 +985,11 @@ class Theme(Enum): }} .textTitle {{ + flex-shrink: 0; font-size: 2.5rem; font-weight: 600; color: {primary}; - margin-bottom: 30px; + margin-bottom: 20px; padding-bottom: 15px; border-bottom: 2px solid {primary}; text-align: center; @@ -942,8 +997,11 @@ class Theme(Enum): }} .textBody {{ - font-size: 1.15rem; - line-height: 1.9; + flex-shrink: 1; + min-height: 0; + overflow: hidden; + font-size: 1.1rem; + line-height: 1.6; color: {text}; text-align: justify; }} @@ -953,40 +1011,46 @@ class Theme(Enum): background: #fefefe; }} - .blankTitle {{ - font-size: 2.5rem; - font-weight: 600; - color: {primary}; - margin-bottom: 30px; - padding-bottom: 15px; - border-bottom: 2px solid {primary}; - text-align: center; - font-family: Georgia, serif; - }} - .blankBody {{ - font-size: 1.15rem; - line-height: 1.9; + flex-shrink: 1; + min-height: 0; + overflow: hidden; + font-size: 1.1rem; + line-height: 1.6; color: {text}; - text-align: justify; + }} + + .slideContent p, .textContent p, .blankContent p {{ + margin: 0 0 0.4em; }} @media print {{ + * {{ + print-color-adjust: exact; + -webkit-print-color-adjust: exact; + }} + body {{ background: white; padding: 0; }} .slide, .cover, .backCover, .sectionSlide, .textSlide, .blankSlide {{ + max-width: none; + width: 297mm; + height: 148.5mm; margin: 0; border: none; - min-height: 100vh; - height: auto; + overflow: hidden; + }} + + .slideContent, .textContent, .blankContent {{ + overflow: hidden; }} }} @page {{ - size: A4 landscape; + size: 297mm 148.5mm; margin: 0; }} """, @@ -1012,15 +1076,28 @@ class Theme(Enum): overflow: hidden; page-break-after: always; page-break-inside: avoid; - min-height: 600px; + height: 600px; + display: flex; + flex-direction: column; }} - .slideContent, .coverContent, .backCoverContent, .sectionContent, .textContent, .blankContent {{ + .slideContent, .textContent, .blankContent {{ + flex: 1 1 0; + min-height: 0; + display: flex; + flex-direction: column; + overflow: hidden; + padding: 60px; + }} + + .coverContent, .backCoverContent, .sectionContent {{ + flex: 0 1 auto; + min-height: 0; + overflow: hidden; padding: 60px; }} .cover {{ - display: flex; align-items: center; justify-content: center; border-left: 8px solid {primary}; @@ -1056,35 +1133,46 @@ class Theme(Enum): }} .slideTitle {{ + flex-shrink: 0; font-size: 2rem; font-weight: 400; color: {primary}; - margin-bottom: 30px; + margin-bottom: 20px; padding-bottom: 10px; border-bottom: 1px solid {primary}; }} .containerImage {{ - text-align: center; - margin: 30px 0; + flex: 1 1 0; + min-height: 0; + display: flex; + align-items: center; + justify-content: center; + overflow: hidden; + padding: 10px; }} .slideImage {{ max-width: 100%; + max-height: 100%; + width: auto; height: auto; + object-fit: contain; }} .slideDescription {{ + flex-shrink: 1; + min-height: 0; + overflow: hidden; font-size: 1.1rem; - line-height: 1.8; + line-height: 1.6; color: {text}; - margin-top: 25px; + margin-top: 10px; }} .backCover {{ - display: flex; - flex-direction: column; align-items: center; + justify-content: center; border-left: 8px solid {primary}; }} @@ -1127,8 +1215,6 @@ class Theme(Enum): .sectionSlide {{ background: white; border-left: 8px solid {primary}; - display: flex; - min-height: 600px; align-items: center; justify-content: center; }} @@ -1148,17 +1234,21 @@ class Theme(Enum): }} .textTitle {{ + flex-shrink: 0; font-size: 2rem; font-weight: 400; color: {primary}; - margin-bottom: 30px; + margin-bottom: 20px; padding-bottom: 10px; border-bottom: 1px solid {primary}; }} .textBody {{ + flex-shrink: 1; + min-height: 0; + overflow: hidden; font-size: 1.1rem; - line-height: 1.8; + line-height: 1.6; color: {text}; }} @@ -1167,36 +1257,45 @@ class Theme(Enum): background: white; }} - .blankTitle {{ - font-size: 2rem; - font-weight: 400; - color: {primary}; - margin-bottom: 30px; - padding-bottom: 10px; - border-bottom: 1px solid {primary}; - }} - .blankBody {{ + flex-shrink: 1; + min-height: 0; + overflow: hidden; font-size: 1.1rem; - line-height: 1.8; + line-height: 1.6; color: {text}; }} + .slideContent p, .textContent p, .blankContent p {{ + margin: 0 0 0.4em; + }} + @media print {{ + * {{ + print-color-adjust: exact; + -webkit-print-color-adjust: exact; + }} + body {{ background: white; padding: 0; }} .slide, .cover, .backCover, .sectionSlide, .textSlide, .blankSlide {{ + max-width: none; + width: 297mm; + height: 148.5mm; margin: 0; - min-height: 100vh; - height: auto; + overflow: hidden; + }} + + .slideContent, .textContent, .blankContent {{ + overflow: hidden; }} }} @page {{ - size: A4 landscape; + size: 297mm 148.5mm; margin: 0; }} """ @@ -1212,7 +1311,7 @@ def __init__(self, title: str, author: str, date: str, description: str): self.Description = description pass - def ToHtml(self, palette: Palette = Palette.BLUE, theme: Theme = Theme.MODERN): + def ToHtml(self, palette: Palette = Palette.BLUE, theme: Theme = Theme.MODERN, embed: bool = False): template = HTML_TEMPLATES[theme]['cover'] colors = PALETTE_COLORS[palette] return template.format( @@ -1223,7 +1322,7 @@ def ToHtml(self, palette: Palette = Palette.BLUE, theme: Theme = Theme.MODERN): **colors ) - def ToMarkdown(self, palette: Palette = Palette.BLUE, theme: Theme = Theme.MODERN): + def ToMarkdown(self, palette: Palette = Palette.BLUE, theme: Theme = Theme.MODERN, embed: bool = False): template = MARKDOWN_TEMPLATES[theme]['cover'] colors = PALETTE_COLORS[palette] return template.format( @@ -1239,7 +1338,7 @@ def __init__(self, title: str, Acknowledgments: str): self.Title = title self.Acknowledgments = Acknowledgments - def ToHtml(self, palette: Palette = Palette.BLUE, theme: Theme = Theme.MODERN): + def ToHtml(self, palette: Palette = Palette.BLUE, theme: Theme = Theme.MODERN, embed: bool = False): if isinstance(self.Acknowledgments, dict): items = "".join( f"
{v}