Module: Emfsvg::Compat
- Defined in:
- lib/emfsvg/compat.rb
Defined Under Namespace
Classes: Result
Constant Summary collapse
- REF_BINARY_DEFAULT =
"/Users/mulgogi/src/claricle/libemf2svg/emf2svg_ref"- REF_LIB_DIR_DEFAULT =
"/Users/mulgogi/src/claricle/libemf2svg/build"
Class Method Summary collapse
-
.compare_glob(fixtures_glob) ⇒ Object
Walk a fixtures glob, produce both outputs, return Result array.
-
.count_elements(svg_root) ⇒ Object
Count drawing elements in an SVG.
-
.generate_emfsvg(emf_path, options = {}) ⇒ Object
Generate emfsvg output.
-
.generate_reference(emf_path, output_path = nil) ⇒ Object
Generate a reference SVG using libemf2svg.
-
.parse_svg(svg_string) ⇒ Object
Normalise an SVG document for structural comparison: - parse to REXML - return the root element.
- .ref_binary_available? ⇒ Boolean
-
.summarize(results) ⇒ Object
Summary across many results.
Class Method Details
.compare_glob(fixtures_glob) ⇒ Object
Walk a fixtures glob, produce both outputs, return Result array.
98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 |
# File 'lib/emfsvg/compat.rb', line 98 def compare_glob(fixtures_glob) results = [] Dir.glob(fixtures_glob).each do |emf| ref_svg = generate_reference(emf) next unless ref_svg emfsvg_svg = begin generate_emfsvg(emf) rescue StandardError nil end next unless emfsvg_svg results << Result.new( fixture: File.basename(emf), ref_bytes: ref_svg.bytesize, emfsvg_bytes: emfsvg_svg.bytesize, ref_elements: count_elements(parse_svg(ref_svg)), emfsvg_elements: count_elements(parse_svg(emfsvg_svg)) ) end results end |
.count_elements(svg_root) ⇒ Object
Count drawing elements in an SVG. Returns a hash like { "rect" => 3, "path" => 17, "ellipse" => 2 }.
66 67 68 69 70 71 72 73 74 |
# File 'lib/emfsvg/compat.rb', line 66 def count_elements(svg_root) counts = Hash.new(0) return counts unless svg_root REXML::XPath.each(svg_root, "descendant-or-self::*") do |el| counts[el.name] += 1 end counts end |
.generate_emfsvg(emf_path, options = {}) ⇒ Object
Generate emfsvg output. Requires the emfsvg gem to be loaded.
51 52 53 |
# File 'lib/emfsvg/compat.rb', line 51 def generate_emfsvg(emf_path, = {}) Emfsvg.from_file(emf_path, **) end |
.generate_reference(emf_path, output_path = nil) ⇒ Object
Generate a reference SVG using libemf2svg. Returns the SVG bytes, or nil if generation failed.
37 38 39 40 41 42 43 44 45 46 47 48 |
# File 'lib/emfsvg/compat.rb', line 37 def generate_reference(emf_path, output_path = nil) binary = ENV.fetch("EMF2SVG_REF_PATH", REF_BINARY_DEFAULT) lib_dir = ENV.fetch("EMF2SVG_REF_LIB_DIR", REF_LIB_DIR_DEFAULT) env = { "DYLD_LIBRARY_PATH" => lib_dir } output_path ||= "#{Dir.mktmpdir}/#{File.basename(emf_path, '.emf')}.svg" _, _, status = Open3.capture3(env, binary, emf_path, output_path) return nil unless status.success? File.binread(output_path) ensure File.delete(output_path) if output_path && !block_given? end |
.parse_svg(svg_string) ⇒ Object
Normalise an SVG document for structural comparison:
- parse to REXML
- return the root element
58 59 60 61 62 |
# File 'lib/emfsvg/compat.rb', line 58 def parse_svg(svg_string) REXML::Document.new(svg_string).root rescue REXML::ParseException nil end |
.ref_binary_available? ⇒ Boolean
30 31 32 33 |
# File 'lib/emfsvg/compat.rb', line 30 def ref_binary_available? path = ENV.fetch("EMF2SVG_REF_PATH", REF_BINARY_DEFAULT) File.executable?(path) end |
.summarize(results) ⇒ Object
Summary across many results.
123 124 125 126 127 128 129 130 131 132 |
# File 'lib/emfsvg/compat.rb', line 123 def summarize(results) return "no results" if results.empty? total_ref = results.sum(&:ref_bytes) total_out = results.sum(&:emfsvg_bytes) ratio = total_ref.zero? ? 0 : (total_out.to_f / total_ref * 100).round(1) avg_overlap = results.sum(&:element_overlap) / results.size format("fixtures=%d total_ref=%d total_out=%d byte_ratio=%.1f%% avg_element_overlap=%.1f%%", results.size, total_ref, total_out, ratio, avg_overlap * 100) end |