2019-10-25に更新

リッチなエディターを作ろうぜ☆(^~^)

.NET Core3.0 WPF RichTextBox 公開下書き

See also| リッチ・テキスト・ボックスって何だぜ☆(^~^)?

KITASHIRAKAWA_Chiyuri_80x100x8_01_Futu.gif
「 リッチ・テキスト・ボックスの使い方を覚えたし、何か作ってみるかだぜ☆?」

KIFUWARABE_80x100x8_01_Futu.gif
「 寝てればいいのに……☆」

パーシング

先頭行が # だったら緑色にする

20191024wpf30.png

KITASHIRAKAWA_Chiyuri_80x100x8_01_Futu.gif
「 コメントとかでよくあるだろ☆」

                AppliesStyle.Go(contents, richTextBox);

KITASHIRAKAWA_Chiyuri_80x100x8_01_Futu.gif
「 ↑呼出し側は、とりあえず、テキストと、リッチ・テキスト・ボックスを指定することにしよう☆」

                richTextBox.Document = AppliesStyle.Go(contents);

OKAZAKI_Yumemi_80x80x8_02_Syaberu.gif
「 ↑こうした方がよくない?」

KITASHIRAKAWA_Chiyuri_80x100x8_01_Futu.gif
「 あとで気づいた☆」

AppliesStyle.cs

namespace WpfApp2
{
    using System.Diagnostics;
    using System.Windows.Controls;
    using System.Windows.Documents;
    using System.Windows.Media;

    public static class AppliesStyle
    {
        public static FlowDocument Go(string contents)
        {
            FlowDocument flowDoc = new FlowDocument();
            Paragraph paragraph = new Paragraph();

            // 改行は "\r"、 "\r\n"、 "\n" の3パターンがあるが、どれが入ってるか分からない。
            // そこで、"\r\n" は "\n" に変換し、残った "\r" を "\n" に変換する。
            contents = contents.Replace("\r\n", "\n");
            contents = contents.Replace('\r', '\n');
            var lines = contents.Split('\n');
            foreach (var line in lines)
            {
                if (line!=string.Empty)
                {
                    Trace.WriteLine($"Line            | [{line}]");
                    if (line.StartsWith("#"))
                    {
                        var run = new Run(line);
                        run.Foreground = Brushes.Green;
                        paragraph.Inlines.Add(run);
                    }
                    else
                    {
                        paragraph.Inlines.Add(new Run(line));
                    }
                }

                // 改行。
                paragraph.Inlines.Add(new LineBreak());
            }
            flowDoc.Blocks.Add(paragraph);

            return flowDoc;
        }
    }
}

KITASHIRAKAWA_Chiyuri_80x100x8_01_Futu.gif
「 ↑とりあえず これでどうだぜ☆」

先頭行が $ だったら 文字を大きくして臙脂(えんじ)色にする

20191024wpf31.png

KIFUWARABE_80x100x8_01_Futu.gif
「 ファミコン・カラーか☆」

抜粋:

// private static Brush SolidEnjiBrush = new SolidColorBrush(Color.FromRgb(179, 66, 74));

    if (line.StartsWith("$"))
    {
        var run = new Run(line);
        run.Foreground = SolidEnjiBrush;
        run.FontSize += 8;
        paragraph.Inlines.Add(run);
    }

KITASHIRAKAWA_Chiyuri_80x100x8_01_Futu.gif
「 ↑とりあえず これでどうだぜ☆」

先頭行が $ だったら 朱(しゅ)色にする

20191024wpf32.png

KIFUWARABE_80x100x8_01_Futu.gif
「 朱は ダメなところに バッテンを付けるときの色じゃないのか☆?」

KITASHIRAKAWA_Chiyuri_80x100x8_01_Futu.gif
「 じゃ、あとで 色変えよ☆」

抜粋:

// private static Brush SolidSyuBrush = new SolidColorBrush(Color.FromRgb(239, 69, 74));

    else if (line.StartsWith("&"))
    {
        var run = new Run(line);
        run.Foreground = SolidSyuBrush;
        paragraph.Inlines.Add(run);
    }

KITASHIRAKAWA_Chiyuri_80x100x8_01_Futu.gif
「 ↑色を付けるのは簡単だな☆」

        /// <summary>
        /// 藍色。
        /// </summary>
        private static Brush SolidAiBrush = new SolidColorBrush(Color.FromRgb(35, 71, 148));

{ から } までマーキングする。ただし {{}} は無視する

20191024wpf33.png

KITASHIRAKAWA_Chiyuri_80x100x8_01_Futu.gif
「 ↑パーサーを作るというやつだぜ☆」

抜粋:

                    else
                    {
                        // { から } までに背景色を付ける。
                        // ただし、 {{}} は無視する。

                        var curr = 0;
                        while (curr < line.Length)
                        {
                            int next;

                            // ひら文
                            for (; ; )
                            {
                                next = line.IndexOf('{', curr);
                                if (next < 0)
                                {
                                    paragraph.Inlines.Add(new Run(line.Substring(curr)));
                                    goto line_loop;
                                }

                                if (next + 1 < line.Length && line[next + 1] == '{')
                                {
                                    paragraph.Inlines.Add(new Run(line.Substring(curr, next + 2 - curr)));
                                    curr = next + 2;
                                }
                                else
                                {
                                    break;
                                }
                            }

                            // ひら文
                            var run = new Run(line.Substring(curr, next-curr));
                            paragraph.Inlines.Add(run);

                            // マーカー
                            curr = next;
                            for (; ; )
                            {
                                next = line.IndexOf('}', curr);
                                if (next < 0)
                                {
                                    // エラー
                                    run = new Run(line.Substring(curr));
                                    run.Background = SolidSyuBrush;
                                    paragraph.Inlines.Add(run);
                                    goto line_loop;
                                }

                                if (next + 1 < line.Length && line[next + 1] == '}')
                                {
                                    run = new Run(line.Substring(curr, next + 2 - curr));
                                    run.Background = Brushes.Yellow;
                                    paragraph.Inlines.Add(run);
                                    curr = next + 2;
                                }
                                else
                                {
                                    break;
                                }
                            }

                            next += 1;
                            run = new Run(line.Substring(curr, next-curr));
                            run.Background = Brushes.Yellow;
                            paragraph.Inlines.Add(run);

                            // 次のループへ。
                            curr = next;
                        }
                    line_loop:
                        ;
                    }

OKAZAKI_Yumemi_80x80x8_02_Syaberu.gif
「 書式チェックまで やってくれないの?」

KITASHIRAKAWA_Chiyuri_80x100x8_01_Futu.gif
「 作り込みは時間のあるときだな☆」

<書きかけ>

何度でもクリック!→

むずでょ

光速のアカウント凍結されちゃったんで……。ゲームプログラムを独習中なんだぜ☆電王戦IIに出た棋士もコンピューターもみんな好きだぜ☆▲(パソコン将棋)WCSC29一次予選36位、SDT5予選42位▲(パソコン囲碁)AI竜星戦予選16位

Crieitは個人で開発中です。 興味がある方は是非記事の投稿をお願いします! どんな軽い内容でも嬉しいです。
なぜCrieitを作ろうと思ったか

また、「こんな記事が読みたいけど見つからない!」という方は是非記事投稿リクエストボードへ!

こじんまりと作業ログやメモ、進捗を書き残しておきたい方はボード機能をご利用ください!

ボードとは?

むずでょ の最近の記事