ó
    ê~ˆj-  ã            
       óÔ   • S r SSKrSSKrSSKrSSKJr  SrSrS\S\4S jr	S\4S	 jr
S
\4S jrS\S\\   S\S-  S\S-  S\4
S jrS\S\\   S\4S jrSS jr\S:X  a  \" 5         gg)aÆ  
Generate static HTML reading pages for a downloaded manga (any source).

For every chapter directory (chapter_NNN/, including suffixed ones like
chapter_71_1/ for fix chapters, with .webp/.jpg/.png images) it
writes:
  - <manga_dir>/index.html        -> overview page listing all chapters
  - <manga_dir>/chapter_NNN/index.html -> reader page for that chapter
    (vertical scroll, lazy-loaded images, prev/next navigation)

Safe to re-run at any time (idempotent): it simply regenerates pages from
whatever is on disk. Run it now to get pages for finished chapters, or
again after the download completes to get everything.

Usage:
  python3 generate_html.py [manga_dir]     (default: disastrous-necromancer)
é    N)ÚPath)z.webpz.jpgz.jpegz.pnga,  
  :root { --bg: #14161a; --fg: #e8e8e8; --muted: #9aa0a6; --accent: #7aa2f7; }
  * { box-sizing: border-box; }
  body { margin: 0; background: var(--bg); color: var(--fg);
         font-family: system-ui, -apple-system, 'Segoe UI', sans-serif; }
  a { color: var(--accent); text-decoration: none; }
  a:hover { text-decoration: underline; }
  header { padding: 16px 20px; border-bottom: 1px solid #2a2d33;
           display: flex; align-items: baseline; gap: 12px; flex-wrap: wrap; }
  header h1 { font-size: 1.25rem; margin: 0; }
  header .sub { color: var(--muted); font-size: 0.9rem; }
  nav { padding: 12px 20px; display: flex; gap: 16px; flex-wrap: wrap;
        border-bottom: 1px solid #2a2d33; background: #1a1d22; }
  nav a { padding: 6px 12px; border-radius: 6px; background: #24272e; }
  nav a:hover { background: #2e323b; text-decoration: none; }
  nav a:empty { display: none; }
  main { max-width: 900px; margin: 0 auto; padding: 0 0 40px; }
  img.page { display: block; width: 100%; height: auto; }
  .chapter-list { list-style: none; padding: 12px 20px; margin: 0;
                  columns: 4; column-gap: 24px; }
  .chapter-list li { break-inside: avoid; }
  .chapter-list a { display: block; padding: 4px 8px; border-radius: 4px; }
  .chapter-list a:hover { background: #24272e; text-decoration: none; }
  .chapter-list li.new a { font-weight: 600; }
  .foot { color: var(--muted); font-size: 0.8rem; text-align: center;
          padding: 16px; border-top: 1px solid #2a2d33; margin-top: 24px; }
  @media (max-width: 700px) { .chapter-list { columns: 2; } }
Údir_nameÚreturnc                 ó¦   • [         R                  " SU 5      nU(       d  U $ SSR                  UR                  S5      R	                  S5      5      -   $ )z;chapter_12 -> 'Chapter 12', chapter_71_1 -> 'Chapter 71.1'.zchapter_(\d+(?:_\d+)*)$zChapter Ú.é   Ú_)ÚreÚmatchÚjoinÚgroupÚsplit©r   Úms     Ú>/home/nathan/projects/ai/drake_scans_download/generate_html.pyÚchapter_titler   9   sB   € ä
�ŠÐ+¨XÓ6€AÞØˆØ˜Ÿ™ §¡¨£×!1Ñ!1°#Ó!6Ó7Ñ7Ð7ó    c                 óª   • [         R                  " SU 5      nU(       a2  S[        S UR                  S5      R	                  S5       5       5      4$ SU 4$ )zNchapter_71 before chapter_71_1 before chapter_72 (numeric, not lexicographic).zchapter_([\d_]+)$r   c              3   ó8   #   • U  H  n[        U5      v •  M     g 7f)N)Úint)Ú.0Úxs     r   Ú	<genexpr>Ú#chapter_sort_key.<locals>.<genexpr>E   s   é € Ð?Ò)> Aœ˜QŸ˜Ò)>ùs   ‚r   r	   )r
   r   Útupler   r   r   s     r   Úchapter_sort_keyr   A   sI   € ä
�ŠÐ% xÓ0€AÞØ”5Ñ?¨¯©°«×)9Ñ)9¸#Ô)>Ó?Ó?Ð@Ð@Øˆxˆ=Ðr   Úpc                 ó¦   • [         R                  " SU R                  5      nU(       a  S[        UR	                  S5      5      4$ SU R                  4$ )zHSort by the LEADING page number only (all-digits would break '002-102').z(\d+)r   r   )r
   r   Únamer   r   )r   r   s     r   Úimg_keyr    I   s<   € ä
�Š�˜1Ÿ6™6Ó"€AÞ#$ˆAŒs�1—7‘7˜1“:‹ÐÐ5¨1¨a¯f©f¨+Ð5r   ÚtitleÚimagesÚprevÚnext_c                 ó°  ^ • SR                  U 4S j[        US5       5       5      nU(       a&  SU S[        R                  " [	        U5      5       S3OSnU(       a&  SU S[        R                  " [	        U5      5       S	3OSnS
[        R                  " T 5       S[
         S[        R                  " T 5       S[        U5       SU SU SU SU SU S3$ )NÚ
c              3   ó¤   >#   • U  HE  u  pS [         R                  " UR                  5       S[         R                  " T5       SU S3v •  MG     g7f)z  <img class="page" src="z" alt="z page z" loading="lazy">N)ÚhtmlÚescaper   )r   Úir   r!   s      €r   r   Úchapter_page.<locals>.<genexpr>P   sK   øé € ð â(‰DˆAð $¤D§K¢K°·±Ó$7Ð#8¸ÄÇÂÈEÓ@RÐ?SÐSYÐZ[ÐY\Ð\mÕnÚ(ùs   ƒAAr   z<a href="../u   /">â†� z</a>Ú ú/">u    â†’</a>ú‹<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>ú</title>
<style>ú$</style>
</head>
<body>
<header><h1>ú</h1><span class="sub">z pages</span></header>
<nav>
  z
  <a href="../">Manga</a>
  z
</nav>
<main>
z
</main>
<div class="foot">u&    Â· <a href="../">All chapters</a> Â· z</div>
</body>
</html>
)r   Ú	enumerater(   r)   r   ÚCSSÚlen)r!   r"   r#   r$   ÚimgsÚ	prev_linkÚ	next_links   `      r   Úchapter_pager8   O   sü   ø€ Ø�9‰9ô ä˜f aÔ(óó €Dö W[�,˜t˜f G¬D¯KªK¼ÀdÓ8KÓ,LÐ+MÈTÑRÐ`b€IÞX]�,˜u˜g S¬¯ª´]À5Ó5IÓ)JÐ(KÈ8ÑTÐce€Iðô
 	�Š�EÓÐð Ü€uð ô �[Š[˜ÓÐ Ð 7¼¸F»°}ð Eà€+ð à€+ð ð €ð à�+ÐCÀIÀ;ð Oð%ð r   Úmanga_titleÚchaptersc                 óv  • / n[        US5       HP  u  p4U[        U5      :X  a  SOSnUR                  SU SU S[        R                  " [        U5      5       S35        MR     SR                  U5      nS	[        R                  " U 5       S
[         S[        R                  " U 5       S[        U5       SU S3$ )Nr   z class="new"r,   z  <liz
><a href="r-   z	</a></li>r&   r.   r/   r0   r1   zE chapters</span></header>
<main>
<ol class="chapter-list" start="1">
uˆ   
</ol>
<div class="foot">Local archive â€” serve this directory, e.g. <code>python3 -m http.server</code></div>
</main>
</body>
</html>
)r2   r4   Úappendr(   r)   r   r   r3   )r9   r:   Úitemsr*   ÚcÚmarkerÚlistings          r   Ú
index_pagerA   n   sÊ   € Ø€EÜ˜( AÖ&‰ˆØ#$¬¨H«Ó#5‘¸2ˆØ�‰�u˜V˜H J¨q¨c°´T·[²[ÄÈqÓAQÓ5RÐ4SÐS\Ð]Ö^ñ 'ð �i‰i˜Ó€Gðô
 	�Š�KÓ Ð!ð "Ü€uð ô �[Š[˜Ó%Ð&Ð&=¼cÀ(»m¸_ð Mð 	€	ð 
ðð r   c            	      ó”  • [        [        R                  5      S:”  a  [        [        R                  S   5      O
[        S5      n U R	                  5       (       d  [        R
                  " SU  35        [        R                  " SSU R                  5      R                  5       n[        S U R                  5        5       [        S9nSn[        U5       H·  u  pEX-  n[        S	 UR                  5        5       [        S9nU(       d  [        S
U S35        MD  US:”  a  X$S-
     OS nUS-   [        U5      :  a  X$S-      OS n	[!        U5      n
US-  R#                  [%        X§X‰5      5        US-  n[        S
U S[        U5       S35        M¹     U S-  R#                  ['        X5      5        [        SU SU  S35        [        SU 5        g )Nr   zdisastrous-necromancerzManga directory not found: z[-_]+Ú c              3   ó¸   #   • U  HP  nUR                  5       (       d  M  [        R                  " S UR                  5      (       d  MB  UR                  v •  MR     g7f)zchapter_\d[\d_]*$N)Úis_dirr
   r   r   )r   Úds     r   r   Úmain.<locals>.<genexpr>‘   s?   é € ð 	CÒ,�AØ�H‰H�Jó 
ÜŸ8š8Ð$8¸!¿&¹&×Aó 
ˆ�ŽÒ,ùs   ‚AŸ$AÁA)Úkeyr   c              3   ó²   #   • U  HM  nUR                   R                  5       [        ;   d  M'  UR                  R	                  S 5      (       a  MI  Uv •  MO     g7f)z.partN)ÚsuffixÚlowerÚIMG_EXTSr   Úendswith)r   r   s     r   r   rG   ™   sA   é € ð [¢K˜qØŸH™HŸN™NÓ,´Ñ8ó ØABÇÁÇÁÐQX×AY÷ ™¢Kùs   ‚&A¬AÁ	Az  z: no images yet, skipping pagez
index.htmlz: z pageszWrote z chapter pages + index.html in Ú/z)Serve it with:  python3 -m http.server -d)r4   ÚsysÚargvr   rE   Úexitr
   Úsubr   r!   ÚsortedÚiterdirr   r2   r    Úprintr   Ú
write_textr8   rA   )Ú	manga_dirr9   Úchapter_dirsÚwrittenr*   r   rF   r"   r#   r$   r!   s              r   ÚmainrZ   ‰   s£  € Ü%(¬¯©£]°QÓ%6””S—X‘X˜a‘[Ô!¼DÐAYÓ<Z€IØ×Ñ×ÑÜ�ŠÐ.¨y¨kÐ:Ô;ä—&’&˜ 3¨	¯©Ó7×=Ñ=Ó?€Käñ	C˜×*Ñ*Ô,ó 	Cäñ€Lð €GÜ˜\Ö*‰ˆØÑˆÜñ [ A§I¡I¤Kó [ä#ñ%ˆö Ü�B�t�fÐ:Ð;Ô<ÙØ&'¨!£eˆ| ™EÒ"°ˆØ'(¨1¡u¬s°<Ó/@Ó'@� ™UÒ#ÀdˆÜ˜dÓ#ˆØ	
ˆ\Ñ	×%Ñ%¤l°5À$Ó&NÔOØ�1‰ˆÜ��4�&˜œ3˜v›;˜- vÐ.Ö/ñ +ð  �Ñ×)Ñ)¬*°[Ó*OÔPÜ	ˆF�7�)Ð:¸9¸+ÀQÐ
GÔHÜ	Ð
5°yÕAr   Ú__main__)r   N)Ú__doc__r(   r
   rO   Úpathlibr   rL   r3   Ústrr   r   r    Úlistr8   rA   rZ   Ú__name__© r   r   Ú<module>rb      s¾   ðñó$ Û 	Û 
Ý à-€ð€ð<8˜Cð 8 Cô 8ð˜sô ð6ˆtô 6ð˜ð  T¨$¡Zð °s¸T±zð È#ÐPTÉ*ð ÐY\ô ð>˜Cð ¨4°©9ð ¸ô ô6 BðF ˆzÓÙ…Fð r   