diff --git a/KindleBookHelper.Core/Book.cs b/KindleBookHelper.Core/Book.cs index bfdce6a..cdd0f3d 100644 --- a/KindleBookHelper.Core/Book.cs +++ b/KindleBookHelper.Core/Book.cs @@ -1,6 +1,6 @@ /* KindleBookHelper - Converts raw text file to html format that can be consumed by KindleGen. - Copyright (C) 2016 Peter Wetzel + Copyright (C) 2018 Peter Wetzel This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -15,18 +15,16 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the You should have received a copy of the GNU General Public License along with this program. If not, see . */ +using Newtonsoft.Json; +using Serilog; using System; using System.Collections.Generic; -using System.IO; -using System.Reflection; -using Newtonsoft.Json; -using Nustache.Core; namespace KindleBookHelper.Core { public class Book { - public const string EndPlaceholder = "[END]"; + public const string DefaultEndPlaceholder = "[END]"; public string RawFilePath { get; set; } public string Title { get; set; } @@ -55,79 +53,33 @@ public class Book [JsonIgnore] public int Copyright { get { return DateTime.Now.Year; } } - private readonly Assembly _assembly; - - public Book() - { - _assembly = Assembly.GetExecutingAssembly(); - } + [JsonIgnore] + public string EndPlaceholder { get; set; } - public static Book Initialize(string sJsonFilePath) - { - var book = JsonConvert.DeserializeObject(File.ReadAllText(sJsonFilePath)); - if (book.Id == Guid.Empty) - { - book.Id = Guid.NewGuid(); - File.WriteAllText(sJsonFilePath, JsonConvert.SerializeObject(book, Formatting.Indented)); - } - return book; - } - - public void Process() + public void Parse() { - if (string.IsNullOrWhiteSpace(RawFilePath)) - { - throw new ArgumentException("RawFilePath parameter must be set"); - } - - OriginalText = FileUtilities.LoadTextFile(RawFilePath); - - Parse(); - - if (Poems.Count == 0) + Poems = new List(); + if (string.IsNullOrWhiteSpace(OriginalText)) { - throw new ApplicationException("No poems found in source"); + Log.Error("OriginalText is required"); + return; } - - var sTargetDirectoryPath = Path.GetDirectoryName(RawFilePath); - RenderTemplate(sTargetDirectoryPath, "html"); - RenderTemplate(sTargetDirectoryPath, "ncx"); - RenderTemplate(sTargetDirectoryPath, "opf"); - - var sCssFilePath = Path.Combine(sTargetDirectoryPath, "poetry.css"); - if (!File.Exists(sCssFilePath)) + if (string.IsNullOrWhiteSpace(EndPlaceholder)) { - var sCss = FileUtilities.LoadTextResource(_assembly, "KindleBookHelper.Core.templates.poetry.css"); - FileUtilities.WriteTextFile(sCssFilePath, sCss); + Log.Error("EndPlaceholder is required"); + return; } - } - - private void RenderTemplate(string sTargetDirectoryPath, string sTemplate) - { - var targetFilePath = Path.Combine(sTargetDirectoryPath, $"{TitleFileSafe}.{sTemplate}"); - using (var reader = new StreamReader(_assembly.GetManifestResourceStream($"KindleBookHelper.Core.templates.{sTemplate}.template"))) - { - using (var writer = File.CreateText(targetFilePath)) - { - Render.Template(reader, this, writer); - } - } - } - - public void Parse() - { - Poems = new List(); - int iPos = 0; - while (iPos >= 0 && iPos < OriginalText.Length) + int i = 0; + while (i >= 0 && i < OriginalText.Length) { - int iEndPos = OriginalText.IndexOf(EndPlaceholder, iPos); - if (iEndPos < 0) + int end = OriginalText.IndexOf(EndPlaceholder, i); + if (end < 0) { break; } - string sRawPoem = OriginalText.Substring(iPos, iEndPos - iPos); - Poems.Add(new Poem(sRawPoem)); - iPos = iEndPos + EndPlaceholder.Length; + var poem = OriginalText.Substring(i, end - i); + Poems.Add(new Poem(poem)); + i = end + EndPlaceholder.Length; } } } diff --git a/KindleBookHelper.Core/BookProcessor.cs b/KindleBookHelper.Core/BookProcessor.cs new file mode 100644 index 0000000..4bdef88 --- /dev/null +++ b/KindleBookHelper.Core/BookProcessor.cs @@ -0,0 +1,96 @@ +/* + KindleBookHelper - Converts raw text file to html format that can be consumed by KindleGen. + Copyright (C) 2018 Peter Wetzel + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ +using System; +using System.IO; +using System.Linq; +using System.Reflection; +using Newtonsoft.Json; +using Nustache.Core; +using Serilog; + +namespace KindleBookHelper.Core +{ + public class BookProcessor + { + private readonly string _jsonFilePath; + private readonly string _endPlaceholder; + private readonly Assembly _assembly; + + public BookProcessor(string jsonFilePath, string endPlaceholder = Book.DefaultEndPlaceholder) + { + if (string.IsNullOrWhiteSpace(jsonFilePath)) + { + throw new ArgumentException($"{nameof(jsonFilePath)} parameter must be set"); + } + _jsonFilePath = jsonFilePath; + _endPlaceholder = endPlaceholder; + _assembly = Assembly.GetExecutingAssembly(); + } + + public Book Process() + { + Log.Information("Processing book file {jsonFilePath}", _jsonFilePath); + var book = JsonConvert.DeserializeObject(File.ReadAllText(_jsonFilePath)); + if (book.Id == Guid.Empty) + { + book.Id = Guid.NewGuid(); + Log.Information("Saving new unique Id"); + File.WriteAllText(_jsonFilePath, JsonConvert.SerializeObject(book, Formatting.Indented)); + } + if (string.IsNullOrWhiteSpace(book.RawFilePath)) + { + Log.Error("RawFilePath is required"); + return null; + } + book.EndPlaceholder = _endPlaceholder; + book.OriginalText = FileUtilities.LoadTextFile(book.RawFilePath); + book.Parse(); + if (!book.Poems.Any()) + { + Log.Error("No poems found in source"); + return null; + } + Log.Information("Found {Count} poems", book.Poems.Count); + var targetDirectoryPath = Path.GetDirectoryName(book.RawFilePath); + RenderTemplate(targetDirectoryPath, "html", book); + RenderTemplate(targetDirectoryPath, "ncx", book); + RenderTemplate(targetDirectoryPath, "opf", book); + var cssFilePath = Path.Combine(targetDirectoryPath, "poetry.css"); + if (!File.Exists(cssFilePath)) + { + var css = FileUtilities.LoadTextResource(_assembly, "KindleBookHelper.Core.templates.poetry.css"); + FileUtilities.WriteTextFile(cssFilePath, css); + } + Log.Information("Finished processing book {Title}", book.Title); + return book; + } + + private void RenderTemplate(string targetDirectoryPath, string template, Book book) + { + var targetFilePath = Path.Combine(targetDirectoryPath, $"{book.TitleFileSafe}.{template}"); + Log.Debug("Rendering template {template}", template); + using (var reader = new StreamReader(_assembly.GetManifestResourceStream($"KindleBookHelper.Core.templates.{template}.template"))) + { + using (var writer = File.CreateText(targetFilePath)) + { + Render.Template(reader, book, writer); + } + } + } + } +} \ No newline at end of file diff --git a/KindleBookHelper.Core/FileUtilities.cs b/KindleBookHelper.Core/FileUtilities.cs index 9172751..a2c5c22 100644 --- a/KindleBookHelper.Core/FileUtilities.cs +++ b/KindleBookHelper.Core/FileUtilities.cs @@ -1,6 +1,6 @@ /* KindleBookHelper - Converts raw text file to html format that can be consumed by KindleGen. - Copyright (C) 2016 Peter Wetzel + Copyright (C) 2018 Peter Wetzel This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -20,49 +20,47 @@ You should have received a copy of the GNU General Public License namespace KindleBookHelper.Core { - public class FileUtilities + public static class FileUtilities { - private FileUtilities() {} - - public static string LoadTextFile(string sFilePath) + public static string LoadTextFile(string filePath) { - string sReturn = ""; - using (StreamReader sr = File.OpenText(sFilePath)) + var data = ""; + using (StreamReader sr = File.OpenText(filePath)) { - sReturn = sr.ReadToEnd(); + data = sr.ReadToEnd(); sr.DiscardBufferedData(); sr.Close(); } - return sReturn; + return data; } - public static string LoadTextResource(Assembly assembly, string sResourceName) + public static string LoadTextResource(Assembly assembly, string resourceName) { - string sReturn = ""; - using (var sr = new StreamReader(assembly.GetManifestResourceStream(sResourceName))) + var data = ""; + using (var sr = new StreamReader(assembly.GetManifestResourceStream(resourceName))) { - sReturn = sr.ReadToEnd(); + data = sr.ReadToEnd(); sr.DiscardBufferedData(); sr.Close(); } - return sReturn; + return data; } - public static void CreateDirectoryIfMissing(string sDirectoryPath) + public static void CreateDirectoryIfMissing(string directoryPath) { - if (!Directory.Exists(sDirectoryPath)) + if (!Directory.Exists(directoryPath)) { - Directory.CreateDirectory(sDirectoryPath); + Directory.CreateDirectory(directoryPath); } } - public static void WriteTextFile(string sFilePath, string sData) + public static void WriteTextFile(string filePath, string data) { - string sDir = Path.GetDirectoryName(sFilePath); - CreateDirectoryIfMissing(sDir); - using (StreamWriter sw = File.CreateText(sFilePath)) + var dirName = Path.GetDirectoryName(filePath); + CreateDirectoryIfMissing(dirName); + using (StreamWriter sw = File.CreateText(filePath)) { - sw.Write(sData); + sw.Write(data); sw.Flush(); sw.Close(); } diff --git a/KindleBookHelper.Core/KindleBookHelper.Core.csproj b/KindleBookHelper.Core/KindleBookHelper.Core.csproj index bac0b11..17e7344 100644 --- a/KindleBookHelper.Core/KindleBookHelper.Core.csproj +++ b/KindleBookHelper.Core/KindleBookHelper.Core.csproj @@ -37,6 +37,9 @@ ..\packages\Nustache.1.16.0.8\lib\net20\Nustache.Core.dll + + ..\packages\Serilog.2.7.1\lib\net46\Serilog.dll + @@ -47,6 +50,7 @@ + diff --git a/KindleBookHelper.Core/Poem.cs b/KindleBookHelper.Core/Poem.cs index 0d41e87..1ba5f71 100644 --- a/KindleBookHelper.Core/Poem.cs +++ b/KindleBookHelper.Core/Poem.cs @@ -1,6 +1,6 @@ /* KindleBookHelper - Converts raw text file to html format that can be consumed by KindleGen. - Copyright (C) 2016 Peter Wetzel + Copyright (C) 2018 Peter Wetzel This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -27,10 +27,10 @@ public class Poem public string TitleUrlSafe { get { return Title.URLFriendly(); } } public List Stanzas { get; set; } - public Poem(string sRaw) + public Poem(string text) { Stanzas = new List(); - List lines = sRaw.Split(new string[] { Environment.NewLine }, StringSplitOptions.None).ToList(); + List lines = text.Split(new string[] { Environment.NewLine }, StringSplitOptions.None).ToList(); // While could do this, still need to account for its location; so, just handling it in full loop //Title = lines.First(x => !string.IsNullOrWhiteSpace(x)); diff --git a/KindleBookHelper.Core/Properties/AssemblyInfo.cs b/KindleBookHelper.Core/Properties/AssemblyInfo.cs index 2ecf15f..16ace7a 100644 --- a/KindleBookHelper.Core/Properties/AssemblyInfo.cs +++ b/KindleBookHelper.Core/Properties/AssemblyInfo.cs @@ -13,5 +13,5 @@ [assembly: ComVisible(false)] [assembly: Guid("3b63a76a-c55e-4cae-84c4-d07a2cbc1afe")] -[assembly: AssemblyVersion("1.4.0.0")] -[assembly: AssemblyFileVersion("1.4.0.0")] \ No newline at end of file +[assembly: AssemblyVersion("2.0.0.0")] +[assembly: AssemblyFileVersion("2.0.0.0")] \ No newline at end of file diff --git a/KindleBookHelper.Core/Stanza.cs b/KindleBookHelper.Core/Stanza.cs index d7006cb..7e60dde 100644 --- a/KindleBookHelper.Core/Stanza.cs +++ b/KindleBookHelper.Core/Stanza.cs @@ -1,6 +1,6 @@ /* KindleBookHelper - Converts raw text file to html format that can be consumed by KindleGen. - Copyright (C) 2016 Peter Wetzel + Copyright (C) 2018 Peter Wetzel This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -22,6 +22,10 @@ namespace KindleBookHelper.Core public class Stanza { public List Lines { get; set; } - public Stanza() { Lines = new List(); } + + public Stanza() + { + Lines = new List(); + } } } \ No newline at end of file diff --git a/KindleBookHelper.Core/packages.config b/KindleBookHelper.Core/packages.config index 403b97f..0679d83 100644 --- a/KindleBookHelper.Core/packages.config +++ b/KindleBookHelper.Core/packages.config @@ -2,4 +2,5 @@ + \ No newline at end of file diff --git a/KindleBookHelper.Test/BookTester.cs b/KindleBookHelper.Test/BookTester.cs index 9536fb3..f35f057 100644 --- a/KindleBookHelper.Test/BookTester.cs +++ b/KindleBookHelper.Test/BookTester.cs @@ -1,6 +1,6 @@ /* KindleBookHelper - Converts raw text file to html format that can be consumed by KindleGen. - Copyright (C) 2016 Peter Wetzel + Copyright (C) 2018 Peter Wetzel This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -15,12 +15,12 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the You should have received a copy of the GNU General Public License along with this program. If not, see . */ -using System; -using System.IO; -using System.Reflection; using KindleBookHelper.Core; using Newtonsoft.Json.Linq; using NUnit.Framework; +using System; +using System.IO; +using System.Reflection; namespace KindleHelper.Test { @@ -32,8 +32,8 @@ public class BookTester [SetUp] public void Setup() { - string sPath = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location); - _sourceFilePath = Path.Combine(sPath, "test.json"); + var path = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location); + _sourceFilePath = Path.Combine(path, "test.json"); Console.WriteLine(_sourceFilePath); } @@ -54,8 +54,8 @@ public void process() AuthorAlphabetical = "Author, Test", }); FileUtilities.WriteTextFile(_sourceFilePath, settings.ToString()); - - string sRaw = @" + string endPlaceholder = "--end--"; + string sample = $@" A Title First Line @@ -64,20 +64,20 @@ Second Line Another Stanze Last Line -[END] +{endPlaceholder} Another Title Another line Yet Another line -[END] +{endPlaceholder} "; - FileUtilities.WriteTextFile(rawFilePath, sRaw); + FileUtilities.WriteTextFile(rawFilePath, sample); + + var p = new BookProcessor(_sourceFilePath, endPlaceholder); + var book = p.Process(); - Book book = Book.Initialize(_sourceFilePath); - book.Process(); - var targetFilePath = Path.Combine(directoryPath, $"{book.TitleFileSafe}.html"); Console.WriteLine(targetFilePath); Assert.IsTrue(File.Exists(targetFilePath)); diff --git a/KindleBookHelper.Test/Properties/AssemblyInfo.cs b/KindleBookHelper.Test/Properties/AssemblyInfo.cs index cb72286..b26fd71 100644 --- a/KindleBookHelper.Test/Properties/AssemblyInfo.cs +++ b/KindleBookHelper.Test/Properties/AssemblyInfo.cs @@ -13,5 +13,5 @@ [assembly: ComVisible(false)] [assembly: Guid("7ae3e0e5-19b9-4927-bfd6-d2c88f536805")] -[assembly: AssemblyVersion("1.4.0.0")] -[assembly: AssemblyFileVersion("1.4.0.0")] \ No newline at end of file +[assembly: AssemblyVersion("2.0.0.0")] +[assembly: AssemblyFileVersion("2.0.0.0")] \ No newline at end of file diff --git a/KindleBookHelper/App.config b/KindleBookHelper/App.config index 94bda4d..41772a3 100644 --- a/KindleBookHelper/App.config +++ b/KindleBookHelper/App.config @@ -1,9 +1,6 @@ - - - - + \ No newline at end of file diff --git a/KindleBookHelper/KindleBookHelper.csproj b/KindleBookHelper/KindleBookHelper.csproj index 31332bc..237904e 100644 --- a/KindleBookHelper/KindleBookHelper.csproj +++ b/KindleBookHelper/KindleBookHelper.csproj @@ -37,9 +37,60 @@ false + + ..\packages\CommandLineParser.2.3.0\lib\net45\CommandLine.dll + + + ..\packages\Serilog.2.7.1\lib\net46\Serilog.dll + + + ..\packages\Serilog.Sinks.Console.3.1.1\lib\net45\Serilog.Sinks.Console.dll + + + ..\packages\Serilog.Sinks.Debug.1.0.1\lib\net46\Serilog.Sinks.Debug.dll + + + + ..\packages\System.Console.4.0.0\lib\net46\System.Console.dll + True + True + + + ..\packages\System.IO.4.1.0\lib\net462\System.IO.dll + True + True + + + ..\packages\System.Linq.4.1.0\lib\net463\System.Linq.dll + True + True + + + ..\packages\System.Linq.Expressions.4.1.0\lib\net463\System.Linq.Expressions.dll + True + True + + + ..\packages\System.Reflection.4.1.0\lib\net462\System.Reflection.dll + True + True + + + ..\packages\System.Reflection.TypeExtensions.4.1.0\lib\net462\System.Reflection.TypeExtensions.dll + + + ..\packages\System.Runtime.4.1.0\lib\net462\System.Runtime.dll + True + True + + + ..\packages\System.Runtime.Extensions.4.1.0\lib\net462\System.Runtime.Extensions.dll + True + True + @@ -48,10 +99,12 @@ + + diff --git a/KindleBookHelper/Program.cs b/KindleBookHelper/Program.cs index 7404575..ab346e3 100644 --- a/KindleBookHelper/Program.cs +++ b/KindleBookHelper/Program.cs @@ -1,6 +1,6 @@ /* KindleBookHelper - Converts raw text file to html format that can be consumed by KindleGen. - Copyright (C) 2017 Peter Wetzel + Copyright (C) 2018 Peter Wetzel This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -17,7 +17,9 @@ You should have received a copy of the GNU General Public License */ using System; using System.Configuration; +using CommandLine; using KindleBookHelper.Core; +using Serilog; namespace KindleBookHelper { @@ -25,15 +27,36 @@ class Program { static void Main(string[] args) { - Console.WriteLine("KindleBookHelper"); - Console.WriteLine("Copyright (C) 2017 Peter Wetzel"); - Console.WriteLine("This program comes with ABSOLUTELY NO WARRANTY; for details see license.txt."); - string sFilePath = args == null || args.Length == 0 ? ConfigurationManager.AppSettings["KindleBookHelper.SourceFilePath"] : args[0]; - Console.WriteLine($"Processing '{sFilePath}'..."); - Book book = Book.Initialize(sFilePath); - book.Process(); - Console.WriteLine("Done. Press any key to continue."); - Console.ReadLine(); + Log.Logger = new LoggerConfiguration() + .MinimumLevel.Debug() + .WriteTo.Debug() + .WriteTo.Console(restrictedToMinimumLevel: Serilog.Events.LogEventLevel.Information) + .CreateLogger(); + + Parser.Default.ParseArguments(args) + .WithParsed(opts => RunOptionsAndReturnExitCode(opts)); + } + + private static void RunOptionsAndReturnExitCode(ProgramOptions options) + { + try + { + var p = new BookProcessor(options.FilePath, options.EndPlaceholder); + p.Process(); + } + catch (Exception ex) + { + Log.Error(ex, ex.Message); + } + finally + { + Log.CloseAndFlush(); + if (options.PauseAtCompletion) + { + Console.WriteLine("Press any key to continue."); + Console.ReadLine(); + } + } } } } \ No newline at end of file diff --git a/KindleBookHelper/ProgramOptions.cs b/KindleBookHelper/ProgramOptions.cs new file mode 100644 index 0000000..236c3b4 --- /dev/null +++ b/KindleBookHelper/ProgramOptions.cs @@ -0,0 +1,34 @@ +/* + KindleBookHelper - Converts raw text file to html format that can be consumed by KindleGen. + Copyright (C) 2018 Peter Wetzel + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ +using CommandLine; +using KindleBookHelper.Core; + +namespace KindleBookHelper +{ + public class ProgramOptions + { + [Option('f', "filepath", Required = true, HelpText = "Full path of file to process.")] + public string FilePath { get; set; } + + [Option('e', "end", Default = Book.DefaultEndPlaceholder, Required = false, HelpText = "Text that indicates the end of a poem.")] + public string EndPlaceholder { get; set; } + + [Option('p', "pause", Required = false, HelpText = "Pause on program completion.")] + public bool PauseAtCompletion { get; set; } + } +} \ No newline at end of file diff --git a/KindleBookHelper/Properties/AssemblyInfo.cs b/KindleBookHelper/Properties/AssemblyInfo.cs index 6bc860b..48b8d5a 100644 --- a/KindleBookHelper/Properties/AssemblyInfo.cs +++ b/KindleBookHelper/Properties/AssemblyInfo.cs @@ -13,5 +13,5 @@ [assembly: ComVisible(false)] [assembly: Guid("dc2d43bd-99a4-4644-bb22-b7288ac659c2")] -[assembly: AssemblyVersion("1.4.0.0")] -[assembly: AssemblyFileVersion("1.4.0.0")] \ No newline at end of file +[assembly: AssemblyVersion("2.0.0.0")] +[assembly: AssemblyFileVersion("2.0.0.0")] \ No newline at end of file diff --git a/KindleBookHelper/packages.config b/KindleBookHelper/packages.config new file mode 100644 index 0000000..bee5967 --- /dev/null +++ b/KindleBookHelper/packages.config @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/README.md b/README.md index 40023d8..f19219e 100644 --- a/README.md +++ b/README.md @@ -3,8 +3,8 @@ ## Overview Converts raw text file to MOBI html format that can be consumed by KindleGen/Previewer. It provides fairly basic formatting/functionality and only includes code for poetry at the moment. -It will generate navigation, including a linkable table of contents. -Some additional text can be included via the json parameter. +It will generate navigation, including a linkable table of contents to each poem. +Some additional text can be included via the book metadata file. ## Output All files utilize an "URL-friendly" version of the book title (lowercase with special characters and spaces encoded or removed) @@ -13,17 +13,19 @@ All files utilize an "URL-friendly" version of the book title (lowercase with sp - book-title.html. Html document that has all content. - poetry.css. Stylesheet used by book. -## Assumptions -- JSON file is provided (location set via application config file) -- The first line is the name of the poem -- Each stanza is separated by a line break -- Each poem is separated by "[END]" text +## Usage +- -f JSON file with book metadata (required) +- -e Text marking the end of each poem (optional; defaults to "[END]") +- -p If provided, pauses the application after running (useful if running within an IDE) + +## Notes +- Program assumes that the first line is the name of the poem and that each stanza is separated by a line break - A unique identifier Id field will be generated on first run; be sure to clear it if re-using json for additional books. - CSS is initially pulled from the application DLL. It will not override it, so you can edit the file freely. ## Examples -### JSON config file +### Book Metadata ```json { @@ -48,7 +50,7 @@ A Title First Line Second Line -Another Stanze +Another Stanza Last Line [END] @@ -57,6 +59,7 @@ Another Title Another line Yet Another line +The line to end all lines [END] ``` \ No newline at end of file