public void ExportTo(string directory, Topic root, Func<Topic, string> pathing) { var fileSystem = new FileSystem(); string sourceContent = _settings.Root.AppendPath("content"); if (fileSystem.DirectoryExists(sourceContent)) { fileSystem.CopyToDirectory(sourceContent, directory.AppendPath("content")); } root.AllTopicsInOrder().Each(topic => { var path = pathing(topic); var parentDirectory = path.ParentUrl(); if (parentDirectory.IsNotEmpty()) { fileSystem.CreateDirectory(directory.AppendPath(parentDirectory)); } var text = _generator.Generate(topic); // Hoakum topic.Substitutions.Each((key, value) => { text = text.Replace(key, value); }); fileSystem.WriteStringToFile(directory.AppendPath(path), text); }); }
public TableOfContentsTag(Topic root, IUrlResolver resolver) : base("ul") { AddClass("table-of-contents"); writeChildNodes(root, root, this, resolver); }
public static void WriteToFiles(string directory, Topic topLevel) { if (!FileSystem.DirectoryExists(directory)) { FileSystem.CreateDirectory(directory); } var file = directory.AppendPath("index.md"); WriteTopicFile(file, topLevel); WriteOrderFile(directory, topLevel); topLevel.Children.Each(child => { var key = child.KeyWithinParent; if (child.Children.Any()) { WriteToFiles(directory.AppendPath(key), child); } else { var childFile = directory.AppendPath(key + ".md"); WriteTopicFile(childFile, child); } }); }
public string Generate(Topic topic) { if (topic.IsSplashPage()) { return _transformer.Transform(topic, new FileSystem().ReadStringFromFile(topic.File)); } try { return generate(topic); } catch (Exception e) { ConsoleWriter.Write(ConsoleColor.Yellow, "Failed to transform topic at " + topic.File); ConsoleWriter.Write(ConsoleColor.Red, e.ToString()); var document = new HtmlDocument { Title = "Error!" }; document.Add("h1").Text("Error!"); document.Add("pre").Text(e.ToString()); return document.ToString(); } }
public IGrammar TheTopicsAre() { return this["BuildTopic"].AsTable("The topics in this directory are") .After(() => { _top = TopicLoader.LoadDirectory(_directory); _top.ParseAndOrder().Wait(); }); }
public string Transform(Topic current, string data) { var parts = data.Split('/'); var app = parts.First(); var command = parts.Last(); var report = _cache.ReportFor(app, command); return new CommandSectionTag(app, report).ToString(); }
public string Transform(Topic current, string data) { var parts = data.Split('/'); var app = parts.First(); var command = parts.Last(); var report = _cache.ReportFor(app, command); return CommandBodyTags(app, report).Select(x => x.ToString()).Join(""); }
public string Transform(Topic current, string data) { var url = _urls.ToUrl(current, data); return new HtmlTag("link") .Attr("href", url) .Attr("rel", "stylesheet") .Attr("type", "text/css") .ToString(); }
public string Transform(Topic current, string data) { var tag = TagForSample(data); var subject = "<p>" + Guid.NewGuid().ToString() + "</p>"; current.Substitutions[subject] = tag.ToString(); return subject; }
public string Transform(Topic current, string data) { var specData = _specData.DataForPath(data); return new HtmlTag("p") .Attr("data-path", data) .Attr("data-spec", JsonSerialization.ToCleanJson(specData.Specification)) .Attr("data-fixtures", JsonSerialization.ToCleanJson(specData.Fixtures)) .Attr("data-results", JsonSerialization.ToCleanJson(specData.Results.Results)) .AddClass("spec-result").ToString(); }
public static void WriteOrderFile(string directory, Topic parent) { FileSystem.AlterFlatFile(directory.AppendPath("order.txt"), list => { list.Clear(); parent.Children.Each(child => { var key = child.KeyWithinParent; list.Add(key); }); }); }
public string Transform(Topic current, string data) { var ol = new HtmlTag("ol").AddClass("breadcrumb"); current.Ancestors().Each(x => { ol.Add("li/a").Attr("href", _resolver.ToUrl(current, x)).Text(x.Title); }); ol.Add("li").AddClass("active").Text(current.Title); return ol.ToString(); }
private void readTopic(string line, LightweightCache<string, Topic> cache) { var parts = line.Split(':'); var key = parts[0]; var title = parts.Length > 1 ? parts[1] : key.Split('/').Last().Capitalize(); if (key.Contains("/")) { var parentKey = key.ParentUrl(); var parent = cache[parentKey]; key = key.Split('/').Last(); var urlSegment = parts.Length == 3 ? parts[2] : key; var topic = new Topic(key, "") { Title = title, UrlSegment = urlSegment }; parent.AddChild(topic); cache[topic.Key] = topic; } else if (_top == null) { _top = new Topic("index", "") { Title = title, UrlSegment = "" }; } else { var urlSegment = parts.Length == 3 ? parts[2] : key; var topic = new Topic(key, "") { Title = title, UrlSegment = urlSegment }; _top.AddChild(topic); cache[topic.Key] = topic; } }
public string Transform(Topic current, string data) { var text = TopicLoader.FileSystem.ReadStringFromFile(current.File); text = _transformer.Transform(current, text); if (Path.GetExtension(current.File) == ".md") { text = ToHtml(text); } return text; }
public static Topic LoadTopic(string file, bool isRoot) { Debug.WriteLine("Loading topic file " + file.ToFullPath()); if (!File.Exists(file)) { throw new FileNotFoundException("No topic file", file); } var key = Path.GetFileNameWithoutExtension(file).EqualsIgnoreCase("splash") ? "index" : Path.GetFileNameWithoutExtension(file); var topic = new Topic(key.ToLower(), file); return topic; }
private void writeChildNodes(Topic root, Topic parent, HtmlTag tag, IUrlResolver resolver) { parent.Children.Each(childTopic => { var li = tag.Add("li"); li.Add("a").Attr("href", resolver.ToUrl(root, childTopic)).Text(childTopic.Title); if (childTopic.Children.Any()) { var ul = li.Add("ul"); writeChildNodes(root, childTopic, ul, resolver); } }); }
public string GenerateHtml(Topic topic) { var html = _generator.Generate(topic); var builder = new StringBuilder(html); topic.Substitutions.Each((key, value) => { builder.Replace(key, value); }); var script = _webSocketScript.Replace("%WEB_SOCKET_ADDRESS%", _settings.WebsocketAddress); builder.Replace("</head>", script + "\n</head>"); var tag = new HtmlTag("script").Attr("language", "javascript").Attr("src", "/topics.js"); builder.Replace("</head>", tag.ToString() + "\n</head>"); return builder.ToString(); }
public static IEnumerable<TodoTask> ReadTasks(Topic topic) { var i = 0; var regex = @"TODO\((.*?)\)"; using (var stream = new FileStream(topic.File, FileMode.Open)) { using (StreamReader streamReader = new StreamReader(stream)) { string text; while ((text = streamReader.ReadLine()) != null) { i++; if (text.Contains("TODO")) { var matches = Regex.Matches(text, regex); foreach (Match match in matches) { var message = match.Groups[1].Value.Trim(); yield return new TodoTask { File = topic.File, Key = topic.Key, Line = i, Message = message }; } if (matches.Count == 0) { var index = text.IndexOf("TODO"); var message = text.Substring(index + 4).Trim(); yield return new TodoTask { File = topic.File, Key = topic.Key, Line = i, Message = message }; } } } } } }
private string generate(Topic topic) { try { var template = readTemplate(); return _transformer.Transform(topic, template); } catch (Exception) { Thread.Sleep(100); // One retry because of over-eager file locking var template = readTemplate(); return _transformer.Transform(topic, template); } }
private string transformFromTopic(Topic current, Topic other, string[] props) { var url = _urls.ToUrl(current, other); var title = other.Title; var template = Template; for (int i = 1; i < props.Length; i++) { if (props[i].StartsWith("title=", StringComparison.Ordinal)) { title = props[i].Split('=').Last().Trim(); } else { template = props[i]; } } return template.Replace("{href}", url).Replace("{title}", title); }
private Topic findOther(Topic current, string key) { if (key.EqualsIgnoreCase("{next}")) { return current.FindNext(); } if (key.EqualsIgnoreCase("{previous}")) { return current.FindPrevious(); } var corrected = ToAbsoluteKey(current.Key, key); var topic = _top.FindByKey(corrected); if (topic == null) { throw new ArgumentOutOfRangeException(nameof(key), $"Cannot find a topic with key '{corrected}'"); } return topic; }
public string Transform(Topic current, string data) { var parts = data.Split(';'); var url = _urls.ToUrl(current, parts.First()); var image = new HtmlTag("img").Attr("src", url).Style("max-width", "100%"); if (parts.Length == 0) { return image.ToString(); } var header = new HtmlTag("h5", x => { x.Add("strong").Text(parts.Last()); }); return header.ToString() + image.ToString(); }
public string Transform(Topic current, string data) { var props = data.Split(';'); var key = props.First(); try { var other = findOther(current, key); if (other == null) return string.Empty; return transformFromTopic(current, other, props); } catch (ArgumentOutOfRangeException) { var tag = new HtmlTag("p").AddClass("bg-warning").Style("padding", "5px"); tag.Add("b").Text($"Unknown topic key '{key}'"); tag.Add("small").Text(" -- CTRL+SHIFT+R to force refresh the topic tree"); return tag.ToString(); } }
public static void WriteTopicFile(string file, Topic topic) { if (!File.Exists(file)) { Console.WriteLine("Writing topic file " + file); new FileSystem().WriteToFlatFile(file, writer => { writer.WriteLine("<!--Title:{0}-->".ToFormat(topic.Title)); if (topic.HasExplicitUrl()) { writer.WriteLine("<!--Url:{0}-->".ToFormat(topic.UrlSegment)); } writer.WriteLine(""); writer.WriteLine("TODO(WriteToText some content!)"); }); } else { Console.WriteLine("Found {0} and will not overwrite", file); } }
public string Transform(Topic current, string before) { var tokens = Token.FindTokens(before).ToArray(); if (!tokens.Any()) return before; var builder = new StringBuilder(); var position = 0; tokens.Each(token => { if (token.FirstIndex > position) builder.Append(before.Substring(position, token.FirstIndex - position)); var handler = _handlers[token.Key]; builder.Append(handler.Transform(current, token.Data)); position = token.LastIndex + 1; }); if (position < before.Length) builder.Append(before.Substring(position)); return builder.ToString(); }
public string Transform(Topic current, string data) { return _urls.RootUrlFrom(current); }
public string Transform(Topic current, string data) { var url = _resolver.ToUrl(current, data); return url; }
public string ToUrl(Topic current, Topic topic) { return current.FileExportPath().RelativeUrlTo(topic.FileExportPath()); }
public string RootUrlFrom(Topic current) { return current.FileExportPath().RelativeUrlTo("index.htm"); }
public string ToUrl(Topic current, string url) { return current.FileExportPath().RelativeUrlTo(url); }