UNPKG

@xwordly/xword-parser

Version:

Fast, type-safe TypeScript library for parsing crossword puzzles (PUZ, iPUZ, JPZ, XD)

1 lines 35.4 kB
{"version":3,"sources":["../src/ipuz.ts"],"names":["CellType"],"mappings":"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","file":"chunk-VJXS4EY5.mjs","sourcesContent":["/**\n * Parser for ipuz crossword format.\n * Based on specification at https://www.puzzazz.com/ipuz\n */\n\nimport { UnsupportedPuzzleTypeError, IpuzParseError } from './errors';\nimport type { Puzzle, Grid, Cell as UnifiedCell, Clues, ParseOptions } from './types';\nimport { ErrorCode } from './types';\nimport { MAX_GRID_WIDTH, MAX_GRID_HEIGHT } from './constants';\n\nexport enum CellType {\n NORMAL = 'normal',\n BLOCK = 'block',\n NULL = 'null',\n}\n\nexport interface CellStyle {\n shapebg?: string;\n highlight?: boolean;\n named?: boolean;\n border?: number;\n divided?: string;\n label?: string;\n mark?: Record<string, unknown>;\n imagebg?: string;\n color?: string;\n colortext?: string;\n colorborder?: string;\n colorbar?: string;\n barred?: string;\n dotted?: string;\n dashed?: string;\n lessthan?: string;\n greaterthan?: string;\n equal?: string;\n handler?: string;\n handlerdata?: unknown;\n}\n\nexport interface IpuzCell {\n type: CellType;\n number?: number | string;\n value?: string;\n solution?: string;\n style?: CellStyle;\n continued?: Record<string, unknown>;\n directions?: string[];\n given?: boolean;\n}\n\nexport interface IpuzClue {\n number: number | string;\n text: string;\n cells?: Array<[number, number]>;\n references?: Array<number | string>;\n continued?: Record<string, unknown>;\n highlight?: boolean;\n image?: string;\n}\n\nexport interface IpuzPuzzle {\n version: string;\n kind: string[];\n\n dimensions: {\n width: number;\n height: number;\n };\n\n puzzle: IpuzCell[][];\n\n title?: string;\n author?: string;\n copyright?: string;\n publisher?: string;\n publication?: string;\n url?: string;\n uniqueId?: string;\n intro?: string;\n explanation?: string;\n annotation?: string;\n notes?: string;\n difficulty?: string;\n origin?: string;\n date?: string;\n\n empty?: string;\n charset?: string;\n\n clues: Record<string, IpuzClue[]>;\n\n solution?: Array<Array<string | null>>;\n\n zones?: Array<Record<string, unknown>>;\n\n styles?: Record<string, unknown>;\n\n extensions: Record<string, unknown>;\n\n volatile?: Record<string, boolean>;\n\n checksum?: string[];\n\n saved?: Array<Array<string | null>>;\n\n enumeration?: boolean;\n enumerations?: string[];\n\n misses?: Record<string, unknown>;\n\n block?: string;\n\n showEnumerations?: boolean;\n cluePlacement?: string;\n\n answer?: string;\n answers?: string[];\n}\n\ninterface IpuzCellData {\n cell?: unknown;\n style?: Record<string, unknown>;\n value?: string;\n continued?: Record<string, unknown>;\n directions?: string[];\n given?: boolean;\n}\n\ninterface IpuzClueData {\n number?: number | string;\n clue?: string;\n cells?: Array<[number, number]>;\n references?: Array<number | string>;\n continued?: Record<string, unknown>;\n highlight?: boolean;\n image?: string;\n}\n\ninterface IpuzData {\n version?: string;\n kind?: string[];\n dimensions?: {\n width: number;\n height: number;\n };\n puzzle?: unknown[][];\n solution?: Array<Array<string | null>>;\n clues?: Record<string, unknown[]>;\n saved?: Array<Array<string | null>>;\n title?: string;\n author?: string;\n copyright?: string;\n publisher?: string;\n publication?: string;\n url?: string;\n uniqueid?: string;\n intro?: string;\n explanation?: string;\n annotation?: string;\n notes?: string;\n difficulty?: string;\n origin?: string;\n date?: string;\n empty?: string;\n charset?: string;\n block?: string;\n showenumerations?: boolean;\n clueplacement?: string;\n answer?: string;\n answers?: string[];\n enumeration?: boolean;\n enumerations?: string[];\n volatile?: Record<string, boolean>;\n checksum?: string[];\n zones?: Array<Record<string, unknown>>;\n styles?: Record<string, unknown>;\n misses?: Record<string, unknown>;\n [key: string]: unknown;\n}\n\nfunction parseCellFromIpuz(cellData: unknown, solutionData?: unknown): IpuzCell {\n const cell: IpuzCell = {\n type: CellType.NORMAL,\n };\n\n if (cellData === null || cellData === 'null') {\n cell.type = CellType.NULL;\n return cell;\n }\n\n if (cellData === '#') {\n cell.type = CellType.BLOCK;\n return cell;\n }\n\n if (typeof cellData === 'object' && cellData !== null) {\n const cellObj = cellData as IpuzCellData;\n\n if ('cell' in cellObj && cellObj.cell !== undefined) {\n const baseValue = cellObj.cell;\n if (baseValue === '#') {\n cell.type = CellType.BLOCK;\n } else if (baseValue === 'null' || baseValue === null) {\n cell.type = CellType.NULL;\n } else if (typeof baseValue === 'number' || typeof baseValue === 'string') {\n if (baseValue !== 0 && baseValue !== '0') {\n cell.number = baseValue;\n }\n }\n }\n\n if ('style' in cellObj && cellObj.style && typeof cellObj.style === 'object') {\n cell.style = {};\n const styleFields: (keyof CellStyle)[] = [\n 'shapebg',\n 'highlight',\n 'named',\n 'border',\n 'divided',\n 'label',\n 'mark',\n 'imagebg',\n 'color',\n 'colortext',\n 'colorborder',\n 'colorbar',\n 'barred',\n 'dotted',\n 'dashed',\n 'lessthan',\n 'greaterthan',\n 'equal',\n 'handler',\n 'handlerdata',\n ];\n\n for (const field of styleFields) {\n if (field in cellObj.style) {\n const value = cellObj.style[field];\n if (value !== undefined) {\n (cell.style as Record<string, unknown>)[field] = value;\n }\n }\n }\n }\n\n if ('value' in cellObj && cellObj.value !== undefined) {\n cell.value = cellObj.value;\n }\n\n if ('continued' in cellObj && cellObj.continued !== undefined) {\n cell.continued = cellObj.continued;\n }\n\n if ('directions' in cellObj && cellObj.directions !== undefined) {\n cell.directions = cellObj.directions;\n }\n\n if ('given' in cellObj && cellObj.given !== undefined) {\n cell.given = cellObj.given;\n }\n } else if (typeof cellData === 'number' || typeof cellData === 'string') {\n if (typeof cellData === 'number' && cellData > 0) {\n cell.number = cellData;\n } else if (typeof cellData === 'string') {\n if (cellData === '0' || cellData === '#' || cellData === 'null') {\n // Handle special cases\n if (cellData === '#') {\n cell.type = CellType.BLOCK;\n }\n } else {\n // Try to parse as number for cell numbering\n const numVal = Number.parseInt(cellData, 10);\n if (!Number.isNaN(numVal) && numVal > 0) {\n cell.number = cellData;\n } else {\n // It's a letter/value\n cell.value = cellData;\n }\n }\n }\n }\n\n if (solutionData) {\n if (\n typeof solutionData === 'string' &&\n solutionData !== '#' &&\n solutionData !== 'null' &&\n solutionData !== null\n ) {\n cell.solution = solutionData;\n }\n }\n\n return cell;\n}\n\nfunction parseCluesFromIpuz(cluesData: Record<string, unknown[]>): Record<string, IpuzClue[]> {\n const clues: Record<string, IpuzClue[]> = {};\n\n for (const [direction, clueList] of Object.entries(cluesData)) {\n if (!Array.isArray(clueList)) {\n continue;\n }\n clues[direction] = [];\n\n for (const clueItem of clueList) {\n let clue: IpuzClue | null = null;\n\n if (Array.isArray(clueItem) && clueItem.length >= 2) {\n clue = {\n number: clueItem[0] as number | string,\n text: clueItem[1] as string,\n };\n\n if (clueItem.length > 2) {\n for (let i = 2; i < clueItem.length; i++) {\n const extra = clueItem[i] as unknown;\n if (typeof extra === 'object' && extra !== null) {\n const extraObj = extra as IpuzClueData;\n if ('references' in extraObj && extraObj.references) {\n clue.references = extraObj.references;\n }\n if ('continued' in extraObj && extraObj.continued) {\n clue.continued = extraObj.continued;\n }\n if ('highlight' in extraObj && extraObj.highlight) {\n clue.highlight = extraObj.highlight;\n }\n if ('image' in extraObj && extraObj.image) {\n clue.image = extraObj.image;\n }\n }\n }\n }\n } else if (typeof clueItem === 'object' && clueItem !== null) {\n const clueObj = clueItem as IpuzClueData;\n clue = {\n number: clueObj.number || '',\n text: clueObj.clue || '',\n };\n\n if (clueObj.cells) {\n clue.cells = clueObj.cells;\n }\n if (clueObj.references) {\n clue.references = clueObj.references;\n }\n if (clueObj.continued) {\n clue.continued = clueObj.continued;\n }\n if (clueObj.highlight !== undefined) {\n clue.highlight = clueObj.highlight;\n }\n if (clueObj.image) {\n clue.image = clueObj.image;\n }\n }\n\n if (clue) {\n clues[direction].push(clue);\n }\n }\n }\n\n return clues;\n}\n\n/**\n * Parse an iPUZ format crossword puzzle.\n *\n * @param content - The iPUZ data as JSON string or Buffer\n * @param options - Optional parsing options\n * @param options.maxGridSize - Maximum allowed grid dimensions\n * @returns An IpuzPuzzle object containing all puzzle data\n * @throws {IpuzParseError} When the content is not valid iPUZ format\n * @throws {UnsupportedPuzzleTypeError} When the puzzle is not a crossword\n *\n * @example\n * ```typescript\n * import { parseIpuz } from 'xword-parser';\n * const ipuzData = '{\"version\":\"http://ipuz.org/v2\",\"kind\":[\"http://ipuz.org/crossword#1\"]...}';\n * const puzzle = parseIpuz(ipuzData);\n * ```\n */\nexport function parseIpuz(content: string | Buffer, options?: ParseOptions): IpuzPuzzle {\n const stringContent = typeof content === 'string' ? content : content.toString('utf-8');\n let jsonContent = stringContent.trim();\n\n if (jsonContent.startsWith('ipuz(') && jsonContent.endsWith(')')) {\n jsonContent = jsonContent.slice(5, -1);\n }\n\n let data: IpuzData;\n try {\n data = JSON.parse(jsonContent) as IpuzData;\n } catch (e) {\n throw new IpuzParseError(\n `Invalid JSON: ${e instanceof Error ? e.message : 'Unknown error'}`,\n ErrorCode.IPUZ_INVALID_JSON,\n undefined,\n e,\n );\n }\n\n if (\n !data.kind ||\n !Array.isArray(data.kind) ||\n !data.kind.some((k: string) => k.includes('crossword'))\n ) {\n throw new UnsupportedPuzzleTypeError('Non-crossword');\n }\n\n // Validate required fields for crossword puzzles\n if (!data.dimensions || typeof data.dimensions !== 'object') {\n throw new IpuzParseError(\n 'Missing or invalid dimensions field',\n ErrorCode.IPUZ_MISSING_REQUIRED_FIELD,\n );\n }\n\n if (!data.dimensions.width || !data.dimensions.height) {\n throw new IpuzParseError(\n 'Missing width or height in dimensions',\n ErrorCode.IPUZ_MISSING_REQUIRED_FIELD,\n );\n }\n\n if (typeof data.dimensions.width !== 'number' || typeof data.dimensions.height !== 'number') {\n throw new IpuzParseError('Width and height must be numbers', ErrorCode.IPUZ_INVALID_DATA_TYPE);\n }\n\n if (!Number.isInteger(data.dimensions.width) || !Number.isInteger(data.dimensions.height)) {\n throw new IpuzParseError('Width and height must be integers', ErrorCode.IPUZ_INVALID_DATA_TYPE);\n }\n\n if (data.dimensions.width <= 0 || data.dimensions.height <= 0) {\n throw new IpuzParseError(\n 'Width and height must be positive numbers',\n ErrorCode.IPUZ_INVALID_GRID_SIZE,\n );\n }\n const maxWidth = options?.maxGridSize?.width ?? MAX_GRID_WIDTH;\n const maxHeight = options?.maxGridSize?.height ?? MAX_GRID_HEIGHT;\n\n if (data.dimensions.width > maxWidth || data.dimensions.height > maxHeight) {\n throw new IpuzParseError(\n `Grid dimensions too large: ${data.dimensions.width}x${data.dimensions.height}. Maximum supported size is ${maxWidth}x${maxHeight}`,\n ErrorCode.IPUZ_INVALID_GRID_SIZE,\n );\n }\n\n if (!data.puzzle || !Array.isArray(data.puzzle)) {\n throw new IpuzParseError(\n 'Missing or invalid puzzle grid',\n ErrorCode.IPUZ_MISSING_REQUIRED_FIELD,\n );\n }\n\n const puzzle: IpuzPuzzle = {\n version: data.version || '',\n kind: data.kind || [],\n dimensions: data.dimensions,\n puzzle: [],\n clues: {},\n extensions: {},\n };\n\n const simpleFields = [\n 'title',\n 'author',\n 'copyright',\n 'publisher',\n 'publication',\n 'url',\n 'intro',\n 'explanation',\n 'annotation',\n 'notes',\n 'difficulty',\n 'origin',\n 'date',\n 'empty',\n 'charset',\n 'block',\n 'answer',\n ] as const;\n\n for (const field of simpleFields) {\n if (field in data && data[field] !== undefined) {\n // Use type assertion for known fields\n (puzzle as unknown as Record<string, unknown>)[field] = data[field];\n }\n }\n\n // Handle fields that need renaming from spec format to camelCase\n if ('uniqueid' in data && data.uniqueid !== undefined) {\n puzzle.uniqueId = data.uniqueid;\n }\n if ('showenumerations' in data && data.showenumerations !== undefined) {\n puzzle.showEnumerations = data.showenumerations;\n }\n if ('clueplacement' in data && data.clueplacement !== undefined) {\n puzzle.cluePlacement = data.clueplacement;\n }\n\n if ('answers' in data && data.answers) {\n puzzle.answers = data.answers;\n }\n\n if ('enumeration' in data && data.enumeration !== undefined) {\n puzzle.enumeration = data.enumeration;\n }\n\n if ('enumerations' in data && data.enumerations) {\n puzzle.enumerations = data.enumerations;\n }\n\n if ('volatile' in data && data.volatile) {\n puzzle.volatile = data.volatile;\n }\n\n if ('checksum' in data && data.checksum) {\n puzzle.checksum = data.checksum;\n }\n\n if ('zones' in data && data.zones) {\n puzzle.zones = data.zones;\n }\n\n if ('styles' in data && data.styles) {\n puzzle.styles = data.styles;\n }\n\n if ('misses' in data && data.misses) {\n puzzle.misses = data.misses;\n }\n\n const solutionGrid = data.solution || [];\n if (solutionGrid.length > 0) {\n puzzle.solution = solutionGrid;\n }\n\n if ('saved' in data && data.saved) {\n puzzle.saved = data.saved;\n }\n\n const puzzleGrid = data.puzzle || [];\n for (let rowIdx = 0; rowIdx < puzzleGrid.length; rowIdx++) {\n const row = puzzleGrid[rowIdx];\n if (!row) continue;\n\n const cellRow: IpuzCell[] = [];\n\n for (let colIdx = 0; colIdx < row.length; colIdx++) {\n const cellData = row[colIdx];\n let solutionVal = undefined;\n\n if (\n solutionGrid.length > rowIdx &&\n solutionGrid[rowIdx] &&\n solutionGrid[rowIdx]!.length > colIdx\n ) {\n solutionVal = solutionGrid[rowIdx]![colIdx];\n }\n\n const cell = parseCellFromIpuz(cellData, solutionVal);\n cellRow.push(cell);\n }\n\n puzzle.puzzle.push(cellRow);\n }\n\n if ('clues' in data && data.clues) {\n puzzle.clues = parseCluesFromIpuz(data.clues);\n }\n\n for (const [key, value] of Object.entries(data)) {\n if (key.startsWith('http://') || key.startsWith('https://') || key.includes(':')) {\n puzzle.extensions[key] = value;\n }\n }\n\n return puzzle;\n}\n\n/**\n * Convert an iPUZ puzzle to the unified Puzzle format.\n *\n * @param puzzle - The IpuzPuzzle object to convert\n * @returns A unified Puzzle object\n *\n * @example\n * ```typescript\n * import { parseIpuz, convertIpuzToUnified } from 'xword-parser';\n * const ipuzPuzzle = parseIpuz(ipuzData);\n * const unifiedPuzzle = convertIpuzToUnified(ipuzPuzzle);\n * ```\n */\nexport function convertIpuzToUnified(puzzle: IpuzPuzzle): Puzzle {\n const grid: Grid = {\n width: puzzle.dimensions.width,\n height: puzzle.dimensions.height,\n cells: [],\n };\n\n // Convert grid\n for (let y = 0; y < puzzle.dimensions.height; y++) {\n const row: UnifiedCell[] = [];\n for (let x = 0; x < puzzle.dimensions.width; x++) {\n const ipuzCell = puzzle.puzzle[y]?.[x];\n const solutionCell = puzzle.solution?.[y]?.[x];\n\n // iPUZ cells are already Cell objects from our parser\n const cellNumber = ipuzCell?.number\n ? typeof ipuzCell.number === 'string'\n ? parseInt(ipuzCell.number)\n : ipuzCell.number\n : undefined;\n\n const isBlack = ipuzCell?.type === CellType.BLOCK;\n\n const solution =\n typeof solutionCell === 'string' ? solutionCell : ipuzCell?.value || undefined;\n\n const cell: UnifiedCell = {\n solution,\n number: cellNumber,\n isBlack,\n };\n\n // Check for circle style (common in iPUZ)\n if (\n ipuzCell?.style &&\n typeof ipuzCell.style === 'object' &&\n ipuzCell.style.shapebg === 'circle'\n ) {\n cell.isCircled = true;\n }\n\n // Add remaining cell-specific metadata if present\n if (ipuzCell?.style || ipuzCell?.continued || ipuzCell?.directions || ipuzCell?.given) {\n cell.additionalProperties = {};\n // Only add style if it has more than just shapebg='circle'\n if (\n ipuzCell.style &&\n typeof ipuzCell.style === 'object' &&\n (Object.keys(ipuzCell.style).length > 1 || ipuzCell.style.shapebg !== 'circle')\n ) {\n cell.additionalProperties.style = ipuzCell.style;\n }\n if (ipuzCell.continued) {\n cell.additionalProperties.continued = ipuzCell.continued;\n }\n if (ipuzCell.directions) {\n cell.additionalProperties.directions = ipuzCell.directions;\n }\n if (ipuzCell.given !== undefined) {\n cell.additionalProperties.given = ipuzCell.given;\n }\n // Remove additionalProperties if it's empty\n if (Object.keys(cell.additionalProperties).length === 0) {\n delete cell.additionalProperties;\n }\n }\n\n row.push(cell);\n }\n grid.cells.push(row);\n }\n\n // Convert clues\n const clues: Clues = {\n across: [],\n down: [],\n };\n\n if (puzzle.clues?.Across) {\n for (const clue of puzzle.clues.Across) {\n const clueNumber = typeof clue.number === 'string' ? parseInt(clue.number) : clue.number;\n // Skip invalid clue numbers (NaN, 0, negative)\n if (!Number.isNaN(clueNumber) && clueNumber > 0) {\n clues.across.push({\n number: clueNumber,\n text: clue.text || '',\n });\n }\n }\n }\n\n if (puzzle.clues?.Down) {\n for (const clue of puzzle.clues.Down) {\n const clueNumber = typeof clue.number === 'string' ? parseInt(clue.number) : clue.number;\n // Skip invalid clue numbers (NaN, 0, negative)\n if (!Number.isNaN(clueNumber) && clueNumber > 0) {\n clues.down.push({\n number: clueNumber,\n text: clue.text || '',\n });\n }\n }\n }\n\n const result: Puzzle = {\n title: puzzle.title,\n author: puzzle.author,\n copyright: puzzle.copyright,\n notes: puzzle.notes,\n date: puzzle.date,\n grid,\n clues,\n };\n\n // Add puzzle-level metadata if present\n const additionalProps: Record<string, unknown> = {};\n if (puzzle.difficulty) additionalProps.difficulty = puzzle.difficulty;\n if (puzzle.publisher) additionalProps.publisher = puzzle.publisher;\n if (puzzle.publication) additionalProps.publication = puzzle.publication;\n if (puzzle.url) additionalProps.url = puzzle.url;\n if (puzzle.uniqueId) additionalProps.uniqueId = puzzle.uniqueId;\n if (puzzle.intro) additionalProps.intro = puzzle.intro;\n if (puzzle.explanation) additionalProps.explanation = puzzle.explanation;\n if (puzzle.annotation) additionalProps.annotation = puzzle.annotation;\n\n // Add styles if present\n if (puzzle.styles && Object.keys(puzzle.styles).length > 0) {\n additionalProps.styles = puzzle.styles;\n }\n\n // Add zones if present\n if (puzzle.zones && puzzle.zones.length > 0) {\n additionalProps.zones = puzzle.zones;\n }\n\n // Add extensions if present\n if (Object.keys(puzzle.extensions).length > 0) {\n additionalProps.extensions = puzzle.extensions;\n }\n\n if (Object.keys(additionalProps).length > 0) {\n result.additionalProperties = additionalProps;\n }\n\n return result;\n}\n"]}