From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S965144AbcAZMJL (ORCPT ); Tue, 26 Jan 2016 07:09:11 -0500 Received: from mga02.intel.com ([134.134.136.20]:60829 "EHLO mga02.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S934455AbcAZMJD (ORCPT ); Tue, 26 Jan 2016 07:09:03 -0500 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.22,350,1449561600"; d="scan'208";a="901340150" From: Jani Nikula To: Jonathan Corbet , linux-doc@vger.kernel.org Cc: linux-kernel@vger.kernel.org, Jani Nikula , Daniel Vetter Subject: [RFC 02/10] kernel-doc: add support for asciidoc output Date: Tue, 26 Jan 2016 14:08:47 +0200 Message-Id: X-Mailer: git-send-email 2.1.4 In-Reply-To: References: <1453764522-29030-1-git-send-email-corbet@lwn.net> In-Reply-To: References: Organization: Intel Finland Oy - BIC 0357606-4 - Westendinkatu 7, 02160 Espoo Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Add new -asciidoc option to produce asciidoc output from kernel-doc. The output is formatted internally, with no dependencies on external tools. Any asciidoc formatting present in kernel-doc will naturally be present in the resulting asciidoc as well. Highlighting of functions(), &struct structures, &enum enumerations, @parameters, etc. will be done by means of asciidoc. Anchors and cross-references are added as well, providing hyperlinking support in the result processed by asciidoc(1). This support is non-conflicting and orthogonal to the patches adding asciidoc support to the kernel-doc DocBook output [1]. Those patches bolt on to the current document generation pipeline; there is currently none for native asciidoc in the kernel (though ideas have been discussed [2]). At this time, this patch should be considered a worthwhile standalone improvement to kernel-doc, independent of the rest. [1] http://mid.gmane.org/1448471279-19748-1-git-send-email-daniel.vetter@ffwll.ch [2] http://mid.gmane.org/20160114131823.2ff43a0c@lwn.net Cc: Jonathan Corbet Cc: Daniel Vetter Signed-off-by: Jani Nikula --- scripts/kernel-doc | 238 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 238 insertions(+) diff --git a/scripts/kernel-doc b/scripts/kernel-doc index 29fd5cabb657..15077f910e81 100755 --- a/scripts/kernel-doc +++ b/scripts/kernel-doc @@ -50,6 +50,7 @@ The documentation comments are identified by "/**" opening comment mark. See Documentation/kernel-doc-nano-HOWTO.txt for the documentation comment syntax. Output format selection (mutually exclusive): + -asciidoc Output AsciiDoc format. -docbook Output DocBook format. -html Output HTML format. -html5 Output HTML5 format. @@ -203,6 +204,8 @@ my $type_param = '\@(\w+)'; my $type_struct = '\&((struct\s*)*[_\w]+)'; my $type_struct_xml = '\\&((struct\s*)*[_\w]+)'; my $type_env = '(\$\w+)'; +my $type_enum_full = '\&(enum)\s*([_\w]+)'; +my $type_struct_full = '\&(struct)\s*([_\w]+)'; # Output conversion substitutions. # One for each output format @@ -268,6 +271,17 @@ my @highlights_text = ( ); my $blankline_text = ""; +# asciidoc-mode +my @highlights_asciidoc = ( + [$type_constant, "`\$1`"], + [$type_func, "<>"], + [$type_struct_full, "<<\$1_\$2,`\$1 \$2`>>"], + [$type_enum_full, "<<\$1_\$2,`\$1 \$2`>>"], + [$type_struct, "<>"], + [$type_param, "*\$1*"] + ); +my $blankline_asciidoc = "\n"; + # list mode my @highlights_list = ( [$type_constant, "\$1"], @@ -404,6 +418,10 @@ while ($ARGV[0] =~ m/^-(.*)/) { $output_mode = "text"; @highlights = @highlights_text; $blankline = $blankline_text; + } elsif ($cmd eq "-asciidoc") { + $output_mode = "asciidoc"; + @highlights = @highlights_asciidoc; + $blankline = $blankline_asciidoc; } elsif ($cmd eq "-docbook") { $output_mode = "xml"; @highlights = @highlights_xml; @@ -1704,6 +1722,214 @@ sub output_blockhead_text(%) { } } +## +# output in asciidoc +sub output_highlight_asciidoc { + my $contents = join "\n",@_; + my $line; + + # undo the evil effects of xml_escape() earlier + $contents = xml_unescape($contents); + + eval $dohighlight; + die $@ if $@; + + foreach $line (split "\n", $contents) { + if ($line eq "") { + print $lineprefix, $blankline; + } else { + $line =~ s/\\\\\\/\&/g; + print $lineprefix, $line; + } + print "\n"; + } +} + +sub output_function_asciidoc(%) { + my %args = %{$_[0]}; + my ($parameter, $section); + my $start; + + print "[[func_$args{'function'}]]\n"; + print "=== " . $args{'function'} . " ===\n"; + print $args{'purpose'} . "\n\n"; + + print "----------\n"; + if ($args{'functiontype'} ne "") { + $start = $args{'functiontype'} . " " . $args{'function'} . " ("; + } else { + $start = $args{'function'} . " ("; + } + print $start; + + my $count = 0; + foreach my $parameter (@{$args{'parameterlist'}}) { + $type = $args{'parametertypes'}{$parameter}; + if ($type =~ m/([^\(]*\(\*)\s*\)\s*\(([^\)]*)\)/) { + # pointer-to-function + print $1 . $parameter . ") (" . $2; + } else { + print $type . " " . $parameter; + } + if ($count != $#{$args{'parameterlist'}}) { + $count++; + print ",\n"; + print " " x length($start); + } else { + print ");\n\n"; + } + } + print "----------\n"; + + print ".Parameters\n"; + print "[horizontal]\n"; + foreach $parameter (@{$args{'parameterlist'}}) { + my $parameter_name = $parameter; + $parameter_name =~ s/\[.*//; + $type = $args{'parametertypes'}{$parameter}; + + print "`$type $parameter`::\n"; + if ($args{'parameterdescs'}{$parameter_name} ne $undescribed) { + $blankline = "+"; + output_highlight_asciidoc($args{'parameterdescs'}{$parameter_name}); + $blankline = "\n"; + } else { + print "_undescribed_\n"; + } + print "\n"; + } + output_section_asciidoc(@_); +} + +sub output_section_asciidoc(%) { + my %args = %{$_[0]}; + my $section; + + foreach $section (@{$args{'sectionlist'}}) { + print ".$section\n\n"; + output_highlight_asciidoc($args{'sections'}{$section}); + print "\n"; + } + print "\n"; +} + +sub output_enum_asciidoc(%) { + my %args = %{$_[0]}; + my ($parameter); + my $count; + + print "[[enum_$args{'enum'}]]\n"; + print "=== enum " . $args{'enum'} . " ===\n"; + print $args{'purpose'} . "\n\n"; + + print "----------\n"; + print "enum " . $args{'enum'} . " {\n"; + $count = 0; + foreach $parameter (@{$args{'parameterlist'}}) { + print "\t$parameter"; + if ($count != $#{$args{'parameterlist'}}) { + $count++; + print ","; + } + print "\n"; + } + print "};\n"; + print "----------\n"; + + print ".Constants\n"; + print "[horizontal]\n"; + foreach $parameter (@{$args{'parameterlist'}}) { + print "`$parameter`::\n"; + if ($args{'parameterdescs'}{$parameter} ne $undescribed) { + $blankline = "+"; + output_highlight_asciidoc($args{'parameterdescs'}{$parameter}); + $blankline = "\n"; + } else { + print "_undescribed_\n"; + } + print "\n"; + } + + output_section_asciidoc(@_); +} + +sub output_typedef_asciidoc(%) { + my %args = %{$_[0]}; + my ($parameter); + my $count; + + print "[[$args{'typedef'}]]\n"; + print "=== typedef " . $args{'typedef'} . " ===\n"; + print $args{'purpose'} . "\n\n"; + + output_section_asciidoc(@_); +} + +sub output_struct_asciidoc(%) { + my %args = %{$_[0]}; + my ($parameter); + + print "[[$args{'type'}_$args{'struct'}]]\n"; + print "=== " . $args{'type'} . " " . $args{'struct'} . " ===\n"; + print $args{'purpose'} . "\n\n"; + + print "----------\n"; + print $args{'type'} . " " . $args{'struct'} . " {\n"; + foreach $parameter (@{$args{'parameterlist'}}) { + if ($parameter =~ /^#/) { + print "$parameter\n"; + next; + } + + my $parameter_name = $parameter; + $parameter_name =~ s/\[.*//; + + ($args{'parameterdescs'}{$parameter_name} ne $undescribed) || next; + $type = $args{'parametertypes'}{$parameter}; + if ($type =~ m/([^\(]*\(\*)\s*\)\s*\(([^\)]*)\)/) { + # pointer-to-function + print "\t$1 $parameter) ($2);\n"; + } elsif ($type =~ m/^(.*?)\s*(:.*)/) { + # bitfield + print "\t$1 $parameter$2;\n"; + } else { + print "\t" . $type . " " . $parameter . ";\n"; + } + } + print "};\n"; + print "----------\n"; + + print ".Members\n"; + print "[horizontal]\n"; + foreach $parameter (@{$args{'parameterlist'}}) { + ($parameter =~ /^#/) && next; + + my $parameter_name = $parameter; + $parameter_name =~ s/\[.*//; + + ($args{'parameterdescs'}{$parameter_name} ne $undescribed) || next; + $type = $args{'parametertypes'}{$parameter}; + print "`$type $parameter`" . "::\n"; + $blankline = "+"; + output_highlight_asciidoc($args{'parameterdescs'}{$parameter_name}); + $blankline = "\n"; + print "\n"; + } + print "\n"; + output_section_asciidoc(@_); +} + +sub output_blockhead_asciidoc(%) { + my %args = %{$_[0]}; + my ($parameter, $section); + + foreach $section (@{$args{'sectionlist'}}) { + print "=== $section ===\n"; + output_highlight_asciidoc($args{'sections'}{$section}); + print "\n"; + } +} + ## list mode output functions sub output_function_list(%) { @@ -2405,6 +2631,18 @@ sub xml_escape($) { return $text; } +# xml_unescape: reverse the effects of xml_escape +sub xml_unescape($) { + my $text = shift; + if (($output_mode eq "text") || ($output_mode eq "man")) { + return $text; + } + $text =~ s/\\\\\\amp;/\&/g; + $text =~ s/\\\\\\lt;//g; + return $text; +} + # convert local escape strings to html # local escape strings look like: '\\\\menmonic:' (that's 4 backslashes) sub local_unescape($) { -- 2.1.4