To render linking gadgets in HTML forms of documentation, so that the reader can navigate from section to section.


§1.

    typedef struct navigation_design {
        struct text_stream *codename;
        int ebook_friendly;
        int plain_friendly;
        int columnar;
        int simplified_examples;
        int simplified_letter_rows;
        struct text_stream *contents_body_class;
        METHOD_CALLS
        MEMORY_MANAGEMENT
    } navigation_design;

    navigation_design *Nav::new(text_stream *code, int e, int p) {
        navigation_design *ND = CREATE(navigation_design);
        ND->codename = Str::duplicate(code);
        ND->ebook_friendly = e;
        ND->plain_friendly = p;
        ND->columnar = FALSE;
        ND->simplified_examples = FALSE;
        ND->simplified_letter_rows = FALSE;
        ND->contents_body_class = I"paper midnightpapertint";
        ND->methods = Methods::new_set();
        return ND;
    }

    void Nav::start(void) {
        Midnight::create(); needs to be created first
        Twilight::create();
        Architect::create();
        Roadsign::create(); needs to be created before unsigned
        Unsigned::create();
        Lacuna::create();
    }

    navigation_design *Nav::default(void) {
        return FIRST_OBJECT(navigation_design);
    }

    navigation_design *Nav::for_ebook(navigation_design *current) {
        if (current->ebook_friendly) return current;
        navigation_design *ND;
        LOOP_OVER(ND, navigation_design)
            if (ND->ebook_friendly)
                return ND;
        return NULL;
    }

    navigation_design *Nav::for_plain_text(navigation_design *current) {
        if (current->plain_friendly) return current;
        navigation_design *ND;
        LOOP_OVER(ND, navigation_design)
            if (ND->plain_friendly)
                return ND;
        return NULL;
    }

    navigation_design *Nav::parse(text_stream *val) {
        navigation_design *ND;
        LOOP_OVER(ND, navigation_design)
            if (Str::eq(val, ND->codename))
                return ND;
        return NULL;
    }

The function Nav::new is used in 4/cl (§1), 4/cm (§1), 4/ca (§1), 4/ct (§1), 4/cr (§1), 4/cu (§1).

The function Nav::start is used in 1/mn (§1.1).

The function Nav::default is used in 1/ins (§2).

The function Nav::for_ebook is used in 1/ins (§3.1).

The function Nav::for_plain_text is used in 1/ins (§3.1).

The function Nav::parse is used in 1/ins (§5.1.5.2).

The structure navigation_design is accessed in 2/exm, 3/iu, 4/cm, 4/ca, 4/ct and here.

§2. Top. At the front end of a section, before any of its text.

    enum RENDER_VOLUME_TITLE_MTID
    enum RENDER_CHAPTER_TITLE_MTID
    enum RENDER_SECTION_TITLE_MTID
    VMETHOD_TYPE(RENDER_VOLUME_TITLE_MTID, navigation_design *ND, text_stream *OUT, volume *V)
    VMETHOD_TYPE(RENDER_CHAPTER_TITLE_MTID, navigation_design *ND, text_stream *OUT, volume *V, chapter *C)
    VMETHOD_TYPE(RENDER_SECTION_TITLE_MTID, navigation_design *ND, text_stream *OUT, volume *V, chapter *C, section *S)

    void Nav::render_navigation_top(OUTPUT_STREAM, volume *V, section *S) {
        if (indoc_settings->insertion_filename)
            HTML::incorporate_HTML(OUT, indoc_settings->insertion_filename);

        if (V->sections[0] == S) VMETHOD_CALL(indoc_settings->navigation, RENDER_VOLUME_TITLE_MTID, OUT, V);

        chapter *C = S->begins_which_chapter;
        if (C) VMETHOD_CALL(indoc_settings->navigation, RENDER_CHAPTER_TITLE_MTID, OUT, V, C);

        if (indoc_settings->html_for_Inform_application)
            <Write HTML comments giving the Inform user interface search assistance 2.1>;

        VMETHOD_CALL(indoc_settings->navigation, RENDER_SECTION_TITLE_MTID, OUT, V, C, S);
    }

The function Nav::render_navigation_top is used in 2/rnd (§9).

§2.1. <Write HTML comments giving the Inform user interface search assistance 2.1> =

        WRITE("\n");
        TEMPORARY_TEXT(comment);
        WRITE_TO(comment, "SEARCH TITLE \"%S\"", S->unlabelled_title);
        HTML::comment(OUT, comment);
        Str::clear(comment);
        WRITE_TO(comment, "SEARCH SECTION \"%S\"", S->label);
        HTML::comment(OUT, comment);
        Str::clear(comment);
        WRITE_TO(comment, "SEARCH SORT \"%S\"", S->sort_code);
        HTML::comment(OUT, comment);
        DISCARD_TEXT(comment);

This code is used in §2.

§3. Index top. And this is a variant for index pages, such as the index of examples.

    enum RENDER_INDEX_TOP_MTID
    VMETHOD_TYPE(RENDER_INDEX_TOP_MTID, navigation_design *ND, text_stream *OUT, text_stream *filename, text_stream *title)

    void Nav::render_navigation_index_top(OUTPUT_STREAM, text_stream *filename, text_stream *title) {
        if (indoc_settings->insertion_filename)
            HTML::incorporate_HTML(OUT, indoc_settings->insertion_filename);

        VMETHOD_CALL(indoc_settings->navigation, RENDER_INDEX_TOP_MTID, OUT, filename, title);
    }

The function Nav::render_navigation_index_top is used in 3/iu (§1).

§4. Middle. At the middle part, when the text is over, but before any example cues.

    enum RENDER_NAV_MIDDLE_MTID
    VMETHOD_TYPE(RENDER_NAV_MIDDLE_MTID, navigation_design *ND, text_stream *OUT, volume *V, section *S)

    void Nav::render_navigation_middle(OUTPUT_STREAM, volume *V, section *S) {
        VMETHOD_CALL(indoc_settings->navigation, RENDER_NAV_MIDDLE_MTID, OUT, V, S);
    }

The function Nav::render_navigation_middle is used in 2/rnd (§9).

§5. Example top. This is reached before the first example is rendered, provided at least one example will be:

    enum RENDER_EXAMPLE_TOP_MTID
    VMETHOD_TYPE(RENDER_EXAMPLE_TOP_MTID, navigation_design *ND, text_stream *OUT, volume *V, section *S)

    void Nav::render_navigation_example_top(OUTPUT_STREAM, volume *V, section *S) {

        if (indoc_settings->format == HTML_FORMAT) {
            HTML::begin_div_with_class_S(OUT, I"bookexamples");
            HTML_OPEN_WITH("p", "class=\"chapterheading\"");
        }

        if (indoc_settings->examples_granularity == CHAPTER_GRANULARITY) {
            chapter *C = S->in_which_chapter;
            WRITE("Examples from %S", C->chapter_full_title);
        } else if (indoc_settings->examples_granularity == BOOK_GRANULARITY) {
            WRITE("Examples");
        }

        if (indoc_settings->format == HTML_FORMAT) { HTML_CLOSE("p"); } else WRITE("\n\n");

        VMETHOD_CALL(indoc_settings->navigation, RENDER_EXAMPLE_TOP_MTID, OUT, V, S);
    }

The function Nav::render_navigation_example_top is used in 2/rnd (§9.1).

§6. Example bottom. Any closing ornament at the end of examples? This is reached after the last example is rendered, provided at least one example has been.

    enum RENDER_EXAMPLE_BOTTOM_MTID
    VMETHOD_TYPE(RENDER_EXAMPLE_BOTTOM_MTID, navigation_design *ND, text_stream *OUT, volume *V, section *S)

    void Nav::render_navigation_example_bottom(OUTPUT_STREAM, volume *V, section *S) {
        if (indoc_settings->format == PLAIN_FORMAT) WRITE("\n\n");

        if (indoc_settings->format == HTML_FORMAT) {
            if (indoc_settings->examples_mode != EXMODE_open_internal)
                HTMLUtilities::ruled_line(OUT);
            HTML::end_div(OUT);
        }

        VMETHOD_CALL(indoc_settings->navigation, RENDER_EXAMPLE_BOTTOM_MTID, OUT, V, S);
    }

The function Nav::render_navigation_example_bottom is used in 2/rnd (§9.1).

§7. Bottom. At the end of the section, after any example cues and perhaps also example bodied. (In a section with no examples, this immediately follows the middle.)

    enum RENDER_NAV_BOTTOM_MTID
    VMETHOD_TYPE(RENDER_NAV_BOTTOM_MTID, navigation_design *ND, text_stream *OUT, volume *V, section *S)

    void Nav::render_navigation_bottom(OUTPUT_STREAM, volume *V, section *S) {
        if (indoc_settings->format == HTML_FORMAT) HTML::comment(OUT, I"START IGNORE");
        VMETHOD_CALL(indoc_settings->navigation, RENDER_NAV_BOTTOM_MTID, OUT, V, S);
        if (indoc_settings->format == HTML_FORMAT) HTML::comment(OUT, I"END IGNORE");
    }

The function Nav::render_navigation_bottom is used in 2/rnd (§9).

§8. Contents page. Midnight provides a contents page of its very own.

    enum RENDER_CONTENTS_MTID
    enum RENDER_CONTENTS_HEADING_MTID
    VMETHOD_TYPE(RENDER_CONTENTS_MTID, navigation_design *ND)
    VMETHOD_TYPE(RENDER_CONTENTS_HEADING_MTID, navigation_design *ND, text_stream *OUT, volume *V)

    void Nav::render_navigation_contents_files(void) {
        VMETHOD_CALLV(indoc_settings->navigation, RENDER_CONTENTS_MTID);
    }

    void Nav::navigation_contents_heading(OUTPUT_STREAM, volume *V) {
        VMETHOD_CALL(indoc_settings->navigation, RENDER_CONTENTS_HEADING_MTID, OUT, V);
    }

The function Nav::render_navigation_contents_files is used in 1/mn (§1.3).

The function Nav::navigation_contents_heading is used in 4/cm (§9).