Class: Pipio::TagBalancer
- Inherits:
-
Object
- Object
- Pipio::TagBalancer
- Defined in:
- lib/pipio/tag_balancer.rb
Overview
From Wordpress’s formatting.php; rewritten in Ruby by Gabe Berke-Williams, 2009.
- Author
-
Leonard Lin <[email protected]>
- License
-
GPL v2.0
- Copyright
-
November 4, 2001
Instance Method Summary collapse
- #balance ⇒ Object
-
#initialize(text) ⇒ TagBalancer
constructor
A new instance of TagBalancer.
Constructor Details
#initialize(text) ⇒ TagBalancer
Returns a new instance of TagBalancer.
12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
# File 'lib/pipio/tag_balancer.rb', line 12 def initialize(text) @text = text @tagstack = [] @stacksize = 0 @tagqueue = '' # Known single-entity/self-closing tags @self_closing_tags = %w(br hr img input meta) # Tags that can be immediately nested within themselves @nestable_tags = %w(blockquote div span font) # 1: tagname, with possible leading "/" # 2: attributes @tag_regex = /<(\/?\w*)\s*([^>]*)>/ end |
Instance Method Details
#balance ⇒ Object
30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 |
# File 'lib/pipio/tag_balancer.rb', line 30 def balance text = @text.dup newtext = '' @tagstack = [] @stacksize = 0 @tagqueue = '' # WP bug fix for comments - in case you REALLY meant to type '< !--' text.gsub!('< !--', '< !--') # WP bug fix for LOVE <3 (and other situations with '<' before a number) text.gsub!(/<([0-9]{1})/, '<\1') while ( pos = (text =~ @tag_regex) ) newtext << @tagqueue tag = $1.downcase attributes = $2 matchlen = $~[0].size # clear the shifter @tagqueue = '' # Pop or Push if end_tag?(tag) tag.slice!(0,1) if tag = '' #or close to be safe: tag = '/' << tag elsif closing_tag?(tag) # if stacktop value == tag close value then pop tag = "</#{tag}>" # Close Tag @tagstack.pop @stacksize -= 1 else # closing tag not at top, search for it (@stacksize-1).downto(0) do |j| if @tagstack[j] == tag # add tag to tagqueue ss = @stacksize - 1 ss.downto(j) do |k| @tagqueue << "</#{@tagstack.pop}>" @stacksize -= 1 end break end end tag = '' end else # Begin Tag # Tag Cleaning if self_closing_attributes?(attributes) || empty_tag?(tag) elsif self_closing_tag?(tag) # ElseIf: it's a known single-entity tag but it doesn't close itself, do so attributes << '/' else # Push the tag onto the stack # If the top of the stack is the same as the tag we want to push, close previous tag if (@stacksize > 0 && ! nestable?(tag) && @tagstack[@stacksize - 1] == tag) @tagqueue = "</#{@tagstack.pop}>" @stacksize -= 1 end @tagstack.push(tag) @stacksize += 1 end # Attributes if attributes != '' attributes = ' ' + attributes end tag = "<#{tag}#{attributes}>" #If already queuing a close tag, then put this tag on, too if @tagqueue @tagqueue << tag tag = '' end end newtext << text[0,pos] << tag text = text[pos+matchlen, text.length - (pos+matchlen)] end # Clear Tag Queue newtext << @tagqueue # Add Remaining text newtext << text # Empty Stack @tagstack.reverse_each do |t| newtext << "</#{t}>" # Add remaining tags to close end # WP fix for the bug with HTML comments newtext.gsub!("< !--", "<!--") newtext.gsub!("< !--", "< !--") newtext end |