private static void Format(TextWriter writer, string template, TextReader reader, Options options, Converter<string, Uri> wikiWordResolver) { Debug.Assert(writer != null); Debug.Assert(template != null); Debug.Assert(reader != null); Debug.Assert(options != null); WikiParser parser = new WikiParser(); parser.WikiWordResolver = wikiWordResolver; NameValueCollection headers = new NameValueCollection(); IEnumerable<WikiToken> tokens = parser.Parse(reader, headers); foreach (string key in headers) options.Variables.Add(key, headers[key]); string bodyName = MaskEmpty(options.BodyName, "body"); char[] buffer = template.ToCharArray(); int index = 0; foreach (Match match in Regex.Matches(template, MaskEmpty(options.NamePattern, "$([A-Za-z_]+)"), RegexOptions.CultureInvariant)) { writer.Write(buffer, index, match.Index - index); string key = match.Groups[1].Value; if (string.CompareOrdinal(key, bodyName) == 0) { HtmlFormatter formatter = new HtmlFormatter(); formatter.Format(tokens, new XhtmlTextWriter(writer, " ")); } else { // TODO: Add URL-encoding support HttpUtility.HtmlEncode(options.FindVariable(key, key + "?"), writer); } index = match.Index + match.Length; } writer.Write(buffer, index, buffer.Length - index); }
private static void Run(Options options, IEnumerable<string> args) { Debug.Assert(options != null); Debug.Assert(args != null); if (options.TemplatePath.Length == 0) throw new ApplicationException("Missing HTML template file path."); TextReader reader = null; TextWriter writer = null; Converter<string, Uri> wikiWordResolver = null; IEnumerator<string> arg = args.GetEnumerator(); try { string wikiPath = null; string wikiExtension = null; string htmlExtension = null; if (arg.MoveNext()) { string sourcePath = arg.Current; if (sourcePath != "-") { options.Variables["title"] = options.FindVariable("title", Path.GetFileNameWithoutExtension(sourcePath)); wikiPath = Path.GetDirectoryName(sourcePath); wikiExtension = Path.GetExtension(sourcePath); reader = File.OpenText(sourcePath); } } if (arg.MoveNext()) { string targetPath = arg.Current; if (targetPath != "-") { writer = File.CreateText(targetPath); htmlExtension = Path.GetExtension(targetPath); } } wikiPath = Mask.EmptyString(wikiPath, Environment.CurrentDirectory); wikiExtension = wikiExtension ?? ".wiki"; htmlExtension = htmlExtension ?? ".html"; wikiWordResolver = delegate(string word) { string filename = word + Mask.EmptyString(htmlExtension, ".html"); if (File.Exists(Path.Combine(wikiPath, filename))) return new Uri(filename, UriKind.Relative); if (File.Exists(Path.Combine(wikiPath, word + wikiExtension))) return new Uri(filename, UriKind.Relative); return null; }; Format(writer ?? Console.Out, File.ReadAllText(options.TemplatePath), reader ?? Console.In, options, wikiWordResolver); } finally { if (reader != null) reader.Close(); if (writer != null) writer.Close(); } }