← Index
NYTProf Performance Profile   « line view »
For ./view
  Run on Fri Jul 31 18:42:36 2015
Reported on Fri Jul 31 18:48:15 2015

Filename/var/www/foswikidev/core/lib/Foswiki/Plugins/FindElsewherePlugin/Core.pm
StatementsExecuted 46 statements in 1.94ms
Subroutines
Calls P F Exclusive
Time
Inclusive
Time
Subroutine
11138µs229µsFoswiki::Plugins::FindElsewherePlugin::Core::::initPluginFoswiki::Plugins::FindElsewherePlugin::Core::initPlugin
51135µs35µsFoswiki::Plugins::FindElsewherePlugin::Core::::preRenderingHandlerFoswiki::Plugins::FindElsewherePlugin::Core::preRenderingHandler
11117µs30µsFoswiki::Plugins::FindElsewherePlugin::Core::::BEGIN@4Foswiki::Plugins::FindElsewherePlugin::Core::BEGIN@4
11110µs14µsFoswiki::Plugins::FindElsewherePlugin::Core::::BEGIN@5Foswiki::Plugins::FindElsewherePlugin::Core::BEGIN@5
1119µs40µsFoswiki::Plugins::FindElsewherePlugin::Core::::BEGIN@17Foswiki::Plugins::FindElsewherePlugin::Core::BEGIN@17
1114µs4µsFoswiki::Plugins::FindElsewherePlugin::Core::::BEGIN@7Foswiki::Plugins::FindElsewherePlugin::Core::BEGIN@7
0000s0sFoswiki::Plugins::FindElsewherePlugin::Core::::_findTopicElsewhereFoswiki::Plugins::FindElsewherePlugin::Core::_findTopicElsewhere
0000s0sFoswiki::Plugins::FindElsewherePlugin::Core::::_makeSingularFoswiki::Plugins::FindElsewherePlugin::Core::_makeSingular
0000s0sFoswiki::Plugins::FindElsewherePlugin::Core::::_putBackBlocksFoswiki::Plugins::FindElsewherePlugin::Core::_putBackBlocks
0000s0sFoswiki::Plugins::FindElsewherePlugin::Core::::_takeOutBlocksFoswiki::Plugins::FindElsewherePlugin::Core::_takeOutBlocks
0000s0sFoswiki::Plugins::FindElsewherePlugin::Core::::makeTopicLinkFoswiki::Plugins::FindElsewherePlugin::Core::makeTopicLink
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
2package Foswiki::Plugins::FindElsewherePlugin::Core;
3
4231µs243µs
# spent 30µs (17+13) within Foswiki::Plugins::FindElsewherePlugin::Core::BEGIN@4 which was called: # once (17µs+13µs) by Foswiki::Plugins::FindElsewherePlugin::initPlugin at line 4
use strict;
# spent 30µs making 1 call to Foswiki::Plugins::FindElsewherePlugin::Core::BEGIN@4 # spent 13µs making 1 call to strict::import
5252µs218µs
# spent 14µs (10+4) within Foswiki::Plugins::FindElsewherePlugin::Core::BEGIN@5 which was called: # once (10µs+4µs) by Foswiki::Plugins::FindElsewherePlugin::initPlugin at line 5
use warnings;
# spent 14µs making 1 call to Foswiki::Plugins::FindElsewherePlugin::Core::BEGIN@5 # spent 4µs making 1 call to warnings::import
6
7
# spent 4µs within Foswiki::Plugins::FindElsewherePlugin::Core::BEGIN@7 which was called: # once (4µs+0s) by Foswiki::Plugins::FindElsewherePlugin::initPlugin at line 14
BEGIN {
8
9 # Do a dynamic 'use locale' for this module
1015µs if ( $Foswiki::cfg{UseLocale} ) {
11 require locale;
12 import locale();
13 }
14122µs14µs}
15
16# Set to 1 to get debug messages written to the warnings log
1721.77ms270µs
# spent 40µs (9+31) within Foswiki::Plugins::FindElsewherePlugin::Core::BEGIN@17 which was called: # once (9µs+31µs) by Foswiki::Plugins::FindElsewherePlugin::initPlugin at line 17
use constant TRACE => 0;
# spent 40µs making 1 call to Foswiki::Plugins::FindElsewherePlugin::Core::BEGIN@17 # spent 31µs making 1 call to constant::import
18
191200nsmy $thisWeb;
201100nsmy $findAcronyms;
2110smy $disablePluralToSingular;
2210smy $redirectable;
231100nsmy @webList;
2410smy $singleMixedAlphaNumRegex;
251100nsmy $otherWebs;
261100nsmy $noAutolink;
27
281800nsmy $EMESC = "\1";
29
30
# spent 229µs (38+191) within Foswiki::Plugins::FindElsewherePlugin::Core::initPlugin which was called: # once (38µs+191µs) by Foswiki::Plugins::FindElsewherePlugin::initPlugin at line 29 of /var/www/foswikidev/core/lib/Foswiki/Plugins/FindElsewherePlugin.pm
sub initPlugin {
31
32 # initPlugin($topic, $web, $user) -> $boolean
33
341400ns $thisWeb = $_[1];
35
3612µs128µs $otherWebs = Foswiki::Func::getPreferencesValue("LOOKELSEWHEREWEBS");
# spent 28µs making 1 call to Foswiki::Func::getPreferencesValue
3712µs134µs unless ( defined($otherWebs) ) {
# spent 34µs making 1 call to Foswiki::Func::getPluginPreferencesValue
38
39 # Compatibility, deprecated
40 $otherWebs =
41 Foswiki::Func::getPluginPreferencesValue("LOOKELSEWHEREWEBS");
42 }
43
4411µs unless ( defined($otherWebs) ) {
45
46 # SMELL: Retained for compatibility, but would be much better
47 # off without this, as we could use the absence of webs to mean the
48 # plugin is disabled.
49 $otherWebs = "$Foswiki::cfg{SystemWebName},$Foswiki::cfg{UsersWebName}";
50 }
51
52 # Item10460: Expand some variables like %USERSWEB%
53 # WARNING: calling expandCommonVariables inside initPlugin is a bad thing to do
54 # as the engine isn't fully initialized at that point
551700ns $otherWebs =~ s/\%USERSWEB%/$Foswiki::cfg{UsersWebName}/g;
561300ns $otherWebs =~ s/\%SYSTEMWEB%/$Foswiki::cfg{SystemWebName}/g;
571200ns $otherWebs =~ s/\%SANDBOXWEB%/$Foswiki::cfg{SandboxWebName}/g;
58
5912µs120µs $findAcronyms =
# spent 20µs making 1 call to Foswiki::Func::getPreferencesValue
60 Foswiki::Func::getPreferencesValue("LOOKELSEWHEREFORACRONYMS") || "all";
61
6211µs124µs $disablePluralToSingular =
# spent 24µs making 1 call to Foswiki::Func::getPreferencesFlag
63 Foswiki::Func::getPreferencesFlag("DISABLEPLURALTOSINGULAR");
641200ns unless ( defined($disablePluralToSingular) ) {
65
66 # Compatibility, deprecated
67 $disablePluralToSingular =
68 Foswiki::Func::getPluginPreferencesFlag("DISABLEPLURALTOSINGULAR");
69 }
70
7111µs124µs $redirectable = Foswiki::Func::getPreferencesFlag("LOOKELSEWHEREFORLOCAL");
# spent 24µs making 1 call to Foswiki::Func::getPreferencesFlag
72
73112µs $singleMixedAlphaNumRegex = qr/[$Foswiki::regex{mixedAlphaNum}]/;
74
7515µs161µs $noAutolink = Foswiki::Func::getPreferencesFlag('NOAUTOLINK');
# spent 61µs making 1 call to Foswiki::Func::getPreferencesFlag
76
77}
78
79
# spent 35µs within Foswiki::Plugins::FindElsewherePlugin::Core::preRenderingHandler which was called 5 times, avg 7µs/call: # 5 times (35µs+0s) by Foswiki::Plugin::invoke at line 310 of /var/www/foswikidev/core/lib/Foswiki/Plugin.pm, avg 7µs/call
sub preRenderingHandler {
80
8155µs @webList = ();
82
83 # Might still be unexpanded macros - expand if necessary
8456µs if ( $otherWebs =~ m/%/ ) {
85 $otherWebs = Foswiki::Func::expandCommonVariables($otherWebs);
86 }
87
88516µs if ( $noAutolink ) {
89 return;
90 }
91
92 foreach my $otherWeb ( split( /[,\s]+/, $otherWebs ) ) {
93 $otherWeb = Foswiki::Sandbox::untaint( $otherWeb,
94 \&Foswiki::Sandbox::validateWebName );
95 push( @webList, $otherWeb ) if $otherWeb;
96 }
97
98 if ( exists( $Foswiki::cfg{FindElsewherePlugin}{CairoLegacyLinking} )
99 && $Foswiki::cfg{FindElsewherePlugin}{CairoLegacyLinking} )
100 {
101
102 #very old, pre-nested webs linking rules.
103 }
104 else {
105 unless ( scalar(@webList) ) {
106
107 # no point if there are no webs to search
108 return;
109 }
110 }
111
112 # Find instances of WikiWords not in this web, but in the otherWeb(s)
113 # If the WikiWord is found in theWeb, put the word back unchanged
114 # If the WikiWord is found in the otherWeb, link to it via
115 # [[otherWeb.WikiWord]]
116 # If it isn't found there either, put the word back unchnaged
117
118 my $removed = {};
119 my $text = _takeOutBlocks( $_[0], 'noautolink', $removed );
120
121 $text =~ s/(?<=[\s\(])
122 ($Foswiki::regex{emailAddrRegex})/${EMESC}<nop>$1/gox;
123
124 # Match
125 # 0) (Allowed preambles: "\s" and "(")
126 # 1) [[something]] - (including [[something][something]], but non-greedy),
127 # 2) WikiWordAsWebName.WikiWord,
128 # 3) WikiWords, and
129 # 4) WIK IWO RDS
130 my %linkedWords = ();
131 my $count = (
132 $text =~ s/(\[\[.*?\]\]|(?:^|(?<=[\s\(,]))
133 (?:$Foswiki::regex{webNameRegex}\.)?
134 (?:$Foswiki::regex{wikiWordRegex}
135 | $Foswiki::regex{abbrevRegex}))/
136 _findTopicElsewhere($thisWeb, $1, \%linkedWords)/gexo
137 );
138
139 $text =~ s/${EMESC}<nop>//go;
140
141 if ($count) {
142 _putBackBlocks( \$text, $removed, 'noautolink' );
143 $_[0] = $text;
144 }
145}
146
147sub makeTopicLink {
148 ##my($otherWeb, $topic) = @_;
149 return "[[$_[0].$_[1]][$_[0]]]";
150}
151
152sub _findTopicElsewhere {
153
154 # This was copied and pruned from Foswiki::internalLink
155 my ( $web, $topic, $linkedWords ) = @_;
156 my $original = $topic;
157 my $linkText = $topic;
158 my $nonForcedAcronym = 0;
159
160 Foswiki::Func::writeDebug(
161 "FindElsewherePlugin: Called $web, $topic Redirectable = $redirectable")
162 if TRACE;
163
164 if (
165 $topic =~ /^\[\[($Foswiki::regex{webNameRegex})\.
166 ($Foswiki::regex{wikiWordRegex})\](?:\[(.*)\])?\]$/ox
167 )
168 {
169 if ( $redirectable && $1 eq $web ) {
170
171 # The topic is *supposed* to be in this web, but the web is
172 # redirectable so we can ignore the web specifier
173 # remove the web name and continue
174 Foswiki::Func::writeDebug(
175 "FindElsewherePlugin: $topic $1 is redirectable")
176 if TRACE;
177 $topic = $2;
178 $linkText = $3 || $topic;
179 }
180 else {
181
182 # The topic is an explicit link to another web
183 return $topic;
184 }
185 }
186 elsif (
187 $topic =~ /^\[\[($Foswiki::regex{wikiWordRegex})\]
188 (?:\[(.*)\])?\]$/ox
189 )
190 {
191
192 # No web specifier, look elsewhere
193 $topic = $1;
194 $linkText = $2 || $topic;
195 }
196 elsif (
197 $topic =~ /^\[\[($Foswiki::regex{abbrevRegex})\]
198 (?:\[(.*)\])?\]$/ox
199 )
200 {
201
202 # No web specifier, look elsewhere
203 $topic = $1;
204 $linkText = $2 || $topic;
205 }
206 elsif ( $topic =~ /^$Foswiki::regex{abbrevRegex}$/o ) {
207 $nonForcedAcronym = 1;
208 }
209 elsif (
210 $topic =~ /^($Foswiki::regex{webNameRegex})\.
211 ($Foswiki::regex{wikiWordRegex})$/ox
212 )
213 {
214 if ( $redirectable && $1 eq $web ) {
215 $linkText = $topic = $2;
216 }
217 else {
218 return $topic;
219 }
220 }
221
222 if ($nonForcedAcronym) {
223 return $topic if $findAcronyms eq "none";
224 return $linkedWords->{$topic}
225 if ( $findAcronyms eq 'all' && $linkedWords->{$topic} );
226 return $topic
227 if ( $findAcronyms eq 'first' && $linkedWords->{$topic} );
228 }
229
230 # Turn spaced-out names into WikiWords - upper case first letter of
231 # whole link, and first of each word.
232 $topic =~ s/^(.)/\U$1/o;
233 $topic =~ s/\s($singleMixedAlphaNumRegex)/\U$1/go;
234 $topic =~ s/\[\[($singleMixedAlphaNumRegex)(.*)\]\]/\u$1$2/o;
235
236 # It's been validated
237 $web = Foswiki::Sandbox::untaintUnchecked($web);
238 $topic = Foswiki::Sandbox::untaintUnchecked($topic);
239
240 # Look in the current web, return if found
241 my $exist = Foswiki::Func::topicExists( $web, $topic );
242
243 if ( !$exist ) {
244 if ( !$disablePluralToSingular && $topic =~ /s$/ ) {
245 my $topicSingular = _makeSingular($topic);
246 if ( Foswiki::Func::topicExists( $web, $topicSingular ) ) {
247 Foswiki::Func::writeDebug(
248 "FindElsewherePlugin: $topicSingular was found in $web")
249 if TRACE;
250 return $original; # leave it as we found it
251 }
252 }
253 }
254 else {
255 Foswiki::Func::writeDebug(
256 "FindElsewherePlugin: $topic was found in $web: $linkText")
257 if TRACE;
258 return $original; # leave it as we found it
259 }
260
261 # Look in the other webs, return when found
262 my @topicLinks;
263
264 foreach my $otherWeb (@webList) {
265
266 # For systems running WebNameAsWikiName
267 # If the $topic is a reference to a the name of
268 # otherWeb, point at otherWeb.WebHome - MRJC
269 if ( $otherWeb eq $topic ) {
270 Foswiki::Func::writeDebug(
271"FindElsewherePlugin: $topic is the name of another web $otherWeb."
272 ) if TRACE;
273 return "[[$otherWeb.WebHome][$otherWeb]]";
274 }
275
276 my $exist = Foswiki::Func::topicExists( $otherWeb, $topic );
277 if ( !$exist ) {
278 if ( !$disablePluralToSingular && $topic =~ /s$/ ) {
279 my $topicSingular = _makeSingular($topic);
280 if ( Foswiki::Func::topicExists( $otherWeb, $topicSingular ) ) {
281 Foswiki::Func::writeDebug(
282"FindElsewherePlugin: $topicSingular was found in $otherWeb"
283 ) if TRACE;
284 push( @topicLinks, makeTopicLink( $otherWeb, $topic ) );
285 }
286 }
287 }
288 else {
289 Foswiki::Func::writeDebug(
290 "FindElsewherePlugin: $topic was found in $otherWeb")
291 if TRACE;
292 push( @topicLinks, makeTopicLink( $otherWeb, $topic ) );
293 }
294 }
295
296 if ( scalar(@topicLinks) > 0 ) {
297 if ( scalar(@topicLinks) == 1 ) {
298
299 # Topic found in one place
300 # If link text [[was in this form]], free it
301 $linkText =~ s/\[\[(.*)\]\]/$1/o;
302
303 # Link to topic
304 $topicLinks[0] =~ s/(\[\[.*?\]\[)(.*?)(\]\])/$1$linkText$3/o;
305 $linkedWords->{$topic} = $topicLinks[0];
306 return $topicLinks[0];
307 }
308 else {
309
310 # topic found in several places
311 # If link text [[was in this form]] <em> it
312 $linkText =~ s/\[\[(.*)\]\]/<em>$1<\/em>/go;
313
314 # If $linkText is a WikiWord, prepend with <nop>
315 # (prevent double links)
316 $linkText =~ s/($Foswiki::regex{wikiWordRegex})/<nop\/>$1/go;
317 my $renderedLink =
318 "$linkText<sup>(" . join( ",", @topicLinks ) . ")</sup>";
319 $linkedWords->{$topic} = $renderedLink;
320 return $renderedLink;
321 }
322 }
323
324 if ( exists( $Foswiki::cfg{FindElsewherePlugin}{CairoLegacyLinking} )
325 && $Foswiki::cfg{FindElsewherePlugin}{CairoLegacyLinking} )
326 {
327
328 #pre-nested webs TWiki treated non-wikiwords more liberally
329 #print STDERR "===( $web, $topic )\n";
330 #replace space letter with uc(letter)
331 #$topic =~ s/\s(\w)/uc($1)/ge;
332 #remove all other non-wikiword links
333 $topic =~ s/[^$Foswiki::regex{mixedAlphaNum}]//g;
334
335 #test for existance
336 #print STDERR "------ exists($web, $topic)\n";
337
338 if ( Foswiki::Func::topicExists( $web, $topic ) ) {
339
340 # Topic found in one place
341 # If link text [[was in this form]], free it
342 $linkText =~ s/\[\[(.*)\]\]/$1/o;
343
344 #print STDERR "------==== >> [[$topic][$linkText]]\n";
345 return "[[$topic][$linkText]]";
346 }
347 }
348
349 return $original;
350}
351
352sub _makeSingular {
353 my ($theWord) = @_;
354
355 $theWord =~ s/ies$/y/o; # plurals like policy / policies
356 $theWord =~ s/sses$/ss/o; # plurals like address / addresses
357 $theWord =~ s/([Xx])es$/$1/o; # plurals like box / boxes
358 $theWord =~
359 s/([A-Za-rt-z])s$/$1/o; # others, excluding ending ss like address(es)
360 return $theWord;
361}
362
3631200nsmy $placeholderMarker = 0;
364
365sub _takeOutBlocks {
366 my ( $intext, $tag, $map ) = @_;
367
368 return $intext unless ( $intext =~ m/<$tag\b/i );
369
370 my $out = '';
371 my $depth = 0;
372 my $scoop;
373 my $tagParams;
374
375 foreach my $token ( split /(<\/?$tag[^>]*>)/i, $intext ) {
376 if ( $token =~ /<$tag\b([^>]*)?>/i ) {
377 $depth++;
378 if ( $depth eq 1 ) {
379 $tagParams = $1;
380 next;
381 }
382 }
383 elsif ( $token =~ /<\/$tag>/i ) {
384 if ( $depth > 0 ) {
385 $depth--;
386 if ( $depth eq 0 ) {
387 my $placeholder = $tag . $placeholderMarker;
388 $placeholderMarker++;
389 $map->{$placeholder}{text} = $scoop;
390 $map->{$placeholder}{params} = $tagParams;
391 $out .= '<!--'
392 . $Foswiki::TranslationToken
393 . $placeholder
394 . $Foswiki::TranslationToken . '-->';
395 $scoop = '';
396 next;
397 }
398 }
399 }
400 if ( $depth > 0 ) {
401 $scoop .= $token;
402 }
403 else {
404 $out .= $token;
405 }
406 }
407
408 # unmatched tags
409 if ( defined($scoop) && ( $scoop ne '' ) ) {
410 my $placeholder = $tag . $placeholderMarker;
411 $placeholderMarker++;
412 $map->{$placeholder}{text} = $scoop;
413 $map->{$placeholder}{params} = $tagParams;
414 $out .= '<!--'
415 . $Foswiki::TranslationToken
416 . $placeholder
417 . $Foswiki::TranslationToken . '-->';
418 }
419
420 return $out;
421}
422
423sub _putBackBlocks {
424 my ( $text, $map, $tag, $newtag, $callback ) = @_;
425
426 $newtag = $tag if ( !defined($newtag) );
427
428 foreach my $placeholder ( keys %$map ) {
429 if ( $placeholder =~ /^$tag\d+$/ ) {
430 my $params = $map->{$placeholder}{params} || '';
431 my $val = $map->{$placeholder}{text};
432 $val = &$callback($val) if ( defined($callback) );
433 if ( $newtag eq '' ) {
434 $$text =~ s(<!--$Foswiki::TranslationToken$placeholder
435 $Foswiki::TranslationToken-->
436 )($val)x;
437 }
438 else {
439 $$text =~ s(<!--$Foswiki::TranslationToken$placeholder
440 $Foswiki::TranslationToken-->
441 )(<$newtag$params>$val</$newtag>)x;
442 }
443 delete( $map->{$placeholder} );
444 }
445 }
446}
447
44814µs1;
449__END__