pangrid 0.2.2 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/pangrid/data/webform.html +1 -0
- data/lib/pangrid/plugins/acrosslite.rb +16 -2
- data/lib/pangrid/plugins/reddit.rb +77 -0
- data/lib/pangrid/plugins/text.rb +1 -1
- data/lib/pangrid/version.rb +1 -1
- data/lib/pangrid/xw.rb +25 -0
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ca64b939037c4c658be062373bc66156605c3833
|
4
|
+
data.tar.gz: 8792223200b3f4a5bfdcd212127c6724b4a087ae
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a3361137ff447f19ae7f2db13ca66c259b10a1f13387382881c25d5f63e5b84a7516999bf19c27a4b984ee08553f8461e7db66389e8391fe2f867b8523bd3aa5
|
7
|
+
data.tar.gz: becb38b39f34b7e25876e5d1a7d148bb92a205fd59230fbb11ea465680099bf65bc46952391df8dafb8a6cf8f9aba7d073388d20504a92c2224058e0ccc689e7
|
@@ -11,7 +11,8 @@ require 'ostruct'
|
|
11
11
|
|
12
12
|
module Pangrid
|
13
13
|
|
14
|
-
GRID_CHARS = {:black => '.', :null => '
|
14
|
+
GRID_CHARS = {:black => '.', :null => '?'}
|
15
|
+
FILL_CHARS = {:black => '.', :null => '-'}
|
15
16
|
|
16
17
|
# CRC checksum for binary format
|
17
18
|
class Checksum
|
@@ -62,7 +63,7 @@ module AcrossLiteUtils
|
|
62
63
|
def empty_fill(xw)
|
63
64
|
# when converting from another format -> binary we won't typically have fill
|
64
65
|
# information, since that is an internal property of the acrosslite player
|
65
|
-
grid = xw.to_array(
|
66
|
+
grid = xw.to_array(FILL_CHARS) {|c| '-'}
|
66
67
|
grid.map(&:join).join
|
67
68
|
end
|
68
69
|
end
|
@@ -138,6 +139,7 @@ class AcrossLiteBinary < Plugin
|
|
138
139
|
|
139
140
|
# fill in some fields that might not be present (checksums needs this)
|
140
141
|
pack_clues
|
142
|
+
xw.clues = xw.clues.map(&:to_s)
|
141
143
|
xw.n_clues = xw.clues.length
|
142
144
|
xw.fill ||= empty_fill(xw)
|
143
145
|
xw.puzzle_type ||= 1
|
@@ -145,6 +147,9 @@ class AcrossLiteBinary < Plugin
|
|
145
147
|
xw.version = "1.3"
|
146
148
|
xw.notes ||= ""
|
147
149
|
xw.extensions ||= []
|
150
|
+
xw.title ||= ""
|
151
|
+
xw.author ||= ""
|
152
|
+
xw.copyright ||= ""
|
148
153
|
|
149
154
|
# extensions
|
150
155
|
xw.encode_rebus!
|
@@ -383,6 +388,15 @@ class AcrossLiteText < Plugin
|
|
383
388
|
# scan the grid for rebus squares and replace them with lookup keys
|
384
389
|
xw.encode_rebus!
|
385
390
|
|
391
|
+
# fill in dummy clues if none exist
|
392
|
+
across, down = xw.number
|
393
|
+
if xw.across_clues.empty?
|
394
|
+
xw.across_clues = ["(no clue)"]*across.length
|
395
|
+
end
|
396
|
+
if xw.down_clues.empty?
|
397
|
+
xw.down_clues = ["(no clue)"]*down.length
|
398
|
+
end
|
399
|
+
|
386
400
|
sections = [
|
387
401
|
['TITLE', [xw.title]],
|
388
402
|
['AUTHOR', [xw.author]],
|
@@ -52,6 +52,83 @@ class RedditBlank < Plugin
|
|
52
52
|
write_xw(xw)
|
53
53
|
end
|
54
54
|
|
55
|
+
def is_grid_row(line)
|
56
|
+
line = line.gsub(/\s/, '')
|
57
|
+
ix = line.index('|')
|
58
|
+
return false unless ix
|
59
|
+
c = line[0...ix]
|
60
|
+
c == "" || c == "*.*" || c =~ /^(\^\d+)?[[:alpha:]]*$/ # allow partially filled grids
|
61
|
+
end
|
62
|
+
|
63
|
+
# make a best-attempt effort to strip off the clue number
|
64
|
+
def strip_clues(nums, clues)
|
65
|
+
nums.zip(clues).each_with_index.map do |(n, cl), i|
|
66
|
+
b = cl.index(n.to_s)
|
67
|
+
if b
|
68
|
+
e = b + n.to_s.length
|
69
|
+
if cl[0...b] =~ /\W*/ and cl[e + 1] =~ /\W/
|
70
|
+
cl[e+1 .. -1].sub(/^\W*\s/, '').strip
|
71
|
+
else
|
72
|
+
cl.strip
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
def read(data)
|
79
|
+
xw = XWord.new
|
80
|
+
lines = data.lines.map(&:chomp)
|
81
|
+
|
82
|
+
# split input into grid and clues
|
83
|
+
#
|
84
|
+
# grid format is from the reddit table markup:
|
85
|
+
# cell|cell|... # table header; first row for us
|
86
|
+
# --|--|... # alignment markers; drop this
|
87
|
+
# cell|cell|... # rest of xword
|
88
|
+
#
|
89
|
+
# we have to be careful about leading/trailing |s
|
90
|
+
ix = lines.find_index {|row| row =~ /^[|\s-]+$/}
|
91
|
+
width = lines[ix].gsub(/\s/, '').split('|').reject(&:empty?).length
|
92
|
+
lines = [lines[(ix - 1)]] + lines[(ix + 1) .. -1]
|
93
|
+
grid = lines.take_while {|i| is_grid_row(i)}
|
94
|
+
|
95
|
+
clues = lines[grid.length .. -1]
|
96
|
+
clues = lines.reject {|i| i.strip.empty?}
|
97
|
+
|
98
|
+
# strip leading |s
|
99
|
+
grid = grid.map {|line| line.sub(/^\|/, '')}
|
100
|
+
grid = grid.map {|line| line.split("|", -1)[0..(width-1)]}
|
101
|
+
grid = grid.map {|line| line.map(&:strip)}
|
102
|
+
xw.width = grid[0].length
|
103
|
+
xw.height = grid.length
|
104
|
+
xw.solution = []
|
105
|
+
check("Grid is not rectangular") { grid.all? {|i| i.length == xw.width} }
|
106
|
+
grid = grid.map do |row|
|
107
|
+
xw.solution << row.map do |c|
|
108
|
+
cell = Cell.new
|
109
|
+
if c == '*.*'
|
110
|
+
cell.solution = :black
|
111
|
+
elsif c =~ /[[:alpha:]]/
|
112
|
+
cell.solution = c.gsub(/[^[:alpha:]]/, '')
|
113
|
+
else
|
114
|
+
cell.solution = :null
|
115
|
+
end
|
116
|
+
cell
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
# Clues
|
121
|
+
across, down = xw.number
|
122
|
+
aix = clues.find_index {|row| row =~ /^\W*across/i}
|
123
|
+
dix = clues.find_index {|row| row =~ /^\W*down/i}
|
124
|
+
xw.across_clues = clues[(aix + 1) .. (aix + across.length)]
|
125
|
+
xw.down_clues = clues[(dix + 1) .. (dix + down.length)]
|
126
|
+
xw.across_clues = strip_clues(across, xw.across_clues)
|
127
|
+
xw.down_clues = strip_clues(down, xw.down_clues)
|
128
|
+
|
129
|
+
xw
|
130
|
+
end
|
131
|
+
|
55
132
|
def grid(xw)
|
56
133
|
xw.to_array({:black => '*.*', :null => ' '}) do |c|
|
57
134
|
c.number ? "^#{c.number}" : ''
|
data/lib/pangrid/plugins/text.rb
CHANGED
@@ -11,7 +11,7 @@ module Pangrid
|
|
11
11
|
class Text < Plugin
|
12
12
|
def write(xw)
|
13
13
|
across, down = xw.number
|
14
|
-
rows = xw.to_array(:black => '#', :null => '
|
14
|
+
rows = xw.to_array(:black => '#', :null => '.')
|
15
15
|
grid = rows.map(&:join).join("\n") + "\n"
|
16
16
|
ac = "Across:\n\n" + format_clues(across, xw.across_clues, 2)
|
17
17
|
dn = "Down:\n\n" + format_clues(down, xw.down_clues, 2)
|
data/lib/pangrid/version.rb
CHANGED
data/lib/pangrid/xw.rb
CHANGED
@@ -147,6 +147,31 @@ class XWord < OpenStruct
|
|
147
147
|
end
|
148
148
|
end
|
149
149
|
end
|
150
|
+
|
151
|
+
def inspect_grid
|
152
|
+
number
|
153
|
+
solution.map {|row|
|
154
|
+
row.map {|c|
|
155
|
+
s = c.solution
|
156
|
+
o = case s
|
157
|
+
when :black
|
158
|
+
"#"
|
159
|
+
when :null
|
160
|
+
"."
|
161
|
+
when String
|
162
|
+
c.to_char
|
163
|
+
when Rebus
|
164
|
+
c.to_char
|
165
|
+
else
|
166
|
+
raise PuzzleFormatError, "Unrecognised cell #{c}"
|
167
|
+
end
|
168
|
+
if c.number && c.number > 0
|
169
|
+
o = "#{c.number} #{o}"
|
170
|
+
end
|
171
|
+
o = o.rjust(4)
|
172
|
+
}.join("|")
|
173
|
+
}.join("\n")
|
174
|
+
end
|
150
175
|
end
|
151
176
|
|
152
177
|
end # module Pangrid
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: pangrid
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Martin DeMello
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-03-
|
11
|
+
date: 2016-03-11 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description:
|
14
14
|
email: martindemello@gmail.com
|