private ParagraphIterator SeekLastLeaf()
        {
            DocumentObject obj = Current;

            if (!(obj is ParagraphElements))
            {
                return(this);
            }

            List <int> indices = new List <int>(_positionIndices);

            while (obj is ParagraphElements)
            {
                ParagraphElements parEls = (ParagraphElements)obj;
                if (((ParagraphElements)obj).Count == 0)
                {
                    return(new ParagraphIterator(_rootNode, obj, indices));
                }

                int idx = ((ParagraphElements)obj).Count - 1;
                indices.Add(idx);
                obj = GetNodeObject(parEls[idx]);
            }
            return(new ParagraphIterator(_rootNode, obj, indices));
        }
Exemplo n.º 2
0
 private static void ProcessParagraphElements(ParagraphElements pe, XmlWriter xmlw)
 {
     xmlw.WriteStartElement("ParagraphElements");
     xmlw.WriteAttributeString("Count", pe.Count.ToStringSafe());
     foreach (ParagraphElement p in pe)
     {
         ProcessParagraphElement(p, xmlw);
     }
     xmlw.WriteEndElement();
 }
Exemplo n.º 3
0
 private static void ProcessParagraphElements(ParagraphElements pe, Utf8JsonWriter jsonw)
 {
     jsonw.WritePropertyName("ParagraphElements");
     jsonw.WriteStartObject();
     jsonw.WriteString("Count", pe.Count.ToStringSafe());
     jsonw.WritePropertyName("Items");
     jsonw.WriteStartArray();
     foreach (ParagraphElement p in pe)
     {
         ProcessParagraphElement(p, jsonw);
     }
     jsonw.WriteEndArray();
     jsonw.WriteEndObject();
 }
        /// <summary>
        /// Returns the previous iterator to a leaf in the document object tree pointing.
        /// </summary>
        /// <returns>The previous leaf, null if none exists.</returns>
        internal ParagraphIterator GetPreviousLeaf()
        {
            //Move up to appropriate parent element
            ParagraphIterator parIterator = GetParentIterator();

            if (parIterator == null)
            {
                return(null);
            }

            int elementIndex         = LastIndex;
            ParagraphElements parEls = (ParagraphElements)parIterator._current;

            while (elementIndex == 0)
            {
                elementIndex = parIterator.LastIndex;
                parIterator  = parIterator.GetParentIterator();
                if (parIterator == null)
                {
                    break;
                }

                parEls = (ParagraphElements)parIterator._current;
            }
            if (parIterator == null)
            {
                return(null);
            }

            int newIndex = elementIndex - 1;

            if (newIndex < 0)
            {
                return(null);
            }

            List <int> indices = new List <int>(parIterator._positionIndices);//(Array_List)parIterator.positionIndices.Clone();

            indices.Add(newIndex);

            DocumentObject    obj      = GetNodeObject(parEls[newIndex]);
            ParagraphIterator iterator = new ParagraphIterator(_rootNode, obj, indices);

            return(iterator.SeekLastLeaf());
        }
Exemplo n.º 5
0
        /// <summary>
        /// Returns the next iterator in the tree pointing to a leaf.
        /// </summary>
        /// <remarks>This function is intended to receive the renderable objects of a paragraph.
        /// Thus, empty ParagraphElement objects (which are collections) don't count as leafs.</remarks>
        internal ParagraphIterator GetNextLeaf()
        {
            //Move up to appropriate parent element
            ParagraphIterator parIterator = GetParentIterator();

            if (parIterator == null)
            {
                return(null);
            }

            int elementIndex         = this.LastIndex;
            ParagraphElements parEls = (ParagraphElements)parIterator.current;

            while (elementIndex == parEls.Count - 1)
            {
                elementIndex = parIterator.LastIndex;
                parIterator  = parIterator.GetParentIterator();
                if (parIterator == null)
                {
                    break;
                }

                parEls = (ParagraphElements)parIterator.current;
            }
            if (parIterator == null)
            {
                return(null);
            }
            int newIndex = elementIndex + 1;

            if (newIndex >= parEls.Count)
            {
                return(null);
            }

            ArrayList indices = (ArrayList)parIterator.positionIndices.Clone();

            indices.Add(newIndex);
            DocumentObject    obj      = GetNodeObject(parEls[newIndex]);
            ParagraphIterator iterator = new ParagraphIterator(this.rootNode, obj, indices);

            return(iterator.SeekFirstLeaf());
        }
Exemplo n.º 6
0
        /// <summary>
        /// Return all text elements in the paragraph - including the text elements
        /// inside the FormattedText elements.
        /// </summary>
        /// <param name="paragraph">The paragraph.</param>
        internal static IEnumerable <string> GetTextElements(this ParagraphElements paragraph)
        {
            if (paragraph == null)
            {
                throw new ArgumentNullException(nameof(paragraph));
            }

            foreach (DocumentObject obj in paragraph)
            {
                if (obj is Text text)
                {
                    yield return(text.Content);
                }
                else if (obj is Character character)
                {
                    if (character.SymbolName == SymbolName.LineBreak)
                    {
                        yield return(Environment.NewLine);
                    }
                    else
                    {
                        // This probably doesn't work.
                        yield return(new string(character.Char, character.Count));
                    }
                }
                else if (obj is FormattedText formattedText)
                {
                    foreach (string subtext in formattedText.Elements.GetTextElements())
                    {
                        yield return(subtext);
                    }
                }
                else if (obj is Hyperlink link)
                {
                    foreach (string subtext in link.Elements.GetTextElements())
                    {
                        yield return(subtext);
                    }
                }
            }
        }
Exemplo n.º 7
0
        /// <summary>
        /// Gets the leftmost leaf within the hierarchy.
        /// </summary>
        /// <returns>The searched leaf.</returns>
        ParagraphIterator SeekFirstLeaf()
        {
            DocumentObject obj = this.Current;

            if (!(obj is ParagraphElements))
            {
                return(this);
            }
            ArrayList indices = (ArrayList)this.positionIndices.Clone();

            while (obj is ParagraphElements)
            {
                ParagraphElements parEls = (ParagraphElements)obj;
                if (parEls.Count == 0)
                {
                    return(new ParagraphIterator(this.rootNode, obj, indices));
                }

                indices.Add(0);
                obj = GetNodeObject(parEls[0]);
            }
            return(new ParagraphIterator(this.rootNode, obj, indices));
        }
        /// <summary>
        /// Gets the leftmost leaf within the hierarchy.
        /// </summary>
        /// <returns>The searched leaf.</returns>
        ParagraphIterator SeekFirstLeaf()
        {
            DocumentObject obj = Current;

            if (!(obj is ParagraphElements))
            {
                return(this);
            }
            List <int> indices = new List <int>(_positionIndices);

            while (obj is ParagraphElements)
            {
                ParagraphElements parEls = (ParagraphElements)obj;
                if (parEls.Count == 0)
                {
                    return(new ParagraphIterator(_rootNode, obj, indices));
                }

                indices.Add(0);
                obj = GetNodeObject(parEls[0]);
            }
            return(new ParagraphIterator(_rootNode, obj, indices));
        }
Exemplo n.º 9
0
        /// <summary>
        /// Parses the keyword «\symbol» resp. «\(».
        /// </summary>
        private void ParseSymbol(ParagraphElements elements)
        {
            AssertSymbol(Symbol.Symbol);

            ReadCode();  // read '('
            AssertSymbol(Symbol.ParenLeft);

            const char ch = (char)0;
            SymbolName symtype = 0;
            int count = 1;

            ReadCode();  // read name
            if (TokenType == TokenType.Identifier)
            {
                try
                {
                    if (Enum.IsDefined(typeof(SymbolName), Token))
                    {
                        AssertCondition(IsSymbolType(Token), DomMsgID.InvalidSymbolType, Token);
                        symtype = (SymbolName)Enum.Parse(typeof(SymbolName), Token, true);
                    }
                }
                catch (Exception ex)
                {
                    ThrowParserException(ex, DomMsgID.InvalidEnum, Token);
                }
            }
            else
            {
                ThrowParserException(DomMsgID.UnexpectedSymbol, Token);
            }

            ReadCode();  // read integer or identifier
            if (Symbol == Symbol.Comma)
            {
                ReadCode();  // read integer
                if (TokenType == TokenType.IntegerLiteral)
                    count = _scanner.GetTokenValueAsInt();
                ReadCode();
            }

            AssertSymbol(Symbol.ParenRight);

            if (symtype != 0)
                elements.AddCharacter(symtype, count);
            else
                elements.AddCharacter(ch, count);
        }
Exemplo n.º 10
0
        /// <summary>
        /// Parses the keyword «\chr».
        /// </summary>
        private void ParseChr(ParagraphElements elements)
        {
            AssertSymbol(Symbol.Chr);

            ReadCode();  // read '('
            AssertSymbol(Symbol.ParenLeft);

            char ch = (char)0;
            SymbolName symtype = 0;
            int count = 1;

            ReadCode();  // read integer
            if (TokenType == TokenType.IntegerLiteral)
            {
                int val = _scanner.GetTokenValueAsInt();
                if (val >= 1 && val < 256)
                    ch = (char)val;
                else
                    ThrowParserException(DomMsgID.OutOfRange, "1 - 255");
            }
            else
            {
                ThrowParserException(DomMsgID.UnexpectedSymbol, Token);
            }

            ReadCode();  // read integer or identifier
            if (Symbol == Symbol.Comma)
            {
                ReadCode();  // read integer
                if (TokenType == TokenType.IntegerLiteral)
                    count = _scanner.GetTokenValueAsInt();
                ReadCode();
            }

            AssertSymbol(Symbol.ParenRight);

            if (symtype != 0)
                elements.AddCharacter(symtype, count);
            else
                elements.AddCharacter(ch, count);
        }
Exemplo n.º 11
0
 /// <summary>
 /// Removes the last blank from the text. Used before a tab, a linebreak or a space will be
 /// added to the text.
 /// </summary>
 private void RemoveTrailingBlank(ParagraphElements elements)
 {
     DocumentObject dom = elements.LastObject;
     Text text = dom as Text;
     if (text != null)
     {
         if (text.Content.EndsWith(" "))
             text.Content = text.Content.Remove(text.Content.Length - 1, 1);
     }
 }
Exemplo n.º 12
0
        /// <summary>
        /// Parses the inner text of a paragraph. Parsing ends if '}' is reached or an empty
        /// line occurs on nesting level 0.
        /// </summary>
        private void ParseFormattedText(ParagraphElements elements, int nestingLevel)
        {
            MoveToParagraphContent();

            bool loop = true;
            bool rootLevel = nestingLevel == 0;
            ReadText(rootLevel);
            while (loop)
            {
                switch (Symbol)
                {
                    case Symbol.Eof:
                        ThrowParserException(DomMsgID.UnexpectedEndOfFile);
                        break;

                    case Symbol.EmptyLine:
                        elements.AddCharacter(SymbolName.ParaBreak);
                        ReadText(rootLevel);
                        break;

                    case Symbol.BraceRight:
                        loop = false;
                        break;

                    case Symbol.Comment:
                        // Ignore comments.
                        ReadText(rootLevel);
                        break;

                    case Symbol.Text:
                        elements.AddText(Token);
                        ReadText(rootLevel);
                        break;

                    case Symbol.Tab:
                        RemoveTrailingBlank(elements);
                        elements.AddTab();
                        _scanner.MoveToNonWhiteSpaceOrEol();
                        ReadText(rootLevel);
                        break;

                    case Symbol.LineBreak:
                        RemoveTrailingBlank(elements);
                        elements.AddLineBreak();
                        _scanner.MoveToNonWhiteSpaceOrEol();
                        ReadText(rootLevel);
                        break;

                    case Symbol.Bold:
                        ParseBoldItalicEtc(elements.AddFormattedText(TextFormat.Bold), nestingLevel + 1);
                        ReadText(rootLevel);
                        break;

                    case Symbol.Italic:
                        ParseBoldItalicEtc(elements.AddFormattedText(TextFormat.Italic), nestingLevel + 1);
                        ReadText(rootLevel);
                        break;

                    case Symbol.Underline:
                        ParseBoldItalicEtc(elements.AddFormattedText(TextFormat.Underline), nestingLevel + 1);
                        ReadText(rootLevel);
                        break;

                    case Symbol.Font:
                        ParseFont(elements.AddFormattedText(), nestingLevel + 1);
                        ReadText(rootLevel);
                        break;

                    case Symbol.FontSize:
                        ParseFontSize(elements.AddFormattedText(), nestingLevel + 1);
                        ReadText(rootLevel);
                        break;

                    case Symbol.FontColor:
                        ParseFontColor(elements.AddFormattedText(), nestingLevel + 1);
                        ReadText(rootLevel);
                        break;

                    case Symbol.Image:
                        ParseImage(elements.AddImage(""), true);
                        ReadText(rootLevel);
                        break;

                    case Symbol.Field:
                        ParseField(elements, nestingLevel + 1);
                        ReadText(rootLevel);
                        break;

                    case Symbol.Footnote:
                        ParseFootnote(elements, nestingLevel + 1);
                        ReadText(rootLevel);
                        break;

                    case Symbol.Hyperlink:
                        ParseHyperlink(elements, nestingLevel + 1);
                        ReadText(rootLevel);
                        break;

                    case Symbol.Space:
                        RemoveTrailingBlank(elements);
                        ParseSpace(elements, nestingLevel + 1);
                        _scanner.MoveToNonWhiteSpaceOrEol();
                        ReadText(rootLevel);
                        break;

                    case Symbol.Symbol:
                        ParseSymbol(elements);
                        ReadText(rootLevel);
                        break;

                    case Symbol.Chr:
                        ParseChr(elements);
                        ReadText(rootLevel);
                        break;

                    default:
                        ThrowParserException(DomMsgID.UnexpectedSymbol, Token);
                        break;
                }
            }
        }
Exemplo n.º 13
0
 /// <summary>
 /// Removes the last blank from the text. Used before a tab, a linebreak or a space will be
 /// added to the text.
 /// </summary>
 private void RemoveTrailingBlank(ParagraphElements elements)
 {
     DocumentObject dom = elements.LastObject;
       if (dom is Text)
       {
     Text text = (Text)dom;
     if (text.Content.EndsWith(" "))
       text.Content = text.Content.Remove(text.Content.Length - 1, 1);
       }
 }
Exemplo n.º 14
0
 /// <summary>
 /// Initializes a paragraph iterator pointing on the given paragraph elements object.
 /// Paragraph iterators received from this paragraph iterator relate to this root node.
 /// </summary>
 /// <param name="rootNode">The root node for the paragraph iterator.</param>
 internal ParagraphIterator(ParagraphElements rootNode)
 {
     this.rootNode        = rootNode;
     this.current         = rootNode;
     this.positionIndices = new ArrayList();
 }
Exemplo n.º 15
0
 /// <summary>
 /// Initializes a paragraph iterator given the root node, its position in the object tree and the current object
 /// </summary>
 /// <param name="rootNode">The node the position indices relate to.</param>
 /// <param name="current">The element the iterator shall point to.</param>
 /// <param name="indices">The position of the paragraph iterator in terms of element indices.</param>
 private ParagraphIterator(ParagraphElements rootNode, DocumentObject current, ArrayList indices)
 {
     this.rootNode        = rootNode;
     this.positionIndices = indices;
     this.current         = current;
 }
Exemplo n.º 16
0
        /// <summary>
        /// Parses the keyword «\hyperlink».
        /// </summary>
        private void ParseHyperlink(ParagraphElements elements, int nestingLevel)
        {
            AssertSymbol(Symbol.Hyperlink);
            ReadCode();

            Hyperlink hyperlink = elements.AddHyperlink("");
            //NYI: Without name and type the hyperlink is senseless, so attributes need to be checked
            if (Symbol == Symbol.BracketLeft)
                ParseAttributes(hyperlink);

            AssertSymbol(Symbol.BraceLeft);
            ParseFormattedText(hyperlink.Elements, nestingLevel);
            AssertSymbol(Symbol.BraceRight);
        }
Exemplo n.º 17
0
        /// <summary>
        /// Parses the keyword «\field».
        /// </summary>
        private void ParseField(ParagraphElements elements, int nestingLevel)
        {
            AssertSymbol(Symbol.Field);

            ReadCode();  // read '('
            AssertSymbol(Symbol.ParenLeft);

            ReadCode();  // read identifier
            AssertSymbol(Symbol.Identifier);
            string fieldType = Token.ToLower();

            ReadCode();  // read ')'
            AssertSymbol(Symbol.ParenRight);

            DocumentObject field = null;
            switch (fieldType)
            {
                case "date":
                    field = elements.AddDateField();
                    break;

                case "page":
                    field = elements.AddPageField();
                    break;

                case "numpages":
                    field = elements.AddNumPagesField();
                    break;

                case "info":
                    field = elements.AddInfoField(0);
                    break;

                case "sectionpages":
                    field = elements.AddSectionPagesField();
                    break;

                case "section":
                    field = elements.AddSectionField();
                    break;

                case "bookmark":
                    field = elements.AddBookmark("");
                    break;

                case "pageref":
                    field = elements.AddPageRefField("");
                    break;
            }
            AssertCondition(field != null, DomMsgID.InvalidFieldType, Token);

            if (_scanner.PeekSymbol() == Symbol.BracketLeft)
            {
                ReadCode();  // read '['
                ParseAttributes(field, false);
            }
        }
Exemplo n.º 18
0
        /// <summary>
        /// Parses the keyword «\footnote».
        /// </summary>
        private void ParseFootnote(ParagraphElements elements, int nestingLevel)
        {
            AssertSymbol(Symbol.Footnote);
            ReadCode();

            Footnote footnote = elements.AddFootnote();
            if (Symbol == Symbol.BracketLeft)
                ParseAttributes(footnote);

            AssertSymbol(Symbol.BraceLeft);

            // The keyword «\paragraph» is typically ommitted.
            if (IsParagraphContent())
            {
                Paragraph paragraph = footnote.Elements.AddParagraph();
                ParseParagraphContent(footnote.Elements, paragraph);
            }
            else
            {
                ReadCode(); // read beyond '{'
                ParseDocumentElements(footnote.Elements, Symbol.Footnote);
            }
            AssertSymbol(Symbol.BraceRight);
        }
Exemplo n.º 19
0
 /// <summary>
 /// Initializes a paragraph iterator pointing on the given paragraph elements object.
 /// Paragraph iterators received from this paragraph iterator relate to this root node.
 /// </summary>
 /// <param name="rootNode">The root node for the paragraph iterator.</param>
 internal ParagraphIterator(ParagraphElements rootNode)
 {
     _rootNode        = rootNode;
     _current         = rootNode;
     _positionIndices = new List <int>();
 }
Exemplo n.º 20
0
        /// <summary>
        /// Parses the keyword «\space».
        /// </summary>
        private void ParseSpace(ParagraphElements elements, int nestingLevel)
        {
            // Samples
            // \space
            // \space(5)
            // \space(em)
            // \space(em,5)
            AssertSymbol(Symbol.Space);

            Character space = elements.AddSpace(1);

            // «\space» can stand alone
            if (_scanner.PeekSymbol() == Symbol.ParenLeft)
            {
                ReadCode(); // read '('
                AssertSymbol(Symbol.ParenLeft);

                ReadCode(); // read beyond '('
                if (Symbol == Symbol.Identifier)
                {
                    string type = Token;
                    if (!IsSpaceType(type))
                        ThrowParserException(DomMsgID.InvalidEnum, type);

                    space.SymbolName = (SymbolName)Enum.Parse(typeof(SymbolName), type, true);

                    ReadCode(); // read ',' or ')'
                    if (Symbol == Symbol.Comma)
                    {
                        ReadCode();  // read integer
                        AssertSymbol(Symbol.IntegerLiteral);
                        space.Count = _scanner.GetTokenValueAsInt();
                        ReadCode(); // read ')'
                    }
                }
                else if (Symbol == Symbol.IntegerLiteral)
                {
                    space.Count = _scanner.GetTokenValueAsInt();
                    ReadCode();
                }
                AssertSymbol(Symbol.ParenRight);
            }
        }
Exemplo n.º 21
0
 /// <summary>
 /// Initializes a paragraph iterator given the root node, its position in the object tree and the current object
 /// </summary>
 /// <param name="rootNode">The node the position indices relate to.</param>
 /// <param name="current">The element the iterator shall point to.</param>
 /// <param name="indices">The position of the paragraph iterator in terms of element indices.</param>
 private ParagraphIterator(ParagraphElements rootNode, DocumentObject current, List <int> indices)
 {
     _rootNode        = rootNode;
     _positionIndices = indices;
     _current         = current;
 }