diff mbox series

[8/8] docs: kernel-doc: Don't mangle literal code blocks in comments

Message ID 20180207172624.24555-9-corbet@lwn.net
State Superseded
Headers show
Series Clean up kernel-doc and fix literal-block handling | expand

Commit Message

Jonathan Corbet Feb. 7, 2018, 5:26 p.m. UTC
It can be useful to put code snippets into kerneldoc comments; that can be
done with the "::" operator at the end of a line like this::

   if (desperate)
       run_in_circles();

kernel-doc currently fails to understand these literal blocks and applies
its normal markup to them, which is then treated as literal by sphinx.  The
result is unsightly markup instead of a useful code snippet.

Apply a hack to the output code to recognize literal blocks and avoid
performing any special markup on them.  It's ugly, but that means it fits
in well with the rest of the script.

Signed-off-by: Jonathan Corbet <corbet@lwn.net>

---
 scripts/kernel-doc | 55 +++++++++++++++++++++++++++++++++++++++++++++++++-----
 1 file changed, 50 insertions(+), 5 deletions(-)

-- 
2.14.3

Comments

Tobin C. Harding Feb. 8, 2018, 2:30 a.m. UTC | #1
On Wed, Feb 07, 2018 at 10:26:24AM -0700, Jonathan Corbet wrote:

[snip]

>    if (desperate)

>        run_in_circles();


this is gold :)
Jani Nikula Feb. 9, 2018, 9:47 a.m. UTC | #2
On Wed, 07 Feb 2018, Jonathan Corbet <corbet@lwn.net> wrote:
> It can be useful to put code snippets into kerneldoc comments; that can be

> done with the "::" operator at the end of a line like this::

>

>    if (desperate)

>        run_in_circles();

>

> kernel-doc currently fails to understand these literal blocks and applies

> its normal markup to them, which is then treated as literal by sphinx.  The

> result is unsightly markup instead of a useful code snippet.

>

> Apply a hack to the output code to recognize literal blocks and avoid

> performing any special markup on them.  It's ugly, but that means it fits

> in well with the rest of the script.

>

> Signed-off-by: Jonathan Corbet <corbet@lwn.net>

> ---

>  scripts/kernel-doc | 55 +++++++++++++++++++++++++++++++++++++++++++++++++-----

>  1 file changed, 50 insertions(+), 5 deletions(-)

>

> diff --git a/scripts/kernel-doc b/scripts/kernel-doc

> index c6c9370a1e49..c984f82cb897 100755

> --- a/scripts/kernel-doc

> +++ b/scripts/kernel-doc

> @@ -748,14 +748,59 @@ sub output_blockhead_rst(%) {

>      }

>  }

>  

> -sub output_highlight_rst {

> -    my $contents = join "\n",@_;

> -    my $line;

> -

> +#

> +# Apply the RST highlights to a sub-block of text.

> +#   

> +sub highlight_block($) {

> +    # The dohighlight kludge requires the text be called $contents

> +    my $contents = shift;

>      eval $dohighlight;

>      die $@ if $@;

> +    return $contents;

> +}

>  

> -    foreach $line (split "\n", $contents) {

> +sub output_highlight_rst {

> +    my $input = join "\n",@_;

> +    my $output = "";

> +    my $line;

> +    my $in_literal = 0;

> +    my $litprefix;

> +    my $block = "";

> +

> +    # The "dohighlight" hack requires that the data be called "$contents"

> +    foreach $line (split "\n",$input) {

> +	#

> +	# If we're in a literal block, see if we should drop out

> +	# of it.  Otherwise pass the line straight through unmunged.

> +	#

> +	if ($in_literal) {

> +	    if (! ($line =~ /$litprefix/ || $line =~ /^\s*$/)) {

> +		$in_literal = 0;

> +	    }

> +	    else {

> +		$output .= $line . "\n";

> +	    }

> +	}

> +	#

> +	# Not in a literal block (or just dropped out)

> +	#

> +	if (! $in_literal) {

> +	    $block .= $line . "\n";

> +	    if ($line =~ /^[^.].*::$/) {


I think you should also add "code-block:: <language>" to the
regexp. There are only a few uses now, but I think someone's bound to
hit the same problem with those.

Perhaps also extract the regexp to a variable with a self-documenting
name.

Thanks for doing this. Not that I like it, but as you say, it fits right
in the script. I have some ideas on how to do all of the highlights
nicely as post-processing in the Sphinx extension, but we need this now
and not somewhere in the distant future.

BR,
Jani.

> +		$in_literal = 1;

> +		# Note current indentation - we'll go as long as it's deeper.

> +		$line =~ /^(\s*)/;

> +		$litprefix = '^' . $1 . ' ';

> +		$output .= highlight_block($block);

> +		$block = ""

> +	    }

> +	}

> +    }

> +

> +    if ($block) {

> +	$output .= highlight_block($block);

> +    }

> +    foreach $line (split "\n", $output) {

>  	print $lineprefix . $line . "\n";

>      }

>  }


-- 
Jani Nikula, Intel Open Source Technology Center
Markus Heiser Feb. 14, 2018, 4:53 p.m. UTC | #3
> Am 07.02.2018 um 18:26 schrieb Jonathan Corbet <corbet@lwn.net>:

> 

> It can be useful to put code snippets into kerneldoc comments; that can be

> done with the "::" operator at the end of a line like this::

> 

>  if (desperate)

>      run_in_circles();

> 

> kernel-doc currently fails to understand these literal blocks and applies

> its normal markup to them, which is then treated as literal by sphinx.  The

> result is unsightly markup instead of a useful code snippet.

> 

> Apply a hack to the output code to recognize literal blocks and avoid

> performing any special markup on them.  It's ugly, but that means it fits

> in well with the rest of the script.

> 

> Signed-off-by: Jonathan Corbet <corbet@lwn.net>



[...]

FYI; added similar patch to python version of kernel-doc:

 https://github.com/return42/linuxdoc/commit/3205b8a68

may you like to add regexpr for code-block directive to your patch (jani mentioned already).

-- Markus --
diff mbox series

Patch

diff --git a/scripts/kernel-doc b/scripts/kernel-doc
index c6c9370a1e49..c984f82cb897 100755
--- a/scripts/kernel-doc
+++ b/scripts/kernel-doc
@@ -748,14 +748,59 @@  sub output_blockhead_rst(%) {
     }
 }
 
-sub output_highlight_rst {
-    my $contents = join "\n",@_;
-    my $line;
-
+#
+# Apply the RST highlights to a sub-block of text.
+#   
+sub highlight_block($) {
+    # The dohighlight kludge requires the text be called $contents
+    my $contents = shift;
     eval $dohighlight;
     die $@ if $@;
+    return $contents;
+}
 
-    foreach $line (split "\n", $contents) {
+sub output_highlight_rst {
+    my $input = join "\n",@_;
+    my $output = "";
+    my $line;
+    my $in_literal = 0;
+    my $litprefix;
+    my $block = "";
+
+    # The "dohighlight" hack requires that the data be called "$contents"
+    foreach $line (split "\n",$input) {
+	#
+	# If we're in a literal block, see if we should drop out
+	# of it.  Otherwise pass the line straight through unmunged.
+	#
+	if ($in_literal) {
+	    if (! ($line =~ /$litprefix/ || $line =~ /^\s*$/)) {
+		$in_literal = 0;
+	    }
+	    else {
+		$output .= $line . "\n";
+	    }
+	}
+	#
+	# Not in a literal block (or just dropped out)
+	#
+	if (! $in_literal) {
+	    $block .= $line . "\n";
+	    if ($line =~ /^[^.].*::$/) {
+		$in_literal = 1;
+		# Note current indentation - we'll go as long as it's deeper.
+		$line =~ /^(\s*)/;
+		$litprefix = '^' . $1 . ' ';
+		$output .= highlight_block($block);
+		$block = ""
+	    }
+	}
+    }
+
+    if ($block) {
+	$output .= highlight_block($block);
+    }
+    foreach $line (split "\n", $output) {
 	print $lineprefix . $line . "\n";
     }
 }