Extensions to the ipuz spec that we support
In general, we try to keep as close to the ipuz spec as possible. Unless listed below, we consider differences between our implementation and the spec as a bug.
However, in some areas the spec is unclear or allows for interpretation. In other areas we want to extend it to get additional functionality. This document captures those differences.
Puzzle Types
Acrostic puzzles
The description for http://ipuz.org/acrostic#1
type puzzles is
minimal in the spec. We support the following conventions
There can be an (optional) clue with a clue of
[QUOTE]
who’s cells can be used to describe the main quote of the puzzle. This quote clue allows us to keep compatibility with apps that only render crosswords. This approach is used by .jpz files.Acrostics with the
[QUOTE]
clue can have thehttp://ipuz.org/crossword#1
kind tag as as well. This will provide compatibility with existing players, and let a reasonably compliant player solve the puzzle.
The
[QUOTE]
clue can appear either in the main clues list (as seen in .jpz files) or a separate clue list.See the section below on clue list directions for more information on how to handle multiple clue lists.
For acrostics, libipuz will either detect the
[QUOTE]
clue if it exists or calculate it based on the shape of the puzzle. It can be accessed throughipuz_acrostic_get_quote_clue ()
. Users of libipuz will have to handle that clue separately in their interface.
Example of optional [QUOTE]
clue:
"clues": {
"Clues": [ {"label":"A", "clue":"Daughter to Brabantio", "cells":[ [9, 8], [4, 0], [10, 2], [19, 13], [10, 13], [18, 2], [8, 10], [8, 1], [6, 9] ] },
{"label":"B", "clue":"\"Tis an _______ thing to play with souls\" <i>(Browning)</i>", "cells":[ [4, 13], [1, 4], [18, 4], [9, 3], [14, 5], [18, 0], [11, 10] ] },
{"label":"C", "clue":"A gentleman of Verona", "cells":[ [9, 0], [7, 1], [8, 4], [19, 2], [1, 6], [11, 1], [11, 5], [4, 10], [17, 8] ] },
... ]
"Clues:Quote": [ {"clue":"[QUOTE]", "cells":[ [0, 0], [0, 1], [0, 2], [0, 4], ... ] } ]
}
Barred puzzles
When saving, we tag barred puzzles as being a separate puzzle type
through the https://libipuz.org/barred#1
kind tag. These are
parseable as normal crosswords, and will also contain
http://ipuz.org/crossword#1
in their kind tag for
compatability. This is primarily so that we can differentiate the
interface in editing mode.
Every barred puzzle is recommended to have three styles within the puzzle to render the barriers. If missing, libipuz will add the styles to the puzzle and use them when setting barriers:
"styles": {
"L": {"barred": "L" },
"T": {"barred": "T" },
"TL": {"barred": "TL" }
}
These are used to render and define the bar, and to be used with the
various _fix()
functions to enforce symmetry.
Note: if you want to add other styles to a cell (such as a shapebg) it’s possible to add a cell-specific style. However, libipuz will currently only check the top and left barred setting when calculating clue extents, etc.
{
"version" : "http://ipuz.org/v2",
"kind" : [ "http://ipuz.org/crossword#1", "http://libipuz.org/barred#1" ],
"styles" : {
"T" : { "barred" : "T" },
"L" : { "barred" : "L" },
"TL" : { "barred" : "TL" }
},
"dimensions" : { "Dimension": n, ... },
"puzzle" : [
[ 1, 0, 0, 2, 0 ],
[0, { "cell" : 3, "style" : "L" }, { "cell" : 0, "style" : "T" }, 0, { "cell" : 4, "style" : "TL" } ],
[ LabeledCell, ... ], ... ],
"solution": [ [ CrosswordValue, ... ], ... ],
"clues": { "Across": [ Clue, ... ],
"Down": [ Clue, ... ] },
}
Filippine puzzles
We tag dutch-style filippine puzzles as being a separate puzzle type
through the https://libipuz.org/filippine#1
kind tag. These are
parseable as normal crosswords, and will also contain
https://ipuz.org/crossword#1
for compatability. This is primarily so
that we can differentiate the interface in editing mode.
Nonograms
Nonograms are a type of picture puzzle game. The puzzle
field is
used represent the image, and has a slightly different cell type than
other puzzles.
Nonograms require row clues to be provided for the user to play the game, but these clues are deterministic and can be calculated from the image. As a result, they are not included in file format.
{
"version": "http://ipuz.org/v2",
"kind": [ "https://libipuz.org/nonogram#1" ],
"dimensions": { "Dimension": n, ... },
"puzzle": [ [ NonogramCell, ... ] ... ]
}
NonogramCell
A NonogramCell is one of:
Field |
Description |
---|---|
|
Omitted cell |
|
Cell without a block (defaults to 0 and can be set by the |
|
A block (defaults to “#” and can be specified by the |
|
A string matching a style with an identical |
Example Nonogram
{
"version": "http://ipuz.org/v2",
"kind": [ "https://libipuz.org/nonogram#1" ],
"dimensions": { "Dimension": n, ... },
"puzzle": [ [ 0 , "#", 0 , 0 , 0 , 0 , 0 , 0 , "#", 0 ],
["#", 0 , 0 , 0 , 0 , 0 , "#", 0 , 0 , "#" ],
[ 0 , 0 , "#", 0 , "#", "#", "#", "#", 0 , 0 ],
[ 0 , 0 , 0 , "#", "#", "#", "#", "#", "#", 0 ],
[ 0 , 0 , "#", "#", "#", "#", "#", "#", "#", "#" ],
[ 0 , "#", "#", "#", "#", "#", "#", "#", "#", 0 ],
["#", "#", "#", "#", "#", "#", "#", "#", "#", 0 ],
[ 0 , "#", "#", "#", "#", "#", "#", "#", 0 , 0 ],
[ 0 , 0 , "#", "#", "#", "#", "#", 0 , 0 , "#" ],
[ 0 , 0 , 0 , "#", "#", 0 , 0 , 0 , 0 , 0 ] ]
}
Color Nonograms
Color Nonograms are a variant of Nonograms where blocks are different
colors. In that instance, the cell value has the same value as
StyleName
.
As an example:
{
"version": "http://ipuz.org/v2",
"kind": [ "https://libipuz.org/nonogram#1", "https://libipuz.org/colornonogram#1" ], ],
"dimensions": { "Dimension": n, ... },
"styles": {
"A": {"color": "#986a44" },
"B": {"color": "#57e389" }
},
"puzzle": [ [ 0 , "A", 0 , 0 , 0 , 0 , 0 , 0 , "A", 0 ],
["A", 0 , 0 , 0 , 0 , 0 , "A", 0 , 0 , "A" ],
[ 0 , 0 , "A", 0 , "B", "B", "B", "A", 0 , 0 ],
[ 0 , 0 , 0 , "B", "B", "B", "B", "B", "A", 0 ],
[ 0 , 0 , "B", "B", "B", "B", "B", "B", "B", "A" ],
[ 0 , "B", "B", "B", "B", "B", "B", "B", "A", 0 ],
["B", "B", "B", "B", "B", "B", "B", "B", "A", 0 ],
[ 0 , "B", "B", "B", "B", "B", "B", "B", 0 , 0 ],
[ 0 , 0 , "B", "B", "B", "B", "B", 0 , 0 , "A" ],
[ 0 , 0 , 0 , "A", "A", 0 , 0 , 0 , 0 , 0 ] ]
}
Extensions and Clarifications
We support a number of extensions to the ipuz spec. These all should be backwards compatible, and are likely to be safely ignored by other implementations. Please file a bug if any of these cause problems!
There are also areas where the spec is unclear. This section details all the libipuz decisions that were made.
Cell coordinates
The spec refers to COL1 and ROW1 as a coordinate for a row but doesn’t explicitly indicate if it is indexed at 0 or 1. The first crossword example implies it starts at zero, but the spec has examples (such as Calcudoku) that imply the coordinates start at 1:
We interpret it as starting at 0, which is what is used by some of the puzzles we’ve found in the wild.
puzzaz interprets puzzles as 0-based as well, which further indicates we should use that.
Charset List
The org.libipuz:charset
list is a supplement for the charset
variable. It’s supposed to be used to handle multi-character cell
values. As an example, Dutch crosswords consider the “IJ” digraph as a
single character.
Ideally, the ipuz spec would accept both a list as well as a string. Until the spec changes, we handle it as an extension.
Examples:
"org.libipuz:charset": [ ..., "E", "F", "G", "H", "I", "IJ", "K", "L", ... ]
"org.libipuz:charset": [ ..., "M", "N", "O", "P", "Q", "QU", "R", "S", ... ]
Clue list directions
We don’t support multiple unadorned Clue lists of the same direction. This is also invalid json.
We do plan to support having multiple clue lists with a label associated with them. This can be used by acrostics to have multiple Zones or Clues sections.
Examples:
Invalid
"clues": {
"Zones": [[1, "The first man"],
[5, "Holds back progress"],
[8, "Many armed sea creature"],
... ]
"Zones": [[1, "Bow companion"],
[2, "___ Leppard"],
[3, "Without a warranty (hyphenated)"],
... ]
}
Valid
"clues": {
"Zones": [[1, "The first man"],
[5, "Holds back progress"],
[8, "Many armed sea creature"],
... ]
"Zones:Second Zone": [[1, "Bow companion"],
[2, "___ Leppard"],
[3, "Without a warranty (hyphenated)"],
... ]
}
HTML
The amount of HTML acceptable in a puzzle is loosely defined in the spec. As a practical matter, we convert the HTML strings into something that’s appropriate for Pango Markup. This is a subset of the valid html and doesn’t include all possible entities.
See Issue #16 for additional details of what is supported and not supported. Unsupported tags are ignored and stripped.
Style on BLOCKS
We support setting styles on BLOCK cells. While this is redundant to the solving of the puzzle, it can be a nice visual addition. Specifically it lets us set a BLOCK to be a specific color rather than just black. It is recommended that implementations texture the block differently from a straight colored cells when this happens.
Example:
{"cell": "#", "style": {"color":"#2d4ce5"}}
License
We add an org.libipuz:license
tag to indicate the license of the
puzzle. We expect these to be a recognized string description of a
well-known license, and not the full license text. The description
should come from the SPDX License List
when applicable. Otherwise, a URL is recommended for a custom or
proprietary license.
Examples:
"org.libipuz:license": "CC-BY-SA-2.0"
"org.libipuz:license": "https://www.example.com/licensing.html"
Locale
We add an org.libipuz:locale
tag that indicates the locale the
puzzle is written for. This can be useful for filtering out the
language of the puzzle for users that don’t speak the language. It
should not affect the parsing of the puzzle at all. It is assumed that
if a puzzle doesn’t have a language tag, it’s of the “C” Locale.
Example:
"org.libipuz:locale": "nl_NL"
Unclear/unhandled ipuz spec terms
What does clueplacement do?
What does annotation do?
How are answer/answers supposed to be rendered?