/// <summary> /// /// </summary> private void CreateFile(MyContent inf) { var convertedData = string.Empty; if (inf.ConvertedData != null && !string.IsNullOrEmpty(inf.ConvertedData.ToString())) { convertedData = inf.ConvertedData.ToString(); } // テンプレートファイルを取得 var templateFi = GetTemplateFileInfo(inf.Yaml == null ? null : inf.Yaml.TemplateFileName); var templateData = string.Empty; if (templateFi.Exists && templateFi.Extension == ".cshtml") { using (var reader = templateFi.OpenText()) { templateData = reader.ReadToEnd(); } } FileInfo destFi = null; if (inf.PostDateFromFileName.HasValue) { // Article var odi = new DirectoryInfo(Path.Combine(this.OutputDi.FullName, inf.OutputBaseFolderName)); if (odi.Exists) { // すでに存在したらYMDをつけて作る odi = new DirectoryInfo(Path.Combine(this.OutputDi.FullName, string.Format("{0}-{1}", inf.OutputBaseFolderName, inf.PostDateFromFileName.Value.ToString("yyyyMMdd")))); if (odi.Exists) { // TODO: YMDをつけても存在したら諦める? } else { odi.Create(); } } else { odi.Create(); } destFi = new FileInfo(Path.Combine(odi.FullName, "index.html")); } else { // Page destFi = new FileInfo(inf.OutputFilePath); } if (!string.IsNullOrEmpty(templateData) && destFi != null) { try { var canonicalLink = string.Empty; { var rp = destFi.FullName.Replace(this.OutputDi.FullName, string.Empty); if (string.IsNullOrEmpty(rp)) { canonicalLink = "/"; } else { canonicalLink = rp.Replace(Path.DirectorySeparatorChar.ToString(), "/"); } } var model = new { SiteLogo = "Title(仮)", PageTitle = inf.Yaml == null ? "no-title" : inf.Yaml.PageTitle, Body = convertedData, Copyright = string.Empty, RecentPosts = new List <string>(), EmbeddedCssString = this.EmbeddedCssString, CanonicalLink = canonicalLink }; try { var config = new TemplateServiceConfiguration() { BaseTemplateType = typeof(HtmlSupportTemplateBase <>) }; var result = string.Empty; using (var service = RazorEngineService.Create(config)) { result = service.RunCompile(templateData, templateFi.Name, null, model); } // 1行ずつファイル出力 // がばっと書いてもいいんだけどね。 using (var reader = new StringReader(result)) { using (var writer = new StreamWriter(destFi.FullName, true, new System.Text.UTF8Encoding(false))) { while (reader.Peek() > -1) { writer.WriteLine(reader.ReadLine()); } } } } catch (Exception ex) { Console.WriteLine(ex.ToString()); } } catch (Exception ex) { Console.WriteLine(ex.ToString()); } } }
/// <summary> /// /// </summary> private void Generate(DirectoryInfo srcDi) { if (srcDi == null) { return; } // 出力フォルダを作成 DirectoryInfo destDi = null; var rp = srcDi.FullName.Replace(this.InputDi.FullName, ""); if (string.IsNullOrEmpty(rp)) { // ルートフォルダ(inputフォルダ) destDi = new DirectoryInfo(this.OutputDi.FullName); } else { if (rp.Substring(0, 1) == Path.DirectorySeparatorChar.ToString()) { rp = rp.Substring(1); } destDi = new DirectoryInfo(Path.Combine(this.OutputDi.FullName, rp)); } // 出力フォルダがなければ作る if (!destDi.Exists) { destDi.Create(); } // 入力フォルダのサブフォルダ foreach (var targetDi in srcDi.GetDirectories()) { // 除外フォルダであればスキップ if (this.IgnoreDiList.Any(p => p.FullName == targetDi.FullName)) { continue; } Generate(targetDi); } // 入力フォルダ配下のファイル foreach (var copyFi in srcDi.GetFiles()) { // 入力ファイルの振り分け var isMarkdownFile = false; var isArticle = false; var isPage = false; // Markdownかどうか var extension = copyFi.Extension; if (!string.IsNullOrEmpty(extension) && extension.ToLower() == ".md") { isMarkdownFile = true; } // ArticleかPageか if (isMarkdownFile) { var contentInfo = new MyContent() { InputFi = copyFi, Yaml = new YamlMetaData() }; var fileNameWithoutExtension = Path.GetFileNameWithoutExtension(copyFi.FullName); var r = new Regex(@"(\d{4}\d{2}\d{2})-(.*)", RegexOptions.IgnoreCase); var m = r.Match(fileNameWithoutExtension); if (m.Success) { // ファイル名から取得した日付とタイトルが有効であれば Article と判定 var ymd = ToDateTime(m.Groups[1].Value); var title = m.Groups[2].Value; if (ymd.HasValue && !string.IsNullOrEmpty(title)) { isArticle = true; contentInfo.OutputBaseFolderName = title; contentInfo.PostDateFromFileName = ymd; } else { // TODO: ArticleっぽいのにPageに判定されそうなやつは警告出しませんか。 } } // ArticleでなければPageにする if (!isArticle) { var outputFileName = string.Format("{0}.html", fileNameWithoutExtension); if (srcDi.GetFiles(outputFileName).Length > 0) { // TODO: ひとまず標準出力で警告 Console.WriteLine("Warning: いるからコピーしないよ。" + fileNameWithoutExtension); } else { isPage = true; contentInfo.OutputFilePath = Path.Combine(destDi.FullName, string.Format("{0}.html", fileNameWithoutExtension)); } } // Article または Page と判定されたら変換する if (isArticle || isPage) { try { // YAMLメタデータの解析結果を格納 SetYamlMetaData(contentInfo); // Pandocの起動設定 var psi = new ProcessStartInfo(); psi.FileName = "pandoc.exe"; psi.Arguments = string.Format("-f markdown-auto_identifiers -t html5 {0}", contentInfo.InputFi.FullName); // コンソール・ウィンドウを開かない psi.CreateNoWindow = true; // シェル機能を使わない // コンソールアプリの場合、シェル機能を使うにしておくとコンソール・ウィンドウが開いてしまうため。 psi.UseShellExecute = false; // UseShellExecute を true にしておくと、OSのファイル関連付けに応じてファイルの開き方を決める。 // たとえば、xlsxであればExcelで開き、txtはメモ帳で開く。exeならそのまま実行する。 // 標準出力をストリームに書き込む psi.RedirectStandardOutput = true; psi.StandardOutputEncoding = new System.Text.UTF8Encoding(false); // 標準出力の文字コードを指定 // プロセス終了時にイベントを発生させる var p = new Process(); p.Exited += new EventHandler(pandoc_Exited); p.EnableRaisingEvents = true; // p.OutputDataReceived += pandoc_OutputDataReceived; // 起動 p.StartInfo = psi; if (p.Start()) { pandocStartedCount++; p.BeginOutputReadLine(); // WaitForExitを指定すると、おそらく非同期にならない // p.WaitForExit(); // p.CancelOutputRead(); convertedDict.Add(p.Id, new StringBuilder()); this.MarkdownFiles.Add(p.Id, contentInfo); } } catch (Exception ex) { Console.WriteLine(contentInfo.InputFi.FullName); Console.WriteLine(ex.ToString()); } } } else { copyFi.CopyTo(Path.Combine(destDi.FullName, copyFi.Name)); } } }