r99842 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r99841‎ | r99842 | r99843 >
Date:03:10, 15 October 2011
Author:smoke3723
Status:deferred (Comments)
Tags:
Comment:
Adding Sternograph extension
Modified paths:
  • /trunk/extensions/Sternograph (added) (history)
  • /trunk/extensions/Sternograph/Sternograph.body.php (added) (history)
  • /trunk/extensions/Sternograph/Sternograph.css (added) (history)
  • /trunk/extensions/Sternograph/Sternograph.i18n.php (added) (history)
  • /trunk/extensions/Sternograph/Sternograph.php (added) (history)

Diff [purge]

Index: trunk/extensions/Sternograph/Sternograph.i18n.php
@@ -0,0 +1,22 @@
 2+<?php
 3+/**
 4+ * Internationalisation file for Sternograph extension.
 5+ */
 6+
 7+$messages = array();
 8+
 9+$messages['en'] = array(
 10+ 'descriptionmsg'=>'&lt;sterno> tags for transcripts of spokens words (plays, interviews, etc)',
 11+ 'empty' => '&lt;sterno> tag cannot be empty',
 12+ 'nested'=>'&lt;sterno> tag cannot be nested',
 13+ 'speakerIs' => '&lt;sterno> speaker block lines must have '.Sternograph::SPEAKER_IS.' character',
 14+
 15+ 'speakerPre'=>'',
 16+ 'speakerPost'=>':&nbsp;',
 17+ 'blockPre'=>'',
 18+ 'blockPost'=>'',
 19+ 'inlinePre'=>'[',
 20+ 'inlinePost'=>']',
 21+ 'contextPre'=>'&mdash;',
 22+ 'contextPost'=>''
 23+);
Property changes on: trunk/extensions/Sternograph/Sternograph.i18n.php
___________________________________________________________________
Added: svn:eol-style
124 + native
Index: trunk/extensions/Sternograph/Sternograph.php
@@ -0,0 +1,20 @@
 2+<?php
 3+$wgHooks['ParserFirstCallInit'][] = 'efSternograph';
 4+$wgExtensionMessagesFiles['Sternograph'] = dirname( __FILE__ ) . "/Sternograph.i18n.php";
 5+$wgAutoloadClasses['Sternograph'] = dirname( __FILE__ ) . "/Sternograph.body.php";
 6+
 7+$wgExtensionCredits['parserhook'][] = array(
 8+ 'path' => __FILE__,
 9+ 'name' => 'Sternograph',
 10+ 'version' => '0.0',
 11+ 'author' =>'Smoke 003723',
 12+ 'url' => 'http://www.mediawiki.org/wiki/Extension:Sternograph',
 13+ 'descriptionmsg' => 'descriptionmsg'
 14+ );
 15+
 16+function efSternograph(){
 17+ new Sternograph;
 18+ return true;
 19+}
 20+
 21+
Property changes on: trunk/extensions/Sternograph/Sternograph.php
___________________________________________________________________
Added: svn:eol-style
122 + native
Index: trunk/extensions/Sternograph/Sternograph.css
@@ -0,0 +1,30 @@
 2+/*
 3+Appearance that applies to the entire Sternograph.
 4+*/
 5+.sternograph{}
 6+/*
 7+Formats the name of the speaker.
 8+*/
 9+.sternographName{
 10+ font-style: bold;
 11+}
 12+/*
 13+Applies to both block directions and inline directions.
 14+*/
 15+.sternographDirection{
 16+ font-style: italic;
 17+}
 18+/*
 19+Formatting that is only applied for directions in their own block.
 20+*/
 21+.sternographDirectionBlock{}
 22+/*
 23+Directions that occur within a spoken line, not on a para of their own.
 24+*/
 25+.sternographDirectionInline{}
 26+/*
 27+Context that appears at the end of the sternograph.
 28+*/
 29+.sternographContext{
 30+ text-align: right;
 31+}
Property changes on: trunk/extensions/Sternograph/Sternograph.css
___________________________________________________________________
Added: svn:eol-style
132 + native
Index: trunk/extensions/Sternograph/Sternograph.body.php
@@ -0,0 +1,224 @@
 2+<?php
 3+/**
 4+ Processes the Sternograph tags.
 5+ Requires PHP 5 as it uses some unique methods.
 6+*/
 7+class Sternograph{
 8+//====FIELDS
 9+ /**
 10+ Separates the different lines.
 11+ */
 12+ const DELIMETER = '^';
 13+ /**
 14+ Delimeter for Speaker blocks. The very first occurence of this string
 15+ is used to separate the speaker block from the content block.
 16+ */
 17+ const SPEAKER_DELIM = '^^^';
 18+ /**
 19+ Delimeter for Context block. The very last occurence of this string
 20+ is used to separate the content block from the context block.
 21+ */
 22+ const CONTEXT_DELIM = '^^';
 23+ /**
 24+ Indicates an in-line break in the speaker.
 25+ */
 26+ const INLINE = '_';
 27+ /**
 28+ Separator indicating who the speaker is.
 29+ */
 30+ const SPEAKER_IS = '=';
 31+ /**
 32+ The name of the tag; used to set our hook and prevent recursive
 33+ Sternographs.
 34+ */
 35+ const TAG = 'sterno';
 36+//====CONSTRUCTORS
 37+ /**
 38+ Core constructor. Sets the hooks to be used.
 39+ */
 40+ function __construct(){
 41+ global $wgParser;
 42+ $wgParser->setHook(Sternograph::TAG, array($this, 'parse'));
 43+ }
 44+//====METHODS
 45+ /**
 46+ Performs the processing of everything within the <sterno> tags. Note that everything is done
 47+ with local variables for thread safety.
 48+
 49+ @param $input The user text provided within the <sterno> tags.
 50+ @param array $args The sterno tag arguments. None are accepted, so this field is ignored.
 51+ @param Parser $parser The parser.
 52+ @param PPFrame $frame The frame.
 53+ @return string The formatted text that will be displayed on the browser.
 54+ */
 55+ public function parse($input, array $args, Parser $parser, PPFrame $frame){
 56+ //Sanity checks
 57+ if ($input == null){
 58+ return Sternograph::error('empty');
 59+ }
 60+ if (preg_match('/<\s*'.Sternograph::TAG.'\s*>/', $input) > 0){
 61+ return Sternograph::error('nested');
 62+ }
 63+ //3 chunks we have to work through:
 64+ $speakers = null;
 65+ $lines = null;
 66+ $context = null;
 67+ //Speakers is optional; if present, it comes first
 68+ $speakers = strpos($input, Sternograph::SPEAKER_DELIM);
 69+ if ($speakers === false){
 70+ $speakers = null;
 71+ $lines = $input;
 72+ }else{
 73+ $lines = substr($input,
 74+ $speakers + strlen(Sternograph::SPEAKER_DELIM));
 75+ $speakers = substr($input, 0, $speakers);
 76+ }
 77+ //Context is also optional, and comes last if present
 78+ $context = strrpos($lines, Sternograph::CONTEXT_DELIM);
 79+ if ($context === false){
 80+ $context = null;
 81+ }else{
 82+ $input = substr($lines, 0, $context);
 83+ $context = substr($lines, $context + strlen(Sternograph::CONTEXT_DELIM));
 84+ $context = wfMsgNoTrans('contextPre').
 85+ trim($context).
 86+ wfMsgNoTrans('contextPost');
 87+ $context = '<div class="sternographContext">'.
 88+ $parser->recursiveTagParse($context, $frame).
 89+ '</div>';
 90+ $lines = $input;
 91+ }
 92+ return Sternograph::render(trim($speakers), trim($lines), $parser, $frame).$context;
 93+ }
 94+
 95+ static private function render($speakers, $lines, Parser $parser, PPFrame $frame){
 96+ $speakers = Sternograph::parseSpeakers($speakers, $parser, $frame);
 97+ if ($speakers != null && !is_array($speakers)){
 98+ return $speakers;
 99+ }
 100+ $result = null;
 101+ $current = null;
 102+ $lines = explode(Sternograph::DELIMETER, $lines);
 103+ $limit = count($lines);
 104+ for ($i = 0; $i < $limit; $i++){
 105+ $current = $lines[$i];
 106+ if (Sternograph::contains($current, Sternograph::SPEAKER_IS)){
 107+ $result .= Sternograph::line($current, $speakers, $parser, $frame);
 108+ }else{
 109+ $result .= Sternograph::direction($current, $speakers, true, $parser, $frame);
 110+ }
 111+ if ($i+1 != $limit){//There are more tokens
 112+ $result .='<br/>';
 113+ }
 114+ }
 115+ return '<div class="sternograph">'.$result.'</div>';
 116+ }
 117+
 118+ static private function parseSpeakers($speakers, Parser $parser, PPFrame $frame){
 119+ if ($speakers == null){
 120+ return null;
 121+ }else{
 122+ $speakers = explode('<br />',
 123+ nl2br($speakers));
 124+ $result = array();
 125+ foreach ($speakers as $i){
 126+ if (preg_match('/[^\s]+/', $i) > 0){
 127+ $i = Sternograph::splitSpeaker($i);
 128+ if (is_array($i)){
 129+ $result[$i[0]] = $parser->recursiveTagParse(trim($i[1]), $frame);
 130+ }else{
 131+ return $i;
 132+ }
 133+ }else{
 134+ continue;
 135+ }
 136+ }
 137+ return $result;
 138+ }
 139+ }
 140+
 141+ static private function splitSpeaker($raw){
 142+ if (Sternograph::contains($raw, Sternograph::SPEAKER_IS)){
 143+ $raw = explode(Sternograph::SPEAKER_IS, $raw);
 144+ $raw[0] = Sternograph::collapseWhitespace($raw[0]);
 145+ $raw[1] = trim($raw[1]);
 146+ return $raw;
 147+ }else{
 148+ return Sternograph::error('speakerIs');
 149+ }
 150+ }
 151+
 152+ static private function line($raw, $speakers, Parser $parser, PPFrame $frame){
 153+ $result = '<font class="sternographName">'.wfMsgNoTrans('speakerPre');
 154+ $raw = Sternograph::splitSpeaker($raw);
 155+ if (!is_array($raw)){
 156+ return $raw;
 157+ }
 158+ $raw[0] = trim($raw[0]);
 159+ if ($speakers == null || !isset($speakers[$raw[0]])){
 160+ $raw[0] = $parser->recursiveTagParse($raw[0]);
 161+ }else{
 162+ $raw[0] = $speakers[$raw[0]];
 163+ }
 164+ $result .= $raw[0].wfMsgNoTrans('speakerPost').'</font>';
 165+ $raw = explode(Sternograph::INLINE, $raw[1]);
 166+ $limit = count($raw);
 167+ $result .= Sternograph::expandSpeakers($raw[0], $speakers, $parser, $frame);
 168+ for ($i = 1; $i < $limit; $i++){
 169+ if ($i % 2 == 0){
 170+ $result .= Sternograph::expandSpeakers($raw[$i], $speakers, $parser, $frame);
 171+ }else{
 172+ $result .= Sternograph::direction($raw[$i], $speakers, false, $parser, $frame);
 173+ }
 174+ if ($i+1 != $limit){//There are more tokens
 175+ $result .='&nbsp;';
 176+ }
 177+ }
 178+ return $result;
 179+ }
 180+
 181+ static private function expandSpeakers($raw, $speakers, Parser $parser, PPFrame $frame){
 182+ if ($speakers != null){
 183+ foreach($speakers as $key => $value){
 184+ $raw = preg_replace('/<\s*'.$key.'\s*>/', $value, $raw);
 185+ }
 186+ }
 187+ return $parser->recursiveTagParse($raw, $frame);
 188+ }
 189+
 190+ static private function direction($raw, $speakers, $block, Parser $parser, PPFrame $frame){
 191+ if ($block === true){
 192+ return '<font class="sternographDirection sternographDirectionBlock">'.
 193+ Sternograph::expandSpeakers(wfMsgNoTrans('blockPre').
 194+ $raw.wfMsgNoTrans('blockPost'),
 195+ $speakers, $parser, $frame).'</font>';
 196+ }else{
 197+ return '<font class="sternographDirection sternographDirectionInline">'.
 198+ Sternograph::expandSpeakers(wfMsgNoTrans('inlinePre').
 199+ $raw.wfMsgNoTrans('inlinePost'),
 200+ $speakers, $parser, $frame).'</font>';
 201+ }
 202+ }
 203+
 204+//====
 205+ /**
 206+ Returns the i18n'd error message.
 207+ */
 208+ static private function error($key){
 209+ return '<strong class="error">'.wfMsgNoTrans($key).'</strong>';
 210+ }
 211+
 212+ /**
 213+ Trims and then strips multiple whitespace, so that only the first one appears.
 214+ */
 215+ static public function collapseWhitespace($str){
 216+ return preg_replace('/\s\s+/', ' ', trim($str));
 217+ }
 218+
 219+ /**
 220+ The given haystack contains the desired needle.
 221+ */
 222+ static public function contains($haystack, $needle){
 223+ return strpos($haystack, $needle) !== false;
 224+ }
 225+}
Property changes on: trunk/extensions/Sternograph/Sternograph.body.php
___________________________________________________________________
Added: svn:eol-style
1226 + native

Follow-up revisions

RevisionCommit summaryAuthorDate
r100485Added i18n message documentationsmoke372301:50, 22 October 2011
r101295Internationalisation codes corrected to current standardssmoke372303:45, 30 October 2011

Comments

#Comment by Reedy (talk | contribs)   03:13, 15 October 2011

Please commit a USERINFO file

#Comment by Hashar (talk | contribs)   13:00, 7 November 2011

Done in r99843 & r99844

#Comment by Raymond (talk | contribs)   05:30, 15 October 2011

Please add message documentation for the newly added messages. Thanks.

#Comment by Hashar (talk | contribs)   13:01, 7 November 2011

i18n documentation added with r100485

#Comment by Raymond (talk | contribs)   05:47, 22 October 2011
  • Please prefix all message keys with the extension name "sternograph-". This avoids key conflicts with MediaWiki core and/or other extensions.
  • Code convention for message keys is all lowercase, using dashes: 'speakerPre' -> 'speaker-pre'
#Comment by Hashar (talk | contribs)   13:02, 7 November 2011

Prefix added with r101295

#Comment by Hashar (talk | contribs)   13:03, 7 November 2011

Welcome around Smoke3723 \o/

Status & tagging log