Chapter 5: Nowebify.

This commit is contained in:
AwesomeAdam54321 2024-03-09 21:05:14 +08:00
parent e1ca0836cd
commit a733b321a5
7 changed files with 518 additions and 510 deletions

View file

@ -3,18 +3,18 @@
A format which renders as a plain-text serialisation of the Inweb weave tree, A format which renders as a plain-text serialisation of the Inweb weave tree,
useful only for testing the weaver. useful only for testing the weaver.
@h Creation. @ \section{Creation.}
= <<*>>=
void Debugging::create(void) { void Debugging::create(void) {
weave_format *wf = Formats::create_weave_format(I"TestingInweb", I".txt"); weave_format *wf = Formats::create_weave_format(I"TestingInweb", I".txt");
METHOD_ADD(wf, RENDER_FOR_MTID, Debugging::render); METHOD_ADD(wf, RENDER_FOR_MTID, Debugging::render);
} }
@h Methods. @ \section{Methods.}
For documentation, see "Weave Fornats". For documentation, see "Weave Fornats".
= <<*>>=
typedef struct debugging_render_state { typedef struct debugging_render_state {
struct text_stream *OUT; struct text_stream *OUT;
struct weave_order *wv; struct weave_order *wv;
@ -33,231 +33,231 @@ int Debugging::render_visit(tree_node *N, void *state, int L) {
text_stream *OUT = drs->OUT; text_stream *OUT = drs->OUT;
for (int i=0; i<L; i++) WRITE(" "); for (int i=0; i<L; i++) WRITE(" ");
WRITE("%S", N->type->node_type_name); WRITE("%S", N->type->node_type_name);
if (N->type == weave_document_node_type) @<Render document@> if (N->type == weave_document_node_type) <<Render document>>
else if (N->type == weave_head_node_type) @<Render head@> else if (N->type == weave_head_node_type) <<Render head>>
else if (N->type == weave_body_node_type) @<Render body@> else if (N->type == weave_body_node_type) <<Render body>>
else if (N->type == weave_tail_node_type) @<Render tail@> else if (N->type == weave_tail_node_type) <<Render tail>>
else if (N->type == weave_verbatim_node_type) @<Render verbatim@> else if (N->type == weave_verbatim_node_type) <<Render verbatim>>
else if (N->type == weave_chapter_header_node_type) @<Render chapter header@> else if (N->type == weave_chapter_header_node_type) <<Render chapter header>>
else if (N->type == weave_chapter_footer_node_type) @<Render chapter footer@> else if (N->type == weave_chapter_footer_node_type) <<Render chapter footer>>
else if (N->type == weave_section_header_node_type) @<Render section header@> else if (N->type == weave_section_header_node_type) <<Render section header>>
else if (N->type == weave_section_footer_node_type) @<Render section footer@> else if (N->type == weave_section_footer_node_type) <<Render section footer>>
else if (N->type == weave_section_purpose_node_type) @<Render purpose@> else if (N->type == weave_section_purpose_node_type) <<Render purpose>>
else if (N->type == weave_subheading_node_type) @<Render subheading@> else if (N->type == weave_subheading_node_type) <<Render subheading>>
else if (N->type == weave_bar_node_type) @<Render bar@> else if (N->type == weave_bar_node_type) <<Render bar>>
else if (N->type == weave_pagebreak_node_type) @<Render pagebreak@> else if (N->type == weave_pagebreak_node_type) <<Render pagebreak>>
else if (N->type == weave_linebreak_node_type) @<Render linebreak@> else if (N->type == weave_linebreak_node_type) <<Render linebreak>>
else if (N->type == weave_paragraph_heading_node_type) @<Render paragraph heading@> else if (N->type == weave_paragraph_heading_node_type) <<Render paragraph heading>>
else if (N->type == weave_endnote_node_type) @<Render endnote@> else if (N->type == weave_endnote_node_type) <<Render endnote>>
else if (N->type == weave_figure_node_type) @<Render figure@> else if (N->type == weave_figure_node_type) <<Render figure>>
else if (N->type == weave_audio_node_type) @<Render audio clip@> else if (N->type == weave_audio_node_type) <<Render audio clip>>
else if (N->type == weave_video_node_type) @<Render video clip@> else if (N->type == weave_video_node_type) <<Render video clip>>
else if (N->type == weave_download_node_type) @<Render download@> else if (N->type == weave_download_node_type) <<Render download>>
else if (N->type == weave_material_node_type) @<Render material@> else if (N->type == weave_material_node_type) <<Render material>>
else if (N->type == weave_embed_node_type) @<Render embed@> else if (N->type == weave_embed_node_type) <<Render embed>>
else if (N->type == weave_pmac_node_type) @<Render pmac@> else if (N->type == weave_pmac_node_type) <<Render pmac>>
else if (N->type == weave_vskip_node_type) @<Render vskip@> else if (N->type == weave_vskip_node_type) <<Render vskip>>
else if (N->type == weave_chapter_node_type) @<Render chapter@> else if (N->type == weave_chapter_node_type) <<Render chapter>>
else if (N->type == weave_section_node_type) @<Render section@> else if (N->type == weave_section_node_type) <<Render section>>
else if (N->type == weave_code_line_node_type) @<Render code line@> else if (N->type == weave_code_line_node_type) <<Render code line>>
else if (N->type == weave_function_usage_node_type) @<Render function usage@> else if (N->type == weave_function_usage_node_type) <<Render function usage>>
else if (N->type == weave_commentary_node_type) @<Render commentary@> else if (N->type == weave_commentary_node_type) <<Render commentary>>
else if (N->type == weave_carousel_slide_node_type) @<Render carousel slide@> else if (N->type == weave_carousel_slide_node_type) <<Render carousel slide>>
else if (N->type == weave_toc_node_type) @<Render toc@> else if (N->type == weave_toc_node_type) <<Render toc>>
else if (N->type == weave_toc_line_node_type) @<Render toc line@> else if (N->type == weave_toc_line_node_type) <<Render toc line>>
else if (N->type == weave_chapter_title_page_node_type) @<Render weave_chapter_title_page_node@> else if (N->type == weave_chapter_title_page_node_type) <<Render weave_chapter_title_page_node>>
else if (N->type == weave_defn_node_type) @<Render defn@> else if (N->type == weave_defn_node_type) <<Render defn>>
else if (N->type == weave_source_code_node_type) @<Render source code@> else if (N->type == weave_source_code_node_type) <<Render source code>>
else if (N->type == weave_url_node_type) @<Render URL@> else if (N->type == weave_url_node_type) <<Render URL>>
else if (N->type == weave_footnote_cue_node_type) @<Render footnote cue@> else if (N->type == weave_footnote_cue_node_type) <<Render footnote cue>>
else if (N->type == weave_begin_footnote_text_node_type) @<Render footnote text@> else if (N->type == weave_begin_footnote_text_node_type) <<Render footnote text>>
else if (N->type == weave_display_line_node_type) @<Render display line@> else if (N->type == weave_display_line_node_type) <<Render display line>>
else if (N->type == weave_function_defn_node_type) @<Render function defn@> else if (N->type == weave_function_defn_node_type) <<Render function defn>>
else if (N->type == weave_item_node_type) @<Render item@> else if (N->type == weave_item_node_type) <<Render item>>
else if (N->type == weave_grammar_index_node_type) @<Render grammar index@> else if (N->type == weave_grammar_index_node_type) <<Render grammar index>>
else if (N->type == weave_inline_node_type) @<Render inline@> else if (N->type == weave_inline_node_type) <<Render inline>>
else if (N->type == weave_locale_node_type) @<Render locale@> else if (N->type == weave_locale_node_type) <<Render locale>>
else if (N->type == weave_maths_node_type) @<Render maths@> else if (N->type == weave_maths_node_type) <<Render maths>>
else WRITE("Unknown node"); else WRITE("Unknown node");
WRITE("\n"); WRITE("\n");
return TRUE; return TRUE;
} }
@<Render document@> = <<Render document>>=
weave_document_node *C = RETRIEVE_POINTER_weave_document_node(N->content); weave_document_node *C = RETRIEVE_POINTER_weave_document_node(N->content);
WRITE(" weave order %d", C->wv->allocation_id); WRITE(" weave order %d", C->wv->allocation_id);
@<Render head@> = <<Render head>>=
weave_head_node *C = RETRIEVE_POINTER_weave_head_node(N->content); weave_head_node *C = RETRIEVE_POINTER_weave_head_node(N->content);
WRITE(" banner <%S>", C->banner); WRITE(" banner <%S>", C->banner);
@<Render body@> = <<Render body>>=
; ;
@<Render tail@> = <<Render tail>>=
weave_tail_node *C = RETRIEVE_POINTER_weave_tail_node(N->content); weave_tail_node *C = RETRIEVE_POINTER_weave_tail_node(N->content);
WRITE(" rennab <%S>", C->rennab); WRITE(" rennab <%S>", C->rennab);
@<Render verbatim@> = <<Render verbatim>>=
weave_verbatim_node *C = RETRIEVE_POINTER_weave_verbatim_node(N->content); weave_verbatim_node *C = RETRIEVE_POINTER_weave_verbatim_node(N->content);
Debugging::show_text(OUT, C->content, 80); Debugging::show_text(OUT, C->content, 80);
@<Render section header@> = <<Render section header>>=
weave_section_header_node *C = RETRIEVE_POINTER_weave_section_header_node(N->content); weave_section_header_node *C = RETRIEVE_POINTER_weave_section_header_node(N->content);
WRITE(" <%S>", C->sect->md->sect_title); WRITE(" <%S>", C->sect->md->sect_title);
@<Render section footer@> = <<Render section footer>>=
weave_section_footer_node *C = RETRIEVE_POINTER_weave_section_footer_node(N->content); weave_section_footer_node *C = RETRIEVE_POINTER_weave_section_footer_node(N->content);
WRITE(" <%S>", C->sect->md->sect_title); WRITE(" <%S>", C->sect->md->sect_title);
@<Render chapter header@> = <<Render chapter header>>=
weave_chapter_header_node *C = RETRIEVE_POINTER_weave_chapter_header_node(N->content); weave_chapter_header_node *C = RETRIEVE_POINTER_weave_chapter_header_node(N->content);
WRITE(" <%S>", C->chap->md->ch_title); WRITE(" <%S>", C->chap->md->ch_title);
@<Render chapter footer@> = <<Render chapter footer>>=
weave_chapter_footer_node *C = RETRIEVE_POINTER_weave_chapter_footer_node(N->content); weave_chapter_footer_node *C = RETRIEVE_POINTER_weave_chapter_footer_node(N->content);
WRITE(" <%S>", C->chap->md->ch_title); WRITE(" <%S>", C->chap->md->ch_title);
@<Render purpose@> = <<Render purpose>>=
weave_section_purpose_node *C = RETRIEVE_POINTER_weave_section_purpose_node(N->content); weave_section_purpose_node *C = RETRIEVE_POINTER_weave_section_purpose_node(N->content);
WRITE(" <%S>", C->purpose); WRITE(" <%S>", C->purpose);
@<Render subheading@> = <<Render subheading>>=
weave_subheading_node *C = RETRIEVE_POINTER_weave_subheading_node(N->content); weave_subheading_node *C = RETRIEVE_POINTER_weave_subheading_node(N->content);
WRITE(" <%S>", C->text); WRITE(" <%S>", C->text);
@<Render bar@> = <<Render bar>>=
; ;
@<Render pagebreak@> = <<Render pagebreak>>=
; ;
@<Render linebreak@> = <<Render linebreak>>=
; ;
@<Render paragraph heading@> = <<Render paragraph heading>>=
weave_paragraph_heading_node *C = RETRIEVE_POINTER_weave_paragraph_heading_node(N->content); weave_paragraph_heading_node *C = RETRIEVE_POINTER_weave_paragraph_heading_node(N->content);
Debugging::show_para(OUT, C->para); Debugging::show_para(OUT, C->para);
if (C->no_skip) WRITE(" (no skip)"); if (C->no_skip) WRITE(" (no skip)");
@<Render endnote@> = <<Render endnote>>=
; ;
@<Render figure@> = <<Render figure>>=
weave_figure_node *C = RETRIEVE_POINTER_weave_figure_node(N->content); weave_figure_node *C = RETRIEVE_POINTER_weave_figure_node(N->content);
WRITE(" <%S> %d by %d", C->figname, C->w, C->h); WRITE(" <%S> %d by %d", C->figname, C->w, C->h);
@<Render audio clip@> = <<Render audio clip>>=
weave_audio_node *C = RETRIEVE_POINTER_weave_audio_node(N->content); weave_audio_node *C = RETRIEVE_POINTER_weave_audio_node(N->content);
WRITE(" <%S> %d", C->audio_name, C->w); WRITE(" <%S> %d", C->audio_name, C->w);
@<Render video clip@> = <<Render video clip>>=
weave_video_node *C = RETRIEVE_POINTER_weave_video_node(N->content); weave_video_node *C = RETRIEVE_POINTER_weave_video_node(N->content);
WRITE(" <%S> %d", C->video_name, C->w); WRITE(" <%S> %d", C->video_name, C->w);
@<Render download@> = <<Render download>>=
weave_download_node *C = RETRIEVE_POINTER_weave_download_node(N->content); weave_download_node *C = RETRIEVE_POINTER_weave_download_node(N->content);
WRITE(" <%S> %S", C->download_name, C->filetype); WRITE(" <%S> %S", C->download_name, C->filetype);
@<Render material@> = <<Render material>>=
weave_material_node *C = RETRIEVE_POINTER_weave_material_node(N->content); weave_material_node *C = RETRIEVE_POINTER_weave_material_node(N->content);
WRITE(" "); WRITE(" ");
Debugging::show_mat(OUT, C->material_type); Debugging::show_mat(OUT, C->material_type);
if (C->material_type == CODE_MATERIAL) WRITE(": %S", C->styling->language_name); if (C->material_type == CODE_MATERIAL) WRITE(": %S", C->styling->language_name);
if (C->plainly) WRITE(" (plainly)"); if (C->plainly) WRITE(" (plainly)");
@<Render embed@> = <<Render embed>>=
weave_embed_node *C = RETRIEVE_POINTER_weave_embed_node(N->content); weave_embed_node *C = RETRIEVE_POINTER_weave_embed_node(N->content);
WRITE(" service <%S> ID <%S> %d by %d", C->service, C->ID, C->w, C->h); WRITE(" service <%S> ID <%S> %d by %d", C->service, C->ID, C->w, C->h);
@<Render pmac@> = <<Render pmac>>=
weave_pmac_node *C = RETRIEVE_POINTER_weave_pmac_node(N->content); weave_pmac_node *C = RETRIEVE_POINTER_weave_pmac_node(N->content);
WRITE(" <%S>", C->pmac->macro_name); WRITE(" <%S>", C->pmac->macro_name);
if (C->defn) WRITE(" (definition)"); if (C->defn) WRITE(" (definition)");
@<Render vskip@> = <<Render vskip>>=
weave_vskip_node *C = RETRIEVE_POINTER_weave_vskip_node(N->content); weave_vskip_node *C = RETRIEVE_POINTER_weave_vskip_node(N->content);
if (C->in_comment) WRITE(" (in comment)"); if (C->in_comment) WRITE(" (in comment)");
@<Render chapter@> = <<Render chapter>>=
weave_chapter_node *C = RETRIEVE_POINTER_weave_chapter_node(N->content); weave_chapter_node *C = RETRIEVE_POINTER_weave_chapter_node(N->content);
WRITE(" <%S>", C->chap->md->ch_title); WRITE(" <%S>", C->chap->md->ch_title);
@<Render section@> = <<Render section>>=
weave_section_node *C = RETRIEVE_POINTER_weave_section_node(N->content); weave_section_node *C = RETRIEVE_POINTER_weave_section_node(N->content);
WRITE(" <%S>", C->sect->md->sect_title); WRITE(" <%S>", C->sect->md->sect_title);
@<Render code line@> = <<Render code line>>=
; ;
@<Render function usage@> = <<Render function usage>>=
weave_function_usage_node *C = RETRIEVE_POINTER_weave_function_usage_node(N->content); weave_function_usage_node *C = RETRIEVE_POINTER_weave_function_usage_node(N->content);
WRITE(" <%S>", C->fn->function_name); WRITE(" <%S>", C->fn->function_name);
@<Render commentary@> = <<Render commentary>>=
weave_commentary_node *C = RETRIEVE_POINTER_weave_commentary_node(N->content); weave_commentary_node *C = RETRIEVE_POINTER_weave_commentary_node(N->content);
Debugging::show_text(OUT, C->text, 80); Debugging::show_text(OUT, C->text, 80);
if (C->in_code) WRITE(" (code)"); if (C->in_code) WRITE(" (code)");
@<Render carousel slide@> = <<Render carousel slide>>=
weave_carousel_slide_node *C = RETRIEVE_POINTER_weave_carousel_slide_node(N->content); weave_carousel_slide_node *C = RETRIEVE_POINTER_weave_carousel_slide_node(N->content);
WRITE(" caption <%S>", C->caption); WRITE(" caption <%S>", C->caption);
@<Render toc@> = <<Render toc>>=
weave_toc_node *C = RETRIEVE_POINTER_weave_toc_node(N->content); weave_toc_node *C = RETRIEVE_POINTER_weave_toc_node(N->content);
WRITE(" - <%S>", C->text1); WRITE(" - <%S>", C->text1);
@<Render toc line@> = <<Render toc line>>=
weave_toc_line_node *C = RETRIEVE_POINTER_weave_toc_line_node(N->content); weave_toc_line_node *C = RETRIEVE_POINTER_weave_toc_line_node(N->content);
WRITE(" - <%S, %S>", C->text1, C->text2); WRITE(" - <%S, %S>", C->text1, C->text2);
if (C->para) Debugging::show_para(OUT, C->para); if (C->para) Debugging::show_para(OUT, C->para);
@<Render weave_chapter_title_page_node@> = <<Render weave_chapter_title_page_node>>=
weave_chapter_title_page_node *C = RETRIEVE_POINTER_weave_chapter_title_page_node(N->content); weave_chapter_title_page_node *C = RETRIEVE_POINTER_weave_chapter_title_page_node(N->content);
WRITE(" - something %d", C->allocation_id); WRITE(" - something %d", C->allocation_id);
@<Render defn@> = <<Render defn>>=
weave_defn_node *C = RETRIEVE_POINTER_weave_defn_node(N->content); weave_defn_node *C = RETRIEVE_POINTER_weave_defn_node(N->content);
WRITE(" <%S>", C->keyword); WRITE(" <%S>", C->keyword);
@<Render source code@> = <<Render source code>>=
weave_source_code_node *C = RETRIEVE_POINTER_weave_source_code_node(N->content); weave_source_code_node *C = RETRIEVE_POINTER_weave_source_code_node(N->content);
WRITE(" <%S>\n", C->matter); WRITE(" <%S>\n", C->matter);
for (int i=0; i<L; i++) WRITE(" "); for (int i=0; i<L; i++) WRITE(" ");
WRITE(" "); WRITE(" ");
WRITE(" _%S_", C->colouring); WRITE(" _%S_", C->colouring);
@<Render URL@> = <<Render URL>>=
weave_url_node *C = RETRIEVE_POINTER_weave_url_node(N->content); weave_url_node *C = RETRIEVE_POINTER_weave_url_node(N->content);
WRITE(" content <%S> url <%S>", C->content, C->url); WRITE(" content <%S> url <%S>", C->content, C->url);
@<Render footnote cue@> = <<Render footnote cue>>=
weave_footnote_cue_node *C = RETRIEVE_POINTER_weave_footnote_cue_node(N->content); weave_footnote_cue_node *C = RETRIEVE_POINTER_weave_footnote_cue_node(N->content);
WRITE(" [%S]", C->cue_text); WRITE(" [%S]", C->cue_text);
@<Render footnote text@> = <<Render footnote text>>=
weave_begin_footnote_text_node *C = RETRIEVE_POINTER_weave_begin_footnote_text_node(N->content); weave_begin_footnote_text_node *C = RETRIEVE_POINTER_weave_begin_footnote_text_node(N->content);
WRITE(" [%S]", C->cue_text); WRITE(" [%S]", C->cue_text);
@<Render display line@> = <<Render display line>>=
weave_display_line_node *C = RETRIEVE_POINTER_weave_display_line_node(N->content); weave_display_line_node *C = RETRIEVE_POINTER_weave_display_line_node(N->content);
WRITE(" <%S>", C->text); WRITE(" <%S>", C->text);
@<Render function defn@> = <<Render function defn>>=
weave_function_defn_node *C = RETRIEVE_POINTER_weave_function_defn_node(N->content); weave_function_defn_node *C = RETRIEVE_POINTER_weave_function_defn_node(N->content);
WRITE(" <%S>", C->fn->function_name); WRITE(" <%S>", C->fn->function_name);
@<Render item@> = <<Render item>>=
weave_item_node *C = RETRIEVE_POINTER_weave_item_node(N->content); weave_item_node *C = RETRIEVE_POINTER_weave_item_node(N->content);
WRITE(" depth %d label <%S>", C->depth, C->label); WRITE(" depth %d label <%S>", C->depth, C->label);
@<Render grammar index@> = <<Render grammar index>>=
; ;
@<Render inline@> = <<Render inline>>=
; ;
@<Render locale@> = <<Render locale>>=
weave_locale_node *C = RETRIEVE_POINTER_weave_locale_node(N->content); weave_locale_node *C = RETRIEVE_POINTER_weave_locale_node(N->content);
Debugging::show_para(OUT, C->par1); Debugging::show_para(OUT, C->par1);
if (C->par2) { if (C->par2) {
@ -265,12 +265,12 @@ int Debugging::render_visit(tree_node *N, void *state, int L) {
Debugging::show_para(OUT, C->par2); Debugging::show_para(OUT, C->par2);
} }
@<Render maths@> = <<Render maths>>=
weave_maths_node *C = RETRIEVE_POINTER_weave_maths_node(N->content); weave_maths_node *C = RETRIEVE_POINTER_weave_maths_node(N->content);
WRITE(" <%S>", C->content); WRITE(" <%S>", C->content);
if (C->displayed) WRITE(" (displayed)"); if (C->displayed) WRITE(" (displayed)");
@ = <<*>>=
void Debugging::show_text(text_stream *OUT, text_stream *text, int limit) { void Debugging::show_text(text_stream *OUT, text_stream *text, int limit) {
WRITE(" <"); WRITE(" <");
for (int i=0; (i<limit) && (i<Str::len(text)); i++) for (int i=0; (i<limit) && (i<Str::len(text)); i++)

View file

@ -3,11 +3,11 @@
To characterise the relevant differences in behaviour between the To characterise the relevant differences in behaviour between the
various weaving formats offered, such as HTML, ePub, or TeX. various weaving formats offered, such as HTML, ePub, or TeX.
@h Formats. @ \section{Formats.}
Exactly as in the previous chapter, each format expresses its behaviour Exactly as in the previous chapter, each format expresses its behaviour
through optional method calls. through optional method calls.
= <<*>>=
typedef struct weave_format { typedef struct weave_format {
struct text_stream *format_name; struct text_stream *format_name;
struct text_stream *woven_extension; struct text_stream *woven_extension;
@ -33,18 +33,18 @@ weave_format *Formats::find_by_name(text_stream *name) {
@ Note that this is the file extension before any post-processing. For @ Note that this is the file extension before any post-processing. For
example, PDFs are made by weaving a TeX file and then running this through example, PDFs are made by weaving a TeX file and then running this through
|pdftex|. The extension here will be |.tex| because that's what the weave [[pdftex]]. The extension here will be [[.tex]] because that's what the weave
stage produces, even though we will later end up with a |.pdf|. stage produces, even though we will later end up with a [[.pdf]].
= <<*>>=
text_stream *Formats::file_extension(weave_format *wf) { text_stream *Formats::file_extension(weave_format *wf) {
return wf->woven_extension; return wf->woven_extension;
} }
@h Creation. @ \section{Creation.}
This must be performed very early in Inweb's run. This must be performed very early in Inweb's run.
= <<*>>=
void Formats::create_weave_formats(void) { void Formats::create_weave_formats(void) {
Debugging::create(); Debugging::create();
TeX::create(); TeX::create();
@ -52,21 +52,22 @@ void Formats::create_weave_formats(void) {
HTMLFormat::create(); HTMLFormat::create();
} }
@h Methods. @ \section{Methods.}
These two don't allow output to be produced: they're for any setting up and These two don't allow output to be produced: they're for any setting up and
putting away that needs tp be done. putting away that needs tp be done.
|BEGIN_WEAVING_FOR_MTID| is called before any output is generated, indeed, [[BEGIN_WEAVING_FOR_MTID]] is called before any output is generated, indeed,
before even the filename(s) for the output are worked out. Note that it before even the filename(s) for the output are worked out. Note that it
can return a |*_SWM| code to change the swarm behaviour of the weave to come; can return a [[*_SWM]] code to change the swarm behaviour of the weave to come;
this is helpful for EPUB weaving. this is helpful for EPUB weaving.
More simply, |END_WEAVING_FOR_MTID| is called when all weaving is done. More simply, [[END_WEAVING_FOR_MTID]] is called when all weaving is done.
@e BEGIN_WEAVING_FOR_MTID <<*>>=
@e END_WEAVING_FOR_MTID enum BEGIN_WEAVING_FOR_MTID
enum END_WEAVING_FOR_MTID
= <<*>>=
INT_METHOD_TYPE(BEGIN_WEAVING_FOR_MTID, weave_format *wf, web *W, weave_pattern *pattern) INT_METHOD_TYPE(BEGIN_WEAVING_FOR_MTID, weave_format *wf, web *W, weave_pattern *pattern)
VOID_METHOD_TYPE(END_WEAVING_FOR_MTID, weave_format *wf, web *W, weave_pattern *pattern) VOID_METHOD_TYPE(END_WEAVING_FOR_MTID, weave_format *wf, web *W, weave_pattern *pattern)
int Formats::begin_weaving(web *W, weave_pattern *pattern) { int Formats::begin_weaving(web *W, weave_pattern *pattern) {
@ -79,18 +80,19 @@ void Formats::end_weaving(web *W, weave_pattern *pattern) {
VOID_METHOD_CALL(pattern->pattern_format, END_WEAVING_FOR_MTID, W, pattern); VOID_METHOD_CALL(pattern->pattern_format, END_WEAVING_FOR_MTID, W, pattern);
} }
@ |RENDER_FOR_MTID| renders the weave tree in the given format: a format must @ [[RENDER_FOR_MTID]] renders the weave tree in the given format: a format must
provide this. provide this.
Note the use of an optional "body template" to provide material before and Note the use of an optional "body template" to provide material before and
after the usage of |[[Weave Content]]|; but note also that this content is after the usage of [[[[Weave Content]]]]; but note also that this content is
generated first, and the fore and aft matter second, so that the fore matter generated first, and the fore and aft matter second, so that the fore matter
can include plugin links whose need was only realised when rendering the can include plugin links whose need was only realised when rendering the
actual content. actual content.
@e RENDER_FOR_MTID <<*>>=
enum RENDER_FOR_MTID
= <<*>>=
VOID_METHOD_TYPE(RENDER_FOR_MTID, weave_format *wf, text_stream *OUT, heterogeneous_tree *tree) VOID_METHOD_TYPE(RENDER_FOR_MTID, weave_format *wf, text_stream *OUT, heterogeneous_tree *tree)
void Formats::render(text_stream *OUT, heterogeneous_tree *tree, filename *into) { void Formats::render(text_stream *OUT, heterogeneous_tree *tree, filename *into) {
weave_document_node *C = RETRIEVE_POINTER_weave_document_node(tree->root->content); weave_document_node *C = RETRIEVE_POINTER_weave_document_node(tree->root->content);
@ -111,9 +113,10 @@ void Formats::render(text_stream *OUT, heterogeneous_tree *tree, filename *into)
document of Preform grammar, and this is the hook for it. Most formats document of Preform grammar, and this is the hook for it. Most formats
should ignore it. should ignore it.
@e PREFORM_DOCUMENT_FOR_MTID <<*>>=
enum PREFORM_DOCUMENT_FOR_MTID
= <<*>>=
INT_METHOD_TYPE(PREFORM_DOCUMENT_FOR_MTID, weave_format *wf, text_stream *OUT, INT_METHOD_TYPE(PREFORM_DOCUMENT_FOR_MTID, weave_format *wf, text_stream *OUT,
weave_order *wv, web *W, chapter *C, section *S, source_line *L, weave_order *wv, web *W, chapter *C, section *S, source_line *L,
text_stream *matter, text_stream *concluding_comment) text_stream *matter, text_stream *concluding_comment)
@ -127,14 +130,15 @@ int Formats::preform_document(OUTPUT_STREAM, weave_order *wv, web *W,
return rv; return rv;
} }
@h Post-processing. @ \section{Post-processing.}
Post-processing is now largely done by commands in the pattern file, rather Post-processing is now largely done by commands in the pattern file, rather
than here, but we retain method calls to enable formats to do some idiosyncratic than here, but we retain method calls to enable formats to do some idiosyncratic
post-processing. post-processing.
@e POST_PROCESS_POS_MTID <<*>>=
enum POST_PROCESS_POS_MTID
= <<*>>=
VOID_METHOD_TYPE(POST_PROCESS_POS_MTID, weave_format *wf, weave_order *wv, int open_afterwards) VOID_METHOD_TYPE(POST_PROCESS_POS_MTID, weave_format *wf, weave_order *wv, int open_afterwards)
void Formats::post_process_weave(weave_order *wv, int open_afterwards) { void Formats::post_process_weave(weave_order *wv, int open_afterwards) {
VOID_METHOD_CALL(wv->format, POST_PROCESS_POS_MTID, wv, open_afterwards); VOID_METHOD_CALL(wv->format, POST_PROCESS_POS_MTID, wv, open_afterwards);
@ -144,9 +148,10 @@ void Formats::post_process_weave(weave_order *wv, int open_afterwards) {
done. Support for TeX console reporting is hard-wired here because it's done. Support for TeX console reporting is hard-wired here because it's
handled by //Patterns::post_process// directly. handled by //Patterns::post_process// directly.
@e POST_PROCESS_REPORT_POS_MTID <<*>>=
enum POST_PROCESS_REPORT_POS_MTID
= <<*>>=
VOID_METHOD_TYPE(POST_PROCESS_REPORT_POS_MTID, weave_format *wf, weave_order *wv) VOID_METHOD_TYPE(POST_PROCESS_REPORT_POS_MTID, weave_format *wf, weave_order *wv)
void Formats::report_on_post_processing(weave_order *wv) { void Formats::report_on_post_processing(weave_order *wv) {
TeXUtilities::report_on_post_processing(wv); TeXUtilities::report_on_post_processing(wv);
@ -156,9 +161,10 @@ void Formats::report_on_post_processing(weave_order *wv) {
@ For the sake of index files, we may want to substitute in values for @ For the sake of index files, we may want to substitute in values for
placeholder text in the template file. placeholder text in the template file.
@e POST_PROCESS_SUBSTITUTE_POS_MTID <<*>>=
enum POST_PROCESS_SUBSTITUTE_POS_MTID
= <<*>>=
INT_METHOD_TYPE(POST_PROCESS_SUBSTITUTE_POS_MTID, weave_format *wf, text_stream *OUT, INT_METHOD_TYPE(POST_PROCESS_SUBSTITUTE_POS_MTID, weave_format *wf, text_stream *OUT,
weave_order *wv, text_stream *detail, weave_pattern *pattern) weave_order *wv, text_stream *detail, weave_pattern *pattern)
int Formats::substitute_post_processing_data(OUTPUT_STREAM, weave_order *wv, int Formats::substitute_post_processing_data(OUTPUT_STREAM, weave_order *wv,

View file

@ -2,30 +2,30 @@
To provide for weaving into HTML and into EPUB books. To provide for weaving into HTML and into EPUB books.
@h Creation. @ \section{Creation.}
ePub books are basically mini-websites, so they share the same renderer. ePub books are basically mini-websites, so they share the same renderer.
= <<*>>=
void HTMLFormat::create(void) { void HTMLFormat::create(void) {
@<Create HTML@>; <<Create HTML>>;
@<Create ePub@>; <<Create ePub>>;
} }
@<Create HTML@> = <<Create HTML>>=
weave_format *wf = Formats::create_weave_format(I"HTML", I".html"); weave_format *wf = Formats::create_weave_format(I"HTML", I".html");
METHOD_ADD(wf, RENDER_FOR_MTID, HTMLFormat::render); METHOD_ADD(wf, RENDER_FOR_MTID, HTMLFormat::render);
@<Create ePub@> = <<Create ePub>>=
weave_format *wf = Formats::create_weave_format(I"ePub", I".html"); weave_format *wf = Formats::create_weave_format(I"ePub", I".html");
METHOD_ADD(wf, RENDER_FOR_MTID, HTMLFormat::render_EPUB); METHOD_ADD(wf, RENDER_FOR_MTID, HTMLFormat::render_EPUB);
METHOD_ADD(wf, BEGIN_WEAVING_FOR_MTID, HTMLFormat::begin_weaving_EPUB); METHOD_ADD(wf, BEGIN_WEAVING_FOR_MTID, HTMLFormat::begin_weaving_EPUB);
METHOD_ADD(wf, END_WEAVING_FOR_MTID, HTMLFormat::end_weaving_EPUB); METHOD_ADD(wf, END_WEAVING_FOR_MTID, HTMLFormat::end_weaving_EPUB);
@h Rendering. @ \section{Rendering.}
To keep track of what we're writing, we store the renderer state in an To keep track of what we're writing, we store the renderer state in an
instance of this: instance of this:
= <<*>>=
typedef struct HTML_render_state { typedef struct HTML_render_state {
struct text_stream *OUT; struct text_stream *OUT;
struct filename *into_file; struct filename *into_file;
@ -41,7 +41,7 @@ typedef struct HTML_render_state {
@ The initial state is as follows: @ The initial state is as follows:
= <<*>>=
HTML_render_state HTMLFormat::initial_state(text_stream *OUT, weave_order *wv, HTML_render_state HTMLFormat::initial_state(text_stream *OUT, weave_order *wv,
int EPUB_mode, filename *into) { int EPUB_mode, filename *into) {
HTML_render_state hrs; HTML_render_state hrs;
@ -63,7 +63,7 @@ HTML_render_state HTMLFormat::initial_state(text_stream *OUT, weave_order *wv,
@ So, then, here are the front-end method functions for rendering to HTML and @ So, then, here are the front-end method functions for rendering to HTML and
ePub respectively: ePub respectively:
= <<*>>=
void HTMLFormat::render(weave_format *self, text_stream *OUT, heterogeneous_tree *tree) { void HTMLFormat::render(weave_format *self, text_stream *OUT, heterogeneous_tree *tree) {
weave_document_node *C = RETRIEVE_POINTER_weave_document_node(tree->root->content); weave_document_node *C = RETRIEVE_POINTER_weave_document_node(tree->root->content);
HTML::declare_as_HTML(OUT, FALSE); HTML::declare_as_HTML(OUT, FALSE);
@ -82,7 +82,7 @@ void HTMLFormat::render_EPUB(weave_format *self, text_stream *OUT, heterogeneous
@ And in either case, we traverse the weave tree with the following visitor function. @ And in either case, we traverse the weave tree with the following visitor function.
= <<*>>=
int HTMLFormat::render_visit(tree_node *N, void *state, int L) { int HTMLFormat::render_visit(tree_node *N, void *state, int L) {
HTML_render_state *hrs = (HTML_render_state *) state; HTML_render_state *hrs = (HTML_render_state *) state;
text_stream *OUT = hrs->OUT; text_stream *OUT = hrs->OUT;
@ -93,56 +93,56 @@ int HTMLFormat::render_visit(tree_node *N, void *state, int L) {
(N->type == weave_pagebreak_node_type) || (N->type == weave_pagebreak_node_type) ||
(N->type == weave_chapter_node_type) || (N->type == weave_chapter_node_type) ||
(N->type == weave_chapter_title_page_node_type) || (N->type == weave_chapter_title_page_node_type) ||
(N->type == weave_grammar_index_node_type)) @<Render nothing@> (N->type == weave_grammar_index_node_type)) <<Render nothing>>
else if (N->type == weave_head_node_type) @<Render head@> else if (N->type == weave_head_node_type) <<Render head>>
else if (N->type == weave_tail_node_type) @<Render tail@> else if (N->type == weave_tail_node_type) <<Render tail>>
else if (N->type == weave_verbatim_node_type) @<Render verbatim@> else if (N->type == weave_verbatim_node_type) <<Render verbatim>>
else if (N->type == weave_section_header_node_type) @<Render header@> else if (N->type == weave_section_header_node_type) <<Render header>>
else if (N->type == weave_section_footer_node_type) @<Render footer@> else if (N->type == weave_section_footer_node_type) <<Render footer>>
else if (N->type == weave_section_purpose_node_type) @<Render purpose@> else if (N->type == weave_section_purpose_node_type) <<Render purpose>>
else if (N->type == weave_subheading_node_type) @<Render subheading@> else if (N->type == weave_subheading_node_type) <<Render subheading>>
else if (N->type == weave_bar_node_type) @<Render bar@> else if (N->type == weave_bar_node_type) <<Render bar>>
else if (N->type == weave_paragraph_heading_node_type) @<Render paragraph heading@> else if (N->type == weave_paragraph_heading_node_type) <<Render paragraph heading>>
else if (N->type == weave_endnote_node_type) @<Render endnote@> else if (N->type == weave_endnote_node_type) <<Render endnote>>
else if (N->type == weave_figure_node_type) @<Render figure@> else if (N->type == weave_figure_node_type) <<Render figure>>
else if (N->type == weave_extract_node_type) @<Render extract@> else if (N->type == weave_extract_node_type) <<Render extract>>
else if (N->type == weave_audio_node_type) @<Render audio clip@> else if (N->type == weave_audio_node_type) <<Render audio clip>>
else if (N->type == weave_video_node_type) @<Render video clip@> else if (N->type == weave_video_node_type) <<Render video clip>>
else if (N->type == weave_download_node_type) @<Render download@> else if (N->type == weave_download_node_type) <<Render download>>
else if (N->type == weave_material_node_type) @<Render material@> else if (N->type == weave_material_node_type) <<Render material>>
else if (N->type == weave_embed_node_type) @<Render embed@> else if (N->type == weave_embed_node_type) <<Render embed>>
else if (N->type == weave_pmac_node_type) @<Render pmac@> else if (N->type == weave_pmac_node_type) <<Render pmac>>
else if (N->type == weave_vskip_node_type) @<Render vskip@> else if (N->type == weave_vskip_node_type) <<Render vskip>>
else if (N->type == weave_section_node_type) @<Render section@> else if (N->type == weave_section_node_type) <<Render section>>
else if (N->type == weave_code_line_node_type) @<Render code line@> else if (N->type == weave_code_line_node_type) <<Render code line>>
else if (N->type == weave_function_usage_node_type) @<Render function usage@> else if (N->type == weave_function_usage_node_type) <<Render function usage>>
else if (N->type == weave_commentary_node_type) @<Render commentary@> else if (N->type == weave_commentary_node_type) <<Render commentary>>
else if (N->type == weave_carousel_slide_node_type) @<Render carousel slide@> else if (N->type == weave_carousel_slide_node_type) <<Render carousel slide>>
else if (N->type == weave_toc_node_type) @<Render toc@> else if (N->type == weave_toc_node_type) <<Render toc>>
else if (N->type == weave_toc_line_node_type) @<Render toc line@> else if (N->type == weave_toc_line_node_type) <<Render toc line>>
else if (N->type == weave_defn_node_type) @<Render defn@> else if (N->type == weave_defn_node_type) <<Render defn>>
else if (N->type == weave_source_code_node_type) @<Render source code@> else if (N->type == weave_source_code_node_type) <<Render source code>>
else if (N->type == weave_url_node_type) @<Render URL@> else if (N->type == weave_url_node_type) <<Render URL>>
else if (N->type == weave_footnote_cue_node_type) @<Render footnote cue@> else if (N->type == weave_footnote_cue_node_type) <<Render footnote cue>>
else if (N->type == weave_begin_footnote_text_node_type) @<Render footnote@> else if (N->type == weave_begin_footnote_text_node_type) <<Render footnote>>
else if (N->type == weave_display_line_node_type) @<Render display line@> else if (N->type == weave_display_line_node_type) <<Render display line>>
else if (N->type == weave_function_defn_node_type) @<Render function defn@> else if (N->type == weave_function_defn_node_type) <<Render function defn>>
else if (N->type == weave_item_node_type) @<Render item@> else if (N->type == weave_item_node_type) <<Render item>>
else if (N->type == weave_inline_node_type) @<Render inline@> else if (N->type == weave_inline_node_type) <<Render inline>>
else if (N->type == weave_locale_node_type) @<Render locale@> else if (N->type == weave_locale_node_type) <<Render locale>>
else if (N->type == weave_maths_node_type) @<Render maths@> else if (N->type == weave_maths_node_type) <<Render maths>>
else if (N->type == weave_linebreak_node_type) @<Render linebreak@> else if (N->type == weave_linebreak_node_type) <<Render linebreak>>
else internal_error("unable to render unknown node"); else internal_error("unable to render unknown node");
return TRUE; return TRUE;
} }
@<Render head@> = <<Render head>>=
weave_head_node *C = RETRIEVE_POINTER_weave_head_node(N->content); weave_head_node *C = RETRIEVE_POINTER_weave_head_node(N->content);
HTML::comment(OUT, C->banner); HTML::comment(OUT, C->banner);
@<Render header@> = <<Render header>>=
if (hrs->EPUB_flag == FALSE) { if (hrs->EPUB_flag == FALSE) {
weave_section_header_node *C = weave_section_header_node *C =
RETRIEVE_POINTER_weave_section_header_node(N->content); RETRIEVE_POINTER_weave_section_header_node(N->content);
@ -173,7 +173,7 @@ int HTMLFormat::render_visit(tree_node *N, void *state, int L) {
HTML_CLOSE("div"); HTML_CLOSE("div");
} }
@<Render footer@> = <<Render footer>>=
weave_section_footer_node *C = weave_section_footer_node *C =
RETRIEVE_POINTER_weave_section_footer_node(N->content); RETRIEVE_POINTER_weave_section_footer_node(N->content);
int count = 0; int count = 0;
@ -194,7 +194,7 @@ int HTMLFormat::render_visit(tree_node *N, void *state, int L) {
HTML_OPEN_WITH("nav", "role=\"progress\""); HTML_OPEN_WITH("nav", "role=\"progress\"");
HTML_OPEN_WITH("div", "class=\"progresscontainer\""); HTML_OPEN_WITH("div", "class=\"progresscontainer\"");
HTML_OPEN_WITH("ul", "class=\"progressbar\""); HTML_OPEN_WITH("ul", "class=\"progressbar\"");
@<Insert previous arrow@>; <<Insert previous arrow>>;
chapter *Ch; chapter *Ch;
LOOP_OVER_LINKED_LIST(Ch, chapter, hrs->wv->weave_web->chapters) { LOOP_OVER_LINKED_LIST(Ch, chapter, hrs->wv->weave_web->chapters) {
if (Ch->md->imported == FALSE) { if (Ch->md->imported == FALSE) {
@ -250,13 +250,13 @@ int HTMLFormat::render_visit(tree_node *N, void *state, int L) {
} }
} }
} }
@<Insert next arrow@>; <<Insert next arrow>>;
HTML_CLOSE("ul"); HTML_CLOSE("ul");
HTML_CLOSE("div"); HTML_CLOSE("div");
HTML_CLOSE("nav"); HTML_CLOSE("nav");
} }
@<Insert previous arrow@> = <<Insert previous arrow>>=
if (prev_S) HTML_OPEN_WITH("li", "class=\"progressprev\"") if (prev_S) HTML_OPEN_WITH("li", "class=\"progressprev\"")
else HTML_OPEN_WITH("li", "class=\"progressprevoff\""); else HTML_OPEN_WITH("li", "class=\"progressprevoff\"");
TEMPORARY_TEXT(TEMP) TEMPORARY_TEXT(TEMP)
@ -267,7 +267,7 @@ int HTMLFormat::render_visit(tree_node *N, void *state, int L) {
DISCARD_TEXT(TEMP) DISCARD_TEXT(TEMP)
HTML_CLOSE("li"); HTML_CLOSE("li");
@<Insert next arrow@> = <<Insert next arrow>>=
if (next_S) HTML_OPEN_WITH("li", "class=\"progressnext\"") if (next_S) HTML_OPEN_WITH("li", "class=\"progressnext\"")
else HTML_OPEN_WITH("li", "class=\"progressnextoff\""); else HTML_OPEN_WITH("li", "class=\"progressnextoff\"");
TEMPORARY_TEXT(TEMP) TEMPORARY_TEXT(TEMP)
@ -278,43 +278,43 @@ int HTMLFormat::render_visit(tree_node *N, void *state, int L) {
DISCARD_TEXT(TEMP) DISCARD_TEXT(TEMP)
HTML_CLOSE("li"); HTML_CLOSE("li");
@<Render tail@> = <<Render tail>>=
weave_tail_node *C = RETRIEVE_POINTER_weave_tail_node(N->content); weave_tail_node *C = RETRIEVE_POINTER_weave_tail_node(N->content);
HTML::comment(OUT, C->rennab); HTML::comment(OUT, C->rennab);
@<Render purpose@> = <<Render purpose>>=
weave_section_purpose_node *C = weave_section_purpose_node *C =
RETRIEVE_POINTER_weave_section_purpose_node(N->content); RETRIEVE_POINTER_weave_section_purpose_node(N->content);
HTML_OPEN_WITH("p", "class=\"purpose\""); HTML_OPEN_WITH("p", "class=\"purpose\"");
HTMLFormat::escape_text(OUT, C->purpose); HTMLFormat::escape_text(OUT, C->purpose);
HTML_CLOSE("p"); WRITE("\n"); HTML_CLOSE("p"); WRITE("\n");
@<Render subheading@> = <<Render subheading>>=
weave_subheading_node *C = RETRIEVE_POINTER_weave_subheading_node(N->content); weave_subheading_node *C = RETRIEVE_POINTER_weave_subheading_node(N->content);
HTML_OPEN("h3"); HTML_OPEN("h3");
HTMLFormat::escape_text(OUT, C->text); HTMLFormat::escape_text(OUT, C->text);
HTML_CLOSE("h3"); WRITE("\n"); HTML_CLOSE("h3"); WRITE("\n");
@<Render bar@> = <<Render bar>>=
HTML::hr(OUT, NULL); HTML::hr(OUT, NULL);
@<Render paragraph heading@> = <<Render paragraph heading>>=
weave_paragraph_heading_node *C = weave_paragraph_heading_node *C =
RETRIEVE_POINTER_weave_paragraph_heading_node(N->content); RETRIEVE_POINTER_weave_paragraph_heading_node(N->content);
paragraph *P = C->para; paragraph *P = C->para;
if (P == NULL) internal_error("no para"); if (P == NULL) internal_error("no para");
if (N->child == NULL) { if (N->child == NULL) {
paragraph *first_in_para = P; paragraph *first_in_para = P;
@<If no para number yet, render a p just to hold this@>; <<If no para number yet, render a p just to hold this>>;
} }
@<Render endnote@> = <<Render endnote>>=
HTML_OPEN("li"); HTML_OPEN("li");
@<Recurse the renderer through children nodes@>; <<Recurse the renderer through children nodes>>;
HTML_CLOSE("li"); HTML_CLOSE("li");
return FALSE; return FALSE;
@<Render figure@> = <<Render figure>>=
weave_figure_node *C = RETRIEVE_POINTER_weave_figure_node(N->content); weave_figure_node *C = RETRIEVE_POINTER_weave_figure_node(N->content);
filename *F = Filenames::in( filename *F = Filenames::in(
Pathnames::down(hrs->wv->weave_web->md->path_to_web, I"Figures"), Pathnames::down(hrs->wv->weave_web->md->path_to_web, I"Figures"),
@ -327,7 +327,7 @@ int HTMLFormat::render_visit(tree_node *N, void *state, int L) {
HTML_CLOSE("p"); HTML_CLOSE("p");
WRITE("\n"); WRITE("\n");
@<Render extract@> = <<Render extract>>=
weave_extract_node *C = RETRIEVE_POINTER_weave_extract_node(N->content); weave_extract_node *C = RETRIEVE_POINTER_weave_extract_node(N->content);
filename *F = Filenames::in( filename *F = Filenames::in(
Pathnames::down(hrs->wv->weave_web->md->path_to_web, I"HTML"), Pathnames::down(hrs->wv->weave_web->md->path_to_web, I"HTML"),
@ -348,7 +348,7 @@ int HTMLFormat::render_visit(tree_node *N, void *state, int L) {
HTML_CLOSE("div"); HTML_CLOSE("div");
WRITE("\n"); WRITE("\n");
@<Render audio clip@> = <<Render audio clip>>=
weave_audio_node *C = RETRIEVE_POINTER_weave_audio_node(N->content); weave_audio_node *C = RETRIEVE_POINTER_weave_audio_node(N->content);
filename *F = Filenames::in( filename *F = Filenames::in(
Pathnames::down(hrs->wv->weave_web->md->path_to_web, I"Audio"), Pathnames::down(hrs->wv->weave_web->md->path_to_web, I"Audio"),
@ -363,7 +363,7 @@ int HTMLFormat::render_visit(tree_node *N, void *state, int L) {
HTML_CLOSE("p"); HTML_CLOSE("p");
WRITE("\n"); WRITE("\n");
@<Render video clip@> = <<Render video clip>>=
weave_video_node *C = RETRIEVE_POINTER_weave_video_node(N->content); weave_video_node *C = RETRIEVE_POINTER_weave_video_node(N->content);
filename *F = Filenames::in( filename *F = Filenames::in(
Pathnames::down(hrs->wv->weave_web->md->path_to_web, I"Video"), Pathnames::down(hrs->wv->weave_web->md->path_to_web, I"Video"),
@ -385,7 +385,7 @@ int HTMLFormat::render_visit(tree_node *N, void *state, int L) {
HTML_CLOSE("p"); HTML_CLOSE("p");
WRITE("\n"); WRITE("\n");
@<Render download@> = <<Render download>>=
weave_download_node *C = RETRIEVE_POINTER_weave_download_node(N->content); weave_download_node *C = RETRIEVE_POINTER_weave_download_node(N->content);
pathname *P = Pathnames::down(hrs->wv->weave_web->md->path_to_web, I"Downloads"); pathname *P = Pathnames::down(hrs->wv->weave_web->md->path_to_web, I"Downloads");
filename *F = Filenames::in(P, C->download_name); filename *F = Filenames::in(P, C->download_name);
@ -404,7 +404,7 @@ int HTMLFormat::render_visit(tree_node *N, void *state, int L) {
Pathnames::relative_URL(url, Filenames::up(hrs->wv->weave_to), TOP); Pathnames::relative_URL(url, Filenames::up(hrs->wv->weave_to), TOP);
WRITE_TO(url, "%S", Filenames::get_leafname(F)); WRITE_TO(url, "%S", Filenames::get_leafname(F));
int N = Filenames::size(F); int N = Filenames::size(F);
if (N > 0) @<Describe the file size@> if (N > 0) <<Describe the file size>>
else Main::error_in_web(I"Download file missing or empty", else Main::error_in_web(I"Download file missing or empty",
hrs->wv->current_weave_line); hrs->wv->current_weave_line);
filename *D = Filenames::from_text(C->download_name); filename *D = Filenames::from_text(C->download_name);
@ -419,7 +419,7 @@ int HTMLFormat::render_visit(tree_node *N, void *state, int L) {
DISCARD_TEXT(size) DISCARD_TEXT(size)
} }
@<Describe the file size@> = <<Describe the file size>>=
WRITE_TO(size, " ("); WRITE_TO(size, " (");
if (Str::len(C->filetype) > 0) WRITE_TO(size, "%S, ", C->filetype); if (Str::len(C->filetype) > 0) WRITE_TO(size, "%S, ", C->filetype);
int x = 0, y = 0; int x = 0, y = 0;
@ -433,7 +433,7 @@ int HTMLFormat::render_visit(tree_node *N, void *state, int L) {
WRITE_TO(size, "%S", unit); WRITE_TO(size, "%S", unit);
WRITE_TO(size, ")"); WRITE_TO(size, ")");
@<Render material@> = <<Render material>>=
weave_material_node *C = RETRIEVE_POINTER_weave_material_node(N->content); weave_material_node *C = RETRIEVE_POINTER_weave_material_node(N->content);
paragraph *first_in_para = NULL; paragraph *first_in_para = NULL;
if ((N == N->parent->child) && if ((N == N->parent->child) &&
@ -443,20 +443,20 @@ int HTMLFormat::render_visit(tree_node *N, void *state, int L) {
first_in_para = PC->para; first_in_para = PC->para;
} }
if (C->material_type == COMMENTARY_MATERIAL) if (C->material_type == COMMENTARY_MATERIAL)
@<Deal with a commentary material node@> <<Deal with a commentary material node>>
else if (C->material_type == CODE_MATERIAL) else if (C->material_type == CODE_MATERIAL)
@<Deal with a code material node@> <<Deal with a code material node>>
else if (C->material_type == FOOTNOTES_MATERIAL) else if (C->material_type == FOOTNOTES_MATERIAL)
@<Deal with a footnotes material node@> <<Deal with a footnotes material node>>
else if (C->material_type == ENDNOTES_MATERIAL) else if (C->material_type == ENDNOTES_MATERIAL)
@<Deal with a endnotes material node@> <<Deal with a endnotes material node>>
else if (C->material_type == MACRO_MATERIAL) else if (C->material_type == MACRO_MATERIAL)
@<Deal with a macro material node@> <<Deal with a macro material node>>
else if (C->material_type == DEFINITION_MATERIAL) else if (C->material_type == DEFINITION_MATERIAL)
@<Deal with a definition material node@>; <<Deal with a definition material node>>;
return FALSE; return FALSE;
@<If no para number yet, render a p just to hold this@> = <<If no para number yet, render a p just to hold this>>=
if (first_in_para) { if (first_in_para) {
HTML_OPEN_WITH("p", "class=\"commentary firstcommentary\""); HTML_OPEN_WITH("p", "class=\"commentary firstcommentary\"");
HTMLFormat::paragraph_number(OUT, first_in_para); HTMLFormat::paragraph_number(OUT, first_in_para);
@ -464,19 +464,19 @@ int HTMLFormat::render_visit(tree_node *N, void *state, int L) {
first_in_para = NULL; first_in_para = NULL;
} }
@<Deal with a commentary material node@> = <<Deal with a commentary material node>>=
int item_depth = 0; int item_depth = 0;
for (tree_node *M = N->child; M; M = M->next) { for (tree_node *M = N->child; M; M = M->next) {
if (M->type == weave_item_node_type) { if (M->type == weave_item_node_type) {
@<If no para number yet, render a p just to hold this@>; <<If no para number yet, render a p just to hold this>>;
weave_item_node *C = RETRIEVE_POINTER_weave_item_node(M->content); weave_item_node *C = RETRIEVE_POINTER_weave_item_node(M->content);
HTMLFormat::go_to_depth(hrs, item_depth, C->depth); HTMLFormat::go_to_depth(hrs, item_depth, C->depth);
item_depth = C->depth; item_depth = C->depth;
Trees::traverse_from(M, &HTMLFormat::render_visit, (void *) hrs, L+1); Trees::traverse_from(M, &HTMLFormat::render_visit, (void *) hrs, L+1);
continue; continue;
} }
if (HTMLFormat::interior_material(M)) @<Render a run of interior matter@>; if (HTMLFormat::interior_material(M)) <<Render a run of interior matter>>;
@<If no para number yet, render a p just to hold this@>; <<If no para number yet, render a p just to hold this>>;
if (item_depth > 0) { if (item_depth > 0) {
HTMLFormat::go_to_depth(hrs, item_depth, 0); HTMLFormat::go_to_depth(hrs, item_depth, 0);
item_depth = 0; item_depth = 0;
@ -489,7 +489,7 @@ int HTMLFormat::render_visit(tree_node *N, void *state, int L) {
item_depth = 0; item_depth = 0;
} }
@<Render a run of interior matter@> = <<Render a run of interior matter>>=
if (first_in_para) { if (first_in_para) {
HTML_OPEN_WITH("p", "class=\"commentary firstcommentary\""); HTML_OPEN_WITH("p", "class=\"commentary firstcommentary\"");
HTMLFormat::paragraph_number(OUT, first_in_para); HTMLFormat::paragraph_number(OUT, first_in_para);
@ -505,8 +505,8 @@ int HTMLFormat::render_visit(tree_node *N, void *state, int L) {
if (item_depth == 0) { HTML_CLOSE("p"); WRITE("\n"); } if (item_depth == 0) { HTML_CLOSE("p"); WRITE("\n"); }
continue; continue;
@<Deal with a code material node@> = <<Deal with a code material node>>=
@<If no para number yet, render a p just to hold this@>; <<If no para number yet, render a p just to hold this>>;
if (C->styling) { if (C->styling) {
TEMPORARY_TEXT(csname) TEMPORARY_TEXT(csname)
WRITE_TO(csname, "%S-Colours", C->styling->language_name); WRITE_TO(csname, "%S-Colours", C->styling->language_name);
@ -520,7 +520,7 @@ int HTMLFormat::render_visit(tree_node *N, void *state, int L) {
else WRITE_TO(cl, "displayed-code"); else WRITE_TO(cl, "displayed-code");
WRITE("<pre class=\"%S all-displayed-code code-font\">\n", cl); WRITE("<pre class=\"%S all-displayed-code code-font\">\n", cl);
DISCARD_TEXT(cl) DISCARD_TEXT(cl)
@<Recurse the renderer through children nodes@>; <<Recurse the renderer through children nodes>>;
HTML_CLOSE("pre"); WRITE("\n"); HTML_CLOSE("pre"); WRITE("\n");
if (Str::len(C->endnote) > 0) { if (Str::len(C->endnote) > 0) {
HTML_OPEN_WITH("ul", "class=\"endnotetexts\""); HTML_OPEN_WITH("ul", "class=\"endnotetexts\"");
@ -530,39 +530,39 @@ int HTMLFormat::render_visit(tree_node *N, void *state, int L) {
HTML_CLOSE("ul"); WRITE("\n"); HTML_CLOSE("ul"); WRITE("\n");
} }
@<Deal with a footnotes material node@> = <<Deal with a footnotes material node>>=
@<If no para number yet, render a p just to hold this@>; <<If no para number yet, render a p just to hold this>>;
HTML_OPEN_WITH("ul", "class=\"footnotetexts\""); HTML_OPEN_WITH("ul", "class=\"footnotetexts\"");
@<Recurse the renderer through children nodes@>; <<Recurse the renderer through children nodes>>;
HTML_CLOSE("ul"); WRITE("\n"); HTML_CLOSE("ul"); WRITE("\n");
@<Deal with a endnotes material node@> = <<Deal with a endnotes material node>>=
@<If no para number yet, render a p just to hold this@>; <<If no para number yet, render a p just to hold this>>;
HTML_OPEN_WITH("ul", "class=\"endnotetexts\""); HTML_OPEN_WITH("ul", "class=\"endnotetexts\"");
@<Recurse the renderer through children nodes@>; <<Recurse the renderer through children nodes>>;
HTML_CLOSE("ul"); WRITE("\n"); HTML_CLOSE("ul"); WRITE("\n");
@<Deal with a macro material node@> = <<Deal with a macro material node>>=
if (first_in_para) { if (first_in_para) {
HTML_OPEN_WITH("p", "class=\"commentary firstcommentary\""); HTML_OPEN_WITH("p", "class=\"commentary firstcommentary\"");
HTMLFormat::paragraph_number(OUT, first_in_para); HTMLFormat::paragraph_number(OUT, first_in_para);
} else { } else {
HTML_OPEN_WITH("p", "class=\"commentary\""); HTML_OPEN_WITH("p", "class=\"commentary\"");
} }
@<Recurse the renderer through children nodes@>; <<Recurse the renderer through children nodes>>;
HTML_CLOSE("p"); WRITE("\n"); HTML_CLOSE("p"); WRITE("\n");
@<Deal with a definition material node@> = <<Deal with a definition material node>>=
@<If no para number yet, render a p just to hold this@>; <<If no para number yet, render a p just to hold this>>;
HTML_OPEN_WITH("pre", "class=\"definitions code-font\""); HTML_OPEN_WITH("pre", "class=\"definitions code-font\"");
@<Recurse the renderer through children nodes@>; <<Recurse the renderer through children nodes>>;
HTML_CLOSE("pre"); WRITE("\n"); HTML_CLOSE("pre"); WRITE("\n");
@ This has to embed some Internet-sourced content. |service| @ This has to embed some Internet-sourced content. [[service]]
here is something like |YouTube| or |Soundcloud|, and |ID| is whatever code here is something like [[YouTube]] or [[Soundcloud]], and [[ID]] is whatever code
that service uses to identify the video/audio in question. that service uses to identify the video/audio in question.
@<Render embed@> = <<Render embed>>=
weave_embed_node *C = RETRIEVE_POINTER_weave_embed_node(N->content); weave_embed_node *C = RETRIEVE_POINTER_weave_embed_node(N->content);
text_stream *CH = I"405"; text_stream *CH = I"405";
text_stream *CW = I"720"; text_stream *CW = I"720";
@ -585,7 +585,7 @@ that service uses to identify the video/audio in question.
WRITE("\n"); WRITE("\n");
} }
@<Render pmac@> = <<Render pmac>>=
weave_pmac_node *C = RETRIEVE_POINTER_weave_pmac_node(N->content); weave_pmac_node *C = RETRIEVE_POINTER_weave_pmac_node(N->content);
paragraph *P = C->pmac->defining_paragraph; paragraph *P = C->pmac->defining_paragraph;
HTML_OPEN_WITH("span", "class=\"named-paragraph-container code-font\""); HTML_OPEN_WITH("span", "class=\"named-paragraph-container code-font\"");
@ -610,19 +610,19 @@ that service uses to identify the video/audio in question.
HTMLFormat::change_colour(OUT, -1, hrs->colours); HTMLFormat::change_colour(OUT, -1, hrs->colours);
} }
@<Render vskip@> = <<Render vskip>>=
WRITE("\n"); WRITE("\n");
@<Render section@> = <<Render section>>=
weave_section_node *C = RETRIEVE_POINTER_weave_section_node(N->content); weave_section_node *C = RETRIEVE_POINTER_weave_section_node(N->content);
LOG("It was %d\n", C->allocation_id); LOG("It was %d\n", C->allocation_id);
@<Render code line@> = <<Render code line>>=
@<Recurse the renderer through children nodes@>; <<Recurse the renderer through children nodes>>;
WRITE("\n"); WRITE("\n");
return FALSE; return FALSE;
@<Render function usage@> = <<Render function usage>>=
weave_function_usage_node *C = RETRIEVE_POINTER_weave_function_usage_node(N->content); weave_function_usage_node *C = RETRIEVE_POINTER_weave_function_usage_node(N->content);
HTML::begin_link_with_class(OUT, I"function-link", C->url); HTML::begin_link_with_class(OUT, I"function-link", C->url);
HTMLFormat::change_colour(OUT, FUNCTION_COLOUR, hrs->colours); HTMLFormat::change_colour(OUT, FUNCTION_COLOUR, hrs->colours);
@ -630,7 +630,7 @@ that service uses to identify the video/audio in question.
HTMLFormat::change_colour(OUT, -1, hrs->colours); HTMLFormat::change_colour(OUT, -1, hrs->colours);
HTML::end_link(OUT); HTML::end_link(OUT);
@<Render commentary@> = <<Render commentary>>=
weave_commentary_node *C = RETRIEVE_POINTER_weave_commentary_node(N->content); weave_commentary_node *C = RETRIEVE_POINTER_weave_commentary_node(N->content);
if (C->in_code) HTMLFormat::change_colour(OUT, COMMENT_COLOUR, hrs->colours); if (C->in_code) HTMLFormat::change_colour(OUT, COMMENT_COLOUR, hrs->colours);
for (int i=0; i < Str::len(C->text); i++) { for (int i=0; i < Str::len(C->text); i++) {
@ -643,14 +643,14 @@ that service uses to identify the video/audio in question.
WRITE("&mdash;"); i++; WRITE("&mdash;"); i++;
} else if ((Str::get_at(C->text, i) == ' ') && (Str::get_at(C->text, i+1) == '-') && } else if ((Str::get_at(C->text, i) == ' ') && (Str::get_at(C->text, i+1) == '-') &&
(Str::get_at(C->text, i+2) == '-') && (Str::get_at(C->text, i+2) == '-') &&
((Str::get_at(C->text, i+3) == ' ') || (Str::get_at(C->text, i+3) == '\n') || ((Str::get_at(C->text, i+3) == ' ') [[| (Str::get_at(C->text, i+3) == '\n') |]]
(Str::get_at(C->text, i+3) == 0))) { (Str::get_at(C->text, i+3) == 0))) {
WRITE(" &mdash;"); i+=2; WRITE(" &mdash;"); i+=2;
} else PUT(Str::get_at(C->text, i)); } else PUT(Str::get_at(C->text, i));
} }
if (C->in_code) HTMLFormat::change_colour(OUT, -1, hrs->colours); if (C->in_code) HTMLFormat::change_colour(OUT, -1, hrs->colours);
@<Render carousel slide@> = <<Render carousel slide>>=
weave_carousel_slide_node *C = RETRIEVE_POINTER_weave_carousel_slide_node(N->content); weave_carousel_slide_node *C = RETRIEVE_POINTER_weave_carousel_slide_node(N->content);
Swarm::ensure_plugin(hrs->wv, I"Carousel"); Swarm::ensure_plugin(hrs->wv, I"Carousel");
TEMPORARY_TEXT(carousel_id) TEMPORARY_TEXT(carousel_id)
@ -682,7 +682,7 @@ that service uses to identify the video/audio in question.
else WRITE(" style=\"display: none;\""); else WRITE(" style=\"display: none;\"");
WRITE(">\n"); WRITE(">\n");
if (C->caption_command == CAROUSEL_ABOVE_CMD) { if (C->caption_command == CAROUSEL_ABOVE_CMD) {
@<Place caption here@>; <<Place caption here>>;
WRITE("<div class=\"%S\">%d / %d</div>\n", WRITE("<div class=\"%S\">%d / %d</div>\n",
slide_count_class, hrs->slide_number, hrs->slide_of); slide_count_class, hrs->slide_number, hrs->slide_of);
} else { } else {
@ -690,9 +690,9 @@ that service uses to identify the video/audio in question.
slide_count_class, hrs->slide_number, hrs->slide_of); slide_count_class, hrs->slide_number, hrs->slide_of);
} }
WRITE("<div class=\"carousel-content\">"); WRITE("<div class=\"carousel-content\">");
@<Recurse the renderer through children nodes@>; <<Recurse the renderer through children nodes>>;
WRITE("</div>\n"); WRITE("</div>\n");
if (C->caption_command != CAROUSEL_ABOVE_CMD) @<Place caption here@>; if (C->caption_command != CAROUSEL_ABOVE_CMD) <<Place caption here>>;
WRITE("</div>\n"); WRITE("</div>\n");
if (hrs->slide_number == hrs->slide_of) { if (hrs->slide_number == hrs->slide_of) {
WRITE("<a class=\"carousel-prev-button\" "); WRITE("<a class=\"carousel-prev-button\" ");
@ -723,11 +723,11 @@ that service uses to identify the video/audio in question.
DISCARD_TEXT(carousel_dots_id) DISCARD_TEXT(carousel_dots_id)
return FALSE; return FALSE;
@<Place caption here@> = <<Place caption here>>=
if (C->caption_command != CAROUSEL_UNCAPTIONED_CMD) if (C->caption_command != CAROUSEL_UNCAPTIONED_CMD)
WRITE("<div class=\"%S\">%S</div>\n", caption_class, C->caption); WRITE("<div class=\"%S\">%S</div>\n", caption_class, C->caption);
@<Render toc@> = <<Render toc>>=
HTML_OPEN_WITH("ul", "class=\"toc\""); HTML_OPEN_WITH("ul", "class=\"toc\"");
for (tree_node *M = N->child; M; M = M->next) { for (tree_node *M = N->child; M; M = M->next) {
HTML_OPEN("li"); HTML_OPEN("li");
@ -739,7 +739,7 @@ that service uses to identify the video/audio in question.
WRITE("\n"); WRITE("\n");
return FALSE; return FALSE;
@<Render toc line@> = <<Render toc line>>=
weave_toc_line_node *C = RETRIEVE_POINTER_weave_toc_line_node(N->content); weave_toc_line_node *C = RETRIEVE_POINTER_weave_toc_line_node(N->content);
TEMPORARY_TEXT(TEMP) TEMPORARY_TEXT(TEMP)
Colonies::paragraph_URL(TEMP, C->para, hrs->wv->weave_to); Colonies::paragraph_URL(TEMP, C->para, hrs->wv->weave_to);
@ -750,14 +750,14 @@ that service uses to identify the video/audio in question.
WRITE(". %S", C->text2); WRITE(". %S", C->text2);
HTML::end_link(OUT); HTML::end_link(OUT);
@<Render defn@> = <<Render defn>>=
weave_defn_node *C = RETRIEVE_POINTER_weave_defn_node(N->content); weave_defn_node *C = RETRIEVE_POINTER_weave_defn_node(N->content);
HTML_OPEN_WITH("span", "class=\"definition-keyword\""); HTML_OPEN_WITH("span", "class=\"definition-keyword\"");
WRITE("%S", C->keyword); WRITE("%S", C->keyword);
HTML_CLOSE("span"); HTML_CLOSE("span");
WRITE(" "); WRITE(" ");
@<Render source code@> = <<Render source code>>=
weave_source_code_node *C = RETRIEVE_POINTER_weave_source_code_node(N->content); weave_source_code_node *C = RETRIEVE_POINTER_weave_source_code_node(N->content);
int starts = FALSE; int starts = FALSE;
if (N == N->parent->child) starts = TRUE; if (N == N->parent->child) starts = TRUE;
@ -776,13 +776,13 @@ that service uses to identify the video/audio in question.
} }
if (current_colour >= 0) HTMLFormat::change_colour(OUT, -1, hrs->colours); if (current_colour >= 0) HTMLFormat::change_colour(OUT, -1, hrs->colours);
@<Render URL@> = <<Render URL>>=
weave_url_node *C = RETRIEVE_POINTER_weave_url_node(N->content); weave_url_node *C = RETRIEVE_POINTER_weave_url_node(N->content);
HTML::begin_link_with_class(OUT, (C->external)?I"external":I"internal", C->url); HTML::begin_link_with_class(OUT, (C->external)?I"external":I"internal", C->url);
WRITE("%S", C->content); WRITE("%S", C->content);
HTML::end_link(OUT); HTML::end_link(OUT);
@<Render footnote cue@> = <<Render footnote cue>>=
weave_footnote_cue_node *C = RETRIEVE_POINTER_weave_footnote_cue_node(N->content); weave_footnote_cue_node *C = RETRIEVE_POINTER_weave_footnote_cue_node(N->content);
text_stream *fn_plugin_name = hrs->wv->pattern->footnotes_plugin; text_stream *fn_plugin_name = hrs->wv->pattern->footnotes_plugin;
if (Str::len(fn_plugin_name) > 0) if (Str::len(fn_plugin_name) > 0)
@ -796,7 +796,7 @@ that service uses to identify the video/audio in question.
WRITE("<sup id=\"fnref:%S\"><a href=\"#fn:%S\" rel=\"footnote\">%S</a></sup>", WRITE("<sup id=\"fnref:%S\"><a href=\"#fn:%S\" rel=\"footnote\">%S</a></sup>",
C->cue_text, C->cue_text, C->cue_text); C->cue_text, C->cue_text, C->cue_text);
@<Render footnote@> = <<Render footnote>>=
weave_begin_footnote_text_node *C = weave_begin_footnote_text_node *C =
RETRIEVE_POINTER_weave_begin_footnote_text_node(N->content); RETRIEVE_POINTER_weave_begin_footnote_text_node(N->content);
text_stream *fn_plugin_name = hrs->wv->pattern->footnotes_plugin; text_stream *fn_plugin_name = hrs->wv->pattern->footnotes_plugin;
@ -808,7 +808,7 @@ that service uses to identify the video/audio in question.
else else
WRITE("<li class=\"footnote\" id=\"fn:%S\"><p class=\"inwebfootnote\">", WRITE("<li class=\"footnote\" id=\"fn:%S\"><p class=\"inwebfootnote\">",
C->cue_text); C->cue_text);
@<Recurse the renderer through children nodes@>; <<Recurse the renderer through children nodes>>;
if (hrs->EPUB_flag) if (hrs->EPUB_flag)
WRITE("<a href=\"#fnref%S\"> (return to text)</a></p></li>", WRITE("<a href=\"#fnref%S\"> (return to text)</a></p></li>",
C->cue_text); C->cue_text);
@ -817,7 +817,7 @@ that service uses to identify the video/audio in question.
C->cue_text); C->cue_text);
return FALSE; return FALSE;
@<Render display line@> = <<Render display line>>=
weave_display_line_node *C = weave_display_line_node *C =
RETRIEVE_POINTER_weave_display_line_node(N->content); RETRIEVE_POINTER_weave_display_line_node(N->content);
HTML_OPEN("blockquote"); WRITE("\n"); INDENT; HTML_OPEN("blockquote"); WRITE("\n"); INDENT;
@ -826,7 +826,7 @@ that service uses to identify the video/audio in question.
HTML_CLOSE("p"); HTML_CLOSE("p");
OUTDENT; HTML_CLOSE("blockquote"); WRITE("\n"); OUTDENT; HTML_CLOSE("blockquote"); WRITE("\n");
@<Render function defn@> = <<Render function defn>>=
weave_function_defn_node *C = weave_function_defn_node *C =
RETRIEVE_POINTER_weave_function_defn_node(N->content); RETRIEVE_POINTER_weave_function_defn_node(N->content);
if ((Functions::used_elsewhere(C->fn)) && (hrs->EPUB_flag == FALSE)) { if ((Functions::used_elsewhere(C->fn)) && (hrs->EPUB_flag == FALSE)) {
@ -846,7 +846,7 @@ that service uses to identify the video/audio in question.
HTMLFormat::change_colour(OUT, -1, hrs->colours); HTMLFormat::change_colour(OUT, -1, hrs->colours);
HTML_CLOSE("span"); HTML_CLOSE("span");
WRITE(":<br/>"); WRITE(":<br/>");
@<Recurse the renderer through children nodes@>; <<Recurse the renderer through children nodes>>;
HTMLFormat::change_colour(OUT, -1, hrs->colours); HTMLFormat::change_colour(OUT, -1, hrs->colours);
WRITE("</button>"); WRITE("</button>");
hrs->popup_counter++; hrs->popup_counter++;
@ -857,23 +857,23 @@ that service uses to identify the video/audio in question.
} }
return FALSE; return FALSE;
@<Render item@> = <<Render item>>=
weave_item_node *C = RETRIEVE_POINTER_weave_item_node(N->content); weave_item_node *C = RETRIEVE_POINTER_weave_item_node(N->content);
if (Str::eq(C->label, I"*")) WRITE("&#9679; "); if (Str::eq(C->label, I"*")) WRITE("&#9679; ");
else if (Str::len(C->label) > 0) WRITE("(%S) ", C->label); else if (Str::len(C->label) > 0) WRITE("(%S) ", C->label);
else WRITE(" "); else WRITE(" ");
@<Render verbatim@> = <<Render verbatim>>=
weave_verbatim_node *C = RETRIEVE_POINTER_weave_verbatim_node(N->content); weave_verbatim_node *C = RETRIEVE_POINTER_weave_verbatim_node(N->content);
WRITE("%S", C->content); WRITE("%S", C->content);
@<Render inline@> = <<Render inline>>=
HTML_OPEN_WITH("span", "class=\"extract\""); HTML_OPEN_WITH("span", "class=\"extract\"");
@<Recurse the renderer through children nodes@>; <<Recurse the renderer through children nodes>>;
HTML_CLOSE("span"); HTML_CLOSE("span");
return FALSE; return FALSE;
@<Render locale@> = <<Render locale>>=
weave_locale_node *C = RETRIEVE_POINTER_weave_locale_node(N->content); weave_locale_node *C = RETRIEVE_POINTER_weave_locale_node(N->content);
TEMPORARY_TEXT(TEMP) TEMPORARY_TEXT(TEMP)
Colonies::paragraph_URL(TEMP, C->par1, hrs->wv->weave_to); Colonies::paragraph_URL(TEMP, C->par1, hrs->wv->weave_to);
@ -885,7 +885,7 @@ that service uses to identify the video/audio in question.
if (C->par2) WRITE("-%S", C->par2->paragraph_number); if (C->par2) WRITE("-%S", C->par2->paragraph_number);
HTML::end_link(OUT); HTML::end_link(OUT);
@<Render maths@> = <<Render maths>>=
weave_maths_node *C = RETRIEVE_POINTER_weave_maths_node(N->content); weave_maths_node *C = RETRIEVE_POINTER_weave_maths_node(N->content);
text_stream *plugin_name = hrs->wv->pattern->mathematics_plugin; text_stream *plugin_name = hrs->wv->pattern->mathematics_plugin;
if ((Str::len(plugin_name) == 0) || (hrs->EPUB_flag)) { if ((Str::len(plugin_name) == 0) || (hrs->EPUB_flag)) {
@ -900,20 +900,20 @@ that service uses to identify the video/audio in question.
if (C->displayed) WRITE("$$"); else WRITE("\\)"); if (C->displayed) WRITE("$$"); else WRITE("\\)");
} }
@<Render linebreak@> = <<Render linebreak>>=
WRITE("<br/>"); WRITE("<br/>");
@<Render nothing@> = <<Render nothing>>=
; ;
@<Recurse the renderer through children nodes@> = <<Recurse the renderer through children nodes>>=
for (tree_node *M = N->child; M; M = M->next) for (tree_node *M = N->child; M; M = M->next)
Trees::traverse_from(M, &HTMLFormat::render_visit, (void *) hrs, L+1); Trees::traverse_from(M, &HTMLFormat::render_visit, (void *) hrs, L+1);
@ These are the nodes falling under a commentary material node which we will @ These are the nodes falling under a commentary material node which we will
amalgamate into a single HTML paragraph: amalgamate into a single HTML paragraph:
= <<*>>=
int HTMLFormat::interior_material(tree_node *N) { int HTMLFormat::interior_material(tree_node *N) {
if (N->type == weave_commentary_node_type) return TRUE; if (N->type == weave_commentary_node_type) return TRUE;
if (N->type == weave_url_node_type) return TRUE; if (N->type == weave_url_node_type) return TRUE;
@ -927,7 +927,7 @@ int HTMLFormat::interior_material(tree_node *N) {
@ Depth 1 means "inside a list entry"; depth 2, "inside an entry of a list @ Depth 1 means "inside a list entry"; depth 2, "inside an entry of a list
which is itself inside a list entry"; and so on. which is itself inside a list entry"; and so on.
= <<*>>=
void HTMLFormat::go_to_depth(HTML_render_state *hrs, int from_depth, int to_depth) { void HTMLFormat::go_to_depth(HTML_render_state *hrs, int from_depth, int to_depth) {
text_stream *OUT = hrs->OUT; text_stream *OUT = hrs->OUT;
if (from_depth == to_depth) { if (from_depth == to_depth) {
@ -945,7 +945,7 @@ void HTMLFormat::go_to_depth(HTML_render_state *hrs, int from_depth, int to_dept
if (to_depth > 0) HTML_OPEN("li"); if (to_depth > 0) HTML_OPEN("li");
} }
@ = <<*>>=
void HTMLFormat::paragraph_number(text_stream *OUT, paragraph *P) { void HTMLFormat::paragraph_number(text_stream *OUT, paragraph *P) {
TEMPORARY_TEXT(TEMP) TEMPORARY_TEXT(TEMP)
Colonies::paragraph_anchor(TEMP, P); Colonies::paragraph_anchor(TEMP, P);
@ -960,7 +960,7 @@ void HTMLFormat::paragraph_number(text_stream *OUT, paragraph *P) {
} }
} }
@ = <<*>>=
void HTMLFormat::change_colour(text_stream *OUT, int col, colour_scheme *cs) { void HTMLFormat::change_colour(text_stream *OUT, int col, colour_scheme *cs) {
if (col == -1) { if (col == -1) {
HTML_CLOSE("span"); HTML_CLOSE("span");
@ -984,7 +984,7 @@ void HTMLFormat::change_colour(text_stream *OUT, int col, colour_scheme *cs) {
} }
} }
@ = <<*>>=
void HTMLFormat::escape_text(text_stream *OUT, text_stream *id) { void HTMLFormat::escape_text(text_stream *OUT, text_stream *id) {
for (int i=0; i < Str::len(id); i++) { for (int i=0; i < Str::len(id); i++) {
if (Str::get_at(id, i) == '&') WRITE("&amp;"); if (Str::get_at(id, i) == '&') WRITE("&amp;");
@ -994,9 +994,9 @@ void HTMLFormat::escape_text(text_stream *OUT, text_stream *id) {
} }
} }
@h EPUB-only methods. @ \section{EPUB-only methods.}
= <<*>>=
int HTMLFormat::begin_weaving_EPUB(weave_format *wf, web *W, weave_pattern *pattern) { int HTMLFormat::begin_weaving_EPUB(weave_format *wf, web *W, weave_pattern *pattern) {
TEMPORARY_TEXT(T) TEMPORARY_TEXT(T)
WRITE_TO(T, "%S", Bibliographic::get_datum(W->md, I"Title")); WRITE_TO(T, "%S", Bibliographic::get_datum(W->md, I"Title"));

View file

@ -3,18 +3,18 @@
To provide for weaving in plain text format, which is not very To provide for weaving in plain text format, which is not very
interesting, but ought to be available. interesting, but ought to be available.
@h Creation. @ \section{Creation.}
= <<*>>=
void PlainText::create(void) { void PlainText::create(void) {
weave_format *wf = Formats::create_weave_format(I"plain", I".txt"); weave_format *wf = Formats::create_weave_format(I"plain", I".txt");
METHOD_ADD(wf, RENDER_FOR_MTID, PlainText::render); METHOD_ADD(wf, RENDER_FOR_MTID, PlainText::render);
} }
@h Methods. @ \section{Methods.}
For documentation, see "Weave Fornats". For documentation, see "Weave Fornats".
= <<*>>=
typedef struct PlainText_render_state { typedef struct PlainText_render_state {
struct text_stream *OUT; struct text_stream *OUT;
struct weave_order *wv; struct weave_order *wv;
@ -47,42 +47,42 @@ int PlainText::render_visit(tree_node *N, void *state, int L) {
(N->type == weave_toc_node_type) || (N->type == weave_toc_node_type) ||
(N->type == weave_toc_line_node_type) || (N->type == weave_toc_line_node_type) ||
(N->type == weave_grammar_index_node_type) || (N->type == weave_grammar_index_node_type) ||
(N->type == weave_inline_node_type)) @<Render nothing@> (N->type == weave_inline_node_type)) <<Render nothing>>
else if (N->type == weave_verbatim_node_type) @<Render verbatim@> else if (N->type == weave_verbatim_node_type) <<Render verbatim>>
else if (N->type == weave_chapter_header_node_type) @<Render chapter header@> else if (N->type == weave_chapter_header_node_type) <<Render chapter header>>
else if (N->type == weave_section_header_node_type) @<Render header@> else if (N->type == weave_section_header_node_type) <<Render header>>
else if (N->type == weave_section_footer_node_type) @<Render footer@> else if (N->type == weave_section_footer_node_type) <<Render footer>>
else if (N->type == weave_section_purpose_node_type) @<Render purpose@> else if (N->type == weave_section_purpose_node_type) <<Render purpose>>
else if (N->type == weave_subheading_node_type) @<Render subheading@> else if (N->type == weave_subheading_node_type) <<Render subheading>>
else if (N->type == weave_bar_node_type) @<Render bar@> else if (N->type == weave_bar_node_type) <<Render bar>>
else if (N->type == weave_pagebreak_node_type) @<Render pagebreak@> else if (N->type == weave_pagebreak_node_type) <<Render pagebreak>>
else if (N->type == weave_linebreak_node_type) @<Render linebreak@> else if (N->type == weave_linebreak_node_type) <<Render linebreak>>
else if (N->type == weave_paragraph_heading_node_type) @<Render paragraph heading@> else if (N->type == weave_paragraph_heading_node_type) <<Render paragraph heading>>
else if (N->type == weave_endnote_node_type) @<Render endnote@> else if (N->type == weave_endnote_node_type) <<Render endnote>>
else if (N->type == weave_embed_node_type) @<Render embed@> else if (N->type == weave_embed_node_type) <<Render embed>>
else if (N->type == weave_pmac_node_type) @<Render pmac@> else if (N->type == weave_pmac_node_type) <<Render pmac>>
else if (N->type == weave_vskip_node_type) @<Render vskip@> else if (N->type == weave_vskip_node_type) <<Render vskip>>
else if (N->type == weave_section_node_type) @<Render section@> else if (N->type == weave_section_node_type) <<Render section>>
else if (N->type == weave_code_line_node_type) @<Render code line@> else if (N->type == weave_code_line_node_type) <<Render code line>>
else if (N->type == weave_function_usage_node_type) @<Render function usage@> else if (N->type == weave_function_usage_node_type) <<Render function usage>>
else if (N->type == weave_commentary_node_type) @<Render commentary@> else if (N->type == weave_commentary_node_type) <<Render commentary>>
else if (N->type == weave_defn_node_type) @<Render defn@> else if (N->type == weave_defn_node_type) <<Render defn>>
else if (N->type == weave_source_code_node_type) @<Render source code@> else if (N->type == weave_source_code_node_type) <<Render source code>>
else if (N->type == weave_url_node_type) @<Render URL@> else if (N->type == weave_url_node_type) <<Render URL>>
else if (N->type == weave_footnote_cue_node_type) @<Render footnote cue@> else if (N->type == weave_footnote_cue_node_type) <<Render footnote cue>>
else if (N->type == weave_begin_footnote_text_node_type) @<Render footnote text@> else if (N->type == weave_begin_footnote_text_node_type) <<Render footnote text>>
else if (N->type == weave_display_line_node_type) @<Render display line@> else if (N->type == weave_display_line_node_type) <<Render display line>>
else if (N->type == weave_function_defn_node_type) @<Render function defn@> else if (N->type == weave_function_defn_node_type) <<Render function defn>>
else if (N->type == weave_item_node_type) @<Render item@> else if (N->type == weave_item_node_type) <<Render item>>
else if (N->type == weave_locale_node_type) @<Render locale@> else if (N->type == weave_locale_node_type) <<Render locale>>
else if (N->type == weave_maths_node_type) @<Render maths@> else if (N->type == weave_maths_node_type) <<Render maths>>
else internal_error("unable to render unknown node"); else internal_error("unable to render unknown node");
return TRUE; return TRUE;
} }
@<Render chapter header@> = <<Render chapter header>>=
weave_chapter_header_node *C = RETRIEVE_POINTER_weave_chapter_header_node(N->content); weave_chapter_header_node *C = RETRIEVE_POINTER_weave_chapter_header_node(N->content);
WRITE("%S\n\n", C->chap->md->ch_title); WRITE("%S\n\n", C->chap->md->ch_title);
section *S; section *S;
@ -91,127 +91,127 @@ int PlainText::render_visit(tree_node *N, void *state, int L) {
S->md->sect_title, S->sect_purpose); S->md->sect_title, S->sect_purpose);
WRITE("\n"); WRITE("\n");
@<Render header@> = <<Render header>>=
weave_section_header_node *C = RETRIEVE_POINTER_weave_section_header_node(N->content); weave_section_header_node *C = RETRIEVE_POINTER_weave_section_header_node(N->content);
WRITE("%S\n\n", C->sect->md->sect_title); WRITE("%S\n\n", C->sect->md->sect_title);
@<Render footer@> = <<Render footer>>=
WRITE("\n\n"); WRITE("\n\n");
@<Render purpose@> = <<Render purpose>>=
weave_section_purpose_node *C = RETRIEVE_POINTER_weave_section_purpose_node(N->content); weave_section_purpose_node *C = RETRIEVE_POINTER_weave_section_purpose_node(N->content);
WRITE("%S\n\n", C->purpose); WRITE("%S\n\n", C->purpose);
@<Render subheading@> = <<Render subheading>>=
weave_subheading_node *C = RETRIEVE_POINTER_weave_subheading_node(N->content); weave_subheading_node *C = RETRIEVE_POINTER_weave_subheading_node(N->content);
WRITE("%S\n\n", C->text); WRITE("%S\n\n", C->text);
@<Render bar@> = <<Render bar>>=
WRITE("\n----------------------------------------------------------------------\n\n"); WRITE("\n----------------------------------------------------------------------\n\n");
@<Render pagebreak@> = <<Render pagebreak>>=
; ;
@<Render linebreak@> = <<Render linebreak>>=
WRITE("\n"); WRITE("\n");
@<Render paragraph heading@> = <<Render paragraph heading>>=
weave_paragraph_heading_node *C = RETRIEVE_POINTER_weave_paragraph_heading_node(N->content); weave_paragraph_heading_node *C = RETRIEVE_POINTER_weave_paragraph_heading_node(N->content);
WRITE("\n"); WRITE("\n");
WRITE("%S%S", C->para->ornament, C->para->paragraph_number); WRITE("%S%S", C->para->ornament, C->para->paragraph_number);
if (Str::len(C->para->heading_text) > 0) WRITE(" %S", C->para->heading_text); if (Str::len(C->para->heading_text) > 0) WRITE(" %S", C->para->heading_text);
WRITE(". "); WRITE(". ");
@<Render endnote@> = <<Render endnote>>=
@<Recurse tne renderer through children nodes@>; <<Recurse tne renderer through children nodes>>;
WRITE("\n"); WRITE("\n");
return FALSE; return FALSE;
@<Render verbatim@> = <<Render verbatim>>=
weave_verbatim_node *C = RETRIEVE_POINTER_weave_verbatim_node(N->content); weave_verbatim_node *C = RETRIEVE_POINTER_weave_verbatim_node(N->content);
WRITE("%S", C->content); WRITE("%S", C->content);
@<Render nothing@> = <<Render nothing>>=
; ;
@<Render embed@> = <<Render embed>>=
weave_embed_node *C = RETRIEVE_POINTER_weave_embed_node(N->content); weave_embed_node *C = RETRIEVE_POINTER_weave_embed_node(N->content);
WRITE("[See %S video with ID %S.]\n", C->service, C->ID); WRITE("[See %S video with ID %S.]\n", C->service, C->ID);
@<Render pmac@> = <<Render pmac>>=
weave_pmac_node *C = RETRIEVE_POINTER_weave_pmac_node(N->content); weave_pmac_node *C = RETRIEVE_POINTER_weave_pmac_node(N->content);
WRITE("<%S (%S)>%s", WRITE("<%S (%S)>%s",
C->pmac->macro_name, C->pmac->defining_paragraph->paragraph_number, C->pmac->macro_name, C->pmac->defining_paragraph->paragraph_number,
(C->defn)?" =":""); (C->defn)?" =":"");
@<Render vskip@> = <<Render vskip>>=
WRITE("\n"); WRITE("\n");
@<Render section@> = <<Render section>>=
weave_section_node *C = RETRIEVE_POINTER_weave_section_node(N->content); weave_section_node *C = RETRIEVE_POINTER_weave_section_node(N->content);
LOG("It was %d\n", C->allocation_id); LOG("It was %d\n", C->allocation_id);
@<Render code line@> = <<Render code line>>=
for (tree_node *M = N->child; M; M = M->next) for (tree_node *M = N->child; M; M = M->next)
Trees::traverse_from(M, &PlainText::render_visit, (void *) prs, L+1); Trees::traverse_from(M, &PlainText::render_visit, (void *) prs, L+1);
WRITE("\n"); WRITE("\n");
return FALSE; return FALSE;
@<Render function usage@> = <<Render function usage>>=
weave_function_usage_node *C = RETRIEVE_POINTER_weave_function_usage_node(N->content); weave_function_usage_node *C = RETRIEVE_POINTER_weave_function_usage_node(N->content);
WRITE("%S", C->fn->function_name); WRITE("%S", C->fn->function_name);
return FALSE; return FALSE;
@<Render commentary@> = <<Render commentary>>=
weave_commentary_node *C = RETRIEVE_POINTER_weave_commentary_node(N->content); weave_commentary_node *C = RETRIEVE_POINTER_weave_commentary_node(N->content);
if (C->in_code) WRITE(" /* "); if (C->in_code) WRITE(" /* ");
WRITE("%S", C->text); WRITE("%S", C->text);
if (C->in_code) WRITE(" */ "); if (C->in_code) WRITE(" */ ");
@<Render defn@> = <<Render defn>>=
weave_defn_node *C = RETRIEVE_POINTER_weave_defn_node(N->content); weave_defn_node *C = RETRIEVE_POINTER_weave_defn_node(N->content);
WRITE("%S ", C->keyword); WRITE("%S ", C->keyword);
@<Render source code@> = <<Render source code>>=
weave_source_code_node *C = RETRIEVE_POINTER_weave_source_code_node(N->content); weave_source_code_node *C = RETRIEVE_POINTER_weave_source_code_node(N->content);
WRITE("%S", C->matter); WRITE("%S", C->matter);
@<Render URL@> = <<Render URL>>=
weave_url_node *C = RETRIEVE_POINTER_weave_url_node(N->content); weave_url_node *C = RETRIEVE_POINTER_weave_url_node(N->content);
WRITE("%S", C->url); WRITE("%S", C->url);
@<Render footnote cue@> = <<Render footnote cue>>=
weave_footnote_cue_node *C = RETRIEVE_POINTER_weave_footnote_cue_node(N->content); weave_footnote_cue_node *C = RETRIEVE_POINTER_weave_footnote_cue_node(N->content);
WRITE("[%S]", C->cue_text); WRITE("[%S]", C->cue_text);
@<Render footnote text@> = <<Render footnote text>>=
WRITE("\n"); WRITE("\n");
@<Render display line@> = <<Render display line>>=
weave_display_line_node *C = RETRIEVE_POINTER_weave_display_line_node(N->content); weave_display_line_node *C = RETRIEVE_POINTER_weave_display_line_node(N->content);
WRITE(" %S\n", C->text); WRITE(" %S\n", C->text);
@<Render function defn@> = <<Render function defn>>=
weave_function_defn_node *C = RETRIEVE_POINTER_weave_function_defn_node(N->content); weave_function_defn_node *C = RETRIEVE_POINTER_weave_function_defn_node(N->content);
WRITE("%S", C->fn->function_name); WRITE("%S", C->fn->function_name);
return TRUE; return TRUE;
@<Render item@> = <<Render item>>=
weave_item_node *C = RETRIEVE_POINTER_weave_item_node(N->content); weave_item_node *C = RETRIEVE_POINTER_weave_item_node(N->content);
for (int i=1; i<C->depth; i++) WRITE(" "); for (int i=1; i<C->depth; i++) WRITE(" ");
WRITE("(%S) ", C->label); WRITE("(%S) ", C->label);
@<Render locale@> = <<Render locale>>=
weave_locale_node *C = RETRIEVE_POINTER_weave_locale_node(N->content); weave_locale_node *C = RETRIEVE_POINTER_weave_locale_node(N->content);
WRITE("%S%S", C->par1->ornament, C->par1->paragraph_number); WRITE("%S%S", C->par1->ornament, C->par1->paragraph_number);
if (C->par2) WRITE("-%S", C->par2->paragraph_number); if (C->par2) WRITE("-%S", C->par2->paragraph_number);
@<Render maths@> = <<Render maths>>=
weave_maths_node *C = RETRIEVE_POINTER_weave_maths_node(N->content); weave_maths_node *C = RETRIEVE_POINTER_weave_maths_node(N->content);
if (C->displayed) WRITE("\n"); if (C->displayed) WRITE("\n");
WRITE("%S", C->content); WRITE("%S", C->content);
if (C->displayed) WRITE("\n\n"); if (C->displayed) WRITE("\n\n");
@<Recurse tne renderer through children nodes@> = <<Recurse tne renderer through children nodes>>=
for (tree_node *M = N->child; M; M = M->next) for (tree_node *M = N->child; M; M = M->next)
Trees::traverse_from(M, &PlainText::render_visit, (void *) prs, L+1); Trees::traverse_from(M, &PlainText::render_visit, (void *) prs, L+1);

View file

@ -3,33 +3,34 @@
To provide for weaving in the standard maths and science typesetting To provide for weaving in the standard maths and science typesetting
software, TeX. software, TeX.
@h Creation. @ \section{Creation.}
= <<*>>=
void TeX::create(void) { void TeX::create(void) {
weave_format *wf = Formats::create_weave_format(I"TeX", I".tex"); weave_format *wf = Formats::create_weave_format(I"TeX", I".tex");
METHOD_ADD(wf, RENDER_FOR_MTID, TeX::render_TeX); METHOD_ADD(wf, RENDER_FOR_MTID, TeX::render_TeX);
METHOD_ADD(wf, PREFORM_DOCUMENT_FOR_MTID, TeX::preform_document); METHOD_ADD(wf, PREFORM_DOCUMENT_FOR_MTID, TeX::preform_document);
} }
@h Rendering. @ \section{Rendering.}
At present, this renderer only makes the dialect of TeX needed for |pdftex|, At present, this renderer only makes the dialect of TeX needed for [[pdftex]],
which involves various extension commands: the curse of modern TeX is the which involves various extension commands: the curse of modern TeX is the
combination of an outdated original, and a proliferation of non-canonical combination of an outdated original, and a proliferation of non-canonical
extensions, but |pdftex| is pretty good. All the same, we should perhaps extensions, but [[pdftex]] is pretty good. All the same, we should perhaps
consider adding LaTeX, or XeTeX. consider adding LaTeX, or XeTeX.
@e PDFTEX_TEX_FORM from 1 <<*>>=
enum PDFTEX_TEX_FORM from 1
= <<*>>=
void TeX::render_TeX(weave_format *self, text_stream *OUT, heterogeneous_tree *tree) { void TeX::render_TeX(weave_format *self, text_stream *OUT, heterogeneous_tree *tree) {
TeX::render_inner(OUT, tree, PDFTEX_TEX_FORM); TeX::render_inner(OUT, tree, PDFTEX_TEX_FORM);
} }
@ From here on, then, the renderer, which should generate TeX which is as @ From here on, then, the renderer, which should generate TeX which is as
generic as possible, but with special features depending on |trs->TeX_form|. generic as possible, but with special features depending on [[trs->TeX_form]].
= <<*>>=
typedef struct TeX_render_state { typedef struct TeX_render_state {
struct text_stream *OUT; struct text_stream *OUT;
struct weave_order *wv; struct weave_order *wv;
@ -47,7 +48,7 @@ void TeX::render_inner(text_stream *OUT, heterogeneous_tree *tree, int form) {
@ For the reason why footnotes are omitted, see below: they aren't really. @ For the reason why footnotes are omitted, see below: they aren't really.
= <<*>>=
int TeX::render_visit(tree_node *N, void *state, int L) { int TeX::render_visit(tree_node *N, void *state, int L) {
TeX_render_state *trs = (TeX_render_state *) state; TeX_render_state *trs = (TeX_render_state *) state;
text_stream *OUT = trs->OUT; text_stream *OUT = trs->OUT;
@ -61,57 +62,57 @@ int TeX::render_visit(tree_node *N, void *state, int L) {
(N->type == weave_download_node_type) || (N->type == weave_download_node_type) ||
(N->type == weave_chapter_node_type) || (N->type == weave_chapter_node_type) ||
(N->type == weave_carousel_slide_node_type) || (N->type == weave_carousel_slide_node_type) ||
(N->type == weave_begin_footnote_text_node_type)) @<Render nothing@> (N->type == weave_begin_footnote_text_node_type)) <<Render nothing>>
else if (N->type == weave_head_node_type) @<Render head@> else if (N->type == weave_head_node_type) <<Render head>>
else if (N->type == weave_tail_node_type) @<Render tail@> else if (N->type == weave_tail_node_type) <<Render tail>>
else if (N->type == weave_verbatim_node_type) @<Render verbatim@> else if (N->type == weave_verbatim_node_type) <<Render verbatim>>
else if (N->type == weave_chapter_header_node_type) @<Render chapter header@> else if (N->type == weave_chapter_header_node_type) <<Render chapter header>>
else if (N->type == weave_section_header_node_type) @<Render header@> else if (N->type == weave_section_header_node_type) <<Render header>>
else if (N->type == weave_section_purpose_node_type) @<Render purpose@> else if (N->type == weave_section_purpose_node_type) <<Render purpose>>
else if (N->type == weave_subheading_node_type) @<Render subheading@> else if (N->type == weave_subheading_node_type) <<Render subheading>>
else if (N->type == weave_bar_node_type) @<Render bar@> else if (N->type == weave_bar_node_type) <<Render bar>>
else if (N->type == weave_pagebreak_node_type) @<Render pagebreak@> else if (N->type == weave_pagebreak_node_type) <<Render pagebreak>>
else if (N->type == weave_linebreak_node_type) @<Render linebreak@> else if (N->type == weave_linebreak_node_type) <<Render linebreak>>
else if (N->type == weave_paragraph_heading_node_type) @<Render paragraph heading@> else if (N->type == weave_paragraph_heading_node_type) <<Render paragraph heading>>
else if (N->type == weave_endnote_node_type) @<Render endnote@> else if (N->type == weave_endnote_node_type) <<Render endnote>>
else if (N->type == weave_figure_node_type) @<Render figure@> else if (N->type == weave_figure_node_type) <<Render figure>>
else if (N->type == weave_material_node_type) @<Render material@> else if (N->type == weave_material_node_type) <<Render material>>
else if (N->type == weave_embed_node_type) @<Render embed@> else if (N->type == weave_embed_node_type) <<Render embed>>
else if (N->type == weave_pmac_node_type) @<Render pmac@> else if (N->type == weave_pmac_node_type) <<Render pmac>>
else if (N->type == weave_vskip_node_type) @<Render vskip@> else if (N->type == weave_vskip_node_type) <<Render vskip>>
else if (N->type == weave_section_node_type) @<Render section@> else if (N->type == weave_section_node_type) <<Render section>>
else if (N->type == weave_code_line_node_type) @<Render code line@> else if (N->type == weave_code_line_node_type) <<Render code line>>
else if (N->type == weave_function_usage_node_type) @<Render function usage@> else if (N->type == weave_function_usage_node_type) <<Render function usage>>
else if (N->type == weave_commentary_node_type) @<Render commentary@> else if (N->type == weave_commentary_node_type) <<Render commentary>>
else if (N->type == weave_toc_node_type) @<Render toc@> else if (N->type == weave_toc_node_type) <<Render toc>>
else if (N->type == weave_toc_line_node_type) @<Render toc line@> else if (N->type == weave_toc_line_node_type) <<Render toc line>>
else if (N->type == weave_defn_node_type) @<Render defn@> else if (N->type == weave_defn_node_type) <<Render defn>>
else if (N->type == weave_source_code_node_type) @<Render source code@> else if (N->type == weave_source_code_node_type) <<Render source code>>
else if (N->type == weave_url_node_type) @<Render URL@> else if (N->type == weave_url_node_type) <<Render URL>>
else if (N->type == weave_footnote_cue_node_type) @<Render footnote cue@> else if (N->type == weave_footnote_cue_node_type) <<Render footnote cue>>
else if (N->type == weave_display_line_node_type) @<Render display line@> else if (N->type == weave_display_line_node_type) <<Render display line>>
else if (N->type == weave_function_defn_node_type) @<Render function defn@> else if (N->type == weave_function_defn_node_type) <<Render function defn>>
else if (N->type == weave_item_node_type) @<Render item@> else if (N->type == weave_item_node_type) <<Render item>>
else if (N->type == weave_grammar_index_node_type) @<Render grammar index@> else if (N->type == weave_grammar_index_node_type) <<Render grammar index>>
else if (N->type == weave_inline_node_type) @<Render inline@> else if (N->type == weave_inline_node_type) <<Render inline>>
else if (N->type == weave_locale_node_type) @<Render locale@> else if (N->type == weave_locale_node_type) <<Render locale>>
else if (N->type == weave_maths_node_type) @<Render maths@> else if (N->type == weave_maths_node_type) <<Render maths>>
else internal_error("unable to render unknown node"); else internal_error("unable to render unknown node");
return TRUE; return TRUE;
} }
@<Render head@> = <<Render head>>=
weave_head_node *C = RETRIEVE_POINTER_weave_head_node(N->content); weave_head_node *C = RETRIEVE_POINTER_weave_head_node(N->content);
WRITE("%% %S\n", C->banner); WRITE("%% %S\n", C->banner);
@<Render tail@> = <<Render tail>>=
weave_tail_node *C = RETRIEVE_POINTER_weave_tail_node(N->content); weave_tail_node *C = RETRIEVE_POINTER_weave_tail_node(N->content);
WRITE("%% %S\n", C->rennab); WRITE("%% %S\n", C->rennab);
WRITE("\\end\n"); WRITE("\\end\n");
@<Render chapter header@> = <<Render chapter header>>=
weave_chapter_header_node *C = RETRIEVE_POINTER_weave_chapter_header_node(N->content); weave_chapter_header_node *C = RETRIEVE_POINTER_weave_chapter_header_node(N->content);
if (Str::ne(C->chap->md->ch_range, I"S")) { if (Str::ne(C->chap->md->ch_range, I"S")) {
TeX::general_heading(OUT, trs->wv, TeX::general_heading(OUT, trs->wv,
@ -126,49 +127,49 @@ int TeX::render_visit(tree_node *N, void *state, int L) {
} }
} }
@<Render header@> = <<Render header>>=
weave_section_header_node *C = RETRIEVE_POINTER_weave_section_header_node(N->content); weave_section_header_node *C = RETRIEVE_POINTER_weave_section_header_node(N->content);
TeX::general_heading(OUT, trs->wv, C->sect, NULL, TeX::general_heading(OUT, trs->wv, C->sect, NULL,
C->sect->md->sect_title, 2, FALSE); C->sect->md->sect_title, 2, FALSE);
@<Render purpose@> = <<Render purpose>>=
weave_section_purpose_node *C = RETRIEVE_POINTER_weave_section_purpose_node(N->content); weave_section_purpose_node *C = RETRIEVE_POINTER_weave_section_purpose_node(N->content);
WRITE("\\smallskip\\par\\noindent{\\it %S}\\smallskip\\noindent\n", C->purpose); WRITE("\\smallskip\\par\\noindent{\\it %S}\\smallskip\\noindent\n", C->purpose);
@<Render subheading@> = <<Render subheading>>=
weave_subheading_node *C = RETRIEVE_POINTER_weave_subheading_node(N->content); weave_subheading_node *C = RETRIEVE_POINTER_weave_subheading_node(N->content);
WRITE("\\par\\noindent{\\bf %S}\\mark{%S}\\medskip\n", C->text, NULL); WRITE("\\par\\noindent{\\bf %S}\\mark{%S}\\medskip\n", C->text, NULL);
@<Render bar@> = <<Render bar>>=
WRITE("\\par\\medskip\\noindent\\hrule\\medskip\\noindent\n"); WRITE("\\par\\medskip\\noindent\\hrule\\medskip\\noindent\n");
@<Render pagebreak@> = <<Render pagebreak>>=
WRITE("\\vfill\\eject\n"); WRITE("\\vfill\\eject\n");
@<Render linebreak@> = <<Render linebreak>>=
WRITE("\n"); WRITE("\n");
@<Render paragraph heading@> = <<Render paragraph heading>>=
weave_paragraph_heading_node *C = weave_paragraph_heading_node *C =
RETRIEVE_POINTER_weave_paragraph_heading_node(N->content); RETRIEVE_POINTER_weave_paragraph_heading_node(N->content);
TeX::general_heading(OUT, trs->wv, C->para->under_section, TeX::general_heading(OUT, trs->wv, C->para->under_section,
C->para, I"", 0, FALSE); C->para, I"", 0, FALSE);
@<Render endnote@> = <<Render endnote>>=
WRITE("\\par\\noindent\\penalty10000\n"); WRITE("\\par\\noindent\\penalty10000\n");
WRITE("{\\usagefont "); WRITE("{\\usagefont ");
@<Recurse tne renderer through children nodes@>; <<Recurse tne renderer through children nodes>>;
WRITE("}\\smallskip\n"); WRITE("}\\smallskip\n");
return FALSE; return FALSE;
@ TeX itself has an almost defiant lack of support for anything pictorial, @ TeX itself has an almost defiant lack of support for anything pictorial,
which is one reason it didn't live up to its hope of being the definitive basis which is one reason it didn't live up to its hope of being the definitive basis
for typography; even today the loose confederation of TeX-like programs and for typography; even today the loose confederation of TeX-like programs and
extensions lack standard approaches. Here we're going to use |pdftex| features, extensions lack standard approaches. Here we're going to use [[pdftex]] features,
having nothing better. All we're trying for is to insert a picture, scaled having nothing better. All we're trying for is to insert a picture, scaled
to a given width, into the text at the current position. to a given width, into the text at the current position.
@<Render figure@> = <<Render figure>>=
weave_figure_node *C = RETRIEVE_POINTER_weave_figure_node(N->content); weave_figure_node *C = RETRIEVE_POINTER_weave_figure_node(N->content);
filename *F = Filenames::in( filename *F = Filenames::in(
Pathnames::down(trs->wv->weave_web->md->path_to_web, I"Figures"), Pathnames::down(trs->wv->weave_web->md->path_to_web, I"Figures"),
@ -181,7 +182,7 @@ to a given width, into the text at the current position.
"\\hbox to\\hsize{\\hfill\\pdfrefximage \\pdflastximage\\hfill}" "\\hbox to\\hsize{\\hfill\\pdfrefximage \\pdflastximage\\hfill}"
"\\smallskip\n"); "\\smallskip\n");
@<Render material@> = <<Render material>>=
weave_material_node *C = RETRIEVE_POINTER_weave_material_node(N->content); weave_material_node *C = RETRIEVE_POINTER_weave_material_node(N->content);
paragraph *first_in_para = NULL; paragraph *first_in_para = NULL;
if ((N == N->parent->child) && if ((N == N->parent->child) &&
@ -191,89 +192,89 @@ to a given width, into the text at the current position.
first_in_para = PC->para; first_in_para = PC->para;
} }
if (C->material_type == COMMENTARY_MATERIAL) if (C->material_type == COMMENTARY_MATERIAL)
@<Deal with a commentary material node@> <<Deal with a commentary material node>>
else if (C->material_type == CODE_MATERIAL) else if (C->material_type == CODE_MATERIAL)
@<Deal with a code material node@> <<Deal with a code material node>>
else if (C->material_type == FOOTNOTES_MATERIAL) else if (C->material_type == FOOTNOTES_MATERIAL)
@<Deal with a footnotes material node@> <<Deal with a footnotes material node>>
else if (C->material_type == ENDNOTES_MATERIAL) else if (C->material_type == ENDNOTES_MATERIAL)
@<Deal with a endnotes material node@> <<Deal with a endnotes material node>>
else if (C->material_type == MACRO_MATERIAL) else if (C->material_type == MACRO_MATERIAL)
@<Deal with a macro material node@> <<Deal with a macro material node>>
else if (C->material_type == DEFINITION_MATERIAL) else if (C->material_type == DEFINITION_MATERIAL)
@<Deal with a definition material node@>; <<Deal with a definition material node>>;
return FALSE; return FALSE;
@<Deal with a commentary material node@> = <<Deal with a commentary material node>>=
@<Recurse tne renderer through children nodes@>; <<Recurse tne renderer through children nodes>>;
WRITE("\n"); WRITE("\n");
@<Deal with a code material node@> = <<Deal with a code material node>>=
WRITE("\\beginlines\n"); WRITE("\\beginlines\n");
@<Recurse tne renderer through children nodes@>; <<Recurse tne renderer through children nodes>>;
WRITE("\\endlines\n"); WRITE("\\endlines\n");
@<Deal with a footnotes material node@> = <<Deal with a footnotes material node>>=
return FALSE; return FALSE;
@<Deal with a endnotes material node@> = <<Deal with a endnotes material node>>=
@<Recurse tne renderer through children nodes@>; <<Recurse tne renderer through children nodes>>;
@<Deal with a macro material node@> = <<Deal with a macro material node>>=
@<Recurse tne renderer through children nodes@>; <<Recurse tne renderer through children nodes>>;
WRITE("\n"); WRITE("\n");
@<Deal with a definition material node@> = <<Deal with a definition material node>>=
WRITE("\\beginlines\n"); WRITE("\\beginlines\n");
@<Recurse tne renderer through children nodes@>; <<Recurse tne renderer through children nodes>>;
WRITE("\\endlines\n"); WRITE("\\endlines\n");
@<Render verbatim@> = <<Render verbatim>>=
weave_verbatim_node *C = RETRIEVE_POINTER_weave_verbatim_node(N->content); weave_verbatim_node *C = RETRIEVE_POINTER_weave_verbatim_node(N->content);
WRITE("%S", C->content); WRITE("%S", C->content);
@<Render nothing@> = <<Render nothing>>=
; ;
@<Render embed@> = <<Render embed>>=
weave_embed_node *C = RETRIEVE_POINTER_weave_embed_node(N->content); weave_embed_node *C = RETRIEVE_POINTER_weave_embed_node(N->content);
LOG("It was %d\n", C->allocation_id); LOG("It was %d\n", C->allocation_id);
@<Render pmac@> = <<Render pmac>>=
weave_pmac_node *C = RETRIEVE_POINTER_weave_pmac_node(N->content); weave_pmac_node *C = RETRIEVE_POINTER_weave_pmac_node(N->content);
TeX::para_macro(OUT, trs->wv, C->pmac, C->defn); TeX::para_macro(OUT, trs->wv, C->pmac, C->defn);
@<Render vskip@> = <<Render vskip>>=
weave_vskip_node *C = RETRIEVE_POINTER_weave_vskip_node(N->content); weave_vskip_node *C = RETRIEVE_POINTER_weave_vskip_node(N->content);
if (C->in_comment) WRITE("\\smallskip\\par\\noindent%%\n"); if (C->in_comment) WRITE("\\smallskip\\par\\noindent%%\n");
else WRITE("\\smallskip\n"); else WRITE("\\smallskip\n");
@<Render section@> = <<Render section>>=
weave_section_node *C = RETRIEVE_POINTER_weave_section_node(N->content); weave_section_node *C = RETRIEVE_POINTER_weave_section_node(N->content);
LOG("It was %d\n", C->allocation_id); LOG("It was %d\n", C->allocation_id);
@<Render code line@> = <<Render code line>>=
WRITE("\\smallskip\\par\\noindent "); WRITE("\\smallskip\\par\\noindent ");
WRITE("|"); WRITE("|");
@<Recurse tne renderer through children nodes@>; <<Recurse tne renderer through children nodes>>;
WRITE("|"); WRITE("|");
WRITE("\n"); WRITE("\n");
return FALSE; return FALSE;
@<Render function usage@> = <<Render function usage>>=
weave_function_usage_node *C = weave_function_usage_node *C =
RETRIEVE_POINTER_weave_function_usage_node(N->content); RETRIEVE_POINTER_weave_function_usage_node(N->content);
WRITE("%S", C->fn->function_name); WRITE("%S", C->fn->function_name);
return FALSE; return FALSE;
@<Render commentary@> = <<Render commentary>>=
weave_commentary_node *C = weave_commentary_node *C =
RETRIEVE_POINTER_weave_commentary_node(N->content); RETRIEVE_POINTER_weave_commentary_node(N->content);
if (C->in_code) WRITE(" |\\hfill{\\ttninepoint\\it "); if (C->in_code) WRITE(" |\\hfill{\\ttninepoint\\it ");
TeX::commentary_text(OUT, trs->wv, C->text); TeX::commentary_text(OUT, trs->wv, C->text);
if (C->in_code) WRITE("}|"); if (C->in_code) WRITE("}|");
@<Render toc@> = <<Render toc>>=
WRITE("\\medskip\\hrule\\smallskip\\par\\noindent{\\usagefont "); WRITE("\\medskip\\hrule\\smallskip\\par\\noindent{\\usagefont ");
for (tree_node *M = N->child; M; M = M->next) { for (tree_node *M = N->child; M; M = M->next) {
Trees::traverse_from(M, &TeX::render_visit, (void *) trs, L+1); Trees::traverse_from(M, &TeX::render_visit, (void *) trs, L+1);
@ -282,15 +283,15 @@ to a given width, into the text at the current position.
WRITE("}\\par\\medskip\\hrule\\bigskip\n"); WRITE("}\\par\\medskip\\hrule\\bigskip\n");
return FALSE; return FALSE;
@<Render toc line@> = <<Render toc line>>=
weave_toc_line_node *C = RETRIEVE_POINTER_weave_toc_line_node(N->content); weave_toc_line_node *C = RETRIEVE_POINTER_weave_toc_line_node(N->content);
WRITE("%S~%S", C->text1, C->text2); WRITE("%S~%S", C->text1, C->text2);
@<Render defn@> = <<Render defn>>=
weave_defn_node *C = RETRIEVE_POINTER_weave_defn_node(N->content); weave_defn_node *C = RETRIEVE_POINTER_weave_defn_node(N->content);
WRITE("|{\\ninebf %S} |", C->keyword); WRITE("[[{\\ninebf %S} ]]", C->keyword);
@<Render source code@> = <<Render source code>>=
weave_source_code_node *C = weave_source_code_node *C =
RETRIEVE_POINTER_weave_source_code_node(N->content); RETRIEVE_POINTER_weave_source_code_node(N->content);
int starts = FALSE; int starts = FALSE;
@ -298,7 +299,7 @@ to a given width, into the text at the current position.
TeX::source_code(OUT, trs->wv, TeX::source_code(OUT, trs->wv,
C->matter, C->colouring, starts); C->matter, C->colouring, starts);
@<Render URL@> = <<Render URL>>=
weave_url_node *C = RETRIEVE_POINTER_weave_url_node(N->content); weave_url_node *C = RETRIEVE_POINTER_weave_url_node(N->content);
WRITE("%S", C->url); WRITE("%S", C->url);
@ -306,7 +307,7 @@ to a given width, into the text at the current position.
which is tricky for us now because the footnote text is somewhere else in which is tricky for us now because the footnote text is somewhere else in
the weave tree -- so, we go for a little walk: the weave tree -- so, we go for a little walk:
@<Render footnote cue@> = <<Render footnote cue>>=
weave_footnote_cue_node *C = RETRIEVE_POINTER_weave_footnote_cue_node(N->content); weave_footnote_cue_node *C = RETRIEVE_POINTER_weave_footnote_cue_node(N->content);
WRITE("\\footnote{${}^{%S}$}{", C->cue_text); WRITE("\\footnote{${}^{%S}$}{", C->cue_text);
tree_node *M = N; tree_node *M = N;
@ -324,7 +325,7 @@ the weave tree -- so, we go for a little walk:
weave_begin_footnote_text_node *FC = weave_begin_footnote_text_node *FC =
RETRIEVE_POINTER_weave_begin_footnote_text_node(F->content); RETRIEVE_POINTER_weave_begin_footnote_text_node(F->content);
if (Str::eq(FC->cue_text, C->cue_text)) if (Str::eq(FC->cue_text, C->cue_text))
@<Found the right footnote text at last@>; <<Found the right footnote text at last>>;
} }
F = F->next; F = F->next;
} }
@ -342,17 +343,17 @@ and TeX renders that automatically.
(The TeX renderer otherwise ignores footnote texts, so if these nodes (The TeX renderer otherwise ignores footnote texts, so if these nodes
are not rendered here, they never will be.) are not rendered here, they never will be.)
@<Found the right footnote text at last@> = <<Found the right footnote text at last>>=
for (tree_node *X = F->child->next; X; X = X->next) for (tree_node *X = F->child->next; X; X = X->next)
Trees::traverse_from(X, &TeX::render_visit, (void *) trs, L+1); Trees::traverse_from(X, &TeX::render_visit, (void *) trs, L+1);
found = TRUE; found = TRUE;
@<Render display line@> = <<Render display line>>=
weave_display_line_node *C = weave_display_line_node *C =
RETRIEVE_POINTER_weave_display_line_node(N->content); RETRIEVE_POINTER_weave_display_line_node(N->content);
WRITE("\\quotesource{%S}\n", C->text); WRITE("\\quotesource{%S}\n", C->text);
@<Render function defn@> = <<Render function defn>>=
weave_function_defn_node *C = weave_function_defn_node *C =
RETRIEVE_POINTER_weave_function_defn_node(N->content); RETRIEVE_POINTER_weave_function_defn_node(N->content);
TeX::change_colour_PDF(OUT, FUNCTION_COLOUR, TRUE); TeX::change_colour_PDF(OUT, FUNCTION_COLOUR, TRUE);
@ -360,7 +361,7 @@ are not rendered here, they never will be.)
TeX::change_colour_PDF(OUT, PLAIN_COLOUR, TRUE); TeX::change_colour_PDF(OUT, PLAIN_COLOUR, TRUE);
return FALSE; return FALSE;
@<Render item@> = <<Render item>>=
weave_item_node *C = RETRIEVE_POINTER_weave_item_node(N->content); weave_item_node *C = RETRIEVE_POINTER_weave_item_node(N->content);
if (Str::len(C->label) > 0) { if (Str::len(C->label) > 0) {
if (C->depth == 1) WRITE("\\item{(%S)}", C->label); if (C->depth == 1) WRITE("\\item{(%S)}", C->label);
@ -370,42 +371,42 @@ are not rendered here, they never will be.)
else WRITE("\\itemitem{}"); else WRITE("\\itemitem{}");
} }
@<Render grammar index@> = <<Render grammar index>>=
InCSupport::weave_grammar_index(OUT); InCSupport::weave_grammar_index(OUT);
@<Render inline@> = <<Render inline>>=
WRITE("|"); WRITE("|");
@<Recurse tne renderer through children nodes@>; <<Recurse tne renderer through children nodes>>;
WRITE("|"); WRITE("|");
return FALSE; return FALSE;
@<Render locale@> = <<Render locale>>=
weave_locale_node *C = RETRIEVE_POINTER_weave_locale_node(N->content); weave_locale_node *C = RETRIEVE_POINTER_weave_locale_node(N->content);
WRITE("$\\%S$%S", C->par1->ornament, C->par1->paragraph_number); WRITE("$\\%S$%S", C->par1->ornament, C->par1->paragraph_number);
if (C->par2) WRITE("-%S", C->par2->paragraph_number); if (C->par2) WRITE("-%S", C->par2->paragraph_number);
@<Render maths@> = <<Render maths>>=
weave_maths_node *C = RETRIEVE_POINTER_weave_maths_node(N->content); weave_maths_node *C = RETRIEVE_POINTER_weave_maths_node(N->content);
if (C->displayed) WRITE("$$"); else WRITE("$"); if (C->displayed) WRITE("$$"); else WRITE("$");
WRITE("%S", C->content); WRITE("%S", C->content);
if (C->displayed) WRITE("$$"); else WRITE("$"); if (C->displayed) WRITE("$$"); else WRITE("$");
@<Recurse tne renderer through children nodes@> = <<Recurse tne renderer through children nodes>>=
for (tree_node *M = N->child; M; M = M->next) for (tree_node *M = N->child; M; M = M->next)
Trees::traverse_from(M, &TeX::render_visit, (void *) trs, L+1); Trees::traverse_from(M, &TeX::render_visit, (void *) trs, L+1);
@ = <<*>>=
text_stream *P_literal = NULL; text_stream *P_literal = NULL;
void TeX::general_heading(text_stream *OUT, weave_order *wv, void TeX::general_heading(text_stream *OUT, weave_order *wv,
section *S, paragraph *P, text_stream *heading_text, int weight, int no_skip) { section *S, paragraph *P, text_stream *heading_text, int weight, int no_skip) {
text_stream *TeX_macro = NULL; text_stream *TeX_macro = NULL;
@<Choose which TeX macro to use in order to typeset the new paragraph heading@>; <<Choose which TeX macro to use in order to typeset the new paragraph heading>>;
if (P_literal == NULL) P_literal = Str::new_from_wide_string(L"P"); if (P_literal == NULL) P_literal = Str::new_from_wide_string(L"P");
text_stream *orn = (P)?(P->ornament):P_literal; text_stream *orn = (P)?(P->ornament):P_literal;
text_stream *N = (P)?(P->paragraph_number):NULL; text_stream *N = (P)?(P->paragraph_number):NULL;
TEMPORARY_TEXT(mark) TEMPORARY_TEXT(mark)
@<Work out the next mark to place into the TeX vertical list@>; <<Work out the next mark to place into the TeX vertical list>>;
TEMPORARY_TEXT(modified) TEMPORARY_TEXT(modified)
Str::copy(modified, heading_text); Str::copy(modified, heading_text);
match_results mr = Regexp::create_mr(); match_results mr = Regexp::create_mr();
@ -427,19 +428,19 @@ void TeX::general_heading(text_stream *OUT, weave_order *wv,
@ We want to have different heading styles for different weights, and TeX is @ We want to have different heading styles for different weights, and TeX is
horrible at using macro parameters as function arguments, so we don't want horrible at using macro parameters as function arguments, so we don't want
to pass the weight that way. Instead we use to pass the weight that way. Instead we use
= (text)
\weavesection \weavesection
\weavesections \weavesections
\weavesectionss \weavesectionss
\weavesectionsss \weavesectionsss
=
where the weight is the number of terminal |s|s, 0 to 3. (TeX macros, where the weight is the number of terminal [[s]]s, 0 to 3. (TeX macros,
lamentably, are not allowed digits in their name.) In the cases 0 and 1, we lamentably, are not allowed digits in their name.) In the cases 0 and 1, we
also have variants |\nsweavesection| and |\nsweavesections| which are also have variants [[\nsweavesection]] and [[\nsweavesections]] which are
the same, but with the initial vertical spacing removed; these allow us to the same, but with the initial vertical spacing removed; these allow us to
prevent unsightly excess white space in certain configurations of a section. prevent unsightly excess white space in certain configurations of a section.
@<Choose which TeX macro to use in order to typeset the new paragraph heading@> = <<Choose which TeX macro to use in order to typeset the new paragraph heading>>=
switch (weight) { switch (weight) {
case 0: TeX_macro = I"weavesection"; break; case 0: TeX_macro = I"weavesection"; break;
case 1: TeX_macro = I"weavesections"; break; case 1: TeX_macro = I"weavesections"; break;
@ -465,12 +466,12 @@ prevent unsightly excess white space in certain configurations of a section.
which follow the material on those pages: so that the running head for a page which follow the material on those pages: so that the running head for a page
can show the paragraph range for the material which tops it, for instance. can show the paragraph range for the material which tops it, for instance.
The ornament has to be set in math mode, even in the mark. |\S| and |\P|, The ornament has to be set in math mode, even in the mark. [[\S]] and [[\P]],
making a section sign and a pilcrow respectively, only work in math mode making a section sign and a pilcrow respectively, only work in math mode
because they abbreviate characters found in math fonts but not regular ones, because they abbreviate characters found in math fonts but not regular ones,
in TeX's deeply peculiar font encoding system. in TeX's deeply peculiar font encoding system.
@<Work out the next mark to place into the TeX vertical list@> = <<Work out the next mark to place into the TeX vertical list>>=
text_stream *chaptermark = Str::new(); text_stream *chaptermark = Str::new();
text_stream *sectionmark = Str::new(); text_stream *sectionmark = Str::new();
if (weight == 3) { if (weight == 3) {
@ -492,26 +493,26 @@ typewriter-type verbatim mode on and off. To get an actual stroke, we must
escape from code mode, escape it using a backslash, then re-enter code escape from code mode, escape it using a backslash, then re-enter code
mode once again: mode once again:
= <<*>>=
void TeX::source_code(text_stream *OUT, weave_order *wv, void TeX::source_code(text_stream *OUT, weave_order *wv,
text_stream *matter, text_stream *colouring, int starts) { text_stream *matter, text_stream *colouring, int starts) {
int current_colour = PLAIN_COLOUR, colour_wanted = PLAIN_COLOUR; int current_colour = PLAIN_COLOUR, colour_wanted = PLAIN_COLOUR;
for (int i=0; i < Str::len(matter); i++) { for (int i=0; i < Str::len(matter); i++) {
colour_wanted = Str::get_at(colouring, i); colour_wanted = Str::get_at(colouring, i);
@<Adjust code colour as necessary@>; <<Adjust code colour as necessary>>;
if (Str::get_at(matter, i) == '|') WRITE("|\\||"); if (Str::get_at(matter, i) == '[[') WRITE("|\\|]]");
else WRITE("%c", Str::get_at(matter, i)); else WRITE("%c", Str::get_at(matter, i));
} }
colour_wanted = PLAIN_COLOUR; @<Adjust code colour as necessary@>; colour_wanted = PLAIN_COLOUR; <<Adjust code colour as necessary>>;
} }
@<Adjust code colour as necessary@> = <<Adjust code colour as necessary>>=
if (colour_wanted != current_colour) { if (colour_wanted != current_colour) {
TeX::change_colour_PDF(OUT, colour_wanted, TRUE); TeX::change_colour_PDF(OUT, colour_wanted, TRUE);
current_colour = colour_wanted; current_colour = colour_wanted;
} }
@ = <<*>>=
void TeX::change_colour_PDF(text_stream *OUT, int col, int in_code) { void TeX::change_colour_PDF(text_stream *OUT, int col, int in_code) {
char *inout = ""; char *inout = "";
if (in_code) inout = "|"; if (in_code) inout = "|";
@ -534,7 +535,7 @@ of the macro in small type; and second, we use cross-reference links.
In the PDF format, these three are all called, in sequence below; in TeX In the PDF format, these three are all called, in sequence below; in TeX
or DVI, only the middle one is. or DVI, only the middle one is.
= <<*>>=
void TeX::para_macro(text_stream *OUT, weave_order *wv, para_macro *pmac, int defn) { void TeX::para_macro(text_stream *OUT, weave_order *wv, para_macro *pmac, int defn) {
if (defn) if (defn)
WRITE("|\\pdfdest num %d fit ", WRITE("|\\pdfdest num %d fit ",
@ -554,7 +555,7 @@ void TeX::para_macro(text_stream *OUT, weave_order *wv, para_macro *pmac, int de
WRITE("\\pdfendlink|"); WRITE("\\pdfendlink|");
} }
@ = <<*>>=
void TeX::commentary_text(text_stream *OUT, weave_order *wv, text_stream *id) { void TeX::commentary_text(text_stream *OUT, weave_order *wv, text_stream *id) {
int math_mode = FALSE; int math_mode = FALSE;
for (int i=0; i < Str::len(id); i++) { for (int i=0; i < Str::len(id); i++) {
@ -564,7 +565,7 @@ void TeX::commentary_text(text_stream *OUT, weave_order *wv, text_stream *id) {
case '_': if (math_mode) WRITE("_"); else WRITE("\\_"); break; case '_': if (math_mode) WRITE("_"); else WRITE("\\_"); break;
case '"': case '"':
if ((Str::get_at(id, i) == '"') && if ((Str::get_at(id, i) == '"') &&
((i==0) || (Str::get_at(id, i-1) == ' ') || ((i==0) [[| (Str::get_at(id, i-1) == ' ') |]]
(Str::get_at(id, i-1) == '('))) (Str::get_at(id, i-1) == '(')))
WRITE("``"); WRITE("``");
else else
@ -579,25 +580,25 @@ void TeX::commentary_text(text_stream *OUT, weave_order *wv, text_stream *id) {
@ The following is called only when the language is InC, and the weave is of @ The following is called only when the language is InC, and the weave is of
the special Preform grammar document. the special Preform grammar document.
= <<*>>=
int TeX::preform_document(weave_format *self, text_stream *OUT, web *W, int TeX::preform_document(weave_format *self, text_stream *OUT, web *W,
weave_order *wv, chapter *C, section *S, source_line *L, text_stream *matter, weave_order *wv, chapter *C, section *S, source_line *L, text_stream *matter,
text_stream *concluding_comment) { text_stream *concluding_comment) {
if (L->preform_nonterminal_defined) { if (L->preform_nonterminal_defined) {
preform_production_count = 0; preform_production_count = 0;
@<Weave the opening line of the nonterminal definition@>; <<Weave the opening line of the nonterminal definition>>;
return TRUE; return TRUE;
} else { } else {
if (L->category == PREFORM_GRAMMAR_LCAT) { if (L->category == PREFORM_GRAMMAR_LCAT) {
@<Weave a line from the body of the nonterminal definition@>; <<Weave a line from the body of the nonterminal definition>>;
return TRUE; return TRUE;
} }
} }
return FALSE; return FALSE;
} }
@<Weave the opening line of the nonterminal definition@> = <<Weave the opening line of the nonterminal definition>>=
WRITE("\\nonterminal{%S} |::=|", WRITE("\\nonterminal{%S} [[::=]]",
L->preform_nonterminal_defined->unangled_name); L->preform_nonterminal_defined->unangled_name);
if (L->preform_nonterminal_defined->as_function) { if (L->preform_nonterminal_defined->as_function) {
WRITE("\\quad{\\it internal definition"); WRITE("\\quad{\\it internal definition");
@ -612,7 +613,7 @@ int TeX::preform_document(weave_format *self, text_stream *OUT, web *W,
} }
WRITE("\n"); WRITE("\n");
@<Weave a line from the body of the nonterminal definition@> = <<Weave a line from the body of the nonterminal definition>>=
TEMPORARY_TEXT(problem) TEMPORARY_TEXT(problem)
match_results mr = Regexp::create_mr(); match_results mr = Regexp::create_mr();
if (Regexp::match(&mr, matter, L"Issue (%c*?) problem")) if (Regexp::match(&mr, matter, L"Issue (%c*?) problem"))
@ -622,18 +623,18 @@ int TeX::preform_document(weave_format *self, text_stream *OUT, web *W,
else if (Regexp::match(&mr, matter, L"FAIL_NONTERMINAL")) else if (Regexp::match(&mr, matter, L"FAIL_NONTERMINAL"))
WRITE_TO(problem, "fail"); WRITE_TO(problem, "fail");
preform_production_count++; preform_production_count++;
WRITE_TO(matter, "|%S|", L->text_operand); WRITE_TO(matter, "[[%S]]", L->text_operand);
while (Regexp::match(&mr, matter, L"(%c+?)|(%c+)")) { while (Regexp::match(&mr, matter, L"(%c+?)|(%c+)")) {
Str::clear(matter); Str::clear(matter);
WRITE_TO(matter, "%S___stroke___%S", mr.exp[0], mr.exp[1]); WRITE_TO(matter, "%S___stroke___%S", mr.exp[0], mr.exp[1]);
} }
while (Regexp::match(&mr, matter, L"(%c*?)___stroke___(%c*)")) { while (Regexp::match(&mr, matter, L"(%c*?)___stroke___(%c*)")) {
Str::clear(matter); Str::clear(matter);
WRITE_TO(matter, "%S|\\||%S", mr.exp[0], mr.exp[1]); WRITE_TO(matter, "%S[[\\|]]%S", mr.exp[0], mr.exp[1]);
} }
while (Regexp::match(&mr, matter, L"(%c*)<(%c*?)>(%c*)")) { while (Regexp::match(&mr, matter, L"(%c*)<(%c*?)>(%c*)")) {
Str::clear(matter); Str::clear(matter);
WRITE_TO(matter, "%S|\\nonterminal{%S}|%S", WRITE_TO(matter, "%S[[\\nonterminal{%S}]]%S",
mr.exp[0], mr.exp[1], mr.exp[2]); mr.exp[0], mr.exp[1], mr.exp[2]);
} }
TEMPORARY_TEXT(label) TEMPORARY_TEXT(label)

View file

@ -2,7 +2,7 @@
A few conveniences for using Inweb with TeX. A few conveniences for using Inweb with TeX.
@h Post-processing TeX console output. @ \section{Post-processing TeX console output.}
Pattern commands post-processing TeX tend to run TeX-like tools in Pattern commands post-processing TeX tend to run TeX-like tools in
"scrollmode", so that any errors whizz by rather than interrupting or halting "scrollmode", so that any errors whizz by rather than interrupting or halting
the session. Prime among errors is the "overfull hbox error", a defect of TeX the session. Prime among errors is the "overfull hbox error", a defect of TeX
@ -16,7 +16,7 @@ the error messages (which begin with an exclamation mark in column 1).
This structure will store what we find: This structure will store what we find:
= <<*>>=
typedef struct tex_results { typedef struct tex_results {
int overfull_hbox_count; int overfull_hbox_count;
int tex_error_count; int tex_error_count;
@ -26,7 +26,7 @@ typedef struct tex_results {
CLASS_DEFINITION CLASS_DEFINITION
} tex_results; } tex_results;
@ = <<*>>=
tex_results *TeXUtilities::new_results(weave_order *wv, filename *CF) { tex_results *TeXUtilities::new_results(weave_order *wv, filename *CF) {
tex_results *res = CREATE(tex_results); tex_results *res = CREATE(tex_results);
res->overfull_hbox_count = 0; res->overfull_hbox_count = 0;
@ -38,9 +38,9 @@ tex_results *TeXUtilities::new_results(weave_order *wv, filename *CF) {
} }
@ So, then, here's the function called from //Patterns// in response to @ So, then, here's the function called from //Patterns// in response to
the special |PROCESS| command: the special [[PROCESS]] command:
= <<*>>=
void TeXUtilities::post_process_weave(weave_order *wv, filename *CF) { void TeXUtilities::post_process_weave(weave_order *wv, filename *CF) {
wv->post_processing_results = TeXUtilities::new_results(wv, CF); wv->post_processing_results = TeXUtilities::new_results(wv, CF);
TextFiles::read(CF, FALSE, TextFiles::read(CF, FALSE,
@ -48,7 +48,7 @@ void TeXUtilities::post_process_weave(weave_order *wv, filename *CF) {
(void *) wv->post_processing_results); (void *) wv->post_processing_results);
} }
@ = <<*>>=
void TeXUtilities::scan_console_line(text_stream *line, text_file_position *tfp, void TeXUtilities::scan_console_line(text_stream *line, text_file_position *tfp,
void *res_V) { void *res_V) {
tex_results *res = (tex_results *) res_V; tex_results *res = (tex_results *) res_V;
@ -66,9 +66,9 @@ void TeXUtilities::scan_console_line(text_stream *line, text_file_position *tfp,
Regexp::dispose_of(&mr); Regexp::dispose_of(&mr);
} }
@h Reporting. @ \section{Reporting.}
= <<*>>=
void TeXUtilities::report_on_post_processing(weave_order *wv) { void TeXUtilities::report_on_post_processing(weave_order *wv) {
tex_results *res = wv->post_processing_results; tex_results *res = wv->post_processing_results;
if (res) { if (res) {
@ -82,7 +82,7 @@ void TeXUtilities::report_on_post_processing(weave_order *wv) {
@ And here are some details to do with the results of post-processing. @ And here are some details to do with the results of post-processing.
= <<*>>=
int TeXUtilities::substitute_post_processing_data(text_stream *to, weave_order *wv, int TeXUtilities::substitute_post_processing_data(text_stream *to, weave_order *wv,
text_stream *detail) { text_stream *detail) {
if (wv) { if (wv) {
@ -115,14 +115,14 @@ int TeXUtilities::substitute_post_processing_data(text_stream *to, weave_order *
return FALSE; return FALSE;
} }
@h Removing math mode. @ \section{Removing math mode.}
"Math mode", in TeX jargon, is what happens when a mathematical formula "Math mode", in TeX jargon, is what happens when a mathematical formula
is written inside dollar signs: in |Answer is $x+y^2$|, the math mode is written inside dollar signs: in [[Answer is $x+y^2$]], the math mode
content is |x+y^2|. But since math mode doesn't (easily) exist in HTML, content is [[x+y^2]]. But since math mode doesn't (easily) exist in HTML,
for example, we want to strip it out if the format is not TeX-related. for example, we want to strip it out if the format is not TeX-related.
To do this, the weaver calls the following. To do this, the weaver calls the following.
= <<*>>=
void TeXUtilities::remove_math_mode(OUTPUT_STREAM, text_stream *text) { void TeXUtilities::remove_math_mode(OUTPUT_STREAM, text_stream *text) {
TEMPORARY_TEXT(math_matter) TEMPORARY_TEXT(math_matter)
TeXUtilities::remove_math_mode_range(math_matter, text, 0, Str::len(text)-1); TeXUtilities::remove_math_mode_range(math_matter, text, 0, Str::len(text)-1);
@ -132,11 +132,11 @@ void TeXUtilities::remove_math_mode(OUTPUT_STREAM, text_stream *text) {
void TeXUtilities::remove_math_mode_range(OUTPUT_STREAM, text_stream *text, int from, int to) { void TeXUtilities::remove_math_mode_range(OUTPUT_STREAM, text_stream *text, int from, int to) {
for (int i=from; i <= to; i++) { for (int i=from; i <= to; i++) {
@<Remove the over construction@>; <<Remove the over construction>>;
} }
for (int i=from; i <= to; i++) { for (int i=from; i <= to; i++) {
@<Remove the rm and it constructions@>; <<Remove the rm and it constructions>>;
@<Remove the sqrt constructions@>; <<Remove the sqrt constructions>>;
} }
int math_mode = FALSE; int math_mode = FALSE;
for (int i=from; i <= to; i++) { for (int i=from; i <= to; i++) {
@ -145,15 +145,15 @@ void TeXUtilities::remove_math_mode_range(OUTPUT_STREAM, text_stream *text, int
if (Str::get_at(text, i+1) == '$') i++; if (Str::get_at(text, i+1) == '$') i++;
math_mode = (math_mode)?FALSE:TRUE; break; math_mode = (math_mode)?FALSE:TRUE; break;
case '~': if (math_mode) WRITE(" "); else WRITE("~"); break; case '~': if (math_mode) WRITE(" "); else WRITE("~"); break;
case '\\': @<Do something to strip out a TeX macro@>; break; case '\\': <<Do something to strip out a TeX macro>>; break;
default: PUT(Str::get_at(text, i)); break; default: PUT(Str::get_at(text, i)); break;
} }
} }
} }
@ Here we remove |{{top}\over{bottom}}|, converting it to |((top) / (bottom))|. @ Here we remove [[{{top}\over{bottom}}]], converting it to [[((top) / (bottom))]].
@<Remove the over construction@> = <<Remove the over construction>>=
if ((Str::get_at(text, i) == '\\') && if ((Str::get_at(text, i) == '\\') &&
(Str::get_at(text, i+1) == 'o') && (Str::get_at(text, i+2) == 'v') && (Str::get_at(text, i+1) == 'o') && (Str::get_at(text, i+2) == 'v') &&
(Str::get_at(text, i+3) == 'e') && (Str::get_at(text, i+4) == 'r') && (Str::get_at(text, i+3) == 'e') && (Str::get_at(text, i+4) == 'r') &&
@ -187,9 +187,9 @@ void TeXUtilities::remove_math_mode_range(OUTPUT_STREAM, text_stream *text, int
return; return;
} }
@ Here we remove |{\rm text}|, converting it to |text|, and similarly |\it|. @ Here we remove [[{\rm text}]], converting it to [[text]], and similarly [[\it]].
@<Remove the rm and it constructions@> = <<Remove the rm and it constructions>>=
if ((Str::get_at(text, i) == '{') && (Str::get_at(text, i+1) == '\\') && if ((Str::get_at(text, i) == '{') && (Str::get_at(text, i+1) == '\\') &&
(((Str::get_at(text, i+2) == 'r') && (Str::get_at(text, i+3) == 'm')) || (((Str::get_at(text, i+2) == 'r') && (Str::get_at(text, i+3) == 'm')) ||
((Str::get_at(text, i+2) == 'i') && (Str::get_at(text, i+3) == 't'))) && ((Str::get_at(text, i+2) == 'i') && (Str::get_at(text, i+3) == 't'))) &&
@ -204,10 +204,10 @@ void TeXUtilities::remove_math_mode_range(OUTPUT_STREAM, text_stream *text, int
return; return;
} }
@ Here we remove |\sqrt{N}|, converting it to |sqrt(N)|. As a special case, @ Here we remove [[\sqrt{N}]], converting it to [[sqrt(N)]]. As a special case,
we also look out for |{}^3\sqrt{N}| for cube root. we also look out for [[{}^3\sqrt{N}]] for cube root.
@<Remove the sqrt constructions@> = <<Remove the sqrt constructions>>=
if ((Str::get_at(text, i) == '\\') && if ((Str::get_at(text, i) == '\\') &&
(Str::get_at(text, i+1) == 's') && (Str::get_at(text, i+2) == 'q') && (Str::get_at(text, i+1) == 's') && (Str::get_at(text, i+2) == 'q') &&
(Str::get_at(text, i+3) == 'r') && (Str::get_at(text, i+4) == 't') && (Str::get_at(text, i+3) == 'r') && (Str::get_at(text, i+4) == 't') &&
@ -237,17 +237,17 @@ we also look out for |{}^3\sqrt{N}| for cube root.
return; return;
} }
@<Do something to strip out a TeX macro@> = <<Do something to strip out a TeX macro>>=
TEMPORARY_TEXT(macro) TEMPORARY_TEXT(macro)
i++; i++;
while ((i < Str::len(text)) && (Characters::isalpha(Str::get_at(text, i)))) while ((i < Str::len(text)) && (Characters::isalpha(Str::get_at(text, i))))
PUT_TO(macro, Str::get_at(text, i++)); PUT_TO(macro, Str::get_at(text, i++));
if (Str::eq(macro, I"not")) @<Remove the not prefix@> if (Str::eq(macro, I"not")) <<Remove the not prefix>>
else @<Remove a general macro@>; else <<Remove a general macro>>;
DISCARD_TEXT(macro) DISCARD_TEXT(macro)
i--; i--;
@<Remove a general macro@> = <<Remove a general macro>>=
if (Str::eq(macro, I"leq")) WRITE("<="); if (Str::eq(macro, I"leq")) WRITE("<=");
else if (Str::eq(macro, I"geq")) WRITE(">="); else if (Str::eq(macro, I"geq")) WRITE(">=");
else if (Str::eq(macro, I"sim")) WRITE("~"); else if (Str::eq(macro, I"sim")) WRITE("~");
@ -358,9 +358,9 @@ we also look out for |{}^3\sqrt{N}| for cube root.
WRITE("\\%S", macro); WRITE("\\%S", macro);
} }
@ For Inform's purposes, we need to deal with just |\not\exists| and |\not\forall|. @ For Inform's purposes, we need to deal with just [[\not\exists]] and [[\not\forall]].
@<Remove the not prefix@> = <<Remove the not prefix>>=
if (Str::get_at(text, i) == '\\') { if (Str::get_at(text, i) == '\\') {
Str::clear(macro); Str::clear(macro);
i++; i++;

View file

@ -2,7 +2,7 @@
An abstraction of the weaver output. An abstraction of the weaver output.
@ = <<*>>=
typedef struct weave_document_node { typedef struct weave_document_node {
struct weave_order *wv; struct weave_order *wv;
CLASS_DEFINITION CLASS_DEFINITION
@ -249,7 +249,7 @@ typedef struct weave_verbatim_node {
CLASS_DEFINITION CLASS_DEFINITION
} weave_verbatim_node; } weave_verbatim_node;
@ = <<*>>=
tree_type *weave_tree_type = NULL; tree_type *weave_tree_type = NULL;
tree_node_type *weave_document_node_type = NULL; tree_node_type *weave_document_node_type = NULL;
tree_node_type *weave_head_node_type = NULL; tree_node_type *weave_head_node_type = NULL;
@ -580,11 +580,11 @@ tree_node *WeaveTree::embed(heterogeneous_tree *tree,
return Trees::new_node(tree, weave_embed_node_type, STORE_POINTER_weave_embed_node(C)); return Trees::new_node(tree, weave_embed_node_type, STORE_POINTER_weave_embed_node(C));
} }
@ This node weaves an angle-bracketed paragraph macro name. |defn| is set @ This node weaves an angle-bracketed paragraph macro name. [[defn]] is set
if and only if this is the place where the macro is defined -- the usual if and only if this is the place where the macro is defined -- the usual
thing is to render some sort of equals sign after it, if so. thing is to render some sort of equals sign after it, if so.
= <<*>>=
tree_node *WeaveTree::pmac(heterogeneous_tree *tree, para_macro *pmac, int defn) { tree_node *WeaveTree::pmac(heterogeneous_tree *tree, para_macro *pmac, int defn) {
weave_pmac_node *C = CREATE(weave_pmac_node); weave_pmac_node *C = CREATE(weave_pmac_node);
C->pmac = pmac; C->pmac = pmac;
@ -593,10 +593,10 @@ tree_node *WeaveTree::pmac(heterogeneous_tree *tree, para_macro *pmac, int defn)
} }
@ The following should render some kind of skip, and may want to take note of @ The following should render some kind of skip, and may want to take note of
whether this happens in commentary or in code: the |in_comment| flag provides this whether this happens in commentary or in code: the [[in_comment]] flag provides this
information. information.
= <<*>>=
tree_node *WeaveTree::vskip(heterogeneous_tree *tree, int in_comment) { tree_node *WeaveTree::vskip(heterogeneous_tree *tree, int in_comment) {
weave_vskip_node *C = CREATE(weave_vskip_node); weave_vskip_node *C = CREATE(weave_vskip_node);
C->in_comment = in_comment; C->in_comment = in_comment;
@ -670,9 +670,10 @@ the mercy of web browsers, which render tabs slightly oddly (and not to the
width this author happens to like). So tabs are automatically converted to width this author happens to like). So tabs are automatically converted to
spaces sufficient to reach the next tab-stop position, calculated as: spaces sufficient to reach the next tab-stop position, calculated as:
@d SPACES_PER_TAB_IN_WOVEN_CODE 4 <<*>>=
#define SPACES_PER_TAB_IN_WOVEN_CODE 4
= <<*>>=
tree_node *WeaveTree::source_code(heterogeneous_tree *tree, tree_node *WeaveTree::source_code(heterogeneous_tree *tree,
text_stream *matter, text_stream *colouring) { text_stream *matter, text_stream *colouring) {
if (Str::len(colouring) != Str::len(matter)) internal_error("bad source segment"); if (Str::len(colouring) != Str::len(matter)) internal_error("bad source segment");
@ -729,17 +730,17 @@ tree_node *WeaveTree::footnote(heterogeneous_tree *tree, text_stream *cue) {
@ This node need not do anything; it simply alerts the renderer that a function @ This node need not do anything; it simply alerts the renderer that a function
definition has just occurred. definition has just occurred.
= <<*>>=
tree_node *WeaveTree::function_defn(heterogeneous_tree *tree, language_function *fn) { tree_node *WeaveTree::function_defn(heterogeneous_tree *tree, language_function *fn) {
weave_function_defn_node *C = CREATE(weave_function_defn_node); weave_function_defn_node *C = CREATE(weave_function_defn_node);
C->fn = fn; C->fn = fn;
return Trees::new_node(tree, weave_function_defn_node_type, STORE_POINTER_weave_function_defn_node(C)); return Trees::new_node(tree, weave_function_defn_node_type, STORE_POINTER_weave_function_defn_node(C));
} }
@ This node produces the |>> Example| bits of example source text, really @ This node produces the [[>> Example]] bits of example source text, really
a convenience for Inform 7 code commentary. a convenience for Inform 7 code commentary.
= <<*>>=
tree_node *WeaveTree::display_line(heterogeneous_tree *tree, text_stream *text) { tree_node *WeaveTree::display_line(heterogeneous_tree *tree, text_stream *text) {
weave_display_line_node *C = CREATE(weave_display_line_node); weave_display_line_node *C = CREATE(weave_display_line_node);
C->text = Str::duplicate(text); C->text = Str::duplicate(text);
@ -747,18 +748,18 @@ tree_node *WeaveTree::display_line(heterogeneous_tree *tree, text_stream *text)
} }
@ An item node produces an item marker in a typical (a), (b), (c), ... sort @ An item node produces an item marker in a typical (a), (b), (c), ... sort
of list. |depth| can be 1 or 2: you can have lists in lists, but not lists in of list. [[depth]] can be 1 or 2: you can have lists in lists, but not lists in
lists in lists. |label| is the marker text, e.g., |a|, |b|, |c|, ...; it can lists in lists. [[label]] is the marker text, e.g., [[a]], [[b]], [[c]], ...; it can
also be empty, in which case the method should move to the matching level of also be empty, in which case the method should move to the matching level of
indentation but not weave any bracketed marker. indentation but not weave any bracketed marker.
(a) This was produced by |depth| equal to 1, |label| equal to |a|. (a) This was produced by [[depth]] equal to 1, [[label]] equal to [[a]].
(-i) This was produced by |depth| equal to 2, |label| equal to |i|. (-i) This was produced by [[depth]] equal to 2, [[label]] equal to [[i]].
(-ii) This was produced by |depth| equal to 2, |label| equal to |ii|. (-ii) This was produced by [[depth]] equal to 2, [[label]] equal to [[ii]].
(...) This was produced by |depth| equal to 1, |label| empty. (...) This was produced by [[depth]] equal to 1, [[label]] empty.
(b) This was produced by |depth| equal to 1, |label| equal to |b|. (b) This was produced by [[depth]] equal to 1, [[label]] equal to [[b]].
= <<*>>=
tree_node *WeaveTree::weave_item_node(heterogeneous_tree *tree, int depth, text_stream *label) { tree_node *WeaveTree::weave_item_node(heterogeneous_tree *tree, int depth, text_stream *label) {
weave_item_node *C = CREATE(weave_item_node); weave_item_node *C = CREATE(weave_item_node);
C->depth = depth; C->depth = depth;