Skip to content

Commit

Permalink
Merge pull request #47 from SukkaW/feat-quote-style
Browse files Browse the repository at this point in the history
feat: quoteStyle option
  • Loading branch information
Scrum authored Nov 18, 2020
2 parents 86f2c9d + 3ee8d58 commit 2de7798
Show file tree
Hide file tree
Showing 4 changed files with 106 additions and 7 deletions.
14 changes: 14 additions & 0 deletions lib/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,20 @@ declare namespace render {
* @default true
*/
quoteAllAttributes: boolean;

/**
* Quote style
*
* 0 - Smart quotes
* <img src="https://example.com/example.png" onload='testFunc("test")'>
* 1 - Single quotes
* <img src='https://example.com/example.png' onload='testFunc("test")'>
* 2 - double quotes
* <img src="https://example.com/example.png" onload="testFunc("test")">
*
* @default 2
*/
quoteStyle: 0 | 1 | 2
};

// PostHTML Tree
Expand Down
39 changes: 32 additions & 7 deletions lib/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -59,12 +59,17 @@ function render(tree, options) {
replaceQuote = true;
}

let {quoteStyle} = options;
if (quoteStyle === undefined) {
quoteStyle = 2;
}

return html(tree);

/** @private */
function isSingleTag(tag) {
if (singleRegExp.length > 0) {
return singleRegExp.some(reg => reg.test(tag))
return singleRegExp.some(reg => reg.test(tag));
}

if (!singleTags.includes(tag)) {
Expand All @@ -87,7 +92,7 @@ function render(tree, options) {
attrValue = object[key].replace(/"/g, '&quot;');
}

attr += ' ' + key + '="' + attrValue + '"';
attr += makeAttr(key, attrValue, quoteStyle);
} else if (object[key] === '') {
attr += ' ' + key;
} else {
Expand All @@ -96,7 +101,7 @@ function render(tree, options) {
} else if (object[key] === true) {
attr += ' ' + key;
} else if (typeof object[key] === 'number') {
attr += ' ' + key + '="' + object[key] + '"';
attr += makeAttr(key, object[key], quoteStyle);
}
}

Expand All @@ -112,6 +117,26 @@ function render(tree, options) {
}
}

/** @private */
function makeAttr(key, attrValue, quoteStyle = 1) {
if (quoteStyle === 1) {
// Single Quote
return ` ${key}='${attrValue}'`;
}

if (quoteStyle === 2) {
// Double Quote
return ` ${key}="${attrValue}"`;
}

// Smart Quote
if (attrValue.includes('"')) {
return ` ${key}='${attrValue}'`;
}

return ` ${key}="${attrValue}"`;
}

/**
* HTML Stringifier
*
Expand All @@ -129,10 +154,10 @@ function render(tree, options) {
traverse(tree, node => {
// Undefined, null, '', [], NaN
if (node === undefined ||
node === null ||
node === false ||
node.length === 0 ||
Number.isNaN(node)) {
node === null ||
node === false ||
node.length === 0 ||
Number.isNaN(node)) {
return;
}

Expand Down
28 changes: 28 additions & 0 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ const html = render(tree, options)
|**[`closingSingleTag`](#closingSingleTag)**|`{String}`|[`>`](#default)|Specify the single tag closing format|
|**[`quoteAllAttributes`](#quoteAllAttributes)**|`{Boolean}`|[`true`](#default)|Put double quotes around all tags, even when not necessary.|
|**[`replaceQuote`](#replaceQuote)**|`{Boolean}`|[`true`](#default)|Replaces quotes in attribute values with `&quote;`.|
|**[`quoteStyle`](#quoteStyle)**|`{0|1|2}`|[`2`](#default)|Specify the style of quote arround the attribute values|

### `singleTags`

Expand Down Expand Up @@ -200,6 +201,33 @@ Replaces quotes in attribute values with `&quote;`.
<img src="<?php echo $foo["bar"] ?>">
```

### `quoteStyle`

##### `2 (Default)`

Attribute values are wrapped in double quotes:

```html
<img src="https://example.com/example.png" onload="testFunc("test")">
```

##### `1`

Attribute values are wrapped in single quote:

```html
<img src='https://example.com/example.png' onload='testFunc("test")'>
```

##### `0`

Quote style is based on attribute values (an alternative for `replaceQuote` option):

```html
<img src="https://example.com/example.png" onload='testFunc("test")'>
```


[npm]: https://img.shields.io/npm/v/posthtml-render.svg
[npm-url]: https://npmjs.com/package/posthtml-render

Expand Down
32 changes: 32 additions & 0 deletions test/render.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -371,5 +371,37 @@ describe('PostHTML Render', () => {
expect(render(fixture, options)).to.eql(expected);
});
});

describe('quoteStyle', () => {
it('1 - single quote', () => {
const options = {replaceQuote: false, quoteStyle: 1};

const fixture = {tag: 'img', attrs: {src: 'https://example.com/example.png', onload: 'testFunc("test")'}};
const expected = '<img src=\'https://example.com/example.png\' onload=\'testFunc("test")\'>';

fs.writeFileSync('test.html', render(fixture, options));
expect(render(fixture, options)).to.eql(expected);
});

it('2 - double quote', () => {
const options = {replaceQuote: false, quoteStyle: 2};

const fixture = {tag: 'img', attrs: {src: 'https://example.com/example.png', onload: 'testFunc("test")'}};
const expected = '<img src="https://example.com/example.png" onload="testFunc("test")">';

fs.writeFileSync('test.html', render(fixture, options));
expect(render(fixture, options)).to.eql(expected);
});

it('0 - smart quote', () => {
const options = {replaceQuote: false, quoteStyle: 0};

const fixture = {tag: 'img', attrs: {src: 'https://example.com/example.png', onload: 'testFunc("test")'}};
const expected = '<img src="https://example.com/example.png" onload=\'testFunc("test")\'>';

fs.writeFileSync('test.html', render(fixture, options));
expect(render(fixture, options)).to.eql(expected);
});
});
});
});

0 comments on commit 2de7798

Please sign in to comment.