Created
April 30, 2025 22:29
-
-
Save danwakefield/7756c03a2a839d46130251033d46a871 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require 'csv' | |
# This reads a CSV and outputs it in the Cross Stitch osx format | |
# For the life of me I could not get https://flosscross.com/ to actually read the output | |
# when run with `ruby csv_to_osx_cross_stitch_format.rb > output.osx` | |
# despite `file output.osx` telling me it was valid XML (and being the same as | |
# a file _exported_ from flosscross) | |
# Instead I created a new blank project in flosscross, exported that to OSX, | |
# Opened it, and replaced its `palette` and `fullstitches` sections with the | |
# ones from this generation. | |
# Maybe newlines or something with encoding but whatever it worked | |
class OsxFileFormat | |
attr_reader :height, :width, :csv_content, :colors | |
def initialize(csv_path, colors: {}) | |
@csv_content = CSV.read(csv_path, headers: false) | |
@width = csv_content.first.length + 2 | |
@height = csv_content.length + 2 | |
@colors = colors | |
@colors.each.with_index(1) { |(_, v), index| v[:index] = index } | |
end | |
def palette_items | |
colors.map do |symbol, config| | |
<<~XML.gsub!(/[[:space:]]+/, " ") | |
<palette_item | |
index="#{config[:index]}" | |
number="#{config[:number]}" | |
name="#{config[:name]}" | |
color="#{config[:color]}" | |
printcolor="#{config[:color]}" | |
blendcolor="nil" | |
comments="" | |
strands="2" | |
symbol="#{config[:index]}" | |
dashpattern="" | |
bsstrands="1" | |
bscolor="ffffff" | |
misc1="" /> | |
XML | |
end | |
end | |
def csv_to_stitches | |
a = [] | |
csv_content.each.with_index(1) do |row, y_index| | |
row.each.with_index(1) do |cell, x_index| | |
c = colors[cell] | |
next if c.nil? | |
stitch_content = <<~XML.gsub!(/[[:space:]]+/, " ").strip! | |
<stitch x="#{x_index}" y="#{y_index}" palindex="#{c[:index]}" /> | |
XML | |
a << stitch_content | |
end | |
end | |
a | |
end | |
def output_file | |
puts <<~XML | |
<?xml version="1.0" encoding="UTF-8"?> | |
<chart> | |
<format comments01="https://ursasoftware.com/OXSFormat/" /> | |
<properties | |
oxsversion="1.0" | |
software="FlossCross" | |
software_version="104" | |
chartheight="#{height}" | |
chartwidth="#{width}" | |
charttitle="vampurr" | |
author="" | |
copyright="" | |
instructions="" | |
stitchesperinch="14" | |
stitchesperinch_y="14" | |
palettecount="#{palette_items.length}" | |
misc1="normal" misc2="" /> | |
<palette> | |
<palette_item index="0" number="cloth" name="cloth" color="FFFFFF" printcolor="FFFFFF" blendcolor="nil" comments="" strands="2" symbol="100" dashpattern="" misc1="" bsstrands="2" bscolor="FFFFFF"/> | |
#{palette_items.join("\n")} | |
</palette> | |
<fullstitches> | |
#{csv_to_stitches.join("")} | |
</fullstitches> | |
<partstitches> | |
<partstitch /> | |
</partstitches> | |
<backstitches> | |
<backstitch /> | |
</backstitches> | |
<ornaments_inc_knots_and_beads> | |
<object /> | |
</ornaments_inc_knots_and_beads> | |
<commentboxes /> | |
</chart> | |
XML | |
end | |
end | |
colors = { | |
"." => { number: "DMC 782", name: "Gold", color: "7E5A23" }, | |
"+" => { number: "DMC 817", name: "Mid Red", color: "AF2D27" }, | |
"–" => { number: "DMC 4", name: "Dark Grey", color: "7F7A7F" }, | |
"w" => { number: "DMC 816", name: "Dark Red", color: "812A32" }, | |
"●" => { number: "DMC 310", name: "Black", color: "000000" }, | |
"≈" => { number: "DMC 1", name: "Lightest Grey", color: "DDDDDD" }, | |
"☆" => { number: "DMC 780", name: "Dark Gold", color: "A55B1A" }, | |
"β" => { number: "DMC 535", name: "Grey", color: "585858" }, | |
"s" => { number: "DMC 3799", name: "Darkest Grey", color: "303030" }, | |
"▮" => { number: "DMC B5200", name: "Blanc", color: "FFFFF9" }, | |
"⊗" => { number: "DMC 2", name: "Lighter Grey", color: "CAC9CC" }, | |
"¶" => { number: "DMC 814", name: "Burgundy", color: "540F21" }, | |
"%" => { number: "DMC 3", name: "Darker Grey", color: "A2A1A8" }, | |
">" => { number: "DMC 3801", name: "Blood Red", color: "C93536" }, | |
"▲" => { number: "DMC 815", name: "Maroon", color: "6C1D24" }, | |
"λ" => { number: "DMC 783", name: "Yellow Gold", color: "D28922" }, | |
"Z" => { number: "DMC 300", name: "Brown", color: "562811" }, | |
} | |
OsxFileFormat.new("/tmp/x.csv", colors: colors).output_file | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
replaced the ones it didn't like??DMC 1
in the number section they must beDMC 01
to match. If they dont match it falls back to hex-math. See the Palette definition in https://flosscross.com/public/assets/scripts/general-86d6bed3c0.js and the logic ingetColors