[PATCH 03/11] Parse render filters from the config

Andy Green andy at warmcat.com
Wed Jun 13 04:01:45 CEST 2018


From: John Keeping <john at keeping.me.uk>

Render filters will be used to present rendered content in the tree
view, for example to display Markdown source rendered as HTML.

We will add support for using these from the tree view in the following
commits.

Signed-off-by: John Keeping <john at keeping.me.uk>
---
 cgit.c       |   19 +++++++++++++++++--
 cgit.h       |    4 +++-
 cgitrc.5.txt |   18 ++++++++++++++++++
 filter.c     |    1 +
 shared.c     |   21 +++++++++++++++++++++
 5 files changed, 60 insertions(+), 3 deletions(-)

diff --git a/cgit.c b/cgit.c
index b37d3e0..975e573 100644
--- a/cgit.c
+++ b/cgit.c
@@ -27,6 +27,18 @@ static void add_mimetype(const char *name, const char *value)
 	item->util = xstrdup(value);
 }
 
+static void add_render_filter(const char *name, const char *cmd)
+{
+	struct string_list_item *item;
+	struct cgit_filter *filter = cgit_new_filter(cmd, RENDER);
+
+	if (!filter)
+		return;
+
+	item = string_list_insert(&ctx.cfg.render_filters, name);
+	item->util = filter;
+}
+
 static void process_cached_repolist(const char *path);
 
 static void repo_config(struct cgit_repo *repo, const char *name, const char *value)
@@ -285,8 +297,10 @@ static void config_cb(const char *name, const char *value)
 			ctx.cfg.branch_sort = 1;
 		if (!strcmp(value, "name"))
 			ctx.cfg.branch_sort = 0;
-	} else if (skip_prefix(name, "mimetype.", &arg))
-		add_mimetype(arg, value);
+	} else if (starts_with(name, "mimetype."))
+		add_mimetype(name + 9, value);
+	else if (starts_with(name, "render."))
+		add_render_filter(name + 7, value);
 	else if (!strcmp(name, "include"))
 		parse_configfile(expand_macros(value), config_cb);
 }
@@ -420,6 +434,7 @@ static void prepare_context(void)
 	ctx.page.expires = ctx.page.modified;
 	ctx.page.etag = NULL;
 	string_list_init(&ctx.cfg.mimetypes, 1);
+	string_list_init(&ctx.cfg.render_filters, 1);
 	if (ctx.env.script_name)
 		ctx.cfg.script_name = xstrdup(ctx.env.script_name);
 	if (ctx.env.query_string)
diff --git a/cgit.h b/cgit.h
index 005ae63..a19742f 100644
--- a/cgit.h
+++ b/cgit.h
@@ -55,7 +55,7 @@ typedef enum {
 } diff_type;
 
 typedef enum {
-	ABOUT, COMMIT, SOURCE, EMAIL, AUTH, OWNER
+	ABOUT, COMMIT, SOURCE, EMAIL, AUTH, OWNER, RENDER
 } filter_type;
 
 struct cgit_filter {
@@ -261,6 +261,7 @@ struct cgit_config {
 	int branch_sort;
 	int commit_sort;
 	struct string_list mimetypes;
+	struct string_list render_filters;
 	struct cgit_filter *about_filter;
 	struct cgit_filter *commit_filter;
 	struct cgit_filter *source_filter;
@@ -389,5 +390,6 @@ extern int readfile(const char *path, char **buf, size_t *size);
 extern char *expand_macros(const char *txt);
 
 extern char *get_mimetype_for_filename(const char *filename);
+extern struct cgit_filter *get_render_for_filename(const char *filename);
 
 #endif /* CGIT_H */
diff --git a/cgitrc.5.txt b/cgitrc.5.txt
index 4da166c..793a0c1 100644
--- a/cgitrc.5.txt
+++ b/cgitrc.5.txt
@@ -359,6 +359,17 @@ renamelimit::
 	 "-1" uses the compiletime value in git (for further info, look at
 	  `man git-diff`). Default value: "-1".
 
+render.<ext>::
+	Specifies a command which will be invoked to render files with the
+	extension `.<ext>`. The command will get the blob content on its STDIN
+	and the name of the blob as its only command line argument. The STDOUT
+	from the command will be included verbatim in the page content. If no
+	render filter is available for a given file extension but the mimetype
+	is specified then the content will be included as an iframe, otherwise
+	the normal source rendering will be used.
++
+Default value: none. See also: "FILTER API".
+
 repo.group::
 	Legacy alias for "section". This option is deprecated and will not be
 	supported in cgit-1.0.
@@ -699,6 +710,13 @@ source filter::
 	file that is to be filtered is available on standard input and the
 	filtered contents is expected on standard output.
 
+render filter::
+	This filter is given a single parameter: the filename of the source
+	file to render. The filter can use the filename to determine (for
+	example) the syntax highlighting mode. The contents of the file that
+	is to be rendered is available on standard input and the rendered
+	content is expected on standard output.
+
 auth filter::
 	The authentication filter receives 12 parameters:
 	  - filter action, explained below, which specifies which action the
diff --git a/filter.c b/filter.c
index 70f5b74..4ae4aaa 100644
--- a/filter.c
+++ b/filter.c
@@ -434,6 +434,7 @@ struct cgit_filter *cgit_new_filter(const char *cmd, filter_type filtertype)
 
 		case SOURCE:
 		case ABOUT:
+		case RENDER:
 			argument_count = 1;
 			break;
 
diff --git a/shared.c b/shared.c
index 477db0a..128c323 100644
--- a/shared.c
+++ b/shared.c
@@ -571,3 +571,24 @@ char *get_mimetype_for_filename(const char *filename)
 	fclose(file);
 	return NULL;
 }
+
+struct cgit_filter *get_render_for_filename(const char *filename)
+{
+	char *ext;
+	struct string_list_item *item;
+
+	if (!filename)
+		return NULL;
+
+	ext = strrchr(filename, '.');
+	if (!ext)
+		return NULL;
+	++ext;
+	if (!ext[0])
+		return NULL;
+	item = string_list_lookup(&ctx.cfg.render_filters, ext);
+	if (item)
+		return item->util;
+
+	return NULL;
+}



More information about the CGit mailing list