punctilio 1.8.1 → 1.8.3

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 (2) hide show
  1. package/README.md +12 -3
  2. package/package.json +1 -1
package/README.md CHANGED
@@ -78,9 +78,18 @@ Setting aside the benchmark, `punctilio`’s test suite includes 1,100+ tests at
78
78
 
79
79
  ## Works with HTML DOMs via separation boundaries
80
80
 
81
- Other typography libraries either transform plain strings or operate on AST nodes individually (`retext-smartypants` [can’t map changes back to HTML](https://github.com/rehypejs/rehype-retext)). But real HTML has text spanning multiple elements—if you concatenate text from `<em>Wait</em>...`, transform it, then try to split it back, you’ve lost track of where `</em>` belonged.
81
+ Perhaps the most innovative feature of the library is that it properly handles DOMs! (This means it'll also work on Markdown: [convert to HTML](https://github.com/remarkjs/remark), transform with `punctilio`, [convert back to Markdown](https://github.com/JohannesKaufmann/html-to-markdown).)
82
82
 
83
- `punctilio` introduces _separation boundaries_. First, insert a “separator” character (default: `U+E000`) at each element boundary before transforming (like at the start and end of an `<em>`). Every regex allows this character mid-pattern without breaking matches. For example, “`.[SEP]..`” still becomes “`…[SEP]`”. `punctilio` validates the output by ensuring the separator count remains the same.
83
+ Other typography libraries take one of two approaches, both with drawbacks. 
84
+
85
+ 1. String-based libraries (like [`smartypants`](https://www.npmjs.com/package/smartypants)) transform plain text but are unaware of HTML structure. If you concatenate text from `<em>Wait</em>...`, transform it into `Wait…`, and then try to convert back—you've lost track of where the `</em>` belongs. 
86
+ 2. AST-based libraries (like [`rehype-retext`](https://github.com/rehypejs/rehype-retext)) process each text node individually, preserving structure but losing cross-node information. A quote that opens inside `<em>"Wait</em>` and closes outside it `..."` spans two text node. Processed independently, the library can't tell whether the final `"` is opening or closing, because it never sees both at once. 
87
+
88
+ `punctilio` introduces *separation boundaries* to get the best of both worlds:
89
+
90
+ 1. Flatten the parent container's contents to a string, delimiting element boundaries with a private-use Unicode character (`U+E000`) to avoid unintended matches.
91
+ 2. Every regex allows (and preserves) these characters, treating them as boundaries of a “permeable membrane” through which contextual information flows. For example, `.U+E000..` still becomes `…U+E000`.
92
+ 3. Rehydrate the HTML AST. For all *k*, set element *k*’s text content to the segment starting at separator occurrence *k*.
84
93
 
85
94
  ```typescript
86
95
  import { transform, DEFAULT_SEPARATOR } from 'punctilio'
@@ -100,7 +109,7 @@ unified()
100
109
  .use(rehypePunctilio)
101
110
  .use(rehypeStringify)
102
111
  .process('<p><em>"Wait</em>..." -- she said</p>')
103
- // → <p><em>"Wait</em>…"—she said</p>
112
+ // → <p><em>“Wait</em>…”—she said</p>
104
113
  // The opening quote inside <em> and the closing quote outside it
105
114
  // are both resolved correctly across the element boundary.
106
115
  ```
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "punctilio",
3
- "version": "1.8.1",
3
+ "version": "1.8.3",
4
4
  "description": "Smart typography transformations: curly quotes, em-dashes, en-dashes, and more",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",