Skip to content

Commit

Permalink
Handle repeated headings.
Browse files Browse the repository at this point in the history
  • Loading branch information
qubyte authored and thlorenz committed Apr 10, 2013
1 parent 276dae0 commit 4d97c80
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 13 deletions.
43 changes: 31 additions & 12 deletions lib/transform.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,14 @@ var _ = require('underscore')
function notNull(x) { return x !== null; }

function addAnchor(mode, header) {
header.anchor = anchor(header.name, mode);
header.anchor = anchor(header.name, mode, header.instance);
return header;
}


function getHashedHeaders (_lines) {
var inCodeBlock = false;

// Turn all headers into '## xxx' even if they were '## xxx ##'
function normalize(header) {
return header.replace(/[ #]+$/, '');
Expand All @@ -29,12 +29,12 @@ function getHashedHeaders (_lines) {
})
.map(function (x, index) {
var match = /^(\#{1,8})[ ]*(.+)$/.exec(x);

return match
? { rank : match[1].length
, name : normalize(match[2])
, line : index
}
}
: null;
})
.filter(notNull)
Expand All @@ -45,12 +45,12 @@ function getUnderlinedHeaders (_lines) {
// Find headers of the form
// h1 h2
// == --

return _lines
.map(function (line, index, lines) {
if (index === 0) return null;
var rank;

if (/^==+/.exec(line)) rank = 1;
else if (/^--+/.exec(line)) rank = 2;
else return null;
Expand All @@ -65,34 +65,53 @@ function getUnderlinedHeaders (_lines) {
.value();
}

function countHeaders (headers) {
var instances = {};

for (var i = 0; i < headers.length; i++) {
var header = headers[i];
var name = header.name;

if (instances.hasOwnProperty(name)) {
instances[name]++;
} else {
instances[name] = 0;
}

header.instance = instances[name];
}

return headers;
}

module.exports = function transform(content, mode) {
var lines = content.split('\n')
, _lines = _(lines).chain()

, allHeaders = getHashedHeaders(_lines).concat(getUnderlinedHeaders(_lines))
, allHeaders = countHeaders(getHashedHeaders(_lines).concat(getUnderlinedHeaders(_lines)))
, lowestRank = _(allHeaders).chain().pluck('rank').min().value()
, linkedHeaders = _(allHeaders).map(addAnchor.bind(null, mode));

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

var toc =
'**Table of Contents** *generated with [DocToc](http://doctoc.herokuapp.com/)*'
+ '\n\n'
var toc =
'**Table of Contents** *generated with [DocToc](http://doctoc.herokuapp.com/)*'
+ '\n\n'
+ linkedHeaders
.map(function (x) {
var indent = _(_.range(x.rank - lowestRank))
.reduce(function (acc, x) { return acc + '\t'; }, '');

return indent + '- ' + x.anchor;
})
.join('\n')
.join('\n')
+ '\n';

var currentToc = _lines
.first(linkedHeaders[0].line)
.value()
.join('\n');

if (currentToc === toc) return { transformed: false };

// Skip all lines up to first header since that is the old table of content
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
},
"dependencies": {
"underscore": ">=1.3.3",
"anchor-markdown-header": "~0.2.0"
"anchor-markdown-header": "~0.3.0"
},
"devDependencies": {
"trap": "~0.3.2"
Expand Down
11 changes: 11 additions & 0 deletions test/lib/transform.js
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,17 @@ check(
].join('')
)

check(
[ '# Repeating A Title'
, ''
, '# Repeating A Title'
].join('\n')
, [ '**Table of Contents** *generated with [DocToc](http://doctoc.herokuapp.com/)*\n\n'
, '- [Repeating A Title](#repeating-a-title)\n'
, '- [Repeating A Title](#repeating-a-title-1)\n\n'
].join('')
)

// bigbucket.org
check(
[ '# My Module'
Expand Down

0 comments on commit 4d97c80

Please sign in to comment.