Skip to content

Commit

Permalink
Item8433: Restructured plugin, added feature to limit acronym links t…
Browse files Browse the repository at this point in the history
…o first instance in a topic.

git-svn-id: http://svn.foswiki.org/trunk/ControlWikiWordPlugin@6184 0b4bb1d4-4e5a-0410-9cc4-b2b747904278
  • Loading branch information
GeorgeClark authored and GeorgeClark committed Jan 28, 2010
1 parent 8e6b37a commit 4f76b7a
Show file tree
Hide file tree
Showing 5 changed files with 293 additions and 124 deletions.
47 changes: 33 additions & 14 deletions data/System/ControlWikiWordPlugin.txt
Expand Up @@ -9,15 +9,18 @@ prefer.
-->
%SHORTDESCRIPTION%

%TOC%
%TOC{depth="3"}%

---++ Usage

This plugin provides 3 functions:
* Rules-based blocking of WikiWord linking backwards compatible to the !StopWikiWordPlugin (Configurable by any user)
This plugin provides 4 functions:
* Rules-based blocking of WikiWord linking backwards compatible to the !StopWikiWordPlugin
* Limit linking of Acronyms to the first instance in a topic.
* !Singleton WikiWord linking backwards compatible to the !SingletonWikiWordPlugin
* Regular Expression rules-based Singleton WikiWord linking (Configurable only by system administrator)

All functions are disabled by default unless explicitly enabled.

-----
---+++ Rules-based blocking of WikiWord linking

Expand All @@ -38,14 +41,40 @@ In this mode, the Plugin prevents automatic linking of selected [[%SYSTEMWEB%.Wi
* LinuxWorld, MacDonald

-----
---+++ Acronym Linking Control

In addition to WikiWords, Foswiki will auto-link Acronyms - any string
consisting of 3 or more upper-case letters and numbers. WikiWords are always
linked - displaying a question mark if the topic does not exist. Acronyms
however only link when the topic exists.

In some technical
topics, this can result in excessive linking. This feature will limit
acronym links to only the first occurrence of an acronym in a topic. Forced
[<nop>[link]] however will always be honored.

---++++ Configuration

To limit Acronym linking, add the CONTROLWIKIWORDPLUGIN_LIMITACRONYMS setting
to the [[%LOCALSITEPREFS%]] topic or in any web in %WEBPREFSTOPIC%, or in user
or individual topics. This mode of operation is not enabled by default. (This
setting can be abbreviated as simply =LIMITACRONYMS=.)

<verbatim>
* Set CONTROLWIKIWORDPLUGIN_LIMITACRONYMS = 1
</verbatim>

---++++ Examples
HTML is an example of an ACRONYM, as is RSS. If an ACRONYM occurs twice, only
the first instance will be linked.

---+++ Singleton<nop>WikiWordPlugin compatible operation

In this mode, the plugin will interpret that a single word is a reference to a Foswiki Topic of that name. To create a Singleton link, write a dot before the topic name. For example, if you have a topic named _Ontology_ you can link to it as _<nop><strong>.</strong>Ontology_ This adds a simpler way to force a single word link. You can already accomplish the same thing by enclosing the word in double square brackets, like this: <nop>[<nop>[Ontology]]

The syntax was chosen to be an extension of the _Web.Topic_ syntax. The syntax does not support topic names qualified with the web name. So to link to _Ontology_ in a different web than the current web, you need to use the square-bracket mode of forcing the links, [%NOP%[Support.Ontology][Support.Ontology]]

---++++ Configuration

To enable backwards compatible operation with the TWiki !SingletonWikiWordPlugin, Add the CONTROLWIKIWORDPLUGIN_DOTSINGLETONENABLE setting to the [[%LOCALSITEPREFS%]] topic or in any web in %WEBPREFSTOPIC%, or in user or individual topics. This mode of operation is not enabled by default.

<verbatim>
Expand Down Expand Up @@ -129,13 +158,3 @@ modifiers. The - "negates" or turns off the following options:
| Support: | http://foswiki.org/bin/view/Support/ControlWikiWordPlugin |

<!-- Do _not_ attempt to edit this topic; it is auto-generated. -->


%META:FORM{name="PackageForm"}%
%META:FIELD{name="ExtensionClassification" attributes="" %title="ExtensionClassification" value="Interface and Visualisation"}%
%META:FIELD{name="ExtensionType" attributes="" title="ExtensionType" value="PluginPackage"}%
%META:FIELD{name="Compatibility" attributes="" title="[[Compatibility]]" value="Should run with: All Foswiki versions."}%
%META:FIELD{name="DemoUrl" attributes="" title="DemoUrl" value=""}%
%META:FIELD{name="SupportUrl" attributes="" title="SupportUrl" value="Support.ControlWikiWordPlutin"}%
%META:FIELD{name="DevelopedInSVN" attributes="" title="DevelopedInSVN" value="Yes"}%
%META:FIELD{name="ModificationPolicy" attributes="" title="ModificationPolicy" value="PleaseFeelFreeToModify"}%
144 changes: 37 additions & 107 deletions lib/Foswiki/Plugins/ControlWikiWordPlugin.pm
@@ -1,4 +1,3 @@
#
# Foswiki WikiClone ($wikiversion has version info)
#
# Copyright (C) 2010 George Clark, geonwiki@fenachrone.com
Expand All @@ -21,8 +20,7 @@
# GNU General Public License for more details, published at
# http://www.gnu.org/copyleft/gpl.html

# =========================
package Foswiki::Plugins::ControlWikiWordPlugin; # change the package name!!!
package Foswiki::Plugins::ControlWikiWordPlugin;

use strict;
use warnings;
Expand Down Expand Up @@ -55,135 +53,67 @@ our $SHORTDESCRIPTION =
# entries so they can be used with =configure=.
our $NO_PREFS_IN_TOPIC = 1;

# Module variables used between functions within this module
my $web;
my $topic;
my $user;
my $installWeb;
my $debug;

my $stopWordsRE = ''; # Regex constructed from user input to stop linking
my $dotSINGLETON = 0; # Enable/Disable parameter for the .Singleton format
my $regexInput = ''; # Regex parameters passed from $Foswiki::cfg
my $disabled = 0;
my $web; # preRendering handler needs current web - passed from initPlugin
my %prefs;

# =========================
sub initPlugin {
( $topic, $web, $user, $installWeb ) = @_;

#my( $topic, $web, $user, $installWeb ) = @_;

# check for Plugins.pm versions
if ( $Foswiki::Plugins::VERSION < 2 ) {
&Foswiki::Func::writeWarning(
if ( $Foswiki::Plugins::VERSION < 1 ) {
Foswiki::Func::writeWarning(
"Version mismatch between ControlWikiWordPlugin and Plugins.pm");
return 0;
}

# Get plugin debug flag
$debug = &Foswiki::Func::getPreferencesFlag("CONTROLWIKIWORDPLUGIN_DEBUG");
if ( Foswiki::Func::getPreferencesFlag('NOAUTOLINK') )
{ # skip plugin if noautolink set for whole topic
$disabled = 1;
return 1;
}

$web = $_[1];

$prefs{'regexInput'} =
$Foswiki::cfg{Plugins}{ControlWikiWordPlugin}{SingletonWords}
|| {};

my $stopWords = Foswiki::Func::getPreferencesValue("STOPWIKIWORDLINK")
$prefs{'stopWords'} = Foswiki::Func::getPreferencesValue("STOPWIKIWORDLINK")
|| Foswiki::Func::getPreferencesValue(
"CONTROLWIKIWORDPLUGIN_STOPWIKIWORDLINK")
|| Foswiki::Func::getPreferencesValue(
"STOPWIKIWORDLINKPLUGIN_STOPWIKIWORDLINK")
|| '';

$stopWordsRE = ''; # Clear - handler only processes topic if provided

if ($stopWords) {

# build regularex:
$stopWords =~ s/\, */\|/go;
$stopWords =~ s/^ *//o;
$stopWords =~ s/ *$//o;
$stopWords =~ s/[^A-Za-z0-9\|]//go;
$stopWordsRE = "(^|[\( \n\r\t\|])($stopWords)"
; # WikiWord preceeded by space or parens
Foswiki::Func::writeDebug(
"ControlWikiWordPlugin - stopWordsRE: $stopWordsRE")
if $debug;
}
$prefs{'controlAbbrev'} =
Foswiki::Func::getPreferencesValue("LIMITACRONYMS")
|| Foswiki::Func::getPreferencesValue(
"CONTROLWIKIWORDPLUGIN_LIMITACRONYMS")
|| '';

$dotSINGLETON = Foswiki::Func::getPreferencesValue(
$prefs{'dotSINGLETON'} = Foswiki::Func::getPreferencesValue(
"CONTROLWIKIWORDPLUGIN_DOTSINGLETONENABLE")
|| '';

$regexInput = $Foswiki::cfg{Plugins}{ControlWikiWordPlugin}{SingletonWords}
|| {};
$disabled = 1
unless ( $prefs{'regexInput'}
|| $prefs{'stopWords'}
|| $prefs{'controlAbbrev'}
|| $prefs{'dotSINGLETON'} );

# Plugin correctly initialized
Foswiki::Func::writeDebug(
"- Foswiki::Plugins::ControlWikiWordPlugin::initPlugin( $web.$topic ) is OK"
) if $debug;
return 1;
}

#===========================================================================
sub preRenderingHandler {
### my ( $text, $map ) = @_;
#
return if ($disabled);

# do not uncomment, use $_[0], $_[1]... instead
#my( $text, $pMap ) = @_;

my $renderer = $Foswiki::Plugins::SESSION->renderer();
my $removedTextareas = {};
my $removedProtected = {};

$_[0] =~ s/$stopWordsRE/$1<nop>$2/g if ($stopWordsRE);

# If we don't have any regex and don't want the dot format, forget it.
if ( scalar keys %$regexInput > 0 || $dotSINGLETON ) {

# Don't bother at all if NOAUTOLINK is requested for the topic.
unless ( Foswiki::Func::getPreferencesFlag('NOAUTOLINK') ) {

# SMELL: Directly calling Foswiki and Render functions is not recommended.
# This needs to be validated for any major changes in Foswiki. Tested on 1.0.9 and 1.1.0 trunk
# Determine which release of Foswiki in use - R1.1 moved takeOUtBlocks into Foswiki proper

# Remove any <noautolink> blocks from the topic
eval(
'$renderer->takeOutBlocks( $_[0], \'noautolink\', $removedTextareas )'
);
if ( $@ ne "" ) {
$_[0] =
Foswiki::takeOutBlocks( $_[0], 'noautolink',
$removedTextareas );
}

# Also remove any forced links from the topic.
$_[0] =
$renderer->_takeOutProtected( $_[0], qr/\[\[(?:.*?)\]\]/si,
'wikilink', $removedProtected );
$_[0] = $renderer->_takeOutProtected(
$_[0], qr/<a\s(?:.*?)<\/a>/si,
'htmllink', $removedProtected
);

foreach my $regex ( keys(%$regexInput) ) {
my $linkWeb = $regexInput->{$regex} || $web;
Foswiki::Func::writeDebug(" Regex is $regex Web is $linkWeb ")
if $debug;
$_[0] =~ s/(\s)($regex)\b/$1."[[$linkWeb.$2][$2]]"/ge;
}
$_[0] =~ s/(\s+)\.([A-Z]+[a-z]*)/"$1"."[[$web.$2][$2]]"/geo
if ($dotSINGLETON);

# put back everything that was removed
if ($@) {
Foswiki::putBackBlocks( \$_[0], $removedTextareas, 'noautolink',
'noautolink' );
}
else {
$renderer->putBackBlocks( \$_[0], $removedTextareas,
'noautolink', 'noautolink' );
}
$renderer->_putBackProtected( \$_[0], 'wikilink',
$removedProtected );
$renderer->_putBackProtected( \$_[0], 'htmllink',
$removedProtected );
}
}

require Foswiki::Plugins::ControlWikiWordPlugin::Core;
return Foswiki::Plugins::ControlWikiWordPlugin::Core::_preRender( $_[0],
$web, \%prefs );
}

1;

0 comments on commit 4f76b7a

Please sign in to comment.