Пример #1
0
        /// <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());
                }
            }
        }
Пример #2
0
        /// <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));
                }
            }
        }