diff --git a/README.md b/README.md index 4426ab2..f08852e 100644 --- a/README.md +++ b/README.md @@ -90,14 +90,16 @@ module_size - The Pixel size of each module (defaults 11) shape_rendering - SVG Attribute: auto | optimizeSpeed | crispEdges | geometricPrecision (defaults crispEdges) -standalone - whether to make this a full SVG file, or only an svg to embed in other svg +standalone - Whether to make this a full SVG file, or only an svg to embed in other svg (default true) use_path - Use to render SVG rather than to significantly reduce size and quality. This will become the default in future versions. (default false) -viewbox - replace the `svg.width` and `svg.height` attribute with `svg.viewBox` to +viewbox - Replace the `svg.width` and `svg.height` attribute with `svg.viewBox` to allow CSS scaling (default false) +svg_attributes - A optional hash of custom attributes. Existing attributes will remain. + (default {}) ``` Example ```ruby @@ -111,7 +113,10 @@ svg = qrcode.as_svg( shape_rendering: 'crispEdges', module_size: 11, standalone: true, - use_path: true + use_path: true, + svg_attributes: { + id: "myUniqueId" + } ) ``` diff --git a/lib/rqrcode/export/svg.rb b/lib/rqrcode/export/svg.rb index 78b9f59..4e2fdf6 100644 --- a/lib/rqrcode/export/svg.rb +++ b/lib/rqrcode/export/svg.rb @@ -115,6 +115,13 @@ def end_y end end + DEFAULT_SVG_ATTRIBUTES = [ + %(version="1.1"), + %(xmlns="http://www.w3.org/2000/svg"), + %(xmlns:xlink="http://www.w3.org/1999/xlink"), + %(xmlns:ev="http://www.w3.org/2001/xml-events") + ] + SVG_PATH_COMMANDS = { move: "M", up: "v-", @@ -145,6 +152,8 @@ def end_y # (default false) # viewbox - replace `width` and `height` in with a viewBox, allows CSS scaling # (default false) + # svg_attributes - A optional hash of custom attributes. Existing attributes will remain. + # (default {}) # def as_svg(options = {}) fill = options[:fill] @@ -155,14 +164,20 @@ def as_svg(options = {}) module_size = options[:module_size] || 11 standalone = options[:standalone].nil? ? true : options[:standalone] viewbox = options[:viewbox].nil? ? false : options[:viewbox] + svg_attributes = options[:svg_attributes] || {} # height and width dependent on offset and QR complexity dimension = (@qrcode.module_count * module_size) + (2 * offset) # use dimensions differently if we are using a viewBox dimensions_attr = viewbox ? %(viewBox="0 0 #{dimension} #{dimension}") : %(width="#{dimension}" height="#{dimension}") + svg_tag_attributes = (DEFAULT_SVG_ATTRIBUTES + [ + dimensions_attr, + %(shape-rendering="#{shape_rendering}") + ] + svg_attributes.map { |k, v| %(#{k}="#{v}") }).join(" ") + xml_tag = %() - open_tag = %() + open_tag = %() close_tag = "" output_tag = (use_path ? Path : Rect).new(@qrcode) diff --git a/spec/rqrcode/data.rb b/spec/rqrcode/data.rb index 130da00..aaf67bb 100644 --- a/spec/rqrcode/data.rb +++ b/spec/rqrcode/data.rb @@ -22,6 +22,10 @@ SVG +AS_SVG5 = <<~SVG.chomp + +SVG + AS_BASIC = <<~STR XXXXXXXOOOXOXOOXXXOOOOXXXXXXX XOOOOOXOOXXXXXOOXOXOOOXOOOOOX diff --git a/spec/rqrcode/export_svg_spec.rb b/spec/rqrcode/export_svg_spec.rb index 6306310..53cbed3 100644 --- a/spec/rqrcode/export_svg_spec.rb +++ b/spec/rqrcode/export_svg_spec.rb @@ -49,4 +49,16 @@ )).to eq(AS_SVG4) end end + + context "svg_attributes" do + it "renders `svg_attributes` when provided " do + expect(RQRCode::QRCode.new("qrcode").as_svg( + use_path: true, + svg_attributes: { + id: "myUniqueId", + class: "myClass" + } + )).to eq(AS_SVG5) + end + end end