pangrid 0.2.2 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|