class Pangrid::AcrossLiteText

Text format

Constants

DESCRIPTION

Attributes

rebus[RW]
xw[RW]

Public Class Methods

new() click to toggle source
# File lib/pangrid/plugins/acrosslite.rb, line 366
def initialize
  @xw = XWord.new
end

Public Instance Methods

read(data) click to toggle source
# File lib/pangrid/plugins/acrosslite.rb, line 370
def read(data)
  s = data.each_line.map(&:strip)
  # first line must be <ACROSS PUZZLE> or <ACROSS PUZZLE V2>
  xw.version = { "<ACROSS PUZZLE>" => 1, "<ACROSS PUZZLE V2>" => 2 }[s.shift]
  check("Could not recognise Across Lite text file") { !xw.version.nil? }
  header, section = "START", []
  s.each do |line|
    if line =~ /^<(.*)>/
      process_section header, section
      header = $1
      section = []
    else
      section << line
    end
  end
  process_section header, section
  xw
end
write(xw) click to toggle source
# File lib/pangrid/plugins/acrosslite.rb, line 389
def write(xw)
  @xw = xw

  # scan the grid for rebus squares and replace them with lookup keys
  xw.encode_rebus!

  # fill in dummy clues if none exist
  across, down = xw.number
  if xw.across_clues.empty?
    xw.across_clues = ["(no clue)"]*across.length
  end
  if xw.down_clues.empty?
    xw.down_clues = ["(no clue)"]*down.length
  end

  sections = [
    ['TITLE', [xw.title]],
    ['AUTHOR', [xw.author]],
    ['COPYRIGHT', [xw.copyright]],
    ['SIZE', ["#{xw.height}x#{xw.width}"]],
    ['GRID', write_grid],
    ['REBUS', write_rebus],
    ['ACROSS', xw.across_clues],
    ['DOWN', xw.down_clues],
    ['NOTEPAD', xw.notes.to_s.split("\n")]
  ]
  out = ["<ACROSS PUZZLE V2>"]
  sections.each do |h, s|
    next if s.nil? || s.empty?
    out << "<#{h}>"
    s.each {|l| out << " #{l}"}
  end
  out.join("\n") + "\n"
end

Private Instance Methods

process_section(header, section) click to toggle source
# File lib/pangrid/plugins/acrosslite.rb, line 426
def process_section(header, section)
  case header
  when "START"
    return
  when "TITLE", "AUTHOR", "COPYRIGHT"
    check { section.length == 1 }
    xw[header.downcase] = section[0]
  when "NOTEPAD"
    xw.notes = section.join("\n")
  when "SIZE"
    check { section.length == 1 && section[0] =~ /^\d+x\d+/ }
    xw.height, xw.width = section[0].split('x').map(&:to_i)
  when "GRID"
    check { xw.width && xw.height }
    check { section.length == xw.height }
    check { section.all? {|line| line.length == xw.width } }
    xw.solution = unpack_solution xw, section.join
  when "REBUS"
    check { section.length > 0 }
    check("Text format v1 does not support <REBUS>") {xw.version == 2}
    # flag list (currently MARK or nothing)
    xw.mark = section[0] == "MARK;"
    section.shift if xw.mark
    section.each do |line|
      check { line =~ /^.+:.+:.$/ }
      sym, long, short = line.split(':')
      xw.each_cell do |c|
        if c.solution == sym
          c.solution = Rebus.new(long, short)
        end
      end
    end
    xw.encode_rebus!

  when "ACROSS"
    xw.across_clues = section
  when "DOWN"
    xw.down_clues = section
  else
    raise PuzzleFormatError, "Unrecognised header #{header}"
  end
end
write_grid() click to toggle source
# File lib/pangrid/plugins/acrosslite.rb, line 469
def write_grid
  xw.to_array(GRID_CHARS).map(&:join)
end
write_rebus() click to toggle source
# File lib/pangrid/plugins/acrosslite.rb, line 473
def write_rebus
  out = []
  out << "MARK;" if xw.mark
  xw.rebus.keys.sort.each do |long|
    key, short = xw.rebus[long]
    out << "#{key}:#{long}:#{short}"
  end
  out
end