Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@webdiscus/pug-loader

Package Overview
Dependencies
Maintainers
1
Versions
71
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@webdiscus/pug-loader - npm Package Compare versions

Comparing version 2.1.1 to 2.2.0

src/filters/code.js

5

CHANGELOG.md
# Change log
## 2.2.0 (2022-05-15)
- feat: add embedded filters `:code`, `:highlight`
- fix: added `&` and `"` chars in `:escape` filter
## 2.1.1 (2022-05-11)

@@ -4,0 +9,0 @@

12

package.json
{
"name": "@webdiscus/pug-loader",
"version": "2.1.1",
"version": "2.2.0",
"description": "Pug loader resolves paths and webpack aliases in a pug template and compiles it to HTML or into a template function.",

@@ -69,2 +69,3 @@ "keywords": [

"ansis": "^1.3.6",
"parse5": "^7.0.0",
"pug": ">=3.0.2",

@@ -74,5 +75,5 @@ "webpack-merge": "^5.8.0"

"devDependencies": {
"@babel/core": "^7.17.10",
"@babel/preset-env": "^7.17.10",
"@types/jest": "^27.5.0",
"@babel/core": "^7.17.12",
"@babel/preset-env": "^7.17.12",
"@types/jest": "^27.5.1",
"css-loader": "^6.7.1",

@@ -83,3 +84,4 @@ "html-loader": "^3.1.0",

"prettier": "^2.6.2",
"pug-plugin": "^2.3.0",
"prismjs": "^1.28.0",
"pug-plugin": "^2.3.1",
"rimraf": "^3.0.2",

@@ -86,0 +88,0 @@ "tsconfig-paths-webpack-plugin": "^3.5.2",

@@ -43,13 +43,18 @@ <div align="center">

1. [Install and Quick start](#install-and-quick-start)
1. [Options](#options)
1. [Embedded filters](#embed-filters)
1. [Usage method `compile`](#method-compile)
1. [Usage method `render`](#method-render)
1. [Usage method `html`](#method-html)
1. [Passing data into pug template](#passing-data-into-template)
1. [Usage embedded resources](#usage-embedded-resources)
1. [Usage with Angular Component](#usage-with-angular-component)
1. [Recipes](#recipes)
1. [Example "Hello World!"](https://github.com/webdiscus/pug-loader/tree/master/examples/webpack-app-hello-pug/)
1. [More examples](https://github.com/webdiscus/pug-loader/tree/master/test/cases)
2. [Options](#options)
3. [Embedded Pug filters](#embed-filters)
- [:escape](#filter-escape)
- [:code](#filter-code)
- [:highlight](#filter-highlight)
4. [Usage of pug-loader methods](#method-compile)
- [compile](#method-compile)
- [render](#method-render)
- [html](#method-html)
5. [Passing data into pug template](#passing-data-into-template)
6. [Usage embedded resources](#usage-embedded-resources)
7. [Usage with Angular Component](#usage-with-angular-component)
8. [Recipes](#recipes)
9. [Example Hello World!](https://github.com/webdiscus/pug-loader/tree/master/examples/hello-world-app/)
9. [Example of using Pug filters](https://github.com/webdiscus/pug-loader/tree/master/examples/pug-filters)
10. [More examples](https://github.com/webdiscus/pug-loader/tree/master/test/cases)

@@ -66,5 +71,5 @@ <a id="features" name="features" href="#features"></a>

- resolves required images in the attribute `srcset` of `img` tag
- has embedded filters, e.g `:escape`
- resolves required JavaScript modules or JSON in pug
- ignore the prefixes `~` `@` for webpack `resolve.alias`
- embedded Pug filters: `:escape` `:code` `:highlight`
- passing custom data into pug template

@@ -304,3 +309,3 @@ - watching of changes in all dependencies

Enable embedded pug filters.
To enable a filter add to pug-loader options following:
To enable a filter, add the following to the pug-loader options:
```js

@@ -325,15 +330,12 @@ {

> 💡 We have currently only one embedded filter, but other useful filters will occasionally be added.
>
> The goal of the embedded filters is use fast and lightweight filters without additional dependencies in package.json.
> Here we want collect most useful small filters.
> It is like [custom filters](https://pugjs.org/language/filters.html#custom-filters), but already exists in the [filter collection](https://github.com/webdiscus/pug-loader/tree/master/src/filters), that can be simply via an option enabled.
>
> In issues, you can suggest your own filter, and we can add it.
> 💡 The goal of the embedded filters is use fast and lightweight filters without additional dependencies in package.json.
> Here we want to collect most useful small filters.
> It is like [custom filters](https://pugjs.org/langucage/filters.html#custom-filters), but already exists in the [filter collection](https://github.com/webdiscus/pug-loader/tree/master/src/filters), that can be simply via an option enabled.\
> The complete usage cases with more information you can see on the GitHub Page [pug filter examples](https://webdiscus.github.io/pug-loader/) and in the [sources](https://github.com/webdiscus/pug-loader/tree/master/examples/pug-filters) of these examples.
### `escape`
Pug filter: `:escape` Filter options: `none`\
The filter escapes HTML tags to display HTML code in the browser as plain text.
This is useful when using syntax highlighting for code containing HTML tags.
<a id="filter-escape" name="filter-escape" href="#filter-escape"></a>
### `:escape`
The `:escape` filter replaces reserved HTML characters with their corresponding HTML entities to display these characters as text.
Filter options: `none`.

@@ -344,6 +346,11 @@ Enable the filter:

{
embedFilters: {
escape: true,
test: /\.pug$/,
loader: '@webdiscus/pug-loader',
options: {
// enable embedded filters
embedFilters: {
escape: true, // enable the :escape filter
},
},
}
},
```

@@ -353,20 +360,16 @@

```pug
```html
pre: code.language-html
:escape
<!-- HTML -->
<div>
<p>Text</p>
</div>
<h1>Header</h1>
<p>Text</p>
```
Generates plain text:
Generated HTML:
```
```html
<pre>
<code class="language-html">
&lt;!-- HTML --&gt;
&lt;div&gt;
&lt;p&gt;Text&lt;/p&gt;
&lt;/div&gt;
&lt;h1&gt;Header&lt;/h1&gt;
&lt;p&gt;Text&lt;/p&gt;
</code>

@@ -376,32 +379,74 @@ </pre>

Display in browser:
Inline syntax:
```html
p.
The #[:escape <html>] element is the root element.<br>
Inside the #[:escape <html>] element there is a #[:escape <body>] element.
```
Generated HTML:
```html
<!-- HTML -->
<div>
<p>Text</p>
</div>
<p>The &lt;html&gt; element is the root element.<br>
Inside the &lt;html&gt; element there is a &lt;body&gt; element.</p>
```
Inline syntax:
> For more examples and info, see [pug filter :escape](https://webdiscus.github.io/pug-loader/escape.html).
<a id="filter-code" name="filter-code" href="#filter-code"></a>
### `:code`
The `:code` filter wraps a content with the `<code>` tag.
Filter options:
- `className {string}` The class name of the `code` tag. For example, the `prismjs` use the `language-*` as class name in `<code>` for styling this tag.
Enable the filter:
```js
{
test: /\.pug$/,
loader: '@webdiscus/pug-loader',
options: {
// enable embedded filters
embedFilters: {
// enable the :code filter
code: {
className: 'language-', // class name of `<code>` tag, needed for `prismjs` theme
},
},
},
},
```
p
:escape The <strong> element has the closing </strong> tag.
p.
The #[:escape <html>] element is the root element.<br>
Inside the #[:escape <html>] element there is a #[:escape <body>] element.
> For more examples and info, see [pug filter :code](https://webdiscus.github.io/pug-loader/code.html).
<a id="filter-highlight" name="filter-highlight" href="#filter-highlight"></a>
### `:highlight`
The `:highlight` filter highlights code syntax.
Filter options:
- `verbose {boolean}` Enable output process info in console.
- `use {string}]` The name of a highlighting npm module. The module must be installed. Currently, is supported the [prismjs](https://prismjs.com) only.
Enable the filter:
```js
{
embedFilters: {
highlight: {
verbose: true,
use: 'prismjs',
},
},
}
```
Generates plain text:
Usage example:
```pug
pre.language-: code
:highlight(html)
<!-- Comment -->
<h1>Header</h1>
<p>Text</p>
```
<p>
The &lt;strong&gt; element has the closing &lt;/strong&gt; tag.
</p>
<p>
The &lt;html&gt; element is the root element.
<br>
Inside the &lt;html&gt; element there is a &lt;body&gt; element.
</p>
```
> For more examples and info, see [pug filter :highlight](https://webdiscus.github.io/pug-loader/highlight.html).

@@ -408,0 +453,0 @@ <a id="method-compile" name="method-compile" href="#method-compile"></a>

@@ -20,3 +20,3 @@ const ansis = require('ansis');

*/
const PugLoaderError = function(message, error = '') {
const PugLoaderError = function (message, error = '') {
if (error && error instanceof PugLoaderException) {

@@ -43,5 +43,4 @@ if (error.toString() === lastError) {

const message =
`${ansisLoaderName} the file ${ansis.yellow(
file,
)} can't be resolved in the pug template:\n` + ansis.cyan(templateFile);
`${ansisLoaderName} the file ${ansis.yellow(file)} can't be resolved in the pug template:\n` +
ansis.cyan(templateFile);

@@ -59,6 +58,6 @@ PugLoaderError(message, error);

`${ansisLoaderName} the expression ${ansis.yellow(
value,
value
)} can't be interpolated with the 'compile' method in the pug template: ${ansis.cyan(templateFile)}\n` +
`${ansis.yellow(
'Possible solution: ',
'Possible solution: '
)} Try to use the loader option 'method' as 'render' or change your dynamic filename to static or use webpack alias instead of alias from tsconfig.`;

@@ -82,3 +81,3 @@

`then pass it into pug ${ansis.magenta(
`'template.pug?customData=' + JSON.stringify({options:{title:'My title'}})`,
`'template.pug?customData=' + JSON.stringify({options:{title:'My title'}})`
)}`;

@@ -95,4 +94,4 @@

const filterNotFoundException = (filterName, availableFilters) => {
const message = `${ansisLoaderName} The 'embedFilters' option contains unknown filter name: ${ansis.red(
filterName)}.\n` +
const message =
`${ansisLoaderName} The 'embedFilters' option contains unknown filter: ${ansis.red(filterName)}.\n` +
`Available embedded filters: ${ansis.green(availableFilters)}.`;

@@ -104,2 +103,26 @@

/**
* @param {string} filterName
* @param {string} filterPath
* @param {Error} error
*/
const filterLoadException = (filterName, filterPath, error) => {
const message =
`${ansisLoaderName} Error by load the ${ansis.red(filterName)} filter.\n` +
`Filter file: ${ansis.cyan(filterPath)}\n` +
error;
PugLoaderError(message);
};
/**
* @param {string} filterName
* @param {Error} error
*/
const filterInitException = (filterName, error) => {
const message = `${ansisLoaderName} Error by initialisation the ${ansis.red(filterName)} filter.\n` + error;
PugLoaderError(message);
};
/**
* @param {string} error

@@ -117,4 +140,6 @@ * @returns {string}

executeTemplateFunctionException,
getPugCompileErrorMessage,
filterNotFoundException,
getPugCompileErrorMessage,
filterLoadException,
filterInitException,
};
/**
* The filter `:escape` escapes HTML tags in pug.
* The `:escape` filter replaces reserved HTML characters with their corresponding HTML entities.
* @see https://developer.mozilla.org/en-US/docs/Glossary/Entity
*
* Note: the filename w/o ext is the filter name.
* Block syntax:
*
* Usage:
* pre: code
* :escape
* <div>
* <a href="home.html">Home</a>
* </div>
*
* pre: code
* :escape
* <a href="home.html">Home</a>
* Inline syntax:
*
* The #[:escape <div>] tag.
*/
// Add the filter `escape` in the options of pug loader:
// To enable the filter add to `@webdiscus/pug-loader` options the following:
// {

@@ -24,4 +29,18 @@ // test: /\.pug$/,

module.exports = function escape(text, options) {
return text.replace(/</g, '&lt;').replace(/>/g, '&gt;');
const reservedChars = /[&<>"]/g;
const charReplacements = {
'&': '&amp;',
'<': '&lt;',
'>': '&gt;',
'"': '&quot;',
};
const escape = {
name: 'escape',
apply(text, options) {
return text.replace(reservedChars, (char) => charReplacements[char]);
},
};
module.exports = escape;

@@ -11,3 +11,8 @@ // add polyfill for node.js >= 12.0.0 && < 15.0.0

const loader = require('./loader');
const { filterNotFoundException, getPugCompileErrorMessage } = require('./exeptions');
const {
filterNotFoundException,
filterLoadException,
filterInitException,
getPugCompileErrorMessage,
} = require('./exeptions');

@@ -71,2 +76,38 @@ // path of embedded pug-loader filters

/**
* Load embedded pug filters.
* @param {{filterName: string, options: boolean|string|object}} filters
*/
const loadFilters = (filters) => {
for (const filterName in filters) {
const options = filters[filterName];
if (options) {
let filterPath = path.resolve(filtersDir, filterName + '.js');
let filter;
try {
filter = require(filterPath);
} catch (error) {
if (error.toString().indexOf('Cannot find module') >= 0) {
const entries = fs.readdirSync(filtersDir, { withFileTypes: true });
const files = entries.filter((file) => !file.isDirectory()).map((file) => path.basename(file.name, '.js'));
filterNotFoundException(filterName, files.join(', '));
}
filterLoadException(filterName, filterPath, error);
}
try {
// filter module may have the `init(options)` method
if (filter.init != null) {
filter.init(options);
}
// add filter to pug compiler
pug.filters[filterName] = filter.apply.bind(filter);
} catch (error) {
filterInitException(filterName, error);
}
}
}
};
/**
* @param {string} content The pug template.

@@ -76,3 +117,3 @@ * @param {function(error: string|null, result: string?)?} callback The asynchronous callback function.

*/
const compile = function(content, callback) {
const compile = function (content, callback) {
const loaderContext = this;

@@ -85,22 +126,4 @@ const loaderOptions = loaderContext.getOptions() || {};

if (!loaderOptions.name) loaderOptions.name = 'template';
if (loaderOptions.embedFilters) loadFilters(loaderOptions.embedFilters);
// embedded pug-loader filters
if (loaderOptions.embedFilters) {
for (const filterName in loaderOptions.embedFilters) {
const filterOptions = loaderOptions.embedFilters[filterName];
// TODO: if filterOptions is a object then add it to loaderOptions.filterOptions by filterName
if (filterOptions) {
let filterPath = path.resolve(filtersDir, filterName + '.js');
try {
pug.filters[filterName] = require(filterPath);
} catch (error) {
const entries = fs.readdirSync(filtersDir, { withFileTypes: true });
const files = entries.filter((file) => !file.isDirectory()).map((file) => path.basename(file.name, '.js'));
filterNotFoundException(filterName, files.join(', '));
}
}
}
}
const compilerOptions = {

@@ -168,3 +191,2 @@ // used to resolve import/extends and to improve errors

compileResult = pug.compileClientWithDependenciesTracked(content, compilerOptions);
} catch (error) {

@@ -203,3 +225,3 @@ // watch files in which an error occurred

const pluginData = plugins.find(
(item) => item.constructor.name === 'HtmlWebpackPlugin' && item.options.template.indexOf(filename) >= 0,
(item) => item.constructor.name === 'HtmlWebpackPlugin' && item.options.template.indexOf(filename) >= 0
);

@@ -219,3 +241,3 @@

module.exports = function(content, map, meta) {
module.exports = function (content, map, meta) {
const callback = this.async();

@@ -222,0 +244,0 @@

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc