wiki.pl: Port some fixes from upstream
[Orgmuse.git] / modules / poetry.pl
blobd4b107d737bc02f785d6a4d77870a7c61d5ec617
1 #!/usr/bin/env perl
2 # ====================[ poetry.pl ]====================
4 =head1 NAME
6 poetry - An Oddmuse module for adding poetry to Oddmuse pages.
8 =head1 SYNOPSIS
10 Poetry - particularly rhymically free, "free verse" poetry - tends to depend on
11 fanciful, often meaningful line-breaks, indentation, and whitespace, which
12 publication of that poetry must preserve. This extension preserves that.
14 =head1 INSTALLATION
16 poetry is easily installable; move this file into the B<wiki/modules/>
17 directory for your Oddmuse Wiki.
19 =cut
20 package OddMuse;
22 $ModulesDescription .= '<p><a href="http://git.savannah.gnu.org/cgit/oddmuse.git/tree/modules/poetry.pl">poetry.pl</a>, see <a href="http://www.oddmuse.org/cgi-bin/oddmuse/Poetry_Extension">Poetry Extension</a></p>';
24 # ....................{ CONFIGURATION }....................
26 =head1 CONFIGURATION
28 poetry is easily configurable; set these variables in the B<wiki/config.pl>
29 file for your Oddmuse Wiki.
31 =cut
32 use vars qw($PoetryIsHandlingCreoleStyleMarkup
33 $PoetryIsHandlingXmlStyleMarkup
34 $PoetryHtmlTag);
36 =head2 $PoetryIsHandlingCreoleStyleMarkup
38 A boolean that, if true, enables handling of Creole-style markup. See
39 L<MARKUP> below. By default, this boolean is true.
41 =cut
42 $PoetryIsHandlingCreoleStyleMarkup = 1;
44 =head2 $PoetryIsHandlingXmlStyleMarkup
46 A boolean that, if true, enables handling of Xml-style markup. See
47 L<MARKUP> below. By default, this boolean is true.
49 =cut
50 $PoetryIsHandlingXmlStyleMarkup = 1;
52 =head2 $PoetryHtmlTag
54 A string having the HTML tag with which to markup poetry. By default, this is a
55 preformatted block with default class "poem", which produces HTML:
57 <pre class="poem">
58 Like this, a
59 <em>poem</em> with default
60 class <code>poem</code>.
61 </pre>
63 Preformatted blocks cleanly preserve paragraph whitespace. However, if
64 preformatted blocks are not your cup of HTML, you can set this string to 'div',
65 which produces HTML:
67 <div class="poem">
68 Like this, a
69 <em>poem</em> with default
70 class <code>poem</code>.
71 </div>
73 =cut
74 $PoetryHtmlTag = 'pre';
76 # ....................{ MARKUP }....................
77 my $PoetryHtmlAttrPattern = '^class="poem( \S|"$)';
79 push(@MyRules, \&PoetryRule);
80 SetHtmlEnvironmentContainer('pre', $PoetryHtmlAttrPattern);
82 # Stanza linebreaks conflict with Creole-style line-breaks.
83 $RuleOrder{\&PoetryRule} = 170;
85 =head2 MARKUP
87 poetry handles two markup styles: Creole and Xml. The Creole style is more
88 concise, but a bit less adjustable, than the Xml style.
90 The Creole style is three colons:
92 :::
93 Like this, a
94 //poem// with default
95 class, ##poem##, and its last
96 stanza
97 indented, and linking to [[Another_Poem|another poem]].
98 :::
100 The Xml style is a "<poem>...</poem>" block:
102 <poem class="haiku">
103 Like this, a %%[[Haiku]]%% having
104 the Html
105 classes, ##haiku## and ##poem##.
106 </poem>
108 Or, more concisely:
110 <poem>
111 Like this, a %%[[Haiku]]%% having
112 the default HT-
113 ML class, ##poem##.
114 </poem>
116 Both markup produce a preformatted block (that is, a "<pre>...</pre>" block)
117 having the "poem" Html class (for CSS stylization of that block). The Xml style
118 permits customization of this Html class; the Creole style does not. Thus, use
119 the Xml style for poetry requiring unique CSS stylization.
121 Both markup preserve linebreaks, leading indendation, and interspersed
122 whitespace, preserving the lyrical structure of the poetry this markup is
123 marking up. In other words, this markup does "the right thing."
125 Both markup permit embedding of other Wiki markup -- like Wiki links, lists,
126 headers, and so on -- within themselves. (This permits, should you leverage it,
127 Wiki poets to pen interactive and actively interesting, Wiki-integrated poetry.)
129 =cut
130 sub PoetryRule {
131 if (InElement($PoetryHtmlTag, $PoetryHtmlAttrPattern)) {
132 # Closure for the current poem.
133 if ($bol and (
134 ($PoetryIsHandlingCreoleStyleMarkup and m~\G:::(\n|$)~cg) or
135 ($PoetryIsHandlingXmlStyleMarkup and m~\G&lt;/poem\&gt;[ \t]*(\n|$)~cg))) {
136 return CloseHtmlEnvironment($PoetryHtmlTag, $PoetryHtmlAttrPattern).
137 AddHtmlEnvironment('p');
139 # Linebreaks and paragraphs. This interprets one newline as a linebreak, two
140 # newlines as a paragraph, and N newlines, where N is greater than two, as a
141 # paragraph followed by N-2 linebreaks. (This produces appropriate vertical
142 # tracking, surprisingly.)
143 elsif (m~\G(\s*\n)+~cg) {
144 $number_of_newlines = ($1 =~ tr/\n//);
146 my $html = '';
147 if ($number_of_newlines > 1) {
148 $number_of_newlines -= 2;
149 $html .= CloseHtmlEnvironments().AddHtmlEnvironment('p');
152 $html .= $q->br() x $number_of_newlines;
153 return $html;
155 # Whitespace and indentation.
156 elsif (m~\G(\s+)~cg) { return '&nbsp;' x length($1); }
158 # A new poem.
159 elsif ($bol and (
160 ($PoetryIsHandlingCreoleStyleMarkup and m~\G:::(\n|$)~cg) or
161 ($PoetryIsHandlingXmlStyleMarkup and
162 m~\G\&lt;poem(\s+(?:class\s*=\s*)?"(.+?)")?\&gt;[ \t]*(\n|$)~cg))) {
163 return CloseHtmlEnvironments()
164 .AddHtmlEnvironment($PoetryHtmlTag, 'class="poem'.
165 (defined $2 ? ' '.$2 : '').'"')
166 .AddHtmlEnvironment('p');
169 return undef;
172 =head1 COPYRIGHT AND LICENSE
174 The information below applies to everything in this distribution,
175 except where noted.
177 Copyleft 2008 by B.w.Curry <http://www.raiazome.com>.
179 This program is free software; you can redistribute it and/or modify
180 it under the terms of the GNU General Public License as published by
181 the Free Software Foundation; either version 3 of the License, or
182 (at your option) any later version.
184 This program is distributed in the hope that it will be useful,
185 but WITHOUT ANY WARRANTY; without even the implied warranty of
186 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
187 GNU General Public License for more details.
189 You should have received a copy of the GNU General Public License
190 along with this program. If not, see L<http://www.gnu.org/licenses/>.
192 =cut