@@ -5,24 +5,56 @@ import { getTypstRuleByName } from "./rule";
55export function exportToTypst ( root : NodeType , nodes : Array < NodeType > ) : string {
66 const imp = `#import "@preview/curryst:0.5.0": rule, prooftree` ;
77 const page = `#set page(fill: none, width: auto, height: auto, margin: (x: 1em, y: 1em))` ;
8- const prooftree = `#prooftree(${ exportSubformula ( root , nodes ) } )` ;
9- return `${ imp } \n${ page } \n${ prooftree } ` ;
8+ const [ formula , footnotes ] = exportSubformula ( root , nodes , 1 ) ;
9+ const prooftree = `#prooftree(${ formula } )` ;
10+
11+ const conditions = ( root . statement . sidecondition || [ ] ) . map ( ( { NotFree : { element, placeholder } } ) => {
12+ return `${ element . value } "not occuring freely in" ${ placeholder . value } `
13+ } ) ;
14+ conditions . push ( ...footnotes . map ( ( [ id , note ] ) => `$"${ id } :" ${ note } $` ) ) ;
15+
16+ let typstStr = `${ imp } \n${ page } \n${ prooftree } ` ;
17+
18+ if ( conditions . length > 0 ) {
19+ typstStr += "\n#set text(size: 7pt)"
20+ typstStr += "\n#let footnotes(body) = context {\n\tpad(top: 4pt, line(length: measure(body).width, stroke: 0.5pt + black))\n\tbody\n}" ;
21+ typstStr += `\n#footnotes[#stack(dir: ttb, spacing: 4pt, ${ conditions . join ( ", " ) } )]`
22+ }
23+
24+ return typstStr ;
1025}
1126
12- function exportSubformula ( node : NodeType , nodes : Array < NodeType > ) : string {
13- const name = getTypstRuleByName ( node . rule as Rules ) ;
27+ function exportSubformula ( node : NodeType , nodes : Array < NodeType > , footnoteNumber : number ) : [ string , Array < [ number , string ] > ] {
28+ let name = getTypstRuleByName ( node . rule as Rules , footnoteNumber ) ;
1429 const lhs = node . statement . lhs . map ( formulaToTypst ) . join ( ", " ) || "emptyset" ;
1530 const current = formulaToTypst ( node . statement . formula ) ;
31+ let currentFootnoteNumber = footnoteNumber ;
32+ const footnotes : Array < [ number , string ] > = [ ] ;
33+ if ( Array . isArray ( name ) ) {
34+ currentFootnoteNumber ++ ;
35+ const formula = node . statement . formula as Formula & { type : "Exists" | "Forall" } ;
36+ const footnote = name [ 1 ]
37+ . replaceAll ( "%%identifier%%" , formula . body . identifier . value )
38+ . replaceAll ( "%%lhs%%" , lhs )
39+ . replaceAll ( "%%rhs%%" , current ) ;
40+ footnotes . push ( [ footnoteNumber , footnote ] ) ;
41+ name = name [ 0 ] ;
42+ } ;
1643
1744 const premisses = node . premisses
1845 . map ( ( premisse ) => {
1946 return nodes . find ( ( node ) => node . name === premisse ) ;
2047 } )
2148 . filter ( Boolean )
22- . map ( ( node ) => exportSubformula ( node as NodeType , nodes ) )
49+ . map ( ( node ) => {
50+ const [ subformula , extraFootnotes ] = exportSubformula ( node as NodeType , nodes , currentFootnoteNumber ) ;
51+ currentFootnoteNumber += extraFootnotes . length ;
52+ footnotes . push ( ...extraFootnotes ) ;
53+ return subformula ;
54+ } )
2355 . join ( ",\n" ) ;
2456
25- return `rule(name: $${ name } $,$${ lhs } tack ${ current } $,${ premisses } )` ;
57+ return [ `rule(name: $${ name } $,$${ lhs } tack ${ current } $,${ premisses } )` , footnotes ] ;
2658}
2759
2860function formulaToTypst ( formula : Formula ) : string {
@@ -47,7 +79,7 @@ function formulaToTypst(formula: Formula): string {
4779 return `exists ${ formulaToTypst ( { type : "Ident" , body : formula . body . identifier } ) } . ${ formulaToTypst ( formula . body . formula ) } ` ;
4880 case "Predicate" : {
4981 const vars = formula . body . identifiers . map ( ( id ) => id . value ) . join ( ", " ) ;
50- return `${ formula . body . identifier } (${ vars } )` ;
82+ return `${ formula . body . identifier . value } (${ vars } )` ;
5183 }
5284 default :
5385 return "" ;
0 commit comments