Repository: haoxins/gulp-file-include
Branch: main
Commit: d444c9bcf6e9
Files: 101
Total size: 63.5 KB
Directory structure:
gitextract_ccu95132/
├── .editorconfig
├── .gitignore
├── .npmrc
├── .travis.yml
├── LICENSE
├── Readme.md
├── example/
│ ├── a/
│ │ ├── a1.txt
│ │ └── a2.txt
│ ├── b/
│ │ ├── b1.txt
│ │ └── b2.txt
│ ├── c/
│ │ └── c.txt
│ ├── conditional.txt
│ ├── gulpfile.js
│ ├── index.txt
│ └── result/
│ └── index.txt
├── lib/
│ ├── indent.js
│ ├── index.js
│ ├── replace-function.js
│ ├── replace-operator.js
│ └── replace-variable.js
├── package.json
└── test/
├── .editorconfig
├── edge-case.js
├── error.js
├── filters.js
├── fixtures/
│ ├── arr-result.html
│ ├── arr.html
│ ├── index-01.html
│ ├── index-02.html
│ ├── index-03.html
│ ├── index-04.js
│ ├── index-05.html
│ ├── index-handler-options.html
│ ├── index-markdown-rot13.html
│ ├── index-markdown.html
│ ├── result.html
│ ├── result.js
│ ├── sameprefix-result.html
│ ├── sameprefix-var.html
│ ├── sameprefix.html
│ ├── var.html
│ ├── var.rot13.html
│ ├── view.html
│ ├── view.md
│ └── view.rot13.md
├── fixtures-edge-case/
│ ├── a.html
│ ├── b.html
│ ├── commented-inclusion-result.html
│ ├── commented-inclusion.html
│ ├── dangerous.txt
│ ├── index.html
│ ├── recursion.html
│ ├── result.html
│ ├── without-trailing-newline-result.txt
│ └── without-trailing-newline.txt
├── fixtures-error/
│ ├── for.html
│ └── if.html
├── fixtures-flatten/
│ ├── index.html
│ └── result.html
├── fixtures-indent/
│ ├── index.html
│ ├── result.html
│ ├── sub-sub.html
│ └── sub.html
├── fixtures-nested/
│ ├── index.html
│ ├── result.html
│ └── var.html
├── fixtures-nested-once/
│ ├── index-twice.html
│ ├── index.html
│ ├── result-twice.html
│ ├── result.html
│ └── var.html
├── fixtures-operator/
│ ├── index.html
│ ├── result-index.html
│ ├── result-suffix.html
│ └── suffix.html
├── fixtures-recursion/
│ ├── index.txt
│ ├── result.txt
│ ├── sub/
│ │ ├── a.txt
│ │ └── b.txt
│ └── var.txt
├── fixtures-suffix/
│ ├── index.html
│ └── var.html
├── fixtures-variable/
│ ├── index-suffix.html
│ ├── index.html
│ └── result.html
├── fixtures-webroot-variable/
│ ├── html-head.html
│ ├── index.html
│ ├── result.html
│ └── sub/
│ ├── home-link.html
│ ├── index.html
│ └── result.html
├── flatten.js
├── indent.js
├── index.js
├── nested-once.js
├── nested.js
├── operator.js
├── plugin-indent.js
├── recursion.js
├── variable.js
└── webroot-variable.js
================================================
FILE CONTENTS
================================================
================================================
FILE: .editorconfig
================================================
root = true
[*.{html,js}]
indent_style = space
indent_size = 2
end_of_line = lf
charset = utf-8
trim_trailing_whitespace = true
================================================
FILE: .gitignore
================================================
package-lock.json
npm-debug.log
node_modules/
.DS_Store
coverage/
================================================
FILE: .npmrc
================================================
package-lock=false
================================================
FILE: .travis.yml
================================================
language: node_js
node_js:
- 16
script: "npm run test-travis"
after_script: "npm install coveralls@2 && cat ./coverage/lcov.info | coveralls"
================================================
FILE: LICENSE
================================================
MIT License
Copyright (c) 2020 Xin Hao
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
================================================
FILE: Readme.md
================================================
[![NPM version][npm-img]][npm-url]
[![Build status][travis-img]][travis-url]
[![Test coverage][coveralls-img]][coveralls-url]
[![License][license-img]][license-url]
[![Dependency status][david-img]][david-url]
[![Gitter][gitter-img]][gitter-url]
# gulp-file-include
a [gulp](https://github.com/gulpjs/gulp) plugin for file includes
## Installation
```bash
npm install --save-dev gulp-file-include
```
## API
```js
const fileinclude = require('gulp-file-include');
```
### fileinclude([prefix])
#### prefix
Type: `string`<br>
Default: `'@@'`
### fileinclude([options])
#### options
Type: `object`
##### options.prefix
Type: `string`<br>
Default: `'@@'`
##### options.suffix
Type: `string`<br>
Default: `''`
##### options.basepath
Type: `string`<br>
Default: `'@file'`
Possible values:
- `'@file'`: include file relative to the dir in which `file` resides ([example](#include-options---type-json))
- `'@root'`: include file relative to the dir in which `gulp` is running
- `path/to/dir`: include file relative to the basepath you provide
##### options.filters
Type: `object`<br>
Default: `false`
Filters of include content.
##### options.context
Type: `object`
Default: `{}`
Context of `if` statement.
##### options.indent
Type: `boolean`
Default: `false`
## Examples
### @@include options - type: `JSON`
index.html
```html
<!DOCTYPE html>
<html>
<body>
@@include('./view.html')
@@include('./var.html', {
"name": "haoxin",
"age": 12345,
"socials": {
"fb": "facebook.com/include",
"tw": "twitter.com/include"
}
})
</body>
</html>
```
view.html
```html
<h1>view</h1>
```
var.html
```html
<label>@@name</label>
<label>@@age</label>
<strong>@@socials.fb</strong>
<strong>@@socials.tw</strong>
```
gulpfile.js
```js
const fileinclude = require('gulp-file-include');
const gulp = require('gulp');
gulp.task('fileinclude', function() {
gulp.src(['index.html'])
.pipe(fileinclude({
prefix: '@@',
basepath: '@file'
}))
.pipe(gulp.dest('./'));
});
```
result:
```html
<!DOCTYPE html>
<html>
<body>
<h1>view</h1>
<label>haoxin</label>
<label>12345</label>
<strong>facebook.com/include</strong>
<strong>twitter.com/include</strong>
</body>
</html>
```
### @@include_once options - type: `JSON`
index.html
```html
<!DOCTYPE html>
<html>
<body>
@@include_once('./view.html')
@@include_once('./var.html', {
"name": "haoxin",
"age": 12345,
"socials": {
"fb": "facebook.com/include",
"tw": "twitter.com/include"
}
})
@@include_once('./var.html', {
"name": "haoxin",
"age": 12345,
"socials": {
"fb": "facebook.com/include",
"tw": "twitter.com/include"
}
})
</body>
</html>
```
view.html
```html
<h1>view</h1>
```
var.html
```html
<label>@@name</label>
<label>@@age</label>
<strong>@@socials.fb</strong>
<strong>@@socials.tw</strong>
```
gulpfile.js
```js
const fileinclude = require('gulp-file-include');
const gulp = require('gulp');
gulp.task('fileinclude', function() {
gulp.src(['index.html'])
.pipe(fileinclude({
prefix: '@@',
basepath: '@file'
}))
.pipe(gulp.dest('./'));
});
```
result:
```html
<!DOCTYPE html>
<html>
<body>
<h1>view</h1>
<label>haoxin</label>
<label>12345</label>
<strong>facebook.com/include</strong>
<strong>twitter.com/include</strong>
</body>
</html>
```
### filters
index.html
```html
<!DOCTYPE html>
<html>
<body>
@@include(markdown('view.md'))
@@include('./var.html', {
"name": "haoxin",
"age": 12345
})
</body>
</html>
```
view.md
```html
view
====
```
gulpfile.js
```js
const fileinclude = require('gulp-file-include');
const markdown = require('markdown');
const gulp = require('gulp');
gulp.task('fileinclude', function() {
gulp.src(['index.html'])
.pipe(fileinclude({
filters: {
markdown: markdown.parse
}
}))
.pipe(gulp.dest('./'));
});
```
### `if` statement
index.html
```
@@include('some.html', { "nav": true })
@@if (name === 'test' && nav === true) {
@@include('test.html')
}
```
gulpfile.js
```js
fileinclude({
context: {
name: 'test'
}
});
```
### `for` statement
index.html
```html
<ul>
@@for (var i = 0; i < arr.length; i++) {
<li>`+arr[i]+`</li>
}
</ul>
```
gulpfile.js
```js
fileinclude({
context: {
arr: ['test1', 'test2']
}
});
```
### `loop` statement
index.html
```html
<body>
@@loop('loop-article.html', [
{ "title": "My post title", "text": "<p>lorem ipsum...</p>" },
{ "title": "Another post", "text": "<p>lorem ipsum...</p>" },
{ "title": "One more post", "text": "<p>lorem ipsum...</p>" }
])
</body>
```
loop-article.html
```html
<article>
<h1>@@title</h1>
@@text
</article>
```
### `loop` statement + `data.json`
data.json
```js
[
{ "title": "My post title", "text": "<p>lorem ipsum...</p>" },
{ "title": "Another post", "text": "<p>lorem ipsum...</p>" },
{ "title": "One more post", "text": "<p>lorem ipsum...</p>" }
]
```
loop-article.html
```html
<body>
@@loop("loop-article.html", "data.json")
</body>
```
### `webRoot` built-in context variable
The `webRoot` field of the context contains the relative path from the source document to
the source root (unless the value is already set in the context options).
support/contact/index.html
```html
<!DOCTYPE html>
<html>
<head>
<link type=stylesheet src=@@webRoot/css/style.css>
</head>
<body>
<h1>Support Contact Info</h1>
<footer><a href=@@webRoot>Home</a></footer>
</body>
</body>
</html>
```
result:
```html
<!DOCTYPE html>
<html>
<head>
<link type=stylesheet src=../../css/style.css>
</head>
<body>
<h1>Support Contact Info</h1>
<footer><a href=../..>Home</a></footer>
</body>
</body>
</html>
```
### License
MIT
[npm-img]: https://img.shields.io/npm/v/gulp-file-include.svg?style=flat-square
[npm-url]: https://npmjs.org/package/gulp-file-include
[travis-img]: https://img.shields.io/travis/haoxins/gulp-file-include.svg?style=flat-square
[travis-url]: https://travis-ci.org/haoxins/gulp-file-include
[coveralls-img]: https://img.shields.io/coveralls/coderhaoxin/gulp-file-include.svg?style=flat-square
[coveralls-url]: https://coveralls.io/r/coderhaoxin/gulp-file-include?branch=master
[license-img]: http://img.shields.io/badge/license-MIT-green.svg?style=flat-square
[license-url]: http://opensource.org/licenses/MIT
[david-img]: https://img.shields.io/david/coderhaoxin/gulp-file-include.svg?style=flat-square
[david-url]: https://david-dm.org/coderhaoxin/gulp-file-include
[gitter-img]: https://badges.gitter.im/Join%20Chat.svg
[gitter-url]: https://gitter.im/coderhaoxin/gulp-file-include?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge
================================================
FILE: example/a/a1.txt
================================================
this is a1
// include a2
@@include('./a2.txt')
================================================
FILE: example/a/a2.txt
================================================
this is a2
// include b1
@@include('../b/b1.txt')
================================================
FILE: example/b/b1.txt
================================================
this is b1
// include b2
@@include('./b2.txt')
================================================
FILE: example/b/b2.txt
================================================
this is b2
================================================
FILE: example/c/c.txt
================================================
this is loop @@number
================================================
FILE: example/conditional.txt
================================================
this is conditional
Flatten object "@@obj"
@@if(typeof context.obj === 'object') {
Flatten variable "@@obj.obj_param"
}
Defined in parent "@@param"
Context variable "@@name"
================================================
FILE: example/gulpfile.js
================================================
'use strict'
const fileinclude = require('..')
const gulp = require('gulp')
gulp.task('include', () => {
gulp.src(['index.txt'])
.pipe(fileinclude({
prefix: '@@',
basepath: '@file',
context: {
name: 'example'
}
}))
.pipe(gulp.dest('./result'))
})
================================================
FILE: example/index.txt
================================================
index
@@include('a/a1.txt')
@@name
@@if (context.name === 'example') {
@@include('conditional.txt', {
"param": "success",
"obj": {
"obj_param": "flatten param"
}
})
@@include('conditional.txt', {
"param": "success too"
})
Defined in include @@param
}
@@loop('c/c.txt', [
{ "number": 1 },
{ "number": 2 },
{ "number": 3 }
])
================================================
FILE: example/result/index.txt
================================================
index
this is a1
// include a2
this is a2
// include b1
this is b1
// include b2
this is b2
example
this is conditional
Flatten object "@@obj"
Flatten variable "flatten param"
Defined in parent "success"
Context variable "example"
this is conditional
Flatten object "@@obj"
Defined in parent "success too"
Context variable "example"
Defined in include @@param
this is loop 1this is loop 2this is loop 3
================================================
FILE: lib/indent.js
================================================
module.exports = function(src, index, dest) {
var indent = ''
var valid = false
while (src[index -= 1] == 0) { // eslint-disable-line
if (src[index] === '\n') {
valid = true
break
}
indent = src[index] + indent
}
if (valid) {
dest = dest.split('\n').map(function(str, i) {
return str == 0 || i === 0 ? str : (indent + str) // eslint-disable-line
}).join('\n')
}
return dest
}
================================================
FILE: lib/index.js
================================================
'use strict'
const replaceOperator = require('./replace-operator')
const replaceFunction = require('./replace-function')
const replaceVariable = require('./replace-variable')
const concat = require('concat-stream')
const setIndent = require('./indent')
const through = require('through2')
const Vinyl = require('vinyl')
const PluginError = require('plugin-error')
const extend = require('extend')
const path = require('path')
const fs = require('fs')
const JSON5 = require('json5')
module.exports = function(opts) {
if (typeof opts === 'string') {
opts = {prefix: opts}
}
opts = extend({}, {
basepath: '@file',
prefix: '@@',
suffix: '',
context: {},
filters: false,
indent: false
}, opts)
if (opts.basepath !== '@file') {
opts.basepath = opts.basepath === '@root' ? process.cwd() : path.resolve(opts.basepath)
}
var customWebRoot = !!opts.context.webRoot
var includeOnceFiles = {};
function fileInclude(file, enc, cb) {
if (!customWebRoot) {
// built-in webRoot variable, example usage: <link rel=stylesheet href=@@webRoot/style.css>
opts.context.webRoot =
path.relative(path.dirname(file.path), file.base).replace(/\\/g, '/') || '.'
}
if (file.isNull()) {
cb(null, file)
} else if (file.isStream()) {
file.contents.pipe(concat(function(data) {
try {
data = include(file, String(data))
cb(null, data)
} catch (e) {
cb(new PluginError('gulp-file-include', e.message))
}
}))
} else if (file.isBuffer()) {
try {
file = include(file, String(file.contents))
cb(null, file)
} catch (e) {
cb(new PluginError('gulp-file-include', e.message))
}
}
}
return through.obj(fileInclude)
/**
* utils
*/
function stripCommentedIncludes(content, opts) {
// remove single line html comments that use the format: <!-- @@include() -->
var regex = new RegExp('<!--(.*)' + opts.prefix + '[ ]*include([\\s\\S]*?)[ ]*' + opts.suffix + '-->', 'g')
return content.replace(regex, '')
}
function include(file, text, data, sourceFile = '') {
var filebase = opts.basepath === '@file' ? path.dirname(file.path) : opts.basepath
var currentFilename = path.resolve(file.base, file.path)
data = extend(true, {}, opts.context, data || {})
data.content = text
text = stripCommentedIncludes(text, opts)
text = replaceOperator(text, {
prefix: opts.prefix,
suffix: opts.suffix,
name: 'if',
handler: conditionalHandler,
sourceFile: sourceFile
})
text = replaceOperator(text, {
prefix: opts.prefix,
suffix: opts.suffix,
name: 'for',
handler: forHandler,
sourceFile: sourceFile
})
text = replaceVariable(text, data, opts)
text = replaceFunction(text, {
prefix: opts.prefix,
suffix: opts.suffix,
name: 'include_once',
handler: includeOnceHandler,
sourceFile: sourceFile
})
text = replaceFunction(text, {
prefix: opts.prefix,
suffix: opts.suffix,
name: 'include',
handler: includeHandler,
sourceFile: sourceFile
})
text = replaceFunction(text, {
prefix: opts.prefix,
suffix: opts.suffix,
name: 'loop',
handler: loopHandler,
sourceFile: sourceFile
})
function conditionalHandler(inst) {
try {
var condition = new Function('var context = this; with (context) { return ' + inst.args + '; }').call(data) // eslint-disable-line
} catch (error) {
throw new Error(error.message + ': ' + inst.args)
}
return condition ? inst.body : ''
}
function forHandler(inst) {
var forLoop = 'for' + inst.args + ' { result+=`' + inst.body + '`; }'
var condition = 'var context = this; with (context) { var result=""; ' + forLoop + ' return result; }'
try {
var result = new Function(condition).call(data) // eslint-disable-line
} catch (error) {
throw new Error(error.message + ': ' + forLoop)
}
return result
}
function includeOnceHandler(inst) {
var args = /[^)"']*["']([^"']*)["'](,\s*({[\s\S]*})){0,1}\s*/.exec(inst.args)
if (args) {
if (typeof includeOnceFiles[inst.sourceFile] === 'undefined') {
includeOnceFiles[inst.sourceFile] = [];
}
if (includeOnceFiles[inst.sourceFile].indexOf(args[1]) === -1) {
includeOnceFiles[inst.sourceFile].push(args[1]);
return includeHandler(inst)
} else {
return '';
}
}
}
function includeHandler(inst) {
var args = /[^)"']*["']([^"']*)["'](,\s*({[\s\S]*})){0,1}\s*/.exec(inst.args)
if (args) {
var includePath = path.resolve(filebase, args[1])
// for checking if we are not including the current file again
if (currentFilename.toLowerCase() === includePath.toLowerCase()) {
throw new Error('recursion detected in file: ' + currentFilename)
}
var includeContent = fs.readFileSync(includePath, 'utf-8')
if (opts.indent) {
includeContent = setIndent(inst.before, inst.before.length, includeContent)
}
// need to double each `$` to escape it in the `replace` function
// includeContent = includeContent.replace(/\$/gi, '$$$$');
// apply filters on include content
if (typeof opts.filters === 'object') {
includeContent = applyFilters(includeContent, args.input)
}
var recFile = new Vinyl({
cwd: process.cwd(),
base: file.base,
path: includePath,
contents: Buffer.from(includeContent)
})
recFile = include(recFile, includeContent, args[3] ? JSON5.parse(args[3]) : {}, inst.sourceFile != '' ? inst.sourceFile : currentFilename)
return String(recFile.contents)
}
}
function loopHandler(inst) {
var args = /[^)"']*["']([^"']*)["'](,\s*([\s\S]*())){0,1}\s*/.exec(inst.args)
var arr = []
if (args) {
// loop array in the json file
if (args[3].match(/^('|")[^']|[^"]('|")$/)) {
// clean filename var and define path
var jsonPath = args[3].replace(/^('|")/, '').replace(/('|")$/, '')
var jsonfile = path.join(file.base, jsonPath)
// check if json file exists
if (fs.existsSync(jsonfile)) {
// make sure we are getting the updated version of the json file
delete require.cache[jsonfile]
arr = require(jsonfile)
} else {
return console.error('JSON file not exists:', jsonfile)
}
} else {
// loop array in the function
try {
arr = JSON5.parse(args[3])
} catch (err) {
return console.error(err, args[3])
}
}
if (arr) {
var includePath = path.resolve(filebase, args[1])
// for checking if we are not including the current file again
if (currentFilename.toLowerCase() === includePath.toLowerCase()) {
throw new Error('recursion detected in file: ' + currentFilename)
}
var includeContent = fs.readFileSync(includePath, 'utf-8')
if (opts.indent) {
includeContent = setIndent(inst.before, inst.before.length, includeContent)
}
// apply filters on include content
if (typeof opts.filters === 'object') {
includeContent = applyFilters(includeContent, args.input)
}
var recFile = new Vinyl({
cwd: process.cwd(),
base: file.base,
path: includePath,
contents: Buffer.from(includeContent)
})
var contents = ''
for (var i in arr) {
if (arr.hasOwnProperty(i)) {
var context = arr[i]
recFile = include(recFile, includeContent, args[3] ? context : {}, inst.sourceFile != '' ? inst.sourceFile : currentFilename)
// why handler dont reconize underscore?
// if (typeof context == 'object' && typeof context['_key'] == 'undefined') {
// context['_key'] = i;
// }
contents += String(recFile.contents)
}
}
}
return contents
}
}
file.contents = Buffer.from(text)
return file
}
function applyFilters(includeContent, match) {
if (!match.match(/\)+$/)) {
// nothing to filter return unchanged
return includeContent
}
// now get the ordered list of filters
var filterlist = match.split('(').slice(0, -1)
filterlist = filterlist.map(function(str) {
return opts.filters[str.trim()]
})
// compose them together into one function
var filter = filterlist.reduce(compose)
// check match for filter options object
var options = match.match('{([^}]*)}')
// and apply the composed function to the stringified content
if (options) {
options = JSON5.parse(options[0])
return filter(String(includeContent), options)
} else {
return filter(String(includeContent))
}
}
}
function compose(f, g) {
return function(x) {
return f(g(x))
}
}
================================================
FILE: lib/replace-function.js
================================================
'use strict'
const balanced = require('balanced-match')
module.exports = function(content, opts) {
var result = ''
var reStart = new RegExp(opts.prefix + '[ ]*' + opts.name + '\\(')
var reEnd = new RegExp('^[ ]*' + opts.suffix)
var matchStart
var matchArg
var matchEnd
var safeStart
var before
var replacement
while (matchStart = reStart.exec(content)) { // eslint-disable-line
safeStart = matchStart.index + matchStart[0].length - 1
matchArg = balanced('(', ')', content.slice(safeStart))
if (matchArg && matchArg.start === 0) {
if (opts.suffix) {
matchEnd = reEnd.exec(matchArg.post)
}
matchEnd = matchEnd ? matchEnd.index + matchEnd[0].length : 0
if (!opts.suffix || matchEnd) {
before = content.slice(0, matchStart.index)
replacement = opts.handler({
before: before,
args: matchArg.body,
sourceFile: opts.sourceFile
})
if (replacement !== undefined) {
result += before + replacement.toString()
content = content.slice(safeStart + matchArg.end + 1 + matchEnd)
continue
}
}
}
result += content.slice(0, safeStart)
content = content.slice(safeStart)
}
result += content
return result
}
================================================
FILE: lib/replace-operator.js
================================================
'use strict'
const balanced = require('balanced-match')
module.exports = function parse(content, opts) {
var regexpStart = new RegExp(opts.prefix + '[ ]*' + opts.name + '([^{}]*)\\{')
var regexpEnd = opts.suffix ? new RegExp('^\\s*' + opts.suffix) : false
var replacement
var result = ''
var matchStart
var matchBody
var matchEnd
var startEnd
var before
while (matchStart = regexpStart.exec(content)) { // eslint-disable-line
startEnd = matchStart.index + matchStart[0].length
matchBody = balanced('{', '}', content.slice(startEnd - 1))
if (matchBody && matchBody.start === 0) {
matchEnd = regexpEnd ? regexpEnd.exec(matchBody.post) : true
if (matchEnd) {
before = content.slice(0, matchStart.index)
matchEnd = regexpEnd ? matchEnd[0].length : 0
replacement = opts.handler({
before: before,
args: matchStart[1],
body: matchBody.body
})
if (replacement !== undefined) {
result += before + parse(replacement.toString(), opts)
content = content.slice(startEnd + matchBody.end + matchEnd)
continue
}
}
}
result += content.slice(0, startEnd)
content = content.slice(startEnd)
}
result += content
return result
}
================================================
FILE: lib/replace-variable.js
================================================
'use strict'
const flatten = require('flatnest').flatten
module.exports = function(content, data, opts) {
var prefix = opts.prefix + '[ ]*'
var suffix = opts.suffix ? '[ ]*' + opts.suffix : ''
data = flatten(data)
// sort keys by longest keys to iterate in that order
var keys = Object.keys(data).sort()
var i = keys.length - 1
var key
for (; ~i; i -= 1) {
key = keys[i]
content = content.replace(new RegExp(prefix + key + suffix, 'g'), data[key])
}
return content
}
================================================
FILE: package.json
================================================
{
"name": "gulp-file-include",
"version": "2.3.0",
"description": "A gulp plugin for file include",
"main": "lib/index.js",
"scripts": {
"lint": "eslint lib test/*.js --fix",
"test": "mocha -R spec -t 200 test/*.js",
"test-cov": "istanbul cover node_modules/.bin/_mocha -- -R dot -t 200 test/*.js",
"test-travis": "istanbul cover node_modules/.bin/_mocha --report lcovonly -- -R dot -t 200 test/*.js"
},
"repository": "haoxins/gulp-file-include",
"keywords": [
"gulpplugin",
"file",
"include",
"replace",
"gulp",
"plugin"
],
"files": [
"lib"
],
"author": "haoxin",
"contributors": [
"Bogdan Chadkin <trysound@yandex.ru>",
"Arthur Araújo <webarthur@gmail.com>"
],
"license": "MIT",
"dependencies": {
"balanced-match": "^1.0.0",
"concat-stream": "^2.0.0",
"extend": "^3.0.2",
"flatnest": "^1.0.0",
"json5": "^2.1.3",
"plugin-error": "^1.0.1",
"through2": "^4.0.2",
"vinyl": "^2.2.1"
},
"devDependencies": {
"eslint-config-ok": "github:haoxins/eslint-config",
"gulp": "^4.0.2",
"istanbul": "^0.4.5",
"markdown": "^0.5.0",
"mocha": "^8.2.1",
"should": "^13.2.3"
},
"eslintConfig": {
"extends": [
"ok"
]
}
}
================================================
FILE: test/.editorconfig
================================================
[*]
insert_final_newline = false
================================================
FILE: test/edge-case.js
================================================
'use strict'
const fileIncludePlugin = require('..')
const Vinyl = require('vinyl')
const should = require('should')
const fs = require('fs')
describe('## gulp-file-include', () => {
describe('# edge cases', () => {
it('should escape included content to avoid recursive includes', done => {
var file = new Vinyl({
path: 'test/fixtures-edge-case/index.html',
contents: fs.createReadStream('test/fixtures-edge-case/index.html')
})
var expected = fs.readFileSync('test/fixtures-edge-case/result.html', 'utf8')
var stream = fileIncludePlugin()
stream.on('data', newFile => {
should.exist(newFile)
should.exist(newFile.contents)
String(newFile.contents).should.equal(expected)
done()
})
stream.write(file)
stream.end()
})
it('should work without trailing newline', done => {
var file = new Vinyl({
path: 'test/fixtures-edge-case/without-trailing-newline.txt',
contents: fs.createReadStream('test/fixtures-edge-case/without-trailing-newline.txt')
})
var expected = fs.readFileSync('test/fixtures-edge-case/without-trailing-newline-result.txt', 'utf8')
var stream = fileIncludePlugin()
stream.on('data', function(newFile) {
should.exist(newFile)
should.exist(newFile.contents)
String(newFile.contents).should.equal(expected)
done()
})
stream.write(file)
stream.end()
})
it('should skip commented includes', done => {
var file = new Vinyl({
path: 'test/fixtures-edge-case/commented-inclusion.html',
contents: fs.createReadStream('test/fixtures-edge-case/commented-inclusion.html')
})
var expected = fs.readFileSync('test/fixtures-edge-case/commented-inclusion-result.html', 'utf8').replace(/\s/g, '')
var stream = fileIncludePlugin()
stream.on('data', newFile => {
var inputString = String(newFile.contents).replace(/\s/g, '')
inputString.should.equal(expected)
done()
})
stream.write(file)
stream.end()
})
it('should give an error on recursive includes', done => {
var file = new Vinyl({
path: 'test/fixtures-edge-case/recursion.html',
contents: fs.createReadStream('test/fixtures-edge-case/recursion.html')
})
var stream = fileIncludePlugin()
stream.on('error', err => {
should.exist(err)
done()
})
stream.write(file)
stream.end()
})
// it('should give an error on circular recursive includes', function(done) {
// var file = new Vinyl({
// path: 'test/fixtures-edge-case/a.html',
// contents: fs.createReadStream('test/fixtures-edge-case/a.html')
// });
// var stream = fileIncludePlugin();
// stream.on('error', function(err) {
// should.exist(err);
// done();
// });
// stream.write(file);
// stream.end();
// });
})
})
================================================
FILE: test/error.js
================================================
'use strict'
const fileIncludePlugin = require('..')
const Vinyl = require('vinyl')
const fs = require('fs')
const os = require('os')
require('should')
describe('## error', () => {
it('# if statement', done => {
var file = new Vinyl({
path: 'test/fixtures-error/if.html',
contents: fs.readFileSync('test/fixtures-error/if.html')
})
var stream = fileIncludePlugin({
prefix: '@@',
basepath: '@root'
})
stream.on('error', error => {
error.message.should.equal('invalid is not defined: (invalid === true) ')
done()
})
stream.write(file)
stream.end()
})
it('# for statement', done => {
var file = new Vinyl({
path: 'test/fixtures-error/if.html',
contents: fs.readFileSync('test/fixtures-error/for.html')
})
var stream = fileIncludePlugin({
prefix: '@@',
basepath: '@root'
})
stream.on('error', error => {
error.message.should.equal('invalid is not defined: for (var i = 0; i < invalid.length; i++) { result+=`' + os.EOL + ' <label>`+invalid[i]+`</label>' + os.EOL + ' `; }')
done()
})
stream.write(file)
stream.end()
})
})
================================================
FILE: test/filters.js
================================================
'use strict'
const fileIncludePlugin = require('..')
const markdown = require('markdown')
const Vinyl = require('vinyl')
const should = require('should')
const fs = require('fs')
describe('## gulp-file-include', () => {
var result = fs.readFileSync('test/fixtures/result.html', 'utf8')
describe('# options - filters', () => {
it('file - filters: markdown', done => {
var file = new Vinyl({
path: 'test/fixtures/index-markdown.html',
contents: fs.readFileSync('test/fixtures/index-markdown.html')
})
var stream = fileIncludePlugin({
filters: {
markdown: markdown.parse
}
})
stream.on('data', newFile => {
should.exist(newFile)
should.exist(newFile.contents)
String(newFile.contents).should.equal(result)
done()
})
stream.write(file)
stream.end()
})
it('stream - filters: markdown', done => {
var file = new Vinyl({
path: 'test/fixtures/index-markdown.html',
contents: fs.createReadStream('test/fixtures/index-markdown.html')
})
var stream = fileIncludePlugin({
filters: {
markdown: markdown.parse
}
})
stream.on('data', newFile => {
should.exist(newFile)
should.exist(newFile.contents)
String(newFile.contents).should.equal(result)
done()
})
stream.write(file)
stream.end()
})
it('file - filters: markdown & rot13', done => {
var file = new Vinyl({
path: 'test/fixtures/index-markdown-rot13.html',
contents: fs.readFileSync('test/fixtures/index-markdown-rot13.html')
})
var stream = fileIncludePlugin({
filters: {
markdown: markdown.parse,
rot13: rot13
}
})
stream.on('data', newFile => {
should.exist(newFile)
should.exist(newFile.contents)
String(newFile.contents).should.equal(result)
done()
})
stream.write(file)
stream.end()
})
it('stream - filters: markdown & rot13', done => {
var file = new Vinyl({
path: 'test/fixtures/index-markdown-rot13.html',
contents: fs.createReadStream('test/fixtures/index-markdown-rot13.html')
})
var stream = fileIncludePlugin({
filters: {
markdown: markdown.parse,
rot13: rot13
}
})
stream.on('data', newFile => {
should.exist(newFile)
should.exist(newFile.contents)
String(newFile.contents).should.equal(result)
done()
})
stream.write(file)
stream.end()
})
it('file - filters: custom filter handler options', done => {
var file = new Vinyl({
path: 'test/fixtures/index-handler-options.html',
contents: fs.createReadStream('test/fixtures/index-handler-options.html')
})
var stream = fileIncludePlugin({
prefix: '@@',
basepath: '@file',
filters: {
handler: function(content, options) {
should.exist(options)
should.exist(options.age)
should.exist(options.name)
// other handler code or
// template engine compiling here, i.e.:
// var template = Handlebars.compile(content);
// return template(options);
return content
}
}
})
stream.on('data', newFile => {
should.exist(newFile)
should.exist(newFile.contents)
String(newFile.contents).should.equal(result)
done()
})
stream.write(file)
stream.end()
})
})
})
function rot13(str) {
// original by: Jonas Raoni Soares Silva (http://www.jsfromhell.com)
return (str + '').replace(/[a-z]/gi, s => {
return String.fromCharCode(
s.charCodeAt(0) + (s.toLowerCase() < 'n' ? 13 : -13)
)
})
}
================================================
FILE: test/fixtures/arr-result.html
================================================
<!DOCTYPE html>
<html>
<body>
<h1>view</h1>
<label>haoxin</label>
<label>12345</label>
</body>
</html>
================================================
FILE: test/fixtures/arr.html
================================================
@@for (var i = 0; i < name.length; i++) {
<label>`+name[i]+`</label>
}
================================================
FILE: test/fixtures/index-01.html
================================================
<!DOCTYPE html>
<html>
<body>
@@include('view.html')
@@ if(true) {@@include('./var.html', {
"name": "haoxin",
"age": 12345
})}
</body>
</html>
================================================
FILE: test/fixtures/index-02.html
================================================
<!DOCTYPE html>
<html>
<body>
@@include('fixtures/view.html')
@@include('./fixtures/var.html', {
"name": "haoxin",
"age": 12345
})
</body>
</html>
================================================
FILE: test/fixtures/index-03.html
================================================
<!DOCTYPE html>
<html>
<body>
@@include('./test/fixtures/view.html')
@@include('test/fixtures/var.html', {
"name": "haoxin",
"age": 12345
})
</body>
</html>
================================================
FILE: test/fixtures/index-04.js
================================================
(function(okanjo) {
okanjo.mvc.registerCss('main', '@@include(jsStringEscape("./test/fixtures/view.html"))', {
id: 'okanjo-test-main'
});
okanjo.mvc.registerCss('main', '@@include(jsStringEscape("test/fixtures/var.html", { "name": "haoxin", "age": 12345 }))', {
id: 'okanjo-test-main'
});
})(okanjo);
================================================
FILE: test/fixtures/index-05.html
================================================
<!DOCTYPE html>
<html>
<body>
@@include('view.html')
@@include('./arr.html', {
"name": ["haoxin", 12345]
})
</body>
</html>
================================================
FILE: test/fixtures/index-handler-options.html
================================================
<!DOCTYPE html>
<html>
<body>
@@include('view.html')
@@include(handler('var.html', {
"name": "haoxin",
"age": 12345
}))
</body>
</html>
================================================
FILE: test/fixtures/index-markdown-rot13.html
================================================
<!DOCTYPE html>
<html>
<body>
@@include(markdown(rot13('view.rot13.md')))
@@include(rot13('./var.rot13.html', {
"name": "haoxin",
"age": 12345
}))
</body>
</html>
================================================
FILE: test/fixtures/index-markdown.html
================================================
<!DOCTYPE html>
<html>
<body>
@@ include(markdown('view.md'))
@@include('./var.html', {
"name": "haoxin",
"age": 12345
})
</body>
</html>
================================================
FILE: test/fixtures/result.html
================================================
<!DOCTYPE html>
<html>
<body>
<h1>view</h1>
<label>haoxin</label>
<label>12345</label>
</body>
</html>
================================================
FILE: test/fixtures/result.js
================================================
(function(okanjo) {
okanjo.mvc.registerCss('main', '<h1>view</h1>', {
id: 'okanjo-test-main'
});
okanjo.mvc.registerCss('main', '<label>haoxin</label>
<label>12345</label>', {
id: 'okanjo-test-main'
});
})(okanjo);
================================================
FILE: test/fixtures/sameprefix-result.html
================================================
<!DOCTYPE html>
<html>
<body>
<a href="http://drewlustro.com">Cool Link</a>
</body>
</html>
================================================
FILE: test/fixtures/sameprefix-var.html
================================================
<a href="@@title_link">@@title</a>
================================================
FILE: test/fixtures/sameprefix.html
================================================
<!DOCTYPE html>
<html>
<body>
@@include('./sameprefix-var.html', {
"title": "Cool Link",
"title_link": "http://drewlustro.com"
})
</body>
</html>
================================================
FILE: test/fixtures/var.html
================================================
<label>@@name</label>
<label>@@ age</label>
================================================
FILE: test/fixtures/var.rot13.html
================================================
<ynory>@@anzr</ynory>
<ynory>@@ntr</ynory>
================================================
FILE: test/fixtures/view.html
================================================
<h1>view</h1>
================================================
FILE: test/fixtures/view.md
================================================
view
====
================================================
FILE: test/fixtures/view.rot13.md
================================================
ivrj
====
================================================
FILE: test/fixtures-edge-case/a.html
================================================
<!DOCTYPE html>
<html>
<body>
<!-- include b, that includes a again -->
@@include('b.html')
</body>
</html>
================================================
FILE: test/fixtures-edge-case/b.html
================================================
<!DOCTYPE html>
<html>
<body>
<!-- includes a again (nested recursion) -->
@@include('a.html')
</body>
</html>
================================================
FILE: test/fixtures-edge-case/commented-inclusion-result.html
================================================
<!DOCTYPE html>
<html>
<body>
<!-- this line stays, but the include should be skipped -->
</body>
</html>
================================================
FILE: test/fixtures-edge-case/commented-inclusion.html
================================================
<!DOCTYPE html>
<html>
<body>
<!-- this line stays, but the include should be skipped -->
<!-- @@include('recursion.html') -->
</body>
</html>
================================================
FILE: test/fixtures-edge-case/dangerous.txt
================================================
This: $& should not trigger recursive includes.
================================================
FILE: test/fixtures-edge-case/index.html
================================================
<!DOCTYPE html>
<html>
<body>
@@include('dangerous.txt')
</body>
</html>
================================================
FILE: test/fixtures-edge-case/recursion.html
================================================
<!DOCTYPE html>
<html>
<body>
<!-- silly recursion, should give an error -->
@@include('recursion.html')
</body>
</html>
================================================
FILE: test/fixtures-edge-case/result.html
================================================
<!DOCTYPE html>
<html>
<body>
This: $& should not trigger recursive includes.
</body>
</html>
================================================
FILE: test/fixtures-edge-case/without-trailing-newline-result.txt
================================================
hello world!
This: $& should not trigger recursive includes.
without trailing newline
This: $& should not trigger recursive includes.
!@
!!This: $& should not trigger recursive includes.
!@
bye
================================================
FILE: test/fixtures-edge-case/without-trailing-newline.txt
================================================
hello world!
@@include('dangerous.txt')without trailing newline
@@include('dangerous.txt')!@
!!@@include('dangerous.txt')!@
bye
================================================
FILE: test/fixtures-error/for.html
================================================
@@for (var i = 0; i < invalid.length; i++) {
<label>`+invalid[i]+`</label>
}
================================================
FILE: test/fixtures-error/if.html
================================================
@@if (invalid === true) {
<h1>a</h1>
}
================================================
FILE: test/fixtures-flatten/index.html
================================================
<label>@@obj</label>
<strong>@@obj.param1</strong>
<strong>@@obj.param2</strong>
================================================
FILE: test/fixtures-flatten/result.html
================================================
<label>@@obj</label>
<strong>value1</strong>
<strong>value2</strong>
================================================
FILE: test/fixtures-indent/index.html
================================================
<h1>Hello</h1>
<div class="section">
<span>Sub</span>
//= include('sub.html')
</div>
================================================
FILE: test/fixtures-indent/result.html
================================================
<h1>Hello</h1>
<div class="section">
<span>Sub</span>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Laboriosam in nisi blanditiis!</p>
<div>
<p>Lorem ipsum dolor sit amet, consectetur.</p>
<small>Am Dig Bo</small>
</div>
</div>
================================================
FILE: test/fixtures-indent/sub-sub.html
================================================
<small>Am Dig Bo</small>
================================================
FILE: test/fixtures-indent/sub.html
================================================
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Laboriosam in nisi blanditiis!</p>
<div>
<p>Lorem ipsum dolor sit amet, consectetur.</p>
//= include('sub-sub.html')
</div>
================================================
FILE: test/fixtures-nested/index.html
================================================
<!DOCTYPE html>
<html>
<body>
@@include('var.html', {
"name": "haoxin",
"age": 12345,
"socials": {
"fb": "facebook.com/include",
"tw": "twitter.com/include"
}
})
</body>
</html>
================================================
FILE: test/fixtures-nested/result.html
================================================
<!DOCTYPE html>
<html>
<body>
<label>haoxin</label>
<label>12345</label>
<strong>facebook.com/include</strong>
<strong>twitter.com/include</strong>
</body>
</html>
================================================
FILE: test/fixtures-nested/var.html
================================================
<label>@@name</label>
<label>@@age</label>
<strong>@@socials.fb</strong>
<strong>@@socials.tw</strong>
================================================
FILE: test/fixtures-nested-once/index-twice.html
================================================
<!DOCTYPE html>
<html>
<body>
@@include_once('var.html', {
"name": "haoxin",
"age": 12345,
"socials": {
"fb": "facebook.com/include",
"tw": "twitter.com/include"
}
})
@@include_once('var.html', {
"name": "haoxin",
"age": 12345,
"socials": {
"fb": "facebook.com/include",
"tw": "twitter.com/include"
}
})
</body>
</html>
================================================
FILE: test/fixtures-nested-once/index.html
================================================
<!DOCTYPE html>
<html>
<body>
@@include_once('var.html', {
"name": "haoxin",
"age": 12345,
"socials": {
"fb": "facebook.com/include",
"tw": "twitter.com/include"
}
})
</body>
</html>
================================================
FILE: test/fixtures-nested-once/result-twice.html
================================================
<!DOCTYPE html>
<html>
<body>
<label>haoxin</label>
<label>12345</label>
<strong>facebook.com/include</strong>
<strong>twitter.com/include</strong>
</body>
</html>
================================================
FILE: test/fixtures-nested-once/result.html
================================================
<!DOCTYPE html>
<html>
<body>
<label>haoxin</label>
<label>12345</label>
<strong>facebook.com/include</strong>
<strong>twitter.com/include</strong>
</body>
</html>
================================================
FILE: test/fixtures-nested-once/var.html
================================================
<label>@@name</label>
<label>@@age</label>
<strong>@@socials.fb</strong>
<strong>@@socials.tw</strong>
================================================
FILE: test/fixtures-operator/index.html
================================================
@@if (content.indexOf('>a') > -1) {
<h1>a</h1>
}
@@if(content.indexOf('>a') > -1){
{<h1>a</h1>}
}
@@if content.indexOf('>a') > -1 {
<h1>a</h1>
}
@@if (content.length > 888) {
<h2>b</h2>
}
@@if (name === 'c') {
@@if (name === 'c') {
<h3>c</h3>
}
}
@@ if (name === 'c' && context.title === 'haoxin') {
<h3>c</h3>
}
@@ if (name === 'c' && context.title !== 'haoxin') {
<h3>c</h3>
}
@@if(name === 'c') {
================================================
FILE: test/fixtures-operator/result-index.html
================================================
<h1>a</h1>
{<h1>a</h1>}
<h1>a</h1>
<h3>c</h3>
<h3>c</h3>
@@if(name === 'c') {
================================================
FILE: test/fixtures-operator/result-suffix.html
================================================
<h1>a</h1>
{<h1>a</h1>}
<h1>a</h1>
<h3>c</h3>
<h3>c</h3>
@@if(name === 'c') {
}
@@if(name === 'c') {
================================================
FILE: test/fixtures-operator/suffix.html
================================================
@@if (content.indexOf('>a') > -1) {
<h1>a</h1>
}##
@@if(content.indexOf('>a') > -1){
{<h1>a</h1>}
} ##
@@if content.indexOf('>a') > -1 {
<h1>a</h1>
}
##
@@if (content.length > 888) {
<h2>b</h2>
}
##
@@if (name === 'c') {
@@if (name === 'c') {
<h3>c</h3>
}##
}
##
@@ if (name === 'c' && context.title === 'haoxin') {
<h3>c</h3>
}##
@@ if (name === 'c' && context.title !== 'haoxin') {
<h3>c</h3>
}##
@@if(name === 'c') {
}
@@if(name === 'c') {
================================================
FILE: test/fixtures-recursion/index.txt
================================================
this is index
@@include('./sub/a.txt')
@@include('./sub/b.txt')
@@include('./var.txt', {
"name": "from index.txt"
})
================================================
FILE: test/fixtures-recursion/result.txt
================================================
this is index
this is a.txt
this is b.txt
name is: from b.txt
this is b.txt
name is: from b.txt
name is: from index.txt
================================================
FILE: test/fixtures-recursion/sub/a.txt
================================================
this is a.txt
@@include('./b.txt')
================================================
FILE: test/fixtures-recursion/sub/b.txt
================================================
this is b.txt
@@include('../var.txt', {
"name": "from b.txt"
})
================================================
FILE: test/fixtures-recursion/var.txt
================================================
name is: @@name
================================================
FILE: test/fixtures-suffix/index.html
================================================
<!DOCTYPE html>
<html>
<body>
@@include('../fixtures/view.html')@@
@@include('./var.html', {
"name": "haoxin",
"age": 12345
})@@
</body>
</html>
================================================
FILE: test/fixtures-suffix/var.html
================================================
<label>@@name@@</label>
<label>@@age@@</label>
================================================
FILE: test/fixtures-variable/index-suffix.html
================================================
<ul>
<li>
<var>//= param1 @@</var>
</li>
<li>
<var>//= obj.param1@@</var>
</li>
<li>
<var>//= obj.param2@@</var>
</li>
<li>
<var>//=param2 @@</var>
</li>
</ul>
================================================
FILE: test/fixtures-variable/index.html
================================================
<ul>
<li>
<var>//= param1</var>
</li>
<li>
<var>//= obj.param1</var>
</li>
<li>
<var>//= obj.param2</var>
</li>
<li>
<var>//=param2</var>
</li>
</ul>
================================================
FILE: test/fixtures-variable/result.html
================================================
<ul>
<li>
<var>value1</var>
</li>
<li>
<var>o1</var>
</li>
<li>
<var>o2</var>
</li>
<li>
<var>value2</var>
</li>
</ul>
================================================
FILE: test/fixtures-webroot-variable/html-head.html
================================================
<head>
<link type=stylesheet src=@@webRoot/style.css>
</head>
================================================
FILE: test/fixtures-webroot-variable/index.html
================================================
<!DOCTYPE html>
<html>
@@include('html-head.html')
<body>
<h1>Page</h1>
<a href=@@webRoot/about>About</a>
@@include('sub/home-link.html')
</body>
</html>
================================================
FILE: test/fixtures-webroot-variable/result.html
================================================
<!DOCTYPE html>
<html>
<head>
<link type=stylesheet src=../../style.css>
</head>
<body>
<h1>Page</h1>
<a href=../../about>About</a>
<a href=../..>Home</a>
</body>
</html>
================================================
FILE: test/fixtures-webroot-variable/sub/home-link.html
================================================
<a href=@@webRoot>Home</a>
================================================
FILE: test/fixtures-webroot-variable/sub/index.html
================================================
<!DOCTYPE html>
<html>
@@include('../html-head.html')
<body>
<h1>Sub Page</h1>
<a href=@@webRoot/about>About</a>
@@include('home-link.html')
</body>
</html>
================================================
FILE: test/fixtures-webroot-variable/sub/result.html
================================================
<!DOCTYPE html>
<html>
<head>
<link type=stylesheet src=../../../style.css>
</head>
<body>
<h1>Sub Page</h1>
<a href=../../../about>About</a>
<a href=../../..>Home</a>
</body>
</html>
================================================
FILE: test/flatten.js
================================================
'use strict'
const fileIncludePlugin = require('..')
const Vinyl = require('vinyl')
const should = require('should')
const fs = require('fs')
describe('## gulp-file-include', () => {
var result = fs.readFileSync('test/fixtures-flatten/result.html', 'utf8')
describe('# flatten variables', () => {
it('file', done => {
var file = new Vinyl({
path: 'test/fixtures-flatten/index.html',
contents: fs.readFileSync('test/fixtures-flatten/index.html')
})
var stream = fileIncludePlugin({
context: {
obj: {
'param1': 'value1',
'param2': 'value2'
}
}
})
stream.on('data', newFile => {
should.exist(newFile)
should.exist(newFile.contents)
String(newFile.contents).should.equal(result)
done()
})
stream.write(file)
stream.end()
})
it('stream', done => {
var file = new Vinyl({
path: 'test/fixtures-flatten/index.html',
contents: fs.createReadStream('test/fixtures-flatten/index.html')
})
var stream = fileIncludePlugin({
context: {
obj: {
'param1': 'value1',
'param2': 'value2'
}
}
})
stream.on('data', newFile => {
should.exist(newFile)
should.exist(newFile.contents)
String(newFile.contents).should.equal(result)
done()
})
stream.write(file)
stream.end()
})
})
})
================================================
FILE: test/indent.js
================================================
'use strict'
const setIndent = require('../lib/indent')
require('should')
describe('## indent', () => {
it('# basic', done => {
setIndent(
' content \n\t start',
13,
'some other \n content').should.equal('some other \n\t content')
done()
})
it('# basic with \\r\\n newlines', done => {
setIndent(
' content \r\n\t start',
14,
'\r\n\r\nsome other \r\n content').should.equal('\r\n\r\n\t some other \r\n\t content')
done()
})
it('# with non-space char', done => {
setIndent(
' content \n\t g start',
14,
'\n\nsome other \n content').should.equal('\n\nsome other \n content')
done()
})
it('# with non-space char and \\r\\n newlines', done => {
setIndent(
' content \r\n\t g start',
15,
'\r\n\r\nsome other \r\n content').should.equal('\r\n\r\nsome other \r\n content')
done()
})
})
================================================
FILE: test/index.js
================================================
'use strict'
const fileIncludePlugin = require('..')
const Vinyl = require('vinyl')
const should = require('should')
const fs = require('fs')
describe('## gulp-file-include', () => {
var result = fs.readFileSync('test/fixtures/result.html', 'utf8')
var resultJS = fs.readFileSync('test/fixtures/result.js', 'utf8')
var resultSamePrefix = fs.readFileSync('test/fixtures/sameprefix-result.html', 'utf8')
var resultArr = fs.readFileSync('test/fixtures/arr-result.html', 'utf8')
describe('# default', () => {
it('file', done => {
var file = new Vinyl({
path: 'test/fixtures/index-01.html',
contents: fs.readFileSync('test/fixtures/index-01.html')
})
var stream = fileIncludePlugin()
stream.on('data', newFile => {
should.exist(newFile)
should.exist(newFile.contents)
String(newFile.contents).should.equal(result)
done()
})
stream.write(file)
stream.end()
})
it('stream', done => {
var file = new Vinyl({
path: 'test/fixtures/index-01.html',
contents: fs.createReadStream('test/fixtures/index-01.html')
})
var stream = fileIncludePlugin()
stream.on('data', newFile => {
should.exist(newFile)
should.exist(newFile.contents)
String(newFile.contents).should.equal(result)
done()
})
stream.write(file)
stream.end()
})
})
describe('# options - basepath', () => {
it('file - basepath: @file', done => {
var file = new Vinyl({
path: 'test/fixtures/index-01.html',
contents: fs.readFileSync('test/fixtures/index-01.html')
})
var stream = fileIncludePlugin({
basepath: '@file'
})
stream.on('data', newFile => {
should.exist(newFile)
should.exist(newFile.contents)
String(newFile.contents).should.equal(result)
done()
})
stream.write(file)
stream.end()
})
it('stream - basepath: @file', done => {
var file = new Vinyl({
path: 'test/fixtures/index-01.html',
contents: fs.createReadStream('test/fixtures/index-01.html')
})
var stream = fileIncludePlugin({
basepath: '@file'
})
stream.on('data', newFile => {
should.exist(newFile)
should.exist(newFile.contents)
String(newFile.contents).should.equal(result)
done()
})
stream.write(file)
stream.end()
})
it('file - basepath: @root', done => {
var file = new Vinyl({
path: 'test/fixtures/index-03.html',
contents: fs.readFileSync('test/fixtures/index-03.html')
})
var stream = fileIncludePlugin({
basepath: '@root'
})
stream.on('data', newFile => {
should.exist(newFile)
should.exist(newFile.contents)
String(newFile.contents).should.equal(result)
done()
})
stream.write(file)
stream.end()
})
it('stream - basepath: @root', done => {
var file = new Vinyl({
path: 'test/fixtures/index-03.html',
contents: fs.createReadStream('test/fixtures/index-03.html')
})
var stream = fileIncludePlugin({
basepath: '@root'
})
stream.on('data', newFile => {
should.exist(newFile)
should.exist(newFile.contents)
String(newFile.contents).should.equal(result)
done()
})
stream.write(file)
stream.end()
})
it('file - basepath: dir', done => {
var file = new Vinyl({
path: 'test/fixtures/index-02.html',
contents: fs.readFileSync('test/fixtures/index-02.html')
})
var stream = fileIncludePlugin({
basepath: __dirname
})
stream.on('data', newFile => {
should.exist(newFile)
should.exist(newFile.contents)
String(newFile.contents).should.equal(result)
done()
})
stream.write(file)
stream.end()
})
it('stream - basepath: dir', done => {
var file = new Vinyl({
path: 'test/fixtures/index-02.html',
contents: fs.createReadStream('test/fixtures/index-02.html')
})
var stream = fileIncludePlugin({
basepath: __dirname
})
stream.on('data', newFile => {
should.exist(newFile)
should.exist(newFile.contents)
String(newFile.contents).should.equal(result)
done()
})
stream.write(file)
stream.end()
})
})
describe('# options - prefix, basepath', () => {
it('file - basepath: @file', done => {
var file = new Vinyl({
path: 'test/fixtures/index-01.html',
contents: fs.readFileSync('test/fixtures/index-01.html')
})
var stream = fileIncludePlugin({
prefix: '@@',
basepath: '@file'
})
stream.on('data', newFile => {
should.exist(newFile)
should.exist(newFile.contents)
String(newFile.contents).should.equal(result)
done()
})
stream.write(file)
stream.end()
})
it('stream - basepath: @file', done => {
var file = new Vinyl({
path: 'test/fixtures/index-01.html',
contents: fs.createReadStream('test/fixtures/index-01.html')
})
var stream = fileIncludePlugin({
prefix: '@@',
basepath: '@file'
})
stream.on('data', newFile => {
should.exist(newFile)
should.exist(newFile.contents)
String(newFile.contents).should.equal(result)
done()
})
stream.write(file)
stream.end()
})
it('file - basepath: @root', done => {
var file = new Vinyl({
path: 'test/fixtures/index-03.html',
contents: fs.readFileSync('test/fixtures/index-03.html')
})
var stream = fileIncludePlugin({
prefix: '@@',
basepath: '@root'
})
stream.on('data', newFile => {
should.exist(newFile)
should.exist(newFile.contents)
String(newFile.contents).should.equal(result)
done()
})
stream.write(file)
stream.end()
})
it('stream - basepath: @root', done => {
var file = new Vinyl({
path: 'test/fixtures/index-03.html',
contents: fs.createReadStream('test/fixtures/index-03.html')
})
var stream = fileIncludePlugin({
prefix: '@@',
basepath: '@root'
})
stream.on('data', newFile => {
should.exist(newFile)
should.exist(newFile.contents)
String(newFile.contents).should.equal(result)
done()
})
stream.write(file)
stream.end()
})
it('file - basepath: dir', done => {
var file = new Vinyl({
path: 'test/fixtures/index-02.html',
contents: fs.readFileSync('test/fixtures/index-02.html')
})
var stream = fileIncludePlugin({
prefix: '@@',
basepath: __dirname
})
stream.on('data', newFile => {
should.exist(newFile)
should.exist(newFile.contents)
String(newFile.contents).should.equal(result)
done()
})
stream.write(file)
stream.end()
})
it('stream - basepath: dir', done => {
var file = new Vinyl({
path: 'test/fixtures/index-02.html',
contents: fs.createReadStream('test/fixtures/index-02.html')
})
var stream = fileIncludePlugin({
prefix: '@@',
basepath: __dirname
})
stream.on('data', newFile => {
should.exist(newFile)
should.exist(newFile.contents)
String(newFile.contents).should.equal(result)
done()
})
stream.write(file)
stream.end()
})
})
describe('# options - suffix', () => {
it('file', done => {
var file = new Vinyl({
path: 'test/fixtures-suffix/index.html',
contents: fs.readFileSync('test/fixtures-suffix/index.html')
})
var stream = fileIncludePlugin({
suffix: '@@'
})
stream.on('data', newFile => {
should.exist(newFile)
should.exist(newFile.contents);
// TODO
(String(newFile.contents) === result).should.equal(true)
// String(newFile.contents).should.equal(result);
done()
})
stream.write(file)
stream.end()
})
it('stream', done => {
var file = new Vinyl({
path: 'test/fixtures-suffix/index.html',
contents: fs.createReadStream('test/fixtures-suffix/index.html')
})
var stream = fileIncludePlugin({
suffix: '@@'
})
stream.on('data', newFile => {
should.exist(newFile)
should.exist(newFile.contents);
// TODO
(String(newFile.contents) === result).should.equal(true)
// String(newFile.contents).should.equal(result);
done()
})
stream.write(file)
stream.end()
})
})
describe('# vars - same key prefix', () => {
it('file', done => {
var file = new Vinyl({
path: 'test/fixtures/sameprefix.html',
contents: fs.readFileSync('test/fixtures/sameprefix.html')
})
var stream = fileIncludePlugin()
stream.on('data', newFile => {
should.exist(newFile)
should.exist(newFile.contents)
String(newFile.contents).should.equal(resultSamePrefix)
done()
})
stream.write(file)
stream.end()
})
it('stream', done => {
var file = new Vinyl({
path: 'test/fixtures/sameprefix.html',
contents: fs.createReadStream('test/fixtures/sameprefix.html')
})
var stream = fileIncludePlugin()
stream.on('data', newFile => {
should.exist(newFile)
should.exist(newFile.contents)
String(newFile.contents).should.equal(resultSamePrefix)
done()
})
stream.write(file)
stream.end()
})
})
describe('# aggressive regex', () => {
it('file - basepath: @root', done => {
var file = new Vinyl({
path: 'test/fixtures/index-04.js',
contents: fs.readFileSync('test/fixtures/index-04.js')
})
var stream = fileIncludePlugin({
prefix: '@@',
basepath: '@root'
})
stream.on('data', newFile => {
should.exist(newFile)
should.exist(newFile.contents)
String(newFile.contents).should.equal(resultJS)
done()
})
stream.write(file)
stream.end()
})
it('stream - basepath: @root', done => {
var file = new Vinyl({
path: 'test/fixtures/index-04.js',
contents: fs.createReadStream('test/fixtures/index-04.js')
})
var stream = fileIncludePlugin({
prefix: '@@',
basepath: '@root'
})
stream.on('data', newFile => {
should.exist(newFile)
should.exist(newFile.contents)
String(newFile.contents).should.equal(resultJS)
done()
})
stream.write(file)
stream.end()
})
})
describe('# for statement', () => {
it('file', done => {
var file = new Vinyl({
path: 'test/fixtures/index-05.html',
contents: fs.readFileSync('test/fixtures/index-05.html')
})
var stream = fileIncludePlugin()
stream.on('data', newFile => {
should.exist(newFile)
should.exist(newFile.contents)
String(newFile.contents).should.equal(resultArr)
done()
})
stream.write(file)
stream.end()
})
it('stream', done => {
var file = new Vinyl({
path: 'test/fixtures/index-05.html',
contents: fs.createReadStream('test/fixtures/index-05.html')
})
var stream = fileIncludePlugin()
stream.on('data', newFile => {
should.exist(newFile)
should.exist(newFile.contents)
String(newFile.contents).should.equal(resultArr)
done()
})
stream.write(file)
stream.end()
})
})
})
================================================
FILE: test/nested-once.js
================================================
'use strict'
const fileIncludePlugin = require('../lib')
const Vinyl = require('vinyl')
const should = require('should')
const fs = require('fs')
describe('## gulp-file-include', () => {
var result = fs.readFileSync('test/fixtures-nested-once/result.html', 'utf8')
var resultTwice = fs.readFileSync('test/fixtures-nested-once/result-twice.html', 'utf8')
describe('# nested once arguments', () => {
it('file', done => {
var file = new Vinyl({
path: 'test/fixtures-nested-once/index.html',
contents: fs.readFileSync('test/fixtures-nested-once/index.html')
})
var stream = fileIncludePlugin()
stream.on('data', newFile => {
should.exist(newFile)
should.exist(newFile.contents)
String(newFile.contents).should.equal(result)
done()
})
stream.write(file)
stream.end()
})
it('stream', done => {
var file = new Vinyl({
path: 'test/fixtures-nested-once/index.html',
contents: fs.createReadStream('test/fixtures-nested-once/index.html')
})
var stream = fileIncludePlugin()
stream.on('data', newFile => {
should.exist(newFile)
should.exist(newFile.contents)
String(newFile.contents).should.equal(result)
done()
})
stream.write(file)
stream.end()
})
})
describe('# nested once arguments twice', () => {
it('file', done => {
var file = new Vinyl({
path: 'test/fixtures-nested-once/index-twice.html',
contents: fs.readFileSync('test/fixtures-nested-once/index-twice.html')
})
var stream = fileIncludePlugin()
stream.on('data', newFile => {
should.exist(newFile)
should.exist(newFile.contents)
String(newFile.contents).should.equal(resultTwice)
done()
})
stream.write(file)
stream.end()
})
it('stream', done => {
var file = new Vinyl({
path: 'test/fixtures-nested-once/index-twice.html',
contents: fs.createReadStream('test/fixtures-nested-once/index-twice.html')
})
var stream = fileIncludePlugin()
stream.on('data', newFile => {
should.exist(newFile)
should.exist(newFile.contents)
String(newFile.contents).should.equal(resultTwice)
done()
})
stream.write(file)
stream.end()
})
})
})
================================================
FILE: test/nested.js
================================================
'use strict'
const fileIncludePlugin = require('..')
const Vinyl = require('vinyl')
const should = require('should')
const fs = require('fs')
describe('## gulp-file-include', () => {
var result = fs.readFileSync('test/fixtures-nested/result.html', 'utf8')
describe('# nested arguments', () => {
it('file', done => {
var file = new Vinyl({
path: 'test/fixtures-nested/index.html',
contents: fs.readFileSync('test/fixtures-nested/index.html')
})
var stream = fileIncludePlugin()
stream.on('data', newFile => {
should.exist(newFile)
should.exist(newFile.contents)
String(newFile.contents).should.equal(result)
done()
})
stream.write(file)
stream.end()
})
it('stream', done => {
var file = new Vinyl({
path: 'test/fixtures-nested/index.html',
contents: fs.createReadStream('test/fixtures-nested/index.html')
})
var stream = fileIncludePlugin()
stream.on('data', newFile => {
should.exist(newFile)
should.exist(newFile.contents)
String(newFile.contents).should.equal(result)
done()
})
stream.write(file)
stream.end()
})
})
})
================================================
FILE: test/operator.js
================================================
'use strict'
const parse = require('../lib/replace-operator')
const fs = require('fs')
require('should')
describe('## operator', () => {
it('# basic usage', done => {
var result = fs.readFileSync('test/fixtures-operator/result-index.html', 'utf-8')
var index = fs.readFileSync('test/fixtures-operator/index.html', 'utf-8')
parse(index, {
prefix: '@@',
suffix: '',
name: 'if',
handler: inst => {
var condition = new Function('var context = this; with (context) { return ' + inst.args + '; }').call({ // eslint-disable-line
content: index,
name: 'c'
})
return condition ? inst.body : ''
}
}).should.equal(result)
done()
})
it('# with suffix', done => {
var result = fs.readFileSync('test/fixtures-operator/result-suffix.html', 'utf-8')
var index = fs.readFileSync('test/fixtures-operator/suffix.html', 'utf-8')
parse(index, {
name: 'if',
prefix: '@@',
suffix: '##',
handler: inst => {
var condition = new Function('var context = this; with (context) { return ' + inst.args + '; }').call({ // eslint-disable-line
content: index,
name: 'c'
})
return condition ? inst.body : ''
}
}).should.equal(result)
done()
})
})
================================================
FILE: test/plugin-indent.js
================================================
'use strict'
const fileIncludePlugin = require('..')
const Vinyl = require('vinyl')
const should = require('should')
const fs = require('fs')
describe('## gulp-file-include', () => {
var result = fs.readFileSync('test/fixtures-indent/result.html', 'utf-8')
describe('# indent', () => {
it('file', done => {
var file = new Vinyl({
path: 'test/fixtures-indent/index.html',
contents: fs.readFileSync('test/fixtures-indent/index.html')
})
var stream = fileIncludePlugin({
prefix: '//=',
indent: true
})
stream.on('data', newFile => {
should.exist(newFile)
should.exist(newFile.contents)
String(newFile.contents).should.equal(result)
done()
})
stream.write(file)
stream.end()
})
it('stream', done => {
var file = new Vinyl({
path: 'test/fixtures-indent/index.html',
contents: fs.createReadStream('test/fixtures-indent/index.html')
})
var stream = fileIncludePlugin({
prefix: '//=',
indent: true
})
stream.on('data', newFile => {
should.exist(newFile)
should.exist(newFile.contents)
String(newFile.contents).should.equal(result)
done()
})
stream.write(file)
stream.end()
})
})
})
================================================
FILE: test/recursion.js
================================================
'use strict'
const fileIncludePlugin = require('..')
const Vinyl = require('vinyl')
const should = require('should')
const fs = require('fs')
describe('## recursion include', () => {
var result = fs.readFileSync('test/fixtures-recursion/result.txt', 'utf8')
describe('# basepath: @file', () => {
it('file', done => {
var file = new Vinyl({
path: 'test/fixtures-recursion/index.txt',
contents: fs.readFileSync('test/fixtures-recursion/index.txt')
})
var stream = fileIncludePlugin({
basepath: '@file'
})
stream.on('data', newFile => {
should.exist(newFile)
should.exist(newFile.contents)
String(newFile.contents).should.equal(result)
done()
})
stream.write(file)
stream.end()
})
it('stream', done => {
var file = new Vinyl({
path: 'test/fixtures-recursion/index.txt',
contents: fs.createReadStream('test/fixtures-recursion/index.txt')
})
var stream = fileIncludePlugin({
basepath: '@file'
})
stream.on('data', newFile => {
should.exist(newFile)
should.exist(newFile.contents)
String(newFile.contents).should.equal(result)
done()
})
stream.write(file)
stream.end()
})
})
})
================================================
FILE: test/variable.js
================================================
'use strict'
const replaceVariable = require('../lib/replace-variable')
const fs = require('fs')
require('should')
describe('## variable', () => {
var result = fs.readFileSync('test/fixtures-variable/result.html', 'utf-8')
it('# basic', done => {
var index = fs.readFileSync('test/fixtures-variable/index.html', 'utf-8')
replaceVariable(index, {
param1: 'value1',
obj: {
param1: 'o1',
param2: 'o2'
},
param2: 'value2'
}, {
prefix: '//='
}).should.equal(result)
done()
})
it('# with suffix', done => {
var index = fs.readFileSync('test/fixtures-variable/index-suffix.html', 'utf-8')
replaceVariable(index, {
param1: 'value1',
obj: {
param1: 'o1',
param2: 'o2'
},
param2: 'value2'
}, {
prefix: '//=',
suffix: '@@'
}).should.equal(result)
done()
})
})
================================================
FILE: test/webroot-variable.js
================================================
'use strict'
const fileIncludePlugin = require('..')
const Vinyl = require('vinyl')
const should = require('should')
const fs = require('fs')
describe('## built-in webRoot variable', () => {
it('# regular usage and includes', done => {
var result = fs.readFileSync('test/fixtures-webroot-variable/result.html', 'utf8')
var path = 'test/fixtures-webroot-variable/index.html'
var file = new Vinyl({ path: path, contents: fs.createReadStream(path) })
var stream = fileIncludePlugin()
stream.on('data', newFile => {
should.exist(newFile)
should.exist(newFile.contents)
String(newFile.contents).should.equal(result)
done()
})
stream.write(file)
stream.end()
})
it('# nested folder', done => {
var result = fs.readFileSync('test/fixtures-webroot-variable/sub/result.html', 'utf8')
var path = 'test/fixtures-webroot-variable/sub/index.html'
var file = new Vinyl({ path: path, contents: fs.createReadStream(path) })
var stream = fileIncludePlugin()
stream.on('data', newFile => {
should.exist(newFile)
should.exist(newFile.contents)
String(newFile.contents).should.equal(result)
done()
})
stream.write(file)
stream.end()
})
})
gitextract_ccu95132/
├── .editorconfig
├── .gitignore
├── .npmrc
├── .travis.yml
├── LICENSE
├── Readme.md
├── example/
│ ├── a/
│ │ ├── a1.txt
│ │ └── a2.txt
│ ├── b/
│ │ ├── b1.txt
│ │ └── b2.txt
│ ├── c/
│ │ └── c.txt
│ ├── conditional.txt
│ ├── gulpfile.js
│ ├── index.txt
│ └── result/
│ └── index.txt
├── lib/
│ ├── indent.js
│ ├── index.js
│ ├── replace-function.js
│ ├── replace-operator.js
│ └── replace-variable.js
├── package.json
└── test/
├── .editorconfig
├── edge-case.js
├── error.js
├── filters.js
├── fixtures/
│ ├── arr-result.html
│ ├── arr.html
│ ├── index-01.html
│ ├── index-02.html
│ ├── index-03.html
│ ├── index-04.js
│ ├── index-05.html
│ ├── index-handler-options.html
│ ├── index-markdown-rot13.html
│ ├── index-markdown.html
│ ├── result.html
│ ├── result.js
│ ├── sameprefix-result.html
│ ├── sameprefix-var.html
│ ├── sameprefix.html
│ ├── var.html
│ ├── var.rot13.html
│ ├── view.html
│ ├── view.md
│ └── view.rot13.md
├── fixtures-edge-case/
│ ├── a.html
│ ├── b.html
│ ├── commented-inclusion-result.html
│ ├── commented-inclusion.html
│ ├── dangerous.txt
│ ├── index.html
│ ├── recursion.html
│ ├── result.html
│ ├── without-trailing-newline-result.txt
│ └── without-trailing-newline.txt
├── fixtures-error/
│ ├── for.html
│ └── if.html
├── fixtures-flatten/
│ ├── index.html
│ └── result.html
├── fixtures-indent/
│ ├── index.html
│ ├── result.html
│ ├── sub-sub.html
│ └── sub.html
├── fixtures-nested/
│ ├── index.html
│ ├── result.html
│ └── var.html
├── fixtures-nested-once/
│ ├── index-twice.html
│ ├── index.html
│ ├── result-twice.html
│ ├── result.html
│ └── var.html
├── fixtures-operator/
│ ├── index.html
│ ├── result-index.html
│ ├── result-suffix.html
│ └── suffix.html
├── fixtures-recursion/
│ ├── index.txt
│ ├── result.txt
│ ├── sub/
│ │ ├── a.txt
│ │ └── b.txt
│ └── var.txt
├── fixtures-suffix/
│ ├── index.html
│ └── var.html
├── fixtures-variable/
│ ├── index-suffix.html
│ ├── index.html
│ └── result.html
├── fixtures-webroot-variable/
│ ├── html-head.html
│ ├── index.html
│ ├── result.html
│ └── sub/
│ ├── home-link.html
│ ├── index.html
│ └── result.html
├── flatten.js
├── indent.js
├── index.js
├── nested-once.js
├── nested.js
├── operator.js
├── plugin-indent.js
├── recursion.js
├── variable.js
└── webroot-variable.js
SYMBOL INDEX (7 symbols across 2 files)
FILE: lib/index.js
constant JSON5 (line 14) | const JSON5 = require('json5')
function fileInclude (line 37) | function fileInclude(file, enc, cb) {
function stripCommentedIncludes (line 70) | function stripCommentedIncludes(content, opts) {
function include (line 76) | function include(file, text, data, sourceFile = '') {
function applyFilters (line 270) | function applyFilters(includeContent, match) {
function compose (line 298) | function compose(f, g) {
FILE: test/filters.js
function rot13 (line 150) | function rot13(str) {
Condensed preview — 101 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (74K chars).
[
{
"path": ".editorconfig",
"chars": 129,
"preview": "root = true\n\n[*.{html,js}]\nindent_style = space\nindent_size = 2\nend_of_line = lf\ncharset = utf-8\ntrim_trailing_whitespac"
},
{
"path": ".gitignore",
"chars": 66,
"preview": "package-lock.json\nnpm-debug.log\nnode_modules/\n.DS_Store\ncoverage/\n"
},
{
"path": ".npmrc",
"chars": 19,
"preview": "package-lock=false\n"
},
{
"path": ".travis.yml",
"chars": 142,
"preview": "language: node_js\nnode_js:\n- 16\nscript: \"npm run test-travis\"\nafter_script: \"npm install coveralls@2 && cat ./coverage/l"
},
{
"path": "LICENSE",
"chars": 1064,
"preview": "MIT License\n\nCopyright (c) 2020 Xin Hao\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof"
},
{
"path": "Readme.md",
"chars": 6741,
"preview": "[![NPM version][npm-img]][npm-url]\n[![Build status][travis-img]][travis-url]\n[![Test coverage][coveralls-img]][coveralls"
},
{
"path": "example/a/a1.txt",
"chars": 48,
"preview": "this is a1\n\n// include a2\n@@include('./a2.txt')\n"
},
{
"path": "example/a/a2.txt",
"chars": 51,
"preview": "this is a2\n\n// include b1\n@@include('../b/b1.txt')\n"
},
{
"path": "example/b/b1.txt",
"chars": 48,
"preview": "this is b1\n\n// include b2\n@@include('./b2.txt')\n"
},
{
"path": "example/b/b2.txt",
"chars": 10,
"preview": "this is b2"
},
{
"path": "example/c/c.txt",
"chars": 21,
"preview": "this is loop @@number"
},
{
"path": "example/conditional.txt",
"chars": 177,
"preview": "this is conditional\n\nFlatten object \"@@obj\"\n@@if(typeof context.obj === 'object') {\n Flatten variable \"@@obj.obj_param\""
},
{
"path": "example/gulpfile.js",
"chars": 295,
"preview": "'use strict'\n\nconst fileinclude = require('..')\nconst gulp = require('gulp')\n\ngulp.task('include', () => {\n gulp.src(['"
},
{
"path": "example/index.txt",
"chars": 367,
"preview": "index\n\n@@include('a/a1.txt')\n\n@@name\n\n@@if (context.name === 'example') {\n @@include('conditional.txt', {\n \"param\": "
},
{
"path": "example/result/index.txt",
"chars": 431,
"preview": "index\n\nthis is a1\n\n// include a2\nthis is a2\n\n// include b1\nthis is b1\n\n// include b2\nthis is b2\n\n\n\n\nexample\n\n\n this is "
},
{
"path": "lib/indent.js",
"chars": 431,
"preview": "module.exports = function(src, index, dest) {\n var indent = ''\n var valid = false\n\n while (src[index -= 1] == 0) { //"
},
{
"path": "lib/index.js",
"chars": 9330,
"preview": "'use strict'\n\nconst replaceOperator = require('./replace-operator')\nconst replaceFunction = require('./replace-function'"
},
{
"path": "lib/replace-function.js",
"chars": 1286,
"preview": "'use strict'\n\nconst balanced = require('balanced-match')\n\nmodule.exports = function(content, opts) {\n var result = ''\n "
},
{
"path": "lib/replace-operator.js",
"chars": 1292,
"preview": "'use strict'\n\nconst balanced = require('balanced-match')\n\nmodule.exports = function parse(content, opts) {\n var regexpS"
},
{
"path": "lib/replace-variable.js",
"chars": 499,
"preview": "'use strict'\n\nconst flatten = require('flatnest').flatten\n\nmodule.exports = function(content, data, opts) {\n var prefix"
},
{
"path": "package.json",
"chars": 1267,
"preview": "{\n \"name\": \"gulp-file-include\",\n \"version\": \"2.3.0\",\n \"description\": \"A gulp plugin for file include\",\n \"main\": \"lib"
},
{
"path": "test/.editorconfig",
"chars": 33,
"preview": "[*]\ninsert_final_newline = false\n"
},
{
"path": "test/edge-case.js",
"chars": 3011,
"preview": "'use strict'\n\nconst fileIncludePlugin = require('..')\nconst Vinyl = require('vinyl')\nconst should = require('should')\nco"
},
{
"path": "test/error.js",
"chars": 1172,
"preview": "'use strict'\n\nconst fileIncludePlugin = require('..')\nconst Vinyl = require('vinyl')\nconst fs = require('fs')\nconst os ="
},
{
"path": "test/filters.js",
"chars": 3912,
"preview": "'use strict'\n\nconst fileIncludePlugin = require('..')\nconst markdown = require('markdown')\nconst Vinyl = require('vinyl'"
},
{
"path": "test/fixtures/arr-result.html",
"chars": 114,
"preview": "<!DOCTYPE html>\n<html>\n <body>\n <h1>view</h1>\n \n<label>haoxin</label>\n\n<label>12345</label>\n\n </body>\n</html>\n"
},
{
"path": "test/fixtures/arr.html",
"chars": 70,
"preview": "@@for (var i = 0; i < name.length; i++) {\n<label>`+name[i]+`</label>\n}"
},
{
"path": "test/fixtures/index-01.html",
"chars": 161,
"preview": "<!DOCTYPE html>\n<html>\n <body>\n @@include('view.html')\n @@ if(true) {@@include('./var.html', {\n \"name\": \"haoxin\",\n"
},
{
"path": "test/fixtures/index-02.html",
"chars": 165,
"preview": "<!DOCTYPE html>\n<html>\n <body>\n @@include('fixtures/view.html')\n @@include('./fixtures/var.html', {\n \"name\": \"haox"
},
{
"path": "test/fixtures/index-03.html",
"chars": 175,
"preview": "<!DOCTYPE html>\n<html>\n <body>\n @@include('./test/fixtures/view.html')\n @@include('test/fixtures/var.html', {\n \"na"
},
{
"path": "test/fixtures/index-04.js",
"chars": 320,
"preview": "(function(okanjo) {\n\n okanjo.mvc.registerCss('main', '@@include(jsStringEscape(\"./test/fixtures/view.html\"))', {\n id"
},
{
"path": "test/fixtures/index-05.html",
"chars": 138,
"preview": "<!DOCTYPE html>\n<html>\n <body>\n @@include('view.html')\n @@include('./arr.html', {\n \"name\": [\"haoxin\", 12345]\n })\n"
},
{
"path": "test/fixtures/index-handler-options.html",
"chars": 154,
"preview": "<!DOCTYPE html>\n<html>\n <body>\n @@include('view.html')\n @@include(handler('var.html', {\n \"name\": \"haoxin\",\n \"ag"
},
{
"path": "test/fixtures/index-markdown-rot13.html",
"chars": 181,
"preview": "<!DOCTYPE html>\n<html>\n <body>\n @@include(markdown(rot13('view.rot13.md')))\n @@include(rot13('./var.rot13.html', {\n "
},
{
"path": "test/fixtures/index-markdown.html",
"chars": 157,
"preview": "<!DOCTYPE html>\n<html>\n <body>\n @@ include(markdown('view.md'))\n @@include('./var.html', {\n \"name\": \"haoxin\",\n "
},
{
"path": "test/fixtures/result.html",
"chars": 111,
"preview": "<!DOCTYPE html>\n<html>\n <body>\n <h1>view</h1>\n <label>haoxin</label>\n<label>12345</label>\n </body>\n</html>\n"
},
{
"path": "test/fixtures/result.js",
"chars": 234,
"preview": "(function(okanjo) {\n\n okanjo.mvc.registerCss('main', '<h1>view</h1>', {\n id: 'okanjo-test-main'\n });\n\n okanjo.mvc."
},
{
"path": "test/fixtures/sameprefix-result.html",
"chars": 98,
"preview": "<!DOCTYPE html>\n<html>\n <body>\n <a href=\"http://drewlustro.com\">Cool Link</a>\n </body>\n</html>\n"
},
{
"path": "test/fixtures/sameprefix-var.html",
"chars": 34,
"preview": "<a href=\"@@title_link\">@@title</a>"
},
{
"path": "test/fixtures/sameprefix.html",
"chars": 162,
"preview": "<!DOCTYPE html>\n<html>\n <body>\n @@include('./sameprefix-var.html', {\n \"title\": \"Cool Link\",\n \"title_link\": \"http"
},
{
"path": "test/fixtures/var.html",
"chars": 43,
"preview": "<label>@@name</label>\n<label>@@ age</label>"
},
{
"path": "test/fixtures/var.rot13.html",
"chars": 42,
"preview": "<ynory>@@anzr</ynory>\n<ynory>@@ntr</ynory>"
},
{
"path": "test/fixtures/view.html",
"chars": 13,
"preview": "<h1>view</h1>"
},
{
"path": "test/fixtures/view.md",
"chars": 10,
"preview": "view\n====\n"
},
{
"path": "test/fixtures/view.rot13.md",
"chars": 10,
"preview": "ivrj\n====\n"
},
{
"path": "test/fixtures-edge-case/a.html",
"chars": 116,
"preview": "<!DOCTYPE html>\n<html>\n <body>\n <!-- include b, that includes a again -->\n @@include('b.html')\n </body>\n</html>\n"
},
{
"path": "test/fixtures-edge-case/b.html",
"chars": 119,
"preview": "<!DOCTYPE html>\n<html>\n <body>\n <!-- includes a again (nested recursion) -->\n @@include('a.html')\n </body>\n</html>\n"
},
{
"path": "test/fixtures-edge-case/commented-inclusion-result.html",
"chars": 113,
"preview": "<!DOCTYPE html>\n<html>\n <body>\n <!-- this line stays, but the include should be skipped -->\n\n </body>\n</html>\n"
},
{
"path": "test/fixtures-edge-case/commented-inclusion.html",
"chars": 151,
"preview": "<!DOCTYPE html>\n<html>\n <body>\n <!-- this line stays, but the include should be skipped -->\n <!-- @@include('recursio"
},
{
"path": "test/fixtures-edge-case/dangerous.txt",
"chars": 48,
"preview": "This: $& should not trigger recursive includes.\n"
},
{
"path": "test/fixtures-edge-case/index.html",
"chars": 79,
"preview": "<!DOCTYPE html>\n<html>\n <body>\n @@include('dangerous.txt')\n </body>\n</html>\n"
},
{
"path": "test/fixtures-edge-case/recursion.html",
"chars": 129,
"preview": "<!DOCTYPE html>\n<html>\n <body>\n <!-- silly recursion, should give an error -->\n @@include('recursion.html')\n </body>"
},
{
"path": "test/fixtures-edge-case/result.html",
"chars": 101,
"preview": "<!DOCTYPE html>\n<html>\n <body>\n This: $& should not trigger recursive includes.\n\n </body>\n</html>\n"
},
{
"path": "test/fixtures-edge-case/without-trailing-newline-result.txt",
"chars": 194,
"preview": "hello world!\nThis: $& should not trigger recursive includes.\nwithout trailing newline\nThis: $& should not trigger recurs"
},
{
"path": "test/fixtures-edge-case/without-trailing-newline.txt",
"chars": 128,
"preview": "hello world!\n@@include('dangerous.txt')without trailing newline\n@@include('dangerous.txt')!@\n!!@@include('dangerous.txt'"
},
{
"path": "test/fixtures-error/for.html",
"chars": 80,
"preview": "@@for (var i = 0; i < invalid.length; i++) {\n <label>`+invalid[i]+`</label>\n }"
},
{
"path": "test/fixtures-error/if.html",
"chars": 40,
"preview": "@@if (invalid === true) {\n <h1>a</h1>\n}"
},
{
"path": "test/fixtures-flatten/index.html",
"chars": 80,
"preview": "<label>@@obj</label>\n<strong>@@obj.param1</strong>\n<strong>@@obj.param2</strong>"
},
{
"path": "test/fixtures-flatten/result.html",
"chars": 68,
"preview": "<label>@@obj</label>\n<strong>value1</strong>\n<strong>value2</strong>"
},
{
"path": "test/fixtures-indent/index.html",
"chars": 90,
"preview": "<h1>Hello</h1>\n\n<div class=\"section\">\n <span>Sub</span>\n //= include('sub.html')\n</div>\n"
},
{
"path": "test/fixtures-indent/result.html",
"chars": 261,
"preview": "<h1>Hello</h1>\n\n<div class=\"section\">\n <span>Sub</span>\n <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. "
},
{
"path": "test/fixtures-indent/sub-sub.html",
"chars": 25,
"preview": "<small>Am Dig Bo</small>\n"
},
{
"path": "test/fixtures-indent/sub.html",
"chars": 188,
"preview": "<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Laboriosam in nisi blanditiis!</p>\n<div>\n <p>Lorem ipsum d"
},
{
"path": "test/fixtures-nested/index.html",
"chars": 213,
"preview": "<!DOCTYPE html>\n<html>\n <body>\n @@include('var.html', {\n \"name\": \"haoxin\",\n \"age\": 12345,\n \"socials\": {\n "
},
{
"path": "test/fixtures-nested/result.html",
"chars": 169,
"preview": "<!DOCTYPE html>\n<html>\n <body>\n <label>haoxin</label>\n<label>12345</label>\n<strong>facebook.com/include</strong>\n<stro"
},
{
"path": "test/fixtures-nested/var.html",
"chars": 102,
"preview": "<label>@@name</label>\n<label>@@age</label>\n<strong>@@socials.fb</strong>\n<strong>@@socials.tw</strong>"
},
{
"path": "test/fixtures-nested-once/index-twice.html",
"chars": 387,
"preview": "<!DOCTYPE html>\n<html>\n <body>\n @@include_once('var.html', {\n \"name\": \"haoxin\",\n \"age\": 12345,\n \"socials\": {\n"
},
{
"path": "test/fixtures-nested-once/index.html",
"chars": 218,
"preview": "<!DOCTYPE html>\n<html>\n <body>\n @@include_once('var.html', {\n \"name\": \"haoxin\",\n \"age\": 12345,\n \"socials\": {\n"
},
{
"path": "test/fixtures-nested-once/result-twice.html",
"chars": 172,
"preview": "<!DOCTYPE html>\n<html>\n <body>\n <label>haoxin</label>\n<label>12345</label>\n<strong>facebook.com/include</strong>\n<stro"
},
{
"path": "test/fixtures-nested-once/result.html",
"chars": 169,
"preview": "<!DOCTYPE html>\n<html>\n <body>\n <label>haoxin</label>\n<label>12345</label>\n<strong>facebook.com/include</strong>\n<stro"
},
{
"path": "test/fixtures-nested-once/var.html",
"chars": 102,
"preview": "<label>@@name</label>\n<label>@@age</label>\n<strong>@@socials.fb</strong>\n<strong>@@socials.tw</strong>"
},
{
"path": "test/fixtures-operator/index.html",
"chars": 423,
"preview": "\n@@if (content.indexOf('>a') > -1) {\n <h1>a</h1>\n}\n\n@@if(content.indexOf('>a') > -1){\n {<h1>a</h1>}\n}\n\n@@if content.in"
},
{
"path": "test/fixtures-operator/result-index.html",
"chars": 110,
"preview": "\n\n <h1>a</h1>\n\n\n\n {<h1>a</h1>}\n\n\n\n <h1>a</h1>\n\n\n\n\n\n\n <h3>c</h3>\n\n\n\n\n\n\n <h3>c</h3>\n\n\n@@if(name === 'c') {\n"
},
{
"path": "test/fixtures-operator/result-suffix.html",
"chars": 135,
"preview": "\n\n <h1>a</h1>\n\n\n\n {<h1>a</h1>}\n\n\n\n <h1>a</h1>\n\n\n\n\n\n\n <h3>c</h3>\n\n\n\n\n\n\n <h3>c</h3>\n\n\n@@if(name === 'c') {\n\n}\n\n@@if(n"
},
{
"path": "test/fixtures-operator/suffix.html",
"chars": 469,
"preview": "\n@@if (content.indexOf('>a') > -1) {\n <h1>a</h1>\n}##\n\n@@if(content.indexOf('>a') > -1){\n {<h1>a</h1>}\n} ##\n\n@@if conte"
},
{
"path": "test/fixtures-recursion/index.txt",
"chars": 121,
"preview": "this is index\n\n@@include('./sub/a.txt')\n@@include('./sub/b.txt')\n\n@@include('./var.txt', {\n \"name\": \"from index.txt\"\n})"
},
{
"path": "test/fixtures-recursion/result.txt",
"chars": 128,
"preview": "this is index\n\nthis is a.txt\nthis is b.txt\nname is: from b.txt\n\n\n\nthis is b.txt\nname is: from b.txt\n\n\n\nname is: from ind"
},
{
"path": "test/fixtures-recursion/sub/a.txt",
"chars": 35,
"preview": "this is a.txt\n@@include('./b.txt')\n"
},
{
"path": "test/fixtures-recursion/sub/b.txt",
"chars": 66,
"preview": "this is b.txt\n@@include('../var.txt', {\n \"name\": \"from b.txt\"\n})\n"
},
{
"path": "test/fixtures-recursion/var.txt",
"chars": 16,
"preview": "name is: @@name\n"
},
{
"path": "test/fixtures-suffix/index.html",
"chars": 163,
"preview": "<!DOCTYPE html>\n<html>\n <body>\n @@include('../fixtures/view.html')@@\n @@include('./var.html', {\n \"name\": \"haoxin\","
},
{
"path": "test/fixtures-suffix/var.html",
"chars": 46,
"preview": "<label>@@name@@</label>\n<label>@@age@@</label>"
},
{
"path": "test/fixtures-variable/index-suffix.html",
"chars": 195,
"preview": "<ul>\n <li>\n <var>//= param1 @@</var>\n </li>\n <li>\n <var>//= obj.param1@@</var>\n </li>\n <li>\n <var>//= o"
},
{
"path": "test/fixtures-variable/index.html",
"chars": 184,
"preview": "<ul>\n <li>\n <var>//= param1</var>\n </li>\n <li>\n <var>//= obj.param1</var>\n </li>\n <li>\n <var>//= obj.par"
},
{
"path": "test/fixtures-variable/result.html",
"chars": 151,
"preview": "<ul>\n <li>\n <var>value1</var>\n </li>\n <li>\n <var>o1</var>\n </li>\n <li>\n <var>o2</var>\n </li>\n <li>\n <"
},
{
"path": "test/fixtures-webroot-variable/html-head.html",
"chars": 64,
"preview": "<head>\n <link type=stylesheet src=@@webRoot/style.css>\n</head>\n"
},
{
"path": "test/fixtures-webroot-variable/index.html",
"chars": 172,
"preview": "<!DOCTYPE html>\n<html>\n @@include('html-head.html')\n <body>\n <h1>Page</h1>\n <a href=@@webRoot/about>About</a>\n "
},
{
"path": "test/fixtures-webroot-variable/result.html",
"chars": 193,
"preview": "<!DOCTYPE html>\n<html>\n <head>\n <link type=stylesheet src=../../style.css>\n</head>\n\n <body>\n <h1>Page</h1>\n <a "
},
{
"path": "test/fixtures-webroot-variable/sub/home-link.html",
"chars": 27,
"preview": "<a href=@@webRoot>Home</a>\n"
},
{
"path": "test/fixtures-webroot-variable/sub/index.html",
"chars": 175,
"preview": "<!DOCTYPE html>\n<html>\n @@include('../html-head.html')\n <body>\n <h1>Sub Page</h1>\n <a href=@@webRoot/about>About"
},
{
"path": "test/fixtures-webroot-variable/sub/result.html",
"chars": 206,
"preview": "<!DOCTYPE html>\n<html>\n <head>\n <link type=stylesheet src=../../../style.css>\n</head>\n\n <body>\n <h1>Sub Page</h1>\n"
},
{
"path": "test/flatten.js",
"chars": 1499,
"preview": "'use strict'\n\nconst fileIncludePlugin = require('..')\nconst Vinyl = require('vinyl')\nconst should = require('should')\nco"
},
{
"path": "test/indent.js",
"chars": 912,
"preview": "'use strict'\n\nconst setIndent = require('../lib/indent')\n\nrequire('should')\n\ndescribe('## indent', () => {\n it('# basic"
},
{
"path": "test/index.js",
"chars": 11997,
"preview": "\n'use strict'\n\nconst fileIncludePlugin = require('..')\nconst Vinyl = require('vinyl')\nconst should = require('should')\nc"
},
{
"path": "test/nested-once.js",
"chars": 2393,
"preview": "'use strict'\n\nconst fileIncludePlugin = require('../lib')\nconst Vinyl = require('vinyl')\nconst should = require('should'"
},
{
"path": "test/nested.js",
"chars": 1233,
"preview": "'use strict'\n\nconst fileIncludePlugin = require('..')\nconst Vinyl = require('vinyl')\nconst should = require('should')\nco"
},
{
"path": "test/operator.js",
"chars": 1318,
"preview": "'use strict'\n\nconst parse = require('../lib/replace-operator')\nconst fs = require('fs')\n\nrequire('should')\n\ndescribe('##"
},
{
"path": "test/plugin-indent.js",
"chars": 1330,
"preview": "'use strict'\n\nconst fileIncludePlugin = require('..')\nconst Vinyl = require('vinyl')\nconst should = require('should')\nco"
},
{
"path": "test/recursion.js",
"chars": 1312,
"preview": "'use strict'\n\nconst fileIncludePlugin = require('..')\nconst Vinyl = require('vinyl')\nconst should = require('should')\nco"
},
{
"path": "test/variable.js",
"chars": 906,
"preview": "'use strict'\n\nconst replaceVariable = require('../lib/replace-variable')\nconst fs = require('fs')\n\nrequire('should')\n\nde"
},
{
"path": "test/webroot-variable.js",
"chars": 1248,
"preview": "'use strict'\n\nconst fileIncludePlugin = require('..')\nconst Vinyl = require('vinyl')\nconst should = require('should')\nco"
}
]
About this extraction
This page contains the full source code of the haoxins/gulp-file-include GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 101 files (63.5 KB), approximately 19.6k tokens, and a symbol index with 7 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.