Exemplo n.º 1
0
        /// <summary>
        /// Добавляет секции содержания и преамбулы к документу.
        /// </summary>
        /// <param name="content">Содержимое страницы.</param>
        /// <param name="rootSection">Корневая секция</param>
        /// <returns>Корневой узел с добавленными вспомогательными узлами.</returns>
        public List <PageSection> AppendAdditionalSections(string content, PageSection rootSection)
        {
            var maxLevel = 0;

            if (rootSection.Children.Count > 0)
            {
                maxLevel = rootSection.Children.Select(x => x.Level).ToArray().Min();
            }

            AppendMissingTitle(rootSection);

            var hasToc          = HasToc(content);
            var tocSection      = GetToc(content, maxLevel);
            var preambleSection = GetPreamble(content, rootSection, maxLevel);

            var linearized = rootSection.Linearize();
            var result     = new List <PageSection>();

            if (tocSection != null && linearized.Count != 0)
            {
                result.Insert(0, tocSection);
            }

            if (preambleSection != null)
            {
                result.Insert(hasToc ? 1:0, preambleSection);
            }

            // корректирую длинну секций, дабы
            // включать только тот текст, который между секциями
            // но исключить дочерние секции
            for (int i = 0; i < linearized.Count; i++)
            {
                var child  = linearized[i];
                var length = child.Length;
                if (i > 0 && linearized[i - 1].Level < linearized[i].Level)
                {
                    // если текущий заголовок ниже предыдущего
                    // нужно подкорректировать длину предыдущего заголовка
                    var j = i;
                    length = linearized[i - 1].Length;
                    var level = linearized[i - 1].Level;
                    do
                    {
                        // учитываем только заголовки одного уровня
                        if (linearized[j].Level == level + 1)
                        {
                            length -= linearized[j].Length;
                        }
                        j++;
                    }
                    // до тех пор, пока не выйдем на уровень выше текущего
                    // или не закончим список
                    while (j < linearized.Count && linearized[j].Level != level);

                    result[result.Count - 1].Length = length;
                }
                result.Add(new PageSection(child.Position, child.Length, child.Level, child.Title, child.BodyOffset));
            }

            if (linearized.Count == 0)
            {
                result.Add(rootSection);
            }

            return(result);
        }