Class: Jekyll::Tags::JekyllInlineSvg

Inherits:
Liquid::Tag
  • Object
show all
Includes:
LiquidExtensions
Defined in:
lib/jekyll-inline-svg.rb

Constant Summary collapse

VARIABLE =

For interpoaltion, look for liquid variables

/\{\{\s*([\w]+\.?[\w]*)\s*\}\}/i
PATH_SYNTAX =

Separate file path from other attributes

%r!
  ^(?<path>[^\s"']+|"[^"]+"|'[^']+')
  (?<params>.*)
!x
PARAM_SYNTAX =

parse the first parameter in a string, giving :

[full_match, param_name, double_quoted_val, single_quoted_val, unquoted_val]

The Regex works like :

  • first group

    - match a group of characters that is alphanumeric, _ or -.
    
  • second group (non-capturing OR)

    - match a double-quoted string
    - match a single-quoted string
    - match an unquoted string matching the set : [\w\.\-#]
    
%r!
  ([\w-]+)\s*=\s*
  (?:"([^"\\]*(?:\\.[^"\\]*)*)"|'([^'\\]*(?:\\.[^'\\]*)*)'|([\w\.\-#]+))
!x

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(tag_name, markup, tokens) ⇒ JekyllInlineSvg

Returns a new instance of JekyllInlineSvg.



44
45
46
47
# File 'lib/jekyll-inline-svg.rb', line 44

def initialize(tag_name, markup, tokens)
  super
  @svg, @params = JekyllInlineSvg.parse_params(markup)
end

Class Method Details

.parse_params(markup) ⇒ Object

Parse parameters. Returns : [svg_path, parameters] Does not interpret variables as it’s done at render time



73
74
75
76
77
78
79
80
81
82
83
84
85
# File 'lib/jekyll-inline-svg.rb', line 73

def self.parse_params(markup)
  matched = markup.strip.match(PATH_SYNTAX)
  if !matched
    raise SyntaxError, "    Syntax Error in tag 'highlight' while parsing the following markup:\n    \#{markup}\n    Valid syntax: svg <path> [property=value]\n    END\n  end\n  path = matched[\"path\"].sub(%r!^[\"']!,\"\").sub(%r![\"']$!,\"\").strip\n  params = matched[\"params\"].strip\n  return path, params\nend\n"

Instance Method Details

#add_file_to_dependency(site, path, context) ⇒ Object



103
104
105
106
107
108
109
110
# File 'lib/jekyll-inline-svg.rb', line 103

def add_file_to_dependency(site, path, context)
  if context.registers[:page] && context.registers[:page].key?("path")
    site.regenerator.add_dependency(
      site.in_source_dir(context.registers[:page]["path"]),
      path
    )
  end
end

#create_plugin(params) ⇒ Object



90
91
92
93
94
95
96
97
98
99
100
101
102
# File 'lib/jekyll-inline-svg.rb', line 90

def create_plugin(params)
  mod = Class.new(SvgOptimizer::Plugins::Base) do
    def self.set (p)
      @@params = p
    end
    def process
      @@params.each {|key,val| xml.root.set_attribute(key,val)}
      return xml
    end
  end
  mod.set(params)
  return mod
end

#fmt(params) ⇒ Object



86
87
88
89
# File 'lib/jekyll-inline-svg.rb', line 86

def fmt(params)
  r = params.to_a.select{|v| v[1] != ""}.map {|v| %!#{v[0]}="#{v[1]}"!}
  r.join(" ")
end

#interpolate(markup, context) ⇒ Object

lookup Liquid variables from markup in context



50
51
52
53
54
55
# File 'lib/jekyll-inline-svg.rb', line 50

def interpolate(markup, context)
  markup.scan VARIABLE do |variable|
    markup = markup.sub(VARIABLE, lookup_variable(context, variable.first))
  end
  markup
end

#render(context) ⇒ Object



112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
# File 'lib/jekyll-inline-svg.rb', line 112

def render(context)
  #global site variable
  site = context.registers[:site]
  #check if given name is a variable. Otherwise use it as a file name
  svg_file = Jekyll.sanitized_path(site.source, interpolate(@svg,context))
  return unless svg_file
  add_file_to_dependency(site,svg_file, context)
  #replace variables with their current value
  params = split_params(@params,context)
  #because ie11 require to have a height AND a width
  if params.key? "width" and ! params.key? "height"
    params["height"] = params["width"]
  end
  #params = @params
  file = File.open(svg_file, "rb").read
  conf = lookup_variable(context,"site.svg")
  if conf["optimize"] == true
    xml = SvgOptimizer.optimize(file, [create_plugin(params)] + PLUGINS)
  else
    xml = Nokogiri::XML(file)
    params.each {|key,val| xml.root.set_attribute(key,val)}
    xml = xml.root.to_xml
  end
 return xml
end

#split_params(markup, context) ⇒ Object



56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
# File 'lib/jekyll-inline-svg.rb', line 56

def split_params(markup, context)
  params={}
  while (match = PARAM_SYNTAX.match(markup))
    markup = markup[match.end(0)..-1]
    value = if match[2]
      interpolate(match[2].gsub(%r!\\"!, '"'), context)
    elsif match[3]
      interpolate(match[3].gsub(%r!\\'!, "'"),context)
    elsif match[4]
      lookup_variable(context, match[4])
    end
    params[match[1]] = value
  end
  return params
end