[Home]WikiPatches/Esperanto

UseModWiki | WikiPatches | RecentChanges | Preferences

Keyboard drivers supporting Esperanto's six accented letters (ĉ ĝ ĥ ĵ ŝ ŭ) are surprisingly rare on the ground. ;) As a consequence, it's common to type the language using a simple substitution code, where the base letters are followed by "x", which letter isn't used in the language. This patch performs the reverse substitution on output to make the wiki prettier to look at; the few without UTF-8 support or full Latin sets in their fonts can click to turn it off.

Text and titles are stored internally in the X-substitution, so URLs are legible, but not entirely [future-proof]. UTF-8 raw input is normalized to X-substitution; non-Esperanto Unicode characters are left as is, and may or may not be damaged by various portions of the wiki. See SupportForUtf8.

Based on modifications made originally for WikiPedia's Esperanto edition (no longer on UseModWiki), adapted for [TEJO-Vikio] and others. Most useful used in conjunction with the EsperantoTranslation!

BrionVibber


Patch version 0.2, against UseModWiki 1.0

--- usemod10/wiki.pl	Thu Sep 11 05:21:02 2003
+++ usmodo.pl	Thu Sep 18 22:18:52 2003
@@ -72,8 +72,8 @@
 # Default configuration (used if UseConfig is 0)
 $CookieName  = "Wiki";          # Name for this wiki (for multi-wiki sites)
 $SiteName    = "Wiki";          # Name of site (used for titles)
-$HomePage    = "HomePage";      # Home page (change space to _)
-$RCName      = "RecentChanges"; # Name of changes page (change space to _)
+$HomePage    = "CxefPagxo";     # Home page (change space to _)
+$RCName      = "LastajSxangxoj";# Name of changes page (change space to _)
 $LogoUrl     = "/wiki.gif";     # URL for site logo ("" for no logo)
 $ENV{PATH}   = "/usr/bin/";     # Path used to find "diff"
 $ScriptTZ    = "";              # Local time zone ("" means do not print)
@@ -93,7 +93,7 @@
 $EditNote    = "";              # HTML notice above buttons on edit page
 $MaxPost     = 1024 * 210;      # Maximum 210K posts (about 200K for pages)
 $NewText     = "";              # New page text ("" for default message)
-$HttpCharset = "";              # Charset for pages, like "iso-8859-2"
+$HttpCharset = "utf-8";         # Charset for pages, like "iso-8859-2"
 $UserGotoBar = "";              # HTML added to end of goto bar
 $InterWikiMoniker = '';         # InterWiki moniker for this wiki. (for RSS)
 $SiteDescription  = $SiteName;  # Description of this wiki. (for RSS)
@@ -327,7 +327,7 @@
 sub DoCacheBrowse {
   my ($query, $idFile, $text);
 
-  return 0  if (!$UseCache);
+  return 0  if (!$UseCache || !&GetParam("recodetext", 1));
   $query = $ENV{'QUERY_STRING'};
   if (($query eq "") && ($ENV{'REQUEST_METHOD'} eq "GET")) {
     $query = $HomePage;  # Allow caching of home page.
@@ -368,7 +368,7 @@
   my ($text) = @_;
 
   if (defined($Translate{$text}) && ($Translate{$text} ne ''))  {
-    return $Translate{$text};
+    return &RecodeOutput($Translate{$text});
   }
   return $text;
 }
@@ -389,6 +389,47 @@
   return $text;
 }
 
+sub RecodeOutput {
+  my ($text) = @_;
+  my %x2u;
+  # In theory, this could be expanded to allow general conversion of the
+  # character encoding used in the database to another encoding optionally
+  # used on the browser end.
+  # For now, hardcoded to convert Esperanto text in "X-Sistemo" to UTF-8.
+  %x2u = (
+  	"x" => "x", "X" => "X",
+  	"C" => "\xc4\x88", "c" => "\xc4\x89",
+	"G" => "\xc4\x9c", "g" => "\xc4\x9d",
+	"H" => "\xc4\xa4", "h" => "\xc4\xa5",
+	"J" => "\xc4\xb4", "j" => "\xc4\xb5",
+	"S" => "\xc5\x9c", "s" => "\xc5\x9d",
+	"U" => "\xc5\xac", "u" => "\xc5\xad");
+  if(&GetParam("recodetext", 1)) {
+    $text =~ s/x[Xx](?=[Xx][Xx])*(?![Xx])/x/g;
+    $text =~ s/X[Xx](?=[Xx][Xx])*(?![Xx])/X/g;
+    $text =~ s/([cghjsu])x/$x2u{$1}/ige;
+  }
+  return $text;
+}
+
+sub RecodeInput {
+  my ($text) = @_;
+  my %u2x;
+  # Convert Esperanto text in UTF-8 to "X-Sistemo"
+  %u2x = (
+  	"\xc4\x88" => "Cx", "\xc4\x89" => "cx",
+	"\xc4\x9c" => "Gx", "\xc4\x9d" => "gx",
+	"\xc4\xa4" => "Hx", "\xc4\xa5" => "hx",
+	"\xc4\xb4" => "Jx", "\xc4\xb5" => "jx",
+	"\xc5\x9c" => "Sx", "\xc5\x9d" => "sx",
+	"\xc5\xac" => "Ux", "\xc5\xad" => "ux");
+  # Don't check the 'recodetext' option; we should be able to accept
+  # Unicode input even with X-code output. This allows cut-n-paste
+  # between certain combinations of apps.
+  $text =~ s/([\xc4][\x88\x89\x9c\x9d\xa4\xa5\xb4\xb5]|[\xc5][\x9c\x9d\xac\xad])/$u2x{$1}/ge;
+  return $text;
+}
+
 # == Normal page-browsing and RecentChanges code =======================
 $BrowseCode = ""; # Comment next line to always compile (slower)
 #$BrowseCode = <<'#END_OF_BROWSE_CODE';
@@ -586,7 +627,7 @@
   $fullHtml .= &GetFooterText($id, $goodRevision);
   print $fullHtml;
   return  if ($showDiff || ($revision ne ''));  # Don't cache special version
-  &UpdateHtmlCache($id, $fullHtml)  if ($UseCache && ($oldId eq ''));
+  &UpdateHtmlCache($id, $fullHtml)  if ($UseCache && ($oldId eq '') && &GetParam("recodetext", 1));
 }
 
 sub ReBrowsePage {
@@ -843,7 +884,7 @@
   }
   $sum = "";
   if (($summary ne "") && ($summary ne "*")) {
-    $summary = &QuoteHtml($summary);
+    $summary = &RecodeOutput(&QuoteHtml($summary));
     $sum = "<strong>[$summary]</strong> ";
   }
   $edit = "";
@@ -1093,14 +1134,14 @@
 sub ScriptLink {
   my ($action, $text) = @_;
 
-  return "<a href=\"$ScriptName" . &ScriptLinkChar() . "$action\">$text</a>";
+  return "<a href=\"$ScriptName" . &ScriptLinkChar() . "$action\">" . &RecodeOutput($text) . "</a>";
 }
 
 sub ScriptLinkClass {
   my ($action, $text, $class) = @_;
 
   return "<a href=\"$ScriptName" . &ScriptLinkChar() . "$action\""
-         . ' class=' . $class . ">$text</a>";
+         . ' class=' . $class . ">" . &RecodeOutput($text) . "</a>";
 }
 
 sub GetPageLinkText {
@@ -1190,7 +1231,7 @@
   if ($EditNameLink) {
     return &GetEditLink($id, $name);
   } else {
-    return $name . &GetEditLink($id, '?');
+    return &RecodeOutput($name) . &GetEditLink($id, '?');
   }
 }
 
@@ -1219,6 +1260,14 @@
   return &ScriptLink("action=random", T('Random Page'));
 }
 
+sub GetRecodeLink {
+  if(&GetParam("recodetext", 1)) {
+    return &ScriptLink("action=norecode", T('Use X-System'));
+  } else {
+    return &ScriptLink("action=recode", T('Use Unicode'));
+  }
+}
+
 sub ScriptLinkDiff {
   my ($diff, $id, $text, $rev) = @_;
 
@@ -1244,9 +1293,10 @@
 
   if ($FreeLinks) {
     $action =~ s/ /_/g;
+    $action =~ s/([\x80-\xff])/sprintf("%%%02X",ord($1))/ge; # URL encode high chars
   }
   return "<a href=\"$ScriptName" . &ScriptLinkChar()
-         . "$action\" title=\"$title\">$text</a>";
+         . "$action\" title=\"$title\">" . &RecodeOutput($text) . "</a>";
 }
 
 sub GetAuthorLink {
@@ -1309,7 +1359,7 @@
   if ($id ne '') {
     $result .= $q->h1($header . &GetBackLinksSearchLink($id));
   } else {
-    $result .= $q->h1($header . $title);
+    $result .= $q->h1($header . &RecodeOutput($title));
   }
   if (&GetParam("toplinkbar", 1)) {
     $result .= &GetGotoBar($id) . "<hr class=wikilineheader>";
@@ -1490,6 +1540,7 @@
   if ($UserGotoBar ne '') {
     $bartext .= " | " . $UserGotoBar;
   }
+  $bartext .= " | " . &GetRecodeLink();
   $bartext .= "<br>\n";
   return $bartext;
 }
@@ -1595,6 +1646,11 @@
   if ($LateRules ne '') {
     $pageText = &EvalLocalRules($LateRules, $pageText, 0);
   }
+  # Unicodize
+  if(&GetParam("recodetext", 1)) {
+    # This *should* change only text that's not inside a <tag>
+    $pageText =~ s/(^|>)((.|\n)*?)(<|$)/$1.&RecodeOutput($2).$4/ige;
+  }
   return &RestoreSavedText($pageText);
 }
 
@@ -3128,6 +3184,10 @@
       &DoConvert();
     } elsif ($action eq "trimusers") {
       &DoTrimUsers();
+    } elsif ($action eq "recode") {
+      &DoRecode(1);

+    } elsif ($action eq "norecode") {
+      &DoRecode(0);
     } else {
       &ReportError(Ts('Invalid action parameter %s', $action));
     }
@@ -3321,6 +3381,33 @@
                       -wrap=>'virtual');
 }
 
+sub DoRecode {
+  my ($recode) = @_;
+
+  &DoNewLogin()  if ($UserID < 400);
+
+  $UserData{"recodetext"} = 1  if ($recode);
+  $UserData{"recodetext"} = 0  if (!$recode);
+
+  print &GetHeader('',T('Saving Preferences'), '');
+  print '<br>';
+  if ($UserID < 1001) {
+    print '<b>',
+          Ts('Invalid UserID %s, preferences not saved.', $UserID), '</b>';
+    if ($UserID == 111) {
+      print '<br>',
+            T('(Preferences require cookies, but no cookie was sent.)');
+    }
+    print &GetCommonFooter();
+    return;
+  }
+
+  &SaveUserData();
+  print '<b>', T('Preferences saved.'), '</b>';
+  print '<p><a href="', $ENV{HTTP_REFERER}, '">', T('Return to previous page.'), '</a></p>';
+  print &GetCommonFooter();
+}
+
 sub DoEditPrefs {
   my ($check, $recentName, %labels);
 
@@ -3374,11 +3461,11 @@
   if ($UseDiff) {
     print '<hr class=wikilinepref><b>', T('Differences:'), "</b>\n";
     print "<br>", &GetFormCheck('diffrclink', 1,
-                                Ts('Show (diff) links on %s', $recentName));
+                                Ts('Show (diff) links on %s', &RecodeOutput($recentName)));
     print "<br>", &GetFormCheck('alldiff', 0,
                                 T('Show differences on all pages'));
     print "  (",  &GetFormCheck('norcdiff', 1,
-                                Ts('No differences on %s', $recentName)), ")";
+                                Ts('No differences on %s', &RecodeOutput($recentName))), ")";
     %labels = (1=>T('Major'), 2=>T('Minor'), 3=>T('Author'));
     print '<br>', T('Default difference type:'), ' ';
     print $q->popup_menu(-name=>'p_defaultdiff',
@@ -3402,6 +3489,8 @@
                               T('Add "Random Page" link to link bar'));
   print '<br>' . T('StyleSheet URL:') . ' ',
         &GetFormText('stylesheet', "", 30, 150);
+  print '<br>', &GetFormCheck('recodetext', 1,
+  			      T('Show supersigns in Unicode'));
   print '<br>', $q->submit(-name=>'Save', -value=>T('Save')), "\n";
   print '</div>';
   print "<hr class=wikilinefooter>\n";
@@ -3434,6 +3523,7 @@
   # All link bar settings should be updated before printing the header
   &UpdatePrefCheckbox("toplinkbar");
   &UpdatePrefCheckbox("linkrandom");
+  &UpdatePrefCheckbox("recodetext");
   print &GetHeader('',T('Saving Preferences'), '');
   print '<br>';
   if ($UserID < 1001) {
@@ -3446,7 +3536,7 @@
     print &GetCommonFooter();
     return;
   }
-  $username = &GetParam("p_username",  "");
+  $username = &RecodeInput(&GetParam("p_username",  ""));
   if ($FreeLinks) {
     $username =~ s/^\[\[(.+)\]\]/$1/;  # Remove [[ and ]] if added
     $username =  &FreeToNormal($username);
@@ -3456,13 +3546,13 @@
     print T('UserName removed.'), '<br>';
     undef $UserData{'username'};
   } elsif ((!$FreeLinks) && (!($username =~ /^$LinkPattern$/))) {
-    print Ts('Invalid UserName %s: not saved.', $username), "<br>\n";
+    print Ts('Invalid UserName %s: not saved.', &RecodeOutput($username)), "<br>\n";
   } elsif ($FreeLinks && (!($username =~ /^$FreeLinkPattern$/))) {
-    print Ts('Invalid UserName %s: not saved.', $username), "<br>\n";
+    print Ts('Invalid UserName %s: not saved.', &RecodeOutput($username)), "<br>\n";
   } elsif (length($username) > 50) {  # Too long
     print T('UserName must be 50 characters or less. (not saved)'), "<br>\n";
   } else {
-    print Ts('UserName %s saved.', $username), '<br>';
+    print Ts('UserName %s saved.', &RecodeOutput($username)), '<br>';
     $UserData{'username'} = $username;
   }
   $password = &GetParam("p_password",  "");
@@ -3711,7 +3801,8 @@
 }
 
 sub DoSearch {
-  my ($string) = @_;
+  # Unicode strings need to be converted to X-system for searching
+  my ($string) = &RecodeInput(@_);
 
   if ($string eq '') {
     &DoIndex();
@@ -3887,9 +3978,9 @@
 
 sub DoPost {
   my ($editDiff, $old, $newAuthor, $pgtime, $oldrev, $preview, $user);
-  my $string = &GetParam("text", undef);
+  my $string = &RecodeInput(&GetParam("text", undef));
   my $id = &GetParam("title", "");
-  my $summary = &GetParam("summary", "");
+  my $summary = &RecodeInput(&GetParam("summary", ""));
   my $oldtime = &GetParam("oldtime", "");
   my $oldconflict = &GetParam("oldconflict", "");
   my $isEdit = 0;

UseModWiki | WikiPatches | RecentChanges | Preferences
Edit text of this page | View other revisions | Search MetaWiki
Last edited December 10, 2020 7:24 pm by MarkusLude (diff)
Search: