class Shortcodes::WordpressShortcodes

Public Class Methods

new() click to toggle source

Ruby port of WordPress wp-includes/shortcodes

# File lib/shortcodes/wordpress_shortcodes.rb, line 6
def initialize
  @shortcode_tags = {}
end

Public Instance Methods

add_shortcode(tag, &block) click to toggle source
# File lib/shortcodes/wordpress_shortcodes.rb, line 18
def add_shortcode(tag, &block)
  @shortcode_tags[tag] = block
end
do_shortcode_tag(*m) click to toggle source
# File lib/shortcodes/wordpress_shortcodes.rb, line 61
def do_shortcode_tag(*m)
  # allow [[foo]] syntax for escaping a tag
  return m[0][1..-2] if m[1] == '[' && m[6] == ']'

  tag = m[2]
  att = shortcode_parse_atts m[3]

  if m[5].present?
    # enclosing tag - extra parameter
    m[1] + @shortcode_tags[tag].call(att, m[5], tag) + m[6]
  else
    # self-closing tag
    m[1] + @shortcode_tags[tag].call(att, nil, tag) + m[6]
  end
end
get_shortcode_regex() click to toggle source
# File lib/shortcodes/wordpress_shortcodes.rb, line 26
def get_shortcode_regex
  tagnames = @shortcode_tags.keys
  tagregexp = tagnames.map{ |x| Regexp::quote(x) }.join('|')

  Regexp.new('\[' +                    # Opening bracket
    '(\[?)' +                          # 1: Optional second opening bracket for escaping shortcodes: [[tag]]
    "(#{tagregexp})" +                 # 2: Shortcode name
    '\b' +                             # Word boundary
    '(' +                              # 3: Unroll the loop: Inside the opening shortcode tag
        '[^\]\/]*' +                   # Not a closing bracket or forward slash
        '(?:' +
            '\/(?!\])' +               # A forward slash not followed by a closing bracket
            '[^\]\/]*' +               # Not a closing bracket or forward slash
        ')*?' +
    ')' +
    '(?:' +
        '(\/)' +                       # 4: Self closing tag ...
        '\]' +                         # ... and closing bracket
    '|' +
        '\]' +                         # Closing bracket
        '(?:' +
            '(' +                      # 5: Unroll the loop: Optionally, anything between the opening and closing shortcode tags
                '[^\[]*+' +            # Not an opening bracket
                '(?:' +
                    '\[(?!\/\2\])' +   # An opening bracket not followed by the closing shortcode tag
                    '[^\[]*+' +        # Not an opening bracket
                ')*+' +
            ')' +
            '\[\/\2\]' +               # Closing shortcode tag
        ')?' +
    ')' +
    '(\]?)'                            # 6: Optional second closing brocket for escaping shortcodes: [[tag]]
  )
end
process(html) click to toggle source
# File lib/shortcodes/wordpress_shortcodes.rb, line 10
def process(html)
  if @shortcode_tags.any?
    html.gsub(get_shortcode_regex){ do_shortcode_tag *($~.to_a) }
  else
    html
  end
end
remove_shortcode(tag) click to toggle source
# File lib/shortcodes/wordpress_shortcodes.rb, line 22
def remove_shortcode(tag)
  @shortcode_tags.delete tag
end
shortcode_parse_atts(text) click to toggle source
# File lib/shortcodes/wordpress_shortcodes.rb, line 77
def shortcode_parse_atts(text)
  pattern = /(\w+)\s*=\s*"([^"]*)"(?:\s|$)|(\w+)\s*=\s*'([^']*)'(?:\s|$)|(\w+)\s*=\s*([^\s'"]+)(?:\s|$)|"([^"]*)"(?:\s|$)|(\S+)(?:\s|$)/
  text = text.gsub /[\u{00a0}\u{200b}]+/, ' '

  att_hash = {}
  att_array = []
  text.scan(pattern) do |m1, m2, m3, m4, m5, m6, m7, m8|
    if m1.present?
      att_hash[m1.downcase] = m2
    elsif m3.present?
      att_hash[m3.downcase] = m4
    elsif m5.present?
      att_hash[m5] = m6
    elsif m7.present?
      att_array << m7
    elsif m8.present?
      att_array << m8
    end
  end

  if !att_hash.empty?
    att_hash
  elsif !att_array.empty?
    att_array
  else
    text.lstrip
  end
end
strip_shortcode_tag(*m) click to toggle source
# File lib/shortcodes/wordpress_shortcodes.rb, line 114
def strip_shortcode_tag(*m)
  # allow [[foo]] syntax for escaping a tag
  if m[1] == '[' && m[6] == ']'
    m[0][1..-2]
  else
    m[1] + m[6]
  end
end
strip_shortcodes(content) click to toggle source
# File lib/shortcodes/wordpress_shortcodes.rb, line 106
def strip_shortcodes(content)
  if @shortcode_tags.any?
    content.gsub(get_shortcode_regex){ strip_shortcode_tag *($~.to_a) }
  else
    content
  end
end