Advertisement
SteelGolem

transcluding wikitext templates

Apr 30th, 2015
332
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 5.44 KB | None | 0 0
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using System.IO;
  6.  
  7. namespace sg_wiki_with_templates_testing
  8. {
  9.     class Program
  10.     {
  11.         static void Main(string[] args)
  12.         {
  13.             // TODO: should be using args[0]
  14.             string arg = "wiki entry 1.txt";
  15.  
  16.             string output = LoadWikiFile(arg);
  17.  
  18.             StreamWriter writer = new StreamWriter("output.txt");
  19.             writer.Write(output);
  20.             writer.Flush();
  21.             writer.Close();
  22.         }
  23.  
  24.         private static string LoadWikiFile(string filename)
  25.         {
  26.             StreamReader reader = new StreamReader(filename);
  27.             string input = reader.ReadToEnd();
  28.             reader.Close();
  29.  
  30.             string mangledInput = input;
  31.             while (mangledInput.Contains("}}"))
  32.             {
  33.                 // find and copy innermost nested template string
  34.                 int end = mangledInput.IndexOf("}}");
  35.                 int start = end;
  36.                 end += "}}".Length;
  37.                 while (mangledInput.Substring(start, 2) != "{{")
  38.                     start--;
  39.                 string textToReplace = mangledInput.Substring(start, end - start);
  40.  
  41.                 string templateFilename = "";
  42.  
  43.                 // break template string into arguments lookup
  44.                 string innerText = textToReplace.Substring("{{".Length, textToReplace.Length - "{{}}".Length);
  45.                 string[] argumentValues = innerText.Split(new char[] { '|' });
  46.                 Dictionary<string, string> argumentLookup = new Dictionary<string, string>();
  47.                 for (int a = 0; a < argumentValues.Length; a++)
  48.                 {
  49.                     string[] argumentTokens = argumentValues[a].Split(new char[] { '=' });
  50.                     string argumentName = argumentTokens[0].Trim();
  51.                     string argumentValue = (argumentTokens.Length > 1) ? argumentTokens[1].Trim() : "";
  52.                     argumentLookup.Add(argumentName, argumentValue);
  53.                     argumentValues[a] = argumentValue; // used for indexed variable lookups later
  54.                     if (a == 0) templateFilename = argumentName + ".txt";
  55.                 }
  56.                
  57.                 // read the template file
  58.                 if (!File.Exists(templateFilename))
  59.                     throw new FileNotFoundException("Could not find template '" + templateFilename + "'. Requested from wikitext '" + filename + "'.");
  60.                 reader = new StreamReader(templateFilename);
  61.                 string template = reader.ReadToEnd();
  62.                 reader.Close();
  63.  
  64.                 // block recursion for now
  65.                 // TODO: recursion is dangerous, but will it be useful?
  66.                 if (template.Contains(textToReplace))
  67.                     // TODO: is this how we should handle this?
  68.                     throw new Exception("Template '" + templateFilename + "' contains a reference to itself; recursion is currently being blocked.");
  69.  
  70.                 // replace arguments with values
  71.                 string mangledTemplate = template;
  72.                 // NOTE: we don't need to worry about nested arguments
  73.                 while (mangledTemplate.Contains("{{{"))
  74.                 {
  75.                     // find next argument
  76.                     start = mangledTemplate.IndexOf("{{{");
  77.                     end = mangledTemplate.IndexOf("}}}", start) + "}}}".Length;
  78.                     string argTextToReplace = mangledTemplate.Substring(start, end - start);
  79.  
  80.                     string argInnerText = argTextToReplace.Substring("{{{".Length, argTextToReplace.Length - "{{{}}}".Length).Trim();
  81.  
  82.                     // TODO: "magic words"
  83.                     string replaceArgWith = "";
  84.                     // see if it's an indexed variable, eg: {{{1}}}
  85.                     int argIndex = -1;
  86.                     if (int.TryParse(argInnerText, out argIndex))
  87.                     {
  88.                         if (argIndex > 0 && argIndex < argumentLookup.Keys.Count)
  89.                             replaceArgWith = argumentValues[argIndex];
  90.                     }
  91.                     else // it's a named variable, eg: {{{n}}}
  92.                     {
  93.                         if (argumentLookup.ContainsKey(argInnerText))
  94.                             replaceArgWith = argumentLookup[argInnerText];
  95.                     }
  96.  
  97.                     // replace the argument string with the result
  98.                     mangledTemplate = mangledTemplate.Replace(argTextToReplace, replaceArgWith);
  99.                 }
  100.  
  101.                 // finish transcluding with processed template
  102.                 mangledInput = mangledInput.Replace(textToReplace, mangledTemplate);
  103.             }
  104.  
  105.             return mangledInput;
  106.         }
  107.     }
  108. }
  109.  
  110. /*
  111.  * wiki entry 1.txt
  112.  *
  113.         some text before template
  114.  
  115.         {{wiki template 1 | arg1 = foo | arg2 = bar | arg3 }}
  116.  
  117.         some text after template
  118.  */
  119.  
  120. /*
  121.  * wiki template 1.txt
  122.  *
  123.         start of template 1 text
  124.  
  125.         1: {{{1}}}
  126.         2: {{{2}}}
  127.         3: {{{3}}}
  128.  
  129.         arg1: {{{arg1}}}
  130.         arg2: {{{arg2}}}
  131.         arg3: {{{arg3}}}
  132.  
  133.         end of template 1 text
  134.  */
  135.  
  136. /*
  137.  * output.txt
  138.  *
  139.         some text before template
  140.  
  141.         start of template 1 text
  142.  
  143.         1: foo
  144.         2: bar
  145.         3:
  146.  
  147.         arg1: foo
  148.         arg2: bar
  149.         arg3:
  150.  
  151.         end of template 1 text
  152.  
  153.         some text after template
  154.  */
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement