Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a way to generate document navigation using the HTML5 outline algorithm and CSS (and possibly JS)?

Is there a way to generate document navigation using the HTML5 outline algorithm and CSS (and possibly JS) like TeX can generate a table of contents?

EDIT: Is there a way to display a linked outline of an HTML document without explicitly writing it? I'm thinking of something like \tableofcontents in TeX. So an empty <nav> tag would be filled with an unordered list of links to sections in the page, for example.

like image 563
ohmygoodness Avatar asked Oct 22 '22 13:10

ohmygoodness


1 Answers

For a javascript who will create an automated toc from document outline, you will have to develop yours for the moment. [i found no copy-paste solution actually]

Study this :

  • http://code.google.com/p/h5o/
  • http://code.google.com/p/h5o/downloads/detail?name=outliner.0.5.0.62.js&can=2&q=
  • https://chrome.google.com/webstore/detail/html5-outliner/afoibpobokebhgfnknfndkgemglggomo
  • https://developer.mozilla.org/en-US/docs/HTML/Sections_and_Outlines_of_an_HTML5_document?redirectlocale=en-US&redirectslug=Sections_and_Outlines_of_an_HTML5_document

and this

  • http://blog.tremily.us/posts/HTML5_outlines/
  • http://projects.jga.me/toc/ ( jQuery plugin you might want to adapt )

[ADDON]

Suggested reading from user @unor : github.com/DylanFM/outliner sent me to this jsFiddle where there is another javascript startup.

Javascript

// See http://html5doctor.com/document-outlines/
// That article begins with info on HTML4 document outlines
// This doesn't do that yet, it just handles the HTML5 stuff beneath in the article
// I'm sure there are problems with handling that HTML5 stuff tho

var headingElements = ['H1', 'H2', 'H3', 'H4', 'H5', 'H6'],
sectioningElements = ['SECTION', 'ARTICLE', 'NAV', 'ASIDE'];

function makeOutline(root) {
var ar = [],
    el = root.firstChild,
    nested, hg;
while(el) {
    // If it's a sectioning element, create a new level in the outline
    if(sectioningElements.indexOf(el.tagName) > -1) {
        nested = makeOutline(el);
        if(nested.every(function(i){ return typeof i !== 'string'; })) {
            nested.unshift('Untitled ' + el.tagName.toLowerCase());
        }
        ar.push(nested);
    } else if(headingElements.indexOf(el.tagName) > -1) {
        ar.push(el.textContent);
    } else if(el.tagName === 'HGROUP') {
        hg = undefined;
        // Find the highest heading element within
        // Use its text, otherwhise it's untitled
        try {
            headingElements.forEach(function(t) {
                els = el.getElementsByTagName(t);
                if(els.length) {
                    hg = els[0].textContent;
                    throw BreakException;
                }
            });
        } catch(e) {}
        if(!hg) {
            hg = 'Untitled hgroup';
        }
        ar.push(hg);
    }
    el = el.nextSibling;
}
return ar;
};

var outline = makeOutline(document.body);

// This is just used for displaying the outline. 
// Inspect the outline variable to see the generated array:
// console.log(outline);

function describeOutline(outline) {
var indentForDepth = function(depth) {
    var str = '';
    for(i=depth;i>0;i--) {
        str += '\t';
    }
    return str;
},
childrenAreStrings = function(ar, depth) {
    var depth = (depth && (depth + 1)) || 1;
    return ar.map(function(item) {
        if({}.toString.call(item)=='[object Array]') {
            return childrenAreStrings(item, depth).join('\n');
        } else {
            return indentForDepth(depth) + '- ' + String(item);
        }
    });
};
// Make sure all items in ar are strings
return childrenAreStrings(outline).join('\n');    
}

(document.getElementsByTagName('pre')[0]).textContent = describeOutline(outline);
like image 176
Milche Patern Avatar answered Oct 24 '22 02:10

Milche Patern