yavsc/Yavsc/Helpers/TeXHelpers.cs

158 lines
5.6 KiB
C#
Raw Normal View History

2016-11-09 14:03:57 +01:00
using System;
2016-11-30 11:01:22 +01:00
using System.Diagnostics;
2016-11-09 14:03:57 +01:00
using System.IO;
2016-11-06 02:03:36 +01:00
using System.Linq;
2016-11-09 14:03:57 +01:00
using Microsoft.AspNet.Http;
using Microsoft.AspNet.Mvc;
using Microsoft.AspNet.Mvc.Rendering;
using Microsoft.AspNet.Mvc.ViewEngines;
2016-11-30 11:01:22 +01:00
using Yavsc.ViewModels.Gen;
2016-11-06 02:03:36 +01:00
namespace Yavsc.Helpers
{
2016-11-30 11:01:22 +01:00
public class TeXString
{
2016-11-10 01:03:49 +01:00
2016-11-30 11:01:22 +01:00
public class Replacement
{
2016-11-10 01:03:49 +01:00
string target;
string replacement;
2016-11-30 11:01:22 +01:00
public Replacement(string target, string replacement)
{
this.target = target;
this.replacement = replacement;
2016-11-10 01:03:49 +01:00
}
public string Execute(string source)
{
2016-11-30 11:01:22 +01:00
return source.Replace(target, replacement);
2016-11-10 01:03:49 +01:00
}
}
2016-11-30 11:01:22 +01:00
public readonly static Replacement[] SpecialCharsRendering =
2016-11-10 01:03:49 +01:00
{
new Replacement("<","\\textless"),
new Replacement(">","\\textgreater"),
new Replacement("©","\\copyright"),
new Replacement("®","\\textregistered"),
new Replacement("\\","\\textbackslash"),
new Replacement("™","\\texttrademark"),
new Replacement("¶","\\P"),
new Replacement("|","\\textbar"),
new Replacement("%","\\%"),
new Replacement("{","\\{"),
new Replacement("}","\\}"),
new Replacement("_","\\_"),
new Replacement("#","\\#"),
new Replacement("$","\\$"),
new Replacement("_","\\_"),
new Replacement("¿","\\textquestiondown"),
new Replacement("§","\\S"),
new Replacement("£","\\pounds"),
new Replacement("&","\\&"),
new Replacement("¡","\\textexclamdown"),
new Replacement("†","\\dag"),
new Replacement("","\\textendash")
};
string data;
2016-11-30 11:01:22 +01:00
public TeXString(string str)
{
2016-11-10 01:03:49 +01:00
data = str;
2016-11-30 11:01:22 +01:00
foreach (var r in SpecialCharsRendering)
{
2016-11-10 01:03:49 +01:00
data = r.Execute(data);
}
}
2016-11-30 11:01:22 +01:00
2016-11-10 01:03:49 +01:00
override public string ToString()
{
return data;
}
}
2016-11-06 02:03:36 +01:00
public static class TeXHelpers
{
public static string NewLinesWith(this string target, string separator)
2016-11-30 11:01:22 +01:00
{
var items = target.Split(new char[] { '\n' }).Where(
s => !string.IsNullOrWhiteSpace(s));
2016-11-06 02:03:36 +01:00
return string.Join(separator, items);
}
2016-11-10 01:03:49 +01:00
2016-11-30 11:01:22 +01:00
public static TeXString ToTeX(string target, string lineSeparator = "\n\\\\")
2016-11-10 01:03:49 +01:00
{
2016-11-30 11:01:22 +01:00
if (target == null) return null;
2016-11-10 01:03:49 +01:00
return new TeXString(target.NewLinesWith(lineSeparator));
}
2016-11-30 11:01:22 +01:00
public static bool GenerateEstimatePdf(this PdfGenerationViewModel Model)
{
string errorMsg = null;
var billdir = Model.DestDir;
var tempdir = Startup.SiteSetup.TempDir;
string name = Model.BaseFileName;
string fullname = new FileInfo(
System.IO.Path.Combine(tempdir, name)).FullName;
string ofullname = new FileInfo(
System.IO.Path.Combine(billdir, name)).FullName;
FileInfo fi = new FileInfo(fullname + ".tex");
FileInfo fo = new FileInfo(ofullname + ".pdf");
using (StreamWriter sw = new StreamWriter(fi.FullName))
{
sw.Write(Model.TeXSource);
}
if (!fi.Exists)
{
errorMsg = "Source write failed";
}
else
{
using (Process p = new Process())
{
p.StartInfo.WorkingDirectory = tempdir;
p.StartInfo = new ProcessStartInfo();
p.StartInfo.UseShellExecute = false;
p.StartInfo.FileName = "/usr/bin/texi2pdf";
p.StartInfo.Arguments = $"--batch --build-dir=. -o {fo.FullName} {fi.FullName}";
p.Start();
p.WaitForExit();
if (p.ExitCode != 0)
{
errorMsg = $"Pdf generation failed with exit code: {p.ExitCode}";
}
}
fi.Delete();
}
Model.Generated = fo.Exists;
Model.GenerationErrorMessage = new HtmlString(errorMsg);
return fo.Exists;
}
2016-11-10 01:03:49 +01:00
2016-11-09 14:03:57 +01:00
public static string RenderViewToString(
this Controller controller, IViewEngine engine,
2016-11-30 11:01:22 +01:00
IHttpContextAccessor httpContextAccessor,
2016-11-09 14:03:57 +01:00
string viewName, object model)
2016-11-30 11:01:22 +01:00
{
using (var sw = new StringWriter())
{
if (engine == null)
throw new InvalidOperationException("no engine");
// try to find the specified view
controller.TryValidateModel(model);
ViewEngineResult viewResult = engine.FindPartialView(controller.ActionContext, viewName);
// create the associated context
ViewContext viewContext = new ViewContext();
viewContext.ActionDescriptor = controller.ActionContext.ActionDescriptor;
viewContext.HttpContext = controller.ActionContext.HttpContext;
viewContext.TempData = controller.TempData;
viewContext.View = viewResult.View;
viewContext.Writer = sw;
// write the render view with the given context to the stringwriter
viewResult.View.RenderAsync(viewContext);
viewResult.EnsureSuccessful();
return sw.GetStringBuilder().ToString();
}
}
2016-11-06 02:03:36 +01:00
}
}