@@ -31,7 +31,8 @@ def initialize(backend, opts = {})
3131 @prefix = opts [ :document ] . attributes . fetch ( "tags-match-prefix" , "" )
3232 end
3333
34- # `node` is an `AbstractNode`.
34+ # node: AbstractNode
35+ # returns: String
3536 def convert ( node , transform = node . node_name , opts = nil )
3637 if transform == "document" then
3738 # This is the top level node. First clear the outputs.
@@ -75,14 +76,16 @@ def convert(node, transform = node.node_name, opts = nil)
7576 end
7677
7778 # Recursively get the text content of this node.
78- content = if node . inline? then node . text else node . content end
79+ content = node_text_content ( node )
7980
8081 # Capture the content in the tag map and section tree if
8182 # this node is tagged appropriately.
8283 unless node . id . nil?
8384 if node . id . start_with? ( @prefix )
8485 raise "Duplicate tag name '#{ node . id } '" unless @tag_map [ node . id ] . nil?
85- @tag_map [ node . id ] = content
86+ raise "Tag '#{ node . id } ' content should be a String but it is #{ content . class } " unless content . is_a? ( String )
87+
88+ @tag_map [ node . id ] = content . strip ( )
8689 @section_stack . last [ "tags" ] << node . id
8790 end
8891 end
@@ -96,4 +99,65 @@ def convert(node, transform = node.node_name, opts = nil)
9699 content
97100 end
98101 end
102+
103+ private
104+
105+ # Return the text content of a node. Adapted from `text-converter.rb`
106+ # in the docs: https://docs.asciidoctor.org/asciidoctor/latest/convert/custom/
107+ #
108+ # node: AbstractNode
109+ # returns: String
110+ def node_text_content ( node )
111+ content_or_nil = case node . node_name
112+ when "document"
113+ raise "node_text_content(document) should be unreachable"
114+ when "section"
115+ "\n " + [ node . title , node . content ] . join ( "\n " ) . rstrip ( )
116+ when "paragraph"
117+ "\n " + normalize_space ( node . content )
118+ when "ulist" , "olist" , "colist"
119+ "\n " + node . items . map do |item |
120+ normalize_space ( item . text ) + ( item . blocks? ? "\n " + item . content : "" )
121+ end . join ( "\n " )
122+ when "dlist"
123+ "\n " + node . items . map do |terms , dd |
124+ terms . map ( &:text ) . join ( ", " ) +
125+ ( dd &.text? ? "\n " + normalize_space ( dd . text ) : "" ) +
126+ ( dd &.blocks? ? "\n " + dd . content : "" )
127+ end . join ( "\n " )
128+ when "table"
129+ # This code was wrong in the docs. This is adapted from the HTML5 converter.
130+ "\n " + node . rows . to_h . map do |tsec , rows |
131+ rows . map do |row |
132+ row . map do |cell |
133+ if tsec == :head
134+ cell . text
135+ else
136+ case cell . style
137+ when :asciidoc
138+ cell . content
139+ when :literal
140+ cell . text
141+ else
142+ # In this case it is an array of paragraphs.
143+ cell . content . join ( "\n " )
144+ end
145+ end
146+ # Separate cells by |.
147+ end . join ( "|" )
148+ # Separate rows by newlines.
149+ end . join ( "\n " )
150+ # Separate table sections by ===.
151+ end . join ( "\n ===\n " )
152+ else
153+ node . inline? ? node . text : [ "\n " , node . content ] . compact . join
154+ end
155+
156+ content_or_nil . nil? ? "" : content_or_nil
157+ end
158+
159+ # Convert spaces to newlines.
160+ def normalize_space text
161+ text . tr ( "\n " , " " )
162+ end
99163end
0 commit comments