From: Jaroslav Kysela Date: Tue, 29 Mar 2016 16:08:36 +0000 (+0200) Subject: webui: add missing doc_md.c X-Git-Tag: v4.2.1~781 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=2ce0ba8c0c3542736408c4669cafd8d25d0b3707;p=thirdparty%2Ftvheadend.git webui: add missing doc_md.c --- diff --git a/src/webui/doc_md.c b/src/webui/doc_md.c new file mode 100644 index 000000000..63f8d7846 --- /dev/null +++ b/src/webui/doc_md.c @@ -0,0 +1,196 @@ +/* + * tvheadend, documenation markdown generator + * Copyright (C) 2016 Jaroslav Kysela + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "tvheadend.h" +#include "config.h" +#include "webui.h" +#include "http.h" + +/* */ +static int +md_nl(htsbuf_queue_t *hq, int nl) +{ + if (nl) + htsbuf_append(hq, "\n", 1); + return 1; +} + +/* */ +static void +md_header(htsbuf_queue_t *hq, const char *prefix, const char *s) +{ + htsbuf_append_str(hq, prefix); + htsbuf_append_str(hq, s); + htsbuf_append(hq, "\n", 1); +} + +/* */ +static void +md_style(htsbuf_queue_t *hq, const char *style, const char *s) +{ + size_t l = strlen(style); + htsbuf_append(hq, style, l); + htsbuf_append_str(hq, s); + htsbuf_append(hq, style, l); +} + +/* */ +static void +md_text(htsbuf_queue_t *hq, const char *first, const char *next, const char *text) +{ + char *s, *t, *p; + int col, nl; + + t = s = p = tvh_strdupa(text); + col = nl = 0; + while (*s) { + if (++col > 74) { + nl = md_nl(hq, nl); + if (first) { + htsbuf_append_str(hq, first); + first = NULL; + } else if (next) { + htsbuf_append_str(hq, next); + } + if (p <= t) + p = t + 74; + htsbuf_append(hq, t, p - t); + col = 0; + t = s = p; + } else if (*s <= ' ') { + *s = ' '; + p = ++s; + } else { + s++; + } + } + if (t < s) { + md_nl(hq, nl); + if (first) + htsbuf_append_str(hq, first); + else if (next) + htsbuf_append_str(hq, next); + htsbuf_append(hq, t, s - t); + } +} + +/** + * List of all classes with documentation + */ +static int +http_markdown_classes(http_connection_t *hc) +{ + idclass_t const **all, **all2; + const idclass_t *ic; + htsbuf_queue_t *hq = &hc->hc_reply; + + pthread_mutex_lock(&global_lock); + all = idclass_find_all(); + if (all == NULL) { + pthread_mutex_unlock(&global_lock); + return HTTP_STATUS_NOT_FOUND; + } + for (all2 = all; *all2; all2++) { + ic = *all2; + if (ic->ic_caption) { + htsbuf_append_str(hq, ic->ic_class); + htsbuf_append(hq, "\n", 1); + } + } + pthread_mutex_unlock(&global_lock); + + free(all); + return 0; +} + +/** + * + */ +static int +http_markdown_class(http_connection_t *hc, const char *clazz) +{ + const idclass_t *ic; + const char *lang = hc->hc_access->aa_lang_ui; + htsbuf_queue_t *hq = &hc->hc_reply; + htsmsg_t *m, *l, *n; + htsmsg_field_t *f; + const char *s; + int nl = 0; + + pthread_mutex_lock(&global_lock); + ic = idclass_find(clazz); + if (ic == NULL) { + pthread_mutex_unlock(&global_lock); + return HTTP_STATUS_NOT_FOUND; + } + m = idclass_serialize(ic, lang); + pthread_mutex_unlock(&global_lock); + s = htsmsg_get_str(m, "caption"); + if (s) { + md_header(hq, "####", s); + nl = 1; + } + l = htsmsg_get_list(m, "props"); + HTSMSG_FOREACH(f, l) { + n = htsmsg_field_get_map(f); + if (!n) continue; + s = htsmsg_get_str(n, "caption"); + if (s) { + nl = md_nl(hq, nl); + md_style(hq, "**", s); + md_nl(hq, 1); + } + s = htsmsg_get_str(n, "description"); + if (s) { + nl = md_nl(hq, nl); + md_text(hq, ": ", " ", s); + md_nl(hq, 1); + } + } + htsmsg_destroy(m); + return 0; +} + +/** + * Handle requests for markdown export. + */ +int +page_markdown(http_connection_t *hc, const char *remain, void *opaque) +{ + char *components[2]; + int nc, r; + + nc = http_tokenize((char *)remain, components, 2, '/'); + if (!nc) + return HTTP_STATUS_BAD_REQUEST; + + if (nc == 2) + http_deescape(components[1]); + + if (nc == 1 && !strcmp(components[0], "classes")) + r = http_markdown_classes(hc); + else if (nc == 2 && !strcmp(components[0], "class")) + r = http_markdown_class(hc, components[1]); + else + r = HTTP_STATUS_BAD_REQUEST; + + if (r == 0) + http_output_content(hc, "text/xml"); + + return r; +}