Revamping the libipuz edit APIs
Status: Reviewed email@example.com | partially-implemented
Currently, all editing is split between
libipuz. We propose a structured way to handle editing to make it
easier to reason about, and to put the majority of the complexity in
fix() API is implemented, but the linters are not.
There currently exists a mixture of API levels used to mutate puzzles
through the editor. For example, it’s possible to change an individual
cell within the puzzle by calling
ipuz_style_set_*. Similarly, you can change a clue. However, all
these functions bring some challenges with them, that can lead to an
internally inconsistent state:
Changing the cell_type can leave the numbering and clue cells inconsistent.
Changing the symmetry can be super destructive
Even clues are super-tricky: We need to make sure every cell knows which clue it’s part, and vice-versa.
Additionally, there are some conventions we want to enforce that aren’t part of the ipuz spec. In particular:
For crosswords, there are only across/down clues, and every cell is part of at least one clue.
We are correctly numbered. Clue numbers increase by 1, and there are no gaps
We store the clue cells within the puzzle, and they don’t have discontinuities
We tried to work around this in calls from
ipuz_crossword_set_cell_type() function, as well as
storing the symmetry within the puzzle. This is always immediatedly
followed but a call to
ipuz_crossword_calculate_clues(). This level
of granularity isn’t sufficient for what we need to do and hasn’t aged
Arrowword, Filippine, and Barred puzzles inherit from Crossword, and Acrostics don’t inherit from Crosswords at all. They don’t share the same conventions that Crossword has, though there are some commonalitites. All of these will need their own adjustment to editing.
For example, Filippine puzzles only have across clues, and have a vertical line that’s highlighted with the answer. Barred puzzles don’t have blocks or nulls, and expect “T”, “L”, and “TL” styles to exist. Arrowwords need to have the arrow updated. Symmetry makes almost no sense for Acrostics.
NOTE: In addition, both Filippine and Acrostic puzzles will
benefit from a locked-down custom editor that doesn’t even let you
change the grid directly. They might want to bypass XwordState’s
editing system entirely. Given that we called it
introduction of an
AcrosticState wouldn’t be surprising, but this
may be substantial work and sources of errors.
Some puzzles do need to break the rules. There are fun puzzles with
diagonal clues, or ‘J’ hooks that don’t reveal themselves
immediately. Maybe you do want a barred puzzle with blocks and/or
discontinuities. We may want to consider adding a raw mode to the
editor that just uses the
_set() functions and lets you produce
valid-but-unusual puzzles. This mode would require people to
automatically set the range of cells of clues, for example.
We will have three different APIs for libipuz. First the existing one demarked by the ipuz
_set()functions. These will let you manipulate the puzzle however you see fit. Example:
We add a set of linting APIs demarked by
_check()functions. This will return a list of potentially broken attributes that might need fixing. We will have to define a set of types for each check type. Example:
We add a correction API, demarked by
_fix()functions may need arguments. For example,
fix_symmetry()will need to take in a list of modified cells to update. Otherwise, we won’t know which direction to change things.
As a convenience, we add an
ipuz_crossword_fix_all()function to call the fix functions in the correct order.
We remove symmetry as a tracked feature of crosswords.
Here’s a diagram of this behavior.
sketch of editing changes
NOTE: We will make both the
_fix() function class
methods, so that child types can override or chain to them. Most
fix_all() also needs to be a class_method.
also need to take in arguments, so the class method will require
We move any settings to give us hints about the type of fixes to the Quirks object.
We will introduce a mangaged_mode/raw_mode enum to the Quirks object to track whether we want to fix things up automatically or not.
As another example, symmetry is another quirk setting
All current mutators within xword_state will fix up puzzle based on that mode.
Editor Changes / Raw Mode
There’s a (currently unwritten) style tab in the editor that will let you customize the label / style of grids. We will have to prevent the user from breaking assumptions
edit-widgets were written to expect the puzzle type and base puzzle to change. We will make it so that
PUZZLE_KINDis a construct-only property.
raw_modeshould be a property that can change, and the widgets have to adjust themselves to adapt.