← Index
NYTProf Performance Profile   « line view »
For ./view
  Run on Fri Jul 31 19:05:14 2015
Reported on Fri Jul 31 19:08:10 2015

Filename/var/www/foswiki11/lib/Foswiki/Render/Anchors.pm
StatementsExecuted 26 statements in 952µs
Subroutines
Calls P F Exclusive
Time
Inclusive
Time
Subroutine
11134µs34µsFoswiki::Render::Anchors::::makeFoswiki::Render::Anchors::make
51121µs21µsFoswiki::Render::Anchors::::clearFoswiki::Render::Anchors::clear
11115µs31µsFoswiki::Render::Anchors::::BEGIN@16Foswiki::Render::Anchors::BEGIN@16
11110µs16µsFoswiki::Render::Anchors::::BEGIN@17Foswiki::Render::Anchors::BEGIN@17
11110µs26µsFoswiki::Render::Anchors::::BEGIN@18Foswiki::Render::Anchors::BEGIN@18
11110µs44µsFoswiki::Render::Anchors::::addFoswiki::Render::Anchors::add
11110µs10µsFoswiki::Render::Anchors::::newFoswiki::Render::Anchors::new
0000s0sFoswiki::Render::Anchors::::addUniqueFoswiki::Render::Anchors::addUnique
0000s0sFoswiki::Render::Anchors::::makeHTMLTargetFoswiki::Render::Anchors::makeHTMLTarget
Call graph for these subroutines as a Graphviz dot language file.
Line State
ments
Time
on line
Calls Time
in subs
Code
1# See bottom of file for license and copyright information
2
3=begin TML
4
5---+ package Foswiki::Render::Anchors
6
7Support for rendering anchors. Objects of this class represent
8a set of generated anchor names, which must be unique in a rendering
9context (topic). The renderer maintains a set of these objects, one
10for each topic, to ensure that anchor names are not re-used.
11
12=cut
13
14package Foswiki::Render::Anchors;
15
16231µs247µs
# spent 31µs (15+16) within Foswiki::Render::Anchors::BEGIN@16 which was called: # once (15µs+16µs) by Foswiki::Render::BEGIN@19 at line 16
use strict;
# spent 31µs making 1 call to Foswiki::Render::Anchors::BEGIN@16 # spent 16µs making 1 call to strict::import
17228µs222µs
# spent 16µs (10+6) within Foswiki::Render::Anchors::BEGIN@17 which was called: # once (10µs+6µs) by Foswiki::Render::BEGIN@19 at line 17
use warnings;
# spent 16µs making 1 call to Foswiki::Render::Anchors::BEGIN@17 # spent 6µs making 1 call to warnings::import
182811µs242µs
# spent 26µs (10+16) within Foswiki::Render::Anchors::BEGIN@18 which was called: # once (10µs+16µs) by Foswiki::Render::BEGIN@19 at line 18
use Assert;
# spent 26µs making 1 call to Foswiki::Render::Anchors::BEGIN@18 # spent 16µs making 1 call to Assert::import
19
20=begin TML
21
22---++ ClassMethod new()
23
24Construct a new anchors set.
25
26=cut
27
28
# spent 10µs within Foswiki::Render::Anchors::new which was called: # once (10µs+0s) by Foswiki::Render::getAnchorNames at line 2229 of /var/www/foswiki11/lib/Foswiki/Render.pm
sub new {
29112µs return bless( { names => {} }, shift );
30}
31
32=begin TML
33
34---++ ObjectMethod clear()
35
36Clear the anchor set. Clearing the anchor set will cause it to forget
37any anchors generated to date.
38
39=cut
40
41
# spent 21µs within Foswiki::Render::Anchors::clear which was called 5 times, avg 4µs/call: # 5 times (21µs+0s) by Foswiki::Render::getRenderedVersion at line 1256 of /var/www/foswiki11/lib/Foswiki/Render.pm, avg 4µs/call
sub clear {
4252µs my $this = shift;
43519µs $this->{names} = {};
44}
45
46=begin TML
47
48---++ ObjectMethod add($text) -> $name
49Add a new anchor to the set. Return the name that was added.
50Note that if a name is added twice, it isn't an error, but only
51the one name is added.
52
53=cut
54
55
# spent 44µs (10+34) within Foswiki::Render::Anchors::add which was called: # once (10µs+34µs) by Foswiki::Render::getRenderedVersion at line 1261 of /var/www/foswiki11/lib/Foswiki/Render.pm
sub add {
5612µs my ( $this, $text ) = @_;
5712µs134µs my $anchorName = make($text);
# spent 34µs making 1 call to Foswiki::Render::Anchors::make
5811µs $this->{names}->{$anchorName} = 1;
5914µs return $anchorName;
60}
61
62=begin TML
63
64---++ ObjectMethod addUnique($text [,$alreadyMade]) -> $uniqueName
65Add a new anchor to the set. if it's already present, rename it.
66
67If =$alreadyMade=, then $text is assumed to be a valid anchor name
68that was made by =make=.
69
70Return the name that was added.
71
72=cut
73
74sub addUnique {
75 my ( $this, $text, $alreadyMade ) = @_;
76 my $anchorName;
77 if ($alreadyMade) {
78 $anchorName = $text;
79 }
80 else {
81 $anchorName = make($text);
82 }
83 my $cnt = 1;
84 my $suffix = '';
85
86 while ( exists $this->{names}->{ $anchorName . $suffix } ) {
87
88 # $anchorName.$suffix must _always_ be 'compatible', or things
89 # would get complicated (whatever that means)
90 $suffix = '_AN' . $cnt++;
91
92 # limit resulting name to 32 chars
93 $anchorName = substr( $anchorName, 0, 32 - length($suffix) );
94
95 # this is only needed because '__' would not be 'compatible'
96 $anchorName =~ s/_+$//g;
97 }
98 $anchorName .= $suffix;
99 $this->{names}->{$anchorName} = 1;
100 return $anchorName;
101}
102
103=begin TML
104
105---++ StaticMethod make( $text ) -> $name
106
107Make an anchor name from some text, subject to:
108 1 Given the same text, this function must always return the same
109 anchor name
110 2 NAME tokens must begin with a letter ([A-Za-z]) and may be
111 followed by any number of letters, digits ([0-9]), hyphens ("-"),
112 underscores ("_"), colons (":"), and periods (".").
113 (from http://www.w3.org/TR/html401/struct/links.html#h-12.2.1)
114
115The making process tranforms an arbitrary text string to a string that
116can legally be used for an HTML anchor.
117
118=cut
119
120
# spent 34µs within Foswiki::Render::Anchors::make which was called: # once (34µs+0s) by Foswiki::Render::Anchors::add at line 57
sub make {
1211800ns my ($text) = @_;
122
12314µs $text =~ s/^\s*(.*?)\s*$/$1/;
124116µs $text =~ s/$Foswiki::regex{headerPatternNoTOC}//go;
125
126117µs if ( $text =~ /^$Foswiki::regex{anchorRegex}$/ ) {
127
128 # accept, already valid -- just remove leading #
129 return substr( $text, 1 );
130 }
131
132 # $anchorName is a *byte* string. If it contains any wide characters
133 # the encoding algorithm will not work.
134 #ASSERT($text !~ /[^\x00-\xFF]/) if DEBUG;
135 $text =~ s/[^\x00-\xFF]//g;
136 ASSERT( $text !~ /[^\x00-\xFF]/ ) if DEBUG;
137
138 # SMELL: This corrects for anchors containing < and >
139 # which for some reason are encoded when building the anchor, but
140 # un-encoded when building the link.
141 #
142 # Convert &, < and > back from entity
143 $text =~ s/&lt;/</g;
144 $text =~ s/&gt;/>/g;
145 $text =~ s/&amp;/&/g;
146
147 # strip out potential links so they don't get rendered.
148 # remove double bracket link
149 $text =~ s/\[(?:\[.*?\])?\[(.*?)\]\s*\]/$1/g;
150
151 # remove HTML tags and entities
152 $text =~ s/<\/?[a-zA-Z][^>]*>//gi;
153 $text =~ s/&#?[a-zA-Z0-9]+;//g;
154
155 # remove escape from escaped wikiWords
156 $text =~
157 s/!($Foswiki::regex{wikiWordRegex}|$Foswiki::regex{abbrevRegex})/$1/go;
158
159 # remove spaces
160 $text =~ s/\s+/_/g;
161
162 # use _ as an escape character to escape any byte outside the
163 # range specified by http://www.w3.org/TR/html401/struct/links.html
164 $text =~ s/([^A-Za-z0-9:._])/'_'.sprintf('%02d', ord($1))/ge;
165
166 # clean up a bit
167 $text =~ s/__/_/g;
168 $text =~ s/^_*//;
169 $text =~ s/_*$//;
170
171 # Ensure the anchor always starts with an [A-Za-z]
172 $text = 'A_' . $text unless $text =~ /^[A-Za-z]/;
173
174 return $text;
175}
176
177=begin TML
178
179---++ ObjectMethod makeHTMLTarget($name) -> $html
180Make an HTML anchor that can be used as the target of links.
181
182=cut
183
184sub makeHTMLTarget {
185 my ( $this, $text ) = @_;
186
187 my $goodAnchor = make($text);
188 my $html = CGI::a( { name => $this->addUnique( $goodAnchor, 1 ) }, '' );
189
190 if ( $Foswiki::cfg{RequireCompatibleAnchors} ) {
191
192 # Add in extra anchors compatible with old formats, as required
193 require Foswiki::Compatibility;
194 my @extras = Foswiki::Compatibility::makeCompatibleAnchors($text);
195 foreach my $extra (@extras) {
196 next if ( $extra eq $goodAnchor );
197 $html .= CGI::a( { name => $this->addUnique( $extra, 1 ), }, '' );
198 }
199 }
200 return $html;
201}
202
20313µs1;
204__END__