2424import argparse
2525import html
2626import re
27- from datetime import date
2827from pathlib import Path
2928from typing import Any , Dict , List , Optional , Sequence
3029
3534from reportlab .lib .utils import ImageReader
3635from reportlab .pdfgen import canvas as pdf_canvas
3736from reportlab .platypus import (
38- Flowable , KeepTogether , ListFlowable , ListItem , PageBreak , Paragraph ,
37+ Flowable , ListFlowable , ListItem , PageBreak , Paragraph ,
3938 SimpleDocTemplate , Spacer , Table , TableStyle ,
4039)
4140from reportlab .lib .styles import ParagraphStyle , getSampleStyleSheet
@@ -271,7 +270,7 @@ def is_block_start(line: str) -> bool:
271270
272271
273272def paragraph_text (lines : Sequence [str ]) -> str :
274- parts = [(l .strip () + "<br/>" ) if l .endswith (" " ) else l .strip () for l in lines ]
273+ parts = [(line .strip () + "<br/>" ) if line .endswith (" " ) else line .strip () for line in lines ]
275274 return re .sub (r"<br/>\s+" , "<br/>" , " " .join (parts ))
276275
277276
@@ -286,19 +285,29 @@ def markdown_to_story(md, styles, available, pal) -> List[Any]:
286285 i += 1
287286 continue
288287 if line == "[PAGE_BREAK]" :
289- story .append (PageBreak ()); i += 1 ; continue
288+ story .append (PageBreak ())
289+ i += 1
290+ continue
290291 if line .startswith ("# " ):
291292 story .append (Paragraph (inline_markup (line [2 :].strip ()), styles ["Title" ]))
292- story .append (Spacer (1 , 0.05 * inch )); i += 1 ; continue
293+ story .append (Spacer (1 , 0.05 * inch ))
294+ i += 1
295+ continue
293296 if line .startswith ("## " ):
294- story .append (Paragraph (numbered_heading_markup (line [3 :].strip (), pal ), styles ["Heading2" ])); i += 1 ; continue
297+ story .append (Paragraph (numbered_heading_markup (line [3 :].strip (), pal ), styles ["Heading2" ]))
298+ i += 1
299+ continue
295300 if line .startswith ("### " ):
296- story .append (Paragraph (inline_markup (line [4 :].strip ()), styles ["Heading3" ])); i += 1 ; continue
301+ story .append (Paragraph (inline_markup (line [4 :].strip ()), styles ["Heading3" ]))
302+ i += 1
303+ continue
297304 if line .startswith ("> " ):
298305 q = []
299306 while i < len (lines ) and lines [i ].strip ().startswith ("> " ):
300- q .append (lines [i ].strip ()[2 :]); i += 1
301- story .append (make_callout (q , styles , available , pal )); continue
307+ q .append (lines [i ].strip ()[2 :])
308+ i += 1
309+ story .append (make_callout (q , styles , available , pal ))
310+ continue
302311 if line .startswith ("- " ):
303312 items = []
304313 while i < len (lines ) and lines [i ].strip ().startswith ("- " ):
@@ -307,16 +316,21 @@ def markdown_to_story(md, styles, available, pal) -> List[Any]:
307316 i += 1
308317 story .append (ListFlowable (items , bulletType = "bullet" , bulletFontName = "Helvetica-Bold" ,
309318 bulletFontSize = 6 , leftIndent = 20 , bulletColor = pal ["accent" ]))
310- story .append (Spacer (1 , 0.04 * inch )); continue
319+ story .append (Spacer (1 , 0.04 * inch ))
320+ continue
311321 if line .startswith ("|" ):
312322 tl = []
313323 while i < len (lines ) and lines [i ].strip ().startswith ("|" ):
314- tl .append (lines [i ]); i += 1
324+ tl .append (lines [i ])
325+ i += 1
315326 story .append (make_table (tl , styles , available , pal ))
316- story .append (Spacer (1 , 0.10 * inch )); continue
317- para = [raw ]; i += 1
327+ story .append (Spacer (1 , 0.10 * inch ))
328+ continue
329+ para = [raw ]
330+ i += 1
318331 while i < len (lines ) and lines [i ].strip () and not is_block_start (lines [i ]):
319- para .append (lines [i ]); i += 1
332+ para .append (lines [i ])
333+ i += 1
320334 story .append (Paragraph (inline_markup (paragraph_text (para )), styles ["Body" ]))
321335 return story
322336
@@ -332,33 +346,42 @@ def draw_watermark(c, w, h, text):
332346 c .setFillColor (colors .Color (0.7 , 0.7 , 0.7 , alpha = 0.16 ))
333347 except TypeError :
334348 c .setFillColor (colors .HexColor ("#D1D5DB" ))
335- c .translate (w / 2.0 , h / 2.0 ); c .rotate (42 )
349+ c .translate (w / 2.0 , h / 2.0 )
350+ c .rotate (42 )
336351 c .setFont ("Helvetica-Bold" , 58 )
337- c .drawCentredString (0 , 0 , text ); c .restoreState ()
352+ c .drawCentredString (0 , 0 , text )
353+ c .restoreState ()
338354
339355
340356def draw_letterhead_band (c , meta , w , h , pal , logo_path ):
341357 band = 0.95 * inch
342358 c .saveState ()
343- c .setFillColor (pal ["accent_dark" ]); c .rect (0 , h - band , w , band , stroke = 0 , fill = 1 )
344- c .setFillColor (pal ["accent" ]); c .rect (0 , h - band - 0.04 * inch , w , 0.04 * inch , stroke = 0 , fill = 1 )
359+ c .setFillColor (pal ["accent_dark" ])
360+ c .rect (0 , h - band , w , band , stroke = 0 , fill = 1 )
361+ c .setFillColor (pal ["accent" ])
362+ c .rect (0 , h - band - 0.04 * inch , w , 0.04 * inch , stroke = 0 , fill = 1 )
345363 pad = 0.72 * inch
346364 ls = 0.52 * inch
347365 draw_logo (c , pad , h - band + (band - ls ) / 2.0 , ls , logo_path , pal , on_dark = True )
348366 nx = pad + ls + 0.18 * inch
349- c .setFillColor (pal ["white" ]); c .setFont ("Helvetica-Bold" , 13.5 )
367+ c .setFillColor (pal ["white" ])
368+ c .setFont ("Helvetica-Bold" , 13.5 )
350369 c .drawString (nx , h - 0.42 * inch , BRAND ["brand_name" ])
351- c .setFont ("Helvetica" , 8.5 ); c .setFillColor (colors .Color (1 , 1 , 1 , alpha = 0.78 ))
370+ c .setFont ("Helvetica" , 8.5 )
371+ c .setFillColor (colors .Color (1 , 1 , 1 , alpha = 0.78 ))
352372 c .drawString (nx , h - 0.58 * inch , BRAND ["brand_tagline" ])
353- c .setFont ("Helvetica" , 7.5 ); c .setFillColor (colors .Color (1 , 1 , 1 , alpha = 0.62 ))
373+ c .setFont ("Helvetica" , 7.5 )
374+ c .setFillColor (colors .Color (1 , 1 , 1 , alpha = 0.62 ))
354375 c .drawString (nx , h - 0.74 * inch , BRAND ["contact" ])
355376 right = w - pad
356377 pairs = meta [:2 ]
357378 ys = [(0.36 , 0.50 ), (0.66 , 0.80 )]
358379 for (label , value ), (ly , vy ) in zip (pairs , ys ):
359- c .setFillColor (colors .Color (1 , 1 , 1 , alpha = 0.7 )); c .setFont ("Helvetica" , 7.2 )
380+ c .setFillColor (colors .Color (1 , 1 , 1 , alpha = 0.7 ))
381+ c .setFont ("Helvetica" , 7.2 )
360382 c .drawRightString (right , h - ly * inch , label .upper ())
361- c .setFillColor (pal ["white" ]); c .setFont ("Helvetica-Bold" , 10.5 )
383+ c .setFillColor (pal ["white" ])
384+ c .setFont ("Helvetica-Bold" , 10.5 )
362385 c .drawRightString (right , h - vy * inch , value )
363386 c .restoreState ()
364387
@@ -369,16 +392,21 @@ def draw_compact_header(c, doc_title, doc_id, w, h, pal, logo_path):
369392 draw_logo (c , pad , h - 0.62 * inch , ls , logo_path , pal , on_dark = False )
370393 tx = pad + ls + 0.12 * inch
371394 c .saveState ()
372- c .setFillColor (pal ["ink" ]); c .setFont ("Helvetica-Bold" , 9 )
395+ c .setFillColor (pal ["ink" ])
396+ c .setFont ("Helvetica-Bold" , 9 )
373397 c .drawString (tx , h - 0.46 * inch , BRAND ["brand_name" ])
374- c .setFillColor (pal ["muted" ]); c .setFont ("Helvetica" , 7.5 )
398+ c .setFillColor (pal ["muted" ])
399+ c .setFont ("Helvetica" , 7.5 )
375400 c .drawString (tx , h - 0.58 * inch , BRAND ["brand_tagline" ])
376401 right = w - pad
377- c .setFillColor (pal ["ink" ]); c .setFont ("Helvetica-Bold" , 8.8 )
402+ c .setFillColor (pal ["ink" ])
403+ c .setFont ("Helvetica-Bold" , 8.8 )
378404 c .drawRightString (right , h - 0.46 * inch , doc_title )
379- c .setFillColor (pal ["muted" ]); c .setFont ("Helvetica" , 7.5 )
405+ c .setFillColor (pal ["muted" ])
406+ c .setFont ("Helvetica" , 7.5 )
380407 c .drawRightString (right , h - 0.58 * inch , doc_id )
381- c .setStrokeColor (pal ["accent" ]); c .setLineWidth (0.8 )
408+ c .setStrokeColor (pal ["accent" ])
409+ c .setLineWidth (0.8 )
382410 c .line (pad , h - 0.74 * inch , right , h - 0.74 * inch )
383411 c .restoreState ()
384412
@@ -388,13 +416,17 @@ def draw_footer(c, doc, footer_text, doc_id, w, pal):
388416 right = w - pad
389417 y = 0.46 * inch
390418 c .saveState ()
391- c .setStrokeColor (pal ["border" ]); c .setLineWidth (0.5 )
419+ c .setStrokeColor (pal ["border" ])
420+ c .setLineWidth (0.5 )
392421 c .line (pad , y + 0.18 * inch , right , y + 0.18 * inch )
393- c .setFillColor (pal ["accent" ]); c .rect (pad , y + 0.18 * inch , 0.32 * inch , 0.012 * inch , stroke = 0 , fill = 1 )
394- c .setFillColor (pal ["muted" ]); c .setFont ("Helvetica" , 7.4 )
422+ c .setFillColor (pal ["accent" ])
423+ c .rect (pad , y + 0.18 * inch , 0.32 * inch , 0.012 * inch , stroke = 0 , fill = 1 )
424+ c .setFillColor (pal ["muted" ])
425+ c .setFont ("Helvetica" , 7.4 )
395426 c .drawString (pad , y , doc_id )
396427 c .drawCentredString (w / 2 , y , footer_text [:120 ])
397- c .setFillColor (pal ["ink" ]); c .setFont ("Helvetica-Bold" , 7.6 )
428+ c .setFillColor (pal ["ink" ])
429+ c .setFont ("Helvetica-Bold" , 7.6 )
398430 c .drawRightString (right , y , f"Page { doc .page } " )
399431 c .restoreState ()
400432
@@ -405,7 +437,8 @@ def draw(c, doc):
405437 draw_watermark (c , w , h , cfg ["watermark" ])
406438 if first_page :
407439 if cover_first :
408- draw_footer (c , doc , cfg ["footer" ], cfg ["doc_id" ], w , pal ); return
440+ draw_footer (c , doc , cfg ["footer" ], cfg ["doc_id" ], w , pal )
441+ return
409442 draw_letterhead_band (c , cfg ["meta" ], w , h , pal , cfg ["logo" ])
410443 else :
411444 draw_compact_header (c , cfg ["title" ], cfg ["doc_id" ], w , h , pal , cfg ["logo" ])
@@ -434,7 +467,7 @@ def field(label, value):
434467
435468 meta = cfg ["meta" ][:3 ]
436469 if meta :
437- row = [[field (l , v ) for l , v in meta ]]
470+ row = [[field (label , value ) for label , value in meta ]]
438471 cw = (available * 0.9 ) / len (meta )
439472 chip = Table (row , colWidths = [cw ] * len (meta ), hAlign = "CENTER" )
440473 chip .setStyle (TableStyle ([
0 commit comments