mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
[ruby/rdoc] Disable other notations in <code> tags
https://github.com/ruby/rdoc/commit/0cd3b55210
This commit is contained in:
parent
ab89c45b90
commit
54aa11efa8
4 changed files with 114 additions and 28 deletions
|
@ -7,16 +7,22 @@ class RDoc::Markup::AttrSpan
|
|||
##
|
||||
# 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
|
||||
|
||||
##
|
||||
|
|
|
@ -58,6 +58,10 @@ class RDoc::Markup::AttributeManager
|
|||
|
||||
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
|
|||
@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
|
|||
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
|
|||
##
|
||||
# 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
|
|||
##
|
||||
# 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
|
|||
#
|
||||
# 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
|
|||
|
||||
@protectable << start[0,1]
|
||||
@protectable.uniq!
|
||||
|
||||
@exclusive_bitmap |= bitmap if exclusive
|
||||
end
|
||||
|
||||
##
|
||||
|
@ -228,8 +277,10 @@ class RDoc::Markup::AttributeManager
|
|||
#
|
||||
# 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
|
|||
#
|
||||
# @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
|
|||
|
||||
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
|
||||
|
|
|
@ -172,22 +172,25 @@ class TestRDocMarkupAttributeManager < RDoc::TestCase
|
|||
|
||||
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
|
|||
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[:symbol]')
|
||||
end
|
||||
|
||||
def test_exclude_tag_flow
|
||||
assert_equal [@tt_on, "aaa", @tt_off, "[:symbol]"],
|
||||
@am.flow("+aaa+[:symbol]")
|
||||
assert_equal [@tt_on, "aaa[:symbol]", @tt_off],
|
||||
@am.flow("+aaa[:symbol]+")
|
||||
assert_equal ["aaa[:symbol]"],
|
||||
@am.flow("aaa[:symbol]")
|
||||
end
|
||||
|
||||
def test_html_like_em_bold
|
||||
assert_equal ["cat ", @em_on, "and ", @em_to_bold, "dog", @bold_off],
|
||||
@am.flow("cat <i>and </i><b>dog</b>")
|
||||
|
|
|
@ -704,6 +704,12 @@ EXPECTED
|
|||
assert_equal "\n<p><a href=\"irc://irc.freenode.net/#ruby-lang\">ruby-lang</a></p>\n", result
|
||||
end
|
||||
|
||||
def test_convert_with_exclude_tag
|
||||
assert_equal "\n<p><code>aaa</code>[:symbol]</p>\n", @to.convert('+aaa+[:symbol]')
|
||||
assert_equal "\n<p><code>aaa[:symbol]</code></p>\n", @to.convert('+aaa[:symbol]+')
|
||||
assert_equal "\n<p><a href=\":symbol\">aaa</a></p>\n", @to.convert('aaa[:symbol]')
|
||||
end
|
||||
|
||||
def test_gen_url
|
||||
assert_equal '<a href="example">example</a>',
|
||||
@to.gen_url('link:example', 'example')
|
||||
|
|
Loading…
Add table
Reference in a new issue