using System; using System.Collections.Generic; using System.Text; using System.Text.RegularExpressions; namespace ScrewTurn.Wiki.ImportWiki { /// /// Implements a translator tool for importing MediaWiki data. /// public class Translator : ScrewTurn.Wiki.ImportWiki.ITranslator { private Regex noWiki = new Regex(@"(.|\n|\r)*?", RegexOptions.Compiled | RegexOptions.IgnoreCase); /// /// Executes the translation. /// /// The input content. /// The WikiMarkup. public string Translate(string input) { StringBuilder sb = new StringBuilder(); sb.Append(input); Regex firsttitle = new Regex(@"(\={2,5}).+?\1"); Regex doubleSquare = new Regex(@"\[{2}.+?\]{2}"); Regex exlink = new Regex(@"(\[(\w+):\/\/([^\]]+)\])|(?\w+):\/\/(?[\w.]+\/?)\S*)(?!\"")"); Regex mailto = new Regex(@"(\[mailto\:([\w\d\.\@]+)\])|(?((.|\n|\r)*?)?"); Regex newlinespace = new Regex(@"^\ .+", RegexOptions.Multiline); Regex transclusion = new Regex(@"(\{{2})(.|\n)+?(\}{2})"); Regex math = new Regex(@"(.|\n|\r)*?"); Regex references = new Regex(@"(.|\n|\r)*?"); Regex references1 = new Regex(@"\"); Regex redirect = new Regex(@"\#REDIRECT\ \[{2}.+\]{2}"); Match match; List noWikiBegin = new List(), noWikiEnd = new List(); /*ComputeNoWiki(sb.ToString(), ref noWikiBegin, ref noWikiEnd); if (sb.ToString().Contains("__NOTOC__")) { sb.Remove(sb.ToString().IndexOf("__NOTOC__"), 9); if (sb.ToString().Contains("{{compactTOC}}")) { sb.Remove(sb.ToString().IndexOf("{{compactTOC}}"),14); sb.Insert(sb.ToString().IndexOf("{{compactTOC}}"), "\n{TOC}\n"); } } else { match = firsttitle.Match(sb.ToString()); if(match.Success) sb.Insert(match.Index, "\n{TOC}\n"); }*/ sb.Replace("\r", ""); ComputeNoWiki(sb.ToString(), ref noWikiBegin, ref noWikiEnd); /////////////////////////////////////////////// //////BEGIN of unsupported formatting-tag////// /////////////////////////////////////////////// match = math.Match(sb.ToString()); while(match.Success) { int end; if(IsNoWikied(match.Index, noWikiBegin, noWikiEnd, out end)) { sb.Replace(match.Value, @"<math>" + match.Value.Substring(6, match.Length - 13) + @"</math> "); match = math.Match(sb.ToString()); ComputeNoWiki(sb.ToString(), ref noWikiBegin, ref noWikiEnd); } else match = math.Match(sb.ToString(), end); } match = references.Match(sb.ToString()); while(match.Success) { int end; if(IsNoWikied(match.Index, noWikiBegin, noWikiEnd, out end)) { sb.Replace(match.Value, @"<ref>" + match.Value.Substring(5, match.Length - 11) + @"</ref> "); match = references.Match(sb.ToString()); ComputeNoWiki(sb.ToString(), ref noWikiBegin, ref noWikiEnd); } else match = references.Match(sb.ToString(), end); } match = references1.Match(sb.ToString()); while(match.Success) { int end; if(IsNoWikied(match.Index, noWikiBegin, noWikiEnd, out end)) { sb.Replace(match.Value, @"<references/> "); match = references1.Match(sb.ToString()); ComputeNoWiki(sb.ToString(), ref noWikiBegin, ref noWikiEnd); } else match = references1.Match(sb.ToString(), end); } match = redirect.Match(sb.ToString()); while(match.Success) { int end; if(IsNoWikied(match.Index, noWikiBegin, noWikiEnd, out end)) { sb.Replace(match.Value, @"" + match.Value + @" "); match = redirect.Match(sb.ToString()); ComputeNoWiki(sb.ToString(), ref noWikiBegin, ref noWikiEnd); } else match = redirect.Match(sb.ToString(), end); } match = transclusion.Match(sb.ToString()); while(match.Success) { int end; if(IsNoWikied(match.Index, noWikiBegin, noWikiEnd, out end)) { string s = @"" + match.Value + @" "; sb.Remove(match.Index, match.Length); sb.Insert(match.Index, s); ComputeNoWiki(sb.ToString(), ref noWikiBegin, ref noWikiEnd); match = transclusion.Match(sb.ToString(), match.Index + s.Length); } match = transclusion.Match(sb.ToString(), end); } ////////////////////////////////////////// /////END of unsupported formetter-tag///// ////////////////////////////////////////// match = pre.Match(sb.ToString()); while(match.Success) { int end; if(IsNoWikied(match.Index, noWikiBegin, noWikiEnd, out end)) { string s = "{{{{" + match.Value.Replace("
", "").Replace("
", "") + @"
}}}}"; sb.Replace(match.Value, s); match = pre.Match(sb.ToString(), match.Index + s.Length); ComputeNoWiki(sb.ToString(), ref noWikiBegin, ref noWikiEnd); } else match = pre.Match(sb.ToString(), end); } match = exlink.Match(sb.ToString()); while(match.Success) { int end; if(IsNoWikied(match.Index, noWikiBegin, noWikiEnd, out end)) { if(match.Value[0] == '[') { string[] split = match.Value.Split(new char[] { ' ' }, 2); if(split.Length == 2) { sb.Remove(match.Index, match.Length); sb.Insert(match.Index, split[0] + "|" + split[1]); match = exlink.Match(sb.ToString(), match.Index + match.Length); } else match = exlink.Match(sb.ToString(), match.Index + match.Length); } else { sb.Remove(match.Index, match.Length); sb.Insert(match.Index, "[" + match.Value + "]"); match = exlink.Match(sb.ToString(), match.Index + match.Length + 1); ComputeNoWiki(sb.ToString(), ref noWikiBegin, ref noWikiEnd); } } else match = exlink.Match(sb.ToString(), end); } match = mailto.Match(sb.ToString()); while(match.Success) { int end; if(IsNoWikied(match.Index, noWikiBegin, noWikiEnd, out end)) { string str = match.Value.Replace(@"mailto:", ""); if(str[0] == '[') { string[] split = str.Split(new char[] { ' ' }, 2); if(split.Length == 2) { sb.Remove(match.Index, match.Length); sb.Insert(match.Length, split[0] + "|" + split[1]); } /*else { sb.Remove(match.Index, match.Length); sb.Insert(match.Index, split[0]); }*/ match = mailto.Match(sb.ToString(), match.Index + str.Length); } else { sb.Remove(match.Index, match.Length); sb.Insert(match.Index, "[" + str.Substring(0, str.Length) + "]"); match = mailto.Match(sb.ToString(), match.Index + str.Length + 1); ComputeNoWiki(sb.ToString(), ref noWikiBegin, ref noWikiEnd); } } else match = mailto.Match(sb.ToString(), end); } match = image.Match(sb.ToString()); while(match.Success) { int end; if(IsNoWikied(match.Index, noWikiBegin, noWikiEnd, out end)) { string str = match.Value.Remove(0, 7); str = str.Remove(str.Length - 1); string name = ""; string location = ""; string caption = ""; string[] splits = str.Split(new char[] { '|' }); name = splits[0]; for(int i = 0; i < splits.Length; i++) { if(splits[i] == "right" || splits[i] == "left" || splits[i] == "center" || splits[i] == "none") location = splits[i]; else if(splits[i].Contains("px")) { } else if(splits[i] == "thumb" || splits[i] == "thumbnail" || splits[i] == "frame") { } else caption = splits[i] + "|"; } if(location == "right" || location == "left") { sb.Remove(match.Index, match.Length); sb.Insert(match.Index, "[image" + location + "|" + caption + "{UP}" + name + "]"); } else { sb.Remove(match.Index, match.Length); sb.Insert(match.Index, "[imageauto|" + caption + "{UP}" + name + "]"); } ComputeNoWiki(sb.ToString(), ref noWikiBegin, ref noWikiEnd); } match = image.Match(sb.ToString(), end); } match = doubleSquare.Match(sb.ToString()); while(match.Success) { int end; if(IsNoWikied(match.Index, noWikiBegin, noWikiEnd, out end)) { if(match.Value.Contains(":")) { sb.Remove(match.Index, match.Length); sb.Insert(match.Index, match.Value.Replace(':', '_').Replace("/", "_").Replace(@"\", "_").Replace('?', '_')); } else { sb.Remove(match.Index, match.Length); sb.Insert(match.Index, match.Value.Substring(1, match.Length - 2).Replace("/", "_").Replace(@"\", "_").Replace('?', '_')); } ComputeNoWiki(sb.ToString(), ref noWikiBegin, ref noWikiEnd); } match = doubleSquare.Match(sb.ToString(), end); } bool first = true; match = newlinespace.Match(sb.ToString()); while(match.Success) { int end; if(IsNoWikied(match.Index, noWikiBegin, noWikiEnd, out end)) { string s = ""; if(first) s += "{{{{" + match.Value.Substring(1, match.Value.Length - 1); else s += match.Value.Substring(1, match.Value.Length - 1); if(sb.Length > match.Index + match.Length + 1) { if(sb[match.Index + match.Length] == '\n' && sb[match.Index + match.Length + 1] == ' ') { first = false; } else { s += "}}}}"; first = true; } } else { s += "}}}}"; first = true; } sb.Remove(match.Index, match.Length); sb.Insert(match.Index, s); match = newlinespace.Match(sb.ToString(), match.Index + s.Length); ComputeNoWiki(sb.ToString(), ref noWikiBegin, ref noWikiEnd); } else match = newlinespace.Match(sb.ToString(), end); } return sb.ToString(); } private void ComputeNoWiki(string text, ref List noWikiBegin, ref List noWikiEnd) { Match match; noWikiBegin.Clear(); noWikiEnd.Clear(); match = noWiki.Match(text); while(match.Success) { noWikiBegin.Add(match.Index); noWikiEnd.Add(match.Index + match.Length - 1); match = noWiki.Match(text, match.Index + match.Length); } } private bool IsNoWikied(int index, List noWikiBegin, List noWikiEnd, out int end) { for(int i = 0; i < noWikiBegin.Count; i++) { if(index >= noWikiBegin[i] && index <= noWikiEnd[i]) { end = noWikiEnd[i]; return false; } } end = 0; return true; } } }