kairo-gokko (1) 回路データの読み込み



f:id:sonota88:20200211103804p:plain

  • (1) 上の画像のような回路図(回路図のつもり)を LibreOffice Draw で描いて
  • (2) fodg ファイルから矩形と直線の情報を抽出する

ところまで。


(1) については、上の画像の通りですね。 グリッド幅は1センチです。

Flat XML ODF Drawing(拡張子は .fodg)形式で保存します。

f:id:sonota88:20200211105311p:plain


(2) は↓ここらへんですでにやったので、それを使って適当に。


適当に書いたもの。

# libo_draw.rb

require "rexml/document"

module LiboDraw

  class Document
    def initialize(path)
      xml = File.read(path)
      @doc = REXML::Document.new(xml)
    end

    def pages
      REXML::XPath.match(@doc, "//draw:page")
        .map { |page_el| Page.new(page_el) }
    end
  end

  class Page
    def initialize(el)
      @el = el
    end

    def rectangles
      custom_shape_els = REXML::XPath.match(@el, "draw:custom-shape")

      custom_shape_els
        .select { |el|
          geo_el = REXML::XPath.match(el, "draw:enhanced-geometry")[0]
          geo_el["draw:type"] == "rectangle"
        }
        .map { |el| Rectangle.new(el) }
    end

    def lines
      REXML::XPath.match(@el, "draw:line")
        .map { |line_el| Line.new(line_el) }
    end
  end

  class Rectangle
    def initialize(el)
      @el = el
    end

    def text
      texts = []
      @el.each_element_with_text { |el|
        texts << el.texts.join(" ")
      }
      texts.join(" ")
    end

    def inspect
      values = [
        self.class.name,
        "x=" + @el["svg:x"],
        "y=" + @el["svg:y"],
        "w=" + @el["svg:width"],
        "h=" + @el["svg:height"],
        "text=" + text.inspect,
      ]

      "(" + values.join(" ") + ")"
    end
  end

  class Line
    def initialize(el)
      @el = el
    end

    def inspect
      values = [
        self.class.name,
        "x1=" + @el["svg:x1"],
        "y1=" + @el["svg:y1"],
        "x2=" + @el["svg:x2"],
        "y2=" + @el["svg:y2"],
      ]

      "(" + values.join(" ") + ")"
    end
  end

end

# --------------------------------

if $0 == __FILE__
  require "pp"

  path = ARGV[0]

  doc = LiboDraw::Document.new(path)

  pp doc.pages[0].rectangles
  pp doc.pages[0].lines
end

実行。

$ ruby libo_draw.rb data_01.fodg
[(LiboDraw::Rectangle x=1.1cm y=4.1cm w=0.8cm h=0.8cm text="-"),
 (LiboDraw::Rectangle x=1.1cm y=3.1cm w=0.8cm h=0.8cm text="+")]
[(LiboDraw::Line x1=1.5cm y1=1.5cm x2=1.5cm y2=3.2cm),
 (LiboDraw::Line x1=3.7cm y1=1.6cm x2=3.6cm y2=4.4cm),
 (LiboDraw::Line x1=3.5cm y1=1.5cm x2=1.6cm y2=1.4cm),
 (LiboDraw::Line x1=3.4cm y1=2.5cm x2=3.5cm y2=6.4cm),
 (LiboDraw::Line x1=1.3cm y1=4.7cm x2=1.3cm y2=6.4cm),
 (LiboDraw::Line x1=3.2cm y1=6.2cm x2=1.4cm y2=6.3cm)]