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

  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%E8%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.