org.eclipse.mylyn.wikitext.html.HtmlLanguageBuilder Maven / Gradle / Ivy
/*******************************************************************************
* Copyright (c) 2013, 2015 Tasktop Technologies 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:
* David Green - initial API and implementation
*******************************************************************************/
package org.eclipse.mylyn.wikitext.html;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.base.Preconditions.checkState;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.eclipse.mylyn.wikitext.html.internal.FontElementStrategy;
import org.eclipse.mylyn.wikitext.html.internal.HtmlSubsetLanguage;
import org.eclipse.mylyn.wikitext.html.internal.LiteralHtmlDocumentHandler;
import org.eclipse.mylyn.wikitext.html.internal.SpanHtmlElementStrategy;
import org.eclipse.mylyn.wikitext.parser.Attributes;
import org.eclipse.mylyn.wikitext.parser.DocumentBuilder;
import org.eclipse.mylyn.wikitext.parser.DocumentBuilder.BlockType;
import org.eclipse.mylyn.wikitext.parser.DocumentBuilder.SpanType;
import org.eclipse.mylyn.wikitext.parser.builder.HtmlDocumentBuilder;
import org.eclipse.mylyn.wikitext.parser.builder.HtmlDocumentHandler;
import org.eclipse.mylyn.wikitext.parser.markup.MarkupLanguage;
import com.google.common.base.Strings;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
/**
* Provides a way to build HTML languages that support a specific set of HTML tags.
*
* @author david.green
* @see HtmlLanguage#builder()
* @since 3.0
*/
public class HtmlLanguageBuilder {
private String name;
private final Set blockTypes = Sets.newHashSet();
private final Set spanTypes = Sets.newHashSet();
private final Map spanTypeToElementNameSubstitution = Maps.newHashMap();
private final List spanElementStrategies = new ArrayList<>();
private int headingLevel;
private LiteralHtmlDocumentHandler documentHandler;
private boolean xhtmlStrict;
HtmlLanguageBuilder() {
// prevent direct instantiation
}
/**
* Sets the {@link MarkupLanguage#getName() name} of the markup language.
*
* @param name
* the name
* @return this builder
*/
public HtmlLanguageBuilder name(String name) {
checkNotNull(name, "Must provide a name"); //$NON-NLS-1$
checkArgument(!Strings.isNullOrEmpty(name), "Name must not be empty"); //$NON-NLS-1$
checkArgument(!name.equalsIgnoreCase(HtmlLanguage.NAME_HTML), "Name must not be equal to %s", //$NON-NLS-1$
HtmlLanguage.NAME_HTML);
checkArgument(name.equals(name.trim()), "Name must not have leading or trailing whitespace"); //$NON-NLS-1$
this.name = name;
return this;
}
/**
* Adds the given {@link BlockType} to the supported syntax of the language created by this builder.
*
* Adding {@link BlockType#TABLE}, {@link BlockType#BULLETED_LIST}, {@link BlockType#NUMERIC_LIST} or
* {@link BlockType#DEFINITION_LIST} will cause the corresponding related blocks to be added. For example, adding
* {@link BlockType#BULLETED_LIST} also adds {@link BlockType#LIST_ITEM}.
*
*
* @param blockType
* the block type
* @return this builder
*/
public HtmlLanguageBuilder add(BlockType blockType) {
blockTypes.add(checkNotNull(blockType, "Must provide a blockType")); //$NON-NLS-1$
return this;
}
/**
* Adds the given {@link SpanType} to the supported syntax of the language created by this builder.
*
* @param spanType
* the span type
* @return this builder
*/
public HtmlLanguageBuilder add(SpanType spanType) {
spanTypes.add(checkNotNull(spanType, "Must provide a spanType")); //$NON-NLS-1$
return this;
}
/**
* Adds to the syntax of the language created by this builder an {@code alternativeTagName} to be used when the
* given {@link SpanType} is {@link DocumentBuilder#beginSpan(SpanType, Attributes) started}.
*
* @param spanType
* the span type
* @param alternativeTagName
* the tag name to be used
* @return this builder
* @see HtmlDocumentBuilder#setElementNameOfSpanType(SpanType, String)
*/
public HtmlLanguageBuilder addSubstitution(SpanType spanType, String alternativeTagName) {
checkNotNull(spanType, "Must provide a spanType"); //$NON-NLS-1$
checkNotNull(alternativeTagName, "Must provide an alternativeTagName"); //$NON-NLS-1$
spanTypeToElementNameSubstitution.put(spanType, alternativeTagName);
return this;
}
/**
* Adds support for headings up to and including the specified level.
*
* @param level
* the level which must be a number between 1 and 6 inclusive
* @return this builder
*/
public HtmlLanguageBuilder addHeadings(int level) {
checkArgument(level > 0 && level <= 6, "Heading level must be between 1 and 6"); //$NON-NLS-1$
headingLevel = level;
return this;
}
/**
* Adds support for the {@code } HTML tag as a {@link SpanType#SPAN}. The resulting document builder will
* convert {@link SpanType#SPAN} with {@code size} or {@code colour} CSS rules to {@code } when generating
* HTML.
*
* @return
*/
public HtmlLanguageBuilder addSpanFont() {
spanElementStrategies.add(new FontElementStrategy());
return this;
}
/**
* Indicate if the resulting document builder should attempt to conform to strict XHTML rules. The default is false.
*
* @param xhtmlStrict
* true if the language should attempt to conform to XHTML strict rules, otherwise false
* @return this builder
*/
public HtmlLanguageBuilder setXhtmlStrict(boolean xhtmlStrict) {
this.xhtmlStrict = xhtmlStrict;
return this;
}
/**
* Provides a prefix and suffix which are emitted as literals at the start and end of content created using the
* {@link MarkupLanguage#createDocumentBuilder(java.io.Writer, boolean) document builder}.
*
* @param prefix
* the prefix which is an HTML literal value that precedes the content, for example {@code ""} or
* {@code ""}. May be empty.
* @param suffix
* the prefix which is an HTML literal value that precedes the content, for example {@code ""} or
* {@code ""}. May be empty.
* @return this builder
* @see HtmlDocumentHandler
*/
public HtmlLanguageBuilder document(String prefix, String suffix) {
checkNotNull(prefix, "Must provide a prefix"); //$NON-NLS-1$
checkNotNull(suffix, "Must provide a suffix"); //$NON-NLS-1$
documentHandler = new LiteralHtmlDocumentHandler(prefix, suffix);
return this;
}
public HtmlLanguage create() {
checkState(name != null, "Name must be provided to create an HtmlLanguage"); //$NON-NLS-1$
return new HtmlSubsetLanguage(name, documentHandler, headingLevel, blockTypes, spanTypes,
spanTypeToElementNameSubstitution, spanElementStrategies, xhtmlStrict);
}
}