This isn't a comprehensive doc because to our knowledge there are no OSS consumers of this lib, but for posterities sake here are the breaking changes:
- Switched the xml parsing library from xml-parser to fast-xml-parser. It may claim to be faster, but it can handle more complicated XML setups. This is mostly useful for the jpz -> xd clue parsing which should cover more cases now
-
All formatting types (bold, italics, strike, underscore, subscript, superscript, link, color) now have a required
childrenfield containing parsed inner components. This enables nested markup like{*{/bold italic/}*}or{*bold {/and italic/} text*}. -
The
textfield (index 1) still contains the raw content string for backwards compatibility. It has been marked as deprecated though. -
The markup has switched from some regexes to a real parser.
- Adds a CLI, see the README for examples of usage
- Roundtrips through xdToJSON and back do not add newlines to custom sections
- Adds support for converting Across Text format to XD.
- Adds some functions for handling importing from a Puzzleme URL. Built on code found in https://github.com/thisisparker/xword-dl and https://github.com/jpd236/kotwords
- Fix bug with pipe positions inside rebus answers that occurred when converting xd format to JSON and back to xd. This change updates the format of JSON puzzle to include
rebusInternalSplits, and updates the signature of the resolveFullClueAnswer function to no longer take a rebusMap parameter.
Markup changes:
- Changed ~ from strike to subscript
- Added ^ for superscript
- Strike now only uses -
- Amuse JSON import improvements
Three breaking changes:
Two minor:
-
clue.metadatanot isn't always aRecord<string, string>- we process bothhintandrevealerclue metadata strings, so that you can use template syntax inside the strings. Available ashint:displayandrevealer:display. -
backgroundLightandbackgroundDarkare now documented asbackground-lightandbackground-darkin the design docs.
The second is a pretty drastic change to barred support. Instead of trying to derive all of the bars by an algorithm, we now explicitly require a design section which describes the bars positions.
I prefer the explicit nature of this, but a lot of the reason is that making a perfect algorithm for this is tricky and requires having access to a lot of examples. This way we can make the jpz/json port simpler and makes the xd file describe the problem better.
We support describing both a bar-top and bar-left in the CSS style system. So, for example the below crossword would have a design section like:
## Design
<style>
A { bar-top: true }
B { bar-left: true }
C { bar-left: true; bar-top: true }
</style>
........
...A.A.C
.BB..A..
.....CBB
.CBB..A.
..A...BB
.BA.....
A.A.A...
Adds support for barred Crosswords (in jpz imports, and if you are hand authoring) - a barred xd file requires you to declare that it is barred via
form: barred
in the metadata, and then during processing we will derive all of the inline bars based on the answers in the clues. Here is an example of a converted jpz to xd which I took from the internet (thanks Kyle!):
## Metadata
title: Beneath The Surface Printer's Devilry #4 (Midi)
author: Kyle Dolan
editor:
date:
copyright: © 2023 Kyle Dolan
form: barred
## Grid
SIGNPOST
UNICORNS
NCNARROW
DAUNTUWE
EYPTENOR
RODENTLV
SLEETIDE
COUNTESS
## Clues
A1. For dorm room wall, deer art is a popular choice (8) ~ SIGNPOST
A6. Playing an investment game in Economics class, was lots offered the market? (7) ~ UNICORN
A9. As flight can be used to describe principles of classical mechanics (6) ~ NARROW
A10. The reunion included grandparents, uncle, sans cousins and other extended family (5) ~ DAUNT
A13. The butcher shop was known for its famous sausages, for which they sold special extra-long buns (5) ~ TENOR
A15. The oral surgeon who removed my wisdom teeth was a pal. Insurance covered the whole thing! (6) ~ RODENT
A16. As commander of the flight, in having the most spacious cabin (3,4) ~ LEETIDE
A17. With the term paper due date approaching, the lazy student tried to buy ad--I say!--off the Internet (8) ~ COUNTESS
D1. The old couple knew each other so well that they had formed a Wordle standing between themselves (7) ~ SUNDERS
D2. For puzzle lovers, a good crossword is like brandy (4) ~ INCA
D3. Loon setting up your user name and password to verify your account... (3,2) ~ GINUP
D4. ...if you need tech, super. Your email? (7) ~ PORTENT
D5. Our catcher isn't playing today--hermit there to be found (4) ~ SNOW
D7. The bouncer didn't bother. Toss ID--she knew right away it was fake (7) ~ CANTEEN
D8. Question: What items of clothing are typically worn by professional billiards players? Ants (7) ~ SWERVES
D11. A lover offs Will, often use them as conversation starters at parties (5) ~ UNTIE
D12. I'll have a turkey sandwich with Swiss cheese, mats of bacon, and tomatoes (4) ~ YOLO
D14. A cake like daiginjo pairs well with sushi (4) ~ OLDS
Sem-ver major because I removed an exported function which was used inside the jpz to xd converter.
Adds a new function validateClueAnswersMatchGrid which verifies the tiles and clues answer matches
Added width/height to:
- Image inline:
{!url|alt text|width|height!} - Image block:
{!!url|alt text|width|height!}
Unknown sections of an xd file are now added into the JSON model, so you can use arbitrary sections at will.
Clues can contain inline colours on a word:
Inline colours:
{#text|hex colour light|hex colour dark#}
It's now possible to put a rebus inside a schrodinger's square. You reference the rebus via the clue/alt
A6. Sugar ____ ~ 1NE
A6 ^alt: 2NE
With the rebus as `Rebus: 1=CO 2=BO
Exports more types
Adds the ability to track and store Schrödinger squares:
## Metadata
title: Mini 240918 Schrödinger 1
author: Puzzled in CNY
copyright: Copyright Puzzled in CNY, all rights reserved
description: Not the world's most challenging or entertaining Schrödinger but...baby steps! - Created on crosshare.org
## Grid
TILE
APEX
C*NE
ODDS
## Clues
A1. Mosaic piece ~ TILE
A5. Pinnacle ~ APEX
A6. Sugar ____ ~ CONE
A6 ^alt: CANE
A7. Chances, in gambling ~ ODDS
D1. Tuesday treat ~ TACO
D2. Apple tech ~ IPOD
D2 ^alt: IPAD
D3. Complement to borrow ~ LEND
D4. Former intimates ~ EXES
Supports multiples of alts, so:
A6. Sugar ____ ~ CONE
A6 ^alt: CANE
A6 ^alt2: BONE
Would all be legit.
Adds the ability to parse inline and block images in a clue using the following syntax:
- Image inline:
{!url|alt text|width|height!} - Image block:
{!!url|alt text|width|height!}
(Updated in 9.1.8)
Split out the parser into it's own package. So, if you're making a crossword game, then you can just depend on xd-crossword-tools-parser and not have to depend on the tools.
Adds support for parsing jpz files into xd files using the new jpzToXD function.
Also adds a function for re-creating the answer metadata on clues (e.g. the ~ ABC bit) on an existing CrosswordJSON object. Needed this for the jpz parser but it's a useful thing to have in general.
After 3 separate attempts to figure out markup support in clues, we've settled on the xd spec compliant version of "markdown with a curly brace."
In the process we've dropped bodyMD as an optional field on a clue, and switched over to having a "display" field on the clue which should really always be used when presenting a clue for user-facing cases. It is a tuple array indicating how to present chunks of the clue incrementally.
A1. {/Captain/}, {*of*}, {_the_}, ship {-pequod-} {@see here|https://mylink.com@} ~ AHABTurns into:
{
"answer": "AHAB",
"body": "{/Captain/}, {*of*}, {_the_}, ship {-pequod-} {@see here|https://mylink.com@}",
"display": [
["italics", "Captain"],
["text", ", "],
["bold", "of"],
["text", ", "],
["underscore", "the"],
["text", ", ship "],
["strike", "pequod"],
["text", " "],
["link", "see here", "https://mylink.com"]
]
}Also adds "direction" on the clue, it's a tiny micro-optimization, but when you are writing tools which interact with clues, you're often keeping track of this separately - might as well move it inline properly.
A brief sojourn into using BBCode as the markup language for clues.
A chunky re-write of the markdown parser now that it's actually in use at Puzzmo, see the README for an up-to-date look at what we think it should do.
Fixes xd -> JSON -> xd process by converting clue answer to an answer that includes the rebus (if there is one), adding back in pipes/splits (if there are any) and then replacing the rebus symbols back to their word mappings.
Adds a fn for generating semantic diffs between xd crossword files: xdDiff.
-
The xdparser is now a recoverable parser, what this means is that it will not throw at the first sign of some unexpected input. This means you can't rely on
try {}to determine if you have a successful parse. Thus: a breaking semver change. -
Added a new
reportobject on the JSON response fromxdToJSON. This will contain any errors or warnings that were encountered during parsing and asuccessboolean. -
Added the concept of warnings. These are generalized messages which you probably want to act on, but really shouldn't be blocking builds.
-
Added a markdown parser to the clue - we don't make assumptions about the rendering engine and so have a mini-markdown parser in the code base, which gives you a JSON array of the clue's text and formatting. See the README for more.
- Clues from .puz files have newlines stripped out of them
-
Adds support taking an
.xdand getting it into a format so it can be used with@confuzzle/writepuzto generate a.puzfile -
Fixes the editor info for the down clues!
- The output for the xd from the app now always uses lowercase keys for the meta section
-
Makes the older hint format of:
A1. Gardener's concerns with A2 and D4. ~ BULB A1. Turned on to illuminate a room. ~ BULBthrow an error. The new format is:
A1. Gardener's concerns with A2 and D4. ~ BULB A1 ^Hint: Turned on to illuminate a room. A1 ^Refs: A2 D4Includes an auto-migration to a 'hint' which wll be removed with v5 when not in strict mode.
-
Strict mode parsing is also switched to default as 'off' if you don't pass that parameter to
xdToJSON. -
Converts license from ISC to MIT. ISC is the default for npm projects, but I'm old school and I like MIT. Adds a license file to the root of the project, so that automated tooling can get it.
-
The text for a crossword's clue's field used to be
hintand now lives inbody
Clue formats changed to handle secondary clue parsing
Shifted the type exports in a way which was breaking but made it easier to have a crossword app extend the types.