ruby-changes:65743
From: aycabta <ko1@a...>
Date: Sat, 3 Apr 2021 01:24:06 +0900 (JST)
Subject: [ruby-changes:65743] 54aa11efa8 (master): [ruby/rdoc] Disable other notations in <code> tags
https://git.ruby-lang.org/ruby.git/commit/?id=54aa11efa8 From 54aa11efa8b1be2c5d20402890d6d2fa90aa19a8 Mon Sep 17 00:00:00 2001 From: aycabta <aycabta@g...> Date: Sun, 14 Mar 2021 18:26:19 +0900 Subject: [ruby/rdoc] Disable other notations in <code> tags https://github.com/ruby/rdoc/commit/0cd3b55210 --- lib/rdoc/markup/attr_span.rb | 10 ++- lib/rdoc/markup/attribute_manager.rb | 102 ++++++++++++++++++------ test/rdoc/test_rdoc_markup_attribute_manager.rb | 24 +++++- test/rdoc/test_rdoc_markup_to_html.rb | 6 ++ 4 files changed, 114 insertions(+), 28 deletions(-) diff --git a/lib/rdoc/markup/attr_span.rb b/lib/rdoc/markup/attr_span.rb index 63aace6..6fe939f 100644 --- a/lib/rdoc/markup/attr_span.rb +++ b/lib/rdoc/markup/attr_span.rb @@ -7,16 +7,22 @@ class RDoc::Markup::AttrSpan https://github.com/ruby/ruby/blob/trunk/lib/rdoc/markup/attr_span.rb#L7 ## # Creates a new AttrSpan for +length+ characters - def initialize(length) + def initialize(length, exclusive) @attrs = Array.new(length, 0) + @exclusive = exclusive end ## # Toggles +bits+ from +start+ to +length+ def set_attrs(start, length, bits) + updated = false for i in start ... (start+length) - @attrs[i] |= bits + if (@exclusive & @attrs[i]) == 0 + @attrs[i] |= bits + updated = true + end end + updated end ## diff --git a/lib/rdoc/markup/attribute_manager.rb b/lib/rdoc/markup/attribute_manager.rb index f052bc8..64ef7fd 100644 --- a/lib/rdoc/markup/attribute_manager.rb +++ b/lib/rdoc/markup/attribute_manager.rb @@ -59,6 +59,10 @@ class RDoc::Markup::AttributeManager https://github.com/ruby/ruby/blob/trunk/lib/rdoc/markup/attribute_manager.rb#L59 attr_reader :regexp_handlings ## + # A bits of exclusive maps + attr_reader :exclusive_bitmap + + ## # Creates a new attribute manager that understands bold, emphasized and # teletype text. @@ -68,17 +72,18 @@ class RDoc::Markup::AttributeManager https://github.com/ruby/ruby/blob/trunk/lib/rdoc/markup/attribute_manager.rb#L72 @protectable = %w[<] @regexp_handlings = [] @word_pair_map = {} + @exclusive_bitmap = 0 @attributes = RDoc::Markup::Attributes.new add_word_pair "*", "*", :BOLD add_word_pair "_", "_", :EM - add_word_pair "+", "+", :TT + add_word_pair "+", "+", :TT, true add_html "em", :EM add_html "i", :EM add_html "b", :BOLD - add_html "tt", :TT - add_html "code", :TT + add_html "tt", :TT, true + add_html "code", :TT, true end ## @@ -122,29 +127,58 @@ class RDoc::Markup::AttributeManager https://github.com/ruby/ruby/blob/trunk/lib/rdoc/markup/attribute_manager.rb#L127 res end + def exclusive?(attr) + (attr & @exclusive_bitmap) != 0 + end + + NON_PRINTING_START = "\1" # :nodoc: + NON_PRINTING_END = "\2" # :nodoc: + ## # Map attributes like <b>text</b>to the sequence # \001\002<char>\001\003<char>, where <char> is a per-attribute specific # character - def convert_attrs(str, attrs) + def convert_attrs(str, attrs, exclusive = false) # first do matching ones - tags = @matching_word_pairs.keys.join("") + tags = @matching_word_pairs.select { |start, bitmap| + if exclusive && exclusive?(bitmap) + true + elsif !exclusive && !exclusive?(bitmap) + true + else + false + end + }.keys.join("") - re = /(^|\W)([#{tags}])([#\\]?[\w:.\/-]+?\S?)\2(\W|$)/ + re = /(^|\W)([#{tags}])([#\\]?[\w:.\/\[\]-]+?\S?)\2(\W|$)/ - 1 while str.gsub!(re) do + 1 while str.gsub!(re) { |orig| attr = @matching_word_pairs[$2] - attrs.set_attrs($`.length + $1.length + $2.length, $3.length, attr) - $1 + NULL * $2.length + $3 + NULL * $2.length + $4 - end + updated = attrs.set_attrs($`.length + $1.length + $2.length, $3.length, attr) + if updated + $1 + NULL * $2.length + $3 + NULL * $2.length + $4 + else + $1 + NON_PRINTING_START + $2 + NON_PRINTING_END + $3 + NON_PRINTING_START + $2 + NON_PRINTING_END + $4 + end + } + str.delete!(NON_PRINTING_START + NON_PRINTING_END) # then non-matching unless @word_pair_map.empty? then @word_pair_map.each do |regexp, attr| - str.gsub!(regexp) { - attrs.set_attrs($`.length + $1.length, $2.length, attr) - NULL * $1.length + $2 + NULL * $3.length + if !exclusive + next if exclusive?(attr) + else + next if !exclusive?(attr) + end + 1 while str.gsub!(regexp) { |orig| + updated = attrs.set_attrs($`.length + $1.length, $2.length, attr) + if updated + NULL * $1.length + $2 + NULL * $3.length + else + orig + end } end end @@ -153,10 +187,18 @@ class RDoc::Markup::AttributeManager https://github.com/ruby/ruby/blob/trunk/lib/rdoc/markup/attribute_manager.rb#L187 ## # Converts HTML tags to RDoc attributes - def convert_html(str, attrs) - tags = @html_tags.keys.join '|' + def convert_html(str, attrs, exclusive = false) + tags = @html_tags.select { |start, bitmap| + if exclusive && exclusive?(bitmap) + true + elsif !exclusive && !exclusive?(bitmap) + true + else + false + end + }.keys.join '|' - 1 while str.gsub!(/<(#{tags})>(.*?)<\/\1>/i) { + 1 while str.gsub!(/<(#{tags})>(.*?)<\/\1>/i) { |orig| attr = @html_tags[$1.downcase] html_length = $1.length + 2 seq = NULL * html_length @@ -168,8 +210,13 @@ class RDoc::Markup::AttributeManager https://github.com/ruby/ruby/blob/trunk/lib/rdoc/markup/attribute_manager.rb#L210 ## # Converts regexp handling sequences to RDoc attributes - def convert_regexp_handlings str, attrs + def convert_regexp_handlings str, attrs, exclusive = false @regexp_handlings.each do |regexp, attribute| + if exclusive + next if !exclusive?(attribute) + else + next if exclusive?(attribute) + end str.scan(regexp) do capture = $~.size == 1 ? 0 : 1 @@ -205,7 +252,7 @@ class RDoc::Markup::AttributeManager https://github.com/ruby/ruby/blob/trunk/lib/rdoc/markup/attribute_manager.rb#L252 # # am.add_word_pair '*', '*', :BOLD - def add_word_pair(start, stop, name) + def add_word_pair(start, stop, name, exclusive = false) raise ArgumentError, "Word flags may not start with '<'" if start[0,1] == '<' @@ -220,6 +267,8 @@ class RDoc::Markup::AttributeManager https://github.com/ruby/ruby/blob/trunk/lib/rdoc/markup/attribute_manager.rb#L267 @protectable << start[0,1] @protectable.uniq! + + @exclusive_bitmap |= bitmap if exclusive end ## @@ -228,8 +277,10 @@ class RDoc::Markup::AttributeManager https://github.com/ruby/ruby/blob/trunk/lib/rdoc/markup/attribute_manager.rb#L277 # # am.add_html 'em', :EM - def add_html(tag, name) - @html_tags[tag.downcase] = @attributes.bitmap_for name + def add_html(tag, name, exclusive = false) + bitmap = @attributes.bitmap_for name + @html_tags[tag.downcase] = bitmap + @exclusive_bitmap |= bitmap if exclusive end ## @@ -238,8 +289,10 @@ class RDoc::Markup::AttributeManager https://github.com/ruby/ruby/blob/trunk/lib/rdoc/markup/attribute_manager.rb#L289 # # @am.add_regexp_handling(/((https?:)\S+\w)/, :HYPERLINK) - def add_regexp_handling pattern, name - @regexp_handlings << [pattern, @attributes.bitmap_for(name)] + def add_regexp_handling pattern, name, exclusive = false + bitmap = @attributes.bitmap_for(name) + @regexp_handlings << [pattern, bitmap] + @exclusive_bitmap |= bitmap if exclusive end ## @@ -250,8 +303,11 @@ class RDoc::Markup::AttributeManager https://github.com/ruby/ruby/blob/trunk/lib/rdoc/markup/attribute_manager.rb#L303 mask_protected_sequences - @attrs = RDoc::Markup::AttrSpan.new @str.length + @attrs = RDoc::Markup::AttrSpan.new @str.length, @exclusive_bitmap + convert_attrs @str, @attrs, true + convert_html @str, @attrs, true + convert_regexp_handlings @str, @attrs, true convert_attrs @str, @attrs convert_html @str, @attrs convert_regexp_handlings @str, @attrs diff --git a/test/rdoc/test_rdoc_markup_attribute_manager.rb b/test/rdoc/test_rdoc_markup_attribute_manager.rb index a180666..2ec135d 100644 --- a/test/rdoc/test_rdoc_markup_attribute_manager.rb +++ b/test/rdoc/test_rdoc_markup_attribute_manager.rb @@ -172,22 +172,25 @@ class TestRDocMarkupAttributeManager < RDoc::TestCase https://github.com/ruby/ruby/blob/trunk/test/rdoc/test_rdoc_markup_attribute_manager.rb#L172 def test_convert_attrs str = '+foo+'.dup - attrs = RDoc::Markup::AttrSpan.new str.length + attrs = RDoc::Markup::AttrSpan.new str.length, @am.exclusive_bitmap + @am.convert_attrs str, attrs, true @am.convert_attrs str, attrs assert_equal "\000foo\000", str str = '+:foo:+'.dup - attrs = RDoc::Markup::AttrSpan.new str.length + attrs = RDoc::Markup::AttrSpan.new str.length, @am.exclusive_bitmap + @am.convert_attrs str, attrs, true @am.convert_attrs str, attrs assert_equal "\000:foo:\000", str str = '+x-y+'.dup - attrs = RDoc::Markup::AttrSpan.new str.length + attrs = RDoc::Markup::AttrSpan.new str.length, @am.exclusive_bitmap + @am.convert_attrs str, attrs, true @am.convert_attrs str, attrs assert_equal "\000x-y\000", str @@ -243,6 +246,21 @@ class TestRDocMarkupAttributeManager < RDoc::TestCase https://github.com/ruby/ruby/blob/trunk/test/rdoc/test_rdoc_markup_attribute_manager.rb#L246 output('unhandled <p>tag</p> unchanged') end + def test_exclude_tag + assert_equal '<CODE>aaa</CODE>[:symbol]', output('+aaa+[:symbol]') + assert_equal '<CODE>aaa[:symbol]</CODE>', output('+aaa[:symbol]+') + assert_equal 'aaa[:symbol]', output('aaa[:sy (... truncated) -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/