asciidoctor / asciidoctor-extensions-lab

A lab for testing and demonstrating Asciidoctor extensions. Please do not use this code in production. If you want to use one of these extensions in your application, create a new project, import the code, and distribute it as a RubyGem. You can then request to make it a top-level project under the Asciidoctor organization.
Other
104 stars 101 forks source link

man-inline-macro doesn't generate the correct output in the manpage backend #121

Closed somasis closed 4 years ago

somasis commented 4 years ago

With asciidoctor 2.0.10, when generating with the manpage backend, the incorrect output is generated.

somasis/trotsky:~/mess/current/asciidoctor-extensions-lab (master) λ asciidoctor -r ./lib/man-inline-macro.rb lib/man-inline-macro/sample.adoc -b manpage -v -o - | man /dev/stdin | col -bx
asciidoctor: ERROR: sample.adoc: line 1: non-conforming manpage title
asciidoctor: ERROR: sample.adoc: line 3: name section expected
asciidoctor: INFO: expected substitution value for custom inline macro to be of type Inline; got String: man:gittutorial[7]
SAMPLE(1)                                                      SAMPLE(1)

See \fBgittutorial\fP(7) to get started.

                               2020-06-16                      SAMPLE(1)

Looking at the generated roff output, it seems that the backslashes are being escaped rather than being passed directly through.

'\" t
.\"     Title: Man Inline Macro Extension
.\"    Author: [see the "AUTHOR(S)" section]
.\" Generator: Asciidoctor 2.0.10
.\"      Date: 2020-06-16
.\"    Manual: \ \&
.\"    Source: \ \&
.\"  Language: English
.\"
.TH "SAMPLE" "1" "2020-06-16" "\ \&" "\ \&"
.ie \n(.g .ds Aq \(aq
.el       .ds Aq '
.ss \n[.ss] 0
.nh
.ad l
.de URL
\fI\\$2\fP <\\$1>\\$3
..
.als MTO URL
.if \n[.g] \{\
.  mso www.tmac
.  am URL
.    ad l
.  .
.  am MTO
.    ad l
.  .
.  LINKSTYLE blue R < >
.\}
.sp
See \(rsfBgittutorial\(rsfP(7) to get started.

After some discussion in the Gitter, it seems that the problem is indeed that. The INFO message indicates that an Inline node should be returned, not a String.

@djencks suggested the following change, which does indeed produce the expected See \fBgittutorial\fP(7) to get started. output.

--- lib/man-inline-macro/extension.rb   2020-06-16 17:11:38.512397861 -0400
+++ lib/man-inline-macro/extension.rb   2020-06-16 17:11:41.662442490 -0400
@@ -27,7 +27,7 @@
       parent.document.register :links, target
       %(#{(create_anchor parent, text, type: :link, target: target).render}#{suffix})
     elsif parent.document.backend == 'manpage'
-      %(\\fB#{manname}\\fP#{suffix})
+      %(\u001b\\fB#{manname}\u001b\\fP#{suffix})
     else
       %(#{manname}#{suffix})
     end

(unrelated, but I really wish this functionality were bundled with asciidoctor rather than being an extension, it'd be so effortless to distribute good HTML and manpage documentation with it being included.)

mojavelinux commented 4 years ago

I really wish this functionality were bundled with asciidoctor rather than being an extension

Ideally, this macro would be available as a formal extension that you can install. I would support the effort to graduate it to a dedicated gem. This is intended to be a lab, so nothing here should be used in production.

The proposal to add a built-in man macro only available when doctype is manpage seems reasonable.

mojavelinux commented 4 years ago

As for the output produced, the problem seems to be that the extension is not compatible with Asciidoctor 2. It should be returning an Inline object, not a string. Returning a string is deprecated.

mojavelinux commented 4 years ago

However, Asciidoctor 2 still allows the extension to return a string. It just issues an info message in verbose mode. The reason the extension stopped working is because Asciidoctor 2 uses additional intermediate markup for formatted text to prevent it from being improperly escaped. This is why the extension should return an object instead of a string.

mojavelinux commented 4 years ago

Fixed.

somasis commented 4 years ago

Thank you :)