Skip to content

Commit

Permalink
Bump to v1.0.1, update README, optimize stripJC()
Browse files Browse the repository at this point in the history
stripJsonComments() is now more compact, and hopefully efficient. In
particular, the newline and whitespace checks now prevent the rest of
the comparisons from executing if the current character is whitespace.

Also shortened variable names to enable collapsing more lines. While
normally this might hinder readability, I find it actually enhances it
in this case. At the same time, I also updated some comments and added
more explicit comments to explain why the conditions are organized as
they are.

Updated the README to make sure all the example index.html paths are
file:// URLs. Also updated the "Multilanguage project" section to show
mbland/tomcat-servlet-testing-example using the installed package.
  • Loading branch information
mbland committed Dec 31, 2023
1 parent 34a69ce commit 6e76799
Show file tree
Hide file tree
Showing 3 changed files with 47 additions and 42 deletions.
27 changes: 18 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ Running the wrapper will generate the local `file://` URL to the generated
`index.html` file, e.g.:

```text
file:///Users/.../jsdoc/jsdoc-cli-wrapper/1.0.0/index.html
file:///path/to/jsdoc/output/jsdoc-cli-wrapper/1.0.0/index.html
```

You can click on or copy this link to open it in your browser. You can also open
Expand Down Expand Up @@ -99,14 +99,15 @@ This wrapper resolves both of these minor annoyances.
```sh
$ pnpm jsdoc

> [email protected].0 jsdoc .../jsdoc-cli-wrapper
> [email protected].1 jsdoc /path/to/jsdoc-cli-wrapper
> node index.js -c jsdoc.json .

jsdoc/jsdoc-cli-wrapper/1.0.0/index.html
file:///path/to/jsdoc-cli-wrapper/jsdoc/jsdoc-cli-wrapper/1.0.0/index.html
```

Of course, your own project would use `jsdoc-cli-wrapper` instead of `node
index.js`. (This project uses the latter to ensure Windows compatibility during development.)
index.js`. This project uses the latter to ensure that it uses the version from
the local repository itself.

### Multilanguage project

Expand All @@ -131,17 +132,25 @@ both the frontend and backend into a common `build/` directory. Its
}
```

Its `package.json` contains a `jsdoc` script that runs this wrapper (before this
repository existed, it used a local version, reflected below):
Its `strcalc/src/main/frontend/package.json` contains a `jsdoc` script that runs
this wrapper:

```json
"scripts": {
"jsdoc": "jsdoc-cli-wrapper -c ./jsdoc.json ."
},
```

Running `pnpm jsdoc` from the `strcalc/src/main/frontend` directory looks like:

```sh
$ cd strcalc/src/main/frontend
$ pnpm jsdoc

> [email protected] jsdoc .../tomcat-servlet-testing-example/strcalc/src/main/frontend
> node bin/jsdoc-cli-wrapper.js -c ./jsdoc.json .
> [email protected] jsdoc /path/to/tomcat-servlet-testing-example/strcalc/src/main/frontend
> jsdoc-cli-wrapper -c ./jsdoc.json .

../../../build/jsdoc/tomcat-servlet-testing-example-frontend/0.0.0/index.html
file:////path/to/tomcat-servlet-testing-example/strcalc/build/jsdoc/tomcat-servlet-testing-example-frontend/0.0.0/index.html
```

## Development
Expand Down
60 changes: 28 additions & 32 deletions lib/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -157,13 +157,13 @@ export async function analyzeArgv(argv) {
* If you really want to strip all the extra whitespace out:
*
* ```js
* JSON.stringify(JSON.parse(stripJsonComments(jsonStr)))
* JSON.stringify(JSON.parse(stripJsonComments(str)))
* ```
*
* If you want to reformat it to your liking, e.g., using two space indents:
*
* ```js
* JSON.stringify(JSON.parse(stripJsonComments(jsonStr)), null, 2)
* JSON.stringify(JSON.parse(stripJsonComments(str)), null, 2)
* ```
*
* This function is necessary because the `jsdoc` command depends upon the
Expand All @@ -174,39 +174,35 @@ export async function analyzeArgv(argv) {
* original implementation to avoid adding any dependencies. It may become its
* own separate package one day, likely scoped to avoid conflicts with
* strip-json-comments.
* @param {string} jsonStr - JSON text to strip
* @returns {string} jsonStr with comments, trailing commas replaced by space
* @param {string} str - JSON text to strip
* @returns {string} str with comments, trailing commas replaced by space
*/
export function stripJsonComments(jsonStr) {
let inString, escaped, inComment, comma, result = []

for (let i = 0; i !== jsonStr.length; ++i) {
const prevChar = jsonStr[i-1]
let curChar = jsonStr[i]
const isNotWhitespace = curChar.trimStart() !== ''

if (inString) {
inString = curChar !== '"' || escaped
escaped = curChar === '\\' && !escaped
} else if (inComment) {
if ((curChar === '\n' && inComment === 'line') ||
(curChar === '/' && inComment === 'block' && prevChar === '*')) {
inComment = null
export function stripJsonComments(str) {
let inString, escaped, comment, comma, result = []

for (let i = 0; i !== str.length; ++i) {
let c = str[i]

if (c === '\n') {
if (comment === 'line') comment = null
} else if (c.trimStart() === '') { // preserve other existing whitespace
} else if (inString) {
inString = c !== '"' || escaped
escaped = c === '\\' && !escaped
} else if (comment) {
if (c === '/' && comment === 'block' && str[i-1] === '*') comment = null
c = ' '
} else if (c === '/' || c === '*') { // maybe a comment, don't update comma
if (str[i-1] === '/') { // definitely a comment, or else a syntax error
comment = (c === '/') ? 'line' : 'block'
c = result[i-1] = ' '
}
if (isNotWhitespace) curChar = ' '
} else if (curChar === '"') { // opening a string
inString = true
comma = null
} else if (curChar === '/' || curChar === '*') { // maybe opening a comment
if (prevChar === '/') { // definitely opening a comment
inComment = (curChar === '/') ? 'line' : 'block'
curChar = result[i-1] = ' '
}
} else if (isNotWhitespace) { // definitely outside string or comment
if (comma && (curChar === ']' || curChar === '}')) result[comma] = ' '
comma = (curChar === ',') ? i : null
} else { // outside any valid string or comment, replace trailing commas
if (c === '"') inString = true
else if (comma && (c === ']' || c === '}')) result[comma] = ' '
comma = (c === ',') ? i : null
}
result.push(curChar)
result.push(c)
}
return result.join('')
}
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "jsdoc-cli-wrapper",
"version": "1.0.0",
"version": "1.0.1",
"description": "JSDoc command line interface wrapper",
"main": "index.js",
"bin": "./index.js",
Expand Down

0 comments on commit 6e76799

Please sign in to comment.