Skip to content

Commit

Permalink
added writer configuration: emptyLineBeforeComments
Browse files Browse the repository at this point in the history
  • Loading branch information
lpaladin committed Dec 24, 2018
1 parent 3ac9f7b commit 74e7836
Show file tree
Hide file tree
Showing 8 changed files with 85 additions and 24 deletions.
12 changes: 10 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@

JSON Inline Doc
============================
#### Add inline comments on stringified JSON, or generate from JSON schema
#### Add inline comments on stringified JSON (JSONC), or generate from JSON schema

Use case: Using JSON for configuration and provide inline documentation as comments for users.

Note: JSON does not support comments. But some editors have the so-called 'JSON with comments' support.
JSONC is JSON with JavaScript style comments. Please note that original JSON does not support comments.

Installation:
--------------------------
Expand Down Expand Up @@ -113,6 +113,14 @@ The abstract base class of all writers.
**`writer = new JSONCommentWriterBase(configuration)`**
* Note: The above line of code is only for explanation. This class is abstract - do not try to `new` a instance by yourself!
* `configuration`: object (optional)
* `emptyLineBeforeComments`: boolean (default true)

Add a blank line before every `block` and `line` comment, except comments of the followings:
* The root object
* The first item in array
* The first key-value pair in object

Not supported if `space` when calling `stringify` is 0.
* `spaceAroundCommentSymbol`: boolean (default true)

Add space around '//', '/\*' and '\*/'.
Expand Down
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "json-inline-doc",
"version": "1.0.2",
"description": "Add inline comments on stringified JSON, or generate from JSON schema",
"version": "2.0.0",
"description": "Add inline comments on stringified JSON (JSONC), or generate from JSON schema",
"main": "./lib/index.js",
"typings": "./lib/index.d.ts",
"repository": {
Expand Down
10 changes: 6 additions & 4 deletions src/defaultCommentGenerator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,10 @@ export const defaultCommentGenerator: CommentGenerator = (schema) => {
}
}
}
return contents.length === 0 ? undefined : {
type: 'block',
content: contents.join('\n')
};
return contents.length === 0
? undefined
: {
type: 'block',
content: contents.join('\n')
};
};
47 changes: 35 additions & 12 deletions src/jsonCommentWriterBase.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import {
*/
export abstract class JSONCommentWriterBase<CommentDataNodeType> {
private static readonly defaultConfiguration: IJSONCommentConfiguration = {
emptyLineBeforeComments: true,
spaceAroundCommentSymbol: true,
styledBlockComment: true,
maxLineLength: 80
Expand Down Expand Up @@ -185,8 +186,7 @@ ${gap} */`;
return 'null';
}
const currGap: string = gap + this.indent;
const lineBreakCurrGap: string =
currGap ? '\n' + currGap : '';
const lineBreakCurrGap: string = currGap ? '\n' + currGap : '';
const lineEndComments: { [index: number]: string } = {};
const partial: string[] = [];
const fnPartialToLine: (value: string, i: number) => string =
Expand All @@ -197,15 +197,27 @@ ${gap} */`;
}
for (let i: number = 0; i < value.length; i++) {
const { comments: parts, childJSON, lineEndComment } = this.getChildJSON(value, i, currGap, node);
parts.push(childJSON || 'null');

if (lineEndComment !== undefined) {
lineEndComments[i] = lineEndComment;
}
partial.push(parts.join(lineBreakCurrGap));

parts.push(childJSON || 'null');
const currentItemWithComments: string = parts.join(lineBreakCurrGap);

if (this.configuration.emptyLineBeforeComments && i > 0 && parts.length > 1 && currGap) {
// Not the first item in array && has comment && spaces != 0
// Add a empty line
partial.push(lineBreakCurrGap + currentItemWithComments);
} else {
partial.push(currGap + currentItemWithComments);
}
}
return currGap ? `[
${currGap}${partial.map(fnPartialToLine).join(lineBreakCurrGap)}
${gap}]` : `[${partial.join(',')}]`;
return currGap
? `[
${partial.map(fnPartialToLine).join('\n')}
${gap}]`
: `[${partial.join(',')}]`;
} else {
const keys: (string | number)[] = Array.isArray(this.replacer) ? this.replacer : Object.keys(value);
if (keys.length === 0) {
Expand All @@ -214,16 +226,27 @@ ${gap}]` : `[${partial.join(',')}]`;
for (const k of keys) {
const { comments: parts, childJSON, lineEndComment } = this.getChildJSON(value, k, currGap, node);
if (childJSON) {
parts.push(JSON.stringify(k) + (currGap ? ': ' : ':') + childJSON);
if (lineEndComment !== undefined) {
lineEndComments[partial.length] = lineEndComment;
}
partial.push(parts.join(lineBreakCurrGap));

parts.push(JSON.stringify(k) + (currGap ? ': ' : ':') + childJSON);
const currentKVPairWithComments: string = parts.join(lineBreakCurrGap);

if (this.configuration.emptyLineBeforeComments && partial.length > 0 && parts.length > 1 && currGap) {
// Not the first key-value pair in object && has comment && spaces != 0
// Add a empty line
partial.push(lineBreakCurrGap + currentKVPairWithComments);
} else {
partial.push(currGap + currentKVPairWithComments);
}
}
}
return currGap ? `{
${currGap}${partial.map(fnPartialToLine).join(lineBreakCurrGap)}
${gap}}` : `{${partial.join(',')}}`;
return currGap
? `{
${partial.map(fnPartialToLine).join('\n')}
${gap}}`
: `{${partial.join(',')}}`;
}
} else {
return JSON.stringify(value);
Expand Down
4 changes: 4 additions & 0 deletions src/test/assets.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,10 +41,12 @@ export const TEST_SCHEMA_COMMENTED = `/**
* @description Description of the schema
*/
"description": "Cluster Configuration",
/**
* @description Type of the schema
*/
"type": "object",
/**
* @type object
* @description Available properties of the schema
Expand All @@ -60,13 +62,15 @@ export const TEST_SCHEMA_COMMENTED = `/**
* @description Type of the schema
*/
"type": "string",
/**
* @type string
* @description Description of the schema
*/
"description": "Cluster name"
}
},
/**
* @type array
* @default []
Expand Down
14 changes: 11 additions & 3 deletions src/test/blockComment.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,12 @@ describe('block comments', () => {
* test4
*/
1,
/**
* test3
*/
2,
/**
* test4
*/
Expand All @@ -59,8 +61,12 @@ describe('block comments', () => {
}`);
});

it('should reflect changes in configuration - no style and space', () => {
const w: CustomCommentWriter = new CustomCommentWriter({ spaceAroundCommentSymbol: false, styledBlockComment: false });
it('should reflect changes in configuration - no empty line, style and space', () => {
const w: CustomCommentWriter = new CustomCommentWriter({
emptyLineBeforeComments: false,
spaceAroundCommentSymbol: false,
styledBlockComment: false
});
w.addComments([], [{ type: 'block', content: 'test' }]);
w.addComments(['test'], [{ type: 'block', content: 'test2' }]);
w.addComments(['test', 1], [{ type: 'block', content: 'test3' }]);
Expand Down Expand Up @@ -94,7 +100,7 @@ describe('block comments', () => {
}`);
});

it('should reflect changes in configuration - no style but with space', () => {
it('should reflect changes in configuration - no style but with empty line and space', () => {
const w: CustomCommentWriter = new CustomCommentWriter({ styledBlockComment: false });
w.addComments([], [{ type: 'block', content: 'test' }]);
w.addComments(['test'], [{ type: 'block', content: 'test2' }]);
Expand All @@ -114,8 +120,10 @@ describe('block comments', () => {
"test": [
/* test4 */
1,
/* test3 */
2,
/* test4 */
3
]
Expand Down
7 changes: 6 additions & 1 deletion src/test/lineComment.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,10 @@ describe('line comments', () => {
"test": [
// test4
1,
// test3
2,
// test4
3
]
Expand All @@ -40,7 +42,10 @@ describe('line comments', () => {
});

it('should reflect changes in configuration', () => {
const w: CustomCommentWriter = new CustomCommentWriter({ spaceAroundCommentSymbol: false });
const w: CustomCommentWriter = new CustomCommentWriter({
emptyLineBeforeComments: false,
spaceAroundCommentSymbol: false
});
w.addComments([], [{ type: 'line', content: 'test' }]);
w.addComments(['test'], [{ type: 'line', content: 'test2' }]);
w.addComments(['test', 1], [{ type: 'line', content: 'test3' }]);
Expand Down
11 changes: 11 additions & 0 deletions src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,17 @@ export type IJSONComment = {
} | string;

export interface IJSONCommentConfiguration {
/**
* @description Add a blank line before every `block` and `line` comment,
* except comments of the followings:
* * The root object
* * The first item in array
* * The first key-value pair in object
* Not supported if `space` when calling `stringify` is 0.
*
* @default true
*/
emptyLineBeforeComments: boolean;
/**
* @description Add space around '//', '/\*' and '\*\/'.
* '/\*' and '\*\/' will not be affected by this
Expand Down

0 comments on commit 74e7836

Please sign in to comment.