lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <1441656124-8997-3-git-send-email-danilo.cesar@collabora.co.uk>
Date:	Mon,  7 Sep 2015 17:02:00 -0300
From:	Danilo Cesar Lemes de Paula <danilo.cesar@...labora.co.uk>
To:	Jonathan Corbet <corbet@....net>
Cc:	Danilo Cesar Lemes de Paula <danilo.cesar@...labora.co.uk>,
	Randy Dunlap <rdunlap@...radead.org>,
	Daniel Vetter <daniel.vetter@...ll.ch>,
	Laurent Pinchart <laurent.pinchart@...asonboard.com>,
	Herbert Xu <herbert@...dor.apana.org.au>,
	Stephan Mueller <smueller@...onox.de>,
	Michal Marek <mmarek@...e.cz>, linux-kernel@...r.kernel.org,
	linux-doc@...r.kernel.org,
	intel-gfx <intel-gfx@...ts.freedesktop.org>,
	dri-devel <dri-devel@...ts.freedesktop.org>
Subject: [PATCH 2/6] scripts/kernel-doc: Adding infrastructure for markdown support

Markdown support is given by calling an external tool, pandoc, for all
highlighted text on kernel-doc.

Pandoc converts Markdown text to proper Docbook tags, which will be
later translated to pdf, html or other targets.

This adds the capability of adding human-readle text highlight (bold,
underline, etc), bullet and numbered lists, simple tables, fixed-width
text (including asciiart), requiring minimal changes to current
documentation.

At this moment, pandoc is totally optional. Docbooks ready for markdown
should be added to the MARKDOWNREADY variable inside the Makefile. In
case the developer doesn't have pandoc installed, Make will throw a
warning and the documentation build will continue, generating
simple Documentation without the features brought by pandoc.

Signed-off-by: Danilo Cesar Lemes de Paula <danilo.cesar@...labora.co.uk>
Cc: Randy Dunlap <rdunlap@...radead.org>
Cc: Daniel Vetter <daniel.vetter@...ll.ch>
Cc: Laurent Pinchart <laurent.pinchart@...asonboard.com>
Cc: Jonathan Corbet <corbet@....net>
Cc: Herbert Xu <herbert@...dor.apana.org.au>
Cc: Stephan Mueller <smueller@...onox.de>
Cc: Michal Marek <mmarek@...e.cz>
Cc: linux-kernel@...r.kernel.org
Cc: linux-doc@...r.kernel.org
Cc: intel-gfx <intel-gfx@...ts.freedesktop.org>
Cc: dri-devel <dri-devel@...ts.freedesktop.org>
---
 Documentation/DocBook/Makefile | 25 +++++++++++-----
 scripts/docproc.c              | 54 ++++++++++++++++++++++++----------
 scripts/kernel-doc             | 66 ++++++++++++++++++++++++++++++++++++++++--
 3 files changed, 119 insertions(+), 26 deletions(-)

diff --git a/Documentation/DocBook/Makefile b/Documentation/DocBook/Makefile
index 93eff64..c1ff834 100644
--- a/Documentation/DocBook/Makefile
+++ b/Documentation/DocBook/Makefile
@@ -17,6 +17,8 @@ DOCBOOKS := z8530book.xml device-drivers.xml \
 	    tracepoint.xml drm.xml media_api.xml w1.xml \
 	    writing_musb_glue_layer.xml crypto-API.xml iio.xml
 
+MARKDOWNREADY := 
+
 include Documentation/DocBook/media/Makefile
 
 ###
@@ -81,18 +83,23 @@ XMLTOFLAGS += --skip-validation
 # The following rules are used to generate the .xml documentation
 # required to generate the final targets. (ps, pdf, html).
 quiet_cmd_docproc = DOCPROC $@
-      cmd_docproc = SRCTREE=$(srctree)/ $(DOCPROC) doc $< >$@
+      cmd_docproc = SRCTREE=$(srctree)/ $(DOCPROC) doc $<
 define rule_docproc
-	set -e;								\
-        $(if $($(quiet)cmd_$(1)),echo '  $($(quiet)cmd_$(1))';) 	\
-        $(cmd_$(1)); 							\
-        ( 								\
-          echo 'cmd_$@ := $(cmd_$(1))'; 				\
-          echo $@: `SRCTREE=$(srctree) $(DOCPROC) depend $<`; 		\
+	set -e;									\
+	USEMARKDOWN="";								\
+	FILE=`basename $@`;							\
+	[[ "$(MARKDOWNREADY)" =~ "$${FILE}" ]] && USEMARKDOWN="-use-markdown";	\
+        $(if $($(quiet)cmd_$(1)),echo '  $($(quiet)cmd_$(1))';) 		\
+        $(cmd_$(1)) $$USEMARKDOWN >$@;						\
+        ( 									\
+          echo 'cmd_$@ := $(cmd_$(1))';				 		\
+          echo $@: `SRCTREE=$(srctree) $(DOCPROC) depend $<`;			\
         ) > $(dir $@).$(notdir $@).cmd
 endef
 
 %.xml: %.tmpl $(KERNELDOC) $(DOCPROC) $(KERNELDOCXMLREF) FORCE
+	@(which pandoc > /dev/null 2>&1) || \
+	(echo "*** To get propper documentation you need to install pandoc ***";)
 	$(call if_changed_rule,docproc)
 
 # Tell kbuild to always build the programs
@@ -103,6 +110,10 @@ notfoundtemplate = echo "*** You have to install docbook-utils or xmlto ***"; \
 db2xtemplate = db2TYPE -o $(dir $@) $<
 xmltotemplate = xmlto TYPE $(XMLTOFLAGS) -o $(dir $@) $<
 
+ifneq ($(shell which pandoc >/dev/null 2>&1 && echo found),found)
+	MARKDOWNREADY := "";
+endif
+
 # determine which methods are available
 ifeq ($(shell which db2ps >/dev/null 2>&1 && echo found),found)
 	use-db2x = db2x
diff --git a/scripts/docproc.c b/scripts/docproc.c
index e267e621..7c6b225 100644
--- a/scripts/docproc.c
+++ b/scripts/docproc.c
@@ -73,12 +73,15 @@ FILELINE * docsection;
 #define NOFUNCTION    "-nofunction"
 #define NODOCSECTIONS "-no-doc-sections"
 #define SHOWNOTFOUND  "-show-not-found"
+#define USEMARKDOWN   "-use-markdown"
 
 static char *srctree, *kernsrctree;
 
 static char **all_list = NULL;
 static int all_list_len = 0;
 
+static int use_markdown = 0;
+
 static void consume_symbol(const char *sym)
 {
 	int i;
@@ -95,10 +98,11 @@ static void consume_symbol(const char *sym)
 
 static void usage (void)
 {
-	fprintf(stderr, "Usage: docproc {doc|depend} file\n");
+	fprintf(stderr, "Usage: docproc {doc|depend} [-use-markdown] file\n");
 	fprintf(stderr, "Input is read from file.tmpl. Output is sent to stdout\n");
 	fprintf(stderr, "doc: frontend when generating kernel documentation\n");
 	fprintf(stderr, "depend: generate list of files referenced within file\n");
+	fprintf(stderr, "-use-markdown: pass -use-markdown to kernel-doc\n");
 	fprintf(stderr, "Environment variable SRCTREE: absolute path to sources.\n");
 	fprintf(stderr, "                     KBUILD_SRC: absolute path to kernel source tree.\n");
 }
@@ -257,12 +261,15 @@ static void docfunctions(char * filename, char * type)
 
 	for (i=0; i <= symfilecnt; i++)
 		symcnt += symfilelist[i].symbolcnt;
-	vec = malloc((2 + 2 * symcnt + 3) * sizeof(char *));
+	vec = malloc((2 + 2 * symcnt + 4) * sizeof(char *));
 	if (vec == NULL) {
 		perror("docproc: ");
 		exit(1);
 	}
 	vec[idx++] = KERNELDOC;
+	if (use_markdown)
+		vec[idx++] = USEMARKDOWN;
+
 	vec[idx++] = DOCBOOK;
 	vec[idx++] = NODOCSECTIONS;
 	for (i=0; i < symfilecnt; i++) {
@@ -294,6 +301,9 @@ static void singfunc(char * filename, char * line)
 	int i, idx = 0;
 	int startofsym = 1;
 	vec[idx++] = KERNELDOC;
+	if (use_markdown)
+		vec[idx++] = USEMARKDOWN;
+
 	vec[idx++] = DOCBOOK;
 	vec[idx++] = SHOWNOTFOUND;
 
@@ -328,8 +338,9 @@ static void singfunc(char * filename, char * line)
 static void docsect(char *filename, char *line)
 {
 	/* kerneldoc -docbook -show-not-found -function "section" file NULL */
-	char *vec[7];
+	char *vec[8];
 	char *s;
+	int idx = 0;
 
 	for (s = line; *s; s++)
 		if (*s == '\n')
@@ -342,30 +353,37 @@ static void docsect(char *filename, char *line)
 	consume_symbol(s);
 	free(s);
 
-	vec[0] = KERNELDOC;
-	vec[1] = DOCBOOK;
-	vec[2] = SHOWNOTFOUND;
-	vec[3] = FUNCTION;
-	vec[4] = line;
-	vec[5] = filename;
-	vec[6] = NULL;
+	vec[idx++] = KERNELDOC;
+	if (use_markdown)
+		vec[idx++] = USEMARKDOWN;
+
+	vec[idx++] = DOCBOOK;
+	vec[idx++] = SHOWNOTFOUND;
+	vec[idx++] = FUNCTION;
+	vec[idx++] = line;
+	vec[idx++] = filename;
+	vec[idx] = NULL;
 	exec_kernel_doc(vec);
 }
 
 static void find_all_symbols(char *filename)
 {
-	char *vec[4]; /* kerneldoc -list file NULL */
+	char *vec[5]; /* kerneldoc -list file NULL */
 	pid_t pid;
 	int ret, i, count, start;
 	char real_filename[PATH_MAX + 1];
 	int pipefd[2];
 	char *data, *str;
 	size_t data_len = 0;
+	int idx = 0;
+
+	vec[idx++] = KERNELDOC;
+	if (use_markdown)
+		vec[idx++] = USEMARKDOWN;
 
-	vec[0] = KERNELDOC;
-	vec[1] = LIST;
-	vec[2] = filename;
-	vec[3] = NULL;
+	vec[idx++] = LIST;
+	vec[idx++] = filename;
+	vec[idx] = NULL;
 
 	if (pipe(pipefd)) {
 		perror("pipe");
@@ -509,7 +527,7 @@ int main(int argc, char *argv[])
 	kernsrctree = getenv("KBUILD_SRC");
 	if (!kernsrctree || !*kernsrctree)
 		kernsrctree = srctree;
-	if (argc != 3) {
+	if (argc < 3 || argc > 4) {
 		usage();
 		exit(1);
 	}
@@ -521,6 +539,10 @@ int main(int argc, char *argv[])
 		exit(2);
 	}
 
+	if (argc == 4 && strcmp("-use-markdown", argv[3]) == 0) {
+		use_markdown = 1;
+	}
+
 	if (strcmp("doc", argv[1]) == 0) {
 		/* Need to do this in two passes.
 		 * First pass is used to collect all symbols exported
diff --git a/scripts/kernel-doc b/scripts/kernel-doc
index 0affe4f..5fe572a 100755
--- a/scripts/kernel-doc
+++ b/scripts/kernel-doc
@@ -1,6 +1,7 @@
 #!/usr/bin/perl -w
 
 use strict;
+use IPC::Open3;
 
 ## Copyright (c) 1998 Michael Zucchi, All Rights Reserved        ##
 ## Copyright (C) 2000, 1  Tim Waugh <twaugh@...hat.com>          ##
@@ -282,6 +283,7 @@ if ($#ARGV == -1) {
 
 my $kernelversion;
 my $dohighlight = "";
+my $use_markdown = 0;
 
 my $verbose = 0;
 my $output_mode = "man";
@@ -424,6 +426,8 @@ while ($ARGV[0] =~ m/^-(.*)/) {
 	$function_only = 2;
 	$function = shift @ARGV;
 	$function_table{$function} = 1;
+    } elsif ($cmd eq "-use-markdown") {
+	$use_markdown = 1;
     } elsif ($cmd eq "-v") {
 	$verbose = 1;
     } elsif (($cmd eq "-h") || ($cmd eq "--help")) {
@@ -442,6 +446,7 @@ sub usage {
     print "         [ -no-doc-sections ]\n";
     print "         [ -function funcname [ -function funcname ...] ]\n";
     print "         [ -nofunction funcname [ -nofunction funcname ...] ]\n";
+    print "         [ -use-markdown ]\n";
     print "         [ -v ]\n";
     print "         c source file(s) > outputfile\n";
     print "         -v : verbose output, more warnings & other info listed\n";
@@ -515,6 +520,49 @@ sub dump_doc_section {
     }
 }
 
+sub markdown_to_docbook {
+	my $orig_content = $_[0];
+
+	my $pid = open3( \*CHLD_IN, \*CHLD_OUT, \*CHLD_ERR, "pandoc  --columns=80 -f markdown -t docbook" );
+
+	print CHLD_IN "$orig_content";
+	close(CHLD_IN);
+
+	waitpid($pid, 0);
+
+	my $content = "";
+	chomp(my @lines = <CHLD_OUT>);
+	foreach my $line (@lines) {
+		$content .= $line . "\n";
+	}
+	close(CHLD_OUT);
+	close(CHLD_ERR);
+
+	# pandoc insists in adding Main <para></para>, we should remove them.
+	$content =~ s:\A\s*<para>\s*\n(.*)\n</para>\Z$:$1:egsm;
+
+	return $content;
+}
+
+# Markdown->Docbook conversion by pandoc requires unescaped text
+# Kernel-doc converts every & to "&amp;", we need to convert it back.
+sub markdown_unescape
+{
+	my $text = shift;
+	my @lines = split /\n/, $text;
+
+	my @result;
+	foreach my $line (@lines) {
+		if ( $line =~ m /^    /s ) {
+			$line =~ s:\&amp;:\&:gs
+		}
+		push @result, $line;
+	}
+
+	return join "\n",@result;
+
+}
+
 ##
 # output function
 #
@@ -541,11 +589,19 @@ sub output_highlight {
 	$contents = local_unescape($contents);
 	# convert data read & converted thru xml_escape() into &xyz; format:
 	$contents =~ s/\\\\\\/\&/g;
+
+	if ($use_markdown) {
+		$contents = markdown_unescape($contents);
+	}
     }
+
 #   print STDERR "contents b4:$contents\n";
     eval $dohighlight;
     die $@ if $@;
 #   print STDERR "contents af:$contents\n";
+    if ($use_markdown) {
+        $contents = markdown_to_docbook($contents);
+    }
 
 #   strip whitespaces when generating html5
     if ($output_mode eq "html5") {
@@ -553,7 +609,8 @@ sub output_highlight {
 	$contents =~ s/\s+$//;
     }
     foreach $line (split "\n", $contents) {
-	if (! $output_preformatted) {
+	if (! $output_preformatted &&
+	    !($use_markdown && $line =~ m /^    /s)) {
 	    $line =~ s/^\s*//;
 	}
 	if ($line eq ""){
@@ -974,7 +1031,9 @@ sub output_section_xml(%) {
 	print "<refsect1>\n";
 	print "<title>$section</title>\n";
 	if ($section =~ m/EXAMPLE/i) {
-	    print "<informalexample><programlisting>\n";
+	    print "<informalexample>\n";
+	    # programlisting is already included by pandoc
+	    print "<programlisting>\n" unless $use_markdown;
 	    $output_preformatted = 1;
 	} else {
 	    print "<para>\n";
@@ -982,7 +1041,8 @@ sub output_section_xml(%) {
 	output_highlight($args{'sections'}{$section});
 	$output_preformatted = 0;
 	if ($section =~ m/EXAMPLE/i) {
-	    print "</programlisting></informalexample>\n";
+	    print "</programlisting>\n" unless $use_markdown;
+	    print "</informalexample>\n";
 	} else {
 	    print "</para>\n";
 	}
-- 
2.4.3

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ