deepagents-printshop 0.1.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- agents/content_editor/__init__.py +1 -0
- agents/content_editor/agent.py +279 -0
- agents/content_editor/content_reviewer.py +327 -0
- agents/content_editor/versioned_agent.py +455 -0
- agents/latex_specialist/__init__.py +1 -0
- agents/latex_specialist/agent.py +531 -0
- agents/latex_specialist/latex_analyzer.py +510 -0
- agents/latex_specialist/latex_optimizer.py +1192 -0
- agents/qa_orchestrator/__init__.py +1 -0
- agents/qa_orchestrator/agent.py +603 -0
- agents/qa_orchestrator/langgraph_workflow.py +733 -0
- agents/qa_orchestrator/pipeline_types.py +72 -0
- agents/qa_orchestrator/quality_gates.py +495 -0
- agents/qa_orchestrator/workflow_coordinator.py +139 -0
- agents/research_agent/__init__.py +1 -0
- agents/research_agent/agent.py +258 -0
- agents/research_agent/llm_report_generator.py +1023 -0
- agents/research_agent/report_generator.py +536 -0
- agents/visual_qa/__init__.py +1 -0
- agents/visual_qa/agent.py +410 -0
- deepagents_printshop-0.1.0.dist-info/METADATA +744 -0
- deepagents_printshop-0.1.0.dist-info/RECORD +37 -0
- deepagents_printshop-0.1.0.dist-info/WHEEL +4 -0
- deepagents_printshop-0.1.0.dist-info/entry_points.txt +2 -0
- deepagents_printshop-0.1.0.dist-info/licenses/LICENSE +86 -0
- tools/__init__.py +1 -0
- tools/change_tracker.py +419 -0
- tools/content_type_loader.py +171 -0
- tools/graph_generator.py +281 -0
- tools/latex_generator.py +374 -0
- tools/llm_latex_generator.py +678 -0
- tools/magazine_layout.py +462 -0
- tools/pattern_injector.py +250 -0
- tools/pattern_learner.py +477 -0
- tools/pdf_compiler.py +386 -0
- tools/version_manager.py +346 -0
- tools/visual_qa.py +799 -0
tools/magazine_layout.py
ADDED
|
@@ -0,0 +1,462 @@
|
|
|
1
|
+
"""Magazine Layout Tools - Professional magazine LaTeX macros and templates.
|
|
2
|
+
|
|
3
|
+
DEPRECATED: All LaTeX macro definitions have been moved into
|
|
4
|
+
content_types/magazine/type.md as ```latex code blocks. The pipeline now reads
|
|
5
|
+
macros directly from type.md via ContentTypeDefinition.latex_preamble_blocks.
|
|
6
|
+
This file is kept for reference only and is no longer imported by active code.
|
|
7
|
+
|
|
8
|
+
Provides LaTeX macro definitions for creating professional magazine layouts including:
|
|
9
|
+
- Cover page mastheads with positioned callouts
|
|
10
|
+
- Creative contents pages with large numbers
|
|
11
|
+
- Dark/light page contrast
|
|
12
|
+
- Circle infographics and data visualizations
|
|
13
|
+
- Pull quotes and vertical text elements
|
|
14
|
+
"""
|
|
15
|
+
|
|
16
|
+
from typing import Dict, List, Optional
|
|
17
|
+
from dataclasses import dataclass, field
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
@dataclass
|
|
21
|
+
class MagazineTheme:
|
|
22
|
+
"""Color theme for magazine styling."""
|
|
23
|
+
primary: str = "2E86AB" # Deep blue
|
|
24
|
+
secondary: str = "A23B72" # Magenta
|
|
25
|
+
accent: str = "F18F01" # Orange
|
|
26
|
+
dark: str = "1A1A2E" # Near black
|
|
27
|
+
light: str = "F5F5F5" # Off white
|
|
28
|
+
text_dark: str = "1A1A2E"
|
|
29
|
+
text_light: str = "FFFFFF"
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
class MagazineLayoutGenerator:
|
|
33
|
+
"""Generate LaTeX macros and preamble for professional magazine layouts."""
|
|
34
|
+
|
|
35
|
+
def __init__(self, theme: Optional[MagazineTheme] = None):
|
|
36
|
+
self.theme = theme or MagazineTheme()
|
|
37
|
+
|
|
38
|
+
def get_preamble_packages(self) -> str:
|
|
39
|
+
"""Get required LaTeX packages for magazine layout."""
|
|
40
|
+
return r"""% Magazine Layout Packages
|
|
41
|
+
\usepackage{tikz}
|
|
42
|
+
\usepackage{eso-pic}
|
|
43
|
+
\usepackage{contour}
|
|
44
|
+
\usepackage{lettrine}
|
|
45
|
+
\usepackage{multicol}
|
|
46
|
+
\usepackage{enumitem}
|
|
47
|
+
\usepackage{xcolor}
|
|
48
|
+
\usepackage{graphicx}
|
|
49
|
+
\usepackage{geometry}
|
|
50
|
+
\usepackage{fancyhdr}
|
|
51
|
+
\usepackage{tcolorbox}
|
|
52
|
+
\usepackage{rotating}
|
|
53
|
+
\usepackage{wrapfig}
|
|
54
|
+
\usepackage{float}
|
|
55
|
+
\usepackage{calc}
|
|
56
|
+
|
|
57
|
+
% TikZ libraries
|
|
58
|
+
\usetikzlibrary{positioning, calc, shapes, backgrounds, fit}
|
|
59
|
+
"""
|
|
60
|
+
|
|
61
|
+
def get_color_definitions(self) -> str:
|
|
62
|
+
"""Get color definitions for the theme."""
|
|
63
|
+
return f"""% Magazine Color Theme
|
|
64
|
+
\\definecolor{{magprimary}}{{HTML}}{{{self.theme.primary}}}
|
|
65
|
+
\\definecolor{{magsecondary}}{{HTML}}{{{self.theme.secondary}}}
|
|
66
|
+
\\definecolor{{magaccent}}{{HTML}}{{{self.theme.accent}}}
|
|
67
|
+
\\definecolor{{magdark}}{{HTML}}{{{self.theme.dark}}}
|
|
68
|
+
\\definecolor{{maglight}}{{HTML}}{{{self.theme.light}}}
|
|
69
|
+
"""
|
|
70
|
+
|
|
71
|
+
def get_masthead_macro(self) -> str:
|
|
72
|
+
"""LaTeX macro for magazine masthead."""
|
|
73
|
+
return r"""% Magazine Masthead - Large title at top of cover
|
|
74
|
+
% Usage: \masthead{MAIN TITLE}{subtitle}
|
|
75
|
+
\newcommand{\masthead}[2]{%
|
|
76
|
+
\begin{tikzpicture}[remember picture, overlay]
|
|
77
|
+
% Main title - large and bold
|
|
78
|
+
\node[anchor=north, font=\fontsize{64}{64}\selectfont\bfseries\sffamily, text=white]
|
|
79
|
+
at ([yshift=-2cm]current page.north) {#1};
|
|
80
|
+
% Subtitle - smaller, lighter weight
|
|
81
|
+
\node[anchor=north, font=\fontsize{18}{20}\selectfont\sffamily, text=white]
|
|
82
|
+
at ([yshift=-3.5cm]current page.north) {#2};
|
|
83
|
+
\end{tikzpicture}%
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
% Masthead with shadow for better readability
|
|
87
|
+
% Usage: \mastheadshadow{MAIN TITLE}{subtitle}
|
|
88
|
+
\newcommand{\mastheadshadow}[2]{%
|
|
89
|
+
\begin{tikzpicture}[remember picture, overlay]
|
|
90
|
+
% Shadow layer
|
|
91
|
+
\node[anchor=north, font=\fontsize{64}{64}\selectfont\bfseries\sffamily, text=black, opacity=0.5]
|
|
92
|
+
at ([yshift=-1.95cm, xshift=0.1cm]current page.north) {#1};
|
|
93
|
+
% Main title
|
|
94
|
+
\node[anchor=north, font=\fontsize{64}{64}\selectfont\bfseries\sffamily, text=white]
|
|
95
|
+
at ([yshift=-2cm]current page.north) {#1};
|
|
96
|
+
% Subtitle
|
|
97
|
+
\node[anchor=north, font=\fontsize{18}{20}\selectfont\sffamily, text=white]
|
|
98
|
+
at ([yshift=-3.5cm]current page.north) {#2};
|
|
99
|
+
\end{tikzpicture}%
|
|
100
|
+
}
|
|
101
|
+
"""
|
|
102
|
+
|
|
103
|
+
def get_cover_callout_macros(self) -> str:
|
|
104
|
+
"""LaTeX macros for cover page callouts."""
|
|
105
|
+
return r"""% Left side callout (positioned on left of cover)
|
|
106
|
+
% Usage: \leftcallout{y-offset}{HEADLINE}{subtext}
|
|
107
|
+
\newcommand{\leftcallout}[3]{%
|
|
108
|
+
\begin{tikzpicture}[remember picture, overlay]
|
|
109
|
+
\node[anchor=west, align=left, text width=5cm,
|
|
110
|
+
font=\sffamily, text=white]
|
|
111
|
+
at ([xshift=1.5cm, yshift=#1]current page.west) {%
|
|
112
|
+
{\fontsize{11}{13}\selectfont\bfseries #2}\\[3pt]
|
|
113
|
+
{\fontsize{9}{11}\selectfont #3}%
|
|
114
|
+
};
|
|
115
|
+
\end{tikzpicture}%
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
% Right side callout (positioned on right of cover)
|
|
119
|
+
% Usage: \rightcallout{y-offset}{HEADLINE}{subtext}
|
|
120
|
+
\newcommand{\rightcallout}[3]{%
|
|
121
|
+
\begin{tikzpicture}[remember picture, overlay]
|
|
122
|
+
\node[anchor=east, align=right, text width=5cm,
|
|
123
|
+
font=\sffamily, text=white]
|
|
124
|
+
at ([xshift=-1.5cm, yshift=#1]current page.east) {%
|
|
125
|
+
{\fontsize{11}{13}\selectfont\bfseries #2}\\[3pt]
|
|
126
|
+
{\fontsize{9}{11}\selectfont #3}%
|
|
127
|
+
};
|
|
128
|
+
\end{tikzpicture}%
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
% Feature headline at bottom of cover
|
|
132
|
+
% Usage: \coverfeature{MAIN HEADLINE}{subheadline}
|
|
133
|
+
\newcommand{\coverfeature}[2]{%
|
|
134
|
+
\begin{tikzpicture}[remember picture, overlay]
|
|
135
|
+
% Dark gradient overlay at bottom
|
|
136
|
+
\fill[black, opacity=0.6]
|
|
137
|
+
(current page.south west) rectangle ([yshift=5cm]current page.south east);
|
|
138
|
+
% Main headline
|
|
139
|
+
\node[anchor=south, font=\fontsize{42}{44}\selectfont\bfseries\sffamily, text=white]
|
|
140
|
+
at ([yshift=2.5cm]current page.south) {#1};
|
|
141
|
+
% Subheadline
|
|
142
|
+
\node[anchor=south, font=\fontsize{14}{16}\selectfont\itshape, text=white]
|
|
143
|
+
at ([yshift=1.5cm]current page.south) {#2};
|
|
144
|
+
\end{tikzpicture}%
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
% Vertical text element (like "ISSUE 01")
|
|
148
|
+
% Usage: \verticaltext{x-offset}{TEXT}
|
|
149
|
+
\newcommand{\verticaltext}[2]{%
|
|
150
|
+
\begin{tikzpicture}[remember picture, overlay]
|
|
151
|
+
\node[anchor=center, rotate=90, font=\fontsize{10}{10}\selectfont\sffamily\bfseries,
|
|
152
|
+
text=white, opacity=0.9]
|
|
153
|
+
at ([xshift=#1, yshift=0cm]current page.west) {#2};
|
|
154
|
+
\end{tikzpicture}%
|
|
155
|
+
}
|
|
156
|
+
"""
|
|
157
|
+
|
|
158
|
+
def get_contents_page_macros(self) -> str:
|
|
159
|
+
"""LaTeX macros for creative contents page."""
|
|
160
|
+
return r"""% Creative Contents Page with Large Numbers
|
|
161
|
+
% Usage: \contentsentry{PAGE}{TITLE}{description}
|
|
162
|
+
\newcommand{\contentsentry}[3]{%
|
|
163
|
+
\noindent
|
|
164
|
+
\begin{minipage}[t]{0.15\textwidth}
|
|
165
|
+
\raggedleft
|
|
166
|
+
{\fontsize{36}{38}\selectfont\color{magprimary}\bfseries #1}%
|
|
167
|
+
\end{minipage}%
|
|
168
|
+
\hspace{0.5cm}%
|
|
169
|
+
\begin{minipage}[t]{0.75\textwidth}
|
|
170
|
+
{\fontsize{12}{14}\selectfont\bfseries #2}\\[2pt]
|
|
171
|
+
{\fontsize{9}{11}\selectfont\color{gray} #3}%
|
|
172
|
+
\end{minipage}%
|
|
173
|
+
\vspace{0.8cm}
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
% Contents page header with vertical text
|
|
177
|
+
% Usage: \contentsheader
|
|
178
|
+
\newcommand{\contentsheader}{%
|
|
179
|
+
\begin{tikzpicture}[remember picture, overlay]
|
|
180
|
+
\node[anchor=west, rotate=90, font=\fontsize{14}{14}\selectfont\sffamily,
|
|
181
|
+
text=magdark, letter spacing=0.3em]
|
|
182
|
+
at ([xshift=0.8cm, yshift=-5cm]current page.north west) {CONTENTS};
|
|
183
|
+
\end{tikzpicture}%
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
% Contents with stacked large numbers (like the coffee magazine sample)
|
|
187
|
+
% Usage in environment
|
|
188
|
+
\newenvironment{creativecontents}{%
|
|
189
|
+
\thispagestyle{empty}
|
|
190
|
+
\contentsheader
|
|
191
|
+
\vspace*{1cm}
|
|
192
|
+
\begin{minipage}[t]{0.45\textwidth}
|
|
193
|
+
\vspace{0pt}
|
|
194
|
+
% Space for hero image
|
|
195
|
+
\end{minipage}%
|
|
196
|
+
\hfill
|
|
197
|
+
\begin{minipage}[t]{0.5\textwidth}
|
|
198
|
+
\vspace{0pt}
|
|
199
|
+
}{%
|
|
200
|
+
\end{minipage}
|
|
201
|
+
\newpage
|
|
202
|
+
}
|
|
203
|
+
"""
|
|
204
|
+
|
|
205
|
+
def get_dark_light_page_macros(self) -> str:
|
|
206
|
+
"""LaTeX macros for dark/light page contrast."""
|
|
207
|
+
return r"""% Dark page environment (full page dark background)
|
|
208
|
+
% Usage: \begin{darkpage} content \end{darkpage}
|
|
209
|
+
\newenvironment{darkpage}{%
|
|
210
|
+
\newpage
|
|
211
|
+
\pagecolor{magdark}%
|
|
212
|
+
\color{white}%
|
|
213
|
+
\thispagestyle{empty}%
|
|
214
|
+
}{%
|
|
215
|
+
\newpage
|
|
216
|
+
\nopagecolor
|
|
217
|
+
\color{black}%
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
% Accent page environment (colored background)
|
|
221
|
+
% Usage: \begin{accentpage} content \end{accentpage}
|
|
222
|
+
\newenvironment{accentpage}{%
|
|
223
|
+
\newpage
|
|
224
|
+
\pagecolor{magprimary}%
|
|
225
|
+
\color{white}%
|
|
226
|
+
\thispagestyle{empty}%
|
|
227
|
+
}{%
|
|
228
|
+
\newpage
|
|
229
|
+
\nopagecolor
|
|
230
|
+
\color{black}%
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
% Dark section box (inline dark background)
|
|
234
|
+
% Usage: \begin{darksection} content \end{darksection}
|
|
235
|
+
\newtcolorbox{darksection}{%
|
|
236
|
+
colback=magdark,
|
|
237
|
+
colframe=magdark,
|
|
238
|
+
coltext=white,
|
|
239
|
+
boxrule=0pt,
|
|
240
|
+
arc=0pt,
|
|
241
|
+
left=15pt,
|
|
242
|
+
right=15pt,
|
|
243
|
+
top=15pt,
|
|
244
|
+
bottom=15pt,
|
|
245
|
+
width=\textwidth
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
% Light section box
|
|
249
|
+
\newtcolorbox{lightsection}{%
|
|
250
|
+
colback=maglight,
|
|
251
|
+
colframe=maglight,
|
|
252
|
+
coltext=magdark,
|
|
253
|
+
boxrule=0pt,
|
|
254
|
+
arc=0pt,
|
|
255
|
+
left=15pt,
|
|
256
|
+
right=15pt,
|
|
257
|
+
top=15pt,
|
|
258
|
+
bottom=15pt,
|
|
259
|
+
width=\textwidth
|
|
260
|
+
}
|
|
261
|
+
"""
|
|
262
|
+
|
|
263
|
+
def get_infographic_macros(self) -> str:
|
|
264
|
+
"""LaTeX macros for data visualizations and infographics."""
|
|
265
|
+
return r"""% Circle statistic display
|
|
266
|
+
% Usage: \circlestat{percentage}{label}
|
|
267
|
+
\newcommand{\circlestat}[2]{%
|
|
268
|
+
\begin{tikzpicture}
|
|
269
|
+
% Outer circle
|
|
270
|
+
\draw[magprimary, line width=3pt] (0,0) circle (1.2cm);
|
|
271
|
+
% Percentage text
|
|
272
|
+
\node[font=\fontsize{20}{20}\selectfont\bfseries] at (0,0) {#1\%};
|
|
273
|
+
% Label below
|
|
274
|
+
\node[font=\fontsize{8}{10}\selectfont, text width=2.5cm, align=center]
|
|
275
|
+
at (0,-1.8) {#2};
|
|
276
|
+
\end{tikzpicture}%
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
% Colored circle stat
|
|
280
|
+
% Usage: \circlestatcolor{percentage}{label}{color}
|
|
281
|
+
\newcommand{\circlestatcolor}[3]{%
|
|
282
|
+
\begin{tikzpicture}
|
|
283
|
+
% Filled circle with transparency
|
|
284
|
+
\fill[#3, opacity=0.15] (0,0) circle (1.2cm);
|
|
285
|
+
% Outer ring
|
|
286
|
+
\draw[#3, line width=3pt] (0,0) circle (1.2cm);
|
|
287
|
+
% Percentage
|
|
288
|
+
\node[font=\fontsize{20}{20}\selectfont\bfseries, text=#3] at (0,0) {#1\%};
|
|
289
|
+
% Label
|
|
290
|
+
\node[font=\fontsize{8}{10}\selectfont, text width=2.5cm, align=center]
|
|
291
|
+
at (0,-1.8) {#2};
|
|
292
|
+
\end{tikzpicture}%
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
% Large number callout (for statistics)
|
|
296
|
+
% Usage: \bigstat{NUMBER}{label}
|
|
297
|
+
\newcommand{\bigstat}[2]{%
|
|
298
|
+
\begin{minipage}{3cm}
|
|
299
|
+
\centering
|
|
300
|
+
{\fontsize{36}{38}\selectfont\bfseries\color{magprimary} #1}\\[5pt]
|
|
301
|
+
{\fontsize{9}{11}\selectfont #2}
|
|
302
|
+
\end{minipage}%
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
% Row of circle stats
|
|
306
|
+
% Usage: \statrrow{\circlestat{25}{Label 1}}{\circlestat{50}{Label 2}}{\circlestat{75}{Label 3}}
|
|
307
|
+
\newcommand{\statrow}[3]{%
|
|
308
|
+
\begin{center}
|
|
309
|
+
#1\hspace{1.5cm}#2\hspace{1.5cm}#3
|
|
310
|
+
\end{center}
|
|
311
|
+
}
|
|
312
|
+
"""
|
|
313
|
+
|
|
314
|
+
def get_pullquote_macro(self) -> str:
|
|
315
|
+
"""LaTeX macro for pull quotes."""
|
|
316
|
+
return r"""% Pull quote styling
|
|
317
|
+
% Usage: \pullquote{Quote text here}
|
|
318
|
+
\newcommand{\pullquote}[1]{%
|
|
319
|
+
\begin{center}
|
|
320
|
+
\begin{minipage}{0.85\textwidth}
|
|
321
|
+
\vspace{1em}
|
|
322
|
+
{\color{magprimary}\rule{\textwidth}{2pt}}\\[0.8em]
|
|
323
|
+
{\fontsize{16}{20}\selectfont\itshape ``#1''}\\[0.5em]
|
|
324
|
+
{\color{magprimary}\rule{\textwidth}{2pt}}
|
|
325
|
+
\vspace{1em}
|
|
326
|
+
\end{minipage}
|
|
327
|
+
\end{center}
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
% Pull quote with attribution
|
|
331
|
+
% Usage: \pullquoteattr{Quote text}{Author Name}
|
|
332
|
+
\newcommand{\pullquoteattr}[2]{%
|
|
333
|
+
\begin{center}
|
|
334
|
+
\begin{minipage}{0.85\textwidth}
|
|
335
|
+
\vspace{1em}
|
|
336
|
+
{\color{magprimary}\rule{\textwidth}{2pt}}\\[0.8em]
|
|
337
|
+
{\fontsize{16}{20}\selectfont\itshape ``#1''}\\[0.5em]
|
|
338
|
+
{\fontsize{10}{12}\selectfont\bfseries --- #2}\\[0.3em]
|
|
339
|
+
{\color{magprimary}\rule{\textwidth}{2pt}}
|
|
340
|
+
\vspace{1em}
|
|
341
|
+
\end{minipage}
|
|
342
|
+
\end{center}
|
|
343
|
+
}
|
|
344
|
+
"""
|
|
345
|
+
|
|
346
|
+
def get_article_header_macro(self) -> str:
|
|
347
|
+
"""LaTeX macro for article headers."""
|
|
348
|
+
return r"""% Article header with section tag
|
|
349
|
+
% Usage: \articleheader{SECTION TAG}{Article Title}{Subtitle or byline}
|
|
350
|
+
\newcommand{\articleheader}[3]{%
|
|
351
|
+
\vspace*{0.5cm}
|
|
352
|
+
{\fontsize{9}{10}\selectfont\sffamily\bfseries\color{magprimary} #1}\\[0.3cm]
|
|
353
|
+
{\fontsize{28}{32}\selectfont\bfseries #2}\\[0.3cm]
|
|
354
|
+
{\fontsize{11}{13}\selectfont\color{gray} #3}\\[0.8cm]
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
% Simple large article title
|
|
358
|
+
% Usage: \articletitle{Title Here}
|
|
359
|
+
\newcommand{\articletitle}[1]{%
|
|
360
|
+
\vspace*{0.5cm}
|
|
361
|
+
{\fontsize{32}{36}\selectfont\bfseries #1}\\[0.8cm]
|
|
362
|
+
}
|
|
363
|
+
"""
|
|
364
|
+
|
|
365
|
+
def get_full_preamble(self) -> str:
|
|
366
|
+
"""Get complete magazine preamble with all macros."""
|
|
367
|
+
sections = [
|
|
368
|
+
self.get_preamble_packages(),
|
|
369
|
+
self.get_color_definitions(),
|
|
370
|
+
self.get_masthead_macro(),
|
|
371
|
+
self.get_cover_callout_macros(),
|
|
372
|
+
self.get_contents_page_macros(),
|
|
373
|
+
self.get_dark_light_page_macros(),
|
|
374
|
+
self.get_infographic_macros(),
|
|
375
|
+
self.get_pullquote_macro(),
|
|
376
|
+
self.get_article_header_macro(),
|
|
377
|
+
]
|
|
378
|
+
return "\n".join(sections)
|
|
379
|
+
|
|
380
|
+
def get_magazine_requirements(self) -> List[str]:
|
|
381
|
+
"""Get list of magazine requirements for LLM prompt."""
|
|
382
|
+
return [
|
|
383
|
+
"""MAGAZINE PREAMBLE REQUIREMENTS:
|
|
384
|
+
Include all the magazine layout macros defined in the preamble. The document should use:
|
|
385
|
+
- \\masthead{TITLE}{subtitle} or \\mastheadshadow{TITLE}{subtitle} for cover title
|
|
386
|
+
- \\leftcallout{y-offset}{HEADLINE}{subtext} for left cover callouts
|
|
387
|
+
- \\rightcallout{y-offset}{HEADLINE}{subtext} for right cover callouts
|
|
388
|
+
- \\coverfeature{MAIN HEADLINE}{subheadline} for bottom feature headline
|
|
389
|
+
- \\verticaltext{x-offset}{TEXT} for vertical text elements like "ISSUE 01"
|
|
390
|
+
""",
|
|
391
|
+
"""COVER PAGE LAYOUT:
|
|
392
|
+
Create a visually striking cover with:
|
|
393
|
+
1. Full-bleed background image using eso-pic
|
|
394
|
+
2. Large masthead at top using \\mastheadshadow (64pt+ font)
|
|
395
|
+
3. 2-3 callouts on left and/or right sides
|
|
396
|
+
4. Feature headline at bottom using \\coverfeature
|
|
397
|
+
5. Vertical "ISSUE XX" text on left edge using \\verticaltext
|
|
398
|
+
6. All text should have good contrast against background
|
|
399
|
+
""",
|
|
400
|
+
"""CONTENTS PAGE DESIGN:
|
|
401
|
+
Use the creative contents style with large page numbers:
|
|
402
|
+
- Use \\contentsheader to add vertical "CONTENTS" text
|
|
403
|
+
- Use \\contentsentry{PAGE}{TITLE}{description} for each entry
|
|
404
|
+
- Page numbers should be large (36pt) and colored
|
|
405
|
+
- Include a hero image if available
|
|
406
|
+
- Keep layout clean with generous whitespace
|
|
407
|
+
""",
|
|
408
|
+
"""DATA VISUALIZATION:
|
|
409
|
+
When presenting statistics or metrics, use infographic macros:
|
|
410
|
+
- \\circlestat{percentage}{label} for percentage displays
|
|
411
|
+
- \\circlestatcolor{percentage}{label}{color} for colored circles
|
|
412
|
+
- \\bigstat{NUMBER}{label} for large number callouts
|
|
413
|
+
- \\statrow{...}{...}{...} to arrange stats in a row
|
|
414
|
+
Place infographics between article sections for visual interest.
|
|
415
|
+
""",
|
|
416
|
+
"""PAGE CONTRAST AND VARIETY:
|
|
417
|
+
Create visual variety using dark/light page contrast:
|
|
418
|
+
- Use \\begin{darkpage}...\\end{darkpage} for impact pages (intros, features)
|
|
419
|
+
- Use \\begin{darksection}...\\end{darksection} for inline dark boxes
|
|
420
|
+
- Alternate between light and dark sections to create rhythm
|
|
421
|
+
- Use \\begin{accentpage}...\\end{accentpage} for colored accent pages
|
|
422
|
+
""",
|
|
423
|
+
"""PULL QUOTES:
|
|
424
|
+
Add pull quotes to break up long text sections:
|
|
425
|
+
- Use \\pullquote{quote text} for anonymous quotes
|
|
426
|
+
- Use \\pullquoteattr{quote text}{Author Name} with attribution
|
|
427
|
+
- Place at natural break points in articles
|
|
428
|
+
- Use sparingly - 1-2 per major article
|
|
429
|
+
""",
|
|
430
|
+
"""ARTICLE HEADERS:
|
|
431
|
+
Start articles with proper headers:
|
|
432
|
+
- Use \\articleheader{SECTION}{Title}{Byline} for full headers
|
|
433
|
+
- Use \\articletitle{Title} for simpler title-only headers
|
|
434
|
+
- Section tags should be small, bold, and colored (e.g., "FEATURE", "INTERVIEW")
|
|
435
|
+
""",
|
|
436
|
+
]
|
|
437
|
+
|
|
438
|
+
|
|
439
|
+
def get_magazine_preamble(theme: Optional[MagazineTheme] = None) -> str:
|
|
440
|
+
"""Convenience function to get full magazine preamble."""
|
|
441
|
+
generator = MagazineLayoutGenerator(theme)
|
|
442
|
+
return generator.get_full_preamble()
|
|
443
|
+
|
|
444
|
+
|
|
445
|
+
def get_magazine_requirements() -> List[str]:
|
|
446
|
+
"""Convenience function to get magazine requirements for LLM."""
|
|
447
|
+
generator = MagazineLayoutGenerator()
|
|
448
|
+
return generator.get_magazine_requirements()
|
|
449
|
+
|
|
450
|
+
|
|
451
|
+
if __name__ == "__main__":
|
|
452
|
+
# Print the full preamble for testing
|
|
453
|
+
print("=" * 60)
|
|
454
|
+
print("MAGAZINE LAYOUT PREAMBLE")
|
|
455
|
+
print("=" * 60)
|
|
456
|
+
print(get_magazine_preamble())
|
|
457
|
+
print("\n" + "=" * 60)
|
|
458
|
+
print("MAGAZINE REQUIREMENTS")
|
|
459
|
+
print("=" * 60)
|
|
460
|
+
for i, req in enumerate(get_magazine_requirements(), 1):
|
|
461
|
+
print(f"\n--- Requirement {i} ---")
|
|
462
|
+
print(req)
|