author | Olivier Brunel
<jjk@jjacky.com> 2023-07-18 21:24:35 UTC |
committer | Olivier Brunel
<jjk@jjacky.com> 2023-07-19 07:23:32 UTC |
parent | e8d511a0269bffe192892a162ffb03b9b46b3db7 |
src/qmdoc/qmdoc.c | +38 | -21 |
diff --git a/src/qmdoc/qmdoc.c b/src/qmdoc/qmdoc.c index ab242fa..ac3267b 100644 --- a/src/qmdoc/qmdoc.c +++ b/src/qmdoc/qmdoc.c @@ -116,6 +116,7 @@ struct qmdoc { int from; } code; int toc_lvl; + int cur_idx; int cur_page; int cur_grp_idx; int options; @@ -797,26 +798,42 @@ leave_block(MD_BLOCKTYPE type, void *details, void *ctx_) return ERR_LEAVE_BLOCK; } if (ctx->options & OPT_BUTTONS) { -#define str_title(i) ctx->sa.s + PAGES(ctx)[i].titleoff -#define str_file(i) ctx->sa.s + PAGES(ctx)[i].dstoff + struct page *p; +#define str_title(p) ctx->sa.s + ((p->nameoff) ? p->nameoff : p->titleoff) +#define str_file(p) ctx->sa.s + p->dstoff if (!raw_str(ctx, "<section id=\"navbuttons\">")) return ERR_LEAVE_BLOCK; - if (ctx->cur_page > !(ctx->doc.flags & DOC_FULL_TOC) - && (!raw_str(ctx, "<a class=\"prev\" href=\"") - || !escape_text(ctx, str_file(ctx->cur_page - 1), - strlen(str_file(ctx->cur_page - 1))) + p = NULL; + for (int i = ctx->cur_idx - 1; i >= !(ctx->doc.flags & DOC_FULL_TOC); --i) { + struct entry *e = &ENTRY(ctx)[genalloc_s(int, &ctx->ga_idx)[i]]; + if (e->is_page) { + p = &PAGES(ctx)[e->page]; + break; + } + } + if (p && (!raw_str(ctx, "<a class=\"prev\" href=\"") + || !escape_text(ctx, str_file(p), + strlen(str_file(p))) || !raw_str(ctx, "\" title=\"") - || !escape_text(ctx, str_title(ctx->cur_page - 1), - strlen(str_title(ctx->cur_page - 1))) + || !escape_text(ctx, str_title(p), + strlen(str_title(p))) || !raw_str(ctx, "\">Previous</a>"))) return ERR_LEAVE_BLOCK; - if (0/* FIXME ctx->cur_page < ctx->nb_pages - 1 */ - && (!raw_str(ctx, "<a class=\"next\" href=\"") - || !escape_text(ctx, str_file(ctx->cur_page + 1), - strlen(str_file(ctx->cur_page + 1))) + + p = NULL; + for (int i = ctx->cur_idx + 1, n = genalloc_len(int, &ctx->ga_idx); i < n; ++i) { + struct entry *e = &ENTRY(ctx)[genalloc_s(int, &ctx->ga_idx)[i]]; + if (e->is_page) { + p = &PAGES(ctx)[e->page]; + break; + } + } + if (p && (!raw_str(ctx, "<a class=\"next\" href=\"") + || !escape_text(ctx, str_file(p), + strlen(str_file(p))) || !raw_str(ctx, "\" title=\"") - || !escape_text(ctx, str_title(ctx->cur_page + 1), - strlen(str_title(ctx->cur_page + 1))) + || !escape_text(ctx, str_title(p), + strlen(str_title(p))) || !raw_str(ctx, "\">Next</a>"))) return ERR_LEAVE_BLOCK; if (!raw_str(ctx, "</section>")) @@ -2394,14 +2411,14 @@ main (int argc, const char *argv[]) /* usually start at 1, but if there's only one entry it means there's only * the index, which means start with it. */ - int i = NB_ENTRIES(&ctx) > 1; + ctx.cur_idx = NB_ENTRIES(&ctx) > 1; ctx.cur_grp_idx = 0; for (;;) { - int cur_entry = genalloc_s(int, &ctx.ga_idx)[i]; + int cur_entry = genalloc_s(int, &ctx.ga_idx)[ctx.cur_idx]; struct entry *e = &ENTRY(&ctx)[cur_entry]; if (genalloc_len(int, &ctx.ga_grp) > ctx.cur_grp_idx + 1 - && genalloc_s(int, &ctx.ga_grp)[ctx.cur_grp_idx + 1] == i) + && genalloc_s(int, &ctx.ga_grp)[ctx.cur_grp_idx + 1] == ctx.cur_idx) ++ctx.cur_grp_idx; if (!e->is_page) { @@ -2427,14 +2444,14 @@ main (int argc, const char *argv[]) ctx.sa.s + PAGES(&ctx)[ctx.cur_page].dstoff, ESC); } - if (++i == genalloc_len(int, &ctx.ga_idx)) { + if (++ctx.cur_idx == genalloc_len(int, &ctx.ga_idx)) { /* having DOC_FULL_TOC means this is the index, *but* this might be * from the first time/loop around, in the odd case of there is only * the index. - * This is why we also break if i==1 */ - if (!(ctx.doc.flags & DOC_FULL_TOC) || i == 1) + * This is why we also break if ctx.cur_idx==1 */ + if (!(ctx.doc.flags & DOC_FULL_TOC) || ctx.cur_idx == 1) break; - i = 0; + ctx.cur_idx = 0; ctx.cur_grp_idx = 0; ctx.doc.flags |= DOC_IS_INDEX; } else if (ctx.doc.flags & DOC_IS_INDEX)