Beefy Boxes and Bandwidth Generously Provided by pair Networks
We don't bite newbies here... much
 
PerlMonks  

RFC: Proofread the POD for my HTML elements module

by Lady_Aleena (Deacon)
on Apr 19, 2013 at 08:45 UTC ( #1029484=perlquestion: print w/ replies, xml ) Need Help??
Lady_Aleena has asked for the wisdom of the Perl Monks concerning the following question:

I have just finished writing the preliminary POD for my HTML elements module to get my thoughts in order about how I wrote the functions. I have already found two functions I need to rewrite and several more which need to be written. I can use and understand the module and POD, however I am not sure others will be able to use it with what I wrote. I have checked to make sure the POD is well formed with CPAN's POD checker which is the best place to read it. I have not figured out how to get tidy output from pod2man yet.

If you have some time to spare, would you please give it a read through and let me know if I need to rewrite it to make it more understandable? Also, if I took a wrong turn anywhere in my code, I would appreciate a note.

PS. I see there is already an HTML::Element module on CPAN, so if I do ever upload this, I will have to come up with a new name.

package HTML::Element; use strict; use warnings; use base 'Exporter'; our @EXPORT_OK = qw(title script heading anchor paragraph sparagraph l +ist definition_list table form fieldset legend label selection input +textarea div pre); use HTML::Entities qw(encode_entities); use Base::Data qw(data_file get_hash); use Base::Nifty qw(sline line); my @ics = ('id','class','style'); my @java = qw(onclick ondblclick onkeypress onkeydown onkeyup onmouseo +ver onmousedown onmouseup onmousemove onmouseout); sub get_attributes { my ($options, $valid) = @_; my @attributes; for (@{$valid}) { my $value = $options->{$_}; push @attributes, qq($_="$value") if defined($options->{$_}); } return join(' ',('',@attributes)); } sub open_tag { my ($tag,$opt,$attributes) = @_; my $tag_attributes = get_attributes($opt,$attributes); return $tag.$tag_attributes; } sub plain_element { my ($tag,$attributes,$tab,$value,$opt) = @_; my $open = open_tag($tag,$opt,$attributes); return sline($tab,"<$open>$value</$tag>"); } # Start elements sub anchor { my ($value,$opt) = @_; my $tag = 'a'; my $open = open_tag($tag,$opt,['href','target','title',@ics,@java]); return "<$open>$value</$tag>"; } sub title { my ($tab,$value,$opt) = @_; my $tag = 'title'; my $open = $tag; line($tab,"<$open>$value</$tag>"); } sub script { my ($tab,$opt) = @_; my $tag = 'script'; my $open = open_tag($tag,$opt,['type','src']); line($tab,"<$open></$tag>"); } sub heading { my ($tab,$level,$value,$opt) = @_; my $tag = 'h'.$level; print plain_element($tag,[@ics,@java],$tab,$value,$opt); } # Begin paragraphs sub sparagraph { my ($tab,$value,$opt) = @_; my $tag = 'p'; my $open = open_tag($tag,$opt,[@ics,@java]); my $sep = $opt->{separator} ? $opt->{separator} : "\n"; my $line; for (grep(length,split(/$sep/,$value))) { $line .= sline($tab,qq(<$open>)); $line .= sline($tab + 1,$_); $line .= sline($tab,qq(</$tag>)); } return $line; } sub paragraph { print sparagraph(@_); } # End paragraphs # Begin elements for ordered and unordered lists. sub item { my ($tab,$value,$opt) = @_; my $tag = 'li'; my $open = open_tag($tag,$opt,[@ics,@java]); line($tab,qq(<$open>)); line($tab + 1,$value); if ($opt->{inlist}) { list($tab + 1, @{$opt->{inlist}}); } line($tab,qq(</$tag>)); } sub list { my ($tab,$type,$list,$opt) = @_; my $tag = $type.'l'; my $open = open_tag($tag,$opt,[@ics,@java]); line($tab,qq(<$open>)); for my $item (@$list) { if (ref($item) eq 'ARRAY') { item($tab + 1,$item->[0],$item->[1]); } else { item($tab + 1,$item); } } line($tab,qq(</$tag>)); } # End elements for ordered and unordered lists. # Begin elements for definition lists. sub term { print plain_element('dt',[@ics,@java],@_); } sub definition { my ($tab,$value,$opt) = @_; my $tag = 'dd'; my $open = open_tag($tag,$opt,[@ics,@java]); line($tab,qq(<$open>)); line($tab + 1,$value); line($tab,qq(</$tag>)); } # I will be rewriting definition_list to get rid of the data gathering + within it. sub definition_list { my ($tab,$opt) = @_; my $tag = 'dl'; my $open = open_tag($tag,$opt,[@ics,@java]); my %definition_list = get_hash( file => $opt->{file} ? $opt->{file} : data_file, headings => [@{$opt->{headings}}], sorted => 'yes', ); line($tab,qq(<$open>)); my $term = shift @{$opt->{headings}}; for my $term (sort {$definition_list{$a}{sort_number} <=> $definitio +n_list{$b}{sort_number}} keys %definition_list) { term($tab + 1,$term); if (@{$opt->{headings}} == 1) { definition($tab + 2,$definition_list{$term}{$opt->{headings}->[0 +]}); } else { for my $heading (@{$opt->{headings}}) { my $upheading = ucfirst $heading; definition($tab + 2,qq(<b>$upheading:</b> ).encode_entities($d +efinition_list{$term}{$heading})); } } } line($tab,qq(</$tag>)); } # End elements for definition lists. # Begin elemeents for tables. sub caption { print plain_element('caption',['align',@ics,@java],@_); } sub cell { my ($tab,$type,$value,$opt) = @_; $type = $opt->{type_override} ? $opt->{type_override} : $type; my $tag = 't'.$type; my $open = open_tag($tag,$opt,['colspan','rowspan',@ics,@java]); line($tab,qq(<$open>)); if ($value eq 'list') { list($tab + 1,@{$opt->{list}}); } else { line($tab + 1,$value); } line($tab,qq(</$tag>)); } sub row { my ($tab,$type,$cells,$opt) = @_; my $tag = 'tr'; my $open = open_tag($tag,$opt,[@ics,@java]); my %types = ( header => 'h', data => 'd', whead => 'd' ); line($tab,qq(<$open>)); if ($type eq 'whead') { my $cell = shift @{$cells}; if (ref($cell) eq 'ARRAY') { cell($tab + 1,'h',ucfirst $cell->[0], { class => 'row_header', $ +cell->[1] }); } else { cell($tab + 1,'h',ucfirst $cell, { class => 'row_header' }); } } my $cell_type = $types{$type}; for my $cell (@{$cells}) { if (ref($cell) eq 'ARRAY') { cell($tab + 1,$cell_type,$cell->[0],$cell->[1]); } else { cell($tab + 1,$cell_type,$cell); } } line($tab,qq(</$tag>)); } sub col { my ($tab,$opt) = @_; my $tag = 'col'; my $open = open_tag($tag,$opt,['span',@ics,@java]); line($tab,qq(<$open>)); } sub cols { my ($tab,$cols) = @_; col($tab,$_) for @{$cols}; } sub table { my ($tab,$opt) = @_; my $tag = 'table'; my $open = open_tag($tag,$opt,[@ics,@java]); line($tab,qq(<$open>)); if ($opt->{caption}) { if (ref($opt->{caption}) eq 'ARRAY') { caption($tab + 1, $opt->{caption}->[0],$opt->{caption}->[1]); } else { caption($tab + 1, $opt->{caption}); } } if ($opt->{cols}) { col($tab + 1, $_) for @{$opt->{cols}}; } for my $rowgroup (@{$opt->{rows}}) { my $type = $rowgroup->[0]; my @rows = $rowgroup->[1]; my $attributes = $rowgroup->[2]; if ($type eq 'header') { row($tab + 1, $type , @rows, $attributes); } else { for my $row (@rows) { row($tab + 1, $type , $_, $attributes) for @$row; } } } line($tab,qq(</$tag>)); } # End elements for tables. # Start elements for forms. sub label { print plain_element('label',['for',@ics,@java],@_); } sub option { print plain_element('option',['value',@ics,@java],@_); } sub selection { my ($tab,$options,$opt) = @_; my $tag = 'select'; my $open = open_tag($tag,$opt,['name','multiple',@ics,@java]); label($tab,@{$opt->{label}}) if ($opt->{label} && $opt->{place_label +} eq 'before'); line($tab,qq(<$open>)); for (@$options) { option($tab + 1,@$_); } line($tab,qq(</$tag>)); label($tab,@{$opt->{label}}) if ($opt->{label} && $opt->{place_label +} eq 'after'); } sub textarea { my ($tab,$value,$opt) = @_; my $tag = 'textarea'; my $open = open_tag($tag,$opt,['name','rows','cols',@ics,@java]); label($tab,@{$opt->{label}}) if ($opt->{label} && $opt->{place_label +} eq 'before'); line($tab,"<$open>$value</$tag>"); label($tab,@{$opt->{label}}) if ($opt->{label} && $opt->{place_label +} eq 'after'); } # I have to rewrite input so it can print a list of inputs for check b +oxes and radio boxes. sub input { my ($tab,$opt) = @_; my $tag = 'input'; my $open = open_tag($tag,$opt,['type','value','name',@ics,@java]); my $text = $opt->{text} ? "$opt->{text} " : ''; label($tab,@{$opt->{label}}) if ($opt->{label} && $opt->{place_label +} eq 'before'); line($tab,"$text<$open>"); label($tab,@{$opt->{label}}) if ($opt->{label} && $opt->{place_label +} eq 'after'); } sub legend { print plain_element('legend',[@ics,@java],@_); } sub fieldset { my ($tab,$code,$opt) = @_; my $tag = 'fieldset'; my $open = open_tag($tag,$opt,[@ics,@java]); line($tab,qq(<$open>)); legend($tab,$opt->{legend}) if $opt->{legend}; &$code; line($tab,qq(</$tag>)); } sub form { my ($tab,$code,$opt) = @_; my $tag = 'form'; my $open = open_tag($tag,$opt,['action','method',@ics,@java]); line($tab,qq(<$open>)); &$code; line($tab,qq(</$tag>)); } # End elements for forms. sub div { my ($tab,$code,$opt) = @_; my $tag = 'div'; my $open = open_tag($tag,$opt,[@ics,@java]); line($tab,qq(<$open>)); &$code; line($tab,qq(</$tag>)); } sub pre { my ($tab,$code) = @_; line(0,'<pre>'); &$code; line(0,'</pre>'); } # End elements =head1 NAME B<HTML::Element> generates HTML tags for most of the HTML elements. =head1 SYNOPSIS To use B<Element> to print HTML tags, use the following. use Base::HTML::Element qw( title heading script anchor paragraph sparagraph list definition_l +ist table form fieldset selection input textarea div pre ); =head1 ELEMENTS All of the functions C<print> the elements with the exception of C<anc +hor> which returns the anchor and C<sparagraph> which returns a parag +raph for use in other functions. As with the Perl community, the HTML community expects some indentatio +n so tabs, the first parameter of every function, are included with e +ach element except where noted. The last parameter of every element is a hash with named options excep +t where noted. Most elements have the C<id>, C<class>, C<style>, and +scripting options (such as C<onclick>). Only the options specific to +the element will be noted. =head2 C<title> B<C<title>> has a value but no options. title($tab, 'My page title'); =head2 C<heading> B<C<heading>> has the heading level, value, and optional parameters. heading($tab, 2, 'My second level heading', { id => 'heading_id', class => 'heading_classes', style => 'heading_styles' }); =head2 C<script> B<C<script>> has optional parameters which are C<type> and C<src>. script($tab,{ type => 'text/javascript', # or other type src => 'script.ext' }); =head2 C<anchor> B<C<anchor>> has a value and the optional parameters C<href>, C<target +>, and C<title>. C<anchor> does not not get a C<tab>. anchor('Anchor text', { href => 'link location', target => 'where the link opens', title => 'alternate text', id => 'anchor_id', class => 'anchor_classes', style => 'anchor_styles' }); =head2 paragraphs B<C<paragraph>> and B<C<sparagraph>> have a value and the optional par +ameter C<separator>. B<C<paragraph>> prints the paragraph(s), and B<C<sparagraph>> returns +the paragraph(s). The C<separator> option allows you to input more th +an one paragraph per use of this function. paragraph($tab, 'My paragraph(s)', { id => 'paragraph_id', class => 'paragraph_classes', style => 'paragraph_styles' separator => 'paragraph_separator' }); =head2 C<list> B<C<list>> has type, list, and the optional parameters. C<type> is C<u> for an unordered list or C<o> for an ordered list. The + C<list> parameter is an array reference. list($tab, 'u', \@list, { id => 'list_id', class => 'list_class' style => 'list_style, }); =head3 Setting up the list items If you do not want your list items formatted, you can pass your array +as is. If you want your list items formatted, the formatted items are + also array references with the optional parameter C<inlist>. 'unformatted value', ['formatted value', { id => 'item_id', class => 'item_class', style => 'item_style', inlist => ['u', \@inner_list, { list options }] }], 'another unformatted value' =head2 C<definition_list> I<I have to tear out some code to make it work like the others.> =head2 C<table> Before you go any further, if you plan on using a table for layout, B< +I<STOP!>> Tables are for tabular data, use L<div|/div> elements to la +y out your webpage. B<C<table>> has the optional parameters of C<caption>, C<cols>, and C< +rows>. C<cols> and C<rows> are array references. table($tab, { id => 'table_id', class => 'table_class', style => 'table_style', caption => 'table caption', cols => \@cols, rows => \@rows, }); =head3 Setting up the caption C<caption> is a value, as seen above, or an array refernce. The C<capt +ion> has the optional parameter C<align>. ['table caption', { id => 'caption_id', class => 'caption_class', style => 'caption_style', align => 'caption_align' }], =head3 Setting up the columns Each C<column> is an array reference of hash references and each has t +he optional parameter C<span>. { id => 'col_id', class => 'col_class', style => 'col_style' span => 2, }, =head3 Setting up the rows Each C<row> is an array reference with C<type>, C<cells>, and optional + parameters. You need to know type of cells are in the row. =over =item * C<header> is a row with only headings. There is only one row allowed i +n C<header>. =item * C<data> is a group of rows with only data. =item * C<whead> is a group of rows with a heading then data. =back rows => [ ['header',\@headings, { id => 'header_row_id', class => 'header_row_class', style => 'header_row_style }], ['data',\@data { id => 'data_row_id', class => 'data_row_class', style => 'data_row_style }], ['whead',\@data_with_heading], ], =head4 Setting up the cells If you do not want your cells formatted, you can pass your array as is +. If you want your cells formatted, the formatted cells are also arra +y references with optional parameters C<list> and C<type_override>. T +he C<list> option is the same as the C<inlist> option for L<list item +s|/Setting up the list items>. If you need to override the row type, +use C<type_override>. 'unformatted value', ['formatted value', { id => 'cell_id', class => 'cell_class', style => 'cell_style', }], ['list', { id => 'cell_with_list_id', class => 'cell_class', style => 'cell_style', list => ['u', \@list_in_cell, { list options }] }], ['formatted value', { id => 'cell_id', class => 'cell_class', style => 'cell_style', type_override => 'h', }], 'another unformatted value' =head2 forms =head3 C<form> B<C<form>> has code and the optional paramters C<action> and C<method> +. C<code> is an anonymous subroutine. form($tab, sub { ... form elements ... }, { action => 'form_action', method => 'form_method', id => 'form_id', class => 'form_class', style => 'form_style' }); =head3 C<fieldset> B<C<fieldset>> has code and the optional paramter C<legend>. C<code> i +s an anonymous subroutine. fieldset($tab, sub { ... fieldset elements ... }, { legend => 'legend_text', id => 'fieldset_id', class => 'fieldset_class', style => 'fieldset_style' }); =head4 Setting up the legend The legend can be unformatted as above or formatted as below in an arr +ay reference with the optional parameter C<align>. legend => ['legend_text', { id => 'legend_id', class => 'legend_class', style => 'legend_style, align => 'legened_align' }], =head3 C<selection> B<C<selection>> has options and the optional parameters C<name>, C<mul +tiple>, and C<label>. selection($tab, \@options, { name => 'select_name', multiple => 'multiple', label => ['label text', { for => 'select_name', id => 'label_id', class => 'label_class', style => 'label_style' } id => 'select_id', class => 'select_class', style => 'select_style' }); =head4 Setting up the options If you do not want your options formatted, all you need to do is pass +the text and C<value> of the option. If you want formatting, you need + to pass the other optional parameters. ['unformatted option', { value => 'unformatted' }], ['formatted option', { value => 'formatted', id => 'option_id', class => 'option_class', style => 'option_style' }] =head3 C<input> I<I need to rewrite it.> =head3 C<textarea> B<C<textarea>> a value and the optional parameters C<name>, C<rows>, C +<cols>, and C<label>. textarea($tab, 'text in the textarea box', { name => 'textarea_name', rows => 100, cols => 100, label => ['label text', { for => 'textarea_name', id => 'label_id', class => 'label_class', style => 'label_style' } id => 'textarea_id', class => 'textarea_class', style => 'textarea_style' }); =head2 C<div> B<C<div>> code and optional parameters. C<code> is an anonymous sub. div($tab, sub { print "Text with out any formatting, great for data dumping." }, { id => 'div_id', class => 'div_class', style => 'div_style' }); =head2 C<pre> B<C<pre>> has code but no optional parameters. The C<tab> will be igno +red and C<code> is an anonymous sub. pre($tab, sub { print "Text without any formatting, great for data dumping." }); =head1 AUTHOR Written by Lady Aleena (Lady underscore Aleena at xecu dot net) with a + lot of help from the L<PerlMonks|http://www.perlmonks.org>. =cut 1;
Have a cookie and a very nice day!
Lady Aleena

Comment on RFC: Proofread the POD for my HTML elements module
Download Code
Re: RFC: Proofread the POD for my HTML elements module
by Khen1950fx (Canon) on Apr 19, 2013 at 12:52 UTC

    Good morning, Lady_Aleena. I had some extra time, so let's get the ball rolling.

    When I finish a module, I try to edit it as many times as possible. I usually start by running it through Deparse and perltidy, then I edit it some more and repeat the process until I'm sure that it's ready for production. Go through the script and look for obvious errors like barewords, etc.. Once the script is tidied, then run perltidy again. Looking at the first 13 lines or so, perltidy output this:
    package HTML::Element; use strict; use warnings; use base qw( Exporter ); our (EXPORT_OK) = qw( title script heading anchor paragraph sparagraph list definition_list table form fieldset legend label selection input textarea div pre ); use HTML::Entities qw( encode_entities ); my (@ics) = qw( id class style ); my (@java) = qw( onclick ondblclick onkeypress onkeydown onkeyup onmouseover onmousedown onmouseup onmousemove onmouseout );
    It's already better, no? Now, here's deparse and perltidy output for your entire script:
Re: RFC: Proofread the POD for my HTML elements module
by Anonymous Monk on Apr 19, 2013 at 14:02 UTC
    Already rendered version of the pod would have been more appropriate and appreciated for the purpose (devoid of large swath of code).
Re: RFC: Proofread the POD for my HTML elements module
by Arunbear (Parson) on Apr 19, 2013 at 14:47 UTC
    The SYNOPSIS should give at least one example of how an end user can make use of the module.

    It's also conventional to have a DESCRIPTION section that gives an overview of what the module does. There are many examples on CPAN that can serve as a guide.

    Those who read the documentation you provide may also wonder what the rationale behind this module is? And what it does that others don't (or does better) ? Also, do you realise that templating systems have long since become the preferred way of generating HTML; e.g. see Using HTML::Template

      Arunbear, thank you for taking time to read it over. I will expand the synopsis and try to come up with a description, though I thought the opening paragraph in ELEMENTS covered it.

      Every time I see HTML::Template mentioned, I want to scream. It will not work for my site. I spent several frustrated hours trying to make it work. It made me so mad, I gave up trying and made my own template which is in a nice neat function.

      Have a cookie and a very nice day!
      Lady Aleena
        I mentioned ovid's node on HTML::Template mainly because he describes why templates should be preferred, but the exact templating module to use is less important.

        I also am not a fan of HTML::Template, but I have used Template Toolkit quite a bit and found it very user friendly and versatile. I suggest giving it a try.

        For what it's worth, I'm entirely in agreement with you about HTML templating.

        Any sufficiently mature templating language starts to exhibit signs of following Greenspun's tenth rule. It acquires bits of syntax for conditionals, looping and so on. They become Turing complete. And if I want to generate my HTML using a Turing-complete language, I've already got one right in front of me: Perl.

        I do use templates occasionally. And when I do, I tend to use Text::Template which allows me to embed Perl in the templates thank-you-very-much and not some poorly designed ersatz scripting language.

        But that's only occasionally; and not usually for outputting HTML, but for outputting other formats. Why? Because of the other thing I dislike about templating...

        The other thing I dislike about templating is that it composes HTML using a linear, string-like paradigm, whereas an HTML document is really a tree-like structure that just happens to have been serialized down to a string.

        If I have a template like:

        <div style="color:red">[% ... %]</div>

        Then I have no confidence that the end </div> tag will end up closing the initial start <div> tag. The stuff within the [% ... %] may well do something like </div><div>. It's simply a flaky way to compose a tree. If I do this:

        div( ... );

        ... and div() is written to return a DOM node, and all the parameters passed to it are DOM nodes, then I know my resulting document is going to be sane.

        My own attempt to write something along the lines of what Lady_Aleena has done above, is HTML::HTML5::Builder.

        Basic usage is along these lines...

        use HTML::HTML5::Builder qw[:standard]; my @things = ( "raindrops on roses", "whiskers on kittens", "bright copper kettles", "warm woollen mittens", ); print html( -lang => 'en', head( title('Test'), Meta(-charset => 'utf-8'), ), body( h1('Test'), p('Here are a few of my favourite things...'), ul(map li($_), @things), ), );

        The module really needs a revisit. The problem is that many HTML elements have names that conflict with Perl's built-ins (tr, map, etc). Right now, HTML::HTML5::Builder exports some of these as capitalized functions to deal with that issue, but I'm not especially happy with the current solution.

        package Cow { use Moo; has name => (is => 'lazy', default => sub { 'Mooington' }) } say Cow->new->name
Re: RFC: Proofread the POD for my HTML elements module
by educated_foo (Vicar) on Apr 19, 2013 at 15:17 UTC
    The fact that there's already a module with the name you chose on CPAN suggests that yours isn't the first attempt to solve this problem. It would be friendly to include a "SEE ALSO" section listing related modules, and explaining how yours is different or better.
    Just another Perler interested in Algol Programming.

      educated_foo, thank you for taking time to read it over. I will add a 'see also' section. Thank you for the tip!

      Have a cookie and a very nice day!
      Lady Aleena
Re: RFC: Proofread the POD for my HTML elements module
by Don Coyote (Monk) on Apr 19, 2013 at 19:20 UTC

    I'm not going to go into the major aspects as I have not yet written up POD myself, just a couple of minor points.

    • I'd like to teach the world to sing...
    • Before you go any further, if you plan on using a table for layout, STOP! Tables are for tabular data, use div elements to lay out your webpage.
      • While it is undeniably gutting to see incorrect usage, the focus of Pod is to inform the user how to implement the module. Refrain from entering ad-hoc didactions about non-related topics.

    • I'd like to teach the perlers a THING...
    • code is an anonymous sub.
      • If I don't know what that funny argument sub {} is, I could always risk asking someone on a forum, or perhaps rtfm. The presentation of the usage should make the argument requirements apparent. If you are going to describe the arguments, consider how consistently you describe them across all the method descriptions. I actually began to look for a hash key 'code' to see what value I would have to provide as an a argument before I realsied you just meant, the first argument is code - how does File::find handle that in Pod?

    • I'd like to teach the italians about drawing...
    • paragraphs, sparagraphs, spaghetti giraffes?
      • Introducing a whole new way to do something as second nature as write a paragraph element, could really do with it has it has own description. You may just be reinventing the wheel in a way that people have not considered previously, and it would be a shame to hide this away by muddling it up with the straight forward paragaraph element method. Or it may be a really bad idea, in which case it can be easily ignored or redifined, either way the paragraph separator routine, dare i say it.... needs separating

    On another point more along the coding itself, why ask the user to provide the $tab argument for every method? Could you not implement this as default module behaviour, and then describe this in the Pod?

    I hope these comments are helpful in your redraftings.

      Don Coyote, thank you for taking time to read it over.

      • I feel very very strongly about not using tables for layout, so I am not too sorry for my prosthelytizing. I will not go into how frames are evil however. (I will not include frames in the module.)
      • Yes, I was inconsistent when it came to the code block description, so the inconsistency has been removed.
      • With the paragraph and sparagraph descriptions, I was hoping to avoid repetition so I put them together. Separating the separator now would lead to many headaches since I have already implemented it throughout my many many pages.

      I am not sure how to determine what tab level the user is at when using the functions, or if the user wants tabs at all. A user could set my $tab = 0; and not have any tabs with any function used as follows.

      # Unwritten elements used in this example, however they will be soon. my $tab = 0; my @list = ( ['red, { style => 'color:#ff0000' }], ['green', { style => 'color:#00ff00' }], ['blue', { style => 'color:#0000ff' }] ); html($tab, sub { head($tab, sub { title($tab, 'My page title'); }); body($tab, sub { div($tab, sub { heading($tab, 1, 'My sample heading', { id => 'sample_heading' +, style => 'color:#666666' }); paragraph($tab, 'A sample paragraph so you can see how this wo +rks.'); list($tab, \@list, { id => 'colors' }); # list items will get +tabbed. paragraph($tab, 'Another paragraph for you'); heading($tab, 1, 'A second sample heading'); }, { class => 'div_class' }); paragraph($tab, 'Some end remarks.', { id => 'end_remarks', clas +s => 'remarks' }); }); });

      A user could set up the tabs like the following.

      my $tab = 0; html($tab, sub { $tab++; head($tab, sub { $tab++; title($tab, 'My page title'); $tab--; }); body($tab, sub { $tab++; div($tab, sub { $tab++; heading($tab, 1, 'My sample heading', { id => 'sample_heading' +, style => 'color:#666666' }); $tab++; paragraph($tab, 'A sample paragraph so you can see how this wo +rks.'); list($tab, \@list, { id => 'colors' }); paragraph($tab, 'Another paragraph for you'); $tab--; heading($tab, 1, 'A second sample heading'); $tab--; }, { class => 'div_class' }); paragraph($tab, 'Some end remarks.', { id => 'end_remarks', clas +s => 'remarks' }); $tab--; }); $tab--; });

      I will not force too many unwanted tabs onto a user. Make sense?

      Have a cookie and a very nice day!
      Lady Aleena

        Hi Aleena, I have had another look now, and I think the key word in review is consistency.

        The $tab is a code impelmentation, and as such does not really fall within the scope of the op. The importance lays with the expected usage being documented in an easy to understand way.

        In respect of paragraphs functions, I was not suggesting to split the code. Consistency would confer that all exported (default or optional) functions recieve a description in the Pod. So describe the paragraph function, then describe the sparagraph function, even if that description is 'see #paragraph function'. This is fairly common in Pod. However the important point is that now I can navigate to each function description from the index, or anywhere else I happen to be. I would also like to know how to pass sparagraph to other functions, from the current description I think sparagrah is essentially an array of paragraph function. What is sparagraph, how is it different from paragraph, what do I need to do to implement it? Should I implement it?

        Scanning through the headings, the 'setting the ...' headings under table suddenly switch from =head3 to =head4 and then the =head4 setting remains for what were previously =head3> headings.

        The export of routines, is an implementation consideration, I am unsure you have achieved what you intended. Unless you have intended there are no functions exported by default? The main difference is that exporting no functions is an OO (Object Orientated) approach, whereas the module you have created is functional, so would be expected to export a default list of functions. This also helps by allowing the user to know which functions make up the interface, and which are used by the module itself.

        For example, if the module tracked a variable value through the use of internal functions. Which then altered the behaviour of the interface functions in a documented way. The user would not expect their program to break if they only use the documented (exported) functions, but if they tried to access the variable value themselves and their program broke after a module update. They get downvotes.

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://1029484]
Approved by marto
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others romping around the Monastery: (8)
As of 2014-12-21 16:09 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    Is guessing a good strategy for surviving in the IT business?





    Results (106 votes), past polls