Skip to content

Commit 24d2b29

Browse files
committed
🌟 Add more precise options to better control the verbose mode (fix #37,#38)
1 parent 58d0391 commit 24d2b29

File tree

5 files changed

+169
-51
lines changed

5 files changed

+169
-51
lines changed

README.md

Lines changed: 59 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ Bring the awesome "Conditional Compilation" to the Webpack, and more.
2727
- [`#!debug`](#debug-1)
2828
- [Caveats](#caveats)
2929
- [Javascript](#javascript)
30+
- [Changelog](#changelog)
3031
- [License](#license)
3132

3233
## Why <!-- omit in toc -->
@@ -363,19 +364,19 @@ Provide constant values for built-in `#!if` / `#!elseif` / `#!else` / `#!endif`
363364

364365
### `verbose`
365366

366-
> type: `boolean`
367+
> type: `boolean` | `{ escapeComments?: boolean; }`
367368
>
368369
> default: `false`
369370
370-
Preserve all directive comments and omitted lines as comments. Basically for debugging purpose.
371+
Preserve all directive comments and omitted lines as comments. Basically for debugging purpose. Note that the normal comments remain as-is(except padding).
371372

372373
Given:
373374

374375
```javascript
375376
// options.params.ENV === 'product'
376377

377378
// #!if ENV === 'develop'
378-
/** some comment */
379+
/** some comment */
379380
console.log("many doge");
380381
// #!else
381382
console.log("much wow");
@@ -384,15 +385,65 @@ console.log("much wow");
384385

385386
If set to `true`, yields:
386387

388+
<!-- prettier-ignore -->
387389
```javascript
388390
// #!if ENV === 'develop'
389-
// /** some comment */
391+
/** some comment */
390392
// console.log('many doge');
391393
// #!else
392394
console.log("much wow");
393395
// #!endif
394396
```
395397

398+
#### `escapeComments`
399+
400+
> default: `false`
401+
402+
There are rare cases where multiple kinds of comment notations live within the same control block. For example:
403+
404+
```html
405+
<body>
406+
<!-- #!if foo === 1-->
407+
<style>
408+
.div {
409+
/* comment because of reasons */
410+
color: tomato;
411+
}
412+
</style>
413+
<script>
414+
/**
415+
* another multiline comment
416+
417+
*/
418+
const bar = 1;
419+
</script>
420+
<!-- #!endif -->
421+
</body>
422+
```
423+
424+
If `foo === 2`, the comments in `style` and `script` tag will stay as-is and "leak" into outside code. To prevent unwanted results, set `escapeComments` to `true`. All _non-directive_ comment notations will be replaced by `@@`, and re-wrapped by those used in the previous directive:
425+
426+
<!-- prettier-ignore -->
427+
```html
428+
<body>
429+
<!-- #!if foo === 1-->
430+
<!-- <style>-->
431+
<!-- .div {-->
432+
<!-- @@ comment because of reasons @@-->
433+
<!-- color: tomato;-->
434+
<!-- }-->
435+
<!-- </style>-->
436+
<!-- <script>-->
437+
<!-- @@*-->
438+
<!-- * another multiline comment-->
439+
<!-- -->
440+
<!-- @@-->
441+
<!-- const bar = 1;-->
442+
<!-- </script>-->
443+
<!-- #!endif -->
444+
</body>
445+
```
446+
396447
## Built-in Directives
397448

398449
### `#!if` / `#!else` / `#!elseif` / `#!endif`
@@ -546,6 +597,10 @@ module.exports = {
546597
};
547598
```
548599

600+
## Changelog
601+
602+
See [Github Release Page](https://github.com/afterwind-io/preprocessor-loader/releases).
603+
549604
## License
550605

551606
MIT License

src/printer.ts

Lines changed: 32 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
import { PlainTextFilter } from "./filter";
22
import { parse } from "./parser";
33
import { reader } from "./reader";
4-
import { IDirectivesMap, IParamsMap } from "./type";
4+
import { IDirectivesMap, IParamsMap, IVerboseOption } from "./type";
5+
6+
export const COMMENT_TAG_PLACEHOLDER = "@@";
57

68
/**
79
* The main entrance to dealt with code processing.
@@ -16,7 +18,7 @@ export function print(
1618
code: string,
1719
directives: IDirectivesMap,
1820
params: IParamsMap,
19-
verbose: boolean
21+
verbose: boolean | IVerboseOption
2022
): string {
2123
let result: string = "";
2224
let lastCommentOpen = "";
@@ -38,18 +40,29 @@ export function print(
3840
if (preserve) {
3941
segment = raw;
4042
} else if (verbose) {
43+
const { c_open, c_close } = block;
44+
4145
if (isDirective) {
42-
const { c_open, c_close } = block;
4346
lastCommentOpen = c_open || lastCommentOpen;
4447
lastCommentClose = c_close || lastCommentClose;
4548

4649
segment = raw;
4750
} else if (isComment) {
48-
// comment may contain multiple lines
49-
const lines = raw.split("\n").filter((l) => l !== "");
50-
segment = lines
51-
.map((l) => verbosePrint(lastCommentOpen, lastCommentClose, l))
52-
.join("");
51+
const escapeComments = !!(verbose as IVerboseOption).escapeComments;
52+
if (escapeComments) {
53+
const comment = raw
54+
.replace(c_open!, COMMENT_TAG_PLACEHOLDER)
55+
.replace(c_close!, COMMENT_TAG_PLACEHOLDER);
56+
57+
segment = transformComment(comment, (line) =>
58+
verbosePrint(lastCommentOpen, lastCommentClose, line)
59+
);
60+
} else {
61+
const padding = Array.from({ length: lastCommentOpen.length + 1 })
62+
.fill(" ")
63+
.join("");
64+
segment = transformComment(raw, (line) => padding + line + "\n");
65+
}
5366
} else {
5467
segment = verbosePrint(lastCommentOpen, lastCommentClose, raw);
5568
}
@@ -60,6 +73,15 @@ export function print(
6073
return result;
6174
}
6275

63-
function verbosePrint(open: string, close: string, block: string): string {
64-
return `${open} ${block.trim()}${close.trim()}\n`;
76+
function transformComment(
77+
comment: string,
78+
lineTransformer: (line: string) => string
79+
): string {
80+
// Comment may contain multiple lines
81+
const lines = comment.trimRight().split("\n");
82+
return lines.map(lineTransformer).join("");
83+
}
84+
85+
function verbosePrint(open: string, close: string, content: string): string {
86+
return `${open} ${content.trimRight()}${close.trim()}\n`;
6587
}

src/type.ts

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,16 @@ export interface IDirectivesMap {
1414
[key: string]: boolean;
1515
}
1616

17+
/**
18+
* Configs for verbose mode.
19+
*/
20+
export interface IVerboseOption {
21+
/**
22+
* Decides whether escape comment notation in normal comments
23+
*/
24+
escapeComments?: boolean;
25+
}
26+
1727
export interface IPreprocessorOption {
1828
/**
1929
* debug mode
@@ -30,5 +40,5 @@ export interface IPreprocessorOption {
3040
/**
3141
* Should keep all lines (omitted code as comment)
3242
*/
33-
verbose: boolean;
43+
verbose: boolean | IVerboseOption;
3444
}

test/case.js

Lines changed: 42 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -148,44 +148,64 @@ module.exports.R_VERBOSE_SINGLE = `
148148

149149
module.exports.C_VERBOSE_MULTI = `
150150
// #!if foo === 1
151+
/* comment1 */
151152
const a = 1;
153+
/**
154+
* comment2
155+
*/
152156
const b = 2;
153157
// #!endif
154158
`;
155159

156160
module.exports.R_VERBOSE_MULTI = `
157161
// #!if foo === 1
162+
/* comment1 */
158163
// const a = 1;
164+
/**
165+
* comment2
166+
*/
159167
// const b = 2;
160168
// #!endif
161169
`;
162170

163171
module.exports.C_VERBOSE_MIXED = `
164-
// #!debug
165-
const a = 1;
166-
/* #!debug */
167-
const b = 2;
168-
<!-- #!if foo === 1 -->
169-
/*
170-
NOT ME
171-
*/
172-
/* NOT ME EITHER */
173-
const c = 3;
174-
<!-- #!endif -->
172+
<body>
173+
<!-- #!if foo === 1-->
174+
<style>
175+
.div {
176+
/* comment because of reasons */
177+
color: tomato;
178+
}
179+
</style>
180+
<script>
181+
/**
182+
* another multiline comment
183+
184+
*/
185+
const bar = 1;
186+
</script>
187+
<!-- #!endif -->
188+
</body>
175189
`;
176190

177191
module.exports.R_VERBOSE_MIXED = `
178-
// #!debug
179-
// const a = 1;
180-
/* #!debug */
181-
/* const b = 2;*/
182-
<!-- #!if foo === 1 -->
183-
<!-- /*-->
184-
<!-- NOT ME-->
185-
<!-- */-->
186-
<!-- /* NOT ME EITHER */-->
187-
<!-- const c = 3;-->
188-
<!-- #!endif -->
192+
<body>
193+
<!-- #!if foo === 1-->
194+
<!-- <style>-->
195+
<!-- .div {-->
196+
<!-- @@ comment because of reasons @@-->
197+
<!-- color: tomato;-->
198+
<!-- }-->
199+
<!-- </style>-->
200+
<!-- <script>-->
201+
<!-- @@*-->
202+
<!-- * another multiline comment-->
203+
<!-- -->
204+
<!-- @@-->
205+
<!-- const bar = 1;-->
206+
<!-- </script>-->
207+
<!-- #!endif -->
208+
</body>
189209
`;
190210

191211
module.exports.C_CASE_INLINE_COMMENT_SINGLE = `

test/test.js

Lines changed: 25 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -300,24 +300,35 @@ describe('Preprocessor-Loader Test', () => {
300300
});
301301

302302
describe('Option Test - Verbose', () => {
303-
const option = {
304-
params: {
305-
foo: 2,
306-
},
307-
debug: false,
308-
verbose: true,
309-
};
303+
describe('enable without options', () => {
304+
const option = {
305+
params: {
306+
foo: 2,
307+
},
308+
debug: false,
309+
verbose: true,
310+
};
310311

311-
it('Single Line', () => {
312-
expect(p.call({ query: option }, C_VERBOSE_SINGLE)).equals(R_VERBOSE_SINGLE);
313-
});
312+
it('Single Line', () => {
313+
expect(p.call({ query: option }, C_VERBOSE_SINGLE)).equals(R_VERBOSE_SINGLE);
314+
});
314315

315-
it('Multiple Lines', () => {
316-
expect(p.call({ query: option }, C_VERBOSE_MULTI)).equals(R_VERBOSE_MULTI);
316+
it('Multiple Lines', () => {
317+
expect(p.call({ query: option }, C_VERBOSE_MULTI)).equals(R_VERBOSE_MULTI);
318+
});
317319
});
318320

319-
it('Verbose lines should be commented with previous symbols', () => {
320-
expect(p.call({ query: option }, C_VERBOSE_MIXED)).equals(R_VERBOSE_MIXED);
321+
describe('escapeComments', () => {
322+
const option = {
323+
params: {
324+
foo: 2,
325+
},
326+
verbose: { escapeComments: true },
327+
};
328+
329+
it('The notation of normal comments should be transformed like pervious directive', () => {
330+
expect(p.call({ query: option }, C_VERBOSE_MIXED)).equals(R_VERBOSE_MIXED);
331+
});
321332
});
322333
});
323334

0 commit comments

Comments
 (0)