/// <summary>
        /// Parse coords text.
        /// </summary>
        /// <remarks>Coords text is in the form <c>Y.X</c> or <c>Y.X@AxR</c>
        /// or <c>Y.X@A</c> (in this case
        /// run defaults to 1).</remarks>
        /// <param name="text">text to parse</param>
        /// <exception cref="ArgumentNullException">null text</exception>
        /// <exception cref="ArgumentException">invalid text</exception>
        public static TokenTextPoint Parse(string text)
        {
            if (text == null)
            {
                throw new ArgumentNullException(nameof(text));
            }

            TokenTextPoint point = new TokenTextPoint();

            point.Read(text);
            return(point);
        }
        /// <summary>
        /// Determines whether the specified <see cref="System.Object" />, is
        /// equal to this instance.
        /// </summary>
        /// <param name="obj">The <see cref="System.Object" /> to compare with
        /// this instance.</param>
        /// <returns>
        /// <c>true</c> if the specified <see cref="System.Object" /> is equal
        /// to this instance; otherwise, <c>false</c>.
        /// </returns>
        public override bool Equals(object obj)
        {
            if (ReferenceEquals(this, obj))
            {
                return(true);
            }

            if (obj is null)
            {
                return(false);
            }

            TokenTextPoint other = obj as TokenTextPoint;

            if (obj == null)
            {
                return(false);
            }
            return(Y == other.Y &&
                   X == other.X &&
                   At == other.At &&
                   Run == other.Run);
        }