private static Section GetIntroSection() { //Add the first section (the introduction one) var introSec = new Section("DocumentMaker example"); //Load and modify the first paragraph string par1 = "Welcome to this example of a document rendered using DocumentMaker C# library"; par1 = TextFormat.ReplaceItalic(par1, "DocumentMaker"); introSec.AddParagraph(par1); introSec.AddHr(); //The second paragraph is loaded from a txt file because it is always the same //and it is quite long introSec.AddParagraph(new FileInfo(INTRO_SECONDPARAGRAPH_FILE)); //Now let's create the subsection "About the author", of heading level 2 var aboutSec = new Section("About the author", 2); introSec.AddSection(aboutSec); //appending this subsection to the first one //Adding the paragraph, changing a substring in italic aboutSec.AddParagraph(TextFormat.ReplaceItalic(File.ReadAllText(INTRO_ABOUT_FILE), "DocumentMaker")); //The dot list with contact info will be manually assembled var contactInfos = new DotList(); contactInfos.AddItem("Github profile: " + new DocLink("https://github.com/PaoloCattaneo92", "Github").Render()); //custom text contactInfos.AddItem("Mail: " + new MailToLink("*****@*****.**").Render()); //this is used to correctly renders mailto addresses contactInfos.AddItem("Linkedin profile: " + new DocLink("https://www.linkedin.com/in/paolo-cattaneo-eng/", "Linkedin").Render()); //Appending the dot list to the about section aboutSec.Add(contactInfos); return(introSec); }
private DotExpression ReadAhead(string token) { switch (token) { case "(": CurColumn += 1; var l = new DotList() { Line = CurLine, Column = CurColumn, Expressions = new LinkedList <DotExpression>() }; while (true) { token = NextToken(); if (token == ")") { CurColumn += 1; return(l); } l.Expressions.AddLast(ReadAhead(token)); } case ")": CurColumn += 1; ParserErrors.Add(new ParserError() { Line = CurLine, Column = CurColumn, Message = "Unexpected ')'!" }); token = NextToken(); return(ReadAhead(token)); } if (_quotes.ContainsKey(token)) { // convert to real expression var keyword = _quotes[token]; var exps = new LinkedList <DotExpression>(); exps.AddLast(new DotSymbol(keyword, CurLine, CurColumn)); exps.AddLast(Read().AST); return(new DotList { Line = CurLine, Column = CurColumn, Expressions = exps }); } var ret = ParseAtom(token, CurLine, CurColumn); CurColumn += token.Length; return(ret); }
private List <T> ExtractTypes <T>(DotList l) where T : DotExpression { var ret = new List <T>(); foreach (var exp in l.Expressions) { if (exp is T s) { ret.Add(s); } if (exp is DotList innerList) { ret.AddRange(ExtractTypes <T>(innerList)); } } return(ret); }
public static DotExpression Expand(DotExpression expression, bool topLevel = false) { if (!(expression is DotList l)) { // constants can't be expanded return(expression); } if (l.Expressions.Count == 0) { throw new ParserException( "An empty list needs to be quoted!", l.Line, l.Column); } var args = l.Expressions.Skip(1).ToList(); // if (!(l.Expressions.First() is DotSymbol op)) // { // throw new EvaluatorException( // "Function or special form expected!"); // } if (l.Expressions.First() is DotSymbol op) { if (op.Name == "quote") { return(expression); } // TODO Find a generic way to check function and procedure argument length and type if (op.Name == "def" || op.Name == "defmacro") { if (args.Count != 2) { throw new ParserException("name and body expected!", op.Line, op.Column); } var defBody = Expand(args.ElementAt(1)); if (op.Name == "defmacro") { if (!topLevel) { throw new ParserException( "'defmacro' only allowed at top level!", op.Line, op.Column); } var procedure = Evaluator.Eval(defBody); if (!(procedure is DotProcedure dp)) { throw new ParserException( "A macro must be a procedure", op.Line, op.Column); } // Add macro GlobalEnvironment.MacroTable.Add( (args.ElementAt(0) as DotSymbol).Name, dp ); return(DotBool.True()); } var expandedDefinition = new LinkedList <DotExpression>(); expandedDefinition.AddLast(op); expandedDefinition.AddLast(args.First()); expandedDefinition.AddLast(defBody); return(new DotList() { Expressions = expandedDefinition }); } if (op.Name == "quasiquote") { return(ExpandQuasiquote(args.First())); } if (GlobalEnvironment.MacroTable.ContainsKey(op.Name)) { // call macro var macro = GlobalEnvironment.MacroTable[op.Name]; var macroArgs = new DotList() { Expressions = args.ToLinkedList() }; return(Expand(macro.Call(macroArgs), topLevel)); } } l.Expressions = l.Expressions .Select(exp => Expand(exp, false)) .ToLinkedList(); return(l); }