From: Jean-Yves Migeon <jeanyves.migeon@free.fr>
To: tech@mdocml.bsd.lv
Subject: Small patch review for html begin/end inclusion files
Date: Fri, 23 Oct 2015 21:58:26 +0200 [thread overview]
Message-ID: <562A9162.8060804@free.fr> (raw)
[-- Attachment #1: Type: text/plain, Size: 1412 bytes --]
Dear list,
I am about to migrate man.netbsd.org to man.cgi to serve NetBSD's man
pages and I'd like to propose for review the attached patch that allows
handling begin/end HTML tweaks without relying on CUSTOMIZE_BEGIN.
Reason behind is that our HTML templates can evolve at any time, and
re-compiling is tedious just for manipulating the HTML code. Also HTML
navigation bars and equivalents require the use of opening (resp.
closing) div's before (resp. after) man.cgi main output, so _END
directive (or equivalent) are needed.
The attached patch implements the following:
- a CUSTOMIZE_END directive, counterpart to CUSTOMIZE_BEGIN, but inserts
the code just before the closing </BODY> anchor;
- code to "internalize" HTML code directly from two files, called
"begin.html" and "end.html" located in the same dir as manpath.conf.
Purpose here is to avoid CUSTOMIZE_BEGIN/_END hardcoding at compile-time
and put HTML code in an easier way to manipulate than multiline C strings.
I would like to see such a feature imported in man.cgi (or another kind
of templating engine if it exists). I am unsure about the way the
begin/end.html handling should happen though:
- a compile-time option, eventually combined with CUSTOMIZE_* macros;
- having a special treatment regarding ENOENT during fopen(2) to not
warn about their absence;
- some other approach... ?
Suggestions welcome.
Thanks,
--
Jean-Yves Migeon
[-- Attachment #2: cgi.c.diff --]
[-- Type: text/plain, Size: 4121 bytes --]
:qâ work/mdocml-1.13.3/cgi.c 2015-03-13 12:38:38.000000000 +0000
+++ cgi.c 2015-10-22 18:35:21.000000000 +0000
@@ -17,6 +17,7 @@
*/
#include "config.h"
+#include <sys/stat.h>
#include <sys/types.h>
#include <sys/time.h>
@@ -52,6 +53,8 @@ struct req {
struct query q;
char **p; /* array of available manpaths */
size_t psz; /* number of available manpaths */
+ char *header; /* custom HTML header */
+ char *footer; /* custom HTML footer */
};
static void catman(const struct req *, const char *);
@@ -63,6 +66,8 @@ static void http_parse(struct req *, c
static void http_print(const char *);
static void http_putchar(char);
static void http_printquery(const struct req *, const char *);
+static void internalize_file(char **, const char *);
+static void htmlgen(struct req *);
static void pathgen(struct req *);
static void pg_error_badrequest(const char *);
static void pg_error_internal(void);
@@ -76,6 +81,7 @@ static void resp_begin_html(int, const
static void resp_begin_http(int, const char *);
static void resp_end_html(void);
static void resp_searchform(const struct req *);
+static void resp_footer(const struct req *);
static void resp_show(const struct req *, const char *);
static void set_query_attr(char **, char **);
static int validate_filename(const char *);
@@ -398,7 +404,10 @@ resp_searchform(const struct req *req)
{
int i;
+ /* Write the customized HTML header */
puts(CUSTOMIZE_BEGIN);
+ if (req->header != NULL)
+ puts(req->header);
puts("<!-- Begin search form. //-->");
printf("<DIV ID=\"mancgi\">\n"
"<FORM ACTION=\"%s\" METHOD=\"get\">\n"
@@ -490,6 +499,16 @@ resp_searchform(const struct req *req)
puts("<!-- End search form. //-->");
}
+static void
+resp_footer(const struct req *req)
+{
+
+ /* Write the customized HTML footer */
+ if (req->footer != NULL)
+ puts(req->footer);
+ puts(CUSTOMIZE_END);
+}
+
static int
validate_urifrag(const char *frag)
{
@@ -544,6 +563,7 @@ pg_index(const struct req *req)
"manual explains the query syntax.\n"
"</P>\n",
scriptname, scriptname);
+ resp_footer(req);
resp_end_html();
}
@@ -555,6 +575,7 @@ pg_noresult(const struct req *req, const
puts("<P>");
puts(msg);
puts("</P>");
+ resp_footer(req);
resp_end_html();
}
@@ -678,6 +699,7 @@ pg_searchres(const struct req *req, stru
resp_show(req, r[iuse].file);
}
+ resp_footer(req);
resp_end_html();
}
@@ -931,6 +953,7 @@ pg_show(struct req *req, const char *ful
resp_begin_html(200, NULL);
resp_searchform(req);
resp_show(req, file);
+ resp_footer(req);
resp_end_html();
}
@@ -1060,6 +1083,7 @@ main(void)
memset(&req, 0, sizeof(struct req));
pathgen(&req);
+ htmlgen(&req);
/* Next parse out the query string. */
@@ -1102,10 +1126,68 @@ main(void)
for (i = 0; i < (int)req.psz; i++)
free(req.p[i]);
free(req.p);
+ free(req.header);
+ free(req.footer);
return(EXIT_SUCCESS);
}
/*
+ * Read and store content of a file located in MAN_DIR
+ */
+static void
+internalize_file(char **buf, const char *name)
+{
+ FILE *fp;
+ struct stat st;
+
+ if (NULL == (fp = fopen(name, "r"))) {
+ fprintf(stderr, "%s/%s: %s\n",
+ MAN_DIR, name, strerror(errno));
+ goto error;
+ }
+
+ if (fstat(fileno(fp), &st) != 0) {
+ fprintf(stderr, "%s/%s: %s\n",
+ MAN_DIR, name, strerror(errno));
+ goto error;
+ }
+
+ *buf = mandoc_calloc(1, st.st_size + 1);
+ if (fread(*buf, sizeof(char), st.st_size, fp) < st.st_size) {
+ if (ferror(fp)) {
+ fprintf(stderr, "%s/%s: %s\n",
+ MAN_DIR, name, strerror(errno));
+ goto error;
+ }
+ if (feof(fp)) {
+ fprintf(stderr, "%s/%s: %s\n",
+ MAN_DIR, name, "premature EOF");
+ goto error;
+ }
+ }
+ fclose(fp);
+ return;
+
+error:
+ if (fp != NULL)
+ fclose(fp);
+ free(*buf);
+ *buf = NULL;
+ return;
+}
+
+/*
+ * Scan for customized HTML header and footer
+ */
+static void
+htmlgen(struct req *req)
+{
+
+ internalize_file(&req->header, "begin.html");
+ internalize_file(&req->footer, "end.html");
+}
+
+/*
* Scan for indexable paths.
*/
static void
[-- Attachment #3: man.cgi.8.diff --]
[-- Type: text/plain, Size: 1392 bytes --]
--- work/mdocml-1.13.3/man.cgi.8 2015-03-13 12:38:38.000000000 +0000
+++ man.cgi.8 2015-10-22 19:20:42.000000000 +0000
@@ -14,7 +14,7 @@
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
.\"
-.Dd $Mdocdate: September 14 2014 $
+.Dd $Mdocdate: October 23 2015 $
.Dt MAN.CGI 8
.Os
.Sh NAME
@@ -158,6 +158,26 @@ to create a
.Xr mandoc.db 5
database inside each manpath.
.Pp
+You can optionally create a file
+.Pa /var/www/man/begin.html
+containing HTML code that will be inserted as-is right after
+the
+.Aq BODY
+element.
+It mimics the behaviour of the
+.Ev CUSTOMIZE_BEGIN
+compile-time option,
+except that the string is obtained through the file rather than
+specified during the compilation step.
+A similar file called
+.Pa /var/www/man/end.html
+will insert its HTML content right before the
+.Aq /BODY
+element,
+in the same way the
+.Ev CUSTOMIZE_END
+compile-time option would do.
+.Pp
Configure your web server to execute CGI programs located in
.Pa /cgi-bin .
When using
@@ -191,6 +211,10 @@ This is used in generated HTML code.
A HTML string to be inserted right after opening the
.Aq BODY
element.
+.It Ev CUSTOMIZE_END
+A HTML string to be inserted right before closing the
+.Aq BODY
+element.
.It Ev CUSTOMIZE_TITLE
An ASCII string to be used for the HTML
.Aq TITLE
next reply other threads:[~2015-10-23 19:58 UTC|newest]
Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-10-23 19:58 Jean-Yves Migeon [this message]
2015-11-05 21:12 ` Ingo Schwarze
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=562A9162.8060804@free.fr \
--to=jeanyves.migeon@free.fr \
--cc=tech@mdocml.bsd.lv \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).