extwee 2.3.11 → 2.3.12

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (179) hide show
  1. package/CHANGELOG.md +219 -0
  2. package/CONTRIBUTING.md +305 -0
  3. package/README.md +16 -0
  4. package/build/extwee.core.min.js +1 -1
  5. package/build/extwee.twine1html.min.js +1 -1
  6. package/build/extwee.twine2archive.min.js +1 -1
  7. package/build/extwee.tws.min.js +1 -1
  8. package/package.json +8 -5
  9. package/src/Story.js +2 -2
  10. package/types/src/Story.d.ts +1 -1
  11. package/.github/FUNDING.yml +0 -3
  12. package/.github/codeql-analysis.yml +0 -51
  13. package/.github/dependabot.yml +0 -11
  14. package/.github/workflows/dependabot-automerge.yml +0 -23
  15. package/.github/workflows/nodejs.yml +0 -28
  16. package/.travis.yml +0 -13
  17. package/babel.config.json +0 -18
  18. package/docs/.nojekyll +0 -0
  19. package/docs/README.md +0 -224
  20. package/docs/_sidebar.md +0 -19
  21. package/docs/build/extwee.core.min.js +0 -1
  22. package/docs/build/extwee.twine1html.min.js +0 -1
  23. package/docs/build/extwee.twine2archive.min.js +0 -1
  24. package/docs/build/extwee.tws.min.js +0 -1
  25. package/docs/demos/compiler/extwee.core.min.js +0 -1
  26. package/docs/demos/compiler/index.css +0 -105
  27. package/docs/demos/compiler/index.html +0 -359
  28. package/docs/demos/decompile/extwee.core.min.js +0 -1
  29. package/docs/demos/decompile/index.css +0 -584
  30. package/docs/demos/decompile/index.html +0 -468
  31. package/docs/examples/dynamicPassages.md +0 -28
  32. package/docs/examples/jsonToTwee.md +0 -23
  33. package/docs/examples/twsToTwee.md +0 -25
  34. package/docs/formats/json.md +0 -17
  35. package/docs/formats/twee.md +0 -13
  36. package/docs/formats/twine1HTML.md +0 -13
  37. package/docs/formats/twine2ArchiveHTML.md +0 -13
  38. package/docs/formats/twine2HTML.md +0 -13
  39. package/docs/formats/tws.md +0 -9
  40. package/docs/index.html +0 -26
  41. package/docs/install/npm.md +0 -16
  42. package/docs/install/npx.md +0 -79
  43. package/docs/objects/passage.md +0 -47
  44. package/docs/objects/story.md +0 -69
  45. package/docs/objects/storyformat.md +0 -27
  46. package/eslint.config.js +0 -28
  47. package/extwee.config.json +0 -6
  48. package/extwee.config.md +0 -67
  49. package/jest.config.json +0 -5
  50. package/test/CLI/CLI.test.js +0 -49
  51. package/test/CLI/files/example.json +0 -1
  52. package/test/CLI/files/example6.twee +0 -22
  53. package/test/CLI/files/harlowe.js +0 -3
  54. package/test/CLI/files/input.html +0 -47
  55. package/test/CLI/files/output/test.twee +0 -0
  56. package/test/CLI/files/test.twee +0 -18
  57. package/test/CLI/files/tweeExample.twee +0 -17
  58. package/test/CLI/files/twine1/LICENSE.txt +0 -32
  59. package/test/CLI/files/twine1/code.js +0 -5
  60. package/test/CLI/files/twine1/engine.js +0 -43
  61. package/test/CLI/files/twine1/header.html +0 -325
  62. package/test/CLI/files/twine1Test.html +0 -371
  63. package/test/CLI/files/twineExample.html +0 -16
  64. package/test/Config/Config.test.js +0 -76
  65. package/test/Config/files/empty.json +0 -3
  66. package/test/Config/files/full.json +0 -8
  67. package/test/Config/files/invalid.json +0 -1
  68. package/test/Config/files/valid.json +0 -6
  69. package/test/Config/isDirectory.test.js +0 -50
  70. package/test/Config/isFile.test.js +0 -53
  71. package/test/Config/loadStoryFormat.test.js +0 -117
  72. package/test/Config/readDirectories.test.js +0 -78
  73. package/test/IFID/IFID.Generate.test.js +0 -10
  74. package/test/JSON/JSON.Parse.test.js +0 -316
  75. package/test/Objects/Passage.test.js +0 -274
  76. package/test/Objects/SnowmanCompatibility.test.js +0 -111
  77. package/test/Objects/Story.test.js +0 -1075
  78. package/test/Objects/StoryFormat.test.js +0 -219
  79. package/test/Roundtrip/Files/Example1.html +0 -64
  80. package/test/Roundtrip/Files/LICENSE +0 -19
  81. package/test/Roundtrip/Files/example1.twee +0 -10
  82. package/test/Roundtrip/Files/example2.twee +0 -27
  83. package/test/Roundtrip/Files/example4.twee +0 -27
  84. package/test/Roundtrip/Files/harlowe.js +0 -3
  85. package/test/Roundtrip/Files/round.html +0 -49
  86. package/test/Roundtrip/Roundtrip.test.js +0 -54
  87. package/test/StoryFormat/StoryFormat.Parse.test.js +0 -479
  88. package/test/TWS/Parse.test.js +0 -56
  89. package/test/TWS/TWSParser/Example5.tws +0 -414
  90. package/test/TWS/TWSParser/noscale.tws +0 -0
  91. package/test/TWS/TWSParser/nostory.tws +0 -0
  92. package/test/Twee/Twee.Escaping.test.js +0 -200
  93. package/test/Twee/Twee.Parse.test.js +0 -108
  94. package/test/Twee/TweeParser/cursed.twee +0 -16
  95. package/test/Twee/TweeParser/cycling.twee +0 -75
  96. package/test/Twee/TweeParser/emptytags.twee +0 -2
  97. package/test/Twee/TweeParser/example.twee +0 -32
  98. package/test/Twee/TweeParser/malformed.twee +0 -2
  99. package/test/Twee/TweeParser/missing.twee +0 -19
  100. package/test/Twee/TweeParser/multipleScriptPassages.twee +0 -19
  101. package/test/Twee/TweeParser/multipleStyleTag.twee +0 -19
  102. package/test/Twee/TweeParser/multipletags.twee +0 -10
  103. package/test/Twee/TweeParser/noTitle.twee +0 -2
  104. package/test/Twee/TweeParser/notes.twee +0 -16
  105. package/test/Twee/TweeParser/pasagemetadataerror.twee +0 -2
  106. package/test/Twee/TweeParser/scriptPassage.twee +0 -16
  107. package/test/Twee/TweeParser/singletag.twee +0 -13
  108. package/test/Twee/TweeParser/start.twee +0 -2
  109. package/test/Twee/TweeParser/startMetadata.twee +0 -14
  110. package/test/Twee/TweeParser/storydataerror.twee +0 -25
  111. package/test/Twee/TweeParser/style.twee +0 -16
  112. package/test/Twee/TweeParser/stylePassage.twee +0 -16
  113. package/test/Twee/TweeParser/test.twee +0 -25
  114. package/test/Twine1HTML/Twine1HTML.Compile.test.js +0 -180
  115. package/test/Twine1HTML/Twine1HTML.Parse.Web.test.js +0 -484
  116. package/test/Twine1HTML/Twine1HTML.Parse.test.js +0 -183
  117. package/test/Twine1HTML/Twine1HTMLCompiler/Twine1/LICENSE +0 -674
  118. package/test/Twine1HTML/Twine1HTMLCompiler/Twine1/engine.js +0 -43
  119. package/test/Twine1HTML/Twine1HTMLCompiler/Twine1/jquery.js +0 -4
  120. package/test/Twine1HTML/Twine1HTMLCompiler/Twine1/modernizr.js +0 -4
  121. package/test/Twine1HTML/Twine1HTMLCompiler/engineTest.html +0 -1
  122. package/test/Twine1HTML/Twine1HTMLCompiler/jonah-1.4.2/LICENSE +0 -32
  123. package/test/Twine1HTML/Twine1HTMLCompiler/jonah-1.4.2/code.js +0 -4
  124. package/test/Twine1HTML/Twine1HTMLCompiler/jonah-1.4.2/header.html +0 -327
  125. package/test/Twine1HTML/Twine1HTMLCompiler/test.html +0 -0
  126. package/test/Twine1HTML/Twine1HTMLCompiler/test1.html +0 -6
  127. package/test/Twine1HTML/Twine1HTMLCompiler/test2.html +0 -6
  128. package/test/Twine1HTML/Twine1HTMLCompiler/test3.html +0 -43
  129. package/test/Twine1HTML/Twine1HTMLCompiler/test4.html +0 -372
  130. package/test/Twine1HTML/Twine1HTMLCompiler/test5.html +0 -372
  131. package/test/Twine2ArchiveHTML/Twine2ArchiveHTML.Compile.test.js +0 -35
  132. package/test/Twine2ArchiveHTML/Twine2ArchiveHTML.Parse.Web.test.js +0 -293
  133. package/test/Twine2ArchiveHTML/Twine2ArchiveHTML.Parse.test.js +0 -42
  134. package/test/Twine2ArchiveHTML/Twine2ArchiveHTMLCompiler/test1.html +0 -6
  135. package/test/Twine2ArchiveHTML/Twine2ArchiveHTMLParser/test1.html +0 -3
  136. package/test/Twine2HTML/Twine2HTML.Compile.test.js +0 -139
  137. package/test/Twine2HTML/Twine2HTML.Parse.Web.test.js +0 -329
  138. package/test/Twine2HTML/Twine2HTML.Parse.test.js +0 -192
  139. package/test/Twine2HTML/Twine2HTMLCompiler/TestTags.html +0 -42
  140. package/test/Twine2HTML/Twine2HTMLCompiler/creator.html +0 -50
  141. package/test/Twine2HTML/Twine2HTMLCompiler/example6.twee +0 -16
  142. package/test/Twine2HTML/Twine2HTMLCompiler/format.js +0 -9
  143. package/test/Twine2HTML/Twine2HTMLCompiler/missingStoryTitle.twee +0 -29
  144. package/test/Twine2HTML/Twine2HTMLCompiler/test11.html +0 -121
  145. package/test/Twine2HTML/Twine2HTMLCompiler/test2.html +0 -58
  146. package/test/Twine2HTML/Twine2HTMLCompiler/test3.html +0 -49
  147. package/test/Twine2HTML/Twine2HTMLCompiler/test4.html +0 -50
  148. package/test/Twine2HTML/Twine2HTMLCompiler/test6.html +0 -49
  149. package/test/Twine2HTML/Twine2HTMLParser/Example1.html +0 -53
  150. package/test/Twine2HTML/Twine2HTMLParser/Tags.html +0 -15
  151. package/test/Twine2HTML/Twine2HTMLParser/lyingStartnode.html +0 -15
  152. package/test/Twine2HTML/Twine2HTMLParser/lyingTagColors.html +0 -48
  153. package/test/Twine2HTML/Twine2HTMLParser/missingCreator.html +0 -11
  154. package/test/Twine2HTML/Twine2HTMLParser/missingCreatorVersion.html +0 -11
  155. package/test/Twine2HTML/Twine2HTMLParser/missingFormat.html +0 -11
  156. package/test/Twine2HTML/Twine2HTMLParser/missingFormatVersion.html +0 -11
  157. package/test/Twine2HTML/Twine2HTMLParser/missingIFID.html +0 -11
  158. package/test/Twine2HTML/Twine2HTMLParser/missingPassageTags.html +0 -15
  159. package/test/Twine2HTML/Twine2HTMLParser/missingPosition.html +0 -15
  160. package/test/Twine2HTML/Twine2HTMLParser/missingScript.html +0 -14
  161. package/test/Twine2HTML/Twine2HTMLParser/missingSize.html +0 -35
  162. package/test/Twine2HTML/Twine2HTMLParser/missingStartnode.html +0 -11
  163. package/test/Twine2HTML/Twine2HTMLParser/missingStyle.html +0 -14
  164. package/test/Twine2HTML/Twine2HTMLParser/missingZoom.html +0 -11
  165. package/test/Twine2HTML/Twine2HTMLParser/tagColors.html +0 -31
  166. package/test/Twine2HTML/Twine2HTMLParser/twineExample.html +0 -23
  167. package/test/Twine2HTML/Twine2HTMLParser/twineExample2.html +0 -15
  168. package/test/Twine2HTML/Twine2HTMLParser/twineExample3.html +0 -15
  169. package/test/Twine2HTML/Twine2HTMLParser/unescaping.html +0 -33
  170. package/test/Web/web-core-coverage.test.js +0 -175
  171. package/test/Web/web-core-global.test.js +0 -93
  172. package/test/Web/web-core.test.js +0 -156
  173. package/test/Web/web-exports.test.js +0 -136
  174. package/test/Web/web-twine1html.test.js +0 -105
  175. package/test/Web/web-twine2archive.test.js +0 -96
  176. package/test/Web/web-tws.test.js +0 -77
  177. package/test/Web/window.Extwee.test.js +0 -97
  178. package/tsconfig.json +0 -21
  179. package/webpack.config.js +0 -47
package/CHANGELOG.md ADDED
@@ -0,0 +1,219 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project will be documented in this file.
4
+
5
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
+ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
+
8
+ ## [2.3.12] - 2025-12-1
9
+
10
+ ### Added
11
+
12
+ - CHANGELOG.md to track project changes
13
+ - CONTRIBUTING.md with development guidelines
14
+ - GitHub issue templates (bug reports, feature requests)
15
+ - GitHub pull request template
16
+ - .npmignore to optimize package size
17
+ - Script-tagged passages now automatically added to `storyJavaScript` property instead of passages array
18
+ - Comprehensive Snowman story format compatibility tests
19
+ - Enhanced HTML entity handling for passage content
20
+ - CI/CD testing across multiple Node.js versions (20.x, 22.x, 23.x)
21
+ - CI/CD testing across multiple operating systems (Ubuntu, Windows, macOS)
22
+
23
+ ### Changed
24
+
25
+ - Passage text content no longer HTML-encoded in output (attributes still encoded)
26
+ - Improved round-trip compatibility between formats
27
+ - Enhanced GitHub Actions workflow for better test coverage
28
+
29
+ ### Fixed
30
+
31
+ - HTML entity encoding bug that broke JavaScript and HTML content in passages
32
+ - Snowman story format compatibility issues with dynamic content
33
+
34
+ ## [2.3.11] - 2025-11-15
35
+
36
+ ### Fixed
37
+
38
+ - Regression of encoding behavior back to original, correct encoding of HTML-like entities
39
+ - Accidentally introduced encoding issue from 2.3.9
40
+
41
+ ## [2.3.10] - 2025-11-15
42
+
43
+ ### Fixed
44
+
45
+ - Issue with parsing of Twee passages using "script" and "stylesheet" keywords
46
+ - Passages not always being processed as Story JavaScript and Story Stylesheet
47
+ - Duplication of passages and incorrect encoding into Twine 2 HTML
48
+
49
+ ## [2.3.9] - 2025-11-15
50
+
51
+ ### Fixed
52
+
53
+ - Edge case issue when encoding special symbols in writing and confirming when reading
54
+
55
+ ## [2.3.8] - 2025-11-15
56
+
57
+ ### Added
58
+
59
+ - Native crypto.randomUUID() for IFID generation (Node.js)
60
+ - Browser-based Crypto API randomUUID() for web builds
61
+ - Performance improvement: UUID generation is much faster
62
+
63
+ ### Changed
64
+
65
+ - Updated dependencies
66
+
67
+ ### Removed
68
+
69
+ - uuid package dependency (replaced with native crypto APIs)
70
+
71
+ ## [2.3.2] - 2025-08-03
72
+
73
+ ### Changed
74
+
75
+ - Monthly maintenance update
76
+ - Updated dependencies (jest, eslint, webpack, eslint-plugin-jsdoc, @inquirer/prompts)
77
+
78
+ ## [2.3.0] - 2024-08-01
79
+
80
+ - May impact older browsers (pre-2021) for web builds
81
+
82
+ ## [2.3.7] - 2025-10-25
83
+
84
+ ### Added
85
+
86
+ - New decompile demo showing Twine 2 HTML analysis with statistics
87
+
88
+ ### Fixed
89
+
90
+ - Issues with web parsing of attributes inside `<tw-storydata>` and `<tw-passagedata>` elements
91
+
92
+ ## [2.3.6] - 2025-10-24
93
+
94
+ ### Changed
95
+
96
+ - Minor release to re-align versions on NPM and GitHub
97
+
98
+ ## [2.3.5] - 2025-10-24
99
+
100
+ ### Added
101
+
102
+ - Exports for various web builds to help with packaging
103
+
104
+ ## [2.3.4] - 2025-10-01
105
+
106
+ ### Added
107
+
108
+ - "Compiler" demo showing browser-based Twee compilation with Story Formats Archive
109
+
110
+ ### Changed
111
+
112
+ - Internal WebPack changes to fix edge cases with loading Extwee in browser
113
+ - Updated dependencies
114
+
115
+ ### Security
116
+
117
+ - Fixed code scanning alert #133: Exception text reinterpreted as HTML
118
+
119
+ ## [2.3.3] - 2025-09-07
120
+
121
+ ### Added
122
+
123
+ - Web-specific versions of major HTML parsers (Twine1HTML, Twine2HTML, Twine2ArchiveHTML) using DOM functionality
124
+ - Separate build files: core, TWS, Twine2Archive, Twine1HTML
125
+
126
+ ### Changed
127
+
128
+ - Optimized web build from 290 KiB to 78.5 KiB (core)
129
+ - Updated UUID to pure ESM module
130
+ - Rewrote Jest mocking functions for compatibility
131
+
132
+ ## [2.3.2] - 2025-08-03
133
+
134
+ ### Added
135
+
136
+ - Support for Twine 2 JSON format
137
+ - Enhanced web build exports
138
+ - Tree-shaking support for better bundle optimization
139
+
140
+ ### Changed
141
+
142
+ - Improved command-line interface with better error messages
143
+ - Updated documentation with more examples
144
+
145
+ ## [2.2.5] - 2024-07-01
146
+
147
+ ### Changed
148
+
149
+ - Separated short and long command-line option flags
150
+ - Improved CLI help documentation
151
+
152
+ ## [2.2.0] - 2024-06-01
153
+
154
+ ### Added
155
+
156
+ - Config file support (extwee.config.json)
157
+ - Better story format version handling
158
+
159
+ ### Changed
160
+
161
+ - Enhanced error messages throughout the application
162
+
163
+ ## [2.1.0] - 2024-05-01
164
+
165
+ ### Added
166
+
167
+ - Twine 2 Archive HTML support
168
+ - Round-trip testing for format conversions
169
+
170
+ ### Fixed
171
+
172
+ - Various parser edge cases
173
+
174
+ ## [2.0.0] - 2024-04-01
175
+
176
+ ### Added
177
+
178
+ - Complete rewrite using ES modules
179
+ - TypeScript type definitions
180
+ - Web builds for browser usage
181
+ - Comprehensive test suite with Jest
182
+
183
+ ### Changed
184
+
185
+ - Modern JavaScript (ES2020+)
186
+ - Improved API design
187
+ - Better separation of concerns
188
+
189
+ ### Breaking Changes
190
+
191
+ - API incompatible with 1.x versions
192
+ - Node.js 14+ required
193
+
194
+ ## [1.6.0] - 2023-12-01
195
+
196
+ ### Added
197
+
198
+ - Twee 3 specification support
199
+ - StoryFormat parsing improvements
200
+
201
+ ### Deprecated
202
+
203
+ - Version 1.x line (replaced by 2.x)
204
+
205
+ ---
206
+
207
+ ## Migration Guides
208
+
209
+ ### From 1.x to 2.x
210
+
211
+ - Update Node.js to version 14 or higher
212
+ - Change CommonJS `require()` to ES `import`
213
+ - Review API changes in object constructors
214
+ - Update file paths to use absolute paths in CLI
215
+
216
+ ### From uuid package to native crypto
217
+
218
+ - No user action required - internal change only
219
+ - IFID generation is now 3.6x faster
@@ -0,0 +1,305 @@
1
+ # Contributing to Extwee
2
+
3
+ Thank you for your interest in contributing to Extwee! This document provides guidelines and instructions for contributing.
4
+
5
+ ## Table of Contents
6
+
7
+ - [Code of Conduct](#code-of-conduct)
8
+ - [Getting Started](#getting-started)
9
+ - [Development Setup](#development-setup)
10
+ - [How to Contribute](#how-to-contribute)
11
+ - [Coding Standards](#coding-standards)
12
+ - [Testing Guidelines](#testing-guidelines)
13
+ - [Submitting Changes](#submitting-changes)
14
+ - [Release Process](#release-process)
15
+
16
+ ## Code of Conduct
17
+
18
+ This project adheres to the Contributor Covenant [Code of Conduct](CODE_OF_CONDUCT.md). By participating, you are expected to uphold this code. Please report unacceptable behavior to the project maintainer.
19
+
20
+ ## Getting Started
21
+
22
+ ### Prerequisites
23
+
24
+ - **Node.js** 18.x or higher (LTS recommended)
25
+ - **npm** 9.x or higher
26
+ - **Git** for version control
27
+
28
+ ### Development Setup
29
+
30
+ 1. **Fork the repository** on GitHub
31
+
32
+ 2. **Clone your fork**:
33
+
34
+ ```bash
35
+ git clone https://github.com/YOUR-USERNAME/extwee.git
36
+ cd extwee
37
+ ```
38
+
39
+ 3. **Add upstream remote**:
40
+
41
+ ```bash
42
+ git remote add upstream https://github.com/videlais/extwee.git
43
+ ```
44
+
45
+ 4. **Install dependencies**:
46
+
47
+ ```bash
48
+ npm install
49
+ ```
50
+
51
+ 5. **Run tests to verify setup**:
52
+
53
+ ```bash
54
+ npm test
55
+ ```
56
+
57
+ 6. **Build the project**:
58
+
59
+ ```bash
60
+ npm run all
61
+ ```
62
+
63
+ ## How to Contribute
64
+
65
+ ### Reporting Bugs
66
+
67
+ 1. **Check existing issues** to avoid duplicates
68
+ 2. **Use the bug report template** when creating a new issue
69
+ 3. **Include**:
70
+ - Clear description of the problem
71
+ - Steps to reproduce
72
+ - Expected vs. actual behavior
73
+ - Your environment (Node.js version, OS, etc.)
74
+ - Relevant code samples or error messages
75
+
76
+ ### Suggesting Enhancements
77
+
78
+ 1. **Check existing feature requests** to avoid duplicates
79
+ 2. **Use the feature request template** when creating a new issue
80
+ 3. **Explain**:
81
+ - What problem this solves
82
+ - How it should work
83
+ - Why this would be useful to most users
84
+
85
+ ### Pull Requests
86
+
87
+ 1. **Create a feature branch**:
88
+
89
+ ```bash
90
+ git checkout -b feature/your-feature-name
91
+ ```
92
+
93
+ 2. **Make your changes** following our [coding standards](#coding-standards)
94
+
95
+ 3. **Write or update tests** for your changes
96
+
97
+ 4. **Run the full test suite**:
98
+
99
+ ```bash
100
+ npm run all
101
+ ```
102
+
103
+ 5. **Commit your changes** with clear, descriptive messages:
104
+
105
+ ```bash
106
+ git commit -m "Add feature: brief description"
107
+ ```
108
+
109
+ 6. **Push to your fork**:
110
+
111
+ ```bash
112
+ git push origin feature/your-feature-name
113
+ ```
114
+
115
+ 7. **Create a Pull Request** on GitHub
116
+
117
+ ## Coding Standards
118
+
119
+ ### JavaScript Style
120
+
121
+ - Use **ES modules** (`import`/`export`)
122
+ - Use **2 spaces** for indentation
123
+ - Use **semicolons**
124
+ - Use **single quotes** for strings
125
+ - Follow **ESLint** configuration (run `npm run lint`)
126
+
127
+ ### Code Organization
128
+
129
+ ```javascript
130
+ // 1. Imports at the top
131
+ import { Something } from './module.js';
132
+
133
+ // 2. Constants
134
+ const CONSTANT_VALUE = 'value';
135
+
136
+ // 3. Helper functions
137
+ function helperFunction() { }
138
+
139
+ // 4. Main exported functions/classes
140
+ export function mainFunction() { }
141
+ ```
142
+
143
+ ### Naming Conventions
144
+
145
+ - **Classes**: PascalCase (`Story`, `Passage`, `StoryFormat`)
146
+ - **Functions**: camelCase (`parseTwee`, `compileTwine2HTML`)
147
+ - **Constants**: UPPER_SNAKE_CASE (`CREATOR_VERSION`)
148
+ - **Private fields**: Prefix with `#_` (`#_passages`, `#_name`)
149
+
150
+ ### Documentation
151
+
152
+ - **All public functions** must have JSDoc comments
153
+ - Include `@param`, `@returns`, `@throws` as appropriate
154
+ - Add usage examples for complex functions
155
+ - Update README.md if adding new features
156
+
157
+ Example:
158
+
159
+ ```javascript
160
+ /**
161
+ * Parse Twee 3 format into Story object.
162
+ * @function parse
163
+ * @param {string} contents - Twee 3 formatted string
164
+ * @returns {Story} Parsed Story object
165
+ * @throws {Error} If contents is not a string
166
+ * @throws {Error} If no passages are found
167
+ * @example
168
+ * const story = parseTwee(':: Start\nHello World!');
169
+ */
170
+ export function parse(contents) {
171
+ // Implementation
172
+ }
173
+ ```
174
+
175
+ ## Testing Guidelines
176
+
177
+ ### Test Requirements
178
+
179
+ - **All new features** must include tests
180
+ - **Bug fixes** should include regression tests
181
+ - Maintain **>90% code coverage**
182
+ - Tests must pass on all supported Node.js versions
183
+
184
+ ### Running Tests
185
+
186
+ ```bash
187
+ # Run all tests
188
+ npm test
189
+
190
+ # Run specific test file
191
+ npm test -- path/to/test.js
192
+
193
+ # Run tests with coverage
194
+ npm test -- --coverage
195
+
196
+ # Run tests in watch mode (during development)
197
+ npm test -- --watch
198
+ ```
199
+
200
+ ### Writing Tests
201
+
202
+ - Use **Jest** testing framework
203
+ - Follow **AAA pattern** (Arrange, Act, Assert)
204
+ - Use **descriptive test names**
205
+ - Group related tests with `describe` blocks
206
+
207
+ Example:
208
+
209
+ ```javascript
210
+ describe('parseTwee()', () => {
211
+ it('should parse a simple Twee file', () => {
212
+ // Arrange
213
+ const input = ':: Start\nHello World!';
214
+
215
+ // Act
216
+ const story = parseTwee(input);
217
+
218
+ // Assert
219
+ expect(story.passages).toHaveLength(1);
220
+ expect(story.passages[0].name).toBe('Start');
221
+ expect(story.passages[0].text).toBe('Hello World!');
222
+ });
223
+
224
+ it('should throw error for invalid input', () => {
225
+ expect(() => parseTwee(123)).toThrow();
226
+ });
227
+ });
228
+ ```
229
+
230
+ ### Test Coverage Areas
231
+
232
+ - **Unit tests**: Individual functions and methods
233
+ - **Integration tests**: Multiple components working together
234
+ - **Edge cases**: Invalid input, empty strings, special characters
235
+ - **Error handling**: Proper error messages and types
236
+
237
+ ## Submitting Changes
238
+
239
+ ### Pull Request Guidelines
240
+
241
+ 1. **Keep PRs focused** - One feature/fix per PR
242
+ 2. **Update documentation** - README, JSDoc, CHANGELOG
243
+ 3. **Add tests** - Maintain or improve coverage
244
+ 4. **Follow commit conventions**:
245
+
246
+ ```text
247
+ type(scope): brief description
248
+
249
+ Longer description if needed
250
+
251
+ Fixes #123
252
+ ```
253
+
254
+ Types: `feat`, `fix`, `docs`, `style`, `refactor`, `test`, `chore`
255
+
256
+ 5. **Ensure CI passes** - All tests and lints must pass
257
+ 6. **Request review** - Wait for maintainer feedback
258
+ 7. **Update your branch** if main has changed:
259
+
260
+ ```bash
261
+ git fetch upstream
262
+ git rebase upstream/main
263
+ ```
264
+
265
+ ### Commit Message Examples
266
+
267
+ ```bash
268
+ # Good commit messages
269
+ feat(parser): add support for metadata in passage headers
270
+ fix(compiler): correct HTML entity encoding in passages
271
+ docs(readme): add examples for JSON format
272
+ test(twee): add edge case tests for escape sequences
273
+
274
+ # Bad commit messages
275
+ fixed bug
276
+ updates
277
+ WIP
278
+ asdf
279
+ ```
280
+
281
+ ## Release Process
282
+
283
+ 1. Update version in `package.json`
284
+ 2. Update `CHANGELOG.md` with release notes
285
+ 3. Run full test suite: `npm run all`
286
+ 4. Commit: `git commit -m "chore: release v2.3.13"`
287
+ 5. Tag: `git tag v2.3.13`
288
+ 6. Push: `git push && git push --tags`
289
+ 7. Publish: `npm publish`
290
+ 8. Create GitHub release with notes from CHANGELOG
291
+
292
+ ## Additional Resources
293
+
294
+ - [Twine Specifications](https://github.com/iftechfoundation/twine-specs)
295
+ - [Twee 3 Specification](https://github.com/iftechfoundation/twine-specs/blob/master/twee-3-specification.md)
296
+ - [Jest Documentation](https://jestjs.io/docs/getting-started)
297
+ - [ESLint Rules](https://eslint.org/docs/rules/)
298
+
299
+ ## Questions?
300
+
301
+ - Open a [Discussion](https://github.com/videlais/extwee/discussions) for questions
302
+ - Check existing [Issues](https://github.com/videlais/extwee/issues) for known problems
303
+ - Review [Documentation](https://videlais.github.io/extwee/) for usage help
304
+
305
+ Thank you for contributing to Extwee! 🎉
package/README.md CHANGED
@@ -217,6 +217,22 @@ When using the API, it is possible to only import a single function or object to
217
217
 
218
218
  <p align="right">(<a href="#readme-top">back to top</a>)</p>
219
219
 
220
+ ## Contributing
221
+
222
+ Contributions are welcome! Please read our [Contributing Guide](CONTRIBUTING.md) for details on:
223
+
224
+ - Setting up your development environment
225
+ - Code style and standards
226
+ - Testing requirements
227
+ - Submitting pull requests
228
+
229
+ See also:
230
+ - [Code of Conduct](CODE_OF_CONDUCT.md)
231
+ - [Changelog](CHANGELOG.md)
232
+ - [Security Policy](SECURITY.md)
233
+
234
+ <p align="right">(<a href="#readme-top">back to top</a>)</p>
235
+
220
236
  ## License
221
237
 
222
238
  Distributed under the MIT License. See `LICENSE.txt` for more information.