Skip to content

Руководство пользователя (русский)

Mikhail Mangushev edited this page Jan 16, 2017 · 7 revisions

Руководство пользователя

Руководство пользователя KefirBB, версия 1.2, русский язык.

Введение

KefirBB — это Java-библиотека для преобразования текста между различными форматами. Изначально KefirBB разрабатывалась для преобразования BB-кодов в HTML. Однако гибкие возможности конфигурирования позволили использовать её и для других преобразований. Например, для преобразования XML в HTML или для фильтрации HTML-тэгов.

Новое в версии 1.2

  • Полная поддержка Textile от TxStyle.
  • Частичная поддержка Markdown от Markdown.
  • Тэги для URL-адресов и Email: <url/>, <email/> — соответственно.
  • Условный тэг для шаблонов.

Новое в версии 1.1

  • Добавлены тэги паттерна начала строки, конца строки и пустой строки: <bol/>, <eol/>, <blankline/> — соответственно.
  • В паттерне можно указывать тэги-призраки (ghost). Если парсер встречает такой тэг, позиция курсора не меняется.
  • Добавлены действия для переменных.
  • Можно указывать несколько паттернов в одном коде.

Новое в версии 1.0

  • Изменены названия пакетов на org.kefirsf.bb.
  • Добавлена возможность не учитывать регистр при создании кодов.
  • Значительно увеличена производительность.
  • Добалено ограничение на максимальную вложенность кодов для предотвращения java.lang.StackOverflowError
  • Конфигурация для фильтрации HTML.

Начало работы

Для начала, Вам нужно подключить библиотеку kefirbb к вашему проекту. Для Maven-проектов достаточно прописать зависимость.

<dependency>
    <groupId>org.kefirsf</groupId>
    <artifactId>kefirbb</artifactId>
    <version>1.2</version>
</dependency>

Для остальных проектов достаточно скачать kefirbb-1.2.jar и проследить, чтобы он был добавлен в classpath приложения.

Преобразованием текста занимаются объекты, реализующие интерфейс org.kefirsf.bb.TextProcessor.

public interface TextProcessor {
    public CharSequence process(CharSequence source);
    public String process(String source);
    public StringBuilder process(StringBuilder source);
    public StringBuffer process(StringBuffer source);
}

Как видно, интерфейс содержит несколько простых методов, которые получают на вход текст в объектах различных типов, преобразовывают его, а затем возращают преобразованный текст в объекте того же типа.

Чтобы получить стандартный TextProcessor для преобразования BB-кодов в HTML, нужно воспользоваться фабрикой org.kefirsf.bb.BBProcessorFactory.

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

Теперь мы можем использовать его для преобразования нашего текста.

assert "<b>text</b>".equals(processor.process("[b]text[/b]"));

Объект processor является потокобезопасным. Это означает, что его можно использовать в нескольких потоках одновременно.

Дополнительные возможности

Библиотека KefirBB имеет очень гибкую конфигурацию, которая позволяет использовать её не только для преобразования BB-кодов в HTML, но и для других преобразований текста. Например, для фильтрации HTML, введенного пользователем или для исключения специальных символов. Пользовтель, так же, может создать свою конфигурацию, практически для любого преобразования текста.

Фильтрация HTML

В составе библиотеки KefirBB содержится конфигурация для фильтрации HTML. Фильтрацию HTML необходимо применять над текстами, введенными пользователем, для предотвращения XSS-атак, а так же во избежание проблем с версткой.

TextProcessor processor = BBProcessorFactory.getInstance()
    .createFromResource(ConfigurationFactory.SAFE_HTML_CONFIGURATION_FILE);
assert "<b>text</b>".equals(processor.process("<b onclick=\"alert('Attack!');\">text</b>"));

Textile

KefirBB полностью поддерживает язык разметки Textile. Описание конфигурации можно найти по адресу TxStyle.

TextProcessor processor = BBProcessorFactory.getInstance()
    .createFromResource(ConfigurationFactory.TEXTILE_CONFIGURATION_FILE);
assert "<p><b>text</b></p>".equals(processor.process("**text**"));

Markdown

В версию 1.2 включена частичная поддержка языка разметки Markdown. Описание синтаксиса можно найти на странице Markdown Syntax. Текущая реализация не поддерживает в полной мере списки и цитирование.

TextProcessor processor = BBProcessorFactory.getInstance()
    .createFromResource(ConfigurationFactory.MARKDOWN_CONFIGURATION_FILE);
assert "&lt;p&gt;&lt;strong&gt;text&lt;/strong&gt;&lt;/p&gt;".equals(processor.process("**text**"));

Исключение специальных последовательностей

Часто встает задача исключения специальных последовательностей символов из текста и замены их другими последовательностями. Для этой цели, библиотека KefirBB содержит специальный класс org.kefirsf.bb.EscapeProcessor. Класс содержит конструктор, на вход которому подается массив последовательностей для исключения и замены.

TextProcessor processor = new EscapeProcessor(
    new String[][]{
        {"a", "4"},
        {"e", "3"},
        {"l", "1"},
        {"o", "0"}
    }
);
assert "4bcd3fghijk1mn0pqrstuvwxyz".equals(processor.process("abcdefghijklmnopqrstuvwxyz"));

Исключение специальных символов XML

Исключение специальных символов XML может понадобиться для вставки произвольного текста в XML или HTML документ. Эта задача появлется достаточно регулярно, поэтому библиотека KefirBB содержит специальную фабрику, которая строит объект org.kefirsf.bb.EscapeProcessor, сконфигурированный для исключения специальных символов XML.

TextProcessor processor = EscapeXmlProcessorFactory.getInstance().create();
assert "&lt;escape tag&gt;".equals(processor.process("<escape tag>"));

Конфигурация пользователя

Программист может создать свою собственную конфигурацию процессора для своих специфических нужд. Конфигурация может быть задана декларативно в XML файле или программно. Существует несколько способов использовать свою конфигурацию.

Первый способ — это назвать файл конфигурации kefirbb.xml и поместить его в корень в classpath. После чего, воспользоваться стандартной фабрикой.

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

Фабрика сначала ищет конфигурацию по пути classpath*:kefirbb.xml и только если не находит, получает стандартную конфигурацию по пути classpath*:org/kefirsf/bb/default.xml. Отдельные параметры конфигурации могут быть вынесены в файлы kefirbb.properties и kefirbb.properties.xml, имеющие стандартный синтаксис java.util.Properties.

Однако, первый способ не может удовлетворить все потребности. Иногда требуется использовать несколько конфигураций или нет возможности разместить файл конфигурации в корне classpath. В этом случае можно использовать загрузку конфигурации из ресурсов.

TextProcessor processor = BBProcessorFactory.getInstance().createFromResource("my/package/config.xml");

Можно получить конфигурацию из файла одним из двух способов.

TextProcessor processor = BBProcessorFactory.getInstance().create("config.xml");

или

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

Можно использовать конфигурацию, созданную программно.

Configuration configuration  = new Configuration();
...
TextProcessor processor = BBProcessorFactory.getInstance().create(configuration);

Программную конфигурацию можно получить из XML-конфигурации при помощи фабрики org.kefirsf.bb.ConfigurationFactory.

Конфигурация

Декларативная конфигурация

Файл конфигурации — это XML-файл описывающий преобразование текста. Постоянный адрес схемы в Интернет (http://kefirsf.org/kefirbb/schema/kefirbb-1.2.xsd). В качестве корневого должен быть использован тэг configuration без атрибутов.

Пример простой конфигурации для процессора, фильтрующего спецсимволы XML:

<?xml version="1.0" encoding="utf-8"?>
<configuration xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
               xmlns="http://kefirsf.org/kefirbb/schema"
               xsi:schemaLocation="http://kefirsf.org/kefirbb/schema http://kefirsf.org/kefirbb/schema/kefirbb-1.2.xsd">
    <code>
        <pattern>&amp;</pattern>
        <template>&amp;amp;</template>
    </code>
    <code>
        <pattern>&apos;</pattern>
        <template>&amp;apos;</template>
    </code>
    <code>
        <pattern>&lt;</pattern>
        <template>&amp;lt;</template>
    </code>
    <code>
        <pattern>&gt;</pattern>
        <template>&amp;gt;</template>
    </code>
    <code>
        <pattern>&quot;</pattern>
        <template>&amp;quot;</template>
    </code>
</configuration>

Коды

Код — это основная единица преобразования текста. Именно код определяет какой фрагмент текста должен быть преобразован и как он должен быть преобразован.

Код определяется при помощи тэга code. Внутри которого обязательны 2 тэга:

  • pattern — образец по которому находится фрагмент текста, который должен быть обработан, начиная с версии 1.1, паттернов может быть несколько в одном коде;
  • template — шаблон для генерации нового текста.

Так же у тэга code определены 2 аттрибута:

  • name — название кода;
  • priority — приоритет кода (чем больше тем выше приоритет, по умолчанию "0").

Пример тэга code:

<code name="bold">
    <pattern ignoreCase="true">[b]<var inherit="true"/>[/b]</pattern>
    <template>&lt;b&gt;<var/>&lt;/b&gt;</template>
</code>

Тэг code может быть определен непосредственно внутри тэга configuration или внутри тэга scope.

Паттерны

Тэг pattern может содержать текст и тэги: var, constant, junk, bol, eol, blankline, url, email. Во время обработки, процессор ищет фрагменты текста соответствующие тексту и константам в тэге pattern кода. Для тэга pattern можно так же указать атрибут ignoreCase, типа boolean. Если значение атрибута ignoreCase равно true, сравнение текста с образцом не будет зависеть от регистра.

Тэг var введен для определения переменных значений и имеет следующие атрибуты:

  • name — название переменной, по умолчанию variable;
  • parse — флаг указывающий на то, требуется ли обработка текста переменной, по умолчанию true;
  • regex — регулярное выражение, которому должна удовлетворять переменная, используется только если parse=false;
  • scope — определяет область видимости, которая будет использована для обработки текста переменной, используется только если parse=true, по умолчанию ROOT;
  • inherit — определяет что нужно унаследовать область видимости от внешнего кода, по умолчанию false;
  • transparent — определяет что переменная должна быть видна внешнему коду, по умолчанию false, введен для обработки атрибутов;
  • action — действие, которую нужно проделать с переменной:
    • rewrite — переписывает значение переменной, поведение по умолчанию;
    • append — добавляет к уже имеющемуся значению переменной новое значение;
    • check — проверяет что текущее значение переменной совпадает с тем что в тексте.
  • ghost — указывает на то что позицию курсора менять не нужно.

Тэг constant используется для обозначения константных значений в тэге pattern. Имеет следующие атрибуты:

  • value — значение константы;
  • ignoreCase — указывает на необходимость игнорировать регистр символов;
  • ghost — указывает на то что позицию курсора менять не нужно.

Тэг junk игнорирует все символы в исходном тексте до терминатора.

Тэг bol служит индикатором начала строки. Многие языки разметки, опираются на начало строки, поэтому он и был введен. Следует учесть, что при обработке тэга bol текущая позиция не изменяется и курсор по прежнему будет находиться на начале строки, поэтому нельзя после тэга bol ставить тэг var с областью видимости, включающей этот же код. Это приведет к появлению бесконечного цикла.

Тэг eol — конец строки. Обрабатывает символы конца строки, независимо от системы, в которой они были поставлены. Имеет следующие аттрибуты:

  • ghost — указывает на то что позицию курсора менять не нужно.

Тэг blankline — пустая строка. Имеет следующие аттрибуты:

  • ghost — указывает на то что позицию курсора менять не нужно.

Тэг url испольуется для обозначения URL-адресов. Имеет следующие аттрибуты:

  • name — название переменной, в которую будет помещен URL-адрес, по умолчанию url;
  • local — позволяет использовать локальные адреса;
  • schemaless — позволяет использовать адреса без указания схемы, в этом случае все адреса будут HTTP;
  • ghost — указывает на то что позицию курсора менять не нужно.

Тэг email — парсит email-адреса. Имеет следующие аттрибуты:

  • name — название переменной, в которую будет помещен email-адрес, по умолчанию email;
  • ghost — указывает на то что позицию курсора менять не нужно.
Шаблоны

Тэг template может содержать текст и тэги var и if.

Тэг var используется для подстановки в результирующий текст значений переменных. Имеет следующие аттрибуты:

  • name — название переменной, значение которой нужно подставить в текст;
  • function — позволяет модифицировать значение переменной перед подстановкой. В настоящее время доступны следующие функции:
    • value — значение переменной, поведение по умолчанию;
    • length — длина текста переменной.

Условный тэг if содержит аттрибут name и проверяет, была ли ранее проинициализирована переменная с данным именем. Если переменная с данным именем действительно была проинициализирована в данном коде, то в результирующий текст попадет содержимое тэга if. В противном случае — нет. Тэг if, так же как и тэг template может содержать текст, тэги var и if.

Область видимости

Область видимости определяет какие коды могут быть использованы для обработки фрагмента текста. По умолчанию, используется область видимости с именем ROOT. Даже если она не определена в конфигурации то она все равно будет создана и в нее будут включены все коды определенные в тэге configuration но не в тэгах scope. Это удобно — для простых конфигурация с небольшим количеством кодов, разработчик может вовсе не заботиться об областях видимости.

Область видимости определяется при помощи тэга scope, который может находиться внутри тэга configuration. Для тэга scope определны следующие атрибуты:

  • name — название области видимости;
  • parent — область видимости из которой будут унаследованы все коды;
  • ignoreText — означает что при обработке текста в этой области видимости нужно игнорировать весь текст, который не относится ни к одному из допустимых внутри этой области видимости кодов;
  • strong — указывает на то что в тексте могут содержаться только тэги из данной области видимости;
  • min — указывает минимальное количество тэгов из данной области видимости, которые должны содержаться в тексте, по умолчанию -1 — не определено;
  • max — указывает максимальное количество тэгов из данной области видимости, которые могут содержаться в тексте, по умолчанию -1 — не определено.

Внутри тэга scope допустимы тэги:

  • code — для определения кода (см. выше);
  • coderef — для ссылки на код, определенный вне тэга scope. У тэга coderef определен один атрибут name, который должен совпадать с именем кода.

Параметры

Параметры — это заранее определенные переменные, которые могут быть использованы при генерации текста в кодах, префиксе и суффиксе. Параметры определяются внутри тэга params при помощи тэгов param, у которых есть 2 атрибута:

  • name — название переменной;
  • value — значение.

Например:

<params>
    <param name="music" value="Punk"/>
</params>

Так же параметры могут быть заданы в отдельном файле kefirbb.properties или kefirbb.properties.xml в classpath. Форматы файлов определены в классе java.util.Properties.

Префикс и суффикс

Префикс и суффикс добавляются в начале и конце обрабатываемого текста соответственно. Определяются при помощи тэгов prefix и suffix, аналогично тэгу template.

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

Программная конфигурация

Программная кофигурация задается классом org.kefirsf.bb.conf.Configuration. Пример:

// Create configuration
Configuration cfg = new Configuration();

// Set the prefix and suffix
cfg.setPrefix(new Template(Arrays.asList(new Constant("["))));
cfg.setSuffix(new Template(Arrays.asList(new Constant("]"))));

// Configure default scope
Scope scope = new Scope(Scope.ROOT);

// Create code and add it to scope
Code code = new Code();
code.setPattern(new Pattern(Arrays.asList(new Constant("val"))));
code.setTemplate(new Template(Arrays.asList(new NamedValue("value"))));

Set<Code> codes = new HashSet<Code>();
codes.add(code);
scope.setCodes(codes);

// Set scope to configuration
cfg.setRootScope(scope);

// Set the parameter
Map<String, Object> params = new HashMap<String, Object>();
params.putAll(cfg.getParams());
params.put("value", "KefirBB");
cfg.setParams(params);

// Test the configuration
TextProcessor processor = BBProcessorFactory.getInstance().create(cfg);
assert "[KefirBB]".equals(processor.process("val"));