From mboxrd@z Thu Jan 1 00:00:00 1970 From: john at keeping.me.uk (John Keeping) Date: Sat, 3 Sep 2016 19:29:36 +0100 Subject: [RFC/PATCH 5/5] ui-tree: use render filters to display content In-Reply-To: References: Message-ID: <5f696af904ece413aead54432ce251904591ad06.1472925431.git.john@keeping.me.uk> This allows applying filters to files in the repository, for example to render Markdown or AsciiDoc as HTML. Signed-off-by: John Keeping --- cgit.css | 5 +++ cmd.c | 4 +-- ui-tree.c | 104 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++----- ui-tree.h | 2 +- 4 files changed, 105 insertions(+), 10 deletions(-) diff --git a/cgit.css b/cgit.css index a4331f8..b0970de 100644 --- a/cgit.css +++ b/cgit.css @@ -254,6 +254,11 @@ div#cgit div#blob { border: solid 1px black; } +div#cgit iframe { + width: 100%; + height: 40em; +} + div#cgit div.error { color: red; font-weight: bold; diff --git a/cmd.c b/cmd.c index 18cc980..544d705 100644 --- a/cmd.c +++ b/cmd.c @@ -131,7 +131,7 @@ static void refs_fn(void) static void source_fn(void) { - cgit_print_tree(ctx.qry.sha1, ctx.qry.path); + cgit_print_tree(ctx.qry.sha1, ctx.qry.path, false); } static void snapshot_fn(void) @@ -157,7 +157,7 @@ static void tag_fn(void) static void tree_fn(void) { - cgit_print_tree(ctx.qry.sha1, ctx.qry.path); + cgit_print_tree(ctx.qry.sha1, ctx.qry.path, true); } #define def_cmd(name, want_repo, want_vpath, is_clone) \ diff --git a/ui-tree.c b/ui-tree.c index 5c715a1..ed41c3c 100644 --- a/ui-tree.c +++ b/ui-tree.c @@ -14,6 +14,7 @@ struct walk_tree_context { char *curr_rev; char *match_path; + bool use_render; int state; }; @@ -129,11 +130,70 @@ static void print_buffer(const char *basename, char *buf, unsigned long size) print_text_buffer(basename, buf, size); } +static void render_buffer(struct cgit_filter *render, const char *name, + char *buf, unsigned long size) +{ + char *filter_arg = xstrdup(name); + + html("
"); + cgit_open_filter(render, filter_arg); + html_raw(buf, size); + cgit_close_filter(render); + html("
"); + + free(filter_arg); +} + +static void include_file(const unsigned char *sha1, const char *path, + const char *mimetype) +{ + const char *delim = "?"; + + html("
"); + + if (!strncmp(mimetype, "image/", 6)) { + html("");
+		html_attr(path);
+		html("defbranch && + strcmp(ctx.qry.head, ctx.repo->defbranch)) { + html(delim); + html("h="); + html_url_arg(ctx.qry.head); + delim = "&"; + } + + html("'>
"); +} + static void print_object(const unsigned char *sha1, char *path, - const char *basename, const char *rev) + const char *basename, const char *rev, bool use_render) { enum object_type type; - char *buf; + struct cgit_filter *render; + char *buf, *mimetype; unsigned long size; type = sha1_object_info(sha1, &size); @@ -150,17 +210,44 @@ static void print_object(const unsigned char *sha1, char *path, return; } + render = get_render_for_filename(path); + mimetype = render ? NULL : get_mimetype_for_filename(path); + set_title_from_path(path); + /* + * If we don't have a render filter or a mimetype, we won't include the + * file in the page. + */ + if (!render && !mimetype) + use_render = false; + cgit_print_layout_start(); htmlf("blob: %s (", sha1_to_hex(sha1)); cgit_plain_link("plain", NULL, NULL, ctx.qry.head, rev, path); + if (use_render) { + html(", "); + cgit_source_link("source", NULL, NULL, ctx.qry.head, + rev, path); + } else if (render || mimetype) { + html(", "); + cgit_tree_link("render", NULL, NULL, ctx.qry.head, + rev, path); + } html(")\n"); - print_buffer(basename, buf, size); -} + if (use_render) { + if (render) + render_buffer(render, basename, buf, size); + else + include_file(sha1, path, mimetype); + } else { + print_buffer(basename, buf, size); + } + free(mimetype); +} static int ls_item(const unsigned char *sha1, struct strbuf *base, const char *pathname, unsigned mode, int stage, void *cbdata) @@ -279,7 +366,9 @@ static int walk_tree(const unsigned char *sha1, struct strbuf *base, return READ_TREE_RECURSIVE; } else { walk_tree_ctx->state = 2; - print_object(sha1, buffer, pathname, walk_tree_ctx->curr_rev); + print_object(sha1, buffer, pathname, + walk_tree_ctx->curr_rev, + walk_tree_ctx->use_render); return 0; } } @@ -292,7 +381,7 @@ static int walk_tree(const unsigned char *sha1, struct strbuf *base, * rev: the commit pointing at the root tree object * path: path to tree or blob */ -void cgit_print_tree(const char *rev, char *path) +void cgit_print_tree(const char *rev, char *path, bool use_render) { unsigned char sha1[20]; struct commit *commit; @@ -306,7 +395,8 @@ void cgit_print_tree(const char *rev, char *path) }; struct walk_tree_context walk_tree_ctx = { .match_path = path, - .state = 0 + .state = 0, + .use_render = use_render, }; if (!rev) diff --git a/ui-tree.h b/ui-tree.h index bbd34e3..a0fc8e2 100644 --- a/ui-tree.h +++ b/ui-tree.h @@ -1,6 +1,6 @@ #ifndef UI_TREE_H #define UI_TREE_H -extern void cgit_print_tree(const char *rev, char *path); +extern void cgit_print_tree(const char *rev, char *path, bool use_render); #endif /* UI_TREE_H */ -- 2.10.0.rc0.142.g1e9f63b