[PATCH v3 05/17] Parse render filters from the config

Andy Green andy at warmcat.com
Tue Jun 19 11:01:51 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.

AG: adapted so render.= can be used to specify the filter for files
without any suffix

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

diff --git a/cgit.c b/cgit.c
index 0c9f3e9..e0e94d5 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)
@@ -281,8 +293,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);
 }
@@ -415,6 +429,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 6feca68..3149946 100644
--- a/cgit.h
+++ b/cgit.h
@@ -57,7 +57,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;
@@ -391,5 +392,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 f6f6502..34b6186 100644
--- a/cgitrc.5.txt
+++ b/cgitrc.5.txt
@@ -342,6 +342,18 @@ 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.  Note <ext> may be empty, in
+	which case the render filter is used on files with no suffix.
++
+Default value: none. See also: "FILTER API".
+
 repository-sort::
 	The way in which repositories in each section are sorted. Valid values
 	are "name" for sorting by the repo name or "age" for sorting by the
@@ -705,6 +717,13 @@ owner filter::
 	standard input and the filter is expected to write to standard
 	output.  The output is included in the Owner column.
 
+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.
+
 source filter::
 	This filter is given a single parameter: the filename of the source
 	file to filter. The filter can use the filename to determine (for
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 d7c7636..665f8ed 100644
--- a/shared.c
+++ b/shared.c
@@ -574,3 +574,22 @@ 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)
+		ext = ".";
+	++ext;
+	item = string_list_lookup(&ctx.cfg.render_filters, ext);
+	if (item)
+		return item->util;
+
+	return NULL;
+}



More information about the CGit mailing list