Welcome to little lamb

Code » qmdoc » commit 73b1859

Add -b/--buttons to add Previous/Next buttons at..

author Olivier Brunel
2023-01-02 17:38:12 UTC
committer Olivier Brunel
2023-01-04 15:10:17 UTC
parent b1cb6b27d2cc6f14fa3a4b8cf5f3c7b9326a446d

Add -b/--buttons to add Previous/Next buttons at..

..the bottom of every pages. The order of pages being that of files as
specified on command line.

base.htm +4 -0
dark.css +6 -0
light.css +6 -0
main.c +38 -3
struct.css +22 -0

diff --git a/base.htm b/base.htm
index bec0bba..d91dd33 100644
--- a/base.htm
+++ b/base.htm
@@ -223,6 +223,10 @@ int main(int argc, char **argv)
                 </div>
                 </p>
             </section>
+            <section id="navbuttons">
+                <a class="prev" href="#" title="Previous Title">Previous</a>
+                <a class="next" href="#" title="Next Title">Next</a>
+            </section>
             <footer>
                 Copyright &copy; 2022 Author Name - All Rights Reserved
                 <br>
diff --git a/dark.css b/dark.css
index 7474f9a..caf4887 100644
--- a/dark.css
+++ b/dark.css
@@ -91,6 +91,12 @@
     main div.box.note > :first-child {
         background: #575656;
     }
+    main #navbuttons a {
+        background: #9f9d1b;
+        border: 1px solid #232323;
+        color: inherit;
+        box-shadow: inset 0 1px 2px -1px hsla(0,0%,100%,.5),inset 0 -2px 0 0 #232323;
+    }
     main footer {
         border-top: 2px solid #515151;
     }
diff --git a/light.css b/light.css
index 63c4eb2..bfd9860 100644
--- a/light.css
+++ b/light.css
@@ -89,6 +89,12 @@ main div.box.note {
 main div.box.note > :first-child {
     background: #5c5353;
 }
+main #navbuttons a {
+    background: #f0efb6;
+    border: 1px solid #232323;
+    color: inherit;
+    box-shadow: inset 0 1px 2px -1px hsla(0,0%,100%,.5),inset 0 -2px 0 0 #232323;
+}
 main footer {
     border-top: 1px solid #979518;
 }
diff --git a/main.c b/main.c
index e45dce8..522dd80 100644
--- a/main.c
+++ b/main.c
@@ -26,6 +26,7 @@ enum {
     OPT_INLINE_CSS  = (1 << 1),
     OPT_OVERWRITE   = (1 << 2),
     OPT_NO_TOC      = (1 << 3),
+    OPT_BUTTONS     = (1 << 4),
 };
 
 enum {
@@ -549,8 +550,37 @@ leave_block(MD_BLOCKTYPE type, void *details, void *ctx_)
             struct tm tm;
             localtime_r(&ts.tv_sec, &tm);
             year[uint32_fmt(year, (uint32) 1900 + tm.tm_year)] = '\0';
-            if (((ctx->doc.flags & DOC_HAS_TITLE) && !raw_str(ctx, "</section>"))
-                    || !raw_str(ctx, "<footer>Copyright &copy; ")
+            if ((ctx->doc.flags & DOC_HAS_TITLE) && !raw_str(ctx, "</section>"))
+                return ERR_PARSER_LEAVE_BLOCK;
+            if (ctx->options & OPT_BUTTONS) {
+#define str_title(i)    ctx->sa.s + ctx->pages[i].titleoff
+#define str_file(i)    ctx->sa.s + ctx->pages[i].fileoff
+                if (!raw_str(ctx, "<section id=\"navbuttons\">"))
+                    return ERR_PARSER_LEAVE_BLOCK;
+                if (ctx->cur_page > 0
+                        && (!raw_str(ctx, "<a class=\"prev\" href=\"")
+                            || !escape_text(ctx, str_file(ctx->cur_page - 1),
+                                            strlen(str_file(ctx->cur_page - 1)))
+                            || !raw_str(ctx, "\" title=\"")
+                            || !escape_text(ctx, str_title(ctx->cur_page - 1),
+                                            strlen(str_title(ctx->cur_page - 1)))
+                            || !raw_str(ctx, "\">Previous</a>")))
+                    return ERR_PARSER_LEAVE_BLOCK;
+                if (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)))
+                            || !raw_str(ctx, "\" title=\"")
+                            || !escape_text(ctx, str_title(ctx->cur_page + 1),
+                                            strlen(str_title(ctx->cur_page + 1)))
+                            || !raw_str(ctx, "\">Next</a>")))
+                    return ERR_PARSER_LEAVE_BLOCK;
+                if (!raw_str(ctx, "</section>"))
+                    return ERR_PARSER_LEAVE_BLOCK;
+#undef str_file
+#undef str_title
+            }
+            if (!raw_str(ctx, "<footer>Copyright &copy; ")
                     || !raw_str(ctx, year)
                     || !raw_str(ctx, " ")
                     || !escape_text(ctx, ctx->doc.author, strlen(ctx->doc.author))
@@ -1077,6 +1107,7 @@ static void
 help(void)
 {
     outh(" -a, --author AUTHOR          Set AUTHOR as author (in meta in footer)\n"
+         " -b, --buttons                Put Previous & Next buttons on pages\n"
          " -C, --no-css                 Do not use CSS (still process --css if any)\n"
          " -c, --css FILE               Add FILE as additional CSS\n"
          " -d, --destdir DIR            Write files into DIR\n"
@@ -1121,6 +1152,7 @@ main (int argc, char *argv[])
     int c;
     struct option opts[] = {
         { "author",         required_argument,  NULL,   'a' },
+        { "buttons",        no_argument,        NULL,   'b' },
         { "no-css",         no_argument,        NULL,   'C' },
         { "css",            required_argument,  NULL,   'c' },
         { "destdir",        required_argument,  NULL,   'd' },
@@ -1134,10 +1166,13 @@ main (int argc, char *argv[])
         { "title",          required_argument,  NULL,   't' },
         { NULL,             0,                  NULL,    0  },
     };
-    while ((c = getopt_long(argc, argv, "a:Cc:d:F:H:hIl:oTt:", opts, NULL)) != -1) switch (c) {
+    while ((c = getopt_long(argc, argv, "a:bCc:d:F:H:hIl:oTt:", opts, NULL)) != -1) switch (c) {
         case 'a':
             ctx.doc.author = optarg;
             break;
+        case 'b':
+            ctx.options |= OPT_BUTTONS;
+            break;
         case 'C':
             ctx.options |= OPT_NO_CSS;
             break;
diff --git a/struct.css b/struct.css
index 4d0a791..a7b4432 100644
--- a/struct.css
+++ b/struct.css
@@ -215,6 +215,28 @@ main div.box div.box {
     width: 90%;
     margin: auto;
 }
+main #navbuttons {
+    height: 23px;
+}
+main #navbuttons a {
+    border-radius: 4px;
+    padding: 4px 12px 8px;
+    text-align: center;
+    font-size: 100%;
+    cursor: pointer;
+    text-decoration: none;
+    user-select: none;
+}
+main #navbuttons a.prev::before {
+    content: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAASCAMAAABhEH5lAAAANlBMVEUAAABAQEBAQEBAQEBAQEBAQEBAQEBBQUFAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAWW5SEAAAAEnRSTlMA/fC9r2kXAjMN34F3ZlUu6B40Y5wGAAAAVElEQVQY08XPSw6AIAwEUIbS8lFE739Zq6luGtbM8iXTTMOCZGECiCX/MhIQTyCNz+SRrUc1MWKVvR5KYCN6pUFDRtqq4Sql9IYJ+aI/70f4qdOHblOhAuUcC5KnAAAAAElFTkSuQmCC);
+}
+main #navbuttons a.next {
+    float: right;
+    margin-top: -4px;
+}
+main #navbuttons a.next::after {
+    content: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAASBAMAAACk4JNkAAAAJFBMVEUAAABAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEC4lvDfAAAAC3RSTlMAx711ZjlFPh3zLASjkrYAAABDSURBVAjXY6AUsGhvcgAzOKR3797YAGIx7t5mvVsAxPLevZ159xYQS3v3zgLrTSDW7tTQBcy7ESyELEIHwhSEyQjbAAH1HsMY8tCHAAAAAElFTkSuQmCC);
+}
 main footer {
     padding: 8px 23px;
     margin: 0 -23px;