Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 29 additions & 1 deletion spec/lucky/text_helpers/svg_inliner_spec.cr
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,18 @@ class TextHelperTestPage
def with_inlined_and_styled_svg
inline_svg("lucky_logo.svg", false)
end

def with_additional_attributes
inline_svg("lucky_logo.svg", data_very: "lucky")
end

def with_original_styles_and_additional_attributes
inline_svg("lucky_logo.svg", strip_styling: false, data_very: "lucky")
end

def without_file_extension
inline_svg("lucky_logo")
end
end

describe Lucky::SvgInliner do
Expand Down Expand Up @@ -45,10 +57,26 @@ describe Lucky::SvgInliner do
inlined_svg.should_not contain %(fill="none" stroke="#2a2a2a" class="logo")
end

it "allows inlinging an svg without stripping its styling attributes" do
it "allows inlining an svg without stripping its styling attributes" do
inlined_svg = view.tap(&.with_inlined_and_styled_svg).render
inlined_svg.should start_with %(<svg data-inline-svg-styled="lucky_logo.svg")
inlined_svg.should contain %(fill="none" stroke="#2a2a2a" class="logo")
end

it "accepts additional arguments for aribitrary attributes" do
inlined_svg = view.tap(&.with_additional_attributes).render
inlined_svg.should contain %(data-very="lucky")
end

it "does not render the strip_styling option as attribute" do
inlined_svg = view.tap(&.with_original_styles_and_additional_attributes).render
inlined_svg.should contain %(data-very="lucky")
inlined_svg.should_not contain %(strip-styling="false")
end

it "allows passing the svg path name without an extension" do
inlined_svg = view.tap(&.without_file_extension).render
inlined_svg.should start_with %(<svg data-inline-svg="lucky_logo.svg")
end
end
end
14 changes: 12 additions & 2 deletions src/lucky/page_helpers/svg_inliner.cr
Original file line number Diff line number Diff line change
Expand Up @@ -6,23 +6,33 @@ end
@[Lucky::SvgInliner::Path("src/svgs")]
@[Lucky::SvgInliner::StripRegex(/(class|fill|stroke|stroke-width|style)="[^"]+" ?/)]
module Lucky::SvgInliner
macro inline_svg(path, strip_styling = true)
macro inline_svg(path, strip_styling = true, **named_args)
{%
svgs_path = Lucky::SvgInliner.annotation(Lucky::SvgInliner::Path).args.first
regex = Lucky::SvgInliner.annotation(Lucky::SvgInliner::StripRegex).args.first
path = "#{path.id}.svg" unless path.ends_with?(".svg")
full_path = "#{svgs_path.id}/#{path.id}"

raise "SVG file #{full_path.id} is missing" unless file_exists?(full_path)

# Strip the XML declaration, comments, and whitespace
svg = read_file(full_path)
.gsub(/<\?xml[^>]+>/, "")
.gsub(/<!--[^>]+>/, "")
.gsub(/\n\s*/, " ")
.strip

# Strip styling using the given regex, if required
svg = svg.gsub(regex, "") if strip_styling
modifier = strip_styling ? "" : "-styled"

# Build new attributes for svg tag
attributes = [%(data-inline-svg#{modifier.id}="#{path.id}")]
named_args.each do |name, value|
attributes << %(#{name.stringify.gsub(/_/, "-").id}="#{value.id}")
end
%}

raw {{svg.gsub(/<svg/, %(<svg data-inline-svg#{modifier.id}="#{path.id}"))}}
raw {{svg.gsub(/<svg/, %(<svg #{attributes.join(" ").id}))}}
end
end