perldoc does not display text between section - perl

I have this POD file:
=head1 Create professional slideshows with Mojolicious::Plugin::RevealJS
=head2 Install and run a Mojolicious server
Santa's elf had a problem. He had to write very fast a presentation and show it to a bunch of new elf's.
The email assigning this to him was sent by Santa himself.
The elf started to look on Metacpan and found this module: L<Mojolicious::Plugin::RevealJS|https://metacpan.org/pod/Mojolicious::Plugin::RevealJS>
He quickly typed the following commands:
C<cpanm Mojolicius Mojolicious::Plugin::RevealJS>
Now he could generate an mojo lite app using:
C<mojo generate lite-app slide_show>
Because the elf was trained in the ancient arts of the elders
he cloud open new file with vim and paste this code in:
=begin perl
use Mojolicious::Lite -signatures;
app->static->paths(['.']);
plugin 'RevealJS';
any '/' => { template => 'presentation', layout => 'revealjs' };
app->start;
=end perl
When I run perldoc t.pod, the code between '=begin perl' and '=end perl' is not visible. I don't understand what I'm doing wrong.

The perlpod documentation says ...
For, begin, and end will let you have regions of text/code/data that are not generally interpreted as normal Pod text, but are passed directly to particular formatters, or are otherwise special. A formatter that can use that format will use the region, otherwise it will be completely ignored.
The formatter in this case is the thing that perldoc uses to render your POD into text. I suspect it doesn't know what to do with the format perl, so it ignores it.
A formatter that produces HTML might know what to do with the perl format, and might replace this with a code block that has syntax highlighting.
If you want your code examples in the POD to always show up as code, use a verbatim paragraph instead. This is done by adding indentation at the front.
=head2 frobnicate($foo)
This function frobnicates the C<$foo>.
my $bar = frobnicate($foo)
=cut
sub frobnicate { ... }

The description of a =begin <format>/=end <format> in perlpod starts by saying this:
=begin formatname
=end formatname
=for formatname text...
For, begin, and end will let you have regions of text/code/data that are not generally interpreted as normal Pod text, but are passed directly to particular formatters, or are otherwise special. A formatter that can use that format will use the region, otherwise it will be completely ignored.
Anything between =begin perl and =end perl is ignored by the standard Pod formatter and will only be processed by a specialised "perl" formatter (and no such formatter exists in the standard Perl toolset - you'd need to write your own).
You don't say what you expect this syntax to achieve, but it seems likely that you're looking for a verbatim paragraph.
Verbatim Paragraph
Verbatim paragraphs are usually used for presenting a codeblock or other text which does not require any special parsing or formatting, and which shouldn't be wrapped.
A verbatim paragraph is distinguished by having its first character be a space or a tab. (And commonly, all its lines begin with spaces and/or tabs.) It should be reproduced exactly, with tabs assumed to be on 8-column boundaries. There are no special formatting codes, so you can't italicize or anything like that. A \ means \, and nothing else.

Related

How to make podlinkcheck not complain about URLs with a fragment

I have a Perl module with a L<...> link like this:
=head1 ...
See L<RFC 8250|https://datatracker.ietf.org/doc/html/rfc8259#section-4>.
=cut
1;
When I run podlinkcheck (version 15) on it, it complains:
themodule.pm:3:5: no module/program/pod "https:"
even though perldoc perlpod says:
Or you can link to a web page:
Lscheme:...
L<text|scheme:...>
Links to an absolute URL. For example, Lhttp://www.perl.org/ or L<The Perl Home Page|http://www.perl.org/>.
I want to keep using podlinkcheck for all my actual Perl module links, but how do I tell it to treat links that start with https:// as hyperlinks instead of looking for a Perl module by that name?
(It seems to work when I remove the fragment (i.e., See L<RFC 8250|https://datatracker.ietf.org/doc/html/rfc8259> but especially for long documents I want to link to a particular section, not just the whole thing. Escaping the # with a backslash and putting double quotes around it did not help.)

Perl POD: line feed

I use Pod to write manuals for my program. And I ran into a problem. Please tell me how to solve it.
I have the following code:
#include <myhead.h>
I<void> myfunc (I<int arg1>, I<int arg2>);
I would like the text to be written from the next line after the word 'void'. Moreover, it is with the next line, and not through one.
Pod is "plain ol' documentation" and doesn't have fancy features. It sounds like you want the text after void to be on the next line. In that case, you have to put that text on the next line and make it verbatim text so it retains the formatting:
=pod
#include <myhead.h>
I<void>
myfunc (I<int arg1>, I<int arg2>);
=cut
If you need something else, improve your questions by showing exactly what you expect.
But, I expect that you probably want to write your own Pod formatter. Then you can do exactly what you want. Fo what it's worth, I write all of my books in Pod and use several custom formatters to get them into their end states.
Pod has paragraph breaks and preformatted text, but no line breaks.
If you are targeting a particular output format, you can do, for example:
=begin html
One line
Another line
=end html
Or you could do some kind of post-processing on the file.

Is there a way to re-use text in perlpod documentation?

I have a bunch of repeated text in my perlpod documentation. I could of course create a separate section and reference it, but I was wondering if there's a way to enter the text once somewhere and have it inserted in multiple places?
I don't think this is possible, but thought I'd ask to make sure I'm not missing anything.
Or - perhaps there's a better perl documentation technique?
As you've realised, Pod is (deliberately) a very simple markup language. It doesn't have any particularly complicated feature and one of the things it is missing is a way to embed text from another source.
I'd suggest moving the repeated text to its own section and linking to that section (using L<...>) whenever you want to reference that text.
While Pod markup is meant to be very basic, we don't have to literally type it all by hand.
Text for documentation can be processed like any other text in Perl, using its extensive set of tools, to create a string with pod-formatted text. That string can then be displayed using core Pod::Usage, via a file (that can be removed or kept), or directly by using core Pod::Simple.
Display the Pod string by writing a file
use warnings;
use strict;
use feature 'say';
use Path::Tiny; # convenience, to "spew" a file
my $man = shift;
show_pod() if $man;
say "done $$";
sub show_pod {
require Pod::Usage; Pod::Usage->import('pod2usage');
my $pod_text = make_pod();
my $pod_file = $0 =~ s/\.pl$/.pod/r;
path($pod_file)->spew($pod_text);
pod2usage( -verbose => 2, -input => $pod_file ); # exits by default
}
sub make_pod {
my $repeated = q(lotsa text that gets repeated);
my $doc_text = <<EOD;
=head1 NAME
$0 - demo perldoc
=head1 SYNOP...
Text that is also used elsewhere: $repeated...
=cut
EOD
return $doc_text;
}
The .pod file can be removed: add -exitval => 'NOEXIT' to pod2usage arguments so that it doesn't exit and then remove the file. Or, rather, keep it available for other tools and uses.
I've split the job into two subs as a hint, since it can be useful to be able to only write a .pod file, which can then also be used and viewed in other ways and formats.† This isn't needed to just show docs, and all Pod business can be done in one sub.
Dispaly the Pod string directly
If there is no desire to keep a .pod file around then we don't have to make it
sub show_pod { # The rest of the program same as above
my $pod_text = make_pod();
require Pod::Simple::Text;
Pod::Simple::Text->filter( \$pod_text ); # doesn't exit so add that
}
The ->filter call is a shortcut for creating an object, setting a filehandle, and processing the contents. See docs for a whole lot more.
Either of these approaches provides you with far more flexibility.
Also, while one can indeed solve the repeated text by referencing a separate section with that text, that of course doesn't allow us to use variables or do any Perl processing -- what is all available when you write a Pod string, which is then passed over to perlpod to dispaly.
Note   Use of .pod files affects perldoc. Thanks to #briandfoy for a comment.
For smaller documentation, that has no particular benefit of using separate .pod files, I recommend the second approach, as hinted in the answer. It only differs in how the docs text is organized in the file while still allowing one to process it as any text is normally processed with Perl.
For use cases where .pod files are of good value I still find it an acceptable trade-off but that is my call. Be aware that perldoc is affected and assess how much that matters in your project.
† I use a system like this in a large project, with .pod files in their directory. There is also a simple separate script for overall documentation management, that invokes individual programs with options to write/update their .pods, in HTML with CPAN's style-file, for the main web page. Any program can also simply display its docs in a desired format.

What are the common workarounds for multi-line comments in Perl?

This RFC mentions
Unlike many programming languages Perl does not currently implement true multiline comments. This, and the workarounds that are in common use can be problematic. This could be solved by adding a new syntax to allow for comments to span more than one line, like the variation on here-documentation cited below.
What are the common workarounds?
Two techniques I found here are
if (0) {
<comment>
}
and
=pod
<comment>
=cut
Are these safe to use? Are there others that work better?
The downside of the "if" solution is that the commented out code still has to be compiled (and therefore still has to be syntax checked).
The downside of your pod solution is that your comments will appear in any documentation generated from the pod.
I use a version of the pod solution that doesn't have that problem. Pod supports =begin format ... =end format paragraphs that are handled by specific formatters. I just invent a "comment" format that isn't handled by any of the formatters I use.
#!/usr/bin/perl
print "This line is executed\n";
=begin comment
print "This line isn't\n";
=end comment
=cut
print "This line is\n";
The Perl documentation tells you how to do it in perlfaq7. It's plenty safe, and since we can do it with Pod, we don't need additional syntax to do it:
How can I comment out a large block of perl code?
You can use embedded POD to discard it. Enclose the blocks you want to
comment out in POD markers. The =begin directive marks a section for
a specific formatter. Use the "comment" format, which no formatter
should claim to understand (by policy). Mark the end of the block with
=end.
# program is here
=begin comment
all of this stuff
here will be ignored
by everyone
=end comment
=cut
# program continues
The pod directives cannot go just anywhere. You must put a pod
directive where the parser is expecting a new statement, not just in
the middle of an expression or some other arbitrary grammar production.
See perlpod for more details.
Although it's non-standard, I just use
=ignore
sub blah { ... }
my $commented_out_var = 3.14;
=cut
It works just as well, and reminds me that it is not POD.
Aside: It is an interesting thing that POD gives us a flexible framework for including various regions that should not regarded as code, specifying what that region means. Clearly we "comment things out" because comments work this way. Yet, it is clear from the term that comments are meant to be words, not instructions; documentation not alterations.
An editor with a "Comment Region" function.
For example, Komodo Edit. I'm pretty sure Eclipse and JEdit do it as well, but I don't have them handy to check.
The feature usually inserts a "Comment this line" symbol at the start of every line in the selected region. It has the benefit of not conflicting with existing comments (which is a risk if you wrap an area containing a multi-line comment in most languages)
My favorite multi-line comment device is __END__.
print "Hello world\n";
__END__
The script has ended. Perl does not treat this part of the file as code.
I can put whatever I want down here. Very handy.
This works too:
q^
This is another way to
add multi-line comments
to your code
^ if 0;
In addition to the
=begin comment
multi-paragraph comments here
=end comment
=cut
form in other answers, you can also do this:
=for comment
this is a single pod paragraph comment do
not put extra blank lines after =for. the
comment ends after the first blank line and
regular pod continues until =cut
Hello! C<Yay!>
=cut
the comment paragraph will not appear in the pod output, but the Hello "Yay!" will.
One special use-case is commenting out several lines of code. But if you use a version control system, you can just delete unwanted code rather than commenting it out, and if you ever need it back, just fetch the old revision.
Something like works too:
q{
my comment
};
THis is an expression I guess evaluated while running Perl.
This even simpler construct worked for me
=comment
It was hard in the Moonta Mines that year
For the miners, down in the pit,
It wasn’t a place for a weak man, but
The Cornish Miners had grit,
They burrowed deeper with every day
Extracting the copper ore,
And the skimps grew high in the heaps that piled
Not far from the Moonta shore.
=cut
I use that way and works for me
=head
"your code to comment
monkey
banana"
=cut
Yet another helpful way!
=begin GHOSTCODE
whatever you want to uncomment
=end GHOSTCODE
=cut
This isn't a Perl syntactical way to do it, but in most editors (like Notepad++) you can highlight code you want to be commented out, and then press CTRL+K. To remove the comments you can highlight them and press CTRL+Shift+K.

Help me understand this Perl statement with <<'ESQ'

substr($obj_strptime,index($strptime,"sub")+6,0) = <<'ESQ';
shift; # package
....
....
ESQ
What is this ESQ and what is it doing here? Please help me understand these statements.
It marks the end of a here-doc section.
EOF is more traditional than ESQ though.
This construct is known as a here-doc (because you're getting standard input from a document here rather than an external document on the file system somewhere).
It basically reads everything from the next line up to but excluding an end marker line, and uses that as standard input to the program or command that you're running. The end marker line is controlled by the text following the <<.
As an example, in bash (which I'm more familiar with than Perl), the command:
cat <<EOF
hello
goodbye
EOF
will run cat and then send two lines to its standard input (the hello and goodbye lines). Perl also has this feature though the syntax is slightly different (as you would expect, given it's a different language). Still, it's close enough for the explanation to still hold.
Wikipedia has an entry for this which you probably would have found had you known it was called a here-doc, but otherwise it would be rather hard to figure it out.
You can basically use any suitable marker. For example, if one of your input lines was EOF, you couldn't really use that as a marker since the standard input would be terminated prematurely:
cat <<EOF
This section contains the line ...
EOF
but then has more stuff
and this line following is the real ...
EOF
In that case, you could use DONE (or anything else that doesn't appear in the text on its own line).
There are other options such as using quotes around the marker (so the indentation can look better) and the use of single or double quotes to control variable substitution.
If you go to the perlop page and search for <<EOF, it will hopefully all become clear.