/*
* (C) Copyright 2006-2011 Nuxeo SA (http://nuxeo.com/) and others.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* Contributors:
* bstefanescu
*
* $Id$
*/
package org.nuxeo.ecm.platform.rendering.wiki;
/**
* Table of contents model.
* <p>
* A simple linked list of toc entries.
*
* @author <a href="mailto:bs@nuxeo.com">Bogdan Stefanescu</a>
*/
public class Toc {
protected final Entry head;
protected Entry tail;
public Toc() {
head = new Entry();
tail = head;
head.title = "Table of Contents";
head.id = null;
}
/**
* Adds a heading to the TOC list and returns the ID of that heading (to be used for anchors).
*
* @param title the heading title
* @param level the heading level
* @return the heading id
*/
public String addHeading(String title, int level) {
Entry entry = new Entry();
entry.title = title;
entry.level = level;
if (level == tail.level) { // same level
tail.next = entry;
entry.parent = tail.parent;
entry.index = tail.index + 1;
} else if (level > tail.level) {
entry.parent = tail;
tail.firstChild = entry;
entry.index = 1;
} else {
Entry prev = tail.parent;
// FIXME: null consistency check
while (prev.level > level && prev != null) {
prev = prev.parent;
}
// FIXME: null consistency check
if (prev == null || prev.parent == null) {
throw new IllegalStateException("Invalid headers. Header levels underflowed");
}
prev.next = entry;
entry.parent = prev.parent;
entry.index = prev.index + 1;
}
if (entry.parent.id != null) {
entry.id = entry.parent.id + "." + entry.index;
} else {
entry.id = "" + entry.index;
}
tail = entry;
return entry.id;
}
public static class Entry {
public Entry parent;
public Entry next;
public Entry firstChild;
public String id;
public String title;
public int level;
public int index;
}
}