support CSS 'content' definition for inline elements

This is meant to be used for elements like 'colgroup' that do not have
any content.

Change-Id: I6378037555de67634397f159033599e49ba89187
Signed-off-by: Carsten Hiesserich <carsten.hie@gmail.com>
diff --git a/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/css/Styles.java b/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/css/Styles.java
index 9a9e157..e63e547 100644
--- a/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/css/Styles.java
+++ b/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/css/Styles.java
@@ -131,6 +131,13 @@
 	}
 
 	/**
+	 * @return <code>true</code> if the stylesheet defined content for this element.
+	 */
+	public boolean isContentDefined() {
+		return contentLexicalUnits.size() > 0;
+	}
+
+	/**
 	 * Returns a <code>List</code> of <code>ContentPart</code> objects representing the <code>content</code> property.<br />
 	 * The content is parsed on every access to get the actual values for attributes. Do not try to get the content via
 	 * the {@link #get(String)} method!
diff --git a/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/layout/InlineElementBox.java b/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/layout/InlineElementBox.java
index 60f7b82..d6ecd4a 100644
--- a/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/layout/InlineElementBox.java
+++ b/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/layout/InlineElementBox.java
@@ -88,10 +88,19 @@
 			}
 		}
 
-		final InlineBoxes inlines = createInlineBoxes(context, node, new ContentRange(startOffset, endOffset));
-		childList.addAll(inlines.boxes);
-		firstContentChild = inlines.firstContentBox;
-		lastContentChild = inlines.lastContentBox;
+		if (styles.isContentDefined()) {
+			// A CSS 'content' definition overrides the actual content
+			System.out.println(styles.getContent(node));
+			final String content = LayoutUtils.getGeneratedContent(context, styles, node);
+			final InlineBox child = new StaticTextBox(context, node, content);
+			childList.add(child);
+			firstContentChild = lastContentChild = child;
+		} else {
+			final InlineBoxes inlines = createInlineBoxes(context, node, new ContentRange(startOffset, endOffset));
+			childList.addAll(inlines.boxes);
+			firstContentChild = inlines.firstContentBox;
+			lastContentChild = inlines.lastContentBox;
+		}
 
 		if (endOffset > node.getEndOffset()) {
 			childList.add(new PlaceholderBox(context, node, node.getEndOffset() - node.getStartOffset()));
diff --git a/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/layout/LayoutUtils.java b/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/layout/LayoutUtils.java
index af0de8d..1df48ae 100644
--- a/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/layout/LayoutUtils.java
+++ b/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/layout/LayoutUtils.java
@@ -1,13 +1,14 @@
 /*******************************************************************************
- * Copyright (c) 2004, 2008 John Krasnay and others.
+ * Copyright (c) 2004, 2013 John Krasnay and others.
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
  * http://www.eclipse.org/legal/epl-v10.html
- * 
+ *
  * Contributors:
  *     John Krasnay - initial API and implementation
  *     Igor Jacy Lino Campista - Java 5 warnings fixed (bug 311325)
+ *     Carsten Hiesserich - make getGeneratedContent public
  *******************************************************************************/
 package org.eclipse.vex.core.internal.layout;
 
@@ -32,7 +33,7 @@
 
 	/**
 	 * Creates a list of generated inline boxes for the given pseudo-element.
-	 * 
+	 *
 	 * @param context
 	 *            LayoutContext in use
 	 * @param pseudoElement
@@ -42,7 +43,9 @@
 	 *            {@link StaticTextBox#StaticTextBox(LayoutContext, INode, String, byte)}
 	 */
 	public static List<InlineBox> createGeneratedInlines(final LayoutContext context, final IElement pseudoElement, final byte marker) {
-		final String text = getGeneratedContent(context, pseudoElement);
+		final Styles styles = context.getStyleSheet().getStyles(pseudoElement);
+		final INode parent = ((PseudoElement) pseudoElement).getParentNode();
+		final String text = getGeneratedContent(context, styles, parent);
 		final List<InlineBox> list = new ArrayList<InlineBox>();
 		if (text.length() > 0) {
 			list.add(new StaticTextBox(context, pseudoElement, text, marker));
@@ -52,7 +55,7 @@
 
 	/**
 	 * Creates a list of generated inline boxes for the given pseudo-element.
-	 * 
+	 *
 	 * @param context
 	 *            LayoutContext in use
 	 * @param pseudoElement
@@ -64,7 +67,7 @@
 
 	/**
 	 * Returns <code>true</code> if the given offset falls within the given element or range.
-	 * 
+	 *
 	 * @param elementOrRange
 	 *            Element or IntRange object representing a range of offsets.
 	 * @param offset
@@ -79,19 +82,17 @@
 	}
 
 	/**
-	 * Creates a string representing the generated content for the given pseudo-element.
-	 * 
+	 * Creates a string representing the generated content for the given node.
+	 *
 	 * @param context
 	 *            LayoutContext in use
-	 * @param pseudoElement
-	 *            PseudoElement for which the generated content is to be returned.
+	 * @param styles
+	 *            The Styles definition to get the content from
+	 * @param node
+	 *            The node passed to Styles#getContent (to get attr values from)
 	 */
-	private static String getGeneratedContent(final LayoutContext context, final IElement pseudoElement) {
-		final Styles styles = context.getStyleSheet().getStyles(pseudoElement);
-		// This cast is a bit ugly, but the parent of a PseudoElement may not be an IParent, so we can't
-		// use INode#getParent
-		assert pseudoElement instanceof PseudoElement;
-		final List<String> content = styles.getContent(((PseudoElement) pseudoElement).getParentNode());
+	public static String getGeneratedContent(final LayoutContext context, final Styles styles, final INode node) {
+		final List<String> content = styles.getContent(node);
 		final StringBuffer sb = new StringBuffer();
 		for (final String string : content) {
 			sb.append(string); // TODO: change to ContentPart
@@ -103,7 +104,7 @@
 	 * Call the given callback for each child matching one of the given display styles. Any nodes that do not match one
 	 * of the given display types cause the onRange callback to be called, with a range covering all such contiguous
 	 * nodes.
-	 * 
+	 *
 	 * @param context
 	 *            LayoutContext to use.
 	 * @param displayStyles
@@ -168,7 +169,7 @@
 	 * Call the given callback for each child matching one of the given display styles. Any nodes that do not match one
 	 * of the given display types cause the onRange callback to be called, with a range covering all such contiguous
 	 * nodes.
-	 * 
+	 *
 	 * @param context
 	 *            LayoutContext to use.
 	 * @param displayStyles
@@ -185,7 +186,7 @@
 
 	/**
 	 * Returns true if the given styles represent an element that can be the child of a table element.
-	 * 
+	 *
 	 * @param styleSheet
 	 *            StyleSheet to use.
 	 * @param element
diff --git a/org.eclipse.vex.docbook/styles/docbook-plain.css b/org.eclipse.vex.docbook/styles/docbook-plain.css
index d6653c9..f4e59e8 100644
--- a/org.eclipse.vex.docbook/styles/docbook-plain.css
+++ b/org.eclipse.vex.docbook/styles/docbook-plain.css
@@ -217,6 +217,9 @@
 
 colspec {
 	display: inline;
+	content: 'colspec';
+	font-size: smaller;
+	background-color: #B0B0B0;
 }
 
 command {