KefirBB user guide

(version 0.4)



I speak English bad. So less words, more code.

Overview

KefirBB is a library for text processing. For example for convert bb-codes to html. Simple example:

TextProcessor processor = BBProcessorFactory.getInstance().create();
assert processor.process("[b]Oi![/b]").equals("<span style=\"font-weight:bold;\">Oi!</span>");

At this code I create the BB-code processor and convert bb-code text to html-text.

Version 0.4 futures

Prefix and suffix added in each converted text.

    <prefix>&lt;!-- bbcodes begin --&gt;</prefix>
    <suffix>&lt;!-- bbcodes end --&gt;</suffix>

At this configuration defines prefix and suffix comment. Result of uses:

    assert "<!-- bbcodes begin -->Test<!-- bbcodes end -->".equals(processor.process(“Test”));

Parameters be added. You can define parameter in XML configuration file, XML properties file, properties format file or at runtime. Runtime parameters have biggest priority. After XML-properties file, properties file and XML configuration parameters.

The example of XML-configuration fragment defined parameters:

    <params>
        <param name="var1" value="1"/>
        <param name="var2" value="2"/>
    </params>

Format of XML-properties and properties files see in the Java API documentation, class java.util.Properties. When you use default method BBProcessorFactory.create() factory try find properties file:
kefirbb.properties – for properties file
kefirbb.properties.xml – for XML properties file.

If you want use programming parameters use ru.perm.kefir.bbcode.ConfigurationFactory and ru.perm.kefir.bbcode.Configuration classes.

Configuration

KefirBB can be configured with XML configuration file. In configuration file defines codes and scopes. Codes define how text will be converted. Scope defines allow codes when codes put in other codes.

To define codes uses tag “code”. In this tags uses tags “pattern” and “template”. “pattern” uses to parse code in source text. “template” uses to generate new text.

    <code name="aquote">
        <pattern>[aquote]<var/>[/aquote]</pattern>
        <template>&amp;laquo;<var/>&amp;raquo;</template>
    </code>

Tag “var” uses to define put-in text wich can be processed. Tag “var” also can have attributes: name, parse, scope, inherit.

name – define variable name
parse – if this attribute is false, then var mustn't process
scope – define scope to process text
inherit – if true, parsing with scope of wrap code

Tag “scope” define scope and contains list of “coderef” tag, wich specify code.

Default configuration file places at “classpath:/ru/perm/kefir/bbcode/default.xml”:

<?xml version="1.0" encoding="utf-8"?>
<configuration xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
               xmlns="http://kefir-bb.sourceforge.net/schemas"
               xsi:schemaLocation="http://kefir-bb.sourceforge.net/schemas http://kefir-bb.sourceforge.net/schemas/kefir-bb-0.4.xsd">
    <!-- XML escape symbols -->
    <scope name="escapeXml">
        <coderef name="amp"/>
        <coderef name="apos"/>
        <coderef name="lt"/>
        <coderef name="gt"/>
        <coderef name="quot"/>
    </scope>
    <code name="amp" priority="100">
        <pattern>&amp;</pattern>
        <template>&amp;amp;</template>
    </code>
    <code name="apos" priority="100">
        <pattern>&apos;</pattern>
        <template>&amp;apos;</template>
    </code>
    <code name="lt" priority="100">
        <pattern>&lt;</pattern>
        <template>&amp;lt;</template>
    </code>
    <code name="gt" priority="100">
        <pattern>&gt;</pattern>
        <template>&amp;gt;</template>
    </code>
    <code name="quot" priority="100">
        <pattern>&quot;</pattern>
        <template>&amp;quot;</template>
    </code>

    <!-- Root scope. This scope uses when processor started work and by default, if not set other scope -->
    <scope name="ROOT" parent="escapeXml">
        <coderef name="br1"/>
        <coderef name="br2"/>
        <coderef name="br3"/>
        <coderef name="br4"/>
        <coderef name="slash"/>
        <coderef name="left_square_bracket"/>
        <coderef name="right_square_bracket"/>
        <coderef name="bold"/>
        <coderef name="u"/>
        <coderef name="s"/>
        <coderef name="i"/>
        <coderef name="code"/>
        <coderef name="img"/>
        <coderef name="img1"/>
        <coderef name="url1"/>
        <coderef name="url2"/>
        <coderef name="url3"/>
        <coderef name="url4"/>
        <coderef name="url5"/>
        <coderef name="url6"/>
        <coderef name="url7"/>
        <coderef name="url8"/>
        <coderef name="color"/>
        <coderef name="quote"/>
        <coderef name="aquote"/>
        <coderef name="size"/>
        <coderef name="symbol"/>
        <coderef name="table"/>
    </scope>

    <!-- line feed characters -->
    <code name="br1" priority="3">
        <pattern>&#x0A;&#x0D;</pattern>
        <template>&lt;br/&gt;</template>
    </code>
    <code name="br2" priority="2">
        <pattern>&#x0D;&#x0A;</pattern>
        <template>&lt;br/&gt;</template>
    </code>
    <code name="br3" priority="1">
        <pattern>&#x0A;</pattern>
        <template>&lt;br/&gt;</template>
    </code>
    <code name="br4" priority="0">
        <pattern>&#x0D;</pattern>
        <template>&lt;br/&gt;</template>
    </code>

    <!--
        Escape bb-code symbols
        double slash to slash
        slash + square bracket to square bracket
     -->
    <code name="slash" priority="10">
        <pattern>\\</pattern>
        <template>\</template>
    </code>
    <code name="left_square_bracket" priority="9">
        <pattern>\[</pattern>
        <template>[</template>
    </code>
    <code name="right_square_bracket" priority="9">
        <pattern>\]</pattern>
        <template>]</template>
    </code>

    <!-- Simple formatting -->
    <code name="bold">
        <pattern>[b]<var/>[/b]</pattern>
        <template>&lt;span style=&quot;font-weight:bold;&quot;&gt;<var/>&lt;/span&gt;</template>
    </code>
    <code name="u">
        <pattern>[u]<var/>[/u]</pattern>
        <template>&lt;span style=&quot;text-decoration:underline;&quot;&gt;<var/>&lt;/span&gt;</template>
    </code>
    <code name="s">
        <pattern>[s]<var/>[/s]</pattern>
        <template>&lt;span style=&quot;text-decoration:line-through;&quot;&gt;<var/>&lt;/span&gt;</template>
    </code>
    <code name="i">
        <pattern>[i]<var/>[/i]</pattern>
        <template>&lt;span style=&quot;font-style:italic;&quot;&gt;<var/>&lt;/span&gt;</template>
    </code>

    <!-- Quote code block -->
    <code name="code">
        <pattern>[code]<var scope="codeScope"/>[/code]</pattern>
        <template>&lt;pre&gt;<var/>&lt;/pre&gt;</template>
    </code>
    <scope name="codeScope" parent="escapeXml">
        <coderef name="br1"/>
        <coderef name="br2"/>
        <coderef name="br3"/>
        <coderef name="br4"/>
        <coderef name="slash"/>
        <coderef name="left_square_bracket"/>
        <coderef name="right_square_bracket"/>
        <coderef name="symbol"/>
    </scope>

    <!-- Insert image -->
    <code name="img">
        <pattern>[img]http://<var scope="escapeXml"/>[/img]</pattern>
        <template>&lt;img src=&quot;http://<var/>&quot;/&gt;</template>
    </code>
    <code name="img1">
        <pattern>[img]/<var scope="escapeXml"/>[/img]</pattern>
        <template>&lt;img src=&quot;/<var/>&quot;/&gt;</template>
    </code>

    <!-- Links. http, malto protocols -->
    <code name="url1" priority="6">
        <pattern>[url=http://<var name="url" scope="escapeXml"/>]<var name="text"/>[/url]</pattern>
        <template>&lt;a href=&quot;http://<var name="url"/>&quot;&gt;<var name="text"/>&lt;/a&gt;</template>
    </code>
    <code name="url2" priority="5">
        <pattern>[url=mailto:<var name="url" scope="escapeXml"/>]<var name="text"/>[/url]</pattern>
        <template>&lt;a href=&quot;mailto:<var name="url"/>&quot;&gt;<var name="text"/>&lt;/a&gt;</template>
    </code>
    <code name="url7" priority="5">
        <pattern>[url=/<var name="url" scope="escapeXml"/>]<var name="text"/>[/url]</pattern>
        <template>&lt;a href=&quot;/<var name="url"/>&quot;&gt;<var name="text"/>&lt;/a&gt;</template>
    </code>
    <code name="url3" priority="4">
        <pattern>[url=<var name="url" scope="escapeXml"/>]<var name="text"/>[/url]</pattern>
        <template>&lt;a href=&quot;http://<var name="url"/>&quot;&gt;<var name="text"/>&lt;/a&gt;</template>
    </code>
    <code name="url4" priority="3">
        <pattern>[url]http://<var name="url" scope="escapeXml"/>[/url]</pattern>
        <template>&lt;a href=&quot;http://<var name="url"/>&quot;&gt;http://<var name="url"/>&lt;/a&gt;</template>
    </code>
    <code name="url5" priority="2">
        <pattern>[url]mailto:<var name="url" scope="escapeXml"/>[/url]</pattern>
        <template>&lt;a href=&quot;mailto:<var name="url"/>&quot;&gt;mailto:<var name="url"/>&lt;/a&gt;</template>
    </code>
    <code name="url8" priority="2">
        <pattern>[url]/<var name="url" scope="escapeXml"/>[/url]</pattern>
        <template>&lt;a href=&quot;/<var name="url"/>&quot;&gt;/<var name="url"/>&lt;/a&gt;</template>
    </code>
    <code name="url6" priority="1">
        <pattern>[url]<var name="url" scope="escapeXml"/>[/url]</pattern>
        <template>&lt;a href=&quot;http://<var name="url"/>&quot;&gt;<var name="url"/>&lt;/a&gt;</template>
    </code>

    <!-- Font color -->
    <code name="color">
        <pattern>[color=<var name="color" scope="escapeXml"/>]<var name="text"/>[/color]</pattern>
        <template>&lt;span style=&quot;color:<var name="color"/>;&quot;&gt;<var name="text"/>&lt;/span&gt;</template>
    </code>

    <!-- Qote block -->
    <code name="quote">
        <pattern>[quote]<var/>[/quote]</pattern>
        <template>&lt;blockquote&gt;<var/>&lt;/blockquote&gt;</template>
    </code>

    <!-- angle quotes -->
    <code name="aquote">
        <pattern>[aquote]<var/>[/aquote]</pattern>
        <template>&amp;laquo;<var/>&amp;raquo;</template>
    </code>

    <!-- Font size -->
    <code name="size">
        <pattern>[size=<var name="size" scope="escapeXml"/>]<var name="text"/>[/size]</pattern>
        <template>&lt;span style=&quot;font-size:<var name="size"/>;&quot;&gt;<var name="text"/>&lt;/span&gt;</template>
    </code>

    <!-- Special html symbols -->
    <code name="symbol">
        <pattern>[symbol=<var scope="escapeXml"/>/]</pattern>
        <template>&amp;<var/>;</template>
    </code>

    <!-- Simple table -->
    <code name="table">
        <pattern>[table]<var scope="tableScope"/>[/table]</pattern>
        <template>&lt;table&gt;<var/>&lt;/table&gt;</template>
    </code>
    <scope name="tableScope" parent="escapeXml">
        <coderef name="tr"/>
    </scope>
    <code name="tr">
        <pattern>[tr]<var scope="trScope"/>[/tr]</pattern>
        <template>&lt;tr&gt;<var/>&lt;/tr&gt;</template>
    </code>
    <scope name="trScope" parent="escapeXml">
        <coderef name="td"/>
    </scope>
    <code name="td">
        <pattern>[td]<var/>[/td]</pattern>
        <template>&lt;td&gt;<var/>&lt;/td&gt;</template>
    </code>
</configuration>

Schema location is “http://kefir-bb.sourceforge.net/schemas/kefir-bb-0.4.xsd”:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
            targetNamespace="http://kefir-bb.sourceforge.net/schemas"
            xmlns="http://kefir-bb.sourceforge.net/schemas"
            elementFormDefault="qualified"
            attributeFormDefault="unqualified">
    <xsd:complexType name="templateType" mixed="true">
        <xsd:choice minOccurs="0" maxOccurs="unbounded">
            <xsd:element name="var">
                <xsd:complexType>
                    <xsd:attribute name="name" type="xsd:string" default="variable"/>
                </xsd:complexType>
            </xsd:element>
        </xsd:choice>
    </xsd:complexType>

    <xsd:element name="configuration">
        <xsd:complexType>
            <xsd:sequence>
                <xsd:element name="params" minOccurs="0" maxOccurs="1">
                    <xsd:complexType>
                        <xsd:choice minOccurs="0" maxOccurs="unbounded">
                            <xsd:element name="param">
                                <xsd:complexType>
                                    <xsd:attribute name="name" type="xsd:string" use="required"/>
                                    <xsd:attribute name="value" type="xsd:string" use="required"/>
                                </xsd:complexType>
                            </xsd:element>
                        </xsd:choice>
                    </xsd:complexType>
                </xsd:element>
                <xsd:element name="prefix" type="templateType" minOccurs="0" maxOccurs="1"/>
                <xsd:element name="suffix" type="templateType" minOccurs="0" maxOccurs="1"/>
                <xsd:choice minOccurs="0" maxOccurs="unbounded">
                    <xsd:element name="code">
                        <xsd:complexType>
                            <xsd:sequence>
                                <xsd:element name="pattern">
                                    <xsd:complexType mixed="true">
                                        <xsd:choice minOccurs="0" maxOccurs="unbounded">
                                            <xsd:element name="var">
                                                <xsd:complexType>
                                                    <xsd:attribute name="name" type="xsd:string" default="variable"/>
                                                    <xsd:attribute name="parse" type="xsd:boolean" default="true"/>
                                                    <xsd:attribute name="scope" type="xsd:IDREF" default="ROOT"/>
                                                    <xsd:attribute name="inherit" type="xsd:boolean" default="false"/>
                                                </xsd:complexType>
                                            </xsd:element>
                                        </xsd:choice>
                                    </xsd:complexType>
                                </xsd:element>
                                <xsd:element name="template" type="templateType"/>
                            </xsd:sequence>
                            <xsd:attribute name="name" type="xsd:ID"/>
                            <xsd:attribute name="priority" type="xsd:integer" default="0"/>
                        </xsd:complexType>
                    </xsd:element>
                    <xsd:element name="scope">
                        <xsd:complexType>
                            <xsd:choice minOccurs="0" maxOccurs="unbounded">
                                <xsd:element name="coderef">
                                    <xsd:complexType>
                                        <xsd:attribute name="name" type="xsd:IDREF" use="required"/>
                                    </xsd:complexType>
                                </xsd:element>
                            </xsd:choice>
                            <xsd:attribute name="name" type="xsd:ID" use="required"/>
                            <xsd:attribute name="parent" type="xsd:string" use="optional"/>
                            <xsd:attribute name="ignoreText" type="xsd:boolean" use="optional" default="false"/>
                        </xsd:complexType>
                    </xsd:element>
                </xsd:choice>
            </xsd:sequence>
        </xsd:complexType>
    </xsd:element>
</xsd:schema>

Usage

This code find configuration file at “classpath:/kefirbb.xml”, which must be defined by user. If can't using default configuration file at “classpath:/ru/perm/kefir/bbcode/default.xml”:

TextProcessor processor = BBProcessorFactory.getInstance().create();

This code create TextProcessor using configuration file from resource:

TextProcessor processor = BBProcessorFactory.getInstance().createFromResource("ru/perm/kefir/bbcode/test.xml");

This code create TextProcessor using configuration file from resource:

TextProcessor processor = BBProcessorFactory.getInstance().create("kefirbb.xml");
TextProcessor processor = BBProcessorFactory.getInstance().create(new File("kefirbb.xml"));

Next code use ru.perm.kefir.bbcode.ConfigurationFactory and ru.perm.kefir.bbcode.Configuration classes:

Configuration configuration = ConfigurationFactory.getInstance().create();
configuration.setParam("myparameter", "any object");
TextProcessor processor = configuration.create();