@@ -18,6 +18,7 @@ use reflexo_typst::{
1818 config:: CompileOpts ,
1919 escape:: { escape_str, AttributeEscapes } ,
2020 path:: PathClean ,
21+ static_html,
2122 system:: SystemWorldComputeGraph ,
2223 vector:: {
2324 ir:: { LayoutRegionNode , Module , Page , PageMetadata } ,
@@ -134,10 +135,18 @@ impl TypstRenderer {
134135 format ! ( "{prefix}-{theme}" )
135136 } ) ;
136137
137- self . extension = if theme. is_empty ( ) {
138- "multi.sir.in" . into ( )
138+ if self . static_html {
139+ self . extension = if theme. is_empty ( ) {
140+ "html" . into ( )
141+ } else {
142+ format ! ( "{theme}.html" ) . into ( )
143+ } ;
139144 } else {
140- format ! ( "{theme}.multi.sir.in" ) . into ( )
145+ self . extension = if theme. is_empty ( ) {
146+ "multi.sir.in" . into ( )
147+ } else {
148+ format ! ( "{theme}.multi.sir.in" ) . into ( )
149+ } ;
141150 } ;
142151 }
143152
@@ -417,19 +426,13 @@ impl TypstRenderer {
417426 items : Vec < OutlineItemRef > ,
418427 ) {
419428 if items. len ( ) != chapters. len ( ) {
420- panic ! (
421- "cannot merge outline with different chapter
422- count"
423- ) ;
429+ panic ! ( "cannot merge outline with different chapter count" ) ;
424430 }
425431 for ( idx, item) in items. into_iter ( ) . enumerate ( ) {
426432 let chapter = & mut chapters[ idx] ;
427433
428434 if chapter. item != item. item {
429- panic ! (
430- "cannot merge outline with different
431- chapter"
432- ) ;
435+ panic ! ( "cannot merge outline with different chapter" ) ;
433436 }
434437
435438 Self :: intern_pages (
@@ -663,74 +666,109 @@ impl TypstRenderer {
663666 TypstDocument :: Paged ( self . pure_compile :: < TypstPagedDocument > ( & graph) ?)
664667 } ;
665668
666- if self . static_html {
667- return Ok ( doc) ;
669+ for theme in THEME_LIST {
670+ if self . static_html {
671+ self . compile_html_page_with ( theme) ?;
672+ } else {
673+ self . compile_paged_page_with ( theme, & graph, settings. clone ( ) ) ?;
674+ }
668675 }
669676
670- for theme in THEME_LIST {
671- self . set_theme_target ( theme) ;
677+ Ok ( doc)
678+ }
679+
680+ pub fn compile_html_page_with ( & mut self , theme : & str ) -> Result < TypstDocument > {
681+ let inputs = TaskInputs {
682+ entry : None ,
683+ inputs : Some ( {
684+ let mut dict = TypstDict :: new ( ) ;
685+ self . set_theme_target ( theme) ;
686+ dict. insert ( "x-target" . into ( ) , self . compiler . target . clone ( ) . into_value ( ) ) ;
672687
673- // let path = path.clone().to_owned();
674- self . compiler
675- . set_post_process_layout ( move |_m, doc, layout| {
676- // println!("post process {}", path.display());
688+ Arc :: new ( LazyHash :: new ( dict) )
689+ } ) ,
690+ } ;
691+ let graph = self . verse . computation_with ( inputs) ;
692+ let doc = self . pure_compile :: < TypstHtmlDocument > ( & graph) ?;
677693
678- let LayoutRegionNode :: Pages ( pages) = layout else {
679- unreachable ! ( ) ;
680- } ;
694+ let html_doc = doc. as_ref ( ) ;
681695
682- let ( mut meta, pages) = pages. take ( ) ;
683-
684- let introspector = & doc. introspector ( ) ;
685- let labels = doc
686- . introspector ( )
687- . all ( )
688- . flat_map ( |elem| elem. label ( ) . zip ( elem. location ( ) ) )
689- . map ( |( label, elem) | {
690- ( label. resolve ( ) . to_owned ( ) , introspector. position ( elem) )
691- } )
692- . map ( |( label, pos) | {
693- (
694- label,
695- format ! (
696- "p{}x{:.2}y{:.2}" ,
697- pos. page,
698- pos. point. x. to_pt( ) ,
699- pos. point. y. to_pt( )
700- ) ,
701- )
702- } )
703- . collect :: < Vec < _ > > ( ) ;
704- // println!("{:#?}", labels);
705-
706- let labels = serde_json:: to_vec ( & labels) . unwrap_or_exit ( ) ;
707- let sema_label_meta = ( "sema-label" . into ( ) , labels. into ( ) ) ;
708-
709- let mut custom = vec ! [ sema_label_meta] ;
710-
711- if settings. with_outline {
712- let mut spans = SpanInternerImpl :: default ( ) ;
713-
714- let outline = crate :: outline:: outline ( & mut spans, & doc) ;
715- let outline = serde_json:: to_vec ( & outline) . unwrap_or_exit ( ) ;
716- let outline_meta = ( "outline" . into ( ) , outline. into ( ) ) ;
717- custom. push ( outline_meta) ;
718- }
696+ let res = self
697+ . report ( static_html ( html_doc) )
698+ . expect ( "failed to render static html" ) ;
719699
720- meta. push ( PageMetadata :: Custom ( custom) ) ;
700+ let dest = self . module_dest_path ( ) ;
701+ std:: fs:: write ( & dest, res. body ) . unwrap_or_exit ( ) ;
721702
722- LayoutRegionNode :: Pages ( Arc :: new ( ( meta , pages ) ) )
723- } ) ;
703+ Ok ( TypstDocument :: Html ( doc . clone ( ) ) )
704+ }
724705
725- let res = DynSvgModuleExport :: run ( & graph, & self . compiler ) ?;
726- if let Some ( doc) = res {
727- let content = doc. to_bytes ( ) ;
728- let dest = self . module_dest_path ( ) ;
729- std:: fs:: write ( & dest, content) . unwrap_or_exit ( ) ;
730- }
706+ pub fn compile_paged_page_with (
707+ & mut self ,
708+ theme : & str ,
709+ graph : & Arc < SystemWorldComputeGraph > ,
710+ settings : CompilePageSetting ,
711+ ) -> Result < ( ) > {
712+ self . set_theme_target ( theme) ;
713+
714+ // let path = path.clone().to_owned();
715+ self . compiler
716+ . set_post_process_layout ( move |_m, doc, layout| {
717+ // println!("post process {}", path.display());
718+
719+ let LayoutRegionNode :: Pages ( pages) = layout else {
720+ unreachable ! ( ) ;
721+ } ;
722+
723+ let ( mut meta, pages) = pages. take ( ) ;
724+
725+ let introspector = & doc. introspector ( ) ;
726+ let labels = doc
727+ . introspector ( )
728+ . all ( )
729+ . flat_map ( |elem| elem. label ( ) . zip ( elem. location ( ) ) )
730+ . map ( |( label, elem) | ( label. resolve ( ) . to_owned ( ) , introspector. position ( elem) ) )
731+ . map ( |( label, pos) | {
732+ (
733+ label,
734+ format ! (
735+ "p{}x{:.2}y{:.2}" ,
736+ pos. page,
737+ pos. point. x. to_pt( ) ,
738+ pos. point. y. to_pt( )
739+ ) ,
740+ )
741+ } )
742+ . collect :: < Vec < _ > > ( ) ;
743+ // println!("{:#?}", labels);
744+
745+ let labels = serde_json:: to_vec ( & labels) . unwrap_or_exit ( ) ;
746+ let sema_label_meta = ( "sema-label" . into ( ) , labels. into ( ) ) ;
747+
748+ let mut custom = vec ! [ sema_label_meta] ;
749+
750+ if settings. with_outline {
751+ let mut spans = SpanInternerImpl :: default ( ) ;
752+
753+ let outline = crate :: outline:: outline ( & mut spans, & doc) ;
754+ let outline = serde_json:: to_vec ( & outline) . unwrap_or_exit ( ) ;
755+ let outline_meta = ( "outline" . into ( ) , outline. into ( ) ) ;
756+ custom. push ( outline_meta) ;
757+ }
758+
759+ meta. push ( PageMetadata :: Custom ( custom) ) ;
760+
761+ LayoutRegionNode :: Pages ( Arc :: new ( ( meta, pages) ) )
762+ } ) ;
763+
764+ let res = DynSvgModuleExport :: run ( graph, & self . compiler ) ?;
765+ if let Some ( doc) = res {
766+ let content = doc. to_bytes ( ) ;
767+ let dest = self . module_dest_path ( ) ;
768+ std:: fs:: write ( & dest, content) . unwrap_or_exit ( ) ;
731769 }
732770
733- Ok ( doc )
771+ Ok ( ( ) )
734772 }
735773
736774 // todo: we should use same snapshot as that compiled documents
0 commit comments