diff options
| author | Vojta Jina | 2013-10-17 14:16:32 -0700 | 
|---|---|---|
| committer | Igor Minar | 2013-10-18 15:35:41 -0700 | 
| commit | e8cc85f733a49ca53e8cda5a96bbaacc9a20ac7e (patch) | |
| tree | f145db33b29ee9cce531492a8332adc537033b70 /docs/src/dom.js | |
| parent | c22adbf160f32c1839fbb35382b7a8c6bcec2927 (diff) | |
| download | angular.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.js | 73 | 
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};      } | 
