Class: Jekyll::Tags::JekyllInlineSvg

Inherits:
Liquid::Tag
  • Object
show all
Includes:
LiquidExtensions
Defined in:
lib/jekyll-inline-external-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.



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

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



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

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

Instance Method Details

#add_file_to_dependency(site, path, context) ⇒ Object



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

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



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

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



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

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



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

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

#render(context) ⇒ Object



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

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
  if params.key? "is_external"
    file = open(svg_file).read
  else
    file = File.open(svg_file, "rb").read
  end
  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.to_xml
  end
 return xml
end

#split_params(markup, context) ⇒ Object



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

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