use v6.d;
use Test;
use RakuDoc::Render;

plan 13;

my $ast;
my $rv;
my RakuDoc::Processor $rdp .= new(:test);
$ast = Q:to/QAST/.AST;
    =numhead1 Test text
    QAST
$rv = $rdp.render( $ast, :pre-finalised );
like $rv.body.Str, /
    '<head>' .+?
    'caption: ｢Test text｣' .+
    'contents: ｢Test text｣' .+
    'id: ｢' .+
    'level: ｢1｣' .+
    'numeration:' .+ '1. Test text' .+
    'target: ｢Test_text｣' .+
    '</head>'
    /, 'numhead template works';

$ast = Q:to/QAST/.AST;
    =begin rakudoc
    =numhead3 This is a level 3 numheader

    Some text in a paragraph
    =end rakudoc
    QAST
$rv = $rdp.render( $ast, :pre-finalised );
like $rv.body.Str, /
     '<head>' .+?
    'caption: ｢This is a level 3 numheader｣' .+
    'contents: ｢This is a level 3 numheader｣' .+
    'level: ｢3｣' .+
    'numeration:' .+ '1.1.1' .+
    '</head>'
    /, 'increment of 3 level only works';

$ast = Q:to/AST/.AST;
    =begin rakudoc
    =numitem1 Visito
    =numitem2 Veni
    =numitem2 Vidi
    =numitem2 Vici
    =end rakudoc
    AST
$rv = $rdp.render( $ast, :pre-finalised );
like $rv.body.Str, /
    '<item-list>' .+
    '<item>' .+? 'contents' .+? 'numeration' .+ '1. Visito' .+
    '<item>' .+? 'contents' .+? 'numeration' .+ '1.1. Veni' .+
    '<item>' .+? 'contents' .+? 'numeration' .+ '1.2. Vidi' .+
    '<item>' .+? 'contents' .+? 'numeration' .+ '1.3. Vici' .+
    '</item-list>'
    /, 'simple ordered list';

$ast = Q:to/AST/.AST;
    =begin rakudoc
    The options are:
    =numitem1 Liberty
    =numitem1 Death
    =numitem1 Beer

    The tools are:

    =numitem1 Revolution
    =numitem1 Deep-fried peanut butter sandwich
    =numitem1 Keg
    =end rakudoc
    AST
$rv = $rdp.render( $ast, :pre-finalised );
like $rv.body.Str, /
    'para' .+? 'contents' .+ 'The options are:' .+
    '<item>' .+? 'contents' .+? 'numeration' .+ '1. Liberty' .+
    '<item>' .+? 'contents' .+? 'numeration' .+ '2. Death' .+
    '<item>' .+? 'contents' .+? 'numeration' .+ '3. Beer' .+
    'para' .+? 'contents' .+ 'The tools are:' .+
    '<item>' .+? 'contents' .+? 'numeration' .+ '1. Revolution' .+
    '<item>' .+? 'contents' .+? 'numeration' .+ '2. Deep-fried peanut butter sandwich' .+
    '<item>' .+? 'contents' .+? 'numeration' .+ '3. Keg'
    /, 'two ordered lists';

$ast = Q:to/AST/.AST;
    =begin rakudoc
    =numitem1 Retreat to remote Himalayan monastery
    =numitem1 Learn the hidden mysteries of space and time

    I<????>
    =counter numitem1 :!restart
    =for numitem1
    Prophet!
    =end rakudoc
    AST
$rv = $rdp.render( $ast, :pre-finalised );
like $rv.body.Str, /
    '<item>' .+? 'contents' .+? 'Retreat to remote Himalayan monastery' .+ 'numeration' .+ '1.' .+
    '<item>' .+? 'contents' .+? 'Learn the hidden mysteries of space and time' .+ 'numeration' .+ '2.' .+
    'para' .+? 'contents' .+ 'markup-I' .+ 'contents' .+ '????' .+ '/markup-I' .+
    '<item>' .+? 'contents' .+? 'Prophet!' .+ 'numeration' .+ '3.'
    /, 'continued ordered list';

$ast = Q:to/QAST/.AST;
    =begin rakudoc
    =numdefn Happy
    When you're I<not> blue.

    =numdefn Blue
    When you're not happy.
    =end rakudoc
    QAST
$rv = $rdp.render( $ast, :pre-finalised );
like $rv.body.Str, /
    '<defn-list>' .+
    '<defn>' .+
    'contents:' .+ "When you're <markup-I>" .+ 'not' .+ '/markup-I' .+ ' blue' .+
    'numeration:' .+ '｢1.' .+
    'target:' .+ 'defn_Happy' .+
    'term:' .+ 'Happy' .+
    '</defn>' .+
    '<defn>' .+
    'contents:' .+ "When you're not happy" .+
    'numeration:' .+ '｢2.' .+
    'target:' .+ 'defn_Blue' .+
    'term:' .+ 'Blue' .+
    '</defn>' .+
    '</defn-list>'
    /, 'Basic definitions';

$ast = Q:to/QAST/.AST;
    =begin rakudoc
    =numhead1 PHYSICS
    =numhead2 Newtonian
    =numhead2 Relativistic
    =begin numformula :caption<Mass-Energy Equivalence>
    E = MC²
    =end numformula
    =end rakudoc
    QAST
$rv = $rdp.render( $ast, :pre-finalised );
like $rv.body.Str, /
    '<head>' .+?
    'numeration' .+? '1. PHYSICS' .+?
    '</head>' .+?
    '<head>' .+? 'numeration' .+? '1.1. Newtonian' .+?
    '</head>' .+?
    '<head>' .+? 'numeration' .+? '1.2. Relativistic' .+?
    '</head>' .+?
    '<formula>' .+? 'numeration' .+? 'Formula 1. Mass-Energy Equivalence' .+?
    '</formula>'
/, 'default renderering';

$ast = Q:to/QAST/.AST;
    =begin rakudoc
    =config numhead1   :form<TOPIC %A - %D>
    =config numhead2   :form<%D [subtopic %A%N]>
    =config numformula :form<Equation %N: %C>
    =numhead1 PHYSICS
    =numhead2 Newtonian
    =numhead2 Relativistic
    =begin numformula :caption<Mass-Energy Equivalence>
    E = MC²
    =end numformula
    =end rakudoc
    QAST
$rv = $rdp.render( $ast, :pre-finalised );
like $rv.body.Str, /
    '<head>' .+?
    'numeration' .+? 'TOPIC A - PHYSICS' .+?
    '</head>' .+?
    '<head>' .+? 'numeration' .+? 'Newtonian [subtopic A1]' .+?
    '</head>' .+?
    '<head>' .+? 'numeration' .+? 'Relativistic [subtopic A2]' .+?
    '</head>' .+?
    '<formula>' .+? 'numeration' .+? 'Equation 1: Mass-Energy Equivalence' .+?
    '</formula>'
    /, 'pre-configured renderering';

# Enumerate blocks
# handle para, procedural table, and nested first because they are special
$ast = qq:to/QAST/.AST;
    =begin rakudoc :!toc
    =begin numpara2
    Some extra internal stuff
    =end numpara2
    =end rakudoc
    QAST
$rv = $rdp.render( $ast, :pre-finalised );
like $rv.body.Str, /
'<rakudoc>' .+? 'contents' .+?
'<para>' .+? 'contents' .+? 'Some extra' .+?
'numeration:' .+? '1.1. Some extra' .+? '</para>'
/, "para enumerates";
$ast = qq:to/QAST/.AST;
    =begin rakudoc :!toc
    Stuff
    =begin numtable2
    =row
    =cell One
    =cell Two
    =end numtable2
    =end rakudoc
    QAST
$rv = $rdp.render( $ast, :pre-finalised );
like $rv.body.Str, /
'Stuff' .+?
'<table>' .+? 'numeration:'
.+? 'Table' .+ '1.1.' .+? '</table>'
/, "procedural table enumerates";

$ast = qq:to/QAST/.AST;
    =begin rakudoc :!toc
    =numpara expect enum one
    =begin numnested
    Some extra internal stuff

    In two paras
    =end numnested
    =numpara expect enum four
    =end rakudoc
    QAST
$rv = $rdp.render( $ast, :pre-finalised );
like $rv.body.Str, /
'<rakudoc>' .+? 'contents' .+?
'<para>' .+? 'numeration' .+? '1. expect enum one' .+? '</par' .+?
'<nested>' .+? 'contents' .+?
'<para>' .+? 'contents' .+? 'Some extra' .+?
'</para>' .+?
'<para>' .+? 'contents' .+? 'In two paras' .+?
'</par' .+?
'</nested>' .+?
'<para>' .+? 'numeration' .+? '4. expect enum four' .+? '</par' .+?
/, "a numnested does not enumerate but generates paras";

my @blocks = <input output code SEMANTIC table>;
# include table in blocks when visual tables do not create a problem
subtest 'numerate blocks' => {
    plan *;
    for @blocks -> $b {
        $ast = qq:to/QAST/.AST;
        =begin rakudoc :!toc
        Stuff
        =begin num{$b}2
        | one  | two  |
        | thre | four |
        =end num{$b}2

        =end rakudoc
        QAST
        $rv = $rdp.render( $ast, :pre-finalised );
        like $rv.body.Str, /
        'Stuff' .+?
        '<' <{ $b.lc }> '>' .+? 'numeration:'
        .+? <{ $b.tc }> .+ '1.1.' .+? '</' <{ $b.lc }> '>'
        /, "$b enumerates";
    }
}

subtest 'Aliases' => {
    plan *;
    $ast = qq:to/QAST/.AST;
        =begin rakudoc :!toc
        Some text
        =numhead First
        =begin numformula :caption<Mass-Energy Equivalence> :numalias<RELFORM>
        E = MC²
        =end numformula
        =numhead2 Second
        =begin numformula :caption<Mass-Energy Equivalence> :numalias< Equation%N | EQNRELFORM>
        E = MC²
        =end numformula
        =for numformula2 :numalias<SNDEQU>
        E = MC²

        Some text with enumeration from aliases A<RELFORM>. And here is one differently formated A<EQNRELFORM>.
        And the level 2 formula A<SNDEQU>.
        =end rakudoc
        QAST
        $rv = $rdp.render( $ast, :pre-finalised );
    like $rv.body.Str, /
        'from aliases' .+?
        '<markup-A>' .+? 'Formula 1' .+?
        '<markup-A>' .+? 'Equation 2' .+?
        '<markup-A>' .+? 'Formula 2.1' .+?
    /, 'Aliases work';
}
done-testing;
