r105082 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r105081‎ | r105082 | r105083 >
Date:21:10, 3 December 2011
Author:foxtrott
Status:deferred
Tags:
Comment:
Release version 0.3
Modified paths:
  • /tags/extensions/Lingo/REL_0_3 (added) (history)

Diff [purge]

Index: tags/extensions/Lingo/REL_0_3/LingoHooks.php
@@ -0,0 +1,70 @@
 2+<?php
 3+
 4+/**
 5+ * File holding the LingoHooks class
 6+ *
 7+ * @author Stephan Gambke
 8+ * @file
 9+ * @ingroup Lingo
 10+ */
 11+if ( !defined( 'LINGO_VERSION' ) ) {
 12+ die( 'This file is part of the Lingo extension, it is not a valid entry point.' );
 13+}
 14+
 15+/**
 16+ * The LingoHooks class.
 17+ *
 18+ * It contains the hook handlers of the extension
 19+ *
 20+ * @ingroup Lingo
 21+ */
 22+class LingoHooks {
 23+
 24+ /**
 25+ * Hooks into ParserAfterTidy.
 26+ *
 27+ * @param Parser $parser
 28+ * @param String $text
 29+ * @return Boolean
 30+ */
 31+ static function parse( &$parser, &$text ) {
 32+
 33+ global $wgexLingoUseNamespaces;
 34+
 35+ $title = $parser->getTitle();
 36+
 37+ // parse if
 38+ if ( !isset( $parser->mDoubleUnderscores['noglossary'] ) && // __NOGLOSSARY__ not present and
 39+ (
 40+ !$title || // title not set or
 41+ !isset( $wgexLingoUseNamespaces[$title->getNamespace()] ) || // namespace not explicitly forbidden or
 42+ $wgexLingoUseNamespaces[$title->getNamespace()] // namespace explicitly allowed
 43+ )
 44+ ) {
 45+ LingoParser::parse( $parser, $text );
 46+ }
 47+
 48+ return true;
 49+ }
 50+
 51+ /**
 52+ * Deferred setting of description in extension credits
 53+ *
 54+ * Setting of description in extension credits has to be deferred to the
 55+ * SpecialVersionExtensionTypes hook as it uses variable $wgexLingoPage (which
 56+ * might be set only after inclusion of the extension in LocalSettings) and
 57+ * function wfMsg not available before.
 58+ *
 59+ * @return Boolean Always true.
 60+ */
 61+ static function setCredits() {
 62+
 63+ global $wgExtensionCredits, $wgexLingoPage;
 64+ $wgExtensionCredits['parserhook']['lingo']['description'] =
 65+ wfMsg( 'lingo-desc', $wgexLingoPage ? $wgexLingoPage : wfMsgForContent( 'lingo-terminologypagename' ) );
 66+
 67+ return true;
 68+ }
 69+
 70+}
 71+
Property changes on: tags/extensions/Lingo/REL_0_3/LingoHooks.php
___________________________________________________________________
Added: svn:eol-style
172 + native
Index: tags/extensions/Lingo/REL_0_3/LingoMessageLog.php
@@ -0,0 +1,91 @@
 2+<?php
 3+
 4+/**
 5+ * File holding the LingoMessageLog class.
 6+ *
 7+ * @author Stephan Gambke
 8+ *
 9+ * @file
 10+ * @ingroup Lingo
 11+ */
 12+if ( !defined( 'LINGO_VERSION' ) ) {
 13+ die( 'This file is part of the Lingo extension, it is not a valid entry point.' );
 14+}
 15+
 16+/**
 17+ * This class holds messages (errors, warnings, notices) for Lingo
 18+ *
 19+ * Contains a static function to initiate the parsing.
 20+ *
 21+ * @ingroup Lingo
 22+ */
 23+class LingoMessageLog {
 24+
 25+ private $mMessages = array();
 26+ private $mParser = null;
 27+
 28+ const MESSAGE_ERROR = 1;
 29+ const MESSAGE_WARNING = 2;
 30+ const MESSAGE_NOTICE = 3;
 31+
 32+ function addMessage( $message, $severity = self::MESSAGE_NOTICE ) {
 33+ $this->mMessages[] = array($message, $severity);
 34+
 35+ // log errors and warnings in debug log
 36+ if ( $severity == self::MESSAGE_WARNING ||
 37+ $severity == self::MESSAGE_ERROR ) {
 38+ wfDebug( $message );
 39+ }
 40+ }
 41+
 42+ function addError( $message ) {
 43+ $this->mMessages[] = array($message, self::MESSAGE_ERROR);
 44+ wfDebug( "Error: $message\n" );
 45+ }
 46+
 47+ function addWarning( $message ) {
 48+ $this->mMessages[] = array($message, self::MESSAGE_WARNING);
 49+ wfDebug( "Warning: $message\n" );
 50+ }
 51+
 52+ function addNotice( $message ) {
 53+ $this->mMessages[] = array($message, self::MESSAGE_NOTICE);
 54+ }
 55+
 56+ function getMessagesFormatted( $severity = self::MESSAGE_WARNING, $header = null ) {
 57+ global $wgTitle, $wgUser;
 58+
 59+ $ret = '';
 60+
 61+ foreach ( $this->mMessages as $message ) {
 62+ if ( $message[1] <= $severity ) {
 63+ $ret .= '* ' . $message[0] . "\n";
 64+ }
 65+ }
 66+
 67+ if ( $ret != '' ) {
 68+ if ( !$this->mParser ) {
 69+ $parser = new Parser();
 70+ }
 71+
 72+ if ( $header == null ) {
 73+ $header = '';
 74+ } elseif ( $header != '' ) {
 75+ $header = Html::rawElement( 'div', array('class' => 'heading'), $header );
 76+ }
 77+
 78+ $ret = Html::rawElement( 'div', array('class' => 'messages'),
 79+ $header . "\n" .
 80+ $ret
 81+ );
 82+
 83+ $ret = $parser->parse( $ret, $wgTitle, ParserOptions::newFromUser( $wgUser ) );
 84+ } else {
 85+ $ret = null;
 86+ }
 87+
 88+ return $ret;
 89+ }
 90+
 91+}
 92+
Property changes on: tags/extensions/Lingo/REL_0_3/LingoMessageLog.php
___________________________________________________________________
Added: svn:eol-style
193 + native
Index: tags/extensions/Lingo/REL_0_3/LingoBackend.php
@@ -0,0 +1,45 @@
 2+<?php
 3+
 4+/**
 5+ * File holding the LingoBackend class
 6+ *
 7+ * @author Stephan Gambke
 8+ * @file
 9+ * @ingroup Lingo
 10+ */
 11+if ( !defined( 'LINGO_VERSION' ) ) {
 12+ die( 'This file is part of the Lingo extension, it is not a valid entry point.' );
 13+}
 14+
 15+/**
 16+ * The LingoBackend class.
 17+ *
 18+ * @ingroup Lingo
 19+ */
 20+abstract class LingoBackend {
 21+
 22+ protected $mMessageLog;
 23+
 24+ public function __construct( LingoMessageLog &$messages = null ) {
 25+
 26+ if ( !$messages ) {
 27+ $this->mMessageLog = new LingoMessageLog();
 28+ } else {
 29+ $this->mMessageLog = $messages;
 30+ }
 31+ }
 32+
 33+ public function getMessageLog() {
 34+ return $this->mMessageLog;
 35+ }
 36+
 37+ /**
 38+ * This function returns the next element. The element is an array of four
 39+ * strings: Term, Definition, Link, Source. If there is no next element the
 40+ * function returns null.
 41+ *
 42+ * @return the next element or null
 43+ */
 44+ abstract public function next();
 45+}
 46+
Property changes on: tags/extensions/Lingo/REL_0_3/LingoBackend.php
___________________________________________________________________
Added: svn:eol-style
147 + native
Index: tags/extensions/Lingo/REL_0_3/skins/linkicon.png
Cannot display: file marked as a binary type.
svn:mime-type = image/png
Property changes on: tags/extensions/Lingo/REL_0_3/skins/linkicon.png
___________________________________________________________________
Added: svn:mime-type
248 + image/png
Index: tags/extensions/Lingo/REL_0_3/skins/Lingo.css
@@ -0,0 +1,64 @@
 2+/*
 3+* Stylesheet for the markup of glossary terms in wiki pages.
 4+*/
 5+
 6+.tooltip {
 7+ display: inline;
 8+ position: relative;
 9+ cursor: help;
 10+}
 11+
 12+.tooltip_abbr {
 13+ border-bottom: 1px dotted #bbf;
 14+}
 15+
 16+.tooltip_tipwrapper {
 17+ display: none;
 18+
 19+ position: absolute;
 20+ top: 0;
 21+ left: 0;
 22+
 23+ height: 3em;
 24+ width: 23em;
 25+
 26+ font-weight: normal;
 27+ font-size: small;
 28+ line-height: 1.2em;
 29+
 30+ z-index: 2;
 31+}
 32+
 33+.tooltip_tip {
 34+ display: block;
 35+
 36+ position: absolute;
 37+ top: 1.5em;
 38+ left: 2em;
 39+
 40+ width: 20em;
 41+
 42+ padding: 0.5em;
 43+ margin: 0;
 44+
 45+ background-color: #F9F9F9;
 46+ border: 1px solid #aaa;
 47+
 48+ -moz-border-radius: 5px;
 49+ border-radius: 5px;
 50+
 51+ -webkit-box-shadow: 3px 3px 3px #888;
 52+ box-shadow: 3px 3px 3px #888;
 53+}
 54+
 55+.tooltip_tip span {
 56+ display: block;
 57+}
 58+
 59+.tooltip:hover .tooltip_abbr {
 60+ background-color:rgba(0,0,0,0.1);
 61+}
 62+
 63+.tooltip:hover .tooltip_tipwrapper {
 64+ display: block;
 65+}
Property changes on: tags/extensions/Lingo/REL_0_3/skins/Lingo.css
___________________________________________________________________
Added: svn:eol-style
166 + native
Index: tags/extensions/Lingo/REL_0_3/COPYING
@@ -0,0 +1,350 @@
 2+The license text below "----" applies to all files within this distribution,
 3+other than those that are in a directory which contains files named "LICENSE"
 4+or "COPYING", or a subdirectory thereof. For those files, the license text
 5+contained in said file overrides any license information contained in
 6+directories of smaller depth. Alternative licenses are typically used for
 7+software that is provided by external parties, and merely packaged with this
 8+software for convenience.
 9+
 10+----
 11+
 12+ GNU GENERAL PUBLIC LICENSE
 13+ Version 2, June 1991
 14+
 15+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
 16+ 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 17+ Everyone is permitted to copy and distribute verbatim copies
 18+ of this license document, but changing it is not allowed.
 19+
 20+ Preamble
 21+
 22+ The licenses for most software are designed to take away your
 23+freedom to share and change it. By contrast, the GNU General Public
 24+License is intended to guarantee your freedom to share and change free
 25+software--to make sure the software is free for all its users. This
 26+General Public License applies to most of the Free Software
 27+Foundation's software and to any other program whose authors commit to
 28+using it. (Some other Free Software Foundation software is covered by
 29+the GNU Library General Public License instead.) You can apply it to
 30+your programs, too.
 31+
 32+ When we speak of free software, we are referring to freedom, not
 33+price. Our General Public Licenses are designed to make sure that you
 34+have the freedom to distribute copies of free software (and charge for
 35+this service if you wish), that you receive source code or can get it
 36+if you want it, that you can change the software or use pieces of it
 37+in new free programs; and that you know you can do these things.
 38+
 39+ To protect your rights, we need to make restrictions that forbid
 40+anyone to deny you these rights or to ask you to surrender the rights.
 41+These restrictions translate to certain responsibilities for you if you
 42+distribute copies of the software, or if you modify it.
 43+
 44+ For example, if you distribute copies of such a program, whether
 45+gratis or for a fee, you must give the recipients all the rights that
 46+you have. You must make sure that they, too, receive or can get the
 47+source code. And you must show them these terms so they know their
 48+rights.
 49+
 50+ We protect your rights with two steps: (1) copyright the software, and
 51+(2) offer you this license which gives you legal permission to copy,
 52+distribute and/or modify the software.
 53+
 54+ Also, for each author's protection and ours, we want to make certain
 55+that everyone understands that there is no warranty for this free
 56+software. If the software is modified by someone else and passed on, we
 57+want its recipients to know that what they have is not the original, so
 58+that any problems introduced by others will not reflect on the original
 59+authors' reputations.
 60+
 61+ Finally, any free program is threatened constantly by software
 62+patents. We wish to avoid the danger that redistributors of a free
 63+program will individually obtain patent licenses, in effect making the
 64+program proprietary. To prevent this, we have made it clear that any
 65+patent must be licensed for everyone's free use or not licensed at all.
 66+
 67+ The precise terms and conditions for copying, distribution and
 68+modification follow.
 69+
 70+ GNU GENERAL PUBLIC LICENSE
 71+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
 72+
 73+ 0. This License applies to any program or other work which contains
 74+a notice placed by the copyright holder saying it may be distributed
 75+under the terms of this General Public License. The "Program", below,
 76+refers to any such program or work, and a "work based on the Program"
 77+means either the Program or any derivative work under copyright law:
 78+that is to say, a work containing the Program or a portion of it,
 79+either verbatim or with modifications and/or translated into another
 80+language. (Hereinafter, translation is included without limitation in
 81+the term "modification".) Each licensee is addressed as "you".
 82+
 83+Activities other than copying, distribution and modification are not
 84+covered by this License; they are outside its scope. The act of
 85+running the Program is not restricted, and the output from the Program
 86+is covered only if its contents constitute a work based on the
 87+Program (independent of having been made by running the Program).
 88+Whether that is true depends on what the Program does.
 89+
 90+ 1. You may copy and distribute verbatim copies of the Program's
 91+source code as you receive it, in any medium, provided that you
 92+conspicuously and appropriately publish on each copy an appropriate
 93+copyright notice and disclaimer of warranty; keep intact all the
 94+notices that refer to this License and to the absence of any warranty;
 95+and give any other recipients of the Program a copy of this License
 96+along with the Program.
 97+
 98+You may charge a fee for the physical act of transferring a copy, and
 99+you may at your option offer warranty protection in exchange for a fee.
 100+
 101+ 2. You may modify your copy or copies of the Program or any portion
 102+of it, thus forming a work based on the Program, and copy and
 103+distribute such modifications or work under the terms of Section 1
 104+above, provided that you also meet all of these conditions:
 105+
 106+ a) You must cause the modified files to carry prominent notices
 107+ stating that you changed the files and the date of any change.
 108+
 109+ b) You must cause any work that you distribute or publish, that in
 110+ whole or in part contains or is derived from the Program or any
 111+ part thereof, to be licensed as a whole at no charge to all third
 112+ parties under the terms of this License.
 113+
 114+ c) If the modified program normally reads commands interactively
 115+ when run, you must cause it, when started running for such
 116+ interactive use in the most ordinary way, to print or display an
 117+ announcement including an appropriate copyright notice and a
 118+ notice that there is no warranty (or else, saying that you provide
 119+ a warranty) and that users may redistribute the program under
 120+ these conditions, and telling the user how to view a copy of this
 121+ License. (Exception: if the Program itself is interactive but
 122+ does not normally print such an announcement, your work based on
 123+ the Program is not required to print an announcement.)
 124+
 125+These requirements apply to the modified work as a whole. If
 126+identifiable sections of that work are not derived from the Program,
 127+and can be reasonably considered independent and separate works in
 128+themselves, then this License, and its terms, do not apply to those
 129+sections when you distribute them as separate works. But when you
 130+distribute the same sections as part of a whole which is a work based
 131+on the Program, the distribution of the whole must be on the terms of
 132+this License, whose permissions for other licensees extend to the
 133+entire whole, and thus to each and every part regardless of who wrote it.
 134+
 135+Thus, it is not the intent of this section to claim rights or contest
 136+your rights to work written entirely by you; rather, the intent is to
 137+exercise the right to control the distribution of derivative or
 138+collective works based on the Program.
 139+
 140+In addition, mere aggregation of another work not based on the Program
 141+with the Program (or with a work based on the Program) on a volume of
 142+a storage or distribution medium does not bring the other work under
 143+the scope of this License.
 144+
 145+ 3. You may copy and distribute the Program (or a work based on it,
 146+under Section 2) in object code or executable form under the terms of
 147+Sections 1 and 2 above provided that you also do one of the following:
 148+
 149+ a) Accompany it with the complete corresponding machine-readable
 150+ source code, which must be distributed under the terms of Sections
 151+ 1 and 2 above on a medium customarily used for software interchange; or,
 152+
 153+ b) Accompany it with a written offer, valid for at least three
 154+ years, to give any third party, for a charge no more than your
 155+ cost of physically performing source distribution, a complete
 156+ machine-readable copy of the corresponding source code, to be
 157+ distributed under the terms of Sections 1 and 2 above on a medium
 158+ customarily used for software interchange; or,
 159+
 160+ c) Accompany it with the information you received as to the offer
 161+ to distribute corresponding source code. (This alternative is
 162+ allowed only for noncommercial distribution and only if you
 163+ received the program in object code or executable form with such
 164+ an offer, in accord with Subsection b above.)
 165+
 166+The source code for a work means the preferred form of the work for
 167+making modifications to it. For an executable work, complete source
 168+code means all the source code for all modules it contains, plus any
 169+associated interface definition files, plus the scripts used to
 170+control compilation and installation of the executable. However, as a
 171+special exception, the source code distributed need not include
 172+anything that is normally distributed (in either source or binary
 173+form) with the major components (compiler, kernel, and so on) of the
 174+operating system on which the executable runs, unless that component
 175+itself accompanies the executable.
 176+
 177+If distribution of executable or object code is made by offering
 178+access to copy from a designated place, then offering equivalent
 179+access to copy the source code from the same place counts as
 180+distribution of the source code, even though third parties are not
 181+compelled to copy the source along with the object code.
 182+
 183+ 4. You may not copy, modify, sublicense, or distribute the Program
 184+except as expressly provided under this License. Any attempt
 185+otherwise to copy, modify, sublicense or distribute the Program is
 186+void, and will automatically terminate your rights under this License.
 187+However, parties who have received copies, or rights, from you under
 188+this License will not have their licenses terminated so long as such
 189+parties remain in full compliance.
 190+
 191+ 5. You are not required to accept this License, since you have not
 192+signed it. However, nothing else grants you permission to modify or
 193+distribute the Program or its derivative works. These actions are
 194+prohibited by law if you do not accept this License. Therefore, by
 195+modifying or distributing the Program (or any work based on the
 196+Program), you indicate your acceptance of this License to do so, and
 197+all its terms and conditions for copying, distributing or modifying
 198+the Program or works based on it.
 199+
 200+ 6. Each time you redistribute the Program (or any work based on the
 201+Program), the recipient automatically receives a license from the
 202+original licensor to copy, distribute or modify the Program subject to
 203+these terms and conditions. You may not impose any further
 204+restrictions on the recipients' exercise of the rights granted herein.
 205+You are not responsible for enforcing compliance by third parties to
 206+this License.
 207+
 208+ 7. If, as a consequence of a court judgment or allegation of patent
 209+infringement or for any other reason (not limited to patent issues),
 210+conditions are imposed on you (whether by court order, agreement or
 211+otherwise) that contradict the conditions of this License, they do not
 212+excuse you from the conditions of this License. If you cannot
 213+distribute so as to satisfy simultaneously your obligations under this
 214+License and any other pertinent obligations, then as a consequence you
 215+may not distribute the Program at all. For example, if a patent
 216+license would not permit royalty-free redistribution of the Program by
 217+all those who receive copies directly or indirectly through you, then
 218+the only way you could satisfy both it and this License would be to
 219+refrain entirely from distribution of the Program.
 220+
 221+If any portion of this section is held invalid or unenforceable under
 222+any particular circumstance, the balance of the section is intended to
 223+apply and the section as a whole is intended to apply in other
 224+circumstances.
 225+
 226+It is not the purpose of this section to induce you to infringe any
 227+patents or other property right claims or to contest validity of any
 228+such claims; this section has the sole purpose of protecting the
 229+integrity of the free software distribution system, which is
 230+implemented by public license practices. Many people have made
 231+generous contributions to the wide range of software distributed
 232+through that system in reliance on consistent application of that
 233+system; it is up to the author/donor to decide if he or she is willing
 234+to distribute software through any other system and a licensee cannot
 235+impose that choice.
 236+
 237+This section is intended to make thoroughly clear what is believed to
 238+be a consequence of the rest of this License.
 239+
 240+ 8. If the distribution and/or use of the Program is restricted in
 241+certain countries either by patents or by copyrighted interfaces, the
 242+original copyright holder who places the Program under this License
 243+may add an explicit geographical distribution limitation excluding
 244+those countries, so that distribution is permitted only in or among
 245+countries not thus excluded. In such case, this License incorporates
 246+the limitation as if written in the body of this License.
 247+
 248+ 9. The Free Software Foundation may publish revised and/or new versions
 249+of the General Public License from time to time. Such new versions will
 250+be similar in spirit to the present version, but may differ in detail to
 251+address new problems or concerns.
 252+
 253+Each version is given a distinguishing version number. If the Program
 254+specifies a version number of this License which applies to it and "any
 255+later version", you have the option of following the terms and conditions
 256+either of that version or of any later version published by the Free
 257+Software Foundation. If the Program does not specify a version number of
 258+this License, you may choose any version ever published by the Free Software
 259+Foundation.
 260+
 261+ 10. If you wish to incorporate parts of the Program into other free
 262+programs whose distribution conditions are different, write to the author
 263+to ask for permission. For software which is copyrighted by the Free
 264+Software Foundation, write to the Free Software Foundation; we sometimes
 265+make exceptions for this. Our decision will be guided by the two goals
 266+of preserving the free status of all derivatives of our free software and
 267+of promoting the sharing and reuse of software generally.
 268+
 269+ NO WARRANTY
 270+
 271+ 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
 272+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
 273+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
 274+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
 275+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 276+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
 277+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
 278+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
 279+REPAIR OR CORRECTION.
 280+
 281+ 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
 282+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
 283+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
 284+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
 285+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
 286+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
 287+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
 288+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
 289+POSSIBILITY OF SUCH DAMAGES.
 290+
 291+ END OF TERMS AND CONDITIONS
 292+
 293+ How to Apply These Terms to Your New Programs
 294+
 295+ If you develop a new program, and you want it to be of the greatest
 296+possible use to the public, the best way to achieve this is to make it
 297+free software which everyone can redistribute and change under these terms.
 298+
 299+ To do so, attach the following notices to the program. It is safest
 300+to attach them to the start of each source file to most effectively
 301+convey the exclusion of warranty; and each file should have at least
 302+the "copyright" line and a pointer to where the full notice is found.
 303+
 304+ <one line to give the program's name and a brief idea of what it does.>
 305+ Copyright (C) <year> <name of author>
 306+
 307+ This program is free software; you can redistribute it and/or modify
 308+ it under the terms of the GNU General Public License as published by
 309+ the Free Software Foundation; either version 2 of the License, or
 310+ (at your option) any later version.
 311+
 312+ This program is distributed in the hope that it will be useful,
 313+ but WITHOUT ANY WARRANTY; without even the implied warranty of
 314+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 315+ GNU General Public License for more details.
 316+
 317+ You should have received a copy of the GNU General Public License
 318+ along with this program; if not, write to the Free Software
 319+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 320+
 321+
 322+Also add information on how to contact you by electronic and paper mail.
 323+
 324+If the program is interactive, make it output a short notice like this
 325+when it starts in an interactive mode:
 326+
 327+ Gnomovision version 69, Copyright (C) year name of author
 328+ Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
 329+ This is free software, and you are welcome to redistribute it
 330+ under certain conditions; type `show c' for details.
 331+
 332+The hypothetical commands `show w' and `show c' should show the appropriate
 333+parts of the General Public License. Of course, the commands you use may
 334+be called something other than `show w' and `show c'; they could even be
 335+mouse-clicks or menu items--whatever suits your program.
 336+
 337+You should also get your employer (if you work as a programmer) or your
 338+school, if any, to sign a "copyright disclaimer" for the program, if
 339+necessary. Here is a sample; alter the names:
 340+
 341+ Yoyodyne, Inc., hereby disclaims all copyright interest in the program
 342+ `Gnomovision' (which makes passes at compilers) written by James Hacker.
 343+
 344+ <signature of Ty Coon>, 1 April 1989
 345+ Ty Coon, President of Vice
 346+
 347+This General Public License does not permit incorporating your program into
 348+proprietary programs. If your program is a subroutine library, you may
 349+consider it more useful to permit linking proprietary applications with the
 350+library. If this is what you want to do, use the GNU Library General
 351+Public License instead of this License.
Property changes on: tags/extensions/Lingo/REL_0_3/COPYING
___________________________________________________________________
Added: svn:eol-style
1352 + native
Index: tags/extensions/Lingo/REL_0_3/LingoBasicBackend.php
@@ -0,0 +1,101 @@
 2+<?php
 3+
 4+/**
 5+ * File holding the LingoBackend class
 6+ *
 7+ * @author Stephan Gambke
 8+ * @file
 9+ * @ingroup Lingo
 10+ */
 11+if ( !defined( 'LINGO_VERSION' ) ) {
 12+ die( 'This file is part of the Lingo extension, it is not a valid entry point.' );
 13+}
 14+
 15+/**
 16+ * The LingoBasicBackend class.
 17+ *
 18+ * @ingroup Lingo
 19+ */
 20+class LingoBasicBackend extends LingoBackend {
 21+
 22+ protected $mArticleLines = array();
 23+
 24+ public function __construct( LingoMessageLog &$messages = null ) {
 25+
 26+ global $wgexLingoPage;
 27+
 28+ $page = $wgexLingoPage ? $wgexLingoPage : wfMsgForContent( 'lingo-terminologypagename' );
 29+
 30+ parent::__construct( $messages );
 31+
 32+ // Get Terminology page
 33+ $title = Title::newFromText( $page );
 34+ if ( $title->getInterwiki() ) {
 35+ $this->getMessageLog()->addError( wfMsgForContent( 'lingo-terminologypagenotlocal' , $page ) );
 36+ return false;
 37+ }
 38+
 39+ $rev = Revision::newFromTitle( $title );
 40+ if ( !$rev ) {
 41+ $this->getMessageLog()->addWarning( wfMsgForContent( 'lingo-noterminologypage' , $page ) );
 42+ return false;
 43+ }
 44+
 45+ $content = $rev->getText();
 46+
 47+ $this->mArticleLines = array_reverse(explode( "\n", $content ));
 48+ }
 49+
 50+ /**
 51+ * This function returns the next element. The element is an array of four
 52+ * strings: Term, Definition, Link, Source. For the LingoBasicBackend Link
 53+ * and Source are set to null. If there is no next element the function
 54+ * returns null.
 55+ *
 56+ * @return Array the next element or null
 57+ */
 58+ public function next() {
 59+
 60+ wfProfileIn( __METHOD__ );
 61+
 62+ $ret = null;
 63+ $term = null;
 64+ static $definition = null;
 65+
 66+ // find next valid line (yes, the assignation is intended)
 67+ while ( ( $ret == null ) && ( $entry = each( $this->mArticleLines ) ) ) {
 68+
 69+ if ( empty( $entry[1] ) || ($entry[1][0] !== ';' && $entry[1][0] !== ':')) {
 70+ continue;
 71+ }
 72+
 73+ $chunks = explode( ':', $entry[1], 2 );
 74+
 75+ // found a new term?
 76+ if ( count( $chunks ) >= 1 && strlen( $chunks[0] ) >= 1 ) {
 77+ $term = trim( substr( $chunks[0], 1 ) );
 78+ }
 79+
 80+ // found a new definition?
 81+ if ( count ( $chunks ) == 2 ) {
 82+ $definition = trim( $chunks[1] );
 83+ }
 84+
 85+ if ( $term !== null ) {
 86+ $ret = array(
 87+ LingoElement::ELEMENT_TERM => $term,
 88+ LingoElement::ELEMENT_DEFINITION => $definition,
 89+ LingoElement::ELEMENT_LINK => null,
 90+ LingoElement::ELEMENT_SOURCE => null
 91+ );
 92+ }
 93+
 94+ }
 95+
 96+ wfProfileOut( __METHOD__ );
 97+
 98+ return $ret;
 99+ }
 100+
 101+}
 102+
Property changes on: tags/extensions/Lingo/REL_0_3/LingoBasicBackend.php
___________________________________________________________________
Added: svn:eol-style
1103 + native
Index: tags/extensions/Lingo/REL_0_3/LingoElement.php
@@ -0,0 +1,146 @@
 2+<?php
 3+
 4+/**
 5+ * File holding the LingoElement class.
 6+ *
 7+ * @author Stephan Gambke
 8+ *
 9+ * @file
 10+ * @ingroup Lingo
 11+ */
 12+if ( !defined( 'LINGO_VERSION' ) ) {
 13+ die( 'This file is part of the Lingo extension, it is not a valid entry point.' );
 14+}
 15+
 16+/**
 17+ * This class represents a term-definition pair.
 18+ * One term may be related to several definitions.
 19+ *
 20+ * @ingroup Lingo
 21+ */
 22+class LingoElement {
 23+ const ELEMENT_TERM = 0;
 24+ const ELEMENT_DEFINITION = 1;
 25+ const ELEMENT_SOURCE = 2;
 26+ const ELEMENT_LINK = 3;
 27+
 28+ private $mFullDefinition = null;
 29+ private $mDefinitions = array();
 30+ private $mTerm = null;
 31+ private $mHasBeenDisplayed = false;
 32+
 33+ static private $mLinkTemplate = null;
 34+
 35+ public function __construct( &$term, &$definition = null ) {
 36+
 37+ $this->mTerm = $term;
 38+
 39+ if ( $definition ) {
 40+ $this->addDefinition( $definition );
 41+ }
 42+ }
 43+
 44+ public function addDefinition( &$definition ) {
 45+ $this->mDefinitions[] = $definition;
 46+ }
 47+
 48+ public function getFullDefinition( DOMDocument &$doc ) {
 49+
 50+ global $wgexLingoDisplayOnce;
 51+
 52+ wfProfileIn( __METHOD__ );
 53+
 54+ // return textnode if
 55+ if ( $wgexLingoDisplayOnce && $this->mHasBeenDisplayed ) {
 56+ return $doc->createTextNode($this->mTerm);
 57+ }
 58+
 59+ // only create if not yet created
 60+ if ( $this->mFullDefinition == null || $this->mFullDefinition->ownerDocument !== $doc ) {
 61+
 62+ // Wrap term and definition in <span> tags
 63+ $span = $doc->createElement( 'span' );
 64+ $span->setAttribute( 'class', 'tooltip' );
 65+
 66+ // Wrap term in <span> tag, hidden
 67+ wfSuppressWarnings();
 68+ $spanTerm = $doc->createElement( 'span', htmlentities( $this->mTerm, ENT_COMPAT, 'UTF-8' ) );
 69+ wfRestoreWarnings();
 70+ $spanTerm->setAttribute( 'class', 'tooltip_abbr' );
 71+
 72+ // Wrap definition in two <span> tags
 73+ $spanDefinitionOuter = $doc->createElement( 'span' );
 74+ $spanDefinitionOuter->setAttribute( 'class', 'tooltip_tipwrapper' );
 75+
 76+ $spanDefinitionInner = $doc->createElement( 'span' );
 77+ $spanDefinitionInner->setAttribute( 'class', 'tooltip_tip' );
 78+
 79+ foreach ( $this->mDefinitions as $definition ) {
 80+ wfSuppressWarnings();
 81+ $element = $doc->createElement( 'span', htmlentities( $definition[self::ELEMENT_DEFINITION], ENT_COMPAT, 'UTF-8' ) );
 82+ wfRestoreWarnings();
 83+ if ( $definition[self::ELEMENT_LINK] ) {
 84+ $linkedTitle = Title::newFromText( $definition[self::ELEMENT_LINK] );
 85+ if ( $linkedTitle ) {
 86+ $link = $this->getLinkTemplate( $doc );
 87+ $link->setAttribute( 'href', $linkedTitle->getFullURL() );
 88+ $element->appendChild( $link );
 89+ }
 90+ }
 91+ $spanDefinitionInner->appendChild( $element );
 92+ }
 93+
 94+ // insert term and definition
 95+ $span->appendChild( $spanTerm );
 96+ $span->appendChild( $spanDefinitionOuter );
 97+ $spanDefinitionOuter->appendChild( $spanDefinitionInner );
 98+
 99+ $this->mFullDefinition = $span;
 100+ $this->mHasBeenDisplayed = true;
 101+ }
 102+
 103+ wfProfileOut( __METHOD__ );
 104+
 105+ return $this->mFullDefinition->cloneNode( true );
 106+ }
 107+
 108+ public function getCurrentKey() {
 109+ return key( $this->mDefinitions );
 110+ }
 111+
 112+ public function getTerm( $key ) {
 113+ return $this->mDefinitions[$key][self::ELEMENT_TERM];
 114+ }
 115+
 116+ public function getSource( &$key ) {
 117+ return $this->mDefinitions[$key][self::ELEMENT_SOURCE];
 118+ }
 119+
 120+ public function getDefinition( &$key ) {
 121+ return $this->mDefinitions[$key][self::ELEMENT_DEFINITION];
 122+ }
 123+
 124+ public function getLink( &$key ) {
 125+ return $this->mDefinitions[$key][self::ELEMENT_LINK];
 126+ }
 127+
 128+ public function next() {
 129+ next( $this->mDefinitions );
 130+ }
 131+
 132+ private function getLinkTemplate( DOMDocument &$doc ) {
 133+ // create template if it does not yet exist
 134+ if ( !self::$mLinkTemplate || ( self::$mLinkTemplate->ownerDocument !== $doc ) ) {
 135+ global $wgScriptPath;
 136+
 137+ $linkimage = $doc->createElement( 'img' );
 138+ $linkimage->setAttribute( 'src', $wgScriptPath . '/extensions/Lingo/skins/linkicon.png' );
 139+
 140+ self::$mLinkTemplate = $doc->createElement( 'a' );
 141+ self::$mLinkTemplate->appendChild( $linkimage );
 142+ }
 143+
 144+ return self::$mLinkTemplate->cloneNode( true );
 145+ }
 146+
 147+}
Property changes on: tags/extensions/Lingo/REL_0_3/LingoElement.php
___________________________________________________________________
Added: svn:eol-style
1148 + native
Index: tags/extensions/Lingo/REL_0_3/libs/Lingo.js
@@ -0,0 +1,189 @@
 2+jQuery(function ($){
 3+
 4+ $(".tooltip")
 5+ .mouseenter(function( event ){
 6+
 7+ event.stopImmediatePropagation();
 8+
 9+ var tip = $(this);
 10+ var wrapper = tip.find(".tooltip_tipwrapper");
 11+ var tipdef = wrapper.find(".tooltip_tip");
 12+
 13+ if ( wrapper.css("display") == "block" ) {
 14+ return;
 15+ }
 16+
 17+ var termLineHeight = tip.outerHeight() + 5;
 18+ var maxAvailableWidth = $(window).width();
 19+ var maxAvailableHeightAbove = tip.offset().top - $(window).scrollTop() - 5;
 20+ var maxAvailableHeightBelow = $(window).height() - (tip.offset().top - $(window).scrollTop()) - termLineHeight;
 21+
 22+ var maxWidthWithoutBreak = maxAvailableWidth / 3;
 23+
 24+ wrapper
 25+ .css({
 26+ 'visibility': 'visible',
 27+ 'display': 'block',
 28+ 'width': '10000000px'
 29+ });
 30+
 31+
 32+ tipdef.css({
 33+ 'position': 'fixed',
 34+ 'width': 'auto',
 35+ 'top': '0px',
 36+ 'left': '0px'
 37+ });
 38+
 39+ // natural width is the width without any constraints
 40+ var naturalWidth = tipdef.width();
 41+ // natural height is the height without any constraints
 42+ var naturalHeight = tipdef.height();
 43+
 44+ var borderWidth = tipdef.outerWidth() - naturalWidth;
 45+
 46+ maxAvailableWidth -= borderWidth;
 47+ maxAvailableHeightAbove -= borderWidth;
 48+ maxAvailableHeightBelow -= borderWidth;
 49+ maxWidthWithoutBreak -= borderWidth;
 50+
 51+ var maxAvailableWidthRight = maxAvailableWidth - (tip.offset().left - $(window).scrollLeft() );
 52+
 53+ tipdef.width( maxAvailableWidth );
 54+
 55+ // height if constrained to the window width, i.e.
 56+ // the minimum width necessary if the full window width were available
 57+ var heightAtMaxWidth = tipdef.height();
 58+
 59+ // The tooltip will be placed above the term if it does fit above, but
 60+ // not below. If it is to high for either, it will be put below at
 61+ // maximum width so at least the first part is visible.
 62+ if ( heightAtMaxWidth > maxAvailableHeightBelow ) {
 63+ // will not fit below
 64+
 65+ if ( heightAtMaxWidth > maxAvailableHeightAbove ) {
 66+ // will neither fit above nor below
 67+ var placeAbove = false;
 68+ var tooLarge = true;
 69+ var maxAvailableHeight = maxAvailableHeightBelow;
 70+
 71+ } else {
 72+ // will fit above
 73+ var placeAbove = true;
 74+ var tooLarge = false;
 75+ var maxAvailableHeight = maxAvailableHeightAbove;
 76+ }
 77+ } else {
 78+ // will fit below
 79+ var placeAbove = false;
 80+ var tooLarge = false;
 81+ var maxAvailableHeight = maxAvailableHeightBelow;
 82+ }
 83+
 84+ if ( tooLarge ) {
 85+
 86+ // if it is too large anyway, just set max available width and be
 87+ // done with it
 88+ wrapper.css({
 89+ 'width': maxAvailableWidth + 'px',
 90+ 'padding-left': '0px',
 91+ 'left': (maxAvailableWidthRight - maxAvailableWidth) +'px',
 92+ 'top': '0px',
 93+ 'padding-bottom': '0px',
 94+ 'padding-top' : termLineHeight +'px'
 95+ });
 96+
 97+ } else {
 98+
 99+ if ( naturalWidth > maxWidthWithoutBreak ) {
 100+
 101+ var width = Math.max( Math.sqrt( 5 * naturalWidth * naturalHeight ), maxWidthWithoutBreak );
 102+ width = Math.min( width, maxAvailableWidth );
 103+
 104+ } else {
 105+
 106+ var width = naturalWidth;
 107+
 108+ }
 109+
 110+ tipdef.width( width );
 111+
 112+ var rounds = 0;
 113+
 114+ while ( tipdef.height() > maxAvailableHeight && rounds < 5 ) {
 115+ width = Math.min (width * ( tipdef.height() / maxAvailableHeight ), maxAvailableWidth);
 116+ tipdef.width ( width );
 117+ rounds++;
 118+ }
 119+
 120+ wrapper.height(tipdef.height());
 121+
 122+ if ( maxAvailableWidthRight - 10 >= width ) {
 123+ // will not bump into right window border
 124+ wrapper.css({
 125+ 'width': (width + 10) + 'px',
 126+ 'padding-left': '10px',
 127+ 'left': '0px'
 128+ });
 129+
 130+ } else {
 131+ // will bump into right window border
 132+ var left = maxAvailableWidthRight - width;
 133+ wrapper.css({
 134+ 'width': width + 'px',
 135+ 'padding-left': '0px',
 136+ 'left': left + 'px'
 137+ });
 138+ }
 139+
 140+ if ( placeAbove ) {
 141+ wrapper.css({
 142+ 'top': ( - tipdef.outerHeight() - 5) + 'px',
 143+ 'padding-bottom': termLineHeight +'px',
 144+ 'padding-top' : '0px'
 145+ });
 146+
 147+ } else {
 148+ wrapper.css({
 149+ // 'position': 'absolute',
 150+ 'top': '0px',
 151+ 'padding-bottom': '0px',
 152+ 'padding-top' : termLineHeight +'px'
 153+ });
 154+ }
 155+
 156+
 157+ }
 158+
 159+ tipdef.css({
 160+ 'position': 'relative'
 161+ });
 162+
 163+
 164+ wrapper
 165+ .css({
 166+ 'height': 'auto',
 167+ 'visibility': 'visible',
 168+ 'display': 'none'
 169+ })
 170+
 171+ .fadeIn(200);
 172+ })
 173+
 174+ .mouseleave( function( event ){
 175+ event.stopImmediatePropagation();
 176+
 177+ $(this).find(".tooltip_tipwrapper").fadeOut(200);
 178+ })
 179+
 180+ .find(".tooltip_tipwrapper")
 181+ .css( "display", "none" )
 182+
 183+ .find(".tooltip_tip")
 184+ .mouseleave( function( event ){
 185+ event.stopImmediatePropagation();
 186+
 187+ $(this).parent().fadeOut(200);
 188+ })
 189+
 190+});
\ No newline at end of file
Property changes on: tags/extensions/Lingo/REL_0_3/libs/Lingo.js
___________________________________________________________________
Added: svn:eol-style
1191 + native
Index: tags/extensions/Lingo/REL_0_3/Lingo.i18n.magic.php
@@ -0,0 +1,39 @@
 2+<?php
 3+/**
 4+ * Internationalisation file for Lingo extension.
 5+ *
 6+ * @file
 7+ * @ingroup Extensions
 8+ */
 9+
 10+$magicWords = array();
 11+
 12+/** English (English) */
 13+$magicWords['en'] = array(
 14+ 'noglossary' => array( 0, '__NOGLOSSARY__' ),
 15+);
 16+
 17+/** Arabic (العربية) */
 18+$magicWords['ar'] = array(
 19+ 'noglossary' => array( 0, '__لا_قاموس__' ),
 20+);
 21+
 22+/** German (Deutsch) */
 23+$magicWords['de'] = array(
 24+ 'noglossary' => array( 0, '__KEIN_GLOSSAR__', '__NOGLOSSARY__' ),
 25+);
 26+
 27+/** Esperanto (Esperanto) */
 28+$magicWords['eo'] = array(
 29+ 'noglossary' => array( 0, '__NEDIFINO__' ),
 30+);
 31+
 32+/** Nedersaksisch (Nedersaksisch) */
 33+$magicWords['nds-nl'] = array(
 34+ 'noglossary' => array( 0, '__GIEN_GLOSSARIUM__' ),
 35+);
 36+
 37+/** Dutch (Nederlands) */
 38+$magicWords['nl'] = array(
 39+ 'noglossary' => array( 0, '___GEENWOORDENLIJST__' ),
 40+);
\ No newline at end of file
Property changes on: tags/extensions/Lingo/REL_0_3/Lingo.i18n.magic.php
___________________________________________________________________
Added: svn:eol-style
141 + native
Index: tags/extensions/Lingo/REL_0_3/LingoParser.php
@@ -0,0 +1,303 @@
 2+<?php
 3+
 4+/**
 5+ * File holding the LingoParser class.
 6+ *
 7+ * @author Stephan Gambke
 8+ *
 9+ * @file
 10+ * @ingroup Lingo
 11+ */
 12+if ( !defined( 'LINGO_VERSION' ) ) {
 13+ die( 'This file is part of the Lingo extension, it is not a valid entry point.' );
 14+}
 15+
 16+/**
 17+ * This class parses the given text and enriches it with definitions for defined
 18+ * terms.
 19+ *
 20+ * Contains a static function to initiate the parsing.
 21+ *
 22+ * @ingroup Lingo
 23+ */
 24+class LingoParser {
 25+
 26+ private $mLingoTree = null;
 27+ private $mLingoBackend = null;
 28+ private static $parserSingleton = null;
 29+
 30+ // The RegEx to split a chunk of text into words
 31+ public static $regex = '/[\p{L}\p{N}]+|[^\p{L}\p{N}]/u';
 32+
 33+ public function __construct( LingoMessageLog &$messages = null ) {
 34+ global $wgexLingoBackend;
 35+
 36+ $this->mLingoBackend = new $wgexLingoBackend( $messages );
 37+ }
 38+
 39+ /**
 40+ *
 41+ * @param $parser
 42+ * @param $text
 43+ * @return Boolean
 44+ */
 45+ static function parse( &$parser, &$text ) {
 46+ wfProfileIn( __METHOD__ );
 47+ if ( !self::$parserSingleton ) {
 48+ self::$parserSingleton = new LingoParser();
 49+ }
 50+
 51+ self::$parserSingleton->realParse( $parser, $text );
 52+
 53+ wfProfileOut( __METHOD__ );
 54+
 55+ return true;
 56+ }
 57+
 58+ /**
 59+ *
 60+ * @return LingoBackend the backend used by the parser
 61+ */
 62+ public function getBackend() {
 63+ return $this->mLingoBackend;
 64+ }
 65+
 66+ /**
 67+ * Returns the list of terms in the glossary
 68+ *
 69+ * @return Array an array mapping terms (keys) to descriptions (values)
 70+ */
 71+ function getLingoArray() {
 72+ wfProfileIn( __METHOD__ );
 73+
 74+ // build glossary array only once per request
 75+ if ( !$this->mLingoTree ) {
 76+ $this->buildLingo();
 77+ }
 78+
 79+ wfProfileOut( __METHOD__ );
 80+
 81+ return $this->mLingoTree->getTermList();
 82+ }
 83+
 84+ /**
 85+ * Returns the list of terms in the glossary as a LingoTree
 86+ *
 87+ * @return LingoTree a LingoTree mapping terms (keys) to descriptions (values)
 88+ */
 89+ function getLingoTree() {
 90+ wfProfileIn( __METHOD__ );
 91+
 92+ // build glossary array only once per request
 93+ if ( !$this->mLingoTree ) {
 94+ $this->buildLingo();
 95+ }
 96+
 97+ wfProfileOut( __METHOD__ );
 98+
 99+ return $this->mLingoTree;
 100+ }
 101+
 102+ protected function buildLingo() {
 103+ wfProfileIn( __METHOD__ );
 104+
 105+ $this->mLingoTree = new LingoTree();
 106+
 107+ $backend = &$this->mLingoBackend;
 108+
 109+ // assemble the result array
 110+ while ( $elementData = $backend->next() ) {
 111+ $this->mLingoTree->addTerm( $elementData[LingoElement::ELEMENT_TERM], $elementData );
 112+ }
 113+
 114+ wfProfileOut( __METHOD__ );
 115+ }
 116+
 117+ /**
 118+ * Parses the given text and enriches applicable terms
 119+ *
 120+ * This method currently only recognizes terms consisting of max one word
 121+ *
 122+ * @param $parser
 123+ * @param $text
 124+ * @return Boolean
 125+ */
 126+ protected function realParse( &$parser, &$text ) {
 127+ global $wgRequest;
 128+
 129+ wfProfileIn( __METHOD__ );
 130+
 131+ $action = $wgRequest->getVal( 'action', 'view' );
 132+
 133+ if ( $text == null ||
 134+ $text == '' ||
 135+ $action == 'edit' ||
 136+ $action == 'ajax' ||
 137+ isset( $_POST['wpPreview'] )
 138+ ) {
 139+
 140+ wfProfileOut( __METHOD__ );
 141+ return true;
 142+ }
 143+
 144+ // Get array of terms
 145+ $glossary = $this->getLingoTree();
 146+
 147+ if ( $glossary == null ) {
 148+ wfProfileOut( __METHOD__ );
 149+ return true;
 150+ }
 151+
 152+ // Parse HTML from page
 153+ // @todo FIXME: this works in PHP 5.3.3. What about 5.1?
 154+ wfProfileIn( __METHOD__ . ' 1 loadHTML' );
 155+ wfSuppressWarnings();
 156+
 157+ $doc = DOMDocument::loadHTML(
 158+ '<html><head><meta http-equiv="content-type" content="charset=utf-8"/></head><body>' . $text . '</body></html>'
 159+ );
 160+
 161+ wfRestoreWarnings();
 162+ wfProfileOut( __METHOD__ . ' 1 loadHTML' );
 163+
 164+ wfProfileIn( __METHOD__ . ' 2 xpath' );
 165+ // Find all text in HTML.
 166+ $xpath = new DOMXpath( $doc );
 167+ $elements = $xpath->query(
 168+ "//*[not(ancestor-or-self::*[@class='noglossary'] or ancestor-or-self::a)][text()!=' ']/text()"
 169+ );
 170+ wfProfileOut( __METHOD__ . ' 2 xpath' );
 171+
 172+ // Iterate all HTML text matches
 173+ $nb = $elements->length;
 174+ $changedDoc = false;
 175+
 176+ for ( $pos = 0; $pos < $nb; $pos++ ) {
 177+ $el = $elements->item( $pos );
 178+
 179+ if ( strlen( $el->nodeValue ) < $glossary->getMinTermLength() ) {
 180+ continue;
 181+ }
 182+
 183+ wfProfileIn( __METHOD__ . ' 3 lexer' );
 184+ $matches = array();
 185+ preg_match_all(
 186+ self::$regex,
 187+ $el->nodeValue,
 188+ $matches,
 189+ PREG_OFFSET_CAPTURE | PREG_PATTERN_ORDER
 190+ );
 191+ wfProfileOut( __METHOD__ . ' 3 lexer' );
 192+
 193+ if ( count( $matches ) == 0 || count( $matches[0] ) == 0 ) {
 194+ continue;
 195+ }
 196+
 197+ $lexemes = &$matches[0];
 198+ $countLexemes = count( $lexemes );
 199+ $parent = &$el->parentNode;
 200+ $index = 0;
 201+ $changedElem = false;
 202+
 203+ while ( $index < $countLexemes ) {
 204+ wfProfileIn( __METHOD__ . ' 4 findNextTerm' );
 205+ list( $skipped, $used, $definition ) =
 206+ $glossary->findNextTerm( $lexemes, $index, $countLexemes );
 207+ wfProfileOut( __METHOD__ . ' 4 findNextTerm' );
 208+
 209+ wfProfileIn( __METHOD__ . ' 5 insert' );
 210+ if ( $used > 0 ) { // found a term
 211+ if ( $skipped > 0 ) { // skipped some text, insert it as is
 212+ $parent->insertBefore(
 213+ $doc->createTextNode(
 214+ substr( $el->nodeValue,
 215+ $currLexIndex = $lexemes[$index][1],
 216+ $lexemes[$index + $skipped][1] - $currLexIndex )
 217+ ),
 218+ $el
 219+ );
 220+ }
 221+
 222+ $parent->insertBefore( $definition->getFullDefinition( $doc ), $el );
 223+
 224+ $changedElem = true;
 225+ } else { // did not find term, just use the rest of the text
 226+ // If we found no term now and no term before, there was no
 227+ // term in the whole element. Might as well not change the
 228+ // element at all.
 229+ // Only change element if found term before
 230+ if ( $changedElem ) {
 231+ $parent->insertBefore(
 232+ $doc->createTextNode(
 233+ substr( $el->nodeValue, $lexemes[$index][1] )
 234+ ),
 235+ $el
 236+ );
 237+ } else {
 238+ wfProfileOut( __METHOD__ . ' 5 insert' );
 239+ // In principle superfluous, the loop would run out
 240+ // anyway. Might save a bit of time.
 241+ break;
 242+ }
 243+ }
 244+ wfProfileOut( __METHOD__ . ' 5 insert' );
 245+
 246+ $index += $used + $skipped;
 247+ }
 248+
 249+ if ( $changedElem ) {
 250+ $parent->removeChild( $el );
 251+ $changedDoc = true;
 252+ }
 253+ }
 254+
 255+ if ( $changedDoc ) {
 256+ $this->loadModules( $parser );
 257+
 258+ // U - Ungreedy, D - dollar matches only end of string, s - dot matches newlines
 259+ $text = preg_replace( '%(^.*<body>)|(</body>.*$)%UDs', '', $doc->saveHTML() );
 260+ }
 261+
 262+ wfProfileOut( __METHOD__ );
 263+
 264+ return true;
 265+ }
 266+
 267+ protected function loadModules( &$parser ) {
 268+ global $wgOut, $wgScriptPath, $wgParser;
 269+
 270+ // load scripts
 271+ if ( defined( 'MW_SUPPORTS_RESOURCE_MODULES' ) ) {
 272+ $parser->getOutput()->addModules( 'ext.Lingo.Scripts' );
 273+ if ( !$wgOut->isArticle() ) {
 274+ $wgOut->addModules( 'ext.Lingo.Scripts' );
 275+ }
 276+ } else {
 277+ global $wgStylePath;
 278+ $parser->getOutput()->addHeadItem( "<script src='$wgStylePath/common/jquery.min.js'></script>\n", 'ext.Lingo.jq' );
 279+ $parser->getOutput()->addHeadItem( "<script src='$wgScriptPath/extensions/Lingo/libs/Lingo.js'></script>\n", 'ext.Lingo.Scripts' );
 280+ if ( !$wgOut->isArticle() ) {
 281+ $wgOut->addHeadItem( 'ext.Lingo.jq', "<script src='$wgStylePath/common/jquery.min.js'></script>\n" );
 282+ $wgOut->addHeadItem( 'ext.Lingo.Scripts', "<script src='$wgScriptPath/extensions/Lingo/libs/Lingo.js'></script>\n" );
 283+ }
 284+ }
 285+
 286+ // load styles
 287+ // FIXME: Modules loaded by the ResourceLoader only work on JS-enabled
 288+ // browsers. This doesn't make any sense for CSS-only modules that don't
 289+ // need any JS. -> Use ResourceLoader if and when Bug 29308 gets fixed.
 290+// if ( defined( 'MW_SUPPORTS_RESOURCE_MODULES' ) ) {
 291+// $parser->getOutput()->addModules( 'ext.Lingo.Styles' );
 292+// if ( !$wgOut->isArticle() ) {
 293+// $wgOut->addModules( 'ext.Lingo.Styles' );
 294+// }
 295+// } else {
 296+ $parser->getOutput()->addHeadItem( "<link rel='stylesheet' href='$wgScriptPath/extensions/Lingo/skins/Lingo.css' />\n", 'ext.Lingo.Styles' );
 297+ if ( !$wgOut->isArticle() ) {
 298+ $wgOut->addHeadItem( 'ext.Lingo.Styles', "<link rel='stylesheet' href='$wgScriptPath/extensions/Lingo/skins/Lingo.css' />\n" );
 299+ }
 300+// }
 301+ }
 302+
 303+}
 304+
Property changes on: tags/extensions/Lingo/REL_0_3/LingoParser.php
___________________________________________________________________
Added: svn:eol-style
1305 + native
Index: tags/extensions/Lingo/REL_0_3/Lingo.i18n.php
@@ -0,0 +1,203 @@
 2+<?php
 3+/**
 4+ * Internationalisation file for extension Lingo.
 5+ *
 6+ * @file
 7+ * @ingroup Lingo
 8+ */
 9+
 10+$messages = array();
 11+
 12+$messages['en'] = array(
 13+ 'lingo-desc' => 'Provides hover-over tool tips on pages from words defined on the [[$1]] page',
 14+ 'lingo-terminologypagename' => 'Terminology',
 15+ 'lingo-noterminologypage' => 'Page "$1" does not exist.',
 16+ 'lingo-terminologypagenotlocal' => 'Page "$1" is not a local page.',
 17+);
 18+
 19+/** Message documentation (Message documentation) */
 20+$messages['qqq'] = array(
 21+ 'lingo-desc' => '{{desc}}',
 22+ 'lingo-terminologypagename' => 'Name of the page where the terms and definitions of the glossary are stored',
 23+);
 24+
 25+/** Belarusian (Taraškievica orthography) (‪Беларуская (тарашкевіца)‬)
 26+ * @author EugeneZelenko
 27+ * @author Wizardist
 28+ */
 29+$messages['be-tarask'] = array(
 30+ 'lingo-desc' => 'Паказвае падказкі да словаў, вызначаных на старонцы [[$1]]',
 31+ 'lingo-terminologypagename' => 'Тэрміналёгія',
 32+ 'lingo-noterminologypage' => 'Старонка «$1» не існуе.',
 33+ 'lingo-terminologypagenotlocal' => 'Старонка «$1» не зьяўляецца лякальнай.',
 34+);
 35+
 36+/** Breton (Brezhoneg)
 37+ * @author Fulup
 38+ * @author Y-M D
 39+ */
 40+$messages['br'] = array(
 41+ 'lingo-terminologypagename' => 'Termenadurezh',
 42+ 'lingo-noterminologypage' => 'N\'eus ket eus ar bajenn "$1".',
 43+ 'lingo-terminologypagenotlocal' => 'N\'eus ket ur bajenn lec\'hel eus "$1".',
 44+);
 45+
 46+/** German (Deutsch)
 47+ * @author Kghbln
 48+ */
 49+$messages['de'] = array(
 50+ 'lingo-desc' => 'Ermöglicht Informationstexte, die eingeblendet werden, sobald man die Maus über einen auf der Seite [[$1]] hinterlegten Begriff führt',
 51+ 'lingo-terminologypagename' => 'Glossar',
 52+ 'lingo-noterminologypage' => 'Seite „$1“ ist nicht vorhanden.',
 53+ 'lingo-terminologypagenotlocal' => 'Seite „$1“ befindet sich nicht auf diesem Wiki.',
 54+);
 55+
 56+/** French (Français)
 57+ * @author Sherbrooke
 58+ */
 59+$messages['fr'] = array(
 60+ 'lingo-desc' => 'Dans les pages, affiche une info-bulle si le mot est défini dans la page de [[$1]].',
 61+ 'lingo-terminologypagename' => 'Terminologie',
 62+ 'lingo-noterminologypage' => "Page « $1 » n'existe pas.",
 63+ 'lingo-terminologypagenotlocal' => "Page « $1 » n'est pas une page locale.",
 64+);
 65+
 66+/** Franco-Provençal (Arpetan)
 67+ * @author ChrisPtDe
 68+ */
 69+$messages['frp'] = array(
 70+ 'lingo-terminologypagename' => 'Tèrminologia',
 71+ 'lingo-noterminologypage' => 'Pâge « $1 » ègziste pas.',
 72+ 'lingo-terminologypagenotlocal' => 'Pâge « $1 » est pas una pâge locala.',
 73+);
 74+
 75+/** Galician (Galego)
 76+ * @author Toliño
 77+ */
 78+$messages['gl'] = array(
 79+ 'lingo-desc' => 'Proporciona consellos nas páxinas ao pasar o rato por riba das palabras definidas na páxina "[[$1]]"',
 80+ 'lingo-terminologypagename' => 'Terminoloxía',
 81+ 'lingo-noterminologypage' => 'A páxina "$1" non existe.',
 82+ 'lingo-terminologypagenotlocal' => 'A páxina "$1" non é unha páxina local.',
 83+);
 84+
 85+/** Hebrew (עברית)
 86+ * @author Amire80
 87+ */
 88+$messages['he'] = array(
 89+ 'lingo-desc' => 'כלי לתצוגה רמזים צצים בדפים לפי מילים שמוגדרות בדף [[$1]]',
 90+ 'lingo-terminologypagename' => 'מינוח',
 91+ 'lingo-noterminologypage' => 'הדף "$1" אניו קיים.',
 92+ 'lingo-terminologypagenotlocal' => 'הדם "$1" אינו דף מקומי.',
 93+);
 94+
 95+/** Upper Sorbian (Hornjoserbsce)
 96+ * @author Michawiki
 97+ */
 98+$messages['hsb'] = array(
 99+ 'lingo-desc' => 'Zwobraznja pomocne teksty, hdyž kursor myše nad słowom steji, kotrež je na stronje [[$1]] definowane.',
 100+ 'lingo-terminologypagename' => 'Terminologija',
 101+ 'lingo-noterminologypage' => 'Strona "$1" njeeksistuje',
 102+ 'lingo-terminologypagenotlocal' => 'Strona "$1" lokalna strona njeje.',
 103+);
 104+
 105+/** Interlingua (Interlingua)
 106+ * @author McDutchie
 107+ */
 108+$messages['ia'] = array(
 109+ 'lingo-desc' => 'Monstra, al passage del cursor del mus, quadros de information super paginas de parolas definite in le pagina [[$1]]',
 110+ 'lingo-terminologypagename' => 'Terminologia',
 111+ 'lingo-noterminologypage' => 'Le pagina "$1" non existe.',
 112+ 'lingo-terminologypagenotlocal' => 'Le pagina "$1" non es un pagina local.',
 113+);
 114+
 115+/** Japanese (日本語)
 116+ * @author Schu
 117+ */
 118+$messages['ja'] = array(
 119+ 'lingo-desc' => '[[$1]] ページに定義された用語から、ページ上にヒントを表示する hover-over ツールを提供します。',
 120+ 'lingo-terminologypagename' => 'Terminology',
 121+ 'lingo-noterminologypage' => '"$1" ページが存在しません。',
 122+ 'lingo-terminologypagenotlocal' => '" $1 "ページはローカルページではありません。',
 123+);
 124+
 125+/** Luxembourgish (Lëtzebuergesch)
 126+ * @author Robby
 127+ */
 128+$messages['lb'] = array(
 129+ 'lingo-desc' => "Erlaabt et 'Tool Tips' ze weisen, wann ee mat der Maus iwwer Wierder fiert déi op der [[$1]]-Säit definéiert sinn",
 130+ 'lingo-terminologypagename' => 'Terminologie',
 131+ 'lingo-noterminologypage' => "Säit '$1' gëtt et net.",
 132+ 'lingo-terminologypagenotlocal' => "Säit '$1' gëtt et op dëser Wiki net.",
 133+);
 134+
 135+/** Macedonian (Македонски)
 136+ * @author Bjankuloski06
 137+ */
 138+$messages['mk'] = array(
 139+ 'lingo-desc' => 'Овозможува описи при лебдење над алатките на страниците (од зборови со утврдени значења на страницата [[$1]])',
 140+ 'lingo-terminologypagename' => 'Терминологија',
 141+ 'lingo-noterminologypage' => 'Страницата „$1“ не постои.',
 142+ 'lingo-terminologypagenotlocal' => 'Страницата „$1“ не е локална страница.',
 143+);
 144+
 145+/** Malay (Bahasa Melayu)
 146+ * @author Anakmalaysia
 147+ */
 148+$messages['ms'] = array(
 149+ 'lingo-desc' => 'Menyediakan petua-petua alatan secara hover pada laman-laman daripada kata-kata yang ditakrifkan di laman [[$1]]',
 150+ 'lingo-terminologypagename' => 'Peristilahan',
 151+ 'lingo-noterminologypage' => 'Laman "$1" tidak wujud.',
 152+ 'lingo-terminologypagenotlocal' => 'Laman "$1" bukan laman tempatan.',
 153+);
 154+
 155+/** Dutch (Nederlands)
 156+ * @author Siebrand
 157+ * @author Tjcool007
 158+ */
 159+$messages['nl'] = array(
 160+ 'lingo-desc' => "Zorgt voor tooltips op pagina's voor woorden gedefinieerd op [[$1]].",
 161+ 'lingo-terminologypagename' => 'Terminologie',
 162+ 'lingo-noterminologypage' => 'De pagina "$1" bestaat niet.',
 163+ 'lingo-terminologypagenotlocal' => 'De pagina "$1" is geen lokale pagina.',
 164+);
 165+
 166+/** Polish (Polski)
 167+ * @author Sp5uhe
 168+ * @author Woytecr
 169+ */
 170+$messages['pl'] = array(
 171+ 'lingo-noterminologypage' => 'Strona „$1“ nie istnieje.',
 172+);
 173+
 174+/** Portuguese (Português)
 175+ * @author Hamilton Abreu
 176+ */
 177+$messages['pt'] = array(
 178+ 'lingo-desc' => 'Permite que a passagem do ponteiro do rato sobre palavras nas páginas, resulte no aparecimento de uma legenda. As palavras são definidas na página [[$1]].',
 179+ 'lingo-terminologypagename' => 'Terminology',
 180+ 'lingo-noterminologypage' => "A página '$1' não existe.",
 181+ 'lingo-terminologypagenotlocal' => "A página '$1' não é uma página local.",
 182+);
 183+
 184+/** Russian (Русский)
 185+ * @author Adata80
 186+ * @author Askarmuk
 187+ * @author Александр Сигачёв
 188+ */
 189+$messages['ru'] = array(
 190+ 'lingo-desc' => 'Показывает всплывающую подсказку при наведении на слово, присутствующее на странице [[$1]]',
 191+ 'lingo-terminologypagename' => 'Терминология',
 192+ 'lingo-noterminologypage' => 'Страница "$1" не существует.',
 193+ 'lingo-terminologypagenotlocal' => 'Страница "$1" не является локальной.',
 194+);
 195+
 196+/** Swedish (Svenska)
 197+ * @author WikiPhoenix
 198+ */
 199+$messages['sv'] = array(
 200+ 'lingo-terminologypagename' => 'Terminologi',
 201+ 'lingo-noterminologypage' => 'Sidan "$1" finns inte',
 202+ 'lingo-terminologypagenotlocal' => 'Sidan "$1" är inte en lokal sida.',
 203+);
 204+
Property changes on: tags/extensions/Lingo/REL_0_3/Lingo.i18n.php
___________________________________________________________________
Added: svn:eol-style
1205 + native
Index: tags/extensions/Lingo/REL_0_3/README
@@ -0,0 +1,70 @@
 2+Lingo is a glossary extension to MediaWiki, that lets you define abbreviations
 3+and their definitions on a wiki page. It displays these definitions whenever an
 4+abbreviation is hovered over in an article.
 5+
 6+See http://www.mediawiki.org/wiki/Extension:Lingo for online documentation.
 7+
 8+
 9+== Installation ==
 10+
 11+This extension was developed for MediaWiki 1.16 und upwards. Other version might
 12+work, but are not tested.
 13+
 14+1. Download the package. Unpack the folder inside /extensions (so that the files
 15+ are in /extensions/Lingo, rename the folder if necessary).
 16+
 17+2. In your LocalSettings.php, add the following line to the end of the file:
 18+
 19+ require_once("$IP/extensions/Lingo/Lingo.php");
 20+
 21+3. Create the page "Terminology" (no namespace), and insert some entries using
 22+ the following syntax:
 23+
 24+
 25+;FTP:File Transport Protocol
 26+;AAAAA:American Association Against Acronym Abuse
 27+;ACK:Acknowledge
 28+;AFAIK:As Far As I Know
 29+;AWGTHTGTATA:Are We Going To Have To Go Through All This Again
 30+;HTTP:HyperText Transfer Protocol
 31+
 32+
 33+== Customization ==
 34+
 35+The following settings may be used:
 36+
 37+* $wgexLingoPage to specify the name of the terminology page
 38+ Example: $wgexLingoPage = 'Glossary';
 39+
 40+* $wgexLingoDisplayOnce to specify that each term should be annotated only once
 41+ per page
 42+ Example: $wgexLingoDisplayOnce = true;
 43+
 44+* $wgexLingoUseNamespaces to specify what namespaces should or should not be used
 45+ Example: $wgexLingoUseNamespaces[NS_TALK] = false;
 46+
 47+If you want to use these settings, just include them in LocalSettings.php AFTER
 48+the require_once("$IP/extensions/Lingo/Lingo.php");
 49+
 50+
 51+== Usage ==
 52+
 53+By default Lingo will mark up any page that is not in a forbidden namespace. To
 54+exclude a page from markup you can include __NOGLOSSARY__ anywhere in the
 55+article. In some cases it may be necessary to exclude portions of a page, e.g.
 56+because Lingo interferes with some JavaScript. This can be achieved by wrapping
 57+the part in an HTML element (e.g. a span or a div) and specify class="noglossary".
 58+
 59+
 60+== Credits ==
 61+
 62+Lingo is a rewrite of Extension:Terminology, written by BarkerJr with
 63+modifications by Benjamin Kahn. It was originally written by Barry Coughlan and
 64+is currently maintained by Stephan Gambke.
 65+
 66+
 67+== Reporting bugs ==
 68+
 69+Comments, questions and suggestions should be sent or posted to:
 70+* the Lingo discussion page: http://www.mediawiki.org/wiki/Extension_talk:Lingo
 71+* the maintainer: http://www.mediawiki.org/wiki/Special:EmailUser/F.trott
Property changes on: tags/extensions/Lingo/REL_0_3/README
___________________________________________________________________
Added: svn:eol-style
172 + native
Index: tags/extensions/Lingo/REL_0_3/Lingo.php
@@ -0,0 +1,97 @@
 2+<?php
 3+
 4+/**
 5+ * Provides hover-over tool tips on articles from words defined on the
 6+ * Terminology page.
 7+ *
 8+ * @file
 9+ * @defgroup Lingo
 10+ * @author Barry Coughlan
 11+ * @copyright 2010 Barry Coughlan
 12+ * @author Stephan Gambke
 13+ * @version 0.3
 14+ * @licence GNU General Public Licence 2.0 or later
 15+ * @see http://www.mediawiki.org/wiki/Extension:Lingo Documentation
 16+ */
 17+if ( !defined( 'MEDIAWIKI' ) ) {
 18+ die( 'This file is part of a MediaWiki extension, it is not a valid entry point.' );
 19+}
 20+
 21+define( 'LINGO_VERSION', '0.3' );
 22+
 23+
 24+// set defaults for settings
 25+
 26+// set the backend to access the glossary
 27+$wgexLingoBackend = 'LingoBasicBackend';
 28+
 29+// set default for Terminology page (null = take from i18n)
 30+$wgexLingoPage = null;
 31+
 32+// set if glossary terms are to be marked up once or always
 33+$wgexLingoDisplayOnce = false;
 34+
 35+// set namespaces to be marked up;
 36+// namespaces to be ignored have to be included in this array and set to false
 37+// anything not in this array (or in this array and set to true) will be marked up
 38+$wgexLingoUseNamespaces = array(
 39+// NS_MEDIA => true,
 40+// NS_SPECIAL => true,
 41+// NS_TALK => false,
 42+// ...
 43+);
 44+
 45+
 46+// set extension credits
 47+// (no description here, will be set later)
 48+$wgExtensionCredits['parserhook']['lingo'] = array(
 49+ 'path' => __FILE__,
 50+ 'name' => 'Lingo',
 51+ 'author' => array('Barry Coughlan', '[http://www.mediawiki.org/wiki/User:F.trott Stephan Gambke]'),
 52+ 'url' => 'http://www.mediawiki.org/wiki/Extension:Lingo',
 53+ 'version' => LINGO_VERSION,
 54+);
 55+
 56+// server-local path to this file
 57+$dir = dirname( __FILE__ );
 58+
 59+// register message files
 60+$wgExtensionMessagesFiles['Lingo'] = $dir . '/Lingo.i18n.php';
 61+$wgExtensionMessagesFiles['LingoMagic'] = $dir . '/Lingo.i18n.magic.php';
 62+
 63+// register class files with the Autoloader
 64+$wgAutoloadClasses['LingoHooks'] = $dir . '/LingoHooks.php';
 65+$wgAutoloadClasses['LingoParser'] = $dir . '/LingoParser.php';
 66+$wgAutoloadClasses['LingoTree'] = $dir . '/LingoTree.php';
 67+$wgAutoloadClasses['LingoElement'] = $dir . '/LingoElement.php';
 68+$wgAutoloadClasses['LingoBackend'] = $dir . '/LingoBackend.php';
 69+$wgAutoloadClasses['LingoBasicBackend'] = $dir . '/LingoBasicBackend.php';
 70+$wgAutoloadClasses['LingoMessageLog'] = $dir . '/LingoMessageLog.php';
 71+
 72+// register hook handlers
 73+$wgHooks['SpecialVersionExtensionTypes'][] = 'LingoHooks::setCredits'; // set credits
 74+$wgHooks['ParserAfterTidy'][] = 'LingoHooks::parse'; // parse page
 75+
 76+// register resource modules with the Resource Loader
 77+$wgResourceModules['ext.Lingo.Styles'] = array(
 78+ 'localBasePath' => $dir,
 79+ 'remoteExtPath' => 'Lingo',
 80+ // 'scripts' => 'libs/ext.myExtension.js',
 81+ 'styles' => 'skins/Lingo.css',
 82+ // 'messages' => array( 'myextension-hello-world', 'myextension-goodbye-world' ),
 83+ // 'dependencies' => array( 'jquery.ui.datepicker' ),
 84+);
 85+
 86+$wgResourceModules['ext.Lingo.Scripts'] = array(
 87+ 'localBasePath' => $dir,
 88+ 'remoteExtPath' => 'Lingo',
 89+ 'scripts' => 'libs/Lingo.js',
 90+ // 'styles' => 'skins/Lingo.css',
 91+ // 'messages' => array( 'myextension-hello-world', 'myextension-goodbye-world' ),
 92+ // 'dependencies' => array( 'jquery.ui.datepicker' ),
 93+);
 94+
 95+MagicWord::$mDoubleUnderscoreIDs[] = 'noglossary';
 96+
 97+unset( $dir );
 98+
Property changes on: tags/extensions/Lingo/REL_0_3/Lingo.php
___________________________________________________________________
Added: svn:eol-style
199 + native
Index: tags/extensions/Lingo/REL_0_3/LingoTree.php
@@ -0,0 +1,143 @@
 2+<?php
 3+
 4+/**
 5+ * File holding the LingoTree class
 6+ *
 7+ * @author Stephan Gambke
 8+ *
 9+ * @file
 10+ * @ingroup Lingo
 11+ */
 12+if ( !defined( 'LINGO_VERSION' ) ) {
 13+ die( 'This file is part of the Lingo extension, it is not a valid entry point.' );
 14+}
 15+
 16+/**
 17+ * The LingoTree class.
 18+ *
 19+ * Vocabulary:
 20+ * Term - The term as a normal string
 21+ * Definition - Its definition (any object)
 22+ * Element - An element (leaf) in the glossary tree
 23+ * Path - The path in the tree to the leaf representing a term
 24+ *
 25+ * The glossary is organized as a tree (nested arrays) where the path to the
 26+ * definition of a term is the lexemes of the term followed by -1 as the end
 27+ * marker.
 28+ *
 29+ * Example:
 30+ * The path to the definition of the term "foo bar baz" would be
 31+ * 'foo'.' '.'bar'.' '.'baz'.'-1'. It could thus be accessed as
 32+ * $mTree['foo'][' ']['bar'][' ']['baz'][-1]
 33+ *
 34+ * @ingroup Lingo
 35+ */
 36+class LingoTree {
 37+
 38+ private $mTree = array();
 39+ private $mList = array();
 40+ private $mMinLength = 1000;
 41+
 42+ /**
 43+ * Adds a string to the Lingo Tree
 44+ * @param String $term
 45+ */
 46+ function addTerm( &$term, $definition ) {
 47+ if ( !$term ) {
 48+ return;
 49+ }
 50+
 51+ if ( isset( $this->mList[$term] ) ) { // term exists, store 2nd definition
 52+ $this->mList[$term]->addDefinition( $definition );
 53+ } else {
 54+
 55+ $matches;
 56+ preg_match_all( LingoParser::$regex, $term, $matches );
 57+
 58+ $elt = $this->addElement( $matches[0], $term, $definition );
 59+ $this->mList[$term] = &$elt[-1];
 60+
 61+ $this->mMinLength = min( array($this->mMinLength, strlen( $term )) );
 62+ }
 63+ }
 64+
 65+ /**
 66+ * Adds an element to the Lingo Tree
 67+ *
 68+ * @param array $path An array containing the constituing lexemes of the term
 69+ * @param String $term
 70+ * @param String $definition
 71+ * @return Array the tree node the element was stored in
 72+ */
 73+ protected function &addElement( Array &$path, &$term, &$definition ) {
 74+
 75+ $tree = &$this->mTree;
 76+
 77+ // end of path, store description; end of recursion
 78+ while ( ($step = array_shift( $path )) !== null ) {
 79+
 80+ if ( !isset( $tree[$step] ) ) {
 81+ $tree[$step] = array();
 82+ }
 83+
 84+ $tree = &$tree[$step];
 85+ }
 86+
 87+ if ( isset( $tree[-1] ) ) {
 88+ $tree[-1]->addDefinition( $definition );
 89+ } else {
 90+ $tree[-1] = new LingoElement( $term, $definition );
 91+ }
 92+
 93+ return $tree;
 94+ }
 95+
 96+ function getMinTermLength() {
 97+ return $this->mMinLength;
 98+ }
 99+
 100+ function getTermList() {
 101+ return $this->mList;
 102+ }
 103+
 104+ function findNextTerm( &$lexemes, $index, $countLexemes ) {
 105+ wfProfileIn( __METHOD__ );
 106+
 107+ $start = $lastindex = $index;
 108+ $definition = null;
 109+
 110+ // skip until ther start of a term is found
 111+ while ( $index < $countLexemes && !$definition ) {
 112+ $currLex = &$lexemes[$index][0];
 113+
 114+ // Did we find the start of a term?
 115+ if ( array_key_exists( $currLex, $this->mTree ) ) {
 116+ list( $lastindex, $definition ) = $this->findNextTermNoSkip( $this->mTree[$currLex], $lexemes, $index, $countLexemes );
 117+ }
 118+
 119+ // this will increase the index even if we found something;
 120+ // will be corrected after the loop
 121+ $index++;
 122+ }
 123+
 124+ wfProfileOut( __METHOD__ );
 125+ if ( $definition ) {
 126+ return array($index - $start - 1, $lastindex - $index + 2, $definition);
 127+ } else {
 128+ return array($index - $start, 0, null);
 129+ }
 130+ }
 131+
 132+ function findNextTermNoSkip( Array &$tree, &$lexemes, $index, $countLexemes ) {
 133+ wfProfileIn( __METHOD__ );
 134+
 135+ if ( $index + 1 < $countLexemes && array_key_exists( $currLex = $lexemes[$index + 1][0], $tree ) ) {
 136+ $ret = $this->findNextTermNoSkip( $tree[$currLex], $lexemes, $index + 1, $countLexemes );
 137+ } else {
 138+ $ret = array($index, &$tree[-1]);
 139+ }
 140+ wfProfileOut( __METHOD__ );
 141+ return $ret;
 142+ }
 143+
 144+}
Property changes on: tags/extensions/Lingo/REL_0_3/LingoTree.php
___________________________________________________________________
Added: svn:eol-style
1145 + native

Status & tagging log