1010import re
1111import sys
1212
13+ import base64
14+
1315try :
1416 import markdown
1517 from markdown .extensions .fenced_code import FencedCodeExtension
1618 from markdown .extensions .tables import TableExtension
1719 from markdown .extensions .toc import TocExtension
20+
1821except ImportError :
1922 print ("Installing markdown library..." )
2023 import subprocess
2124 subprocess .check_call ([sys .executable , "-m" , "pip" , "install" , "markdown" ])
25+
2226 import markdown
2327 from markdown .extensions .fenced_code import FencedCodeExtension
2428 from markdown .extensions .tables import TableExtension
2529 from markdown .extensions .toc import TocExtension
2630
31+ try :
32+ import zstandard
33+ except ImportError :
34+ print ("Installing zstandard library..." )
35+ import subprocess
36+ subprocess .check_call ([sys .executable , "-m" , "pip" , "install" , "zstandard" ])
37+ import zstandard
38+
2739# ── Paths ────────────────────────────────────────────────────────────────────
2840
2941DOCS_DIR = os .path .dirname (os .path .abspath (__file__ ))
@@ -325,7 +337,7 @@ def build_toc_sidebar(toc_tokens, current_slug):
325337 <link rel="icon" href="favicon.svg" type="image/svg+xml">
326338 <link rel="preconnect" href="https://fonts.googleapis.com">
327339 <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
328- <link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700; 800&family=JetBrains+Mono:wght@400;500;600; 700&display=swap" rel="stylesheet">
340+ <link href="https://fonts.googleapis.com/css2?family=Inter:ital,opsz, wght@0,14..32, 400.. 800&family=JetBrains+Mono:wght@400.. 700&display=swap" rel="stylesheet">
329341 <link rel="stylesheet" href="style.css">
330342</head>
331343<body>
@@ -376,7 +388,8 @@ def build_toc_sidebar(toc_tokens, current_slug):
376388 </svg>
377389 </button>
378390
379- <script>window.SEARCH_INDEX={search_index};</script>
391+ <script id="zstd-data" type="text/plain">{search_index_zstd_b64}</script>
392+ <script src="https://cdn.jsdelivr.net/npm/fzstd@0.1.1/umd/index.js" async></script>
380393 <script src="script.js"></script>
381394</body>
382395</html>
@@ -427,7 +440,7 @@ def build_page(slug):
427440 subtitle_html = subtitle_html ,
428441 body = body_html ,
429442 sidebar = sidebar ,
430- search_index = _search_index_json ,
443+ search_index_zstd_b64 = _search_index_zstd_b64 ,
431444 )
432445
433446 out_name = "index.html" if slug == "index" else f"{ slug } .html"
@@ -444,10 +457,10 @@ def get_all_slugs():
444457 return slugs
445458
446459
447- _search_index_json = "[] "
460+ _search_index_zstd_b64 = ""
448461
449462def main ():
450- global _search_index_json
463+ global _search_index_zstd_b64
451464 print ("📖 Building PyJavaBridge docs..." )
452465 print (f" Source: { SRC_DIR } " )
453466 print (f" Output: { OUT_DIR } " )
@@ -519,7 +532,14 @@ def main():
519532 search_index .append ({"slug" : slug , "title" : title , "url" : url , "sections" : sections })
520533
521534 import json
522- _search_index_json = json .dumps (search_index , separators = (',' , ':' ))
535+ search_json = json .dumps (search_index , separators = (',' , ':' ))
536+ cctx = zstandard .ZstdCompressor (level = 22 )
537+ compressed = cctx .compress (search_json .encode ('utf-8' ))
538+ _search_index_zstd_b64 = base64 .b64encode (compressed ).decode ('ascii' )
539+ raw_size = len (search_json .encode ('utf-8' ))
540+ compressed_size = len (compressed )
541+ b64_size = len (_search_index_zstd_b64 )
542+ print (f" Search index: { raw_size :,} bytes → { compressed_size :,} zstd → { b64_size :,} base64 ({ 100 * b64_size / raw_size :.1f} %)" )
523543
524544 # Build pages (with search index inlined)
525545 for slug in slugs :
0 commit comments