[前][次][番号順一覧][スレッド一覧]

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/

[前][次][番号順一覧][スレッド一覧]