From e70186667937ca100e8e0c0970563e0a4a9333b2 Mon Sep 17 00:00:00 2001 From: Adam Weber Date: Wed, 11 Mar 2026 16:09:56 -0700 Subject: [PATCH 1/2] Update with TexLive 2026 --- .gitignore | 5 ++ Makefile | 31 +++++++---- build-wasm.sh | 135 +++++++++++++++++++++++++++++++++++++++----- regen-formats.sh | 142 +++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 287 insertions(+), 26 deletions(-) create mode 100644 regen-formats.sh diff --git a/.gitignore b/.gitignore index c694cc0f..66a1769a 100644 --- a/.gitignore +++ b/.gitignore @@ -12,3 +12,8 @@ example/bibtex/ build/ source/ dist/ +*.iso +.DS_Store + +# One-off scripts +test-install.sh diff --git a/Makefile b/Makefile index 4160a6e0..92688285 100644 --- a/Makefile +++ b/Makefile @@ -2,10 +2,13 @@ # http://www.linuxfromscratch.org/blfs/view/svn/pst/texlive.html # https://www.tug.org/texlive//devsrc/Master/texmf-dist/tex/latex/ -# TL2025 URLs -URL_texlive_full_iso = https://mirror.ctan.org/systems/texlive/Images/texlive2025.iso -URL_texlive_full_iso_cache = https://mirror.ctan.org/systems/texlive/Images/texlive2025.iso -URL_texlive = https://github.com/TeX-Live/texlive-source/archive/refs/heads/tags/texlive-2025.0.tar.gz +# TL2026 URLs +URL_texlive_full_iso = https://mirror.ctan.org/systems/texlive/Images/texlive2026-20260301.iso +URL_texlive_full_iso_cache = https://mirror.ctan.org/systems/texlive/Images/texlive2026-20260301.iso +URL_texlive = https://github.com/TeX-Live/texlive-source/archive/refs/heads/tags/texlive-2026.0.tar.gz +# Old TL2025 URLs (commented out) +#URL_texlive_full_iso = https://mirror.ctan.org/systems/texlive/Images/texlive2025.iso +#URL_texlive = https://github.com/TeX-Live/texlive-source/archive/refs/heads/tags/texlive-2025.0.tar.gz # Old TL2023 URLs (commented out) #URL_texlive_full_iso = https://tug.ctan.org/systems/texlive/Images/texlive2023-20230313.iso #URL_texlive_full_iso_cache = https://github.com/busytex/busytex/releases/download/texlive2023-20230313.iso/texlive2023-20230313.iso.00 ... @@ -92,7 +95,7 @@ BIBTEX_REDEFINE = initialize eoln last history bad xchr buffer close_file usage SYNCTEX_REDEFINE = synctex_ctxt synctex_dot_open synctex_record_node_char synctex_record_node_kern synctex_record_node_math synctex_record_node_unknown synctexabort synctexchar synctexcurrent synctexhlist synctexhorizontalruleorglue synctexinitcommand synctexkern synctexmath synctexmrofxfdp synctexnode synctexoption synctexpdfrefxform synctexpdfxform synctexsheet synctexstartinput synctexteehs synctexterminate synctextsilh synctextsilv synctexvlist synctexvoidhlist synctexvoidvlist -PDFTEX_REDEFINE = initialize getstringsstarted sortavail zprimitive znewtrieop ztrienode zcompresstrie zfirstfit ztriepack ztriefix newpatterns inittrie zlinebreak newhyphexceptions zdomarks prefixedcommand storefmtfile loadfmtfile finalcleanup initprim mainbody println zprintchar zprint zprintnl zprintesc zprintthedigs zprintint zprintcs zsprintcs zprintfilename zprintsize zprintwritewhatsit zprintsanum zprintcsnames printfileline initterminal zstreqbuf zstreqstr zsearchstring zprinttwo zprinthex zprintromanint printcurrentstring zhalf zrounddecimals zprintscaled zmultandadd zxovern zxnoverd zbadness zmakefrac ztakefrac zabvscd newrandoms zinitrandoms zunifrand zshowtokenlist runaway zflushlist zfreenode zroundxnoverd zprevrightmost zflushstr getmicrointerval zshortdisplay zprintfontandchar zprintmark zprintruledimen zprintglue zprintspec zprintfamandchar zprintdelimiter zprintstyle zprintskipparam zdeletetokenref zdeleteglueref zprintmode zprintinmode popnest zprintparam begindiagnostic zenddiagnostic zprintlengthparam zprintcmdchr zprintgroup zgrouptrace pseudoclose zdeletesaref ztokenshow printmeaning showcurcmdchr showcontext groupwarning ifwarning filewarning endfilereading clearforerrorprompt zeffectivechar zaddorsub zquotient zfract beginname zpackfilename zpackbufferedname zpackjobname zeffectivecharinfo zprunemovements zshortdisplayn zcharpw zheightplusdepth zmathkern popalignment showsavegroups printtotals zfreezepagespecs youcant znormmin trapzeroglue newinteraction giveerrhelp openfmtfile closefilesandterminate zdvifour preparemag dviswap zdvifontdef zfatalerror zoverflow jumpout normalizeselector error makestring slowmakestring getavail zgetnode newnullbox zcharbox zstackintobox zvardelimiter zmakeleftright newrule znewmath znewspec znewparamglue znewglue zappendtovlist znewkern znewpenalty znewindex newnoad indentinhmode zmathglue pushalignment znewwhatsit zfractionrule fixlanguage appenditaliccorrection znewskipparam appspace pushnest zidlookup zprimlookup pseudoinput znewsavelevel zeqsave zbegintokenlist beginfilereading zstrtoks insertsrcspecial appendsrcspecial zmorename endname znewedge znewstyle newchoice znewligature znewligitem newdisc zsasave zfindsaelement zsaveforafter makenamestring zamakenamestring zzwmakenamestring zbmakenamestring zpromptfilename terminput openlogfile firmuptheline zdvipop zmovement zspecialout getnext checkoutervalidity endtokenlist gettoken zinterror pauseforinstructions zreconstitute backinput insertrelax inserror initcol zmlog backerror muerror zcharwarning znewcharacter zfetch zmakeord zfiniteshrink reportillegalcase extrarightbrace noalignerror omiterror cserror mathlimitswitch insertdollarsign offsave headforvmode alignerror zeTeXenabled normrand privileged passtext getrtoken macrocall zreadtoks zpushmath zconfusion zflushnodelist zsadestroy zeqdestroy flushmath hyphenate zcopynodelist zchangeiflimit zzreverse zmakevcenter zprunepagetop zvertbreak deletelast zjustcopy zjustreverse zfinmlist zpdferror ztokenstostring zshownodelist zprintsubsidiarydata zshowbox zvpackage zoverbar zvsplit zshoweqtb zrestoretrace zeqdefine zeqworddefine normalparagraph zinitspan initrow endgraf starteqno zgeqdefine zgeqworddefine zshowsa zsadef zsawdef zgsadef zgsawdef sarestore unsave showinfo zboxerror showactivities zensurevbox zreadfontinfo znewmarginkern zpushnode zfindprotcharleft popnode zhpack zrebox zcleanbox mlisttohlist zmakescripts zmakeover zmakeunder zmakeradical zmakemathaccent zmakefraction zmakeop zappdisplay zfindprotcharright ztotalpw ztrybreak zpostlinebreak scanfilenamebraced scanfilename getxtoken expand startinput thetoks conditional convtoks scanregisternum pseudostart zscankeyword xtoken getxorprotected fincol doassignments scanoptionalequals zsetmathchar scanleftbrace scangeneraltext appenddiscretionary builddiscretionary appendchoices buildchoices shiftcase scanfontident scanint zfindfontdimen zscansomethinginternal scancharnum zscanglue scanexpr scaneightbitint begininsertoradjust scanfourbitint scanfifteenbitint unpackage scanfourbitintor18 alterprevgraf alterinteger znewwritewhatsit makeaccent zscanmath subsup mathac mathradical zscandimen scannormalglue scanmuglue appendglue getpreambletoken appendkern insthetoks showwhatever zscantoks comparestrings zwriteout zoutwhat vlistout hlistout zshipout zfireup buildpage itsallover znewgraf appendpenalty initmath resumeafterdisplay aftermath finalign alignpeek finrow doendv zboxend zpackage handlerightbrace makemark issuemessage scanpdfexttoks scanrulespec zscanspec zbeginbox zscanbox zdoregistercommand alterpagesofar alterboxdimen initalign zscandelimiter mathfraction mathleftright alteraux znewfont openorclosein doextension maincontrol getnullstr loadpoolstrings generic_synctex_get_current_name runsystem texmf_yesno maininit topenin ipcpage open_in_or_pipe open_out_or_pipe close_file_or_pipe init_start_time get_date_and_time get_seconds_and_micros input_line calledit do_dump do_undump makefullnamestring getjobname gettexstring isnewsource remembersourceinfo makesrcspecial initstarttime find_input_file getcreationdate getfilemoddate getfilesize getfiledump convertStringToHexString getmd5sum pdftex_fail maketexstring initversionstring fixdateandtime shellenabledp restrictedshell argv argc interactionoption dump_name filelineerrorstylep parsefirstlinep translate_filename default_translate_filename readyalready etexp TEXformatdefault formatdefaultlength outputcomment dumpoption insertsrcspecialauto insertsrcspecialeverypar srcspecialsp dumpline buffer first last strstart outputfilename strpool xchr interrupt bufsize maxbufstack inputptr inputstack inopen inputfile poolptr poolsize start_time_str iniversion mltexp insertsrcspecialeveryparend insertsrcspecialeverycr insertsrcspecialeverymath insertsrcspecialeveryhbox insertsrcspecialeveryvbox insertsrcspecialeverydisplay bad bounddefault boundname membot mainmemory extramembot memmin memtop extramemtop memmax errorline halferrorline maxprintline maxstrings stringsfree stringvacancies poolfree fontmemsize fontmax fontk hyphsize triesize stacksize maxinopen paramsize nestsize savesize dvibufsize expanddepth eightbitp haltonerrorp quotedfilename strptr initpoolptr initstrptr poolfile logfile selector dig tally termoffset fileoffset trickbuf trickcount firstcount interaction deletionsallowed setboxallowed history errorcount helpline helpptr useerrhelp OKtointerrupt aritherror texremainder randoms jrandom randomseed twotothe speclog tempptr yzmem zmem lomemmax himemmin varused dynused avail memend rover fontinshortdisplay depththreshold breadthmax nest nestptr maxneststack curlist shownmode oldsetting systime sysday sysmonth sysyear zeqtb zzzaa zzzab hash yhash hashused hashextra hashtop eqtbtop hashhigh nonewcontrolsequence cscount prim primused savestack saveptr maxsavestack curlevel curgroup curboundary magset curcmd curchr curcs curtok maxinstack curinput openparens line linestack sourcefilenamestack fullsourcefilenamestack scannerstatus warningindex defref paramstack paramptr maxparamstack alignstate baseptr parloc partoken forceeof isincsname curmark longstate pstack curval curvallevel radix curorder readfile readopen condptr iflimit curif ifline skipline curname curarea curext areadelimiter extdelimiter nameinprogress jobname logopened dvifile texmflogname tfmfile fontinfo fmemptr fontptr fontcheck fontsize fontdsize fontparams fontname fontarea fontbc fontec fontglue fontused hyphenchar skewchar bcharlabel fontbchar fontfalsebchar charbase widthbase heightbase depthbase italicbase ligkernbase kernbase extenbase parambase nullcharacter totalpages maxv maxh maxpush lastbop deadcycles doingleaders discwidth bestplline bestplace minimaldemerits breakwidth background curactivewidth activewidth hliststack totalshrink totalstretch readopen readfile pstack curmark prim zzzaa speclog twotothe randoms helpline trickbuf dig xord dvibuf halfbuf dvilimit dviptr dvioffset dvigone downptr rightptr dvih dviv curh curv dvif curs epochseconds microseconds totalstretch totalshrink lastbadness adjusttail lastleftmostchar lastrightmostchar hliststack hliststacklevel preadjusttail packbeginline emptyfield nulldelimiter curmlist curstyle cursize curmu mlistpenalties curf curc curi magicoffset curalign curspan curloop alignptr curhead curtail curprehead curpretail justbox passive printednode passnumber activewidth curactivewidth background breakwidth firstp noshrinkerroryet curp secondpass finalpass threshold minimaldemerits minimumdemerits bestplace bestplline discwidth easyline lastspecialline firstwidth secondwidth firstindent secondindent bestbet fewestdemerits bestline actuallooseness linediff trieused trieoplang trieopval trieopptr maxopused smallop triec trieo triel trier trieptr triehash trietaken triemin triemax trienotready bestheightplusdepth pagetail pagecontents pagemaxdepth bestpagebreak leastpagecost bestsize pagesofar lastglue lastpenalty lastkern lastnodetype insertpenalties outputactive mainf maini mainj maink mainp mains bchar falsebchar cancelboundary insdisc curbox aftertoken longhelpseen formatident fmtfile writefile writeopen writeloc pdflastxpos pdflastypos curpagewidth curpageheight curhoffset curvoffset eTeXmode eofseen LRptr LRproblems curdir pseudofiles grpstack ifstack maxregnum maxreghelpline saroot curptr sanull sachain salevel lastlinefill dolastlinefit activenodesize fillwidth bestplshort bestplglue hyphstart hyphindex discptr editnamestart editnamelength editline ipcon stopatspace savestrptr savepoolptr debugformatfile expanddepthcount mltexenabledp accentc basec replacec baseslant accentslant basexheight basewidth baseheight accentwidth accentheight delta synctexoffset xord discptr bestplglue bestplshort fillwidth saroot pagesofar triemin trieopval trieoplang trieused opstart hyfnext hyfnum hyfdistance initlhyf initrhyf hyfbchar hyf initlist initlig initlft hyphenpassed curl curr curq ligstack ligaturepresent lfthit rthit trietrl trietro trietrc hyfdistance hyfnum hyfnext opstart hyphword hyphlist hyphlink hyphcount ruleht ruledp rulewd hyfchar curlang initcurlang lq lr hc hn ha hb hf hu iac ibc hyf c f g k l t writefile lhyf rhyf hyphnext writeopen lhyf rhyf hyphnext writeopen t1_line_array t1_free get_fe_entry enc_free fe_tree t1_buf_array load_enc_file t1_line_ptr t1_length3 t1_encoding t1_length1 t1_buf_limit t1_buf_ptr t1_line_limit t1_length2 haltingonerrorp max_print_line +PDFTEX_REDEFINE = initialize getstringsstarted sortavail zprimitive znewtrieop ztrienode zcompresstrie zfirstfit ztriepack ztriefix newpatterns inittrie zlinebreak newhyphexceptions zdomarks prefixedcommand storefmtfile loadfmtfile finalcleanup initprim mainbody println zprintchar zprint zprintnl zprintesc zprintthedigs zprintint zprintcs zsprintcs zprintfilename zprintsize zprintwritewhatsit zprintsanum zprintcsnames printfileline initterminal zstreqbuf zstreqstr zsearchstring zprinttwo zprinthex zprintromanint printcurrentstring zhalf zrounddecimals zprintscaled zmultandadd zxovern zxnoverd zbadness zmakefrac ztakefrac zabvscd newrandoms zinitrandoms zunifrand zshowtokenlist runaway zflushlist zfreenode zroundxnoverd zprevrightmost zflushstr getmicrointerval zshortdisplay zprintfontandchar zprintmark zprintruledimen zprintglue zprintspec zprintfamandchar zprintdelimiter zprintstyle zprintskipparam zdeletetokenref zdeleteglueref zprintmode zprintinmode popnest zprintparam begindiagnostic zenddiagnostic zprintlengthparam zprintcmdchr zprintgroup zgrouptrace pseudoclose zdeletesaref ztokenshow printmeaning showcurcmdchr showcontext groupwarning ifwarning filewarning endfilereading clearforerrorprompt zeffectivechar zaddorsub zquotient zfract beginname zpackfilename zpackbufferedname zpackjobname zeffectivecharinfo zprunemovements zshortdisplayn zcharpw zheightplusdepth zmathkern popalignment showsavegroups printtotals zfreezepagespecs youcant znormmin trapzeroglue newinteraction giveerrhelp openfmtfile closefilesandterminate zdvifour preparemag dviswap zdvifontdef zfatalerror zoverflow jumpout normalizeselector error makestring slowmakestring getavail zgetnode newnullbox zcharbox zstackintobox zvardelimiter zmakeleftright newrule znewmath znewspec znewparamglue znewglue zappendtovlist znewkern znewpenalty znewindex newnoad indentinhmode zmathglue pushalignment znewwhatsit zfractionrule fixlanguage appenditaliccorrection znewskipparam appspace pushnest zidlookup zprimlookup pseudoinput znewsavelevel zeqsave zbegintokenlist beginfilereading zstrtoks insertsrcspecial appendsrcspecial zmorename endname znewedge znewstyle newchoice znewligature znewligitem newdisc zsasave zfindsaelement zsaveforafter makenamestring zamakenamestring zzwmakenamestring zbmakenamestring zpromptfilename terminput openlogfile firmuptheline zdvipop zmovement zspecialout getnext checkoutervalidity endtokenlist gettoken zinterror pauseforinstructions zreconstitute backinput insertrelax inserror initcol zmlog backerror muerror zcharwarning znewcharacter zfetch zmakeord zfiniteshrink reportillegalcase extrarightbrace noalignerror omiterror cserror mathlimitswitch insertdollarsign offsave headforvmode alignerror zeTeXenabled normrand privileged passtext getrtoken macrocall zreadtoks zpushmath zconfusion zflushnodelist zsadestroy zeqdestroy flushmath hyphenate zcopynodelist zchangeiflimit zzreverse zmakevcenter zprunepagetop zvertbreak deletelast zjustcopy zjustreverse zfinmlist zpdferror ztokenstostring zshownodelist zprintsubsidiarydata zshowbox zvpackage zoverbar zvsplit zshoweqtb zrestoretrace zeqdefine zeqworddefine normalparagraph zinitspan initrow endgraf starteqno zgeqdefine zgeqworddefine zshowsa zsadef zsawdef zgsadef zgsawdef sarestore unsave showinfo zboxerror showactivities zensurevbox zreadfontinfo znewmarginkern zpushnode zfindprotcharleft popnode zhpack zrebox zcleanbox mlisttohlist zmakescripts zmakeover zmakeunder zmakeradical zmakemathaccent zmakefraction zmakeop zappdisplay zfindprotcharright ztotalpw ztrybreak zpostlinebreak scanfilenamebraced scanfilename getxtoken expand startinput thetoks conditional convtoks scanregisternum pseudostart zscankeyword xtoken getxorprotected fincol doassignments scanoptionalequals zsetmathchar scanleftbrace scangeneraltext appenddiscretionary builddiscretionary appendchoices buildchoices shiftcase scanfontident scanint zfindfontdimen zscansomethinginternal scancharnum zscanglue scanexpr scaneightbitint begininsertoradjust scanfourbitint scanfifteenbitint unpackage scanfourbitintor18 alterprevgraf alterinteger znewwritewhatsit makeaccent zscanmath subsup mathac mathradical zscandimen scannormalglue scanmuglue appendglue getpreambletoken appendkern insthetoks showwhatever zscantoks comparestrings zwriteout zoutwhat vlistout hlistout zshipout zfireup buildpage itsallover znewgraf appendpenalty initmath resumeafterdisplay aftermath finalign alignpeek finrow doendv zboxend zpackage handlerightbrace makemark issuemessage scanpdfexttoks scanrulespec zscanspec zbeginbox zscanbox zdoregistercommand alterpagesofar alterboxdimen initalign zscandelimiter mathfraction mathleftright alteraux znewfont openorclosein doextension maincontrol getnullstr loadpoolstrings generic_synctex_get_current_name runsystem texmf_yesno maininit topenin ipcpage open_in_or_pipe open_out_or_pipe close_file_or_pipe init_start_time get_date_and_time get_seconds_and_micros input_line calledit do_dump do_undump makefullnamestring getjobname gettexstring isnewsource remembersourceinfo makesrcspecial initstarttime find_input_file getcreationdate getfilemoddate getfilesize getfiledump convertStringToHexString getmd5sum pdftex_fail maketexstring initversionstring fixdateandtime shellenabledp restrictedshell argv argc interactionoption dump_name filelineerrorstylep parsefirstlinep translate_filename default_translate_filename readyalready etexp TEXformatdefault formatdefaultlength outputcomment dumpoption insertsrcspecialauto insertsrcspecialeverypar srcspecialsp dumpline buffer first last strstart outputfilename strpool xchr interrupt bufsize maxbufstack inputptr inputstack inopen inputfile poolptr poolsize start_time_str iniversion mltexp insertsrcspecialeveryparend insertsrcspecialeverycr insertsrcspecialeverymath insertsrcspecialeveryhbox insertsrcspecialeveryvbox insertsrcspecialeverydisplay bad bounddefault boundname membot mainmemory extramembot memmin memtop extramemtop memmax errorline halferrorline maxprintline maxstrings stringsfree stringvacancies poolfree fontmemsize fontmax fontk hyphsize triesize stacksize maxinopen paramsize nestsize savesize dvibufsize expanddepth eightbitp haltonerrorp quotedfilename strptr initpoolptr initstrptr poolfile logfile selector dig tally termoffset fileoffset trickbuf trickcount firstcount interaction deletionsallowed setboxallowed history errorcount helpline helpptr useerrhelp OKtointerrupt aritherror texremainder randoms jrandom randomseed twotothe speclog tempptr yzmem zmem lomemmax himemmin varused dynused avail memend rover fontinshortdisplay depththreshold breadthmax nest nestptr maxneststack curlist shownmode oldsetting systime sysday sysmonth sysyear zeqtb zzzaa zzzab hash yhash hashused hashextra hashtop eqtbtop hashhigh nonewcontrolsequence cscount prim primused savestack saveptr maxsavestack curlevel curgroup curboundary magset curcmd curchr curcs curtok maxinstack curinput openparens line linestack sourcefilenamestack fullsourcefilenamestack scannerstatus warningindex defref paramstack paramptr maxparamstack alignstate baseptr parloc partoken forceeof isincsname curmark longstate pstack curval curvallevel radix curorder readfile readopen condptr iflimit curif ifline skipline curname curarea curext areadelimiter extdelimiter nameinprogress jobname logopened dvifile texmflogname tfmfile fontinfo fmemptr fontptr fontcheck fontsize fontdsize fontparams fontname fontarea fontbc fontec fontglue fontused hyphenchar skewchar bcharlabel fontbchar fontfalsebchar charbase widthbase heightbase depthbase italicbase ligkernbase kernbase extenbase parambase nullcharacter totalpages maxv maxh maxpush lastbop deadcycles doingleaders discwidth bestplline bestplace minimaldemerits breakwidth background curactivewidth activewidth hliststack totalshrink totalstretch readopen readfile pstack curmark prim zzzaa speclog twotothe randoms helpline trickbuf dig xord dvibuf halfbuf dvilimit dviptr dvioffset dvigone downptr rightptr dvih dviv curh curv dvif curs epochseconds microseconds totalstretch totalshrink lastbadness adjusttail lastleftmostchar lastrightmostchar hliststack hliststacklevel preadjusttail packbeginline emptyfield nulldelimiter curmlist curstyle cursize curmu mlistpenalties curf curc curi magicoffset curalign curspan curloop alignptr curhead curtail curprehead curpretail justbox passive printednode passnumber activewidth curactivewidth background breakwidth firstp noshrinkerroryet curp secondpass finalpass threshold minimaldemerits minimumdemerits bestplace bestplline discwidth easyline lastspecialline firstwidth secondwidth firstindent secondindent bestbet fewestdemerits bestline actuallooseness linediff trieused trieoplang trieopval trieopptr maxopused smallop triec trieo triel trier trieptr triehash trietaken triemin triemax trienotready bestheightplusdepth pagetail pagecontents pagemaxdepth bestpagebreak leastpagecost bestsize pagesofar lastglue lastpenalty lastkern lastnodetype insertpenalties outputactive mainf maini mainj maink mainp mains bchar falsebchar cancelboundary insdisc curbox aftertoken longhelpseen formatident fmtfile writefile writeopen writeloc pdflastxpos pdflastypos curpagewidth curpageheight curhoffset curvoffset eTeXmode eofseen LRptr LRproblems curdir pseudofiles grpstack ifstack maxregnum maxreghelpline saroot curptr sanull sachain salevel lastlinefill dolastlinefit activenodesize fillwidth bestplshort bestplglue hyphstart hyphindex discptr editnamestart editnamelength editline ipcon stopatspace savestrptr savepoolptr debugformatfile expanddepthcount mltexenabledp accentc basec replacec baseslant accentslant basexheight basewidth baseheight accentwidth accentheight delta synctexoffset xord discptr bestplglue bestplshort fillwidth saroot pagesofar triemin trieopval trieoplang trieused opstart hyfnext hyfnum hyfdistance initlhyf initrhyf hyfbchar hyf initlist initlig initlft hyphenpassed curl curr curq ligstack ligaturepresent lfthit rthit trietrl trietro trietrc hyfdistance hyfnum hyfnext opstart hyphword hyphlist hyphlink hyphcount ruleht ruledp rulewd hyfchar curlang initcurlang lq lr hc hn ha hb hf hu iac ibc hyf c f g k l t writefile lhyf rhyf hyphnext writeopen lhyf rhyf hyphnext writeopen t1_line_array t1_free get_fe_entry enc_free fe_tree t1_buf_array load_enc_file t1_line_ptr t1_length3 t1_encoding t1_length1 t1_buf_limit t1_buf_ptr t1_line_limit t1_length2 haltingonerrorp max_print_line zisbitset savearitherror oldselectorignorederr outputcanend LUATEX_REDEFINE = init_start_time topenin get_date_and_time get_seconds_and_micros input_line getjobname err runaway unpackage privileged initialize maketexstring makecstring open_in_or_pipe open_out_or_pipe close_file_or_pipe new_fm_entry delete_fm_entry avl_do_entry mitem check_std_t1font pdfmapfile pdfmapline check_ff_exist is_subsetable fm_free glyph_unicode_free write_tounicode zip_free pdf_printf convertStringToPDFString getcreationdate matrixused getllx getlly geturx getury matrixtransformrect matrixtransformpoint matrixrecalculate libpdffinish conditional unsave expand fd_tree fo_tree new_fd_entry lookup_fd_entry register_fd_entry get_unsigned_byte get_unsigned_pair read_jbig2_info write_jbig2 read_jpg_info write_jpg read_png_info write_png colorstackused newcolorstack colorstackcurrent colorstackpop colorstackskippagestart ttf_free writettf writeotf read_pdf_info write_epdf epdf_free make_subset_tag tex_printf xfwrite xfflush xgetc xputc initversionstring char_array selector strstart strstart error notdef mac_glyph_names ambiguous_names cur_file_name t3_line_array t3_file t3_line_ptr t3_line_limit ttf_length first last buffer epochseconds microseconds argc argv dump_name interaction interactionoption history interrupt pstack synctexoffset shellenabledp restrictedshell line parsefirstlinep filelineerrorstylep haltonerrorp nest radix hash rover avail char_ptr char_limit tally dig g nameoffile namelength write_fontencodings writet1 mk_shellcmdlist get_start_time set_start_time init_shell_escape shell_cmd_is_allowed normalize_quotes getrandomseed luatex_revision engine_name luatex_version_string luaopen_mplib luatex_version c_job_name luatex_banner haltingonerrorp max_print_line @@ -150,7 +153,7 @@ CXXFLAGS_TEXLIVE_native = $(CFLAGS_TEXLIVE_native) $(CXXFLAGS_native) # -fno-common # https://www.openwall.com/lists/musl/2017/02/16/3 -LDFLAGS_TEXLIVE_native = --static -static -static-libstdc++ -static-libgcc -ldl -lm -pthread -lpthread -lc -Wl,--unresolved-symbols=ignore-all +LDFLAGS_TEXLIVE_native = --static -static -static-libstdc++ -static-libgcc -ldl -lm -pthread -lpthread -lc -Wl,--unresolved-symbols=ignore-all -Wl,--allow-multiple-definition # The WASM build can't assemble `.s` files when building pkgdata for obvious reasons. PKGDATAFLAGS_ICU_wasm = --without-assembly -O $(ROOT)/build/wasm/texlive/libs/icu/icu-build/data/icupkg.inc @@ -205,7 +208,7 @@ OPTS_BUSYTEX_COMPILE_wasm = -DBUSYTEX_MAKEINDEX -DBUSYTEX_KPSE -DBUSYTEX_BIBTE OPTS_BUSYTEX_LINK = --static -static -static-libstdc++ -static-libgcc OPTS_BUSYTEX_LINK_native = $(OPTS_BUSYTEX_LINK) -ldl -lm -pthread -lpthread -Wl,--unresolved-symbols=ignore-all -OPTS_BUSYTEX_LINK_wasm = $(OPTS_BUSYTEX_LINK) -Wl,--unresolved-symbols=ignore-all -Wl,-error-limit=0 -sINITIAL_MEMORY=$(INITIAL_MEMORY) -sMAXIMUM_MEMORY=$(MAXIMUM_MEMORY) -sALLOW_MEMORY_GROWTH=1 -sEXIT_RUNTIME=0 -sINVOKE_RUN=0 -sASSERTIONS=1 -sERROR_ON_UNDEFINED_SYMBOLS=0 -sFORCE_FILESYSTEM=1 -sLZ4=1 -sMODULARIZE=1 -sEXPORT_NAME=busytex -sEXPORTED_FUNCTIONS='["_main", "_flush_streams"]' -sEXPORTED_RUNTIME_METHODS='["callMain", "FS", "ENV", "LZ4", "PATH"]' +OPTS_BUSYTEX_LINK_wasm = $(OPTS_BUSYTEX_LINK) -Wl,--unresolved-symbols=ignore-all -Wl,-error-limit=0 -sINITIAL_MEMORY=$(INITIAL_MEMORY) -sMAXIMUM_MEMORY=$(MAXIMUM_MEMORY) -sSTACK_SIZE=5242880 -sALLOW_MEMORY_GROWTH=1 -sEXIT_RUNTIME=0 -sINVOKE_RUN=0 -sASSERTIONS=1 -sERROR_ON_UNDEFINED_SYMBOLS=0 -sFORCE_FILESYSTEM=1 -sLZ4=1 -sMODULARIZE=1 -sEXPORT_NAME=busytex -sEXPORTED_FUNCTIONS='["_main", "_flush_streams"]' -sEXPORTED_RUNTIME_METHODS='["callMain", "FS", "ENV", "LZ4", "PATH"]' ############################################################################################################################## @@ -466,16 +469,20 @@ build/texlive-full.profile: echo TEXMFSYSCONFIG $(ROOT)/$(basename $@)/texmf-dist/texmf-config >> $@ #echo TEXMFVAR $(ROOT)/$(basename $@)/home/texmf-var >> build/texlive-$*.profile -build/texlive-%.txt: build/texlive-%.profile source/texmfrepo.txt +build/texlive-%.txt: source/texmfrepo.txt + # Regenerate profile in-place to ensure paths match current environment (host vs container) + rm -f build/texlive-$*.profile + $(MAKE) build/texlive-$*.profile $(BUSYTEX_native) mkdir -p $(basename $@)/$(BINARCH_native) - cp $(BUSYTEX_native) $(basename $@)/$(BINARCH_native) + cp $(BUSYTEX_native) $(basename $@)/$(BINARCH_native) # - $(foreach name,texlive-scripts latexconfig tex-ini-files,tar -xf source/texmfrepo/archive/$(name).r*.tar.xz -C $(basename $@); ) + $(foreach name,texlive-scripts latexconfig tex-ini-files kpathsea texlive.infra,tar -xf source/texmfrepo/archive/$(name).r*.tar.xz -C $(basename $@); ) + sed -i 's|TEXMFSYSVAR = $$TEXMFROOT/texmf-var|TEXMFSYSVAR = $$TEXMFROOT/texmf-dist/texmf-var|;s|TEXMFSYSCONFIG = $$TEXMFROOT/texmf-config|TEXMFSYSCONFIG = $$TEXMFROOT/texmf-dist/texmf-config|;s|!!$$TEXMFDIST|$$TEXMFDIST|;s|!!$$TEXMFSYSCONFIG|$$TEXMFSYSCONFIG|;s|!!$$TEXMFSYSVAR|$$TEXMFSYSVAR|;s|!!$$TEXMFLOCAL|$$TEXMFLOCAL|' $(basename $@)/texmf-dist/web2c/texmf.cnf $(foreach name,xetex luahbtex pdftex xelatex luahblatex pdflatex kpsewhich kpseaccess kpsestat kpsereadlink,printf "#!/bin/sh\n$(ROOT)/$(basename $@)/$(BINARCH_native)/busytex $(name) $$"@ > $(basename $@)/$(BINARCH_native)/$(name) ; chmod +x $(basename $@)/$(BINARCH_native)/$(name); ) - $(foreach name,mktexlsr.pl updmap-sys.sh updmap.pl fmtutil-sys.sh fmtutil.pl,mv $(basename $@)/texmf-dist/scripts/texlive/$(name) $(basename $@)/$(BINARCH_native)/$(basename $(name)); ) + $(foreach name,mktexlsr.pl updmap-sys.sh updmap.pl fmtutil-sys.sh fmtutil.pl,cp $(basename $@)/texmf-dist/scripts/texlive/$(name) $(basename $@)/$(BINARCH_native)/$(basename $(name)); ) #mkdir -p $(ROOT)/source/texmfrepotmp; export TMPDIR=$(ROOT)/source/texmfrepotmp - TEXLIVE_INSTALL_NO_RESUME=1 $(PERL) source/texmfrepo/install-tl --repository source/texmfrepo --profile build/texlive-$*.profile --custom-bin $(ROOT)/$(basename $@)/$(BINARCH_native) --no-doc-install --no-src-install # strace -f -s 128 + -TEXLIVE_INSTALL_NO_RESUME=1 $(PERL) source/texmfrepo/install-tl --repository source/texmfrepo --profile build/texlive-$*.profile --custom-bin $(ROOT)/$(basename $@)/$(BINARCH_native) --no-doc-install --no-src-install # strace -f -s 128 # ##printf "#!/bin/sh\n$(ROOT)/$(basename $@)/$(BINARCH_native)/busytex lualatex $$"@ > $(basename $@)/$(BINARCH_native)/luahbtex echo '/texlive/texmf-dist/fonts/opentype/texlive/texmf-dist/fonts/type1' > $(basename $@)/fonts.conf diff --git a/build-wasm.sh b/build-wasm.sh index 365a9fc2..94a1171c 100755 --- a/build-wasm.sh +++ b/build-wasm.sh @@ -4,20 +4,127 @@ set -e NATIVE_RELEASE="build_native_ff0318af379bd80fb72b9b928d4744b5d9c9077d_12853073565_1" URLRELEASE="https://github.com/busytex/busytex/releases/download/${NATIVE_RELEASE}" EMSCRIPTEN_VERSION="3.1.43" +IMAGE="emscripten/emsdk:${EMSCRIPTEN_VERSION}" -# Parse arguments -BUILD_TARGET="${1:-wasm-all}" +run_container() { + podman run --rm -v "$(pwd):/work" -w /work "$IMAGE" bash -c "$1" +} -# Clean build artifacts that may have macOS-specific symlinks (only if clean requested) -if [ "$1" = "clean" ]; then +usage() { + cat <<'EOF' +Usage: ./build-wasm.sh + +Commands: + native Build native busytex binary (for install-tl) + wasm Build native + WASM binaries (busytex.wasm + busytex.js) + relink Relink WASM binary only (fast — reuses .o files) + texlive Run install-tl to install TeX Live packages + formats Regenerate format files using WASM binary (ensures match) + package Run file_packager to create texlive-basic.data + bundles Split texlive-basic.data into browser-loadable bundles (runs on host) + all Run full pipeline: wasm → texlive → formats → package → bundles + clean Remove build/ and source/ directories + +Upgrade workflow (TeX Live version bump): + 1. Update Makefile URLs for new TeX Live version + 2. Download ISO: make source/texmfrepo.txt + 3. ./build-wasm.sh wasm # Rebuild native + WASM engines + 4. ./build-wasm.sh texlive # Install packages via install-tl + 5. ./build-wasm.sh formats # Regenerate .fmt files with WASM binary + 6. ./build-wasm.sh package # Create texlive-basic.data + 7. ./build-wasm.sh bundles # Split into browser bundles + +Prerequisites: + - Podman (podman machine start) + - Bun runtime (for bundle splitting) + - ~10GB disk for TeX Live ISO +EOF +} + +cmd_native() { + echo "=== Building native busytex binary ===" + # Use Ubuntu container — native static linking needs full glibc dev libs + podman run --rm -v "$(pwd):/work" -w /work ubuntu:22.04 bash -c " + apt-get update && + apt-get install -y build-essential gperf p7zip-full icu-devtools file wget pkg-config python3 && + make source/texlive.txt && + make native + " + echo "=== Done: build/native/busytex ===" +} + +cmd_wasm() { + echo "=== Building native + WASM binaries ===" + run_container " + sudo apt-get update && + sudo apt-get install -y gperf p7zip-full icu-devtools file && + make source/texlive.txt && + make native && + make wasm-all + " + echo "=== Done: build/native/busytex + build/wasm/busytex.wasm + build/wasm/busytex.js ===" +} + +cmd_relink() { + echo "=== Relinking WASM binary (fast — reuses existing .o files) ===" + run_container " + rm -f build/wasm/busytex.js build/wasm/busytex.wasm && + make build/wasm/busytex.js + " + echo "=== Done: build/wasm/busytex.wasm + build/wasm/busytex.js ===" +} + +cmd_texlive() { + echo "=== Running install-tl in container ===" + run_container " + sudo apt-get update -qq && sudo apt-get install -yqq perl >/dev/null 2>&1 && + make build/texlive-basic.txt + " + echo "=== Done: build/texlive-basic/ ===" +} + +cmd_formats() { + echo "=== Regenerating format files with WASM binary ===" + run_container "bash regen-formats.sh" + echo "=== Done: format files regenerated ===" +} + +cmd_package() { + echo "=== Packaging texlive-basic.data ===" + run_container "make build/wasm/texlive-basic.js" + echo "=== Done: build/wasm/texlive-basic.data + build/wasm/texlive-basic.js ===" +} + +cmd_bundles() { + echo "=== Splitting into browser bundles ===" + cd ../packages + bun run split-bundle.ts ../busytex/build/wasm/texlive-basic.js ../busytex/build/wasm/texlive-basic.data ./bundles + echo "=== Done: packages/bundles/ ===" +} + +cmd_clean() { + echo "=== Cleaning build artifacts ===" rm -rf build source - exit 0 -fi - -podman run --rm -v "$(pwd):/work" -w /work emscripten/emsdk:${EMSCRIPTEN_VERSION} bash -c " - sudo apt-get update && - sudo apt-get install -y gperf p7zip-full icu-devtools file && - make URLRELEASE=${URLRELEASE} download-native && - make source/texlive.txt && - make ${BUILD_TARGET} -" + echo "=== Done ===" +} + +cmd_all() { + cmd_wasm + cmd_texlive + cmd_formats + cmd_package + cmd_bundles +} + +case "${1:-help}" in + native) cmd_native ;; + wasm) cmd_wasm ;; + relink) cmd_relink ;; + texlive) cmd_texlive ;; + formats) cmd_formats ;; + package) cmd_package ;; + bundles) cmd_bundles ;; + all) cmd_all ;; + clean) cmd_clean ;; + help|*) usage ;; +esac diff --git a/regen-formats.sh b/regen-formats.sh new file mode 100644 index 00000000..df766a23 --- /dev/null +++ b/regen-formats.sh @@ -0,0 +1,142 @@ +#!/bin/bash +# Regenerate format files using the WASM binary via Node.js. +# This ensures format files match the WASM engine's string pool. +# +# Run inside the emscripten container after install-tl has installed packages: +# podman run --rm -v "$(pwd):/work" -w /work emscripten/emsdk:3.1.43 bash regen-formats.sh + +set -e + +TEXLIVE_DIR="build/texlive-basic" +WASM_DIR="build/wasm" +FMT_DIR="${TEXLIVE_DIR}/texmf-dist/texmf-var/web2c" + +echo "=== Regenerating format files with WASM binary ===" +echo "Node version: $(node --version)" + +# Remove old format files generated by native binary +echo "Removing old format files..." +rm -f ${FMT_DIR}/pdftex/*.fmt ${FMT_DIR}/xetex/*.fmt ${FMT_DIR}/luahbtex/*.fmt + +# Create a Node.js script (CommonJS, no top-level await) +cat > /tmp/gen-format.js << 'SCRIPT' +'use strict'; +const fs = require('fs'); +const path = require('path'); + +const args = process.argv.slice(2); +const engine = args[0]; +const texliveDir = args[1]; +const wasmDir = args[2]; +const fmtOutputDir = args[3]; + +const engineMap = { + 'pdflatex': { program: 'pdflatex', iniArgs: ['-ini', '-jobname=pdflatex', '*pdflatex.ini'] }, + 'xelatex': { program: 'xelatex', iniArgs: ['-ini', '-jobname=xelatex', '*xelatex.ini'] }, + 'luahblatex': { program: 'luahblatex', iniArgs: ['-ini', '-jobname=lualatex', '*lualatex.ini'] }, +}; + +const config = engineMap[engine]; +if (!config) { + console.error('Unknown engine: ' + engine); + process.exit(1); +} + +function collectFiles(dir, prefix) { + var result = {}; + var entries = fs.readdirSync(dir, { withFileTypes: true }); + for (var i = 0; i < entries.length; i++) { + var entry = entries[i]; + var fullPath = path.join(dir, entry.name); + var vfsPath = prefix ? prefix + '/' + entry.name : entry.name; + if (entry.isDirectory()) { + Object.assign(result, collectFiles(fullPath, vfsPath)); + } else if (entry.isFile()) { + result[vfsPath] = fs.readFileSync(fullPath); + } + } + return result; +} + +async function main() { + console.log('Generating format: ' + engine); + + var wasmBinary = fs.readFileSync(path.join(wasmDir, 'busytex.wasm')); + + console.log('Collecting texmf-dist files...'); + var texmfFiles = collectFiles(path.join(texliveDir, 'texmf-dist'), '/texlive/texmf-dist'); + console.log('Collected ' + Object.keys(texmfFiles).length + ' files'); + + var busytexFactory = require(path.join(process.cwd(), wasmDir, 'busytex.js')); + + var Module = await busytexFactory({ + wasmBinary: wasmBinary, + noInitialRun: true, + thisProgram: '/texlive/texmf-dist/bin/busytex', + arguments: [config.program].concat(config.iniArgs), + preRun: [function(mod) { + // Create a dummy binary so kpathsea can lstat it for $SELFAUTODIR + mod.FS.mkdirTree('/texlive/texmf-dist/bin'); + mod.FS.writeFile('/texlive/texmf-dist/bin/busytex', ''); + var paths = Object.keys(texmfFiles); + for (var i = 0; i < paths.length; i++) { + var p = paths[i]; + var dir = path.dirname(p); + try { mod.FS.mkdirTree(dir); } catch(e) {} + mod.FS.writeFile(p, texmfFiles[p]); + } + mod.ENV['TEXMFCNF'] = '/texlive/texmf-dist/web2c'; + }], + print: function(text) { console.log('[TeX] ' + text); }, + printErr: function(text) { console.error('[TeX ERR] ' + text); } + }); + + await Module.ready; + + try { + Module.callMain([config.program].concat(config.iniArgs)); + } catch (e) { + console.log('Engine exited: ' + e.message); + } + + var fmtName = (engine === 'luahblatex' ? 'lualatex' : engine) + '.fmt'; + try { + var fmtData = Module.FS.readFile(fmtName); + fs.mkdirSync(fmtOutputDir, { recursive: true }); + var outputPath = path.join(fmtOutputDir, fmtName); + fs.writeFileSync(outputPath, fmtData); + console.log('Written: ' + outputPath + ' (' + fmtData.length + ' bytes)'); + } catch (e) { + console.error('Failed to extract ' + fmtName + ': ' + e.message); + try { + console.log('CWD files:', Module.FS.readdir('.')); + } catch(e2) {} + process.exit(1); + } +} + +main().catch(function(e) { console.error(e); process.exit(1); }); +SCRIPT + +# Generate each format +for engine in pdflatex xelatex; do + subdir=$(echo $engine | sed 's/pdflatex/pdftex/;s/xelatex/xetex/') + mkdir -p "${FMT_DIR}/${subdir}" + echo "--- Generating ${engine}.fmt ---" + node /tmp/gen-format.js "$engine" "$TEXLIVE_DIR" "$WASM_DIR" "${FMT_DIR}/${subdir}" || echo "WARN: ${engine} format generation failed" +done + +# Handle luahblatex separately (renamed from lualatex) +mkdir -p "${FMT_DIR}/luahbtex" +echo "--- Generating lualatex.fmt (for luahblatex) ---" +node /tmp/gen-format.js "luahblatex" "$TEXLIVE_DIR" "$WASM_DIR" "${FMT_DIR}/luahbtex" || echo "WARN: luahblatex format generation failed" + +# Rename lualatex.fmt to luahblatex.fmt +if [ -f "${FMT_DIR}/luahbtex/lualatex.fmt" ]; then + mv "${FMT_DIR}/luahbtex/lualatex.fmt" "${FMT_DIR}/luahbtex/luahblatex.fmt" +fi + +echo "" +echo "=== Format files ===" +ls -la ${FMT_DIR}/*/*.fmt 2>/dev/null || echo "No format files found!" +echo "=== Done ===" From 43ba4002e04814b8e11850b1bb9ad5a06fff6e0c Mon Sep 17 00:00:00 2001 From: Adam Weber Date: Wed, 11 Mar 2026 16:11:33 -0700 Subject: [PATCH 2/2] Update README for TexLive version change to 2026 --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index b5fde6a9..ac2d89ab 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# Programs from TexLive 2023 compiled with Emscripten into a single fully static binary (x86_64-linux / WASM) +# Programs from TexLive 2026 compiled with Emscripten into a single fully static binary (x86_64-linux / WASM) Currently compiles into a **fully static binary** (via musl on Alpine Linux): - xetex