Beefy Boxes and Bandwidth Generously Provided by pair Networks
The stupid question is the question not asked
 
PerlMonks  

Re^5: RFC: Proofread the POD for my HTML elements module

by Don Coyote (Monk)
on Apr 21, 2013 at 11:57 UTC ( #1029754=note: print w/ replies, xml ) Need Help??


in reply to Re^4: RFC: Proofread the POD for my HTML elements module
in thread RFC: Proofread the POD for my HTML elements module

If you think that was confusing, see below...

Sticking to the op, a lot of Pod I read is interwoven with the code within which it documents. Have you tried placing the function descriptions pods above each of the relevant functions? This may help you to keep clarity with which art of the pod is document which part of the module

I thought you may have been told not to include default exports. Which is fine. However in terms of the pod, your synopsis is an example in how to import routines, rather than how to use your module. So you need to show an example of how to use the module, something like the $tab example you did earlier in this thread. The import example is also the only place where all of the user functions are listed. I think these things need to be listed in a place which says, these are the modules routines. Not as at present, being a side effect of the synopsis.

Heading away from the op and back to tabs...

Looking at the $tabs implementation. There are a couple of issues I see with this.

  • Indirectly conflicts with accessibility elements such as tabindex
  • Currently user implemented due to module author being unable to determine and implement user requirement.

In the case of accessibilty, I would propose you choose a different name for this variable.

Further to the above, consideration of accessibilty attributes and elements to be included with the first release would be advantageous. The element <noscript> I notice does not appear. Also along with [qw(id class style)] consider including [qw(role)] as a default attribute.

Tab implementation. You say you do not know what level the user requires, however, if you did know how would you approach that. To keep this as short as I can, I will just say what I think, rather than explain my thinking.

keeping use base Exporter allows you to customise the import routine. By overriding and extending the routine, you can keep all the functionality of import, and provide a layout indentation pragma to determine the user requirement.

The problem now becomes one of detecting where the indentations are required. Starting with say, wherever a sub{} argument is provided a child element is produced and therefore an indentation would be required, you could effectively determine when the indentation should be increased. Returning from the sub{} argument would indicate a return to the parent element and therefore a reduction in the indentation variable. There is what I think the strategy for indentation implementation in your module should be thinking about.

An alternative may be to apply the indentation after the HTML has been produced, if the indentation pragma has been set. Like using CGI::Pretty, or Perl::Tidy, but as a setting rather than a module. By storing the html then running it throuhgh an indent parser after.

Customising the import routine to overide and extend would go something like this:

Disclaimer: untested code, probably broken, purely figurative. In a rush gotta go..

use HTML::LadyAleenaStyle qw(:all -in1); # end -in with single digit for 'level'.
Package HTML::LadyAleenaStyle; use strict; use warnings; #use Carp; use deparse; #see corrupt code further down use base Exporter; use Base::Nifty qw(line sline); our @EXPORT = qw(html body script noscript etc); our @EXPORT_OK = qw(table form nonessential etc); my $inflag; # indentation flag for checking. my $in; # indentation depth variable. # Expect indentation flag may need to be a constant for checking. # Need to review how to set the constant correctly. sub import{ # strip out the indentation pragma from the argument list; $inflag = ($1) = grep s/^-in(\d){1}$//, @_; # untested $in = 0 if $inflag; # start indentation depth at 0 if flag set >= 1; # pass arg list to Exporter for usual behaviour; SUPER::import(@_); } # now if flag set, determine if child element and alter depth. # this code is a suggestive starting point. # the depth decrement requirements would also need to be determined. # this sub code is gibberish. sub element{ if($inflag){ if(my $indent = map ref(CODE), @_){ $in++ if( grep deparse(&{CODE}) =~ /CHILD ELEMENT SUB/ ); } } # rest of sub ... #return line($in, $open,); }

hope these comments are helpful. I tried to stick to commenting on pod aspects, but somehow diverged into the implementation. I think you wanted a little input on both though.


Comment on Re^5: RFC: Proofread the POD for my HTML elements module
Select or Download Code
Re^6: RFC: Proofread the POD for my HTML elements module
by Don Coyote (Monk) on Apr 23, 2013 at 11:53 UTC

    Pod. I put pod =head2 headings above each of the exportable routines in the code. I am not sure this is any easier to read, but you can see which pod relates to which part of code. I then cut and paste your pod over into the relevant spaces, and where there were conflicts just pasted your pod as is. This may help to show where the function descriptions and general module implementation descriptions and examples need to be refined.

    changed use base 'Exporter'; to use Exporter qw(import); not extending import so no need to become an Exporter.

    Tabs. extending the import routine may have been overkill. using deparse to get at teh child elements may not be overkill, rather it may be necessary, but in reality highlights ineffective code.

    I quite like the idea of extending the import and using a pragma to set a module variable. But for simplicity, I have converted this into a settable variable.

    The idea is that whenever you would call $tab in the module code to open a tag you now call the tab ascenscion routine, $ref to (CODE) to return the increased level, and the the same for descenscion, but a different $ref to (CODE)

    Now the user only has to set the $HTML::LadyAleenaStyle::inlvl variable to a suitable number. Because in the Module you replace the $tab variables throughought the element subs with calls to &$ina for ascending tab depth, and &$ind for descending tab depth. And remove $tab assignement from special array.

    This still does not work perfectly, as it now only indents the parent element itself rather than the child elements. This is probably far simpler than trying to deparse code during sub calls to see what the user may have in store for us, which we probably should not be doing anyway. And, I'm just getting my head round inheritance and callbacks right now. I have also thus far refrained from viewing CGI.pm source, lest the old copy and paste button inexplicably resembles free beer.

    again code untested, figurative...

    package HTML::LadyAleenaStyle; use strict; use warnings; use Exporter qw(import); 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); =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 ); ## Module Vars =head3 C<indentation> To print readable html, set the indentation to the level. Can be 0 - 9 +. Each level constitutes a tab space multiplier applied to child elements (according to dominterpretation?). Default i +s no indentation in output or 0 level. $HTML::LadyAleenaStyle::inlvl = 7; Each child element will be indented seven tab stops from the relevant +parent element =cut $HTML::LadyAleenaStyle::inlvl = 0 unless $HTML::LadyAleenaStyle::inlvl +; # default indentation none; ### set module variables if required in calling script. sub in_depth { state $level = 0; # requires Perl version 5.10 return ( sub { $level += $HTML::LadyAleenaStyle::inlvl }, sub { $level -= $HTML::LadyAleenaStyle::inlvl }, ); } my ($ina,$ind) = in_depth; # now replace the $tab variables throughought the element subs with ca +lls to # &$ina for ascending tab depth, # &$ind for descending tab depth, # and remove $tab assignement from secial array. # for example in sub div: # # sub div{ # # my ($code,$opt) = @_; # no $tab # my $tag = 'div'; # my $open = open_tag($tag,$opt,[@ics,@java]); # # line(&$ina,qq(<$open>)); # indent depth increase # &$code; # line(&$ind,qq(</$tag>)); # indent depth decrease # } #

    all the code here

      I have made changes since my original post and more are forthcoming when I get inspired. So I do not make this thread any longer than it already is, I created a gist on GitHub. Now onto some comments.

      1. Did you know by mixing the POD in with the code, you added two pages worth of scrolling? With each =cut and the blank line after it, you added that much more scrolling. The code with the POD at the end is already 854 lines long. Adding another 70+ lines and 25% of a kb makes getting around the file more work. (If you have read my home node, file size still matters.)
      2. You have =head3 Setting up the list items before =head2 C<list>. The =head3 would be viewed as part of the =head2 C<paragraph> above it. My head levels were not arbitrary, they are written for (PO)document structure.
      3. Any element not exported does not get a POD heading for it.
        • title - set with the title parameter in head.
        • item - used in the list function.
        • term - used in the definition_list function.
        • definition - used in the definition_list function.
        • cell - set with the rows parameter in table.
        • row - set with the rows parameter in table.
        • col - set with the cols parameter in table.
        • cols - written but unused.
        • legend - set by the legend parameter in fieldset.
        • label - set by the label parameter in selection, textarea, and input functions.
        • option - used in the selection function.
      4. $tab and a tabindex are mutually exclusive. tabindex would be an optional parameter in anchor, input, selection, and textarea.
      5. Comments are supposed to be little things, so one # and a space are enough. I think most text editors these days have syntax highlighting, so long strings of # are not needed.

      Reading the POD in POD Checker would show you why I set up the POD as I did. You will see my document structure in all its glory. Any time I write a POD, I always check it with the POD checker.

      I am not getting how your tabbed lines work. I have not tried it yet, since it is a major paradigm shift.

      Have a cookie and a very nice day!
      Lady Aleena

        I agree with your module need criteria. Being faced with CGI.pm when you start up in perl does kind of slow down production. A functional base HTML element Module would be a far better introduction to programatically producing html. is this what you are thinking here? However, I believe a functional module is expected to export some routines. For example I am expecting I will not have to declare I want to import html, head, body, div, paragraph at a bare minimum. I can understand you being informed not to create an import list if the module was going to be in any way object orientated, but as a functional module, no import list, does not make sense.

        1. yes you are right here, my bad.
        2. I remained consistent here. I placed a head2 above each exported function, and where your pod matched filled in, otherwise placed the approximate pod nearby in the format existing. I found that the pod was not in the same order as the source, this made finding the related pod and source cumbersome in clarity.
        3. Some of the items in the list are still in your EXPORT_OK list. I'm figuring this is just oversight at the moment. However it would be clearer if when I viewed the source I could distinguish between what a user function and an intrenal module function. I understand the convention is to include an underscore within the function name. Or more explicitly as the first character of the function name. For example, I might currently think &definition_list is an internal module function which I should not use (excepting it being in the export_ok list), but that I can import and use &legend. In this case my headaches increase and my kudos for the author decrease when the author decides to reimplement &legend behaviour. Certainly adds to the folklore...
        4. keyword being 'would'. I do not think any other optional parameter other than the prescribed values can curently be input, being validated, as they are.
        5. Pod is to the user as comments are to the maintainer, no? What I mean is, well written comments complement the source, such as CGI.pm, the comments I included in the source were meant to hint at this kind of using comments to structure the source into sections. You already started doing this with the # start/end comments. My comments are still getting the noobland translation app treatment. I will keep your point in mind.

        The main principal of the tabbing is, I do not think the user wants to sit and write out tab increments and decrements. I think the user wants to the module to do that for them. What I am suggesting is that you present the user with a couple of optins how the tabs will be implemented, and they choose which they like, by setting a flag on or off. The major difference is you write an internal function to handle the implementations, based on the flag value, saving the user from having to do this. Would you like me to work on that properly? I have so far just thrown it in as an idea more than anything. I think really just need to clarify the way the variable is set, and add an actual $level return sub. I can see from your functions you have already determined some elements will be untabbed anyway such as pre, and anchor. So you are already making half the decision for the user.

        The gist source is really readable and easy to navigate, good stuff.

Log In?
Username:
Password:

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

How do I use this? | Other CB clients
Other Users?
Others wandering the Monastery: (6)
As of 2014-08-01 05:14 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    My favorite superfluous repetitious redundant duplicative phrase is:









    Results (256 votes), past polls