added epub renderer
This commit is contained in:
parent
eeb7f1badb
commit
8f89d1e951
|
@ -0,0 +1,6 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8" ?>
|
||||||
|
<configuration>
|
||||||
|
<startup>
|
||||||
|
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
|
||||||
|
</startup>
|
||||||
|
</configuration>
|
|
@ -0,0 +1,64 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
||||||
|
<PropertyGroup>
|
||||||
|
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||||
|
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||||
|
<ProjectGuid>{C9D8CF8A-3CBE-4E45-91A3-37F8256A81A7}</ProjectGuid>
|
||||||
|
<OutputType>Exe</OutputType>
|
||||||
|
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||||
|
<RootNamespace>Ficdown.Console</RootNamespace>
|
||||||
|
<AssemblyName>Ficdown.Console</AssemblyName>
|
||||||
|
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
|
||||||
|
<FileAlignment>512</FileAlignment>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||||
|
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||||
|
<DebugSymbols>true</DebugSymbols>
|
||||||
|
<DebugType>full</DebugType>
|
||||||
|
<Optimize>false</Optimize>
|
||||||
|
<OutputPath>bin\Debug\</OutputPath>
|
||||||
|
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||||
|
<ErrorReport>prompt</ErrorReport>
|
||||||
|
<WarningLevel>4</WarningLevel>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||||
|
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||||
|
<DebugType>pdbonly</DebugType>
|
||||||
|
<Optimize>true</Optimize>
|
||||||
|
<OutputPath>bin\Release\</OutputPath>
|
||||||
|
<DefineConstants>TRACE</DefineConstants>
|
||||||
|
<ErrorReport>prompt</ErrorReport>
|
||||||
|
<WarningLevel>4</WarningLevel>
|
||||||
|
</PropertyGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Reference Include="System" />
|
||||||
|
<Reference Include="System.Core" />
|
||||||
|
<Reference Include="System.Xml.Linq" />
|
||||||
|
<Reference Include="System.Data.DataSetExtensions" />
|
||||||
|
<Reference Include="Microsoft.CSharp" />
|
||||||
|
<Reference Include="System.Data" />
|
||||||
|
<Reference Include="System.Xml" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Compile Include="Program.cs" />
|
||||||
|
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<None Include="App.config" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\Ficdown.Parser\Ficdown.Parser.csproj">
|
||||||
|
<Project>{780f652d-7541-4171-bb89-2d263d3961dc}</Project>
|
||||||
|
<Name>Ficdown.Parser</Name>
|
||||||
|
</ProjectReference>
|
||||||
|
</ItemGroup>
|
||||||
|
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||||
|
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||||
|
Other similar extension points exist, see Microsoft.Common.targets.
|
||||||
|
<Target Name="BeforeBuild">
|
||||||
|
</Target>
|
||||||
|
<Target Name="AfterBuild">
|
||||||
|
</Target>
|
||||||
|
-->
|
||||||
|
</Project>
|
|
@ -0,0 +1,153 @@
|
||||||
|
namespace Ficdown.Console
|
||||||
|
{
|
||||||
|
using System;
|
||||||
|
using System.IO;
|
||||||
|
using Microsoft.SqlServer.Server;
|
||||||
|
using Parser;
|
||||||
|
using Parser.Render;
|
||||||
|
|
||||||
|
internal class Program
|
||||||
|
{
|
||||||
|
private static void Main(string[] args)
|
||||||
|
{
|
||||||
|
string infile = null;
|
||||||
|
string output = null;
|
||||||
|
string tempdir = null;
|
||||||
|
string format = null;
|
||||||
|
string author = null;
|
||||||
|
var debug = false;
|
||||||
|
|
||||||
|
if (args.Length == 1)
|
||||||
|
{
|
||||||
|
if (args[0] == "/?" || args[0] == "/help" || args[0] == "-help" || args[0] == "--help")
|
||||||
|
{
|
||||||
|
ShowHelp();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (args.Length > 1)
|
||||||
|
{
|
||||||
|
for (var i = 0; i < args.Length; i += 2)
|
||||||
|
{
|
||||||
|
switch (args[i])
|
||||||
|
{
|
||||||
|
case "--format":
|
||||||
|
format = args[i + 1];
|
||||||
|
break;
|
||||||
|
case "--in":
|
||||||
|
infile = args[i + 1];
|
||||||
|
break;
|
||||||
|
case "--out":
|
||||||
|
output = args[i + 1];
|
||||||
|
break;
|
||||||
|
case "--template":
|
||||||
|
tempdir = args[i + 1];
|
||||||
|
break;
|
||||||
|
case "--author":
|
||||||
|
author = args[i + 1];
|
||||||
|
break;
|
||||||
|
case "--debug":
|
||||||
|
i--;
|
||||||
|
debug = true;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
Console.WriteLine(@"Unknown option: {0}", args[i]);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ShowHelp();
|
||||||
|
}
|
||||||
|
if (string.IsNullOrWhiteSpace(format))
|
||||||
|
{
|
||||||
|
ShowHelp();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (string.IsNullOrWhiteSpace(infile) || !File.Exists(infile))
|
||||||
|
{
|
||||||
|
Console.WriteLine(@"Source file {0} not found.", infile);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (string.IsNullOrWhiteSpace(output))
|
||||||
|
if (format == "html")
|
||||||
|
output = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, @"html");
|
||||||
|
else if (format == "epub")
|
||||||
|
output = "output.epub";
|
||||||
|
|
||||||
|
if (!string.IsNullOrWhiteSpace(output) && (Directory.Exists(output) || File.Exists(output)))
|
||||||
|
{
|
||||||
|
Console.WriteLine(@"Specified output {0} already exists.", output);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!string.IsNullOrWhiteSpace(tempdir))
|
||||||
|
{
|
||||||
|
if (!Directory.Exists(tempdir))
|
||||||
|
{
|
||||||
|
Console.WriteLine(@"Template directory {0} does not exist.", tempdir);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!File.Exists(Path.Combine(tempdir, "index.html")) ||
|
||||||
|
!File.Exists(Path.Combine(tempdir, "scene.html")) ||
|
||||||
|
!File.Exists(Path.Combine(tempdir, "styles.css")))
|
||||||
|
{
|
||||||
|
Console.WriteLine(
|
||||||
|
@"Template directory must contain ""index.html"", ""scene.html"", and ""style.css"" files.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var parser = new FicdownParser();
|
||||||
|
var storyText = File.ReadAllText(infile);
|
||||||
|
|
||||||
|
Console.WriteLine(@"Parsing story...");
|
||||||
|
|
||||||
|
var story = parser.ParseStory(storyText);
|
||||||
|
|
||||||
|
IRenderer rend;
|
||||||
|
switch (format)
|
||||||
|
{
|
||||||
|
case "html":
|
||||||
|
Directory.CreateDirectory(output);
|
||||||
|
rend = (string.IsNullOrWhiteSpace(tempdir)
|
||||||
|
? new HtmlRenderer()
|
||||||
|
: new HtmlRenderer(File.ReadAllText(Path.Combine(tempdir, "index.html")),
|
||||||
|
File.ReadAllText(Path.Combine(tempdir, "scene.html")),
|
||||||
|
File.ReadAllText(Path.Combine(tempdir, "styles.css"))));
|
||||||
|
break;
|
||||||
|
case "epub":
|
||||||
|
if (string.IsNullOrWhiteSpace(author))
|
||||||
|
{
|
||||||
|
Console.WriteLine(@"Epub format requires the --author argument.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
rend = (string.IsNullOrWhiteSpace(tempdir)
|
||||||
|
? new EpubRenderer(author)
|
||||||
|
: new EpubRenderer(author, File.ReadAllText(Path.Combine(tempdir, "index.html")),
|
||||||
|
File.ReadAllText(Path.Combine(tempdir, "scene.html")),
|
||||||
|
File.ReadAllText(Path.Combine(tempdir, "styles.css"))));
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
ShowHelp();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Console.WriteLine(@"Rendering story...");
|
||||||
|
|
||||||
|
rend.Render(story, output, debug);
|
||||||
|
|
||||||
|
Console.WriteLine(@"Done.");
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void ShowHelp()
|
||||||
|
{
|
||||||
|
Console.WriteLine(
|
||||||
|
@"Usage: ficdown.exe
|
||||||
|
--format (html|epub)
|
||||||
|
--in ""/path/to/source.md""
|
||||||
|
[--out ""/path/to/output""]
|
||||||
|
[--template ""/path/to/template/dir""]
|
||||||
|
[--author ""Author Name""
|
||||||
|
[--debug]");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,36 @@
|
||||||
|
using System.Reflection;
|
||||||
|
using System.Runtime.CompilerServices;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
|
// General Information about an assembly is controlled through the following
|
||||||
|
// set of attributes. Change these attribute values to modify the information
|
||||||
|
// associated with an assembly.
|
||||||
|
[assembly: AssemblyTitle("Ficdown.Console")]
|
||||||
|
[assembly: AssemblyDescription("")]
|
||||||
|
[assembly: AssemblyConfiguration("")]
|
||||||
|
[assembly: AssemblyCompany("")]
|
||||||
|
[assembly: AssemblyProduct("Ficdown.Console")]
|
||||||
|
[assembly: AssemblyCopyright("Copyright © 2015")]
|
||||||
|
[assembly: AssemblyTrademark("")]
|
||||||
|
[assembly: AssemblyCulture("")]
|
||||||
|
|
||||||
|
// Setting ComVisible to false makes the types in this assembly not visible
|
||||||
|
// to COM components. If you need to access a type in this assembly from
|
||||||
|
// COM, set the ComVisible attribute to true on that type.
|
||||||
|
[assembly: ComVisible(false)]
|
||||||
|
|
||||||
|
// The following GUID is for the ID of the typelib if this project is exposed to COM
|
||||||
|
[assembly: Guid("dafaccf5-0218-412d-b127-665c768f85ec")]
|
||||||
|
|
||||||
|
// Version information for an assembly consists of the following four values:
|
||||||
|
//
|
||||||
|
// Major Version
|
||||||
|
// Minor Version
|
||||||
|
// Build Number
|
||||||
|
// Revision
|
||||||
|
//
|
||||||
|
// You can specify all the values or you can default the Build and Revision Numbers
|
||||||
|
// by using the '*' as shown below:
|
||||||
|
// [assembly: AssemblyVersion("1.0.*")]
|
||||||
|
[assembly: AssemblyVersion("1.0.0.0")]
|
||||||
|
[assembly: AssemblyFileVersion("1.0.0.0")]
|
|
@ -30,6 +30,12 @@
|
||||||
<WarningLevel>4</WarningLevel>
|
<WarningLevel>4</WarningLevel>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<Reference Include="Epub4Net">
|
||||||
|
<HintPath>..\packages\Epub4Net.1.2.0\lib\net40\Epub4Net.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="Ionic.Zip">
|
||||||
|
<HintPath>..\packages\DotNetZip.1.9.1.8\lib\net20\Ionic.Zip.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
<Reference Include="MarkdownSharp">
|
<Reference Include="MarkdownSharp">
|
||||||
<HintPath>..\packages\MarkdownSharp.1.13.0.0\lib\35\MarkdownSharp.dll</HintPath>
|
<HintPath>..\packages\MarkdownSharp.1.13.0.0\lib\35\MarkdownSharp.dll</HintPath>
|
||||||
</Reference>
|
</Reference>
|
||||||
|
@ -67,11 +73,30 @@
|
||||||
<Compile Include="Model\Story\Action.cs" />
|
<Compile Include="Model\Story\Action.cs" />
|
||||||
<Compile Include="Model\Story\Scene.cs" />
|
<Compile Include="Model\Story\Scene.cs" />
|
||||||
<Compile Include="Model\Story\Story.cs" />
|
<Compile Include="Model\Story\Story.cs" />
|
||||||
|
<Compile Include="Render\EpubRenderer.cs" />
|
||||||
<Compile Include="Render\HtmlRenderer.cs" />
|
<Compile Include="Render\HtmlRenderer.cs" />
|
||||||
<Compile Include="Render\IRenderer.cs" />
|
<Compile Include="Render\IRenderer.cs" />
|
||||||
|
<Compile Include="Render\Template.Designer.cs">
|
||||||
|
<AutoGen>True</AutoGen>
|
||||||
|
<DesignTime>True</DesignTime>
|
||||||
|
<DependentUpon>Template.resx</DependentUpon>
|
||||||
|
</Compile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<None Include="packages.config" />
|
<None Include="packages.config" />
|
||||||
|
<Content Include="Render\Views\scene.html" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Content Include="Render\Assets\styles.css" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Content Include="Render\Views\index.html" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<EmbeddedResource Include="Render\Template.resx">
|
||||||
|
<Generator>ResXFileCodeGenerator</Generator>
|
||||||
|
<LastGenOutput>Template.Designer.cs</LastGenOutput>
|
||||||
|
</EmbeddedResource>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||||
|
|
|
@ -0,0 +1,82 @@
|
||||||
|
/* Adapted from http://wiki.mobileread.com/wiki/CSS_template */
|
||||||
|
|
||||||
|
@page {
|
||||||
|
margin-top: 30px;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
margin-right: 30px;
|
||||||
|
margin-left: 30px;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
img {
|
||||||
|
max-width: 100%;
|
||||||
|
oeb-column-number: 1;
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
font-style: italic;
|
||||||
|
color: #009;
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1.title {
|
||||||
|
font-family: Verdana, Geneva, sans-serif;
|
||||||
|
font-size: x-large;
|
||||||
|
text-align: center;
|
||||||
|
font-weight: bold;
|
||||||
|
color: #000;
|
||||||
|
margin-top: 2em;
|
||||||
|
text-indent: 0;
|
||||||
|
-webkit-hyphens: none;
|
||||||
|
-moz-hyphens: none;
|
||||||
|
hyphens: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1, h2, h3, h4, h5, h6 {
|
||||||
|
page-break-after: avoid;
|
||||||
|
-webkit-hyphenate-lines: 0 !important;
|
||||||
|
-webkit-hyphens: none !important;
|
||||||
|
adobe-hyphenate: none !important;
|
||||||
|
-moz-hyphens: none !important;
|
||||||
|
hyphens: none !important;
|
||||||
|
hyphenate-lines: 0;
|
||||||
|
color: #000;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1 + p, h2 + p {
|
||||||
|
text-indent: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
p {
|
||||||
|
line-height: 1.5em;
|
||||||
|
text-align: justify;
|
||||||
|
widows: 2;
|
||||||
|
orphans: 2;
|
||||||
|
margin: 1em 0 0 0;
|
||||||
|
text-indent: 2em;
|
||||||
|
-webkit-hyphenate-before: 3;
|
||||||
|
hyphenate-before: 3;
|
||||||
|
-webkit-hyphenate-after: 3;
|
||||||
|
hyphenate-after: 3;
|
||||||
|
-webkit-hyphenate-lines: 2;
|
||||||
|
hyphenate-lines: 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
ol {
|
||||||
|
margin: 1em 0 1em 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul {
|
||||||
|
margin: 1em 0 1em 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
li {
|
||||||
|
line-height: 1.5em;
|
||||||
|
orphans: 2;
|
||||||
|
widows: 2;
|
||||||
|
text-align: justify;
|
||||||
|
}
|
|
@ -0,0 +1,49 @@
|
||||||
|
namespace Ficdown.Parser.Render
|
||||||
|
{
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
|
using Epub4Net;
|
||||||
|
|
||||||
|
public class EpubRenderer : HtmlRenderer
|
||||||
|
{
|
||||||
|
private readonly string _author;
|
||||||
|
|
||||||
|
public EpubRenderer(string author) : base()
|
||||||
|
{
|
||||||
|
_author = author;
|
||||||
|
}
|
||||||
|
|
||||||
|
public EpubRenderer(string author, string index, string scene, string styles) : base(index, scene, styles)
|
||||||
|
{
|
||||||
|
_author = author;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Render(Model.Parser.ResolvedStory story, string outPath, bool debug = false)
|
||||||
|
{
|
||||||
|
var temppath = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());
|
||||||
|
Directory.CreateDirectory(temppath);
|
||||||
|
base.Render(story, temppath, debug);
|
||||||
|
|
||||||
|
var chapters = new List<Chapter>
|
||||||
|
{
|
||||||
|
new Chapter(Path.Combine(temppath, "index.html"), "index.html", "Title Page")
|
||||||
|
};
|
||||||
|
chapters.AddRange(from file in Directory.GetFiles(temppath)
|
||||||
|
select Path.GetFileName(file)
|
||||||
|
into fname
|
||||||
|
where fname != "index.html" && fname != "styles.css"
|
||||||
|
select new Chapter(Path.Combine(temppath, fname), fname, fname.Replace(".html", string.Empty)));
|
||||||
|
|
||||||
|
var epub = new Epub(Story.Name, _author, chapters);
|
||||||
|
epub.AddResourceFile(new ResourceFile("styles.css", Path.Combine(temppath, "styles.css"), "text/css"));
|
||||||
|
|
||||||
|
var builder = new EPubBuilder();
|
||||||
|
var built = builder.Build(epub);
|
||||||
|
|
||||||
|
File.Move(built, outPath);
|
||||||
|
Directory.Delete(temppath, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,29 +1,64 @@
|
||||||
namespace Ficdown.Parser.Render
|
namespace Ficdown.Parser.Render
|
||||||
{
|
{
|
||||||
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using MarkdownSharp;
|
using MarkdownSharp;
|
||||||
using Model.Parser;
|
using Model.Parser;
|
||||||
using Parser;
|
using Parser;
|
||||||
|
|
||||||
internal class HtmlRenderer : IRenderer
|
public class HtmlRenderer : IRenderer
|
||||||
{
|
{
|
||||||
private readonly Markdown _md;
|
protected readonly Markdown Markdown;
|
||||||
|
|
||||||
|
private string _index;
|
||||||
|
private string _scene;
|
||||||
|
private string _styles;
|
||||||
|
|
||||||
|
protected ResolvedStory Story { get; set; }
|
||||||
|
|
||||||
public HtmlRenderer()
|
public HtmlRenderer()
|
||||||
{
|
{
|
||||||
_md = new Markdown();
|
Markdown = new Markdown();
|
||||||
|
_index = Template.Index;
|
||||||
|
_scene = Template.Scene;
|
||||||
|
_styles = Template.Styles;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Render(ResolvedStory story, string outPath, bool debug = false)
|
public HtmlRenderer(string index, string scene, string styles)
|
||||||
{
|
{
|
||||||
var index = string.Format("# {0}\n\n{1}\n\n[Click here]({2}.html) to start!", story.Name, story.Description,
|
_index = index;
|
||||||
story.FirstPage);
|
_scene = scene;
|
||||||
|
_styles = styles;
|
||||||
|
}
|
||||||
|
|
||||||
File.WriteAllText(Path.Combine(outPath, "index.html"), _md.Transform(index));
|
public virtual void Render(ResolvedStory story, string outPath, bool debug = false)
|
||||||
|
{
|
||||||
|
Story = story;
|
||||||
|
GenerateHtml(story, outPath, debug);
|
||||||
|
}
|
||||||
|
|
||||||
|
private string FillTemplate(string template, Dictionary<string, string> values)
|
||||||
|
{
|
||||||
|
return values.Aggregate(template,
|
||||||
|
(current, pair) => current.Replace(string.Format("@{0}", pair.Key), pair.Value));
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void GenerateHtml(ResolvedStory story, string outPath, bool debug)
|
||||||
|
{
|
||||||
|
var index = FillTemplate(_index, new Dictionary<string, string>
|
||||||
|
{
|
||||||
|
{"Title", story.Name},
|
||||||
|
{"Description", Markdown.Transform(story.Description)},
|
||||||
|
{"FirstScene", string.Format("{0}.html", story.FirstPage)}
|
||||||
|
});
|
||||||
|
|
||||||
|
File.WriteAllText(Path.Combine(outPath, "index.html"), index);
|
||||||
|
|
||||||
foreach (var page in story.Pages)
|
foreach (var page in story.Pages)
|
||||||
{
|
{
|
||||||
|
File.WriteAllText(Path.Combine(outPath, "styles.css"), _styles);
|
||||||
|
|
||||||
var content = page.Content;
|
var content = page.Content;
|
||||||
foreach (var anchor in Utilities.ParseAnchors(page.Content))
|
foreach (var anchor in Utilities.ParseAnchors(page.Content))
|
||||||
{
|
{
|
||||||
|
@ -35,7 +70,14 @@
|
||||||
content += string.Format("\n\n### State Debug\n\n{0}",
|
content += string.Format("\n\n### State Debug\n\n{0}",
|
||||||
string.Join("\n", page.ActiveToggles.Select(t => string.Format("- {0}", t)).ToArray()));
|
string.Join("\n", page.ActiveToggles.Select(t => string.Format("- {0}", t)).ToArray()));
|
||||||
}
|
}
|
||||||
File.WriteAllText(Path.Combine(outPath, string.Format("{0}.html", page.Name)), _md.Transform(content));
|
|
||||||
|
var scene = FillTemplate(_scene, new Dictionary<string, string>
|
||||||
|
{
|
||||||
|
{"Title", story.Name},
|
||||||
|
{"Content", Markdown.Transform(content)}
|
||||||
|
});
|
||||||
|
|
||||||
|
File.WriteAllText(Path.Combine(outPath, string.Format("{0}.html", page.Name)), scene);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
{
|
{
|
||||||
using Model.Parser;
|
using Model.Parser;
|
||||||
|
|
||||||
internal interface IRenderer
|
public interface IRenderer
|
||||||
{
|
{
|
||||||
void Render(ResolvedStory story, string outPath, bool debug);
|
void Render(ResolvedStory story, string outPath, bool debug);
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,144 @@
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
// <auto-generated>
|
||||||
|
// This code was generated by a tool.
|
||||||
|
// Runtime Version:4.0.30319.34014
|
||||||
|
//
|
||||||
|
// Changes to this file may cause incorrect behavior and will be lost if
|
||||||
|
// the code is regenerated.
|
||||||
|
// </auto-generated>
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
namespace Ficdown.Parser.Render {
|
||||||
|
using System;
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// A strongly-typed resource class, for looking up localized strings, etc.
|
||||||
|
/// </summary>
|
||||||
|
// This class was auto-generated by the StronglyTypedResourceBuilder
|
||||||
|
// class via a tool like ResGen or Visual Studio.
|
||||||
|
// To add or remove a member, edit your .ResX file then rerun ResGen
|
||||||
|
// with the /str option, or rebuild your VS project.
|
||||||
|
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
|
||||||
|
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||||
|
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
|
||||||
|
internal class Template {
|
||||||
|
|
||||||
|
private static global::System.Resources.ResourceManager resourceMan;
|
||||||
|
|
||||||
|
private static global::System.Globalization.CultureInfo resourceCulture;
|
||||||
|
|
||||||
|
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
|
||||||
|
internal Template() {
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Returns the cached ResourceManager instance used by this class.
|
||||||
|
/// </summary>
|
||||||
|
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
|
||||||
|
internal static global::System.Resources.ResourceManager ResourceManager {
|
||||||
|
get {
|
||||||
|
if (object.ReferenceEquals(resourceMan, null)) {
|
||||||
|
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Ficdown.Parser.Render.Template", typeof(Template).Assembly);
|
||||||
|
resourceMan = temp;
|
||||||
|
}
|
||||||
|
return resourceMan;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Overrides the current thread's CurrentUICulture property for all
|
||||||
|
/// resource lookups using this strongly typed resource class.
|
||||||
|
/// </summary>
|
||||||
|
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
|
||||||
|
internal static global::System.Globalization.CultureInfo Culture {
|
||||||
|
get {
|
||||||
|
return resourceCulture;
|
||||||
|
}
|
||||||
|
set {
|
||||||
|
resourceCulture = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Looks up a localized string similar to <!DOCTYPE html>
|
||||||
|
///
|
||||||
|
///<html lang="en" xmlns="http://www.w3.org/1999/xhtml">
|
||||||
|
///<head>
|
||||||
|
/// <meta charset="utf-8" />
|
||||||
|
/// <title>@Title</title>
|
||||||
|
/// <link rel="stylesheet" type="text/css" href="styles.css"/>
|
||||||
|
///</head>
|
||||||
|
/// <body>
|
||||||
|
/// <h1 class="title">@Title</h1>
|
||||||
|
/// @Description
|
||||||
|
/// <p><a href="@FirstScene">Begin reading...</a></p>
|
||||||
|
/// </body>
|
||||||
|
///</html>.
|
||||||
|
/// </summary>
|
||||||
|
internal static string Index {
|
||||||
|
get {
|
||||||
|
return ResourceManager.GetString("Index", resourceCulture);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Looks up a localized string similar to <!DOCTYPE html>
|
||||||
|
///
|
||||||
|
///<html lang="en" xmlns="http://www.w3.org/1999/xhtml">
|
||||||
|
///<head>
|
||||||
|
/// <meta charset="utf-8" />
|
||||||
|
/// <title>@Title</title>
|
||||||
|
/// <link rel="stylesheet" type="text/css" href="styles.css" />
|
||||||
|
///</head>
|
||||||
|
///<body>
|
||||||
|
/// @Content
|
||||||
|
///</body>
|
||||||
|
///</html>.
|
||||||
|
/// </summary>
|
||||||
|
internal static string Scene {
|
||||||
|
get {
|
||||||
|
return ResourceManager.GetString("Scene", resourceCulture);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Looks up a localized string similar to /* Adapted from http://wiki.mobileread.com/wiki/CSS_template */
|
||||||
|
///
|
||||||
|
///@page {
|
||||||
|
/// margin-top: 30px;
|
||||||
|
/// margin-bottom: 20px;
|
||||||
|
///}
|
||||||
|
///
|
||||||
|
///body {
|
||||||
|
/// margin-right: 30px;
|
||||||
|
/// margin-left: 30px;
|
||||||
|
/// padding: 0;
|
||||||
|
///}
|
||||||
|
///
|
||||||
|
///img {
|
||||||
|
/// max-width: 100%;
|
||||||
|
/// oeb-column-number: 1;
|
||||||
|
/// display: inline-block;
|
||||||
|
///}
|
||||||
|
///
|
||||||
|
///a {
|
||||||
|
/// font-style: italic;
|
||||||
|
/// color: #000;
|
||||||
|
/// text-decoration: none;
|
||||||
|
///}
|
||||||
|
///
|
||||||
|
///h1.title {
|
||||||
|
/// font-family: Verdana, Geneva, sans-serif;
|
||||||
|
/// font-size: x-large;
|
||||||
|
/// text-align: center;
|
||||||
|
/// font-weight: bold;
|
||||||
|
/// [rest of string was truncated]";.
|
||||||
|
/// </summary>
|
||||||
|
internal static string Styles {
|
||||||
|
get {
|
||||||
|
return ResourceManager.GetString("Styles", resourceCulture);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,130 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<root>
|
||||||
|
<!--
|
||||||
|
Microsoft ResX Schema
|
||||||
|
|
||||||
|
Version 2.0
|
||||||
|
|
||||||
|
The primary goals of this format is to allow a simple XML format
|
||||||
|
that is mostly human readable. The generation and parsing of the
|
||||||
|
various data types are done through the TypeConverter classes
|
||||||
|
associated with the data types.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
... ado.net/XML headers & schema ...
|
||||||
|
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||||
|
<resheader name="version">2.0</resheader>
|
||||||
|
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||||
|
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||||
|
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||||
|
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||||
|
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||||
|
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||||
|
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||||
|
<comment>This is a comment</comment>
|
||||||
|
</data>
|
||||||
|
|
||||||
|
There are any number of "resheader" rows that contain simple
|
||||||
|
name/value pairs.
|
||||||
|
|
||||||
|
Each data row contains a name, and value. The row also contains a
|
||||||
|
type or mimetype. Type corresponds to a .NET class that support
|
||||||
|
text/value conversion through the TypeConverter architecture.
|
||||||
|
Classes that don't support this are serialized and stored with the
|
||||||
|
mimetype set.
|
||||||
|
|
||||||
|
The mimetype is used for serialized objects, and tells the
|
||||||
|
ResXResourceReader how to depersist the object. This is currently not
|
||||||
|
extensible. For a given mimetype the value must be set accordingly:
|
||||||
|
|
||||||
|
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||||
|
that the ResXResourceWriter will generate, however the reader can
|
||||||
|
read any of the formats listed below.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.binary.base64
|
||||||
|
value : The object must be serialized with
|
||||||
|
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.soap.base64
|
||||||
|
value : The object must be serialized with
|
||||||
|
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||||
|
value : The object must be serialized into a byte array
|
||||||
|
: using a System.ComponentModel.TypeConverter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
-->
|
||||||
|
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||||
|
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||||
|
<xsd:element name="root" msdata:IsDataSet="true">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:choice maxOccurs="unbounded">
|
||||||
|
<xsd:element name="metadata">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||||
|
<xsd:attribute name="type" type="xsd:string" />
|
||||||
|
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||||
|
<xsd:attribute ref="xml:space" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="assembly">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:attribute name="alias" type="xsd:string" />
|
||||||
|
<xsd:attribute name="name" type="xsd:string" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="data">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||||
|
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||||
|
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||||
|
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||||
|
<xsd:attribute ref="xml:space" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="resheader">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
</xsd:choice>
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
</xsd:schema>
|
||||||
|
<resheader name="resmimetype">
|
||||||
|
<value>text/microsoft-resx</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="version">
|
||||||
|
<value>2.0</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="reader">
|
||||||
|
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="writer">
|
||||||
|
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||||
|
</resheader>
|
||||||
|
<assembly alias="System.Windows.Forms" name="System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
|
||||||
|
<data name="Index" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||||
|
<value>views\index.html;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;utf-8</value>
|
||||||
|
</data>
|
||||||
|
<data name="Scene" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||||
|
<value>views\scene.html;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;utf-8</value>
|
||||||
|
</data>
|
||||||
|
<data name="Styles" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||||
|
<value>assets\styles.css;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;utf-8</value>
|
||||||
|
</data>
|
||||||
|
</root>
|
|
@ -0,0 +1,14 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
|
||||||
|
<html lang="en" xmlns="http://www.w3.org/1999/xhtml">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8" />
|
||||||
|
<title>@Title</title>
|
||||||
|
<link rel="stylesheet" type="text/css" href="styles.css"/>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h1 class="title">@Title</h1>
|
||||||
|
@Description
|
||||||
|
<p><a href="@FirstScene">Begin reading...</a></p>
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -0,0 +1,12 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
|
||||||
|
<html lang="en" xmlns="http://www.w3.org/1999/xhtml">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8" />
|
||||||
|
<title>@Title</title>
|
||||||
|
<link rel="stylesheet" type="text/css" href="styles.css" />
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
@Content
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -1,4 +1,6 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<packages>
|
<packages>
|
||||||
|
<package id="DotNetZip" version="1.9.1.8" targetFramework="net45" />
|
||||||
|
<package id="Epub4Net" version="1.2.0" targetFramework="net45" />
|
||||||
<package id="MarkdownSharp" version="1.13.0.0" targetFramework="net45" />
|
<package id="MarkdownSharp" version="1.13.0.0" targetFramework="net45" />
|
||||||
</packages>
|
</packages>
|
|
@ -1,12 +1,14 @@
|
||||||
|
|
||||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||||
# Visual Studio 2013
|
# Visual Studio 2013
|
||||||
VisualStudioVersion = 12.0.30110.0
|
VisualStudioVersion = 12.0.31101.0
|
||||||
MinimumVisualStudioVersion = 10.0.40219.1
|
MinimumVisualStudioVersion = 10.0.40219.1
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ficdown.Parser", "Ficdown.Parser\Ficdown.Parser.csproj", "{780F652D-7541-4171-BB89-2D263D3961DC}"
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ficdown.Parser", "Ficdown.Parser\Ficdown.Parser.csproj", "{780F652D-7541-4171-BB89-2D263D3961DC}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ficdown.Parser.Tests", "Ficdown.Parser.Tests\Ficdown.Parser.Tests.csproj", "{756192E2-BA47-4850-8096-289D44878A7E}"
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ficdown.Parser.Tests", "Ficdown.Parser.Tests\Ficdown.Parser.Tests.csproj", "{756192E2-BA47-4850-8096-289D44878A7E}"
|
||||||
EndProject
|
EndProject
|
||||||
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ficdown.Console", "Ficdown.Console\Ficdown.Console.csproj", "{C9D8CF8A-3CBE-4E45-91A3-37F8256A81A7}"
|
||||||
|
EndProject
|
||||||
Global
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
Debug|Any CPU = Debug|Any CPU
|
Debug|Any CPU = Debug|Any CPU
|
||||||
|
@ -21,6 +23,10 @@ Global
|
||||||
{756192E2-BA47-4850-8096-289D44878A7E}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{756192E2-BA47-4850-8096-289D44878A7E}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
{756192E2-BA47-4850-8096-289D44878A7E}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{756192E2-BA47-4850-8096-289D44878A7E}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{756192E2-BA47-4850-8096-289D44878A7E}.Release|Any CPU.Build.0 = Release|Any CPU
|
{756192E2-BA47-4850-8096-289D44878A7E}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{C9D8CF8A-3CBE-4E45-91A3-37F8256A81A7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{C9D8CF8A-3CBE-4E45-91A3-37F8256A81A7}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{C9D8CF8A-3CBE-4E45-91A3-37F8256A81A7}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{C9D8CF8A-3CBE-4E45-91A3-37F8256A81A7}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(SolutionProperties) = preSolution
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
HideSolutionNode = FALSE
|
HideSolutionNode = FALSE
|
||||||
|
|
Loading…
Reference in New Issue