[wiki] [sites] build-page: support gopher pages || David Gričar

From: <git_AT_suckless.org>
Date: Sat, 21 Mar 2020 01:31:28 +0100

commit dec7792fbd89c33f490cb732e6cc1a4a29476c29
Author: David Gričar <suckless_AT_coppie.xyz>
Date: Sat Mar 21 01:28:49 2020 +0100

    build-page: support gopher pages
    
    If second argument to 'build-page' is '-g' switch then gopher pages will
    be built instead of html.
    
    Gopher menus will add 'about' entries that link to 'index.md' if a
    linked directory contains both 'index.md' and subdirectories. If
    directory contains no subdirectories it will be treated as a link
    directly to 'index.md'.
    
    Current gopher page layout seems most reasonable to me. Links to domains
    have to be somewhere as there is no 'homepage' before entering any
    subdomains.
    
    Makefile will still build only html pages by default as not to break
    anything that is already in place. I also added an instruction for
    gopher pages 'make gph' for manual testing and later integration
    into default 'make'.
    
    Added gph files to '.gitignore'.

diff --git a/.gitignore b/.gitignore
index 11fe41d8..d7e29d2c 100644
--- a/.gitignore
+++ b/.gitignore
_AT_@ -1,5 +1,7 @@
 # these files are ignored by git.
 *.html
 !/*.html
+*.gph
+!/*.gph
 build-page
 test
diff --git a/Makefile b/Makefile
index d7f5b8e3..6cbf89bc 100644
--- a/Makefile
+++ b/Makefile
_AT_@ -1,7 +1,12 @@
 CFLAGS = -Wall -Wextra -std=c99 -pedantic
 LDFLAGS = -static -s
 
-all: build-page
+all: html
+
+gph: build-page
+ find * -type d -exec sh -ec './build-page "$$0" -g >$$0/index.gph' {} \;
+
+html: build-page
         find * -type d -exec sh -ec './build-page "$$0" >$$0/index.html' {} \;
 
 build-page: build-page.c
diff --git a/build-page.c b/build-page.c
index f21ecb39..1bfd1cac 100644
--- a/build-page.c
+++ b/build-page.c
_AT_@ -18,6 +18,9 @@
 #define TITLE_DEFAULT "suckless.org"
 #define DIR_MAX 1024
 
+#define GOPHER_ROW_MAX 80
+#define GOPHER_PORT 70
+
 char *html_header =
         "<!doctype html>
"
         "<html>
"
_AT_@ -43,6 +46,8 @@ char *html_nav_bar =
 
 char *html_footer = "</html>
";
 
+char *gopher_header = "suckless.org %1$s

";
+
 struct domain {
         char *label;
         char *dir;
_AT_@ -330,26 +335,165 @@ print_footer(void)
         fputs(html_footer, stdout);
 }
 
+void
+print_gopher_item(char type, char *disp, char *domain, char *path,
+ char * file, int port, int level)
+{
+ char d[GOPHER_ROW_MAX];
+ int l;
+
+ strncpy(d, disp, sizeof d);
+ memset(d+GOPHER_ROW_MAX-1, '+
+ printf("[%c|", type);
+
+ for (l = 0; l < level; ++l)
+ printf(" ");
+ print_name(d);
+ if (type == '1')
+ putchar('/');
+ putchar('|');
+
+ if (path)
+ printf("/%s", path);
+ if (file)
+ printf("/%s", file);
+
+ printf("|%s|%d]
", domain, port);
+}
+
+void
+print_gopher_header(void)
+{
+ char title[GOPHER_ROW_MAX];
+
+ printf(gopher_header, oneline(title, sizeof(title), ".title") ?
+ title : TITLE_DEFAULT);
+}
+
+int
+has_index(char *this)
+{
+ DIR *dp;
+ struct dirent *de;
+ char newdir[PATH_MAX];
+ int index;
+
+ if ((dp = opendir(this ? this : ".")) == NULL)
+ die_perror("opendir: %s", this ? this : ".");
+
+ index = 0;
+ while (index == 0 && (de = readdir(dp))) {
+ if (de->d_name[0] == '.')
+ continue;
+ snprintf(newdir, sizeof(newdir), this ? "%2$s/%1$s" : "%s", de->d_name, this);
+ if (stat_isfile(newdir) && strcmp(de->d_name, "index.md") == 0)
+ index = 1;
+ }
+ closedir(dp);
+
+ return index;
+}
+
+void
+print_gopher_menu(char *domain, char *this)
+{
+ DIR *dp;
+ struct dirent *de;
+ char newdir[PATH_MAX];
+ char *d_list[DIR_MAX], *d;
+ size_t d_len, l;
+ int depth = this ? 1 : 0;
+
+ if ((dp = opendir(this ? this : ".")) == NULL)
+ die_perror("opendir: %s", this ? this : ".");
+
+ d_len = 0;
+ while (d_len < LEN(d_list) && (de = readdir(dp))) {
+ d_list[d_len++] = xstrdup(de->d_name);
+ }
+ closedir(dp);
+
+ qsort(d_list, d_len, sizeof *d_list, qsort_strcmp);
+
+ printf("%s/
", this ? this : "");
+
+ if (has_index(this))
+ print_gopher_item('0', "about", domain, this ? this : NULL,
+ "index.md", GOPHER_PORT, depth);
+
+ for (l = 0; l < d_len; free(d_list[l++])) {
+ d = d_list[l];
+ if (*d == '.')
+ continue;
+ snprintf(newdir, sizeof(newdir), this ? "%2$s/%1$s" : "%s",
+ d, this);
+ if (!stat_isdir(newdir))
+ continue;
+
+ if (has_subdirs(newdir))
+ print_gopher_item('1', d, domain, newdir, NULL,
+ GOPHER_PORT, depth);
+ else
+ print_gopher_item('0', d, domain, newdir, "index.md",
+ GOPHER_PORT, depth);
+ }
+}
+
+void
+print_gopher_nav(char *domain)
+{
+ struct domain *d;
+
+ for (d = domain_list; d->dir; ++d) {
+ if (strcmp(domain, d->dir) == 0)
+ printf("%s
", d->label);
+ else
+ print_gopher_item('1', d->label, d->dir, NULL, NULL,
+ GOPHER_PORT, 0);
+ }
+
+ putchar('
');
+ print_gopher_item('1', "download", "dl.suckless.org", NULL, NULL,
+ GOPHER_PORT, 0);
+ print_gopher_item('1', "source", "git.suckless.org", NULL, NULL,
+ GOPHER_PORT, 0);
+}
+
 int
 main(int argc, char *argv[])
 {
         char *domain, *page;
+ int gopher = 0;
 
- if (argc != 2)
- die("usage: %s directory", argv[0]);
- if ((page = strchr(argv[1], '/')))
+ if (argc != 2) {
+ if (argc != 3 || (strcmp(argv[2], "-g") != 0))
+ die("usage: %s directory [-g]", argv[0]);
+ gopher = 1;
+ }
+ if ((page = strchr(argv[1], '/'))) {
                 *page++ = '+ if (strlen(page) == 0)
+ page = NULL;
+ }
         domain = argv[1];
         if (chdir(domain) == -1)
                 die_perror("chdir: %s", domain);
 
- print_header();
- print_nav_bar(domain);
- puts("<div id=\"content\">");
- print_menu_panel(domain, page);
- print_content(domain, page);
- puts("</div>
");
- print_footer();
+ if (gopher) {
+ print_gopher_header();
+ print_gopher_menu(domain, page);
+ printf("-------------
");
+ print_gopher_nav(domain);
+ } else {
+ print_header();
+ print_nav_bar(domain);
+ puts("<div id=\"content\">");
+ print_menu_panel(domain, page);
+ print_content(domain, page);
+ puts("</div>
");
+ print_footer();
+ }
 
         return 0;
 }
Received on Sat Mar 21 2020 - 01:31:28 CET

This archive was generated by hypermail 2.3.0 : Sat Mar 21 2020 - 01:36:47 CET