File Coverage

blib/lib/App/Chart/Texinfo/Util.pm
Criterion Covered Total %
statement 32 32 100.0
branch 7 8 87.5
condition n/a
subroutine 7 7 100.0
pod 1 1 100.0
total 47 48 97.9


line stmt bran cond sub pod time code
1             # Copyright 2007, 2008, 2009, 2010, 2011, 2016 Kevin Ryde
2              
3             # This file is part of Chart.
4             #
5             # Chart is free software; you can redistribute it and/or modify it under the
6             # terms of the GNU General Public License as published by the Free Software
7             # Foundation; either version 3, or (at your option) any later version.
8             #
9             # Chart is distributed in the hope that it will be useful, but WITHOUT ANY
10             # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11             # FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
12             # details.
13             #
14             # You should have received a copy of the GNU General Public License along
15             # with Chart. If not, see <http://www.gnu.org/licenses/>.
16              
17              
18             package App::Chart::Texinfo::Util;
19 1     1   417 use 5.004;
  1         3  
20 1     1   4 use strict;
  1         2  
  1         18  
21 1     1   4 use warnings;
  1         1  
  1         25  
22 1     1   4 use Exporter;
  1         2  
  1         29  
23              
24 1     1   5 use vars qw(@ISA @EXPORT_OK %EXPORT_TAGS $VERSION);
  1         1  
  1         278  
25             @ISA = qw(Exporter);
26             @EXPORT_OK = qw(node_to_html_anchor);
27             %EXPORT_TAGS = (all => \@EXPORT_OK);
28              
29              
30             # Nodes "HTML Xref Node Name Expansion"
31             # and "HTML Xref 8-bit Character Expansion" in the Texinfo manual
32             # Given $node is wide-char.
33             #
34             sub node_to_html_anchor {
35 7     7 1 21 my ($node) = @_;
36              
37             # precomposed characters where possible
38 7 100       27 if ($node =~ /[^[:ascii:]]/) {
39 2         379 require Unicode::Normalize;
40 2         1566 $node = Unicode::Normalize::NFC ($node);
41             }
42              
43             # rule 3 multiple space,tab,newline become one space
44 7         28 $node =~ s/[ \t\n]+/ /g;
45              
46             # rule 4 lose leading and trailing space
47 7         12 $node =~ s/^ +//;
48 7         11 $node =~ s/ +$//;
49              
50             # rule 6 chars except ascii alnum and the "-" (just inserted) become hex
51 7         29 $node =~ s/([^ A-Za-z0-9])/_escape_char($1)/ge;
  16         26  
52              
53             # rule 5 remaining spaces become dashes
54 7         17 $node =~ tr/ /-/;
55              
56             # rule 7 prepend "g_t" if doesn't begin with alpha
57 7 100       19 if ($node =~ /^[^A-Za-z]/) {
58 3         7 $node = 'g_t' . $node;
59             }
60 7         34 return $node;
61             }
62             # ENHANCE-ME: For EBCDIC presumably a UTF-EBCDIC -> unicode conversion is
63             # needed here, instead of just ord().
64             sub _escape_char {
65 16     16   30 my ($c) = @_; # single-char string
66 16         19 $c = ord($c);
67 16 100       29 if ($c <= 0xFFFF) {
    50          
68 15         55 return sprintf ('_%04x', $c);
69             } elsif ($c <= 0xFF_FFFF) {
70 1         5 return sprintf ('__%06x', $c);
71             }
72             }
73              
74             1;
75             __END__
76              
77             =for stopwords texinfo Texinfo utf unicode
78              
79             =head1 NAME
80              
81             App::Chart::Texinfo::Util -- some texinfo utilities
82              
83             =for test_synopsis my ($anchor, $node)
84              
85             =head1 SYNOPSIS
86              
87             use App::Chart::Texinfo::Util;
88             $anchor = App::Chart::Texinfo::Util::node_to_html_anchor ($node);
89              
90             # or imported
91             use App::Chart::Texinfo::Util ':all';
92             $anchor = node_to_html_anchor ($node);
93              
94             =head1 DESCRIPTION
95              
96             A function which hasn't found a better place to live yet.
97              
98             =head1 FUNCTIONS
99              
100             =over 4
101              
102             =item C<$string = App::Chart::Texinfo::Util::node_to_html_anchor ($node)>
103              
104             Return a HTML anchor for a Texinfo node name, as per anchor generation
105             specified in the Texinfo manual "HTML Xref Node Name Expansion" and "HTML
106             Xref 8-bit Character Expansion". It encodes various spaces and
107             non-alphanumeric characters as hexadecimal "_HHHH" sequences. For example,
108              
109             App::Chart::Texinfo::Util::node_to_html_anchor ('My Node-Name')
110             # returns 'My-Node_002dName'
111              
112             Perl utf8 wide-char strings can be passed here. Characters beyond 255 are
113             taken to be unicode and encoded as 4 or 6 hex digits per the Texinfo spec.
114              
115             =back
116              
117             =head1 SEE ALSO
118              
119             L<Texinfo::Menus>
120              
121             =head1 HOME PAGE
122              
123             L<http://user42.tuxfamily.org/chart/index.html>
124              
125             =head1 LICENCE
126              
127             Copyright 2007, 2008, 2009, 2010, 2011, 2016 Kevin Ryde
128              
129             Chart is free software; you can redistribute it and/or modify it under the
130             terms of the GNU General Public License as published by the Free Software
131             Foundation; either version 3, or (at your option) any later version.
132              
133             Chart is distributed in the hope that it will be useful, but WITHOUT ANY
134             WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
135             FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
136             details.
137              
138             You should have received a copy of the GNU General Public License along with
139             Chart; see the file F<COPYING>. Failing that, see
140             L<http://www.gnu.org/licenses/>.
141              
142             =cut