using ICSharpCode.AvalonEdit.Document;
using ICSharpCode.AvalonEdit.Folding;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;

namespace LunarSF.SHomeWorkshop.LunarMarkdownEditor
{
    /// <summary>
    /// 此类用以定义编辑器的折叠区。
    /// </summary>
    class CustomFoldingStrategy : AbstractFoldingStrategy
    {
        private ICSharpCode.AvalonEdit.TextEditor edit;
        /// <summary>
        /// 要应用折叠功能的编辑器。
        /// </summary>
        public ICSharpCode.AvalonEdit.TextEditor Edit { get { return this.edit; } }

        /// <summary>
        /// [构造方法]创建一个新的折叠区。
        /// </summary>
        public CustomFoldingStrategy(ICSharpCode.AvalonEdit.TextEditor edit)
        {
            this.edit = edit;
        }

        /// <summary>
        /// 为特定文档创建 NewFolding 对象集。
        /// </summary>
        public override IEnumerable<NewFolding> CreateNewFoldings(TextDocument document, out int firstErrorOffset)
        {
            firstErrorOffset = -1;
            return CreateNewFoldings(document);
        }

        /// <summary>
        /// 为特定文档创建 NewFolding 对象集。
        /// </summary>
        public IEnumerable<NewFolding> CreateNewFoldings(ITextSource document)
        {
            List<NewFolding> newFoldings = new List<NewFolding>();

            #region 使六级标题都支持折叠
            List<HeaderInfo> preHeadersInfos = new List<HeaderInfo>();

            for (int i = 1; i <= edit.LineCount; i++)
            {
                var line = edit.Document.GetLineByNumber(i);

                string text = edit.Document.GetText(line.Offset, line.Length);

                if (text.StartsWith("#") == false && CustomMarkdownSupport.IsTaskLine(text) == false) continue;

                var headerText = GetHeaderOfTitleOrTaskListItem(text);
                var contentText = GetContentOfHeaderOrTaskListItem(text);

                var newHeaderInfo = new HeaderInfo()
                {
                    HeaderText = headerText,
                    ContentText = contentText,
                    Length = headerText.Length,
                    Offset = line.Offset,
                    EndOffset = line.EndOffset,
                };

                if (preHeadersInfos.Count <= 0)
                {
                    preHeadersInfos.Add(newHeaderInfo);
                    continue;
                }

                for (int j = preHeadersInfos.Count - 1; j >= 0; j--)
                {
                    if (newHeaderInfo.Length <= preHeadersInfos[j].Length)
                    {
                        var endOffset = newHeaderInfo.Offset - 2;//-2是\r\n的宽度

                        //如果在这个标题只有一行,不折叠
                        if (endOffset > preHeadersInfos[j].EndOffset)
                        {
                            var newFolding = new NewFolding(preHeadersInfos[j].Offset, newHeaderInfo.Offset - 2)
                            {
                                Name = BuildHeaderOrTaskListItemHeader(preHeadersInfos[j].HeaderText) +
                                    (string.IsNullOrEmpty(preHeadersInfos[j].ContentText) ?
                                    "... " :
                                    preHeadersInfos[j].ContentText) + " ※ ",
                            };
                            newFoldings.Add(newFolding);
                        }
                        preHeadersInfos.RemoveAt(j);
                    }
                }

                preHeadersInfos.Add(newHeaderInfo);
            }

            //到最后一行,看看要不要添加折叠块。
            if (preHeadersInfos.Count > 0)
            {
                var lastLine = this.edit.Document.GetLineByNumber(this.edit.Document.LineCount);
                if (lastLine != null)
                {
                    var lastLineText = this.edit.Document.GetText(lastLine);

                    if (lastLineText.StartsWith("#") == false && CustomMarkdownSupport.IsTaskLine(lastLineText) == false)
                    {

                        for (int j = preHeadersInfos.Count - 1; j >= 0; j--)
                        {
                            var endOffset = edit.Document.Lines.Last().Offset;//最后一行,没有\r\n,不用 - 2;

                            //如果在这个标题只有一行,不折叠
                            if (endOffset > preHeadersInfos[j].EndOffset)
                            {
                                newFoldings.Add(new NewFolding(preHeadersInfos[j].Offset, endOffset)
                                {
                                    Name = BuildHeaderOrTaskListItemHeader(preHeadersInfos[j].HeaderText) +
                                        (string.IsNullOrEmpty(preHeadersInfos[j].ContentText) ?
                                        "... " :
                                        preHeadersInfos[j].ContentText + " ※ "),
                                });
                            }
                            preHeadersInfos.RemoveAt(j);
                        }
                    }
                }
            }
            #endregion

            #region 添加试题所需要的折叠块
            Stack<int> startOffsets = new Stack<int>();
            string openingMark = "试题>>";
            string closingMark = "〓〓〓〓〓〓";

            for (int i = 1; i <= edit.LineCount; i++)
            {
                var line = edit.Document.GetLineByNumber(i);
                var preLine = line.PreviousLine;

                string text = edit.Document.GetText(line.Offset, line.Length).TrimStart();

                if (text.StartsWith(openingMark))
                {
                    if (preLine != null && startOffsets.Count > 0)
                    {
                        int startOffset = startOffsets.Pop();
                        // 首尾标记在同一行时不折叠。
                        if (startOffset < preLine.Offset)
                        {
                            newFoldings.Add(new NewFolding(startOffset, preLine.EndOffset)
                            {
                                Name = openingMark,
                                IsSpecial = true,
                            });
                        }
                    }

                    startOffsets.Push(line.Offset);
                }
                else if (text.StartsWith(closingMark) && startOffsets.Count > 0)
                {
                    int startOffset = startOffsets.Pop();
                    // 首尾标记在同一行时不折叠。
                    if (startOffset < line.EndOffset)
                    {
                        newFoldings.Add(new NewFolding(startOffset, line.EndOffset)
                        {
                            Name = openingMark,
                            IsSpecial = true,
                        });
                    }
                }
            }
            #endregion

            #region 使二维文字表支持折叠
            int fstTextTableLineStartOffset = -1;
            int fstTextTableLineEndOffset = -1;
            int preTextTableLineStartOffset = -1;
            int preTextTableLineEndOffset = -1;
            int currentLineEndOffset = -1;
            string tableTitle = "";

            for (int i = 1; i <= edit.LineCount; i++)
            {
                var line = edit.Document.GetLineByNumber(i);
                currentLineEndOffset = line.EndOffset;
                string lineText = edit.Document.GetText(line.Offset, line.Length);

                if (lineText.IndexOf('|') >= 0 || lineText.IndexOf('|') >= 0)
                {
                    if (fstTextTableLineStartOffset < 0)
                    {
                        preTextTableLineStartOffset =
                            fstTextTableLineStartOffset = line.Offset;
                        preTextTableLineEndOffset =
                            fstTextTableLineEndOffset = line.EndOffset;

                        string[] pieces = lineText.Split(new char[] { '|', '|' }, StringSplitOptions.RemoveEmptyEntries);
                        foreach (var piece in pieces)
                        {
                            var text = piece.Trim(new char[] { ' ', ' ', '\t' });
                            if (string.IsNullOrWhiteSpace(text) == false)
                            {
                                tableTitle = text;
                                break;
                            }
                        }
                    }
                    else
                    {
                        preTextTableLineStartOffset = line.Offset;
                        preTextTableLineEndOffset = line.EndOffset;
                    }
                }
                else
                {
                    if (CustomMarkdownSupport.IsCommentLine(lineText))
                    {
                        preTextTableLineStartOffset = line.Offset;
                        preTextTableLineEndOffset = line.EndOffset;
                        continue;
                    }
                    else
                    {
                        if (fstTextTableLineStartOffset >= 0 && preTextTableLineEndOffset >= 0)
                        {
                            var ttfolding = new NewFolding(fstTextTableLineStartOffset, preTextTableLineEndOffset)//不该把同级行折叠起来
                            {
                                Name = $"┣{(string.IsNullOrWhiteSpace(tableTitle) ? "文字表" : tableTitle)}┫",
                                IsSpecial = true,
                            };

                            newFoldings.Add(ttfolding);

                            //还原
                            fstTextTableLineEndOffset = -1;
                            fstTextTableLineStartOffset = -1;
                            preTextTableLineEndOffset = -1;
                            preTextTableLineStartOffset = -1;
                        }
                    }
                }
            }

            //防止最后一行也是二维文字表行。
            if (fstTextTableLineStartOffset >= 0 && preTextTableLineEndOffset >= 0)
            {
                var ttfolding = new NewFolding(fstTextTableLineStartOffset,
                    (currentLineEndOffset >= 0 ? currentLineEndOffset : preTextTableLineEndOffset))//不该把同级行折叠起来
                {
                    Name = $"二维文字表{(string.IsNullOrWhiteSpace(tableTitle) ? "" : ":")}{tableTitle}",
                    IsSpecial = true,
                };

                newFoldings.Add(ttfolding);

                //还原
                fstTextTableLineEndOffset = -1;
                fstTextTableLineStartOffset = -1;
                preTextTableLineEndOffset = -1;
                preTextTableLineStartOffset = -1;
            }
            #endregion

            #region 使引用块支持折叠
            int fstBlockQuoteLineStartOffset = -1;
            int fstBlockQuoteLineEndOffset = -1;
            int preBlockQuoteLineStartOffset = -1;
            int preBlockQuoteLineEndOffset = -1;
            int currentBlockQuoteLineEndOffset = -1;
            string blockQuoteTitle = "";

            for (int i = 1; i <= edit.LineCount; i++)
            {
                var line = edit.Document.GetLineByNumber(i);
                currentBlockQuoteLineEndOffset = line.EndOffset;
                string lineText = edit.Document.GetText(line.Offset, line.Length);

                if (CustomMarkdownSupport.IsBlockQuoteLine(lineText))
                {
                    if (fstBlockQuoteLineStartOffset < 0)
                    {
                        preBlockQuoteLineStartOffset =
                            fstBlockQuoteLineStartOffset = line.Offset;
                        preBlockQuoteLineEndOffset =
                            fstBlockQuoteLineEndOffset = line.EndOffset;

                        var text = lineText.Trim(new char[] { ' ', ' ', '\t' });
                        Regex regexBlockQuoter = new Regex(@"^[  ]{0,3}([>》〉]{1}[  ]{0,}){1,}");
                        var matchBlockQuoter = regexBlockQuoter.Match(text);
                        if (matchBlockQuoter != null && matchBlockQuoter.Success)
                        {
                            text = text.Substring(matchBlockQuoter.Length);
                        }

                        if (string.IsNullOrWhiteSpace(blockQuoteTitle) && string.IsNullOrWhiteSpace(text) == false)//保留第一行作标题。
                        {
                            blockQuoteTitle = text;
                            if (blockQuoteTitle.Length > 36)
                            {
                                blockQuoteTitle = blockQuoteTitle.Substring(0, 36) + "...";
                            }
                        }
                    }
                    else
                    {
                        preBlockQuoteLineStartOffset = line.Offset;
                        preBlockQuoteLineEndOffset = line.EndOffset;
                    }
                }
                else
                {
                    if (fstBlockQuoteLineStartOffset >= 0 && preBlockQuoteLineEndOffset >= 0)
                    {
                        var bqfolding = new NewFolding(fstBlockQuoteLineStartOffset, preBlockQuoteLineEndOffset)//不该把同级行折叠起来
                        {
                            Name = $"> {(string.IsNullOrWhiteSpace(blockQuoteTitle) ? "引用块" : blockQuoteTitle)}",
                            IsSpecial = false,
                        };

                        newFoldings.Add(bqfolding);

                        //还原
                        fstBlockQuoteLineEndOffset = -1;
                        fstBlockQuoteLineStartOffset = -1;
                        preBlockQuoteLineEndOffset = -1;
                        preBlockQuoteLineStartOffset = -1;
                        blockQuoteTitle = null;
                    }
                }
            }

            //防止最后一行也是引用块行。
            if (fstBlockQuoteLineStartOffset >= 0 && preBlockQuoteLineEndOffset >= 0)
            {
                var bqfolding = new NewFolding(fstBlockQuoteLineStartOffset,
                    (currentBlockQuoteLineEndOffset >= 0 ? currentBlockQuoteLineEndOffset : preBlockQuoteLineEndOffset))//不该把同级行折叠起来
                {
                    Name = $"引用块{(string.IsNullOrWhiteSpace(blockQuoteTitle) ? "" : ":")}{blockQuoteTitle}",
                    IsSpecial = false,
                };

                newFoldings.Add(bqfolding);

                //还原
                fstBlockQuoteLineEndOffset = -1;
                fstBlockQuoteLineStartOffset = -1;
                preBlockQuoteLineEndOffset = -1;
                preBlockQuoteLineStartOffset = -1;
                blockQuoteTitle = null;
            }
            #endregion

            #region 使树型文字表支持折叠
            List<TreeListTextLine> foldTreeLines = null;
            List<List<TreeListTextLine>> listss = new List<List<TreeListTextLine>>();
            //双层列表嵌套,这是为了解决多个不连续的树型文字表

            for (int i = 1; i <= edit.LineCount; i++)
            {
                var line = edit.Document.GetLineByNumber(i);
                string lineText = edit.Document.GetText(line.Offset, line.Length);

                string header, tail; int level;
                if (MarkDownEditorBase.IsTreeListLine(lineText, out header, out tail, out level))
                {
                    var ti = new TreeListTextLine()
                    {
                        Line = line,
                        HeaderTextArray = header.ToCharArray(),
                        OldLevel = level,
                        NewLevel = level,
                        OldText = lineText,
                        NewText = lineText,
                        TailText = tail,
                    };

                    if (foldTreeLines == null)
                    {
                        foldTreeLines = new List<TreeListTextLine>();
                        listss.Add(foldTreeLines);
                    }

                    foldTreeLines.Add(ti);
                }
                else
                {
                    if (foldTreeLines != null) foldTreeLines = null;
                }
            }

            foreach (List<TreeListTextLine> list in listss)
            {
                if (list.Count <= 1) continue;

                for (int j = 0; j < list.Count - 1; j++)//最后一个没必要折叠
                {
                    TreeListTextLine tltl = list[j];
                    NewFolding ttfolding = null;

                    for (int k = j + 1; k < list.Count; k++)//但最后一个有必要判断是否完成折叠
                    {
                        var nexttltl = list[k];
                        if (nexttltl.NewLevel <= tltl.NewLevel)
                        {
                            //这个对象并非无意义,但不能放到下一层判断之中。
                            ttfolding = new NewFolding(tltl.Line.Offset, nexttltl.Line.Offset - 2)//不该把同级行折叠起来
                            {
                                Name = tltl.NewText,
                                IsSpecial = true,
                            };

                            if (nexttltl.Line.LineNumber > tltl.Line.LineNumber + 1)//如果只有一行,不加折叠
                            {
                                newFoldings.Add(ttfolding);
                            }
                            break;
                        }
                    }

                    if (ttfolding == null && tltl.Line.LineNumber < list[list.Count - 1].Line.LineNumber)
                    {
                        ttfolding = new NewFolding(tltl.Line.Offset, list[list.Count - 1].Line.EndOffset)
                        {
                            Name = tltl.NewText,
                            IsSpecial = true,
                        };
                        newFoldings.Add(ttfolding);
                    }
                }
            }
            #endregion

            #region 用户自定义 JavaScript 代码块
            string startRegionScript = @"^[<][Ss][Cc][Rr][Ii][Pp][Tt]([ ]{1,}.*)?[>]";
            string endRegionScript = @"[<][/][Ss][Cc][Rr][Ii][Pp][Tt][>]";                 //短的一行就可以。

            Stack<LineInfo> regionStartLinesStackScript = new Stack<LineInfo>();

            for (int i = 1; i <= edit.LineCount; i++)
            {
                var lineScript = edit.Document.GetLineByNumber(i);

                string lineTextScript = edit.Document.GetText(lineScript.Offset, lineScript.Length);
                Regex regexStartScript = new Regex(startRegionScript);
                var matchStartScript = regexStartScript.Match(lineTextScript);

                if (matchStartScript != null && matchStartScript.Success)
                {
                    regionStartLinesStackScript.Push(new LunarMarkdownEditor.LineInfo()
                    {
                        Line = lineScript,
                        LineText = lineTextScript,
                        HeaderText = lineTextScript.Substring(matchStartScript.Length),
                    });
                }
                else
                {
                    Regex regexEndScript = new Regex(endRegionScript);
                    var matchEndScript = regexEndScript.Match(lineTextScript);

                    if (matchEndScript != null && matchEndScript.Success)// && preRegionLine != null)
                    {
                        if (regionStartLinesStackScript.Count > 0)
                        {
                            var preRegionLineScript = regionStartLinesStackScript.Pop();
                            newFoldings.Add(new NewFolding(preRegionLineScript.Line.Offset, lineScript.EndOffset)
                            {
                                Name = "<Script />",
                                IsSpecial = true,
                            });
                        }
                    }
                }
            }
            #endregion

            #region 用户自定义内部样式表区域
            string startRegionStyle = @"^[<][Ss][Tt][Yy][Ll][Ee]([ ]{1,}.*)?[>]";
            string endRegionStyle = @"[<][/][Ss][Tt][Yy][Ll][Ee][>]";                 //短的一行就可以。

            Stack<LineInfo> regionStartLinesStackStyle = new Stack<LineInfo>();

            for (int i = 1; i <= edit.LineCount; i++)
            {
                var lineStyle = edit.Document.GetLineByNumber(i);

                string lineTextStyle = edit.Document.GetText(lineStyle.Offset, lineStyle.Length);
                Regex regexStartStyle = new Regex(startRegionStyle);
                var matchStartStyle = regexStartStyle.Match(lineTextStyle);

                if (matchStartStyle != null && matchStartStyle.Success)
                {
                    regionStartLinesStackStyle.Push(new LunarMarkdownEditor.LineInfo()
                    {
                        Line = lineStyle,
                        LineText = lineTextStyle,
                        HeaderText = lineTextStyle.Substring(matchStartStyle.Length),
                    });
                }
                else
                {
                    Regex regexEndStyle = new Regex(endRegionStyle);
                    var matchEndStyle = regexEndStyle.Match(lineTextStyle);

                    if (matchEndStyle != null && matchEndStyle.Success)// && preRegionLine != null)
                    {
                        if (regionStartLinesStackStyle.Count > 0)
                        {
                            var preRegionLineStyle = regionStartLinesStackStyle.Pop();
                            newFoldings.Add(new NewFolding(preRegionLineStyle.Line.Offset, lineStyle.EndOffset)
                            {
                                Name = "<Style />",
                                IsSpecial = true,
                            });
                        }
                    }
                }
            }
            #endregion

            #region 添加方块文本
            string startRegionS = @"^[  ]{0,3}(\[[  \t]*(?!(.*\].*)))";
            string endRegionS = @"^[  ]{0,3}\].*";

            Stack<LineInfo> regionStartLinesStackS = new Stack<LineInfo>();

            for (int i = 1; i <= edit.LineCount; i++)
            {
                var lineS = edit.Document.GetLineByNumber(i);

                string lineTextS = edit.Document.GetText(lineS.Offset, lineS.Length);
                Regex regexStartS = new Regex(startRegionS);
                var matchStartS = regexStartS.Match(lineTextS);

                if (matchStartS != null && matchStartS.Success)
                {
                    regionStartLinesStackS.Push(new LunarMarkdownEditor.LineInfo()
                    {
                        Line = lineS,
                        LineText = lineTextS,
                        HeaderText = lineTextS.Substring(matchStartS.Length),
                    });
                }
                else
                {
                    Regex regexEndS = new Regex(endRegionS);
                    var matchEndS = regexEndS.Match(lineTextS);

                    if (matchEndS != null && matchEndS.Success)// && preRegionLine != null)
                    {
                        if (regionStartLinesStackS.Count > 0)
                        {
                            var preRegionLineS = regionStartLinesStackS.Pop();
                            newFoldings.Add(new NewFolding(preRegionLineS.Line.Offset, lineS.EndOffset)
                            {
                                Name = (preRegionLineS.HeaderText == null ? $"[{lineTextS.Substring(matchEndS.Length)}]" : $"[{preRegionLineS.HeaderText}]"),
                                IsSpecial = true,
                            });
                        }
                    }
                }
            }
            #endregion

            #region 添加自定义折叠块
            string startRegion = @"^[  ]{0,3}([rrRR][eeEE][ggGG][iiII][ooOO][nnNN][  \t]*)?([!?!?IWEQIWEQiweqiweq][  \t]*)?\{[  \t]*";
            string endRegion = @"^[  ]{0,3}\}[  \t]*([rrRR][eeEE][ggGG][iiII][ooOO][nnNN][  \t]*)?";

            Stack<LineInfo> regionStartLinesStack = new Stack<LineInfo>();

            for (int i = 1; i <= edit.LineCount; i++)
            {
                var line = edit.Document.GetLineByNumber(i);

                string lineText = edit.Document.GetText(line.Offset, line.Length);
                Regex regexStart = new Regex(startRegion);
                var matchStart = regexStart.Match(lineText);

                if (matchStart != null && matchStart.Success)
                {
                    regionStartLinesStack.Push(new LunarMarkdownEditor.LineInfo()
                    {
                        Line = line,
                        LineText = lineText,
                        HeaderText = lineText.Substring(matchStart.Length),
                    });
                }
                else
                {
                    Regex regexEnd = new Regex(endRegion);
                    var matchEnd = regexEnd.Match(lineText);

                    if (matchEnd != null && matchEnd.Success)// && preRegionLine != null)
                    {
                        if (regionStartLinesStack.Count > 0)
                        {
                            var preRegionLine = regionStartLinesStack.Pop();
                            newFoldings.Add(new NewFolding(preRegionLine.Line.Offset, line.EndOffset)
                            {
                                Name = (preRegionLine.HeaderText == null ? $"{{{lineText.Substring(matchEnd.Length)}}}" : $"{{{preRegionLine.HeaderText}}}"),
                                IsSpecial = true,
                            });
                        }
                    }
                }
            }
            #endregion

            #region 单行图像链接折叠或文件链接
            Regex regImageOrFileHeader = new Regex(@"(?<=(!?\[)).*(?=\])");
            for (int i = 1; i <= edit.LineCount; i++)
            {
                var line = edit.Document.GetLineByNumber(i);

                string lineText = edit.Document.GetText(line.Offset, line.Length);

                if (CustomMarkdownSupport.IsImageLinkLine(lineText))
                {
                    var matchImageHeader = regImageOrFileHeader.Match(lineText);
                    newFoldings.Add(new NewFolding(line.Offset, line.EndOffset)
                    {
                        Name = (matchImageHeader.Success && string.IsNullOrWhiteSpace(matchImageHeader.Value) == false) ? $"![{matchImageHeader.Value}]" : "![图像链接]",
                        IsSpecial = true,
                    });
                }
                else if (CustomMarkdownSupport.IsFileLinkLine(lineText))
                {
                    var matchFileHeader = regImageOrFileHeader.Match(lineText);
                    newFoldings.Add(new NewFolding(line.Offset, line.EndOffset)
                    {
                        Name = (matchFileHeader.Success && string.IsNullOrWhiteSpace(matchFileHeader.Value) == false) ? $"[{matchFileHeader.Value}]" : "[文件链接]",
                        IsSpecial = true,
                    });
                }
            }
            #endregion

            newFoldings.Sort((a, b) => a.StartOffset.CompareTo(b.StartOffset));
            return newFoldings;
        }

        /// <summary>
        /// 生成标题或任务列表被折叠时显示的文本。
        /// </summary>
        /// <param name="sourceText">如果是 Header,只应传入“###”部分,不应包括后面的内容。</param>
        private string BuildHeaderOrTaskListItemHeader(string sourceText)
        {
            if (string.IsNullOrWhiteSpace(sourceText)) return "";

            if (sourceText.StartsWith("[-]") || sourceText.StartsWith("[-]")) return "[-] ";
            if (sourceText.StartsWith("[+]")) return "[+] ";
            if (sourceText.StartsWith("[%]")) return "[%] ";
            if (sourceText.StartsWith("[#]")) return "[#] ";

            var level = sourceText.Length;
            switch (level)
            {
                case 1: return "Ⅰ ※ ";
                case 2: return "Ⅱ ※ ";
                case 3: return "Ⅲ ※ ";
                case 4: return "Ⅳ ※ ";
                case 5: return "Ⅴ ※ ";
                case 6: return "Ⅵ ※ ";
                default: return "";
            }
        }

        /// <summary>
        /// 取标题或任务列表的文字部分(去除标志文本、空白字符等)。
        /// </summary>
        /// <param name="src">源文本</param>
        public string GetContentOfHeaderOrTaskListItem(string src)
        {
            if (string.IsNullOrEmpty(src)) return "";

            if (CustomMarkdownSupport.IsTaskLine(src)) return CustomMarkdownSupport.GetContentOfTaskListItem(src);

            if (src.StartsWith("#") == false) return "";

            if (src.StartsWith("######")) return src.Substring(6);
            if (src.StartsWith("#####")) return src.Substring(5);
            if (src.StartsWith("####")) return src.Substring(4);
            if (src.StartsWith("###")) return src.Substring(3);
            if (src.StartsWith("##")) return src.Substring(2);
            if (src.StartsWith("#")) return src.Substring(1);

            return "";
        }

        /// <summary>
        /// 取标题或任务列表的标志文本(不包含其它表示具体意思的文本)。
        /// </summary>
        /// <param name="src">源文本</param>
        public string GetHeaderOfTitleOrTaskListItem(string src)
        {
            if (string.IsNullOrEmpty(src)) return "";
            if (CustomMarkdownSupport.IsTaskLine(src))
            {
                return CustomMarkdownSupport.GetHeaderOfTaskListItem(src);
            }
            if (src.StartsWith("#") == false) return "";

            if (src.StartsWith("######")) return "######";
            if (src.StartsWith("#####")) return "#####";
            if (src.StartsWith("####")) return "####";
            if (src.StartsWith("###")) return "###";
            if (src.StartsWith("##")) return "##";
            if (src.StartsWith("#")) return "#";

            return "";
        }
    }

    /// <summary>
    /// 提供六级标题的折叠功能时,此类用于记录某个标题的相关位置信息。
    /// </summary>
    public class HeaderInfo
    {
        private string headerText = "...";
        public string HeaderText
        {
            get { return this.headerText; }
            set { this.headerText = value; }
        }

        private string contentText = "#";
        public string ContentText
        {
            get { return contentText; }
            set { this.contentText = value; }
        }

        private int length = 1;
        public int Length
        {
            get { return this.length; }
            set { this.length = value; }
        }

        private int offset = -1;
        public int Offset
        {
            get { return this.offset; }
            set { this.offset = value; }
        }

        private int endOffset = -1;
        public int EndOffset
        {
            get { return this.endOffset; }
            set { this.endOffset = value; }
        }

    }

    public class LineInfo
    {
        public DocumentLine Line { get; set; }
        public string LineText { get; set; }
        public string HeaderText { get; set; }
    }
}