Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 22 additions & 6 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -41,20 +41,36 @@ Use
Please read the `wiki <https://github.com/riverrun/genxword/wiki>`_ for
information about how to use genxword.

Installation
------------
GUI Installation
----------------

To install genxword (add *sudo* to the command, or run as root,
if you are using Linux): ::
if you are using Linux):

pip3 install genxword

Next, ensure you have installed all the necessary dependencies under #Dependencies.

Lite Installation
-----------------

Simply run:

pip3 install genxword --no-deps

Everything will work fine. However, you will only be able to export to:
t: Text,
z: IPUZ,
c: CSV,
j: Simplified JSON Representation

Dependencies
------------

Genxword depends on pycairo (python-cairo), pygobject (python-gobject or python-gi),
python-gi-cairo (if you are using a Debian-based system), pango (gir1.2-pango-1.0),
gtksourceview3 (gir1.2-gtksource-3.0) and gettext.
Genxword requires pycairo (python-cairo), pygobject (python-gobject or python-gi),
python-gi-cairo (if you are using a Debian-based system), and pango (gir1.2-pango-1.0).

If you would like to use the GUI, install gtksourceview3 (gir1.2-gtksource-3.0) and gettext.

These dependencies can easily be installed on Linux by using your package manager,
and with most distributions, they will already be installed.
Expand Down
112 changes: 102 additions & 10 deletions genxword/calculate.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,22 @@
# You should have received a copy of the GNU General Public License
# along with genxword. If not, see <http://www.gnu.org/licenses/gpl.html>.

import gi
gi.require_version('PangoCairo', '1.0')
gi.require_version('Pango', '1.0')

from gi.repository import Pango, PangoCairo
import random, time, cairo, json
NOGTK = False
try:
import gi
gi.require_version('PangoCairo', '1.0')
gi.require_version('Pango', '1.0')

from gi.repository import Pango, PangoCairo
import cairo
except ImportError as e:
NOGTK = True
print("MISSING DEPENDENCIES!")
print("IGNORE IF LITE VERSION WAS INTENTIONALLY INSTALLED!")
print(e)
print()

import random, time, json, csv
from operator import itemgetter
from collections import defaultdict

Expand Down Expand Up @@ -188,12 +198,12 @@ def draw_img(self, name, context, px, xoffset, yoffset, RTL):
for r in range(self.rows):
for i, c in enumerate(self.grid[r]):
if c != self.empty:
context.set_line_width(1.0)
context.set_source_rgb(0.5, 0.5, 0.5)
context.set_line_width(3.0)
context.set_source_rgb(0.3, 0.3, 0.3)
context.rectangle(xoffset+(i*px), yoffset+(r*px), px, px)
context.stroke()
context.set_line_width(1.0)
context.set_source_rgb(0, 0, 0)
context.set_line_width(3.0)
context.set_source_rgb(0.3, 0.3, 0.3)
context.rectangle(xoffset+1+(i*px), yoffset+1+(r*px), px-2, px-2)
context.stroke()
if '_key.' in name:
Expand Down Expand Up @@ -277,6 +287,15 @@ def create_files(self, name, save_format, lang, message):
else:
RTL = False
img_files = ''
if 't' in save_format:
self.write_text(name, name + '.txt', lang)
img_files += name + '.txt'
if 'j' in save_format:
self.write_json(name, name + '.json', lang)
img_files += name + '.json'
if 'c' in save_format:
self.write_csv(name, name + '.csv', lang)
img_files += name + '.csv'
if 'p' in save_format:
self.export_pdf(name, '_grid.pdf', lang, RTL)
self.export_pdf(name, '_key.pdf', lang, RTL)
Expand Down Expand Up @@ -375,3 +394,76 @@ def write_ipuz(self, name, filename, lang):

with open(filename, 'w') as fp:
json.dump(data, fp, indent=4)

def write_json(self, name, filename, lang):
# Generate the clue numbers if we haven't already
if len(self.wordlist[0]) < 6:
self.order_number_words()

# Generate some data structures for the final output
data = {
"name": name,
'dimensions': {
'width': self.cols,
'height': self.rows
},
'puzzle': []
}
# Iterate the clues to calculate the main data
for clue in self.wordlist:
word, clue_text, row, col, vertical, num = clue[:6]
c = {
"ans": word,
"clue": clue_text,
"row": row,
"col": col,
"vspan": bool(vertical) # if Vertical
}
data["puzzle"].append(c)

with open(filename, 'w') as fp:
json.dump(data, fp)


def write_text(self, name, filename, lang):
# Generate the clue numbers if we haven't already
if len(self.wordlist[0]) < 6:
self.order_number_words()

# Generate some data structures format the final output
puzzle = [["##"] * self.cols for row in range(self.rows)]
clues = {'Across': [], 'Down': []}
solution = [['#' if col == '-' else col for col in row] for row in self.grid]

# Iterate the clues to calculate the main data
for clue in self.wordlist:
word, clue_text, row, col, vertical, num = clue[:6]
puzzle[row][col] = str(num) if num > 9 else "0" + str(num)

puz_clue = [num, clue_text]
if vertical:
clues['Down'].append(puz_clue)
for i in range(len(word)):
if puzzle[row + i][col] == "##":
puzzle[row + i][col] = " "
else:
clues['Across'].append(puz_clue)
for i in range(len(word)):
if puzzle[row][col + i] == "##":
puzzle[row][col + i] = " "

with open(filename, 'w') as fp:
fp.write(name + "\n\n")
for row in puzzle:
fp.write(' '.join(row) + '\n')
fp.write('\n')
for (dir, cluelist) in clues.items():
fp.write(dir + ":\n")
for clue in cluelist:
fp.write('{:2d}'.format(clue[0]) + ": " + clue[1] + '\n')

def write_csv(self, name, filename, lang):
with open(filename, 'w') as fp:
fieldnames = ["word", "clue", "row", "col", "vertical", "num"]
writer = csv.writer(fp)
writer.writerows(self.wordlist)
9 changes: 7 additions & 2 deletions genxword/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,13 +27,18 @@
def main():
parser = argparse.ArgumentParser(description=_('Crossword generator.'), prog='genxword', epilog=usage_info)
parser.add_argument('infile', help=_('Name of word list file.'))
parser.add_argument('saveformat', help=_('Save files as A4 pdf (p), letter size pdf (l), png (n), svg(s) and/or '
'ipuz(z).'))
filetypes = [c for c in 'plnszcjt']
parser.add_argument('saveformat', help=_('Save files as A4 PDF (p), Letter Size PDF (l), PNG (n), SVG (s), IPUZ (z),'
'Plain Text (t), CSV (c), and/or JSON (j).'))
parser.add_argument('-a', '--auto', dest='auto', action='store_true', help=_('Automated (non-interactive) option.'))
parser.add_argument('-m', '--mix', dest='mixmode', action='store_true', help=_('Create anagrams for the clues'))
parser.add_argument('-n', '--number', dest='nwords', type=int, default=50, help=_('Number of words to be used.'))
parser.add_argument('-o', '--output', dest='output', default='Gumby', help=_('Name of crossword.'))
args = parser.parse_args()
if not any([f in args.saveformat for f in filetypes]):
# If none of the filetypes matched
print("ERROR: Unrecognized File Type!")
quit(1)
gen = Genxword(args.auto, args.mixmode)
with open(args.infile) as infile:
gen.wlist(infile, args.nwords)
Expand Down