xd-crossword-tools
v6.5.1
Published
Tools for taking different crossword file formats and converting them to xd, and for converting an xd file to useful JSON
Downloads
592
Readme
xd-crossword-tools
xd is a text-based crossword format which is easy for humans to read and reason about.
This repo provides tools for taking different crossword file formats and converting them to xd. Then has a comprehensive xd to JSON function. Mostly conforms to the v2 xd spec, and comes with a few editor-experience extensions for a REPL-like environment. Uses a vendored copy of 'puzjs' which was ported to TypeScript.
Runs in node, browsers, React Native and edge runtimes.
Documentation for authoring in xd
.xd to .JSON
import { xdToJSON } from "xd-crossword-tools"
const xd = "[...]"
const crossword = xdToJSON(xd)
The JSON format is a bit more verbose than you might expect (see below for an example), but the goal is to have as much information pre-computed at parse time in order to save lookups later at runtime. You should use crossword.report
to determine the parsing's success. You can see the type definitions here: ./lib/types.ts
.
.puz to .xd
Builds on puzjs (ISC license). The puz format is generally what tools and websites will give you as an output format.
import { puzToXD } from "xd-crossword-tools"
const puzResponse = await fetch(url)
const puzBuffer = await res.arrayBuffer()
const xd = puzToXD(puzBuffer)
This API should cover most features in puz and xd.
UClick .xml to .xd
import { uclickXMLToXd } from "xd-crossword-tools"
const xmlResponse = await fetch(url)
const xmlString = await res.body()
const xd = uclickXMLToXd(xmlString)
.xd to .puz
We don't support all of .puz features, but this library can generate a JSON object which can then be used @confuzzle/writepuz
to generate a .puz file as a buffer which you can write to a file in node, or offer as a download on the web.
import { JSONToPuzJSON } from "xd-crossword-tools"
import { writepuz } from "@confuzzle/writepuz"
const xd = "[...]"
const writeJSON = JSONToPuzJSON(xd)
const puzBuffer = writepuz(writeJSON)
Editor Support
You can opt-in to more information from the parser, and lint warnings, by passing true
as the third argument to xdToJSON
.
Triggering this will:
- Turn on the linter for your code editor, which will give you warnings about your crossword based on pretty universally useful rules.
- Add section metadata in the return value's
editorInfo
property - Add line numbers to the metadata section of the puzzle
- Add line numbers to clues/hints/other in the metadata section of each clue
This library includes editorInfoAtCursor
which can get some information about what's under the cursor at { line, index }
.
import { xdToJSON, editorInfoAtCursor } from "xd-crossword-tools"
const xd = "[...]"
const editorSupport = true
const crossword = xdToJSON(xd, true, editorSupport)
const info = editorInfoAtCursor(crossword)
const cursorInfo = info(0, 0)
Which returns a union of different results, you can check the types + tests to see what's available, but it's something like this:
export type PositionInfo =
| { type: "noop" }
| { type: "grid"; position: Position }
| { type: "clue"; direction: CursorDirection; number: number }
| ...
xd Diffing
This library includes a diffing function which can take two xd strings and return a list of changes. This is useful for version control, and for building a diffing UI.
import { diffXD } from "xd-crossword-tools"
const diff = diffXD(xd1, xd2)
Example
Let's take this free .puz
: https://dehodson.github.io/crossword-puzzles/crosswords/alpha-bits/
Their .puz file turns into this xd:
## Metadata
title: Alpha-Bits
author: Drew Hodson
copyright: © 2021
description: N/A
## Grid
AHAB..CUD.SERIF
MADAM.ANY.ABODE
PLANE.DIE.NOTON
....TODO.EGO...
GASH.NINJA.KEEL
ARTICLE.ORU.DOE
YEARLY.MISPRINT
..NEI.MAN.SOT..
CALENDAR.RETIES
ICE.TAR.POTHOLE
OTEP.HQTRS.SNIT
...ALL.HEAL....
SPIRO.NET.ATLAS
TARTS.ETA.DOONE
UWAVE.WAX..YUTZ
## Clues
A1. Captain of the Pequod ~ AHAB
A5. Food for second chance chewing ~ CUD
A8. Font feature ~ SERIF
A13. Palindromic address to a female ~ MADAM
A15. ___ Way You Want It ~ ANY
A16. Place often described as humble ~ ABODE
A17. Flat two dimensional surface in geometry ~ PLANE
A18. Grim homophone of 7D ~ DIE
A19. Off ~ NOTON
A20. Heading for some lists ~ TODO
A22. Kanye West is famous for his ~ EGO
A23. Laceration ~ GASH
A27. Alias of Twitch star Richard Tyler Blevins ~ NINJA
A29. Capsize ~ KEEL
A33. Piece of clothing or print ~ ARTICLE
A35. Evangelical school in Tulsa, OK ~ ORU
A37. ___-eyed ~ DOE
A38. Annual ~ YEARLY
A39. The stamp with the upside down airplane is a famous one ~ MISPRINT
A41. With 42A and Marcus, a luxury department store chain ~ NEI
A42. 41A continued ~ MAN
A43. Lush ~ SOT
A44. The Mayan one ended in 2012 ~ CALENDAR
A47. What a child often does to their shoes ~ RETIES
A50. Vanilla ___ ~ ICE
A51. Maligned cigarette ingredient ~ TAR
A52. Frequent cause for a new tire ~ POTHOLE
A53. Los Angeles heavy metal act ~ OTEP
A55. Bldgs. such as the Googleplex ~ HQTRS
A57. A fit of irritation ~ SNIT
A58. Lead-in to American or day ~ ALL
A60. What Pokémon do at a Pokémon Center ~ HEAL
A62. Nixon's vice ~ SPIRO
A65. Nothing but ___ ~ NET
A66. One with the world on his shoulders ~ ATLAS
A71. Filled pastries ~ TARTS
A72. Age, in Milan ~ ETA
A73. Lorna ___, novel or cookie ~ DOONE
A74. Electrocardiogram readout feature ~ UWAVE
A75. Hip slang for records ~ WAX
A76. Yiddish for a foolish person ~ YUTZ
D1. Pc. of concert gear ~ AMP
D2. AI antagonist of 2001 ~ HAL
D3. Programming pioneer Lovelace ~ ADA
D4. Prohibit ~ BAN
D5. Type of person to routinely carry a club ~ CADDIE
D6. State of the ___ Address ~ UNION
D7. Colorful homophone of 18A ~ DYE
D8. Snitched ~ SANG
D9. Kindle fare ~ EBOOK
D10. Decayed matter ~ ROT
D11. Type of response you hope to get at the altar ~ IDO
D12. Peat-accumulating wetland ~ FEN
D14. The ___, NY art museum ~ MET
D21. ___Fans ~ ONLY
D22. Friends, Romans, countrymen, lend me your... ~ EARS
D23. "Friend of Dorothy" ~ GAY
D24. We ___ the Champions ~ ARE
D25. Father of Spider-Man ~ STANLEE
D26. What a certain applicant becomes ~ HIREE
D28. Connect ~ JOIN
D30. Particular form of a published text ~ EDITION
D31. Suffix at the end of all of Eevee's evolutions ~ EON
D32. Live and ___ Die ~ LET
D34. Famous Eastwood whose name became a famous Gorillaz song ~ CLINT
D36. Unexpected result in a sporting competition ~ UPSET
D39. Disfigure ~ MAR
D40. David Lee and Tim ~ ROTHS
D42. Luxury watch collection by Garmin ~ MARQ
D44. Top dog in an IT org ~ CIO
D45. Sister ___ ~ ACT
D46. Author Roald ~ DAHL
D47. Civil rights activist Parks ~ ROSA
D48. An additional name that could be part of 40D's clue ~ ELI
D49. Director's domain ~ SET
D52. Type of income to go in a 401k ~ PRETAX
D54. The Empire Strikes Back, to the Star Wars saga ~ PARTV
D56. Greek letter following 72A ~ THETA
D59. Misplace ~ LOSE
D61. Wee boy ~ LAD
D62. Dad to Tommy Pickles ~ STU
D63. The only Patrol I trust ~ PAW
D64. Smart savings plan, briefly ~ IRA
D65. Fresh ~ NEW
D67. Breeds such as Chihuahua or Pomeranian ~ TOY
D68. Bega behind "Mambo No. 5" ~ LOU
D69. Aardvark breakfast ~ ANT
D70. Sonic ___ ~ SEZ
## Notes
## Design
<style>O { background: circle }</style>
O..O##O.O#.O..O
.....#...#.....
.....#...#.....
####....#...###
O..O#.O.O.#O..O
.......#...#...
......#........
##...#O.O#...##
........#......
...#...#.......
O..O#.O.O.#O..O
###...#....####
.....#...#.....
.....#...#.....
O..O.#O.O##O..O
{
"meta": {
"title": "Alpha-Bits",
"author": "Drew Hodson",
"date": "Not set",
"editor": "Not set",
"title:line": "2",
"author:line": "3",
"copyright": "© 2021",
"copyright:line": "4",
"description": "N/A",
"description:line": "5"
},
"tiles": [
[
{
"type": "letter",
"letter": "A"
},
{
"type": "letter",
"letter": "H"
},
{
"type": "letter",
"letter": "A"
},
{
"type": "letter",
"letter": "B"
},
{
"type": "blank"
},
{
"type": "blank"
},
{
"type": "letter",
"letter": "C"
},
{
"type": "letter",
"letter": "U"
},
{
"type": "letter",
"letter": "D"
},
{
"type": "blank"
},
{
"type": "letter",
"letter": "S"
},
{
"type": "letter",
"letter": "E"
},
{
"type": "letter",
"letter": "R"
},
{
"type": "letter",
"letter": "I"
},
{
"type": "letter",
"letter": "F"
}
],
[
{
"type": "letter",
"letter": "M"
},
{
"type": "letter",
"letter": "A"
},
{
"type": "letter",
"letter": "D"
},
{
"type": "letter",
"letter": "A"
},
{
"type": "letter",
"letter": "M"
},
{
"type": "blank"
},
{
"type": "letter",
"letter": "A"
},
{
"type": "letter",
"letter": "N"
},
{
"type": "letter",
"letter": "Y"
},
{
"type": "blank"
},
{
"type": "letter",
"letter": "A"
},
{
"type": "letter",
"letter": "B"
},
{
"type": "letter",
"letter": "O"
},
{
"type": "letter",
"letter": "D"
},
{
"type": "letter",
"letter": "E"
}
],
[
{
"type": "letter",
"letter": "P"
},
{
"type": "letter",
"letter": "L"
},
{
"type": "letter",
"letter": "A"
},
{
"type": "letter",
"letter": "N"
},
{
"type": "letter",
"letter": "E"
},
{
"type": "blank"
},
{
"type": "letter",
"letter": "D"
},
{
"type": "letter",
"letter": "I"
},
{
"type": "letter",
"letter": "E"
},
{
"type": "blank"
},
{
"type": "letter",
"letter": "N"
},
{
"type": "letter",
"letter": "O"
},
{
"type": "letter",
"letter": "T"
},
{
"type": "letter",
"letter": "O"
},
{
"type": "letter",
"letter": "N"
}
],
[
{
"type": "blank"
},
{
"type": "blank"
},
{
"type": "blank"
},
{
"type": "blank"
},
{
"type": "letter",
"letter": "T"
},
{
"type": "letter",
"letter": "O"
},
{
"type": "letter",
"letter": "D"
},
{
"type": "letter",
"letter": "O"
},
{
"type": "blank"
},
{
"type": "letter",
"letter": "E"
},
{
"type": "letter",
"letter": "G"
},
{
"type": "letter",
"letter": "O"
},
{
"type": "blank"
},
{
"type": "blank"
},
{
"type": "blank"
}
],
[
{
"type": "letter",
"letter": "G"
},
{
"type": "letter",
"letter": "A"
},
{
"type": "letter",
"letter": "S"
},
{
"type": "letter",
"letter": "H"
},
{
"type": "blank"
},
{
"type": "letter",
"letter": "N"
},
{
"type": "letter",
"letter": "I"
},
{
"type": "letter",
"letter": "N"
},
{
"type": "letter",
"letter": "J"
},
{
"type": "letter",
"letter": "A"
},
{
"type": "blank"
},
{
"type": "letter",
"letter": "K"
},
{
"type": "letter",
"letter": "E"
},
{
"type": "letter",
"letter": "E"
},
{
"type": "letter",
"letter": "L"
}
],
[
{
"type": "letter",
"letter": "A"
},
{
"type": "letter",
"letter": "R"
},
{
"type": "letter",
"letter": "T"
},
{
"type": "letter",
"letter": "I"
},
{
"type": "letter",
"letter": "C"
},
{
"type": "letter",
"letter": "L"
},
{
"type": "letter",
"letter": "E"
},
{
"type": "blank"
},
{
"type": "letter",
"letter": "O"
},
{
"type": "letter",
"letter": "R"
},
{
"type": "letter",
"letter": "U"
},
{
"type": "blank"
},
{
"type": "letter",
"letter": "D"
},
{
"type": "letter",
"letter": "O"
},
{
"type": "letter",
"letter": "E"
}
],
[
{
"type": "letter",
"letter": "Y"
},
{
"type": "letter",
"letter": "E"
},
{
"type": "letter",
"letter": "A"
},
{
"type": "letter",
"letter": "R"
},
{
"type": "letter",
"letter": "L"
},
{
"type": "letter",
"letter": "Y"
},
{
"type": "blank"
},
{
"type": "letter",
"letter": "M"
},
{
"type": "letter",
"letter": "I"
},
{
"type": "letter",
"letter": "S"
},
{
"type": "letter",
"letter": "P"
},
{
"type": "letter",
"letter": "R"
},
{
"type": "letter",
"letter": "I"
},
{
"type": "letter",
"letter": "N"
},
{
"type": "letter",
"letter": "T"
}
],
[
{
"type": "blank"
},
{
"type": "blank"
},
{
"type": "letter",
"letter": "N"
},
{
"type": "letter",
"letter": "E"
},
{
"type": "letter",
"letter": "I"
},
{
"type": "blank"
},
{
"type": "letter",
"letter": "M"
},
{
"type": "letter",
"letter": "A"
},
{
"type": "letter",
"letter": "N"
},
{
"type": "blank"
},
{
"type": "letter",
"letter": "S"
},
{
"type": "letter",
"letter": "O"
},
{
"type": "letter",
"letter": "T"
},
{
"type": "blank"
},
{
"type": "blank"
}
],
[
{
"type": "letter",
"letter": "C"
},
{
"type": "letter",
"letter": "A"
},
{
"type": "letter",
"letter": "L"
},
{
"type": "letter",
"letter": "E"
},
{
"type": "letter",
"letter": "N"
},
{
"type": "letter",
"letter": "D"
},
{
"type": "letter",
"letter": "A"
},
{
"type": "letter",
"letter": "R"
},
{
"type": "blank"
},
{
"type": "letter",
"letter": "R"
},
{
"type": "letter",
"letter": "E"
},
{
"type": "letter",
"letter": "T"
},
{
"type": "letter",
"letter": "I"
},
{
"type": "letter",
"letter": "E"
},
{
"type": "letter",
"letter": "S"
}
],
[
{
"type": "letter",
"letter": "I"
},
{
"type": "letter",
"letter": "C"
},
{
"type": "letter",
"letter": "E"
},
{
"type": "blank"
},
{
"type": "letter",
"letter": "T"
},
{
"type": "letter",
"letter": "A"
},
{
"type": "letter",
"letter": "R"
},
{
"type": "blank"
},
{
"type": "letter",
"letter": "P"
},
{
"type": "letter",
"letter": "O"
},
{
"type": "letter",
"letter": "T"
},
{
"type": "letter",
"letter": "H"
},
{
"type": "letter",
"letter": "O"
},
{
"type": "letter",
"letter": "L"
},
{
"type": "letter",
"letter": "E"
}
],
[
{
"type": "letter",
"letter": "O"
},
{
"type": "letter",
"letter": "T"
},
{
"type": "letter",
"letter": "E"
},
{
"type": "letter",
"letter": "P"
},
{
"type": "blank"
},
{
"type": "letter",
"letter": "H"
},
{
"type": "letter",
"letter": "Q"
},
{
"type": "letter",
"letter": "T"
},
{
"type": "letter",
"letter": "R"
},
{
"type": "letter",
"letter": "S"
},
{
"type": "blank"
},
{
"type": "letter",
"letter": "S"
},
{
"type": "letter",
"letter": "N"
},
{
"type": "letter",
"letter": "I"
},
{
"type": "letter",
"letter": "T"
}
],
[
{
"type": "blank"
},
{
"type": "blank"
},
{
"type": "blank"
},
{
"type": "letter",
"letter": "A"
},
{
"type": "letter",
"letter": "L"
},
{
"type": "letter",
"letter": "L"
},
{
"type": "blank"
},
{
"type": "letter",
"letter": "H"
},
{
"type": "letter",
"letter": "E"
},
{
"type": "letter",
"letter": "A"
},
{
"type": "letter",
"letter": "L"
},
{
"type": "blank"
},
{
"type": "blank"
},
{
"type": "blank"
},
{
"type": "blank"
}
],
[
{
"type": "letter",
"letter": "S"
},
{
"type": "letter",
"letter": "P"
},
{
"type": "letter",
"letter": "I"
},
{
"type": "letter",
"letter": "R"
},
{
"type": "letter",
"letter": "O"
},
{
"type": "blank"
},
{
"type": "letter",
"letter": "N"
},
{
"type": "letter",
"letter": "E"
},
{
"type": "letter",
"letter": "T"
},
{
"type": "blank"
},
{
"type": "letter",
"letter": "A"
},
{
"type": "letter",
"letter": "T"
},
{
"type": "letter",
"letter": "L"
},
{
"type": "letter",
"letter": "A"
},
{
"type": "letter",
"letter": "S"
}
],
[
{
"type": "letter",
"letter": "T"
},
{
"type": "letter",
"letter": "A"
},
{
"type": "letter",
"letter": "R"
},
{
"type": "letter",
"letter": "T"
},
{
"type": "letter",
"letter": "S"
},
{
"type": "blank"
},
{
"type": "letter",
"letter": "E"
},
{
"type": "letter",
"letter": "T"
},
{
"type": "letter",
"letter": "A"
},
{
"type": "blank"
},
{
"type": "letter",
"letter": "D"
},
{
"type": "letter",
"letter": "O"
},
{
"type": "letter",
"letter": "O"
},
{
"type": "letter",
"letter": "N"
},
{
"type": "letter",
"letter": "E"
}
],
[
{
"type": "letter",
"letter": "U"
},
{
"type": "letter",
"letter": "W"
},
{
"type": "letter",
"letter": "A"
},
{
"type": "letter",
"letter": "V"
},
{
"type": "letter",
"letter": "E"
},
{
"type": "blank"
},
{
"type": "letter",
"letter": "W"
},
{
"type": "letter",
"letter": "A"
},
{
"type": "letter",
"letter": "X"
},
{
"type": "blank"
},
{
"type": "blank"
},
{
"type": "letter",
"letter": "Y"
},
{
"type": "letter",
"letter": "U"
},
{
"type": "letter",
"letter": "T"
},
{
"type": "letter",
"letter": "Z"
}
]
],
"clues": {
"across": [
{
"body": "Captain of the Pequod",
"answer": "AHAB",
"number": 1,
"position": {
"col": 0,
"index": 0
},
"metadata": {
"body:line": "28",
"answer:unprocessed": "AHAB"
}
},
{
"body": "Food for second chance chewing",
"answer": "CUD",
"number": 5,
"position": {
"col": 6,
"index": 0
},
"metadata": {
"body:line": "29",
"answer:unprocessed": "CUD"
}
},
{
"body": "Font feature",
"answer": "SERIF",
"number": 8,
"position": {
"col": 10,
"index": 0
},
"metadata": {
"body:line": "30",
"answer:unprocessed": "SERIF"
}
},
{
"body": "Palindromic address to a female",
"answer": "MADAM",
"number": 13,
"position": {
"col": 0,
"index": 1
},
"metadata": {
"body:line": "31",
"answer:unprocessed": "MADAM"
}
},
{
"body": "___ Way You Want It",
"answer": "ANY",
"number": 15,
"position": {
"col": 6,
"index": 1
},
"metadata": {
"body:line": "32",
"answer:unprocessed": "ANY"
}
},
{
"body": "Place often described as humble",
"answer": "ABODE",
"number": 16,
"position": {
"col": 10,
"index": 1
},
"metadata": {
"body:line": "33",
"answer:unprocessed": "ABODE"
}
},
{
"body": "Flat two dimensional surface in geometry",
"answer": "PLANE",
"number": 17,
"position": {
"col": 0,
"index": 2
},
"metadata": {
"body:line": "34",
"answer:unprocessed": "PLANE"
}
},
{
"body": "Grim homophone of 7D",
"answer": "DIE",
"number": 18,
"position": {
"col": 6,
"index": 2
},
"metadata": {
"body:line": "35",
"answer:unprocessed": "DIE"
}
},
{
"body": "Off",
"answer": "NOTON",
"number": 19,
"position": {
"col": 10,
"index": 2
},
"metadata": {
"body:line": "36",
"answer:unprocessed": "NOTON"
}
},
{
"body": "Heading for some lists",
"answer": "TODO",
"number": 20,
"position": {
"col": 4,
"index": 3
},
"metadata": {
"body:line": "37",
"answer:unprocessed": "TODO"
}
},
{
"body": "Kanye West is famous for his",
"answer": "EGO",
"number": 22,
"position": {
"col": 9,
"index": 3
},
"metadata": {
"body:line": "38",
"answer:unprocessed": "EGO"
}
},
{
"body": "Laceration",
"answer": "GASH",
"number": 23,
"position": {
"col": 0,
"index": 4
},
"metadata": {
"body:line": "39",
"answer:unprocessed": "GASH"
}
},
{
"body": "Alias of Twitch star Richard Tyler Blevins",
"answer": "NINJA",
"number": 27,
"position": {
"col": 5,
"index": 4
},
"metadata": {
"body:line": "40",
"answer:unprocessed": "NINJA"
}
},
{
"body": "Capsize",
"answer": "KEEL",
"number": 29,
"position": {
"col": 11,
"index": 4
},
"metadata": {
"body:line": "41",
"answer:unprocessed": "KEEL"
}
},
{
"body": "Piece of clothing or print",
"answer": "ARTICLE",
"number": 33,
"position": {
"col": 0,
"index": 5
},
"metadata": {
"body:line": "42",
"answer:unprocessed": "ARTICLE"
}
},
{
"body": "Evangelical school in Tulsa, OK",
"answer": "ORU",
"number": 35,
"position": {
"col": 8,
"index": 5
},
"metadata": {
"body:line": "43",
"answer:unprocessed": "ORU"
}
},
{
"body": "___-eyed",
"answer": "DOE",
"number": 37,
"position": {
"col": 12,
"index": 5
},
"metadata": {
"body:line": "44",
"answer:unprocessed": "DOE"
}
},
{
"body": "Annual",
"answer": "YEARLY",
"number": 38,
"position": {
"col": 0,
"index": 6
},
"metadata": {
"body:line": "45",
"answer:unprocessed": "YEARLY"
}
},
{
"body": "The stamp with the upside down airplane is a famous one",
"answer": "MISPRINT",
"number": 39,
"position": {
"col": 7,
"index": 6
},
"metadata": {
"body:line": "46",
"answer:unprocessed": "MISPRINT"
}
},
{
"body": "With 42A and Marcus, a luxury department store chain",
"answer": "NEI",
"number": 41,
"position": {
"col": 2,
"index": 7
},
"metadata": {
"body:line": "47",
"answer:unprocessed": "NEI"
}
},
{
"body": "41A continued",
"answer": "MAN",
"number": 42,
"position": {
"col": 6,
"index": 7
},
"metadata": {
"body:line": "48",
"answer:unprocessed": "MAN"
}
},
{
"body": "Lush",
"answer": "SOT",
"number": 43,
"position": {
"col": 10,
"index": 7
},
"metadata": {
"body:line": "49",
"answer:unprocessed": "SOT"
}
},
{
"body": "The Mayan one ended in 2012",
"answer": "CALENDAR",
"number": 44,
"position": {
"col": 0,
"index": 8
},
"metadata": {
"body:line": "50",
"answer:unprocessed": "CALENDAR"
}
},
{
"body": "What a child often does to their shoes",
"answer": "RETIES",
"number": 47,
"position": {
"col": 9,
"index": 8
},
"metadata": {
"body:line": "51",
"answer:unprocessed": "RETIES"
}
},
{
"body": "Vanilla ___",
"answer": "ICE",
"number": 50,
"position": {
"col": 0,
"index": 9
},
"metadata": {
"body:line": "52",
"answer:unprocessed": "ICE"
}
},
{
"body": "Maligned cigarette ingredient",
"answer": "TAR",
"number": 51,
"position": {
"col": 4,
"index": 9
},
"metadata": {
"body:line": "53",
"answer:unprocessed": "TAR"
}
},
{
"body": "Frequent cause for a new tire",
"answer": "POTHOLE",
"number": 52,
"position": {
"col": 8,
"index": 9
},
"metadata": {
"body:line": "54",
"answer:unprocessed": "POTHOLE"
}
},
{
"body": "Los Angeles heavy metal act",
"answer": "OTEP",
"number": 53,
"position": {
"col": 0,
"index": 10
},
"metadata": {
"body:line": "55",
"answer:unprocessed": "OTEP"
}
},
{
"body": "Bldgs. such as the Googleplex",
"answer": "HQTRS",
"number": 55,
"position": {
"col": 5,
"index": 10
},
"metadata": {
"body:line": "56",
"answer:unprocessed": "HQTRS"
}
},
{
"body": "A fit of irritation",
"answer": "SNIT",
"number": 57,
"position": {
"col": 11,
"index": 10
},
"metadata": {
"body:line": "57",
"answer:unprocessed": "SNIT"
}
},
{
"body": "Lead-in to American or day",
"answer": "ALL",
"number": 58,
"position": {
"col": 3,
"index": 11
},
"metadata": {
"body:line": "58",
"answer:unprocessed": "ALL"
}
},
{
"body": "What Pokémon do at a Pokémon Center",
"answer": "HEAL",
"number": 60,
"position": {
"col": 7,
"index": 11
},
"metadata": {
"body:line": "59",
"answer:unprocessed": "HEAL"
}
},
{
"body": "Nixon's vice",
"answer": "SPIRO",
"number": 62,
"position": {
"col": 0,
"index": 12
},
"metadata": {
"body:line": "60",
"answer:unprocessed": "SPIRO"
}
},
{
"body": "Nothing but ___",
"answer": "NET",
"number": 65,
"position": {
"col": 6,
"index": 12
},
"metadata": {
"body:line": "61",
"answer:unprocessed": "NET"
}
},
{
"body": "One with the world on his shoulders",
"answer": "ATLAS",
"number": 66,
"position": {
"col": 10,
"index": 12
},
"metadata": {
"body:line": "62",
"answer:unprocessed": "ATLAS"
}
},
{
"body": "Filled pastries",
"answer": "TARTS",
"number": 71,
"position": {
"col": 0,
"index": 13
},
"metadata": {
"body:line": "63",
"answer:unprocessed": "TARTS"
}
},
{
"body": "Age, in Milan",
"answer": "ETA",
"number": 72,
"position": {
"col": 6,
"index": 13
},
"metadata": {
"body:line": "64",
"answer:unprocessed": "ETA"
}
},
{
"body": "Lorna ___, novel or cookie",
"answer": "DOONE",
"number": 73,
"position": {
"col": 10,
"index": 13
},
"metadata": {
"body:line": "65",
"answer:unprocessed": "DOONE"
}
},
{
"body": "Electrocardiogram readout feature",
"answer": "UWAVE",
"number": 74,
"position": {
"col": 0,
"index": 14
},
"metadata": {
"body:line": "66",
"answer:unprocessed": "UWAVE"
}
},
{
"body": "Hip slang for records",
"answer": "WAX",
"number": 75,
"position": {
"col": 6,
"index": 14
},
"metadata": {
"body:line": "67",
"answer:unprocessed": "WAX"
}
},
{
"body": "Yiddish for a foolish person",
"answer": "YUTZ",
"number": 76,
"position": {
"col": 11,
"index": 14
},
"metadata": {
"body:line": "68",
"answer:unprocessed": "YUTZ"
}
}
],
"down": [
{
"body": "Pc. of concert gear",
"answer": "AMP",
"number": 1,
"position": {
"col": 0,
"index": 0
},
"metadata": {
"body:line": "70",
"answer:unprocessed": "AMP"
}
},
{
"body": "AI antagonist of 2001",
"answer": "HAL",
"number": 2,
"position": {
"col": 1,
"index": 0
},
"metadata": {
"body:line": "71",
"answer:unprocessed": "HAL"
}
},
{
"body": "Programming pioneer Lovelace",
"answer": "ADA",
"number": 3,
"position": {
"col": 2,
"index": 0
},
"metadata": {
"body:line": "72",
"answer:unprocessed": "ADA"
}
},
{
"body": "Prohibit",
"answer": "BAN",
"number": 4,
"position": {
"col": 3,
"index": 0
},
"metadata": {
"body:line": "73",
"answer:unprocessed": "BAN"
}
},
{
"body": "Type of person to routinely carry a club",
"answer": "CADDIE",
"number": 5,
"position": {
"col": 6,
"index": 0
},
"metadata": {
"body:line": "74",
"answer:unprocessed": "CADDIE"
}
},
{
"body": "State of the ___ Address",
"answer": "UNION",
"number": 6,
"position": {
"col": 7,
"index": 0
},
"metadata": {
"body:line": "75",
"answer:unprocessed": "UNION"
}
},
{
"body": "Colorful homophone of 18A",
"answer": "DYE",
"number": 7,
"position": {
"col": 8,
"index": 0
},
"metadata": {
"body:line": "76",
"answer:unprocessed": "DYE"
}
},
{
"body": "Snitched",
"answer": "SANG",
"number": 8,
"position": {
"col": 10,
"index": 0
},
"metadata": {
"body:line": "77",
"answer:unprocessed": "SANG"
}
},
{
"body": "Kindle fare",
"answer": "EBOOK",
"number": 9,
"position": {
"col": 11,
"index": 0
},
"metadata": {
"body:line": "78",
"answer:unprocessed": "EBOOK"
}
},
{
"body": "Decayed matter",
"answer": "ROT",
"number": 10,
"position": {
"col": 12,
"index": 0
},
"metadata": {
"body:line": "79",
"answer:unprocessed": "ROT"
}
},
{
"body": "Type of response you hope to get at the altar",
"answer": "IDO",
"number": 11,
"position": {
"col": 13,
"index": 0
},
"metadata": {
"body:line": "80",
"answer:unprocessed": "IDO"
}
},
{
"body": "Peat-accumulating wetland",
"answer": "FEN",
"number": 12,
"position": {
"col": 14,
"index": 0
},
"metadata": {
"body:line": "81",
"answer:unprocessed": "FEN"
}
},
{
"body": "The ___, NY art museum",
"answer": "MET",
"number": 14,
"position": {
"col": 4,
"index": 1
},
"metadata": {
"body:line": "82",
"answer:unprocessed": "MET"
}
},
{
"body": "___Fans",
"answer": "ONLY",
"number": 21,
"position": {
"col": 5,
"index": 3
},
"metadata": {
"body:line": "83",
"answer:unprocessed": "ONLY"
}
},
{
"body": "Friends, Romans, countrymen, lend me your...",
"answer": "EARS",
"number": 22,
"position": {
"col": 9,
"index": 3
},
"metadata": {
"body:line": "84",
"answer:unprocessed": "EARS"
}
},
{
"body": "\"Friend of Dorothy\"",
"answer": "GAY",
"number": 23,
"position": {
"col": 0,
"index": 4
},
"metadata": {
"body:line": "85",
"answer:unprocessed": "GAY"
}
},
{
"body": "We ___ the Champions",
"answer": "ARE",
"number": 24,
"position": {
"col": 1,
"index": 4
},
"metadata": {
"body:line": "86",
"answer:unprocessed": "ARE"
}
},
{
"body": "Father of Spider-Man",
"answer": "STANLEE",
"number": 25,
"position": {
"col": 2,
"index": 4
},
"metadata": {
"body:line": "87",
"answer:unprocessed": "STANLEE"
}
},
{
"body": "What a certain applicant becomes",
"answer": "HIREE",
"number": 26,
"position": {
"col": 3,
"index": 4
},
"metadata": {
"body:line": "88",
"answer:unprocessed": "HIREE"
}
},
{
"body": "Connect",
"answer": "JOIN",
"number": 28,
"position": {
"col": 8,
"index": 4
},
"metadata": {
"body:line": "89",
"answer:unprocessed": "JOIN"
}
},
{
"body": "Particular form of a published text",
"answer": "EDITION",
"number": 30,
"position": {
"col": 12,
"index": 4
},
"metadata": {
"body:line": "90",
"answer:unprocessed": "EDITION"
}
},
{
"body": "Suffix at the end of all of Eevee's evolutions",
"answer": "EON",
"number": 31,
"position": {
"col": 13,
"index": 4
},
"metadata": {
"body:line": "91",
"answer:unprocessed": "EON"
}
},
{
"body": "Live and ___ Die",
"answer": "LET",
"number": 32,
"position": {
"col": 14,
"index": 4
},
"metadata": {
"body:line": "92",
"answer:unprocessed": "LET"
}
},
{
"body": "Famous Eastwood whose name became a famous Gorillaz song",
"answer": "CLINT",
"number": 34,
"position": {
"col": 4,
"index": 5
},
"metadata": {
"body:line": "93",
"answer:unprocessed": "CLINT"
}
},
{
"body": "Unexpected result in a sporting competition",
"answer": "UPSET",
"number": 36,
"position": {
"col": 10,
"index": 5
},
"metadata": {
"body:line": "94",
"answer:unprocessed": "UPSET"
}
},
{
"body": "Disfigure",
"answer": "MAR",
"number": 39,
"position": {
"col": 7,
"index": 6
},
"metadata": {
"body:line": "95",
"answer:unprocessed": "MAR"
}
},
{
"body": "David Lee and Tim",
"answer": "ROTHS",
"number": 40,
"position": {
"col": 11,
"index": 6
},
"metadata": {
"body:line": "96",
"answer:unprocessed": "ROTHS"
}
},
{
"body": "Luxury watch collection by Garmin",
"answer": "MARQ",
"number": 42,
"position": {
"col": 6,
"index": 7
},
"metadata": {
"body:line": "97",
"answer:unprocessed": "MARQ"
}
},
{
"body": "Top dog in an IT org",
"answer": "CIO",
"number": 44,
"position": {
"col": 0,
"index": 8
},
"metadata": {
"body:line": "98",
"answer:unprocessed": "CIO"
}
},
{
"body": "Sister ___",
"answer": "ACT",
"number": 45,
"position": {
"col": 1,
"index": 8
},
"metadata": {
"body:line": "99",
"answer:unprocessed": "ACT"
}
},
{
"body": "Author Roald",
"answer": "DAHL",
"number": 46,
"position": {
"col": 5,
"index": 8
},
"metadata": {
"body:line": "100",
"answer:unprocessed": "DAHL"
}
},
{
"body": "Civil rights activist Parks",
"answer": "ROSA",
"number": 47,
"position": {
"col": 9,
"index": 8
},
"metadata": {
"body:line": "101",
"answer:unprocessed": "ROSA"
}
},
{
"body": "An additional name that could be part of 40D's clue",
"answer": "ELI",
"number": 48,
"position": {
"col": 13,
"index": 8
},
"metadata": {
"body:line": "102",
"answer:unprocessed": "ELI"
}
},
{
"body": "Director's domain",
"answer": "SET",
"number": 49,
"position": {
"col": 14,
"index": 8
},
"metadata": {
"body:line": "103",
"answer:unprocessed": "SET"
}
},
{
"body": "Type of income to go in a 401k",
"answer": "PRETAX",
"number": 52,
"position": {
"col": 8,
"index": 9
},
"metadata": {
"body:line": "104",
"answer:unprocessed": "PRETAX"
}
},
{
"body": "The Empire Strikes Back, to the Star Wars saga",
"answer": "PARTV",
"number": 54,
"position": {
"col": 3,
"index": 10
},
"metadata": {
"body:line": "105",
"answer:unprocessed": "PARTV"
}
},
{
"body": "Greek letter following 72A",
"answer": "THETA",
"number": 56,
"position": {
"col": 7,
"index": 10
},
"metadata": {
"body:line": "106",
"answer:unprocessed": "THETA"
}
},
{
"body": "Misplace",
"answer": "LOSE",
"number": 59,
"position": {
"col": 4,
"index": 11
},
"metadata": {
"body:line": "107",
"answer:unprocessed": "LOSE"
}
},
{
"body": "Wee boy",
"answer": "LAD",
"number": 61,
"position": {
"col": 10,
"index": 11
},
"metadata": {
"body:line": "108",
"answer:unprocessed": "LAD"
}
},
{
"body": "Dad to Tommy Pickles",
"answer": "STU",
"number": 62,
"position": {
"col": 0,
"index": 12
},
"metadata": {
"body:line": "109",
"answer:unprocessed": "STU"
}
},
{
"body": "The only Patrol I trust",
"answer": "PAW",
"number": 63,
"position": {
"col": 1,
"index": 12
},
"metadata": {
"body:line": "110",
"answer:unprocessed": "PAW"
}
},
{
"body": "Smart savings plan, briefly",
"answer": "IRA",
"number": 64,
"position": {
"col": 2,
"index": 12
},
"metadata": {
"body:line": "111",
"answer:unprocessed": "IRA"
}
},
{
"body": "Fresh",
"answer": "NEW",
"number": 65,
"position": {
"col": 6,
"index": 12
},
"metadata": {
"body:line": "112",
"answer:unprocessed": "NEW"
}
},
{
"body": "Breeds such as Chihuahua or Pomeranian",
"answer": "TOY",
"number": 67,
"position": {
"col": 11,
"index": 12
},
"metadata": {
"body:line": "113",
"answer:unprocessed": "TOY"
}
},
{
"body": "Bega behind \"Mambo No. 5\"",
"answer": "LOU",
"number": 68,
"position": {
"col": 12,
"index": 12
},
"metadata": {
"body:line": "114",
"answer:unprocessed": "LOU"
}
},
{
"body": "Aardvark breakfast",
"answer": "ANT",
"number": 69,
"position": {
"col": 13,
"index": 12
},
"metadata": {
"body:line": "115",
"answer:unprocessed": "ANT"
}
},
{
"body": "Sonic ___",
"answer": "SEZ",
"number": 70,
"position": {
"col": 14,
"index": 12
},
"metadata": {
"body:line": "116",
"answer:unprocessed": "SEZ"
}
}
]
},
"rebuses": {},
"notes": "",
"report": {
"success": true,
"errors": [],
"warnings": []
},
"editorInfo": {
"sections": [
{
"startLine": 0,
"endLine": 6,
"type": "metadata"
},
{
"startLine": 7,
"endLine": 25,
"type": "grid"
},
{
"startLine": 26,
"endLine": 117,
"type": "clues"
},
{
"startLine": 118,
"endLine": 119,
"type": "notes"
},
{
"startLine": 120,
"endLine": 140,
"type": "design"
}
],
"lines": [
"## Metadata",
"",
"title: Alpha-Bits",
"author: Drew Hodson",
"copyright: © 2021",
"description: N/A",
"",
"## Grid",
"",
"AHAB..CUD.SERIF",
"MADAM.ANY.ABODE",
"PLANE.DIE.NOTON",
"....TODO.EGO...",
"GASH.NINJA.KEEL",
"ARTICLE.ORU.DOE",
"YEARLY.MISPRINT",
"..NEI.MAN.SOT..",
"CALENDAR.RETIES",
"ICE.TAR.POTHOLE",
"OTEP.HQTRS.SNIT",
"...ALL.HEAL....",
"SPIRO.NET.ATLAS",
"TARTS.ETA.DOONE",
"UWAVE.WAX..YUTZ",
"",
"",
"## Clues",
"",
"A1. Captain of the Pequod ~ AHAB",
"A5. Food for second chance chewing ~ CUD",
"A8. Font feature ~ SERIF",
"A13. Palindromic address to a female ~ MADAM",
"A15. ___ Way You Want It ~ ANY",
"A16. Place often described as humble ~ ABODE",
"A17. Flat two dimensional surface in geometry ~ PLANE",
"A18. Grim homophone of 7D ~ DIE",
"A19. Off ~ NOTON",
"A20. Heading for some lists ~ TODO",
"A22. Kanye West is famous for his ~ EGO",
"A23. Laceration ~ GASH",
"A27. Alias of Twitch star Richard Tyler Blevins ~ NINJA",
"A29. Capsize ~ KEEL",
"A33. Piece of clothing or print ~ ARTICLE",
"A35. Evangelical school in Tulsa, OK ~ ORU",
"A37. ___-eyed ~ DOE",
"A38. Annual ~ YEARLY",
"A39. The stamp with the upside down airplane is a famous one ~ MISPRINT",
"A41. With 42A and Marcus, a luxury department store chain ~ NEI",
"A42. 41A continued ~ MAN",
"A43. Lush ~ SOT",
"A44. The Mayan one ended in 2012 ~ CALENDAR",
"A47. What a child often does to their shoes ~ RETIES",
"A50. Vanilla ___ ~ ICE",
"A51. Maligned cigarette ingredient ~ TAR",
"A52. Frequent cause for a new tire ~ POTHOLE",
"A53. Los Angeles heavy metal act ~ OTEP",
"A55. Bldgs. such as the Googleplex ~ HQTRS",
"A57. A fit of irritation ~ SNIT",
"A58. Lead-in to American or day ~ ALL",
"A60. What Pokémon do at a Pokémon Center ~ HEAL",
"A62. Nixon's vice ~ SPIRO",
"A65. Nothing but ___ ~ NET",
"A66. One with the world on his shoulders ~ ATLAS",
"A71. Filled pastries ~ TARTS",
"A72. Age, in Milan ~ ETA",
"A73. Lorna ___, novel or cookie ~ DOONE",
"A74. Electrocardiogram readout feature ~ UWAVE",
"A75. Hip slang for records ~ WAX",
"A76. Yiddish for a foolish person ~ YUTZ",
"",
"D1. Pc. of concert gear ~ AMP",
"D2. AI antagonist of 2001 ~ HAL",
"D3. Programming pioneer Lovelace ~ ADA",
"D4. Prohibit ~ BAN",
"D5. Type of person to routinely carry a club ~ CADDIE",
"D6. State of the ___ Address ~ UNION",
"D7. Colorful homophone of 18A ~ DYE",
"D8. Snitched ~ SANG",
"D9. Kindle fare ~ EBOOK",
"D10. Decayed matter ~ ROT",
"D11. Type of response you hope to get at the altar ~ IDO",
"D12. Peat-accumulating wetland ~ FEN",
"D14. The ___, NY art museum ~ MET",
"D21. ___Fans ~ ONLY",
"D22. Friends, Romans, countrymen, lend me your... ~ EARS",
"D23. \"Friend of Dorothy\" ~ GAY",
"D24. We ___ the Champions ~ ARE",
"D25. Father of Spider-Man ~ STANLEE",
"D26. What a certain applicant becomes ~ HIREE",
"D28. Connect ~ JOIN",
"D30. Particular form of a published text ~ EDITION",
"D31. Suffix at the end of all of Eevee's evolutions ~ EON",
"D32. Live and ___ Die ~ LET",
"D34. Famous Eastwood whose name became a famous Gorillaz song ~ CLINT",
"D36. Unexpected result in a sporting competition ~ UPSET",
"D39. Disfigure ~ MAR",
"D40. David Lee and Tim ~ ROTHS",
"D42. Luxury watch collection by Garmin ~ MARQ",
"D44. Top dog in an IT org ~ CIO",
"D45. Sister ___ ~ ACT",
"D46. Author Roald ~ DAHL",
"D47. Civil rights activist Parks ~ ROSA",
"D48. An additional name that could be part of 40D's clue ~ ELI",
"D49. Director's domain ~ SET",
"D52. Type of income to go in a 401k ~ PRETAX",
"D54. The Empire Strikes Back, to the Star Wars saga ~ PARTV",
"D56. Greek letter following 72A ~ THETA",
"D59. Misplace ~ LOSE",
"D61. Wee boy ~ LAD",
"D62. Dad to Tommy Pickles ~ STU",
"D63. The only Patrol I trust ~ PAW",
"D64. Smart savings plan, briefly ~ IRA",
"D65. Fresh ~ NEW",
"D67. Breeds such as Chihuahua or Pomeranian ~ TOY",
"D68. Bega behind \"Mambo No. 5\" ~ LOU",
"D69. Aardvark breakfast ~ ANT",
"D70. Sonic ___ ~ SEZ",
"",
"## Notes",
"",
"## Design",
"",
"<style>O { background: circle }</style>",
"",
"O..O##O.O#.O..O",
".....#...#.....",
".....#...#.....",
"####....#...###",
"O..O#.O.O.#O..O",
".......#...#...",
"......#........",
"##...#O.O#...##",
"........#......",
"...#...#.......",
"O..O#.O.O.#O..O",
"###...#....####",
".....#...#.....",
".....#...#.....",
"O..O.#O.O##O..O",
""
]
},
"design": {
"styles": {
"O": {
"background": "circle"
}
},
"positions": [
[
"O",
null,
null,
"O",
null,
null,
"O",
null,
"O",
null,
null,
"O",
null,
null,
"O"
],
[],
[],
[],
[
"O",
null,
null,
"O",
null,
null,
"O",
null,
"O",
null,
null,
"O",
null,
null,
"O"
],
[],
[],
[
null,
null,
null,
null,
null,
null,
"O",
null,
"O"
],
[],
[],
[
"O",
null,
null,
"O",
null,
null,
"O",
null,
"O",
null,
null,
"O",
null,
null,
"O"
],
[],
[],
[],
[
"O",
null,
null,
"O",
null,
null,
"O",
null,
"O",
null,
null,
"O",
null,
null,
"O"
]
]
}
}
xd
Extensions
This lib creates xd
compatible files, but also extends the format in a way that allows for thinking of xd
as a human-editor format.
Structural
Headers -
xd
out of the box has an implicit order:- Meta
- Grid
- Clues
- Notes (optional)
This library respects that behavior, but also supports a markdown header format whereby you could write an
xd
document like:## Metadata Title: Square Author: Orta Editor: Orta Therox Date: 2021-03-16 ## Grid BULB OK#O L##O DESK ## Clues A1. Gardener's concern. ~ BULB A4. A reasonable statement. ~ OK A5. The office centerpiece. ~ DESK D1. To \_ly go. ~ BOLD D2. Bigger than britain. ~ UK D3. A conscious tree. ~ BOOK
This makes the sections a bit more explicit (and conceptually more user-friendly if you have not read the xd documentation ahead of seeing the file) and frees the order in which someone could write a document. Capitalization is ignored.
Clue Metadata
You can add arbitrary metadata to clues by repeating the clue with a custom suffix:
A1. Gardener's concerns with A2 and D4. ~ BULB A1 ^Hint: Turned on to illuminate a room. A1 ^Refs: A2 D4 A4. A reasonable statement. ~ OK A4 ^Hint: All \_\_. A5. The office centerpiece. ~ DESK A5 ^Hint: Fried. D1. To \_ly go. ~ BOLD D1 ^Hint: When you want to make some text stronger. D2. Bigger than britain. ~ UK D2 ^Hint: A union which left europe. D3. A conscious tree. ~ BOOK D3 ^Hint: Registering with a restaurant. ~ BOOK
Capitalization is ignored, the metadata prefix will always be given as lowercase inside the JSON representation.
Markdown/HTML style comments
In markdown you can write
<!--
and-->
to comment out a section of your code. Our implementation is not super smart:## Metadata <!-- WIP: Maybe it should be called rectangle? --> Title: Square Author: Orta Editor: Orta Therox <!-- Date: 2021-03-16 -->
The key is that a line has to start with
<!--
and eventually the same or another line has to end with-->
.Markdown clue syntax
When a clue is written in markdown, it will be parsed into a JSON representation that can be used to render the clue in a UI. The markdown syntax is limited, but should be enough to cover most cases. The syntax is:
A1. [Captain](https://github.com/orta) _of_ /the/ ship Pequod ~ AHAB
Which will add the optional "bodyMD"
to the clue:
{
"answer": "AHAB",
"body": "[Captain](https://github.com/orta) *of* /the/ ship Pequod",
"bodyMD": [
["link", "Captain", "https://github.com/orta"],
["text", " "],
["bold", "of"],
["text", " "],
["italics", "the"],
["text", " ship Pequod"]
]
}
Italics
/word/
or/a phrase/
(not_word_
because_
is often used as a "gap" in the clue text)Bold:
*word*
or*a phrase*
Strike through:
~word~
or~a phrase~
Link:
[text](url)
Split character
Provide hints for where one word terminates and the next begins in a single solution by declaring
SplitCharacter: {character}
inMetadata
, and adding the chosen SplitCharacter between words inClues
.## Metadata SplitCharacter: | ## Clues … D25. Father of Spider-Man ~ STAN|LEE
The 'answer' given from the parser here will be 'STANLEE', but the indexes for each bar will be noted in the clue.
Spec-Breaking Differences
We want to highlight that 'Clue Metadata', 'Comments' and 'Split Characters' are all spec-breaking extensions. E.g. a parser which conforms exactly to the xd spec would likely choke when seeing these features.
We'd be open to a variant of our JSONToXD
function which produces spec-compliant versions of the xd files instead of just our extensions.
Metadata
Shrodinger's Squares. It's likely that a special form of Rebus will work here, for example:
Rebus: 1=M|F
Indicates to the game engine that the rebus for
1
on the grid can be eitherM
orF
.Rebus: 1=M&F 2=L&T
Indicates to the game engine that the rebus for
1
on the grid can be eitherM
orF
, but that the side needs to be respected across all possible rebuses in the clue. So forM1L2
you could haveMALE
andFATE
but notFALE
orMATE
.
Notes
## Design
This is our WIP extension to describe the visual aspects of individual cells. The
xd
format uses lowercase letters in the grid to indicate a particular special trait (for example having a circle background.) We are looking at describing a more complex set of visual attributes, and so the puz -> xd parser uses a new section to indicate the design attributes in a manner similar to how rebuses are handled.## Design <style> O { background: circle } </style> ....###...#.... ....##....#.... ....#.....#.... ............### ...#....##....# ......#....O... ##...#....#O... ..O....#...O... ..O.#....#.O.## ..O.....#..O... #.OO.##....#O.. ###O........O.. ...O#.....#.O.. ...O#....##.O.. ...O#...###.O..
## Start
Instead of starting with an board, create a board with letters pre-filled. For example this crossword would start with "GO" "FOR" and "IT" already in:
## Start GO..##FOR#IT... .....#...#..... .....#...#..... ####....#...### ....#.....#.... .......#...#... ......#........ ##...#...#...## ........#...... ...#...#....... ....#.....#.... ###...#....#### .....#...#..... .....#...#..... .....#...##....
## Metapuzzle
We'd like a way to describe a final question and a final answer for a puzzle. For example, in alpha-bits above the circles indicate a letter pattern and there could be a way to respond that you got the theme. For example:
## Metapuzzle How are the words sorted? > Alphabetic
Case in the answer should be ignored by engines.
Filetypes this lib is open to adding
- http://www.ipuz.org
- https://www.xwordinfo.com/XPF/ / https://www.xwordinfo.com/JSON/