Extension:Auto-Anchor
![]() | This extension stores its source code on a wiki page. Please be aware that this code may be unreviewed or maliciously altered. They may contain security holes, outdated interfaces that are no longer compatible etc. Note: No localisation updates are provided for this extension by translatewiki.net . |
![]() | This extension is currently not actively maintained! Although it may still work, any bug reports or feature requests will more than likely be ignored. |
Auto-Anchor Release status: unmaintained |
|
---|---|
Implementation | Parser extension , Parser function |
Description | Create id attribute values using a similar mechanism that headers use |
Author(s) | David M. Sledge |
Latest version | 0.7.0 (2007-12-07) |
MediaWiki | 1.11.0+ |
License | GNU General Public License 2.0 or later |
Download | See instructions |
Introduction[edit]
One thing about wiki headers is that, with the following:
==='''[[some page|Header Text]] More ''Text'''''===
MediaWiki is smart enough to strip out all the markup and hyper-linking from the text to create an anchor with the name "Header_Text_More_Text." However, it's been found that sometimes this mechanism is desired outside the headers, because, although, it does a great job making destination anchors, one doesn't necessarily want every destination anchor showing up in the TOC. And though you can manually create the destination anchor like so:
<span id="Header Text More Text">'''[[some page|Header Text]] More ''Text'''''</span>
Some of us are just plain lazy. This is where this simple little extension comes into play.
Usage[edit]
{{#anc: wikitext [| count ]}}
Where count is 0 or any positive integer. It specifies the number of wiki-headers that already have "wikitext". This is needed because there no way for the extension to know what IDs are already in use. (See bugzilla:7356.)
Examples[edit]
{{#anc: '''Runnin' Down''' [[A Dream]] }}
gives Runnin' Down A Dream where the ID of the surrounding span tag is Runnin.27_Down_A_Dream. So if I want to link to that section I can just copy the text and paste into a wiki-syntax link:
[[#Runnin' Down A Dream|Link! Damn you!]]
yields Link! Damn you!.
Specifying count as "4"
{{#anc: '''Runnin' Down''' [[A Dream]] | 4 }}
gives the id as Runnin.27_Down_A_Dream_5 without changing the displayed text.
Don't Templates Like Anchor Already Do This?[edit]
The template doesn't strip out any markup. So if a template named Template:Anchor were used whose content is
<span id="{{{id|{{{1}}}}}}">{{{1}}}</span>
using the above example like so
{{anchor|'''Runnin' Down''' [[A Dream]]}}
would give the id as .27.27.27Runnin.27_Down.27.27.27_.5B.5BA_Dream.5D.5D.
Known Issues[edit]
- No guarantee of ID uniqueness.
- Does not ensure the first character of the ID is a letter. Blocked by bugzilla:4515.
- Newlines as part of the input may result in overlapping HTML tags blocks.
Download instructions[edit]
Please cut and paste the code found below and place it in $IP/extensions/AutoAnchor/AutoAnchor.php
and $IP/extensions/AutoAnchor/AutoAnchor.i18n.php
. Note: $IP stands for the root directory of your MediaWiki installation, the same directory that holds LocalSettings.php .
Installation[edit]
To install this extension, add the following to LocalSettings.php :
require_once("$IP/extensions/AutoAnchor/AutoAnchor.php");
Code[edit]
AutoAnchor.php[edit]
<?php
$wgExtensionFunctions[] = array( 'ExtAutoAnchor', 'setup' );
$wgHooks['LanguageGetMagic'][] = 'ExtAutoAnchor::languageGetMagic';
$wgExtensionCredits['parserhook'][] = array(
'name' => 'Auto-Anchor Extension',
'author' => 'David M. Sledge',
"url" => "http://www.mediawiki.org/wiki/Extension:Auto-Anchor",
'version' => ExtAutoAnchor::VERSION,
"description" => "Create header-like anchors IDs without headers",
);
class ExtAutoAnchor
{
const VERSION = '0.7.0';
public static $ids = array();
public static function setup()
{
global $wgParser;
$wgParser->setFunctionHook( 'anc', array( __CLASS__, 'autoAnchor' ) );
}
public static function languageGetMagic( &$magicWords, $langCode )
{
require_once( dirname( __FILE__ ) . '/AutoAnchor.i18n.php' );
foreach( AutoAnchor_i18n::magicWords( $langCode ) as $word => $trans )
$magicWords[$word] = $trans;
return true;
}
public static function autoAnchor( &$parser, $input, $count = '0' )
{
// need some input to make the id
if ( $input === '' )
// error: no input
return '';
// get the value of the 'count' attribute This attribute indicates the
// number of wiki headers that use this text. This extension is unable
// to get that information itself so it must be supplied by the user; if
// not specified, it defaults to 0.
$count = intval( $attrs["count"] );
// make sure it's not less than 0
if ( $count < 0 )
$count = 0;
// parse the input
$parsedInput = $parser->recursiveTagParse( $input );
// strip out the encoded link to get the displayed text which
// will be used to generate the span tag's id attribute value.
$id = $parser->replaceLinkHoldersText( $parsedInput );
// strip out any HTML markup
$id = trim( preg_replace( '/<.*?>/m', '', $id ) );
// escape the string so it contains valid
// characters for the id attribute
$id = Sanitizer::escapeId( $id, Sanitizer::NONE );
// make sure the ID is unique
$id = self::getUniqueID( $id, $count );
// put it all together
$spanid = "<span id=\"$id\">$input</span>";
return $spanid;
}
// known limitation: MediaWiki currently (v1.11.0) has no mechanism for
// enforcing id-uniqueness within an article, so it's entirely possible that
// another HTML tag will have the same id attribute value as the ones
// supplied by this method. We can however, enforce uniqueness the with IDs
// generated within this extension
private static function getUniqueID( $id, $count )
{
$count++;
// if this isn't the first instance of this id, we append the number of
// this instance to the id: "wikitext_2", "wikitext_3",
// "wikitext_4",... "wikitext_n".
if ( in_array( $count == 1 ? $id : $id . '_' . $count, self::$ids ) )
{
// of course we have to make sure "wikitext_x" doesn't already exist
// if it does, we increment x by one until we hit an id that doesn't
// exist yet
for ( $count++; in_array( $id . '_' . $count, self::$ids ); $count++ ) ;
self::$ids[] = $id . '_' . $count;
return end( self::$ids );
}
self::$ids[] = $count == 1 ? $id : $id . '_' . $count;
return end( self::$ids );
}
}
AutoAnchor.i18n.php[edit]
<?php
class AutoAnchor_i18n
{
private static $words = array(
// English
'en' => array(
'anc' => array( 0, 'anc' ),
),
);
private static $messages = array(
// English
'en' => array(),
);
public static function getMessages()
{
return self::$messages;
}
/**
* Get translated magic words, if available
*
* @param string $lang Language code
* @return array
*/
public static function magicWords( $lang )
{
// English is used as a fallback, and the English synonyms are
// used if a translation has not been provided for a given word
return ( $lang == 'en' || !isset( self::$words[$lang] ) ) ?
self::$words['en'] :
array_merge( self::$words['en'], self::$words[$lang] );
}
}