aboutsummaryrefslogtreecommitdiffstats
path: root/docs/src/dom.js
diff options
context:
space:
mode:
authorVojta Jina2013-10-17 14:16:32 -0700
committerIgor Minar2013-10-18 15:35:41 -0700
commite8cc85f733a49ca53e8cda5a96bbaacc9a20ac7e (patch)
treef145db33b29ee9cce531492a8332adc537033b70 /docs/src/dom.js
parentc22adbf160f32c1839fbb35382b7a8c6bcec2927 (diff)
downloadangular.js-e8cc85f733a49ca53e8cda5a96bbaacc9a20ac7e.tar.bz2
chore(docs): generate header ids for better linking
- generate ids for all headers - collect defined anchors - check broken links (even if the page exists, but the anchor/id does not)
Diffstat (limited to 'docs/src/dom.js')
-rw-r--r--docs/src/dom.js73
1 files changed, 56 insertions, 17 deletions
diff --git a/docs/src/dom.js b/docs/src/dom.js
index 897a1831..e696faf4 100644
--- a/docs/src/dom.js
+++ b/docs/src/dom.js
@@ -4,6 +4,7 @@
exports.DOM = DOM;
exports.htmlEscape = htmlEscape;
+exports.normalizeHeaderToId = normalizeHeaderToId;
//////////////////////////////////////////////////////////
@@ -16,10 +17,36 @@ function htmlEscape(text){
.replace(/\}\}/g, '<span>}}</span>');
}
+function nonEmpty(header) {
+ return !!header;
+}
+
+function idFromCurrentHeaders(headers) {
+ if (headers.length === 1) return headers[0];
+ // Do not include the first level title, as that's the title of the page.
+ return headers.slice(1).filter(nonEmpty).join('_');
+}
+
+function normalizeHeaderToId(header) {
+ if (typeof header !== 'string') {
+ return '';
+ }
+
+ return header.toLowerCase()
+ .replace(/<.*>/g, '') // html tags
+ .replace(/[\!\?\:\.\']/g, '') // special characters
+ .replace(/&#\d\d;/g, '') // html entities
+ .replace(/\(.*\)/mg, '') // stuff in parenthesis
+ .replace(/\s$/, '') // trailing spaces
+ .replace(/\s+/g, '-'); // replace whitespaces with dashes
+}
+
function DOM() {
this.out = [];
this.headingDepth = 0;
+ this.currentHeaders = [];
+ this.anchors = [];
}
var INLINE_TAGS = {
@@ -44,17 +71,28 @@ DOM.prototype = {
},
html: function(html) {
- if (html) {
- var headingDepth = this.headingDepth;
- for ( var i = 10; i > 0; --i) {
- html = html
- .replace(new RegExp('<h' + i + '(.*?)>([\\s\\S]+)<\/h' + i +'>', 'gm'), function(_, attrs, content){
- var tag = 'h' + (i + headingDepth);
- return '<' + tag + attrs + '>' + content + '</' + tag + '>';
- });
- }
- this.out.push(html);
- }
+ if (!html) return;
+
+ var self = this;
+ // rewrite header levels, add ids and collect the ids
+ html = html.replace(/<h(\d)(.*?)>([\s\S]+?)<\/h\1>/gm, function(_, level, attrs, content) {
+ level = parseInt(level, 10) + self.headingDepth; // change header level based on the context
+
+ self.currentHeaders[level - 1] = normalizeHeaderToId(content);
+ self.currentHeaders.length = level;
+
+ var id = idFromCurrentHeaders(self.currentHeaders);
+ self.anchors.push(id);
+ return '<h' + level + attrs + ' id="' + id + '">' + content + '</h' + level + '>';
+ });
+
+ // collect anchors
+ html = html.replace(/<a name="(\w*)">/g, function(match, anchor) {
+ self.anchors.push(anchor);
+ return match;
+ });
+
+ this.out.push(html);
},
tag: function(name, attr, text) {
@@ -85,17 +123,18 @@ DOM.prototype = {
h: function(heading, content, fn){
if (content==undefined || (content instanceof Array && content.length == 0)) return;
+
this.headingDepth++;
+ this.currentHeaders[this.headingDepth - 1] = normalizeHeaderToId(heading);
+ this.currentHeaders.length = this.headingDepth;
+
var className = null,
anchor = null;
if (typeof heading == 'string') {
- var id = heading.
- replace(/\(.*\)/mg, '').
- replace(/[^\d\w\$]/mg, '.').
- replace(/-+/gm, '-').
- replace(/-*$/gm, '');
+ var id = idFromCurrentHeaders(this.currentHeaders);
+ this.anchors.push(id);
anchor = {'id': id};
- var classNameValue = id.toLowerCase().replace(/[._]/mg, '-');
+ var classNameValue = this.currentHeaders[this.headingDepth - 1]
if(classNameValue == 'hide') classNameValue = '';
className = {'class': classNameValue};
}