Difference between revisions of "User:Paxed/ReplaceCharsBlock"

From NetHackWiki
Jump to navigation Jump to search
m (doc ruleset templates)
m (Code for ReplaceCharsBlock.php: update to fix php warning)
 
(4 intermediate revisions by 2 users not shown)
Line 31: Line 31:
 
|width="50%"|
 
|width="50%"|
 
<pre>
 
<pre>
<div class='ttyscreen'>
+
<div class=ttyscreen>{{lightgray|
 
<replacecharsblock>
 
<replacecharsblock>
 
k=[[kobold|{{red|k}}]]
 
k=[[kobold|{{red|k}}]]
Line 37: Line 37:
 
f=[[cat|{{white|f}}]]
 
f=[[cat|{{white|f}}]]
 
@={{white|@}}
 
@={{white|@}}
|={{lightgray|&amp;#124;}}
 
 
bar=[[foo|{{yellow|foo}}]]
 
bar=[[foo|{{yellow|foo}}]]
default={{lightgray|$1}}
 
 
newline=<br>
 
newline=<br>
 +
|=&amp;#124;
 +
-=&amp;#45;
 +
=&amp;nbsp;
  
------- ------- ------- -------
+
------- ------- ------- -------
|...... |.BAR.. |...... |kkkk̂k.
+
|...... |.BAR.. |...... |kkkk̂k.
|.....| |.bar.| |.....| |kkkkk|
+
|.....| |.bar.| |.....| |kkkkk|
|..k..| |.....| |..f..| |kkfkk|
+
|..k..| |.....| |..f..| |kkfkk|
|.kfk.| |..kk.| |.kkk.| |k...k|
+
|.kfk.| |..kk.| |.kkk.| |k...k|
|.k@k.| |..@fk| |..@..| |kk@kk|
+
|.k@k.| |..@fk| |..@..| |kk@kk|
|.....| |..kk.| |.....| |kkkkk|
+
|.....| |..kk.| |.....| |kkkkk|
-.----- -.----- -.----- -.-----
+
-.----- -.----- -.----- -.-----
 
</replacecharsblock>
 
</replacecharsblock>
</div>
+
}}</div>
 
</pre>
 
</pre>
 
|width="50%"|
 
|width="50%"|
<div class='ttyscreen'>
+
<div class=ttyscreen>{{lightgray|
 
<replacecharsblock>
 
<replacecharsblock>
 
k=[[kobold|{{red|k}}]]
 
k=[[kobold|{{red|k}}]]
Line 60: Line 61:
 
f=[[cat|{{white|f}}]]
 
f=[[cat|{{white|f}}]]
 
@={{white|@}}
 
@={{white|@}}
|={{lightgray|&#124;}}
 
 
bar=[[foo|{{yellow|foo}}]]
 
bar=[[foo|{{yellow|foo}}]]
default={{lightgray|$1}}
 
 
newline=<br>
 
newline=<br>
 +
|=&#124;
 +
-=&#45;
 +
=&nbsp;
  
------- ------- ------- -------
+
------- ------- ------- -------
|...... |.BAR.. |...... |kkkk̂k.
+
|...... |.BAR.. |...... |kkkk̂k.
|.....| |.bar.| |.....| |kkkkk|
+
|.....| |.bar.| |.....| |kkkkk|
|..k..| |.....| |..f..| |kkfkk|
+
|..k..| |.....| |..f..| |kkfkk|
|.kfk.| |..kk.| |.kkk.| |k...k|
+
|.kfk.| |..kk.| |.kkk.| |k...k|
|.k@k.| |..@fk| |..@..| |kk@kk|
+
|.k@k.| |..@fk| |..@..| |kk@kk|
|.....| |..kk.| |.....| |kkkkk|
+
|.....| |..kk.| |.....| |kkkkk|
-.----- -.----- -.----- -.-----
+
-.----- -.----- -.----- -.-----
 
</replacecharsblock>
 
</replacecharsblock>
</div>
+
}}</div>
 
|}
 
|}
  
Predefined replacement rulesets can be used with <tt><nowiki><replacecharsblock rules="ttymap"></nowiki></tt>, which would load rules from {{tl|ttymap}}. The lines after the first empty line in the ruleset template are ignored.
+
Predefined replacement rulesets can be used with <tt><nowiki><replacecharsblock rules="ttymap"></nowiki></tt>, which would load rules from {{tl|ttymap}}. The lines after the first empty line in the ruleset template are ignored. Additional rules can be defined as normal.
 +
 
 +
===Tips===
 +
 
 +
* Instead of using <code>default={{tl|lightgray|$1}}</code>, it's more efficient to wrap the whole block in a {{tl|lightgray}} template, as shown above.
 +
 
 +
* The rules <code>|=&amp;#124;</code>, <code>-=&amp;#45;</code> and <code>&nbsp;=&amp;nbsp;</code> are useful for preventing <code>|</code> and <code>-</code> from being parsed as wiki markup, and to prevent consecutive spaces from collapsing.  (These rules probably should be included automatically by default, but they currently aren't.)
  
 
==TODO==
 
==TODO==
Line 88: Line 96:
 
<syntaxhighlight lang="php">
 
<syntaxhighlight lang="php">
 
<?php
 
<?php
/**                                                                                                                                        
+
/**
  * ReplaceCharsBlock -- replace chars in a block with strings.                                                                              
+
  * ReplaceCharsBlock -- replace chars in a block with strings.
  *                                                                                                                                          
+
  *
 
  */
 
  */
  
Line 101: Line 109:
 
$wgExtensionCredits['parserhook'][] = array(
 
$wgExtensionCredits['parserhook'][] = array(
 
         'name' => 'ReplaceCharsBlock',
 
         'name' => 'ReplaceCharsBlock',
         'version' => '0.3',
+
         'version' => '0.5',
 
         'author' => array(
 
         'author' => array(
 
                 '[http://nethackwiki.com/wiki/User:Paxed Pasi Kallinen]',
 
                 '[http://nethackwiki.com/wiki/User:Paxed Pasi Kallinen]',
Line 113: Line 121:
 
         $parser->setHook( 'replacecharsblock', 'renderCharReplacement' );
 
         $parser->setHook( 'replacecharsblock', 'renderCharReplacement' );
 
         return true;
 
         return true;
 +
}
 +
 +
function replaceCharsBlockGetPageContent ($name) {
 +
    $id = Title::newFromText($name, NS_TEMPLATE)->getArticleId();
 +
    if ($id == null) return "";
 +
    $article = Article::newFromId($id);
 +
    if ($article == null) return "";
 +
 +
    $rev = $article->getRevision();
 +
    $content = $rev->getContent(Revision::RAW);
 +
    $text = ContentHandler::getContentText($content);
 +
    return $text;
 
}
 
}
  
Line 118: Line 138:
 
         /*$parser->disableCache();*/
 
         /*$parser->disableCache();*/
  
         list( $defs, $text ) = preg_split( '/\n\s*\n/', $input, 2 );
+
         list($defs, $text) = array_pad(preg_split('/\n\s*\n/', $input, 2), 2, null);
         if ( !isset( $text ) ) {
+
         if (!isset($text) || is_null($text)) {
 
                 $text = $defs;
 
                 $text = $defs;
 
                 $defs = "";
 
                 $defs = "";
 +
        }
 +
 +
        if (isset($argv['rules'])) {
 +
            list( $ruledefs, $ruledoc ) = preg_split( '/\n\s*\n/', replaceCharsBlockGetPageContent($argv['rules']), 2 );
 +
            $defs = $ruledefs . $defs;
 
         }
 
         }
  
Line 135: Line 160:
 
                         return "<strong class='error'>Replacecharsblock error on line $i: invalid definition " . htmlspecialchars( $line ) . "</strong>";
 
                         return "<strong class='error'>Replacecharsblock error on line $i: invalid definition " . htmlspecialchars( $line ) . "</strong>";
 
                 }
 
                 }
                 // wfDebug( __METHOD__ . ": mapping $match[1] to $match[2]\n" );                                                            
+
                 // wfDebug( __METHOD__ . ": mapping $match[1] to $match[2]\n" );
 
                 if ( $match[1] === 'default' ) {
 
                 if ( $match[1] === 'default' ) {
 
                         $default = $match[2];
 
                         $default = $match[2];
Line 150: Line 175:
 
                 foreach ( $chars as $char ) {
 
                 foreach ( $chars as $char ) {
 
                         $reps[$char] = str_replace( '$1', $char, $default );
 
                         $reps[$char] = str_replace( '$1', $char, $default );
                         // wfDebug( __METHOD__ . ": adding default map from $char to $reps[$char]\n" );                                    
+
                         // wfDebug( __METHOD__ . ": adding default map from $char to $reps[$char]\n" );
 
                 }
 
                 }
 
         }
 
         }

Latest revision as of 08:29, 18 August 2017

ReplaceCharsBlock extension

Adds a <replacecharsblock> -tag, which allows replacing (or translating, using php:strtr) characters and strings in the block with other characters or strings. Replacements are defined first, and the block of text to be replaced after an empty line.

Replacement format is replace_from=replace_to, one per line.

<replacecharsblock>
b=foo

abcb
</replacecharsblock>

afoocfoo

  • default as a replacement: used for any characters that don't have explicitly defined replacement. $1 in the replacement will be substituted with the character which is being replaced.
  • newline as a replacement: each newline character will be replaced with this.
  • Longer replacement strings will be replaced first, then shorter ones.
  • Replacements are case sensitive.

For example:

<div class=ttyscreen>{{lightgray|
<replacecharsblock>
k=[[kobold|{{red|k}}]]
k̂=[[kobold shaman|{{brightblue|k}}]]
f=[[cat|{{white|f}}]]
@={{white|@}}
bar=[[foo|{{yellow|foo}}]]
newline=<br>
|=&#124;
-=&#45;
 =&nbsp;

-------  -------  -------  -------
|......  |.BAR..  |......  |kkkk̂k.
|.....|  |.bar.|  |.....|  |kkkkk|
|..k..|  |.....|  |..f..|  |kkfkk|
|.kfk.|  |..kk.|  |.kkk.|  |k...k|
|.k@k.|  |..@fk|  |..@..|  |kk@kk|
|.....|  |..kk.|  |.....|  |kkkkk|
-.-----  -.-----  -.-----  -.-----
</replacecharsblock>
}}</div>

-------  -------  -------  -------
|......  |.BAR..  |......  |kkkkk.
|.....|  |.foo.|  |.....|  |kkkkk|
|..k..|  |.....|  |..f..|  |kkfkk|
|.kfk.|  |..kk.|  |.kkk.|  |k...k|
|.k@k.|  |..@fk|  |..@..|  |kk@kk|
|.....|  |..kk.|  |.....|  |kkkkk|
-.-----  -.-----  -.-----  -.-----

Predefined replacement rulesets can be used with <replacecharsblock rules="ttymap">, which would load rules from {{ttymap}}. The lines after the first empty line in the ruleset template are ignored. Additional rules can be defined as normal.

Tips

  • Instead of using default={{lightgray|$1}}, it's more efficient to wrap the whole block in a {{lightgray}} template, as shown above.
  • The rules |=&#124;, -=&#45; and  =&nbsp; are useful for preventing | and - from being parsed as wiki markup, and to prevent consecutive spaces from collapsing. (These rules probably should be included automatically by default, but they currently aren't.)

TODO

  • Allow multiple replacement definitions for same char; use the replacements in the order they're defined, looping.
    • Maybe also in random order, though that'll invalidate cache.
  • Exceptions? (eg. maybe one 'k' is different from all the other 'k' chars) Format, how to define?


Code for ReplaceCharsBlock.php

<?php
/**
 * ReplaceCharsBlock -- replace chars in a block with strings.
 *
 */

if( !defined( 'MEDIAWIKI' ) ) {
        die( "This is not a valid entry point to MediaWiki.\n" );
}

$wgHooks['ParserFirstCallInit'][] = 'wfReplaceCharsBlock';

$wgExtensionCredits['parserhook'][] = array(
        'name' => 'ReplaceCharsBlock',
        'version' => '0.5',
        'author' => array(
                '[http://nethackwiki.com/wiki/User:Paxed Pasi Kallinen]',
                '[http://nethackwiki.com/wiki/User:Ilmari_Karonen Ilmari Karonen]',
        ),
        'url' => 'http://nethackwiki.com/wiki/User:Paxed/ReplaceCharsBlock',
        'description' => 'Replace characters in a block of text with strings.',
);

function wfReplaceCharsBlock( &$parser ) {
        $parser->setHook( 'replacecharsblock', 'renderCharReplacement' );
        return true;
}

function replaceCharsBlockGetPageContent ($name) {
    $id = Title::newFromText($name, NS_TEMPLATE)->getArticleId();
    if ($id == null) return "";
    $article = Article::newFromId($id);
    if ($article == null) return "";

    $rev = $article->getRevision();
    $content = $rev->getContent(Revision::RAW);
    $text = ContentHandler::getContentText($content);
    return $text;
}

function renderCharReplacement( $input, $argv, $parser, $frame ) {
        /*$parser->disableCache();*/

        list($defs, $text) = array_pad(preg_split('/\n\s*\n/', $input, 2), 2, null);
        if (!isset($text) || is_null($text)) {
                $text = $defs;
                $defs = "";
        }

        if (isset($argv['rules'])) {
            list( $ruledefs, $ruledoc ) = preg_split( '/\n\s*\n/', replaceCharsBlockGetPageContent($argv['rules']), 2 );
            $defs = $ruledefs . $defs;
        }

        $reps = array();
        $default = false;

        $defs = explode( "\n", $defs );
        foreach ( $defs as $i => $line ) {
                if ( !preg_match( '/\S/u', $line ) ) {
                        continue;
                }
                if ( !preg_match( '/^(\X+?)=(.+)$/u', $line, $match ) ) {
                        return "<strong class='error'>Replacecharsblock error on line $i: invalid definition " . htmlspecialchars( $line ) . "</strong>";
                }
                // wfDebug( __METHOD__ . ": mapping $match[1] to $match[2]\n" );
                if ( $match[1] === 'default' ) {
                        $default = $match[2];
                } else if ( $match[1] === 'newline' ) {
                    $reps["\n"] = $match[2];
                } else {
                        $reps[ $match[1] ] = $match[2];
                }
        }

        if ( $default !== false ) {
                preg_match_all( '/(?>[^\\pM\\pC]\\pM*)/u', $text, $chars );
                $chars = array_diff( array_unique( $chars[0] ), array_keys( $reps ) );
                foreach ( $chars as $char ) {
                        $reps[$char] = str_replace( '$1', $char, $default );
                        // wfDebug( __METHOD__ . ": adding default map from $char to $reps[$char]\n" );
                }
        }

        $text = strtr( $text, $reps );
        return $parser->recursiveTagParse( $text, $frame );
}