diff options
author | Nobuyoshi Nakada <[email protected]> | 2021-01-26 00:31:00 +0900 |
---|---|---|
committer | Nobuyoshi Nakada <[email protected]> | 2021-03-16 15:47:27 +0900 |
commit | 3651f678a719ae3a35825bcb4e0dabbc7c60d8df (patch) | |
tree | f8705c06212e4778780c1db52b99ae17d319e33d /lib/rdoc | |
parent | 05898c5b9001c0b1e8bd7bf0d12b42a8e7c388b8 (diff) |
[ruby/rdoc] Support GFM table
https://github.com/ruby/rdoc/commit/9dc933df16
Notes
Notes:
Merged: https://github.com/ruby/ruby/pull/4274
Diffstat (limited to 'lib/rdoc')
-rw-r--r-- | lib/rdoc/markdown.rb | 349 | ||||
-rw-r--r-- | lib/rdoc/markup.rb | 1 | ||||
-rw-r--r-- | lib/rdoc/markup/table.rb | 47 | ||||
-rw-r--r-- | lib/rdoc/markup/to_html.rb | 23 | ||||
-rw-r--r-- | lib/rdoc/markup/to_joined_paragraph.rb | 1 | ||||
-rw-r--r-- | lib/rdoc/markup/to_rdoc.rb | 28 | ||||
-rw-r--r-- | lib/rdoc/markup/to_table_of_contents.rb | 1 |
7 files changed, 448 insertions, 2 deletions
diff --git a/lib/rdoc/markdown.rb b/lib/rdoc/markdown.rb index 903e744105..d9bfbd38fb 100644 --- a/lib/rdoc/markdown.rb +++ b/lib/rdoc/markdown.rb @@ -897,7 +897,7 @@ class RDoc::Markdown return _tmp end - # Block = @BlankLine* (BlockQuote | Verbatim | CodeFence | Note | Reference | HorizontalRule | Heading | OrderedList | BulletList | DefinitionList | HtmlBlock | StyleBlock | Para | Plain) + # Block = @BlankLine* (BlockQuote | Verbatim | CodeFence | Table | Note | Reference | HorizontalRule | Heading | OrderedList | BulletList | DefinitionList | HtmlBlock | StyleBlock | Para | Plain) def _Block _save = self.pos @@ -923,6 +923,9 @@ class RDoc::Markdown _tmp = apply(:_CodeFence) break if _tmp self.pos = _save2 + _tmp = apply(:_Table) + break if _tmp + self.pos = _save2 _tmp = apply(:_Note) break if _tmp self.pos = _save2 @@ -15847,6 +15850,343 @@ class RDoc::Markdown return _tmp end + # Table = &{ github? } TableRow:header TableLine:line TableRow+:body { table = RDoc::Markup::Table.new(header, line, body) } + def _Table + + _save = self.pos + while true # sequence + _save1 = self.pos + _tmp = begin; github? ; end + self.pos = _save1 + unless _tmp + self.pos = _save + break + end + _tmp = apply(:_TableRow) + header = @result + unless _tmp + self.pos = _save + break + end + _tmp = apply(:_TableLine) + line = @result + unless _tmp + self.pos = _save + break + end + _save2 = self.pos + _ary = [] + _tmp = apply(:_TableRow) + if _tmp + _ary << @result + while true + _tmp = apply(:_TableRow) + _ary << @result if _tmp + break unless _tmp + end + _tmp = true + @result = _ary + else + self.pos = _save2 + end + body = @result + unless _tmp + self.pos = _save + break + end + @result = begin; table = RDoc::Markup::Table.new(header, line, body) ; end + _tmp = true + unless _tmp + self.pos = _save + end + break + end # end sequence + + set_failed_rule :_Table unless _tmp + return _tmp + end + + # TableRow = < TableItem+:row > "|" @Newline { row } + def _TableRow + + _save = self.pos + while true # sequence + _text_start = self.pos + _save1 = self.pos + _ary = [] + _tmp = apply(:_TableItem) + if _tmp + _ary << @result + while true + _tmp = apply(:_TableItem) + _ary << @result if _tmp + break unless _tmp + end + _tmp = true + @result = _ary + else + self.pos = _save1 + end + row = @result + if _tmp + text = get_text(_text_start) + end + unless _tmp + self.pos = _save + break + end + _tmp = match_string("|") + unless _tmp + self.pos = _save + break + end + _tmp = _Newline() + unless _tmp + self.pos = _save + break + end + @result = begin; row ; end + _tmp = true + unless _tmp + self.pos = _save + end + break + end # end sequence + + set_failed_rule :_TableRow unless _tmp + return _tmp + end + + # TableItem = "|" < (!"|" !@Newline .)+ > { text.strip } + def _TableItem + + _save = self.pos + while true # sequence + _tmp = match_string("|") + unless _tmp + self.pos = _save + break + end + _text_start = self.pos + _save1 = self.pos + + _save2 = self.pos + while true # sequence + _save3 = self.pos + _tmp = match_string("|") + _tmp = _tmp ? nil : true + self.pos = _save3 + unless _tmp + self.pos = _save2 + break + end + _save4 = self.pos + _tmp = _Newline() + _tmp = _tmp ? nil : true + self.pos = _save4 + unless _tmp + self.pos = _save2 + break + end + _tmp = get_byte + unless _tmp + self.pos = _save2 + end + break + end # end sequence + + if _tmp + while true + + _save5 = self.pos + while true # sequence + _save6 = self.pos + _tmp = match_string("|") + _tmp = _tmp ? nil : true + self.pos = _save6 + unless _tmp + self.pos = _save5 + break + end + _save7 = self.pos + _tmp = _Newline() + _tmp = _tmp ? nil : true + self.pos = _save7 + unless _tmp + self.pos = _save5 + break + end + _tmp = get_byte + unless _tmp + self.pos = _save5 + end + break + end # end sequence + + break unless _tmp + end + _tmp = true + else + self.pos = _save1 + end + if _tmp + text = get_text(_text_start) + end + unless _tmp + self.pos = _save + break + end + @result = begin; text.strip ; end + _tmp = true + unless _tmp + self.pos = _save + end + break + end # end sequence + + set_failed_rule :_TableItem unless _tmp + return _tmp + end + + # TableLine = TableColumn+:line "|" @Newline { line } + def _TableLine + + _save = self.pos + while true # sequence + _save1 = self.pos + _ary = [] + _tmp = apply(:_TableColumn) + if _tmp + _ary << @result + while true + _tmp = apply(:_TableColumn) + _ary << @result if _tmp + break unless _tmp + end + _tmp = true + @result = _ary + else + self.pos = _save1 + end + line = @result + unless _tmp + self.pos = _save + break + end + _tmp = match_string("|") + unless _tmp + self.pos = _save + break + end + _tmp = _Newline() + unless _tmp + self.pos = _save + break + end + @result = begin; line ; end + _tmp = true + unless _tmp + self.pos = _save + end + break + end # end sequence + + set_failed_rule :_TableLine unless _tmp + return _tmp + end + + # TableColumn = "|" < ("-"+ ":"? | ":" "-"*) > { text.start_with?(":") ? :left : text.end_with?(":") ? :right : nil } + def _TableColumn + + _save = self.pos + while true # sequence + _tmp = match_string("|") + unless _tmp + self.pos = _save + break + end + _text_start = self.pos + + _save1 = self.pos + while true # choice + + _save2 = self.pos + while true # sequence + _save3 = self.pos + _tmp = match_string("-") + if _tmp + while true + _tmp = match_string("-") + break unless _tmp + end + _tmp = true + else + self.pos = _save3 + end + unless _tmp + self.pos = _save2 + break + end + _save4 = self.pos + _tmp = match_string(":") + unless _tmp + _tmp = true + self.pos = _save4 + end + unless _tmp + self.pos = _save2 + end + break + end # end sequence + + break if _tmp + self.pos = _save1 + + _save5 = self.pos + while true # sequence + _tmp = match_string(":") + unless _tmp + self.pos = _save5 + break + end + while true + _tmp = match_string("-") + break unless _tmp + end + _tmp = true + unless _tmp + self.pos = _save5 + end + break + end # end sequence + + break if _tmp + self.pos = _save1 + break + end # end choice + + if _tmp + text = get_text(_text_start) + end + unless _tmp + self.pos = _save + break + end + @result = begin; + text.start_with?(":") ? :left : + text.end_with?(":") ? :right : nil + ; end + _tmp = true + unless _tmp + self.pos = _save + end + break + end # end sequence + + set_failed_rule :_TableColumn unless _tmp + return _tmp + end + # DefinitionList = &{ definition_lists? } DefinitionListItem+:list { RDoc::Markup::List.new :NOTE, *list.flatten } def _DefinitionList @@ -16046,7 +16386,7 @@ class RDoc::Markdown Rules = {} Rules[:_root] = rule_info("root", "Doc") Rules[:_Doc] = rule_info("Doc", "BOM? Block*:a { RDoc::Markup::Document.new(*a.compact) }") - Rules[:_Block] = rule_info("Block", "@BlankLine* (BlockQuote | Verbatim | CodeFence | Note | Reference | HorizontalRule | Heading | OrderedList | BulletList | DefinitionList | HtmlBlock | StyleBlock | Para | Plain)") + Rules[:_Block] = rule_info("Block", "@BlankLine* (BlockQuote | Verbatim | CodeFence | Table | Note | Reference | HorizontalRule | Heading | OrderedList | BulletList | DefinitionList | HtmlBlock | StyleBlock | Para | Plain)") Rules[:_Para] = rule_info("Para", "@NonindentSpace Inlines:a @BlankLine+ { paragraph a }") Rules[:_Plain] = rule_info("Plain", "Inlines:a { paragraph a }") Rules[:_AtxInline] = rule_info("AtxInline", "!@Newline !(@Sp /\#*/ @Sp @Newline) Inline") @@ -16279,6 +16619,11 @@ class RDoc::Markdown Rules[:_Notes] = rule_info("Notes", "(Note | SkipBlock)*") Rules[:_RawNoteBlock] = rule_info("RawNoteBlock", "@StartList:a (!@BlankLine OptionallyIndentedLine:l { a << l })+ < @BlankLine* > { a << text } { a }") Rules[:_CodeFence] = rule_info("CodeFence", "&{ github? } Ticks3 (@Sp StrChunk:format)? Spnl < ((!\"`\" Nonspacechar)+ | !Ticks3 /`+/ | Spacechar | @Newline)+ > Ticks3 @Sp @Newline* { verbatim = RDoc::Markup::Verbatim.new text verbatim.format = format.intern if format.instance_of?(String) verbatim }") + Rules[:_Table] = rule_info("Table", "&{ github? } TableRow:header TableLine:line TableRow+:body { table = RDoc::Markup::Table.new(header, line, body) }") + Rules[:_TableRow] = rule_info("TableRow", "< TableItem+:row > \"|\" @Newline { row }") + Rules[:_TableItem] = rule_info("TableItem", "\"|\" < (!\"|\" !@Newline .)+ > { text.strip }") + Rules[:_TableLine] = rule_info("TableLine", "TableColumn+:line \"|\" @Newline { line }") + Rules[:_TableColumn] = rule_info("TableColumn", "\"|\" < (\"-\"+ \":\"? | \":\" \"-\"*) > { text.start_with?(\":\") ? :left : text.end_with?(\":\") ? :right : nil }") Rules[:_DefinitionList] = rule_info("DefinitionList", "&{ definition_lists? } DefinitionListItem+:list { RDoc::Markup::List.new :NOTE, *list.flatten }") Rules[:_DefinitionListItem] = rule_info("DefinitionListItem", "DefinitionListLabel+:label DefinitionListDefinition+:defns { list_items = [] list_items << RDoc::Markup::ListItem.new(label, defns.shift) list_items.concat defns.map { |defn| RDoc::Markup::ListItem.new nil, defn } unless list_items.empty? list_items }") Rules[:_DefinitionListLabel] = rule_info("DefinitionListLabel", "StrChunk:label @Sp @Newline { label }") diff --git a/lib/rdoc/markup.rb b/lib/rdoc/markup.rb index fd59fca314..92aed757cf 100644 --- a/lib/rdoc/markup.rb +++ b/lib/rdoc/markup.rb @@ -843,6 +843,7 @@ https://github.com/ruby/rdoc/issues autoload :List, 'rdoc/markup/list' autoload :ListItem, 'rdoc/markup/list_item' autoload :Paragraph, 'rdoc/markup/paragraph' + autoload :Table, 'rdoc/markup/table' autoload :Raw, 'rdoc/markup/raw' autoload :Rule, 'rdoc/markup/rule' autoload :Verbatim, 'rdoc/markup/verbatim' diff --git a/lib/rdoc/markup/table.rb b/lib/rdoc/markup/table.rb new file mode 100644 index 0000000000..7bcb10aff3 --- /dev/null +++ b/lib/rdoc/markup/table.rb @@ -0,0 +1,47 @@ +# frozen_string_literal: true +## +# A section of table + +class RDoc::Markup::Table + attr_accessor :header, :align, :body + + def initialize header, align, body + @header, @align, @body = header, align, body + end + + def == other + self.class == other.class and + @header == other.header and + @align == other.align and + @body == other.body + end + + def accept visitor + visitor.accept_table @header, @body, @align + end + + def pretty_print q # :nodoc: + q.group 2, '[Table: ', ']' do + q.group 2, '[Head: ', ']' do + q.seplist @header.zip(@align) do |text, align| + q.pp text + if align + q.text ":" + q.breakable + q.text align.to_s + end + end + end + q.breakable + q.group 2, '[Body: ', ']' do + q.seplist @body do |body| + q.group 2, '[', ']' do + q.seplist body do |text| + q.pp text + end + end + end + end + end + end +end diff --git a/lib/rdoc/markup/to_html.rb b/lib/rdoc/markup/to_html.rb index 3b1b0e9d40..e2a00bd8a1 100644 --- a/lib/rdoc/markup/to_html.rb +++ b/lib/rdoc/markup/to_html.rb @@ -314,6 +314,29 @@ class RDoc::Markup::ToHtml < RDoc::Markup::Formatter @res << raw.parts.join("\n") end + ## + # Adds +table+ to the output + + def accept_table header, body, aligns + @res << "\n<table role=\"table\">\n<thead>\n<tr>\n" + header.zip(aligns) do |text, align| + @res << '<th' + @res << ' align="' << align << '"' if align + @res << '>' << CGI.escapeHTML(text) << "</th>\n" + end + @res << "</tr>\n</thead>\n<tbody>\n" + body.each do |row| + @res << "<tr>\n" + row.zip(aligns) do |text, align| + @res << '<td' + @res << ' align="' << align << '"' if align + @res << '>' << CGI.escapeHTML(text) << "</td>\n" + end + @res << "</tr>\n" + end + @res << "</tbody>\n</table>\n" + end + # :section: Utilities ## diff --git a/lib/rdoc/markup/to_joined_paragraph.rb b/lib/rdoc/markup/to_joined_paragraph.rb index 795f3f62ee..46e07c94ad 100644 --- a/lib/rdoc/markup/to_joined_paragraph.rb +++ b/lib/rdoc/markup/to_joined_paragraph.rb @@ -41,6 +41,7 @@ class RDoc::Markup::ToJoinedParagraph < RDoc::Markup::Formatter alias accept_raw ignore alias accept_rule ignore alias accept_verbatim ignore + alias accept_table ignore end diff --git a/lib/rdoc/markup/to_rdoc.rb b/lib/rdoc/markup/to_rdoc.rb index 81b16c4973..3cdf4fd08b 100644 --- a/lib/rdoc/markup/to_rdoc.rb +++ b/lib/rdoc/markup/to_rdoc.rb @@ -238,6 +238,34 @@ class RDoc::Markup::ToRdoc < RDoc::Markup::Formatter end ## + # Adds +table+ to the output + + def accept_table header, body, aligns + widths = header.zip(body) do |h, b| + [h.size, b.size].max + end + aligns = aligns.map do |a| + case a + when nil + :center + when :left + :ljust + when :right + :rjust + end + end + @res << header.zip(widths, aligns) do |h, w, a| + h.__send__(a, w) + end.join("|").rstrip << "\n" + @res << widths.map {|w| "-" * w }.join("|") << "\n" + body.each do |row| + @res << row.zip(widths, aligns) do |t, w, a| + t.__send__(a, w) + end.join("|").rstrip << "\n" + end + end + + ## # Applies attribute-specific markup to +text+ using RDoc::AttributeManager def attributes text diff --git a/lib/rdoc/markup/to_table_of_contents.rb b/lib/rdoc/markup/to_table_of_contents.rb index f68b90bcf6..eb8e8faa16 100644 --- a/lib/rdoc/markup/to_table_of_contents.rb +++ b/lib/rdoc/markup/to_table_of_contents.rb @@ -82,6 +82,7 @@ class RDoc::Markup::ToTableOfContents < RDoc::Markup::Formatter alias accept_list_item_end ignore alias accept_list_end_bullet ignore alias accept_list_start ignore + alias accept_table ignore # :startdoc: end |