using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Text; using System.Threading.Tasks; namespace RuriLib.LS { /// /// Provides useful functions for writing a block as a piece of LoliScript code. /// public class BlockWriter : StringWriter { private bool Indented { get; set; } private Type Type { get; set; } private object Block { get; set; } private bool Disabled { get; set; } /// /// Creates a new BlockWriter for the given block type and with the given settings. /// /// The Type of the block to write /// Whether the code can be indented on multiple lines for readability /// Whether the block to write is disabled public BlockWriter(Type blockType, bool indented = true, bool disabled = false) { Type = blockType; Block = Activator.CreateInstance(blockType); Indented = indented; Disabled = disabled; if (Disabled) Write("!"); } /// /// Writes any type of variable as a token (by calling its default ToString method) and a space. /// /// The variable to write /// The name of the property of the block. If the value is the default one, it will not be written. Do not set this parameter to always write the variable. /// The BlockWriter itself public BlockWriter Token(dynamic token, string property = "") { if (property != "" && CheckDefault(token, property)) return this; Write($"{token.ToString()} "); return this; } /// /// Writes an integer value and a space. /// /// The integer value to write /// The name of the property of the block. If the value is the default one, it will not be written. Do not set this parameter to always write the variable. /// The BlockWriter itself public BlockWriter Integer(int integer, string property = "") { if (property != "" && CheckDefault(integer, property)) return this; Write($"{integer} "); return this; } /// /// Writes a literal value (with escaped double-quotes) wrapped by double-quotes and a space. /// /// The literal value to write /// The name of the property of the block. If the value is the default one, it will not be written. Do not set this parameter to always write the variable. /// The BlockWriter itself public BlockWriter Literal(string literal, string property = "") { if (property != "" && CheckDefault(literal, property)) return this; Write($"\"{literal.Replace("\\", "\\\\").Replace("\"", "\\\"")}\" "); return this; } /// /// Writes an Arrow (->) and a space. /// /// The BlockWriter itself public BlockWriter Arrow() { Write("-> "); return this; } /// /// Writes a block label as a # sign, the label name and a space. /// /// The label of the block /// The BlockWriter itself public BlockWriter Label(string label) { if (CheckDefault(label, "Label")) return this; Write($"#{label.Replace(" ", "_")} "); return this; } /// /// Writes a boolean with the syntax Name=Value and a space. /// /// The boolean value to write /// The name of the property /// public BlockWriter Boolean(bool boolean, string property) { if (property != "" && CheckDefault(boolean, property)) return this; Write($"{property}={boolean.ToString().ToUpper()} "); return this; } /// /// Writes a linebreak and a given number of spaces on the next line. /// /// The amount of spacing to perform. A spacing of value 1 means two blank space characters, 2 means 4 etc. /// public BlockWriter Indent(int spacing = 1) { if (Indented) { WriteLine(); if (Disabled) Write("!"); for (var i = 0; i < spacing; i++) Write(" "); } return this; } /// /// Writes a linebreak. /// /// public BlockWriter Return() { WriteLine(); return this; } /// /// Checks if a property has the default value. /// /// The value that needs to be checked /// The name of the property that contains that value /// Whether the property has the default value or not public bool CheckDefault(object value, string property) { var prop = Type.GetProperty(property); var val = prop.GetValue(Block); return value.Equals(val); } } }