The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.
NAME
    Text::Xatena - Text-to-HTML converter with Xatena syntax.

SYNOPSIS
      use Text::Xatena;

      my $thx = Text::Xatena->new;
      $thx->format($string);

      # with some aggressive functions
      my $thx = Text::Xatena->new(
          inline => Text::Xatena::Inline::Aggressive->new(cache => Cache::MemoryCache->new)
      );
      $thx->format($string);

    Customizing inline formatting rule

      Text::Xatena->new(
          inline => MyInline->new
      )->format($string);

      package MyInline;
      use strict;
      use warnings;
      use Text::Xatena::Inline::Base -Base;
  
      match qr{\@([a-z0-9]+)} => sub {
          my ($self, $twitter_id) = @_;
          sprintf('<a href="http://twitter.com/%s">@%s</a>',
              $twitter_id,
              $twitter_id,
          );
      };
  
      1;

DESCRIPTION
    Text::Xatena is a text-to-html converter.

    Text::Xatena is comfortably to writing usual diary and blog, especially
    for programmers, writers treating long text.

  What is Xatena
    Xatena syntax is similar to Hatena syntax (implemented as Text::Hatena),
    but is independent from Hatena services and has more expandability.

    Most block level syntax notations are supported and more compatibility
    with Hatena::Diary than Text::Hatena 0.20.

    And don't support rare syntax or what isn't to be done of syntax
    formatter. (for example, linking keywords)

SYNTAX
    Basically, Xatena convert single line breaks to "<br/"> and double line
    breaks to "<p"> element except "Stop P" syntax.

      fooo
      bar

      baz

    is converted to following:

      <p>fooo<br/>bar</p>
      <p>baz</p>

  Blockquote
      >>
      quoted text

      foobar
      <<

    is converted to following:

      <blockquote>
      <p>quoted text</p>
      <p>foobar</p>
      </blockquote>

   with cite
      >http://example.com/>
      foobar
      <<

    is converted to following:

      <blockquote cite="http://example.com/">
        <p>quote</p>
        <cite><a href="http://example.com/">http://example.com/</a></cite>
      </blockquote>

  Pre
      >|
      pre <a href="">formatted</a>
      |<

    is converted to following:

      <pre>
      pre <a href="">formatted</a>
      </pre>

  Super pre
      >||
      super pre <a>
      ||<

    is converted to following:

      <pre>
      super pre &lt;a&gt;
      </pre>

   with lang
      >|perl|
      use Text::Xatena;
      ||<

    is converted to following:

      <pre class="code lang-perl">
      use Text::Xatena;
      </pre>

  Stop P
    Stop insert p or br.

      ><blockquote>
      <p>
      hogehoge br
      </p>
      </blockquote><

    is converted to following:

      <blockquote>
      <p>
      hogehoge br
      </p>
      </blockquote><

   with custom block level element
      ><ins><
      foobar
      ></ins><

    is convert with auto inserting p to

      <ins>
      <p>foobar</p>
      </ins>

  Section
    Create structured sections by * following heading.

      * head1

      foobar

      ** head2

      *** head3

    is converted to following:

      <div class="section">
      <h3>head1</h3>
      <p>foobar</p>
        <div class="section">
        <h4>head2</h4>
          <div class="section">
          <h5>head3</h5>
          </div>
        </div>
      </div>

  List
   unordered list
      - ul
      - ul
      -- ul
      -- ul
      --- ul
      - ul

    is converted to following:

      <ul>
        <li>ul</li>
        <li>ul</li>
        <li>
          <ul>
            <li>ul</li>
            <li>ul</li>
            <li>
              <ul>
                <li>ul</li>
              </ul>
            </li>
          </ul>
        </li>
        <li>ul</li>
      </ul>

   ordered list
      + ol
      + ol
      ++ ol
      ++ ol
      +++ ol
      + ol

    is converted to following:

      <ol>
        <li>ol</li>
        <li>ol</li>
        <li>
          <ol>
            <li>ol</li>
            <li>ol</li>
            <li>
              <ol>
                <li>ol</li>
              </ol>
            </li>
          </ol>
        </li>
        <li>ol</li>
      </ol>

   mixed list
      - ul
      - ul
      -+ ol
      -+ ol
      -+ ol
      - ul

   definition list
      :definition:description
      :definition:description

    is converted to following:

      <dl>
        <dt>definition</dt>
        <dd>description</dd>
        <dt>definition</dt>
        <dd>description</dd>
      </dl>

   multiline
    This is incompatible syntax with Hatena::Diary

      :definition:
      :: description
      :definition:
      :: description

  Table
      |*foo|*bar|*baz|
      |test|test|test|
      |test|test|test|

    is converted to following:

      <table>
        <tr>
          <th>foo</th>
          <th>bar</th>
          <th>baz</th>
        </tr>
        <tr>
          <td>test</td>
          <td>test</td>
          <td>test</td>
        </tr>
        <tr>
          <td>test</td>
          <td>test</td>
          <td>test</td>
        </tr>
      </table>

  Inline syntax
    Autolink http:// ftp:// mailto://
        http://example.com/
        ftp://example.com/
        mailto:cho45@lowreal.net
        [http://example.com/]

        # using Xatena::Inline::Aggressive
        [http://example.com/]
        [http://example.com/:title] # auto retrieving from url
        [http://example.com/:title=Foobar]
        [http://example.com/:barcode] # show qrcode with google chart API

    Deter inline syntax
        []http://example.com/[]

    Footnote syntax
        Perl((most famous light weight language))

      is converted to

        Perl<a href="#fn1">*1</a>

      and footnote object is available in inline object, so you will do
      expand it like following:

        my $thx = Text::Xatena->new;
        my $inline = Text::Xatena::Inline->new;
        $thx->inline($inline);
        my $formatted = $thx->format('aaa((foobar)) bbb((barbaz))');
        my $out = '';
        $out .= '<div class="body">';
        $out .= $formatted;
        $out .= '</div>';
        $out .= '<div class="notes">';
        for my $footnote (@{ $inline->footnotes }) {
           $out .= sprintf('<div class="footnote" id="#fn%d">*%d: %s</div>',
             $footnote->{number},
             $footnote->{number},
             $footnote->{note},
           );
        }
        $out .= '</div>';

  Compatibility with Hatena::Diary syntax
    Some default behaviors of Xatena syntax are different from Hatena::Diary
    syntax.

    Big differences:

    1. Hatena::Diary syntax converts single break to "<p"> block but Xatena
    converts it to "<br/">.
    2. Hatena::Diary syntax converts * (heading notation) to simple "<hn">
    element but Xatena converts it to "<div class="section"">
    3. Xatena support multiline definition list

    But Xatena supports Hatena::Diary compatible mode, you can change the
    behavior with a option.

      my $thx = Text::Xatena->new(hatena_compatible => 1);

  Customize templates in formatting
    If you want to customize HTML, you can specify templates in
    Text::Xatena#new. This is interpreted as Text::MicroTemplate.

    You should reuse Text::Xatena object for performance.

      my $thx = Text::Xatena->new(
        templates => {
          'Section' => q[
            <section class="level-{{= $level }}">
                <h1>{{= $title }}</h1>
                {{= $content }}
            </section>
          ],
        }
      );

AUTHOR
    cho45 <cho45@lowreal.net>

SEE ALSO
    Text::Hatena

    <http://hatenadiary.g.hatena.ne.jp/keyword/%E3%81%AF%E3%81%A6%E3%81%AA%E
    8%A8%98%E6%B3%95%E4%B8%80%E8%A6%A7>>

LICENSE
    This library is free software; you can redistribute it and/or modify it
    under the same terms as Perl itself.