New Research: Supply Chain Attack on Axios Pulls Malicious Dependency from npm.Details →
Socket
Book a DemoSign in
Socket

gulp-processhtml

Package Overview
Dependencies
Maintainers
1
Versions
14
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

gulp-processhtml - npm Package Compare versions

Comparing version
0.0.6
to
1.0.0
+7
test/expected/attributes.html
<!doctype html>
<html>
<head></head>
<body>
<script src="app.js"></script>
</body>
</html>
<!doctype html>
<html>
<head>
<link rel="stylesheet" href="style.min.css">
</head>
<body>
<script src="app.min.js"></script>
</body>
</html>
<!doctype html>
<html>
<head>
<style>
body { background: teal; }
</style>
</head>
<body>
<h1 class="title">This is a title</h1>
<section><p>This is a section</p></section>
</body>
</html>
<!doctype html>
<html>
<head></head>
<body>
</body>
</html>
<!doctype html>
<html>
<head></head>
<body>
<!-- build:[src] app.js -->
<script src="livereload.js"></script>
<!-- /build -->
</body>
</html>
<!doctype html>
<html>
<head>
<!-- build:css style.min.css -->
<link rel="stylesheet" href="style.css">
<!-- /build -->
</head>
<body>
<!-- build:js app.min.js -->
<script src="app.js"></script>
<!-- /build -->
</body>
</html>
<!doctype html>
<html>
<head>
<style>
<!-- build:include includes/styles.css -->
<!-- Me thinks it should replace whatever is in between the build tags -->
<div>FOO</div>
<!-- /build -->
</style>
</head>
<body>
<!-- build:include includes/title.html --><!-- /build -->
<!-- build:include includes/section.html --><!-- /build -->
</body>
</html>
<section><p>This is a section</p></section>
body { background: teal; }
<h1 class="title">This is a title</h1>
<!doctype html>
<html>
<head></head>
<body>
<!-- build:remove -->
<script src="livereload.js"></script>
<!-- /build -->
</body>
</html>
'use strict';
var assert = require('assert')
, os = require('os')
, fs = require('fs')
, path = require('path')
, through = require('through2')
, gulp = require('gulp')
, htmlprocessor = require('../');
require('mocha');
function process(input, options, output, done) {
options = options || {};
gulp
.src(input)
.pipe(htmlprocessor(options))
.pipe(through.obj(function (file, enc) {
var actual = file.contents.toString(enc);
fs.readFile(output, function (err, data) {
assert.deepEqual(actual, data.toString(enc));
done();
});
}));
}
describe('gulp-processhtml', function () {
it('should process html comments', function (done) {
process('test/fixtures/basic.html', null, 'test/expected/basic.html', done);
});
it('should remove content', function (done) {
process('test/fixtures/remove.html', null, 'test/expected/remove.html', done);
});
it('should transform attributes', function (done) {
process('test/fixtures/attributes.html', null, 'test/expected/attributes.html', done);
});
it('should include files', function (done) {
process('test/fixtures/include.html', null, 'test/expected/include.html', done);
});
});
+19
-167

@@ -1,181 +0,33 @@

var through = require('through')
, os = require('os')
, path = require('path')
var through = require('through2')
, gutil = require('gulp-util')
, PluginError = gutil.PluginError
, File = gutil.File
, fs = require('fs')
, transformer;
, HTMLProcessor = require('htmlprocessor')
, PluginError = gutil.PluginError;
module.exports = function(fileName, options) {
transformer = {
replace: function (content, section, line, asset) {
return content.replace(line, section.indent + asset);
},
var processor = new HTMLProcessor(options);
attr: function (content, section, line, lineContent) {
var reg, replaced;
// only run attr replacer for the block content
reg = new RegExp('(\\s*(?:' + section.attr + ')=[\'"])(.*?)(".*)', 'gi');
replaced = lineContent.replace(reg, function (wholeMatch, start, asset, end) {
// check if only the path was provided to leave the original asset name intact
asset = (!path.extname(section.asset) && /\//.test(section.asset))? section.asset + path.basename(asset) : section.asset;
return start + asset + end;
});
return content.replace(line, replaced);
},
function processContent(file, enc, cb) {
var content;
css: function (content, section, line) {
return transformer.replace(content, section, line, '<link rel="stylesheet" href="' + section.asset + '">');
},
js: function (content, section, line) {
return transformer.replace(content, section, line, '<script src="' + section.asset + '"></script>');
},
remove: function (content, section, line) {
var escaped = line.replace(/([.?*+\^=!:$\[\]\\(){}|\-])/g, '\\$1')
, regReplace = new RegExp(escaped.replace(/^\s*|[\r\n]+\s*/g, '\\s*').replace(/\n{1}$/g, '\\n'));
return content.replace(regReplace, '');
},
include: function (content, section, line, asset) {
var file = fs.readFileSync(path.join(process.cwd(), section.asset), 'utf8')
, i
, l;
l = line.length;
while ((i = content.indexOf(line)) !== -1) {
content = content.substring(0, i) +
section.indent + file.toString().trim() + content.substring(i + l);
}
return content;
}
};
function findSections(content, marker) {
var lines
, line
, i
, l
, sections = []
, section
, regStart
, regEnd
, inside
, buildStart
, buildEnd
, attr;
regStart = new RegExp('<!--\\s*' + marker + ':(\\[?[\\w-]+\\]?)(?::(\\w+))?(?:\\s*([^\\s]+)\\s*-->)*');
regEnd = new RegExp('(?:<!--\\s*)*\\/' + marker + '\\s*-->');
lines = content.split(/\n/);
l = lines.length;
for (i = 0; i < l; i += 1) {
line = lines[i];
buildStart = line.match(regStart);
buildEnd = regEnd.test(line);
if (buildStart) {
inside = true;
attr = buildStart[1].match(/(?:\[([\w-]+)\])*/)[1];
section = {
type: attr ? 'attr' : buildStart[1],
attr: attr,
target: buildStart[2],
asset: buildStart[3],
indent: /^\s*/.exec(line)[0],
raw: []
};
}
if (inside && section) {
section.raw.push(line);
}
if (inside && buildEnd) {
inside = false;
sections.push(section);
}
}
return sections;
}
module.exports = function(fileName, opt){
var buffer = []
, firstFile;
if (!fileName) {
throw new PluginError('gulp-processhtml', 'Missing fileName option for gulp-processhtml');
}
opt = opt || {};
opt.newLine = opt.newLine || gutil.linefeed;
opt.marker = opt.marker || 'build';
function processContents(file) {
var contents
, sections
, section
, line
, content
, i
, l;
if (file.isNull()) {
return;
}
if (file.isStream()) {
return this.emit('error', new PluginError('gulp-processhtml', 'Streaming not supported'));
this.emit('error', new PluginError('gulp-processhtml', 'Streams aren\'t supported'));
return cb();
}
if (!firstFile) {
firstFile = file;
}
if (file.isBuffer()) {
content = processor.processContent(file.contents.toString(enc), file.path);
contents = file.contents.toString('utf8').replace(/\r\n/g, '\n');
sections = findSections(contents, opt.marker);
if (options && options.process) {
content = processor.template(content, processor.data, options.templateSettings);
}
l = sections.length;
for (i = 0; i < l; i += 1) {
section = sections[i];
line = section.raw.join(opt.newLine);
content = section.raw.slice(1, -1).join(opt.newLine);
contents = transformer[section.type](contents, section, line, content);
file.contents = new Buffer(content, enc);
}
buffer.push(contents);
}
function endStream(){
var joinedContents
, joinedPath
, joinedFile;
this.push(file);
cb();
};
if (buffer.length === 0) {
return this.emit('end');
}
joinedContents = buffer.join(opt.newLine);
joinedPath = path.join(firstFile.base, fileName);
joinedFile = new File({
cwd: firstFile.cwd,
base: firstFile.base,
path: joinedPath,
contents: new Buffer(joinedContents)
});
this.emit('data', joinedFile);
this.emit('end');
}
return through(processContents, endStream);
return through.obj(processContent);
};
{
"name": "gulp-processhtml",
"version": "0.0.6",
"version": "1.0.0",
"description": "Process html files at build time to modify them as you wish",

@@ -15,11 +15,15 @@ "repository": {

"keywords": [
"gulpplugin"
"gulpplugin",
"htmlprocessor",
"process",
"html"
],
"dependencies": {
"through": "*",
"gulp-util": "*"
"gulp-util": "latest",
"htmlprocessor": "latest",
"through2": "latest"
},
"devDependencies": {
"mocha": "*",
"should": "*"
"gulp": "latest",
"mocha": "latest"
},

@@ -26,0 +30,0 @@ "author": "Julien Castelain <jcastelain@gmail.com> (http://www.punkscum.org)",

+20
-14
#gulp-processhtml
This is a port of Denis Ciccale's [grunt-processhtml](https://github.com/dciccale/grunt-processhtml)
[Grunt](http://www.gruntjs.com) plugin for [gulp.js](http://www.gulpjs.com).
This gulp-plugin uses Denis Ciccale's [node-htmlprocessor](https://github.com/dciccale/node-htmlprocessor),
to process/transform html files.
Some things are still missing (includes and templates)
#Usage
###Install the dependencies:

@@ -20,15 +16,16 @@

var gulp = require('gulp')
, processhtml = require('gulp-processhtml');
, processhtml = require('gulp-processhtml')
, opts = { /* plugin options */ };
gulp.task('default', function () {
gulp.src('index.html')
.pipe(processhtml('test.html'))
.pipe(gulp.dest('./'));
gulp.src('./*.html')
.pipe(processhtml(opts))
.pipe(gulp.dest('dist'));
});
```
###Example usage
###Example usage
You might need to change some attributes in your html, when you're releasing
for a different environment.
for a different environment.

@@ -46,7 +43,7 @@ Using this plugin, you can transform this:

<body>
<!--build:js app.min.js-->
<script src="app.js"></script>
<!--/build -->
<!--build:remove-->

@@ -73,2 +70,11 @@ <script src="http://192.168.0.1:35729/livereload.js?snipver=1"></script>

###Credits
[Denis Ciccale](https://twitter.com/tdecs)
###Note
Since I don't usually use [Gulp](http://gulpjs.com) and prefer [G.N.U. Make](http://www.gnu.org/software/make),
feel free to ask me to transfer this repo to your GitHub account if you want to maintain it.
<section>
<p>This is a section</p>
</section>
body { background: teal; }
<h1 class="title">This is a title</h1>
var processhtml = require('../')
, should = require('should')
, os = require('os')
, path = require('path')
, File = require('gulp-util').File
, Buffer = require('buffer').Buffer;
require('mocha');
describe('gulp-processhtml', function() {
describe('processhtml()', function() {
it('should processhtml comments', function(done) {
var stream = processhtml('processed.html')
, fakeFile = new File({
cwd: './',
base: './',
path: './file.html',
contents: new Buffer([
'<!doctype html>',
'<html>',
'<head>',
' <!-- build:css style.min.css -->',
' <link rel="stylesheet" href="style.css">',
' <!-- /build -->',
'</head>',
'<body>',
' <!-- build:js app.min.js -->',
' <script src="app.js"></script>',
' <!-- /build -->',
'</body>',
'</html>'
].join('\n'))
});
stream.on('data', function (newFile) {
var newFilePath
, expectedFilePath;
should.exist(newFile);
should.exist(newFile.path);
should.exist(newFile.relative);
should.exist(newFile.contents);
newFilePath = path.resolve(newFile.path);
expectedFilePath = path.resolve('./processed.html');
newFilePath.should.equal(expectedFilePath);
newFile.relative.should.equal('processed.html');
Buffer.isBuffer(newFile.contents).should.equal(true);
String(newFile.contents).should.equal([
'<!doctype html>',
'<html>',
'<head>',
' <link rel="stylesheet" href="style.min.css">',
'</head>',
'<body>',
' <script src="app.min.js"></script>',
'</body>',
'</html>'
].join('\n'));
done();
});
stream.write(fakeFile);
stream.end();
});
it('should handle carriage returns', function(done) {
var stream = processhtml('processed.html')
, fakeFile = new File({
cwd: './',
base: './',
path: './file.html',
contents: new Buffer([
'<!doctype html>',
'<html>',
'<head>',
' <!-- build:css style.min.css -->',
' <link rel="stylesheet" href="style.css">',
' <!-- /build -->',
'</head>',
'<body>',
' <!-- build:js app.min.js -->',
' <script src="app.js"></script>',
' <!-- /build -->',
'</body>',
'</html>'
].join('\r\n'))
});
stream.on('data', function (newFile) {
var newFilePath
, expectedFilePath;
should.exist(newFile);
should.exist(newFile.path);
should.exist(newFile.relative);
should.exist(newFile.contents);
newFilePath = path.resolve(newFile.path);
expectedFilePath = path.resolve('./processed.html');
newFilePath.should.equal(expectedFilePath);
newFile.relative.should.equal('processed.html');
Buffer.isBuffer(newFile.contents).should.equal(true);
String(newFile.contents).should.equal([
'<!doctype html>',
'<html>',
'<head>',
' <link rel="stylesheet" href="style.min.css">',
'</head>',
'<body>',
' <script src="app.min.js"></script>',
'</body>',
'</html>'
].join('\n'));
done();
});
stream.write(fakeFile);
stream.end();
});
it('should remove content', function(done) {
var stream = processhtml('processed.html')
, fakeFile = new File({
cwd: './',
base: './',
path: './file.html',
contents: new Buffer([
'<!doctype html>',
'<html>',
'<head></head>',
'<body>',
' <!-- build:remove -->',
' <script src="livereload.js"></script>',
' <!-- /build -->',
'</body>',
'</html>'
].join('\n'))
});
stream.on('data', function (newFile) {
var newFilePath
, expectedFilePath;
should.exist(newFile);
should.exist(newFile.path);
should.exist(newFile.relative);
should.exist(newFile.contents);
Buffer.isBuffer(newFile.contents).should.equal(true);
String(newFile.contents).should.equal([
'<!doctype html>',
'<html>',
'<head></head>',
'<body>',
'</body>',
'</html>'
].join('\n'));
done();
});
stream.write(fakeFile);
stream.end();
});
it('should transform attributes', function(done) {
var stream = processhtml('processed.html')
, fakeFile = new File({
cwd: './',
base: './',
path: './file.html',
contents: new Buffer([
'<!doctype html>',
'<html>',
'<head></head>',
'<body>',
' <!-- build:[src] app.js -->',
' <script src="livereload.js"></script>',
' <!-- /build -->',
'</body>',
'</html>'
].join('\n'))
});
stream.on('data', function (newFile) {
var newFilePath
, expectedFilePath;
should.exist(newFile);
should.exist(newFile.path);
should.exist(newFile.relative);
should.exist(newFile.contents);
Buffer.isBuffer(newFile.contents).should.equal(true);
String(newFile.contents).should.equal([
'<!doctype html>',
'<html>',
'<head></head>',
'<body>',
' <script src="app.js"></script>',
'</body>',
'</html>'
].join('\n'));
done();
});
stream.write(fakeFile);
stream.end();
});
it('should include files', function(done) {
var stream = processhtml('processed.html')
, fakeFile = new File({
cwd: './',
base: './',
path: './file.html',
contents: new Buffer([
'<!doctype html>',
'<html>',
'<head>',
' <style>',
' <!-- build:include test/fixtures/styles.css -->',
' <!-- Me thinks it should replace whatever is in between the build tags -->',
' <div>FOO</div>',
' <!-- /build -->',
' </style>',
'</head>',
'<body>',
'<!-- build:include test/fixtures/title.html --><!-- /build -->',
'<!-- build:include test/fixtures/section.html --><!-- /build -->',
'</body>',
'</html>'
].join('\n'))
});
stream.on('data', function (newFile) {
var newFilePath
, expectedFilePath;
should.exist(newFile);
should.exist(newFile.path);
should.exist(newFile.relative);
should.exist(newFile.contents);
Buffer.isBuffer(newFile.contents).should.equal(true);
String(newFile.contents).should.equal([
'<!doctype html>',
'<html>',
'<head>',
' <style>',
' body { background: teal; }',
' </style>',
'</head>',
'<body>',
'<h1 class="title">This is a title</h1>',
'<section>',
' <p>This is a section</p>',
'</section>',
'</body>',
'</html>'
].join('\n'));
done();
});
stream.write(fakeFile);
stream.end();
});
});
});