Skip to content

Commit

Permalink
correctly handling h1,2,3, etc. tags found in inlined html
Browse files Browse the repository at this point in the history
  • Loading branch information
thlorenz committed Apr 23, 2014
1 parent 680dbe5 commit fe39528
Show file tree
Hide file tree
Showing 4 changed files with 265 additions and 30 deletions.
34 changes: 11 additions & 23 deletions lib/get-html-headers.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,14 @@

var htmlparser = require('htmlparser2');

function addLinenos(src, headers) {
var current = 0, match, line;
var lines = src.split('\n');
function addLinenos(lines, headers) {
var current = 0, line;

return headers.map(function (x) {
for (var lineno = current; lineno < lines.length; lineno++) {
line = lines[lineno];
if (new RegExp(x.text[0]).test(line)) {
console.log(line)
current = lineno + 1;
current = lineno;
x.line = lineno;
x.name = x.text.join('');
return x
Expand All @@ -27,8 +25,9 @@ function rankify(headers) {
})
}

var go = module.exports = function (lines, md) {
var acc = [], grabbing = null, text = [];
var go = module.exports = function (lines) {
var md = lines.join('\n');
var headers = [], grabbing = null, text = [];

var parser = new htmlparser.Parser({
onopentag: function (name, attr) {
Expand All @@ -43,29 +42,18 @@ var go = module.exports = function (lines, md) {
onclosetag: function (name) {
if (!grabbing) return;
if (grabbing === name) {
acc.push({ text: text, tag: grabbing });
headers.push({ text: text, tag: grabbing });
grabbing = null;
text = [];
}
}
},
{ decodeEntities: true })

parser.write(src);
parser.write(md);
parser.end();

acc = addLinenos(src, acc)
acc = rankify(acc);
return acc;
}

// Test
function inspect(obj, depth) {
console.error(require('util').inspect(obj, false, depth || 5, true));
}

var fs = require('fs');
if (!module.parent && typeof window === 'undefined') {
var src = fs.readFileSync(__dirname + '/../test/fixtures/readme-with-html.md', 'utf8');
inspect(go(src));
headers = addLinenos(lines, headers)
headers = rankify(headers);
return headers;
}
19 changes: 12 additions & 7 deletions lib/transform.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,8 @@ function addAnchor(mode, header) {


function getHashedHeaders (lines) {
var inCodeBlock = false;
var inCodeBlock = false
, lineno = 0;

// Turn all headers into '## xxx' even if they were '## xxx ##'
function normalize(header) {
Expand All @@ -35,19 +36,22 @@ function getHashedHeaders (lines) {

// Find headers of the form '### xxxx xxx xx [###]'
return lines
.map(function (x, idx) {
return { lineno: idx, line: x }
})
.filter(function (x) {
if (x.match(/^```/)) {
if (x.line.match(/^```/)) {
inCodeBlock = !inCodeBlock;
}
return !inCodeBlock;
})
.map(function (x, index) {
var match = /^(\#{1,8})[ ]*(.+)\r?$/.exec(x);
.map(function (x) {
var match = /^(\#{1,8})[ ]*(.+)\r?$/.exec(x.line);

return match
? { rank : match[1].length
, name : normalize(match[2])
, line : index
, line : x.lineno
}
: null;
})
Expand Down Expand Up @@ -117,7 +121,9 @@ exports = module.exports = function transform(content, mode) {
var currentToc = info.hasStart && lines.slice(info.startIdx, info.endIdx).join('\n')
, linesToToc = getLinesToToc(lines, currentToc, info);

var headers = getHashedHeaders(linesToToc).concat(getUnderlinedHeaders(linesToToc));
var headers = getHashedHeaders(linesToToc)
.concat(getUnderlinedHeaders(linesToToc))
.concat(getHtmlHeaders(linesToToc))

headers.sort(function (a, b) {
return a.line - b.line;
Expand All @@ -129,7 +135,6 @@ exports = module.exports = function transform(content, mode) {

if (linkedHeaders.length === 0) return { transformed: false };


var toc =
'**Table of Contents** *generated with [DocToc](http://doctoc.herokuapp.com/)*'
+ '\n\n'
Expand Down
212 changes: 212 additions & 0 deletions test/fixtures/readme-with-html.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,212 @@
# dockops [![build status](https://secure.travis-ci.org/thlorenz/dockops.png)](http://travis-ci.org/thlorenz/dockops)

docker convenience functions on top of dockerode

<!-- START doctoc generated TOC please keep comment here to allow auto update -->
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
**Table of Contents** *generated with [DocToc](http://doctoc.herokuapp.com/)*

- [Installation](#installation)
- [API](#api)
- [License](#license)

<!-- END doctoc generated TOC please keep comment here to allow auto update -->

```js
var dockops = require('dockops')
var docker = dockops.createDocker({ dockerhost: dockerhost });

var images = new dockops.Images(docker);
dockops.logEvents(images, 'verbose');

var containers = new dockops.Containers(docker);
dockops.logEvents(containers, 'verbose');

build('test:uno', testUnoTar, function () {
build('toast:uno', toastUnoTar, function () {

containers.run(.. // run test:uno and toast:uno containers

containers.listRunning(function (err, res) {
inspect(res);
containers.stopRemoveGroup('test', function (err, res) {
containers.listRunning(function (err, res) {
inspect(res);
http.request({ port: 49222 }, function (res) {
console.log('--------------------------')
inspect({ status: res.statusCode, headers: res.headers })
res.pipe(process.stdout)
}).end()
})
})
})
})
})
```
[full example](https://github.com/thlorenz/dockops/blob/master/example/create-wipe.js)
![output](https://github.com/thlorenz/dockops/raw/master/assets/output.gif)
## Installation
npm install dockops
## API
<!-- START docme generated API please keep comment here to allow auto update -->
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN docme TO UPDATE -->
<div>
<div class="jsdoc-githubify">
<section>
<article>
<div class="container-overview">
<dl class="details">
</dl>
</div>
<dl>
<dt>
<h4 class="name" id="dockops::Containers"><span class="type-signature"></span>dockops::Containers<span class="signature">(docker)</span><span class="type-signature"> &rarr; {Object}</span></h4>
</dt>
<dd>
<div class="description">
<p>Creates a new containers instance that will use the given docker instance to communicate with docker.</p>
</div>
<h5>Parameters:</h5>
<table class="params">
<thead>
<tr>
<th>Name</th>
<th>Type</th>
<th class="last">Description</th>
</tr>
</thead>
<tbody>
<tr>
<td class="name"><code>docker</code></td>
<td class="type">
<span class="param-type">Object</span>
</td>
<td class="description last"><p>dockerode instance to communicate with docker</p></td>
</tr>
</tbody>
</table>
<dl class="details">
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy">
<li>
<a href="https://github.com/thlorenz/dockops/blob/master/containers.js">containers.js</a>
<span>, </span>
<a href="https://github.com/thlorenz/dockops/blob/master/containers.js#L24">lineno 24</a>
</li>
</ul></dd>
</dl>
<h5>Returns:</h5>
<div class="param-desc">
<p>initialized containers</p>
</div>
<dl>
<dt>
Type
</dt>
<dd>
<span class="param-type">Object</span>
</dd>
</dl>
</dd>
<dt>
<h4 class="name" id="dockops::Containers::activePorts"><span class="type-signature"></span>dockops::Containers::activePorts<span class="signature">(cb)</span><span class="type-signature"></span></h4>
</dt>
<dd>
<div class="description">
<p>Lists all running containers by the ports they expose.</p>
</div>
<h5>Parameters:</h5>
<table class="params">
<thead>
<tr>
<th>Name</th>
<th>Type</th>
<th class="last">Description</th>
</tr>
</thead>
<tbody>
<tr>
<td class="name"><code>cb</code></td>
<td class="type">
<span class="param-type">function</span>
</td>
<td class="description last"><p>called back with list of containers hashed by their port number</p></td>
</tr>
</tbody>
</table>
<dl class="details">
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy">
<li>
<a href="https://github.com/thlorenz/dockops/blob/master/containers.js">containers.js</a>
<span>, </span>
<a href="https://github.com/thlorenz/dockops/blob/master/containers.js#L275">lineno 275</a>
</li>
</ul></dd>
</dl>
</dd>
<dt>
<h4 class="name" id="dockops::Containers::clean"><span class="type-signature"></span>dockops::Containers::clean<span class="signature">(id, cb)</span><span class="type-signature"></span></h4>
</dt>
<dd>
<div class="description">
<p>Stops and/or kills and then removes a container.</p>
<p>Heavy machinery clean operation.
It was useful when running on arch with docker not always working as promised.
This may not be needed anymore as docker got more stable.</p>
</div>
<h5>Parameters:</h5>
<table class="params">
<thead>
<tr>
<th>Name</th>
<th>Type</th>
<th class="last">Description</th>
</tr>
</thead>
<tbody>
<tr>
<td class="name"><code>id</code></td>
<td class="type">
<span class="param-type">string</span>
</td>
<td class="description last"><p>container id</p></td>
</tr>
<tr>
<td class="name"><code>cb</code></td>
<td class="type">
<span class="param-type">function</span>
</td>
<td class="description last"><p>called back after container was cleaned or maximum attempts were exceeded</p></td>
</tr>
</tbody>
</table>
<dl class="details">
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy">
<li>
<a href="https://github.com/thlorenz/dockops/blob/master/containers.js">containers.js</a>
<span>, </span>
<a href="https://github.com/thlorenz/dockops/blob/master/containers.js#L97">lineno 97</a>
</li>
</ul></dd>
</dl>
</dd>
</article>
</section>
</div>
*generated with [docme](https://github.com/thlorenz/docme)*
</div>
<!-- END docme generated API please keep comment here to allow auto update -->
## License
MIT
30 changes: 30 additions & 0 deletions test/transform-html.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
'use strict';
/*jshint asi: true */

var test = require('tap').test
, transform = require('../lib/transform')

test('\ngiven a file that includes html with header tags', function (t) {
var content = require('fs').readFileSync(__dirname + '/fixtures/readme-with-html.md', 'utf8');
var headers = transform(content);

t.deepEqual(
headers.toc.split('\n')
, [ '**Table of Contents** *generated with [DocToc](http://doctoc.herokuapp.com/)*',
'',
'- [Installation](#installation)',
'- [API](#api)',
'\t\t- [dockops::Containers(docker) → {Object}](#dockopscontainersdocker-→-{object})',
'\t\t\t- [Parameters:](#parameters)',
'\t\t\t- [Returns:](#returns)',
'\t\t- [dockops::Containers::activePorts(cb)](#dockopscontainersactiveportscb)',
'\t\t\t- [Parameters:](#parameters-1)',
'\t\t- [dockops::Containers::clean(id, cb)](#dockopscontainerscleanid-cb)',
'\t\t\t- [Parameters:](#parameters-2)',
'- [License](#license)',
'' ]
, 'generates correct toc for non html and html headers'
)

t.end()
})

0 comments on commit fe39528

Please sign in to comment.