Spreadsheet-HTML

 view release on metacpan or  search on metacpan

bin/benchmark-spreadsheet-html  view on Meta::CPAN

    $table->as_HTML;
}

sub html_tiny {
    my $h = HTML::Tiny->new;
    $h->table( [ map $h->tr( [ map $h->td( $_ ), @$_ ] ), @$data ]);
}

sub html_autotag {
    my $auto = HTML::AutoTag->new;
    $auto->tag( tag => 'table', cdata => [ map { tag => 'tr', cdata => [ map { tag => 'td', cdata => $_, }, @$_ ], }, @$data ] );
}

sub dbix_xhtml_table {
    my $table = DBIx::XHTML_Table->new( $data );
    $table->output;
}

sub html_fromarrayref {
    HTML::FromArrayref::HTML( [ table => {}, map [ tr => {}, map [ td => $_ ], @$_ ], @$data ] );
}

lib/Spreadsheet/HTML.pm  view on Meta::CPAN

        $args{data} = [@{ _transpose( $args{data} ) }];

    } elsif ($args{theta} == 270) {

        $args{data} = [ CORE::reverse @{ _transpose( $args{data} ) }];
    }

    if ($args{scroll}) {
        my ($js, %new_args) = Spreadsheet::HTML::Presets::Scroll::scroll(
            %args,
            data => [ map [ map $_->{cdata}, @$_ ], @{ $args{data} } ],
        );
        for (keys %args) {
            if (ref $args{$_} eq 'HASH') {
                $new_args{$_} = { %{ $new_args{$_} || {} }, %{ $args{$_} || {} } };
            }
        }
        my $table = _make_table( _process( %new_args ) );
        return $js . $table;
    }

lib/Spreadsheet/HTML.pm  view on Meta::CPAN

    my $tag   = ($args->{headless} or $args->{matrix}) ? 'td' : 'th';
    for my $row (0 .. $args->{_max_rows} - 1) {

        unless ($args->{_layout}) {
            push @{ $data->[$row] }, undef for 1 .. $args->{_max_cols} - $#{ $data->[$row] } + 1;  # pad
            pop  @{ $data->[$row] } for $args->{_max_cols} .. $#{ $data->[$row] };                 # truncate
        }

        for my $col (0 .. $#{ $data->[$row] }) {

            my ( $cdata, $attr ) = ( $data->[$row][$col], undef );
            for ($tag, "-c$col", "-r$row", "-r${row}c${col}") {
                next unless exists $args->{$_};
                ( $cdata, $attr ) = _extrapolate( $cdata, $attr, $args->{$_} );
            }

            do{ no warnings;
                $cdata = HTML::Entities::encode_entities( $cdata, $args->{encodes} ) if $args->{encode} || exists $args->{encodes};
                $cdata =~ s/^\s*$/$empty/g;
            };

            $data->[$row][$col] = { 
                tag => $tag, 
                (defined( $cdata ) ? (cdata => $cdata) : ()), 
                (keys( %$attr )    ? (attr => $attr)   : ()),
            };
        }
        $tag = 'td';
    }

    if ($args->{cache} and $self and !$self->{is_cached}) {
        $self->{data} = $data;
        $self->{is_cached} = 1;
    }

    shift @$data if $args->{headless};

    return wantarray ? ( data => $data, %$args ) : $data;
}

sub _make_table {
    my %args = @_;

    my @cdata = ( _tag( %args, tag => 'caption' ) || (), _colgroup( %args ) );

    if ($args{tgroups}) {

        my @body = @{ $args{data} };
        my $head = shift @body unless $args{matrix} and scalar @{ $args{data} } > 2;
        my $foot = pop @body if !$args{matrix} and $args{tgroups} > 1 and scalar @{ $args{data} } > 2;

        my $head_row  = { tag => 'tr', attr => $args{'thead.tr'}, cdata => $head };
        my $foot_row  = { tag => 'tr', attr => $args{'tfoot.tr'}, cdata => $foot };
        my $body_rows = [ map { tag => 'tr', attr => $args{tr}, cdata => $_ }, @body ];

        if (int($args{group} || 0) > 1) {
            $body_rows = [
                map [ @$body_rows[$_ .. $_ + $args{group} - 1] ],
                _range( 0, $#$body_rows, $args{group} )
            ];
            pop @{ $body_rows->[-1] } while !defined $body_rows->[-1][-1];
        } else {
            $body_rows = [ $body_rows ];
        }

        push @cdata, (
            ( $head ? { tag => 'thead', attr => $args{thead}, cdata => $head_row } : () ),
            ( $foot ? { tag => 'tfoot', attr => $args{tfoot}, cdata => $foot_row } : () ),
            ( map     { tag => 'tbody', attr => $args{tbody}, cdata => $_ }, @$body_rows ),
        );


    } else {
        push @cdata, map { tag => 'tr', attr => $args{tr}, cdata => $_ }, @{ $args{data} };
    }

    return $args{_auto}->tag( tag => 'table', attr => $args{table}, cdata => \@cdata );
}

sub _args {
    my ($self,@data,$data,@args,$args);
    $self = shift if UNIVERSAL::isa( $_[0], __PACKAGE__ );
    $data = shift if (@_ == 1);

    while (@_) {
        if (ref( $_[0] )) {
            push @data, shift;

lib/Spreadsheet/HTML.pm  view on Meta::CPAN

    if ($args->{fill}) {
        my ($row,$col) = split /\D/, $args->{fill};
        $args->{_max_rows} = $row if (int($row || 0)) > ($args->{_max_rows});
        $args->{_max_cols} = $col if (int($col || 0)) > ($args->{_max_cols});
    }

    return ( $self, [ map [@$_], @$data], $args );
}

sub _extrapolate {
    my ( $cdata, $attr, $thingy ) = @_;
    my $new_attr;
    $thingy = [ $thingy ] unless ref( $thingy ) eq 'ARRAY';
    for (@{ $thingy }) {
        if (ref($_) eq 'CODE') {
            $cdata = $_->($cdata);
        } elsif (ref($_) eq 'HASH') {
            $new_attr = $_;
        }
    }
    $attr = { %{ $attr || {} }, %{ $new_attr || {} } };
    return ( $cdata, $attr );
}

sub _colgroup {
    my %args = @_;

    my @colgroup;
    $args{col} = [ $args{col} ] if ref($args{col}) eq 'HASH';

    if (ref($args{col}) eq 'ARRAY') {

        if (ref $args{colgroup} eq 'ARRAY') {
            @colgroup = map {
                tag   => 'colgroup',
                attr  => $_,
                cdata => [ map { tag => 'col', attr => $_ }, @{ $args{col} } ]
            }, @{ $args{colgroup} }; 
        } else {
            @colgroup = {
                tag   => 'colgroup',
                attr  => $args{colgroup},
                cdata => [ map { tag => 'col', attr => $_ }, @{ $args{col} } ]
            }; 
        }

    } else {

        $args{colgroup} = [ $args{colgroup} ] if ref($args{colgroup}) eq 'HASH';
        if (ref $args{colgroup} eq 'ARRAY') {
            @colgroup = map { tag => 'colgroup', attr => $_ }, @{ $args{colgroup} };
        }
    }

    return @colgroup;
}

sub _tag {
    my %args = @_;
    my $thingy = $args{ $args{tag} };
    return unless defined $thingy;
    my $tag = { tag => $args{tag}, cdata => $thingy };
    if (ref $thingy eq 'HASH') {
        $tag->{cdata} = ( keys   %$thingy )[0];
        $tag->{attr}  = ( values %$thingy )[0];
    }
    return $tag;
}

# credit: Math::Matrix
sub _transpose {
    my $data = shift;
    my @trans;
    for my $i (0 .. $#{ $data->[0] }) {

lib/Spreadsheet/HTML/Presets.pm  view on Meta::CPAN

    my %args = @_;

    unless ($NO_MINIFY) {
        $args{code} = JavaScript::Minifier::minify(
            input      => $args{code},
            copyright  => $args{copyright} || 'Copyright 2024 Jeff Anderson',
            stripDebug => 1,
        );
    }

    my $js = $args{_auto}->tag( tag => 'script', cdata => $args{code}, attr => { type => 'text/javascript' } );
    return $js if $args{bare};

    $args{jquery} ||= 'https://ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js';

    my $html = $args{_auto}->tag( tag => 'script', cdata => '',    attr => { src => $args{jquery} } );
    $html   .= $args{_auto}->tag( tag => 'script', cdata => '',    attr => { src => $args{jqueryui} } ) if $args{jqueryui};
    $html   .= $args{_auto}->tag( tag => 'script', cdata => '',    attr => { src => $args{handsonjs} } ) if $args{handsonjs};
    $html   .= $args{_auto}->tag( tag => 'link', attr => { rel => 'stylesheet', media => 'screen', href => $args{css} } ) if $args{css};

    return $html . $js;
}

=head1 NAME

Spreadsheet::HTML::Presets - Generate preset HTML tables.

=head1 DESCRIPTION

lib/Spreadsheet/HTML/Presets/Handson.pm  view on Meta::CPAN

    }

    $args->{id} ||= 'handsontable';
    my @args = (
        @_,
        empty => undef,
        table => { %{ $args->{table} || {} }, class => $args->{id} },
    );

    my $table = $self ? $self->generate( @args ) : Spreadsheet::HTML::generate( @args );
    return _javascript( %$args ) . $args->{_auto}->tag( tag => 'div', cdata => $table, attr => { id => $args->{id} } );
}

sub _javascript {
    my %args = @_;

    my $js = sprintf _js_tmpl(), $args{id}, $args{json};

    $args{css} ||= 'http://handsontable.com/dist/handsontable.full.css';
    $args{handsonjs} ||= 'http://handsontable.com/dist/handsontable.full.js';
    $args{copyright} = 'Copyright (c) 2012-2014 Marcin Warpechowski | Copyright 2024 Handsoncode sp. z o.o.';

lib/Spreadsheet/HTML/Presets/List.pm  view on Meta::CPAN

        $list = [ map { $data->[$_][$args->{col}] } 0 .. $#$data ];
    }

    shift @$list if $args->{headless};

    $HTML::AutoTag::ENCODE  = defined $args->{encode}  ? $args->{encode}  : exists $args->{encodes};
    $HTML::AutoTag::ENCODES = defined $args->{encodes} ? $args->{encodes} : '';
    return $args->{_auto}->tag(
        tag   => $args->{ordered} ? 'ol' : 'ul', 
        attr  => $args->{ol} || $args->{ul},
        cdata => [
            map {
                my ( $cdata, $attr ) = Spreadsheet::HTML::_extrapolate( $_, undef, $args->{li} );
                { tag => 'li', attr => $attr, cdata => $cdata }
            } @$list
        ]
    );
}

sub select {
    my ($self,$data,$args);
    $self = shift if ref($_[0]) =~ /^Spreadsheet::HTML/;
    ($self,$data,$args) = $self ? $self->_args( @_ ) : Spreadsheet::HTML::_args( @_ );

    my $cdata  = [];
    my $values = [];
    if (exists $args->{row}) {
        $args->{row} = 0 unless $args->{row} =~ /^\d+$/;
        $cdata  = @$data[$args->{row}];
        $values = @$data[$args->{row} + 1];
    } else {
        $args->{col} = 0 unless $args->{col} && $args->{col} =~ /^\d+$/;
        $cdata  = [ map { $data->[$_][$args->{col}] } 0 .. $#$data ];
        $values = [ map { $data->[$_][$args->{col} + 1 ] } 0 .. $#$data ];
    }

    my $selected = [];
    if ($args->{selected}) {
        $args->{selected} = [ $args->{selected} ] unless ref $args->{selected};
        for my $text (@$cdata) {
            if (grep $_ eq $text, @{ $args->{selected} }) {
                push @$selected, 'selected';
            } else {
                push @$selected, undef;
            }
        }
    }

    my $attr = { value => [] };
    $attr->{value}    = $cdata   if $args->{values};
    $attr->{selected} = $selected if map defined $_ ? $_ : (), @$selected;

    my $options = [
        map { 
            my ( $cdata, $opt_attr ) = Spreadsheet::HTML::_extrapolate( $_, $attr, $args->{option} );
            { tag => 'option', attr => $opt_attr, cdata => $cdata };
        } $args->{values} ? @$values : @$cdata
    ];

    if (ref( $args->{optgroup} ) eq 'ARRAY' and @{ $args->{optgroup} }) {
        my @groups = @{ $args->{optgroup} };
        my @ranges = Spreadsheet::HTML::_range( 0, $#$options, $#groups );
        splice( @$options, $_, 0, { tag => 'optgroup', attr => { label => pop @groups } } ) for reverse @ranges;
    }

    if ($args->{headless}) {
        shift @$options;

lib/Spreadsheet/HTML/Presets/List.pm  view on Meta::CPAN

    $HTML::AutoTag::ENCODES = defined $args->{encodes} ? $args->{encodes} : '';

    my $label = '';
    if ($args->{label}) {
        $label = $args->{_auto}->tag( %{ Spreadsheet::HTML::_tag( %$args, tag => 'label' ) } );
    }

    return $label . $args->{_auto}->tag(
        tag   => 'select', 
        attr  => $args->{select},
        cdata => [
            ( $args->{placeholder} 
                ? { tag => 'option', attr => { value => '' }, cdata => $args->{placeholder} } 
                : ()
            ), @$options
        ],
    );
}

=head1 NAME

Spreadsheet::HTML::Presets::List - Generate <select>, <ol> and <ul> lists.

t/03-encode-data.t  view on Meta::CPAN

my $encodes = [
    [ qw( < = & > " ' ) ],
    [ qw( < = & > " ' ) ],
];
my $spaces = [
    [ "\n", "foo\n", " ", " \n" ],
    [ "\n", "foo\n", " ", " \n" ],
];

my $expected_encodes = [
    [ map { tag => 'th', cdata => $_ }, qw( < = & > " ' ) ],
    [ map { tag => 'td', cdata => $_ }, qw( < = & > " ' ) ],
];
my $expected_spaces = [
    [ map { tag => 'th', cdata => $_ }, '&nbsp;', "foo\n", '&nbsp;', '&nbsp;' ],
    [ map { tag => 'td', cdata => $_ }, '&nbsp;', "foo\n", '&nbsp;', '&nbsp;' ],
];

my $table = Spreadsheet::HTML->new( data => $encodes );
is_deeply scalar $table->_process, $expected_encodes,  "we are not encoding data by default";
is_deeply scalar $table->_process, $expected_encodes,  "only processes once";

is $table->generate(),
    q(<table><tr><th><</th><th>=</th><th>&</th><th>></th><th>"</th><th>'</th></tr><tr><td><</td><td>=</td><td>&</td><td>></td><td>"</td><td>'</td></tr></table>),
    "encodes turned off by default";

t/03-encode-data.t  view on Meta::CPAN

is $table->generate( encode => 1, encodes => undef ),
    q(<table><tr><th>&lt;</th><th>=</th><th>&amp;</th><th>&gt;</th><th>&quot;</th><th>&#39;</th></tr><tr><td>&lt;</td><td>=</td><td>&amp;</td><td>&gt;</td><td>&quot;</td><td>&#39;</td></tr></table>),
    "setting encodes to undef with encode set to true encodes default";


$table = Spreadsheet::HTML->new( data => $spaces );
is_deeply scalar $table->_process, $expected_spaces,  "correctly substituted spaces";
is_deeply scalar $table->_process, $expected_spaces,  "only processes once";

$expected_spaces = [
    [ map { tag => 'th', cdata => $_ }, '', "foo\n", '', '' ],
    [ map { tag => 'td', cdata => $_ }, '', "foo\n", '', '' ],
];
$table = Spreadsheet::HTML->new( data => $spaces, empty => undef );
is_deeply scalar $table->_process, $expected_spaces,  "spaces untouched";

$expected_spaces = [
    [ map { tag => 'th', cdata => $_ }, '', "foo\n", '', '' ],
    [ map { tag => 'td', cdata => $_ }, '', "foo\n", '', '' ],
];
$table = Spreadsheet::HTML->new( data => $spaces, empty => '' );
is_deeply scalar $table->_process, $expected_spaces,  "correctly substituted spaces";

$expected_spaces = [
    [ map { tag => 'th', cdata => $_ }, ' ', "foo\n", ' ', ' ' ],
    [ map { tag => 'td', cdata => $_ }, ' ', "foo\n", ' ', ' ' ],
];
$table = Spreadsheet::HTML->new( data => $spaces, empty => ' ' );
is_deeply scalar $table->_process, $expected_spaces,  "correctly substituted spaces";

$expected_spaces = [
    [ map { tag => 'th', cdata => $_ }, 0, "foo\n", 0, 0 ],
    [ map { tag => 'td', cdata => $_ }, 0, "foo\n", 0, 0 ],
];
$table = Spreadsheet::HTML->new( data => $spaces, empty => 0 );
is_deeply scalar $table->_process, $expected_spaces,  "correctly substituted spaces";

$table = Spreadsheet::HTML->new( data => '&bar', encodes => 'a&' );
is $table->generate, '<table><tr><th>&amp;b&#97;r</th></tr></table>',  "ampersand does not double encode";

$table = Spreadsheet::HTML->new( data => 0, encodes => 0 );
is $table->generate, '<table><tr><th>&#48;</th></tr></table>',  "ampersand does not double encode";



( run in 0.685 second using v1.01-cache-2.11-cpan-454fe037f31 )