예제 #1
0
        // ------------------------------------------------------------------------------------
        // Name:   eTreeSentence
        // Goal:   Re-analyze a whole sentence in the following way:
        //         1. Based on the content of the [eLeaf] nodes:
        //            a. Determine the <seg> text
        //            b. Determine @from and @to for the [eLeaf] nodes
        //         2. Determine @from and @to for all the [eTree] nodes again
        // History:
        // 03-01-2013  ERK Created
        // ------------------------------------------------------------------------------------
        public bool eTreeSentence(ref XmlNode ndxThis, ref XmlNode ndxNew, bool bVerbose = false,
                                  bool bOldEnglish = false, bool bDoOrg = true)
        {
            XmlNode ndxFor = null;          // My parent forest node
            // XmlNode ndxChild = null; // Working node
            XmlNodeList ndxList    = null;  // List of children
            XmlNode     ndxVern    = null;  // Vernacular text line
            XmlNode     ndxLeaf    = null;  // One working leaf
            int         intI       = 0;     // Counter
            int         intFrom    = 0;     // Word starting point
            int         intTo      = 0;     // End of word
            bool        bNeedSpace = false; // No space needed after this word
            bool        bChanged   = false; // Whether anythying has in fact changed
            string      strLine    = "";    // Text of this line

            try {
                // Validate something is selected
                if (ndxThis == null)
                {
                    return(false);
                }
                // Determine the parent forest node
                ndxFor = ndxThis.SelectSingleNode("./ancestor-or-self::forest[1]");
                if (ndxFor == null)
                {
                    return(false);
                }
                // Need to recalculate the "org" text?
                if (bDoOrg)
                {
                    // Get the vernacular text line
                    ndxVern = ndxFor.SelectSingleNode("./child::div[@lang='org']/seg");
                    if (ndxVern == null)
                    {
                        return(false);
                    }
                    // Get all the [eLeaf] children, but only if they have no CODE nor METADATA ancestor
                    ndxList = ndxFor.SelectNodes(".//descendant::eLeaf[count(ancestor::eTree[tb:matches(@Label, '" + strNoText + "')])=0]", XPathFunctions.conTb);
                    // Walk all the children
                    for (intI = 0; intI < ndxList.Count; intI++)
                    {
                        // ============ DEBUG =========
                        // If (intI = 11) Then Stop
                        // ============================
                        // Process this <eLeaf>
                        // Check if this <eLeaf> has the correct type
                        if ((ndxList[intI].Attributes["Type"].Value == "Punct") &&
                            (General.DoLike(ndxList[intI].Attributes["Text"].Value, "*[a-zA-Z]*")))
                        {
                            // It must be of type "Vern" instead
                            ndxList[intI].Attributes["Type"].Value = "Vern";
                        }
                        switch (ndxList[intI].Attributes["Type"].Value)
                        {
                        case "Vern":
                            // Need to add a space?
                            if (bNeedSpace)
                            {
                                strLine += " ";
                            }
                            // Get the starting point of the word
                            intFrom = strLine.Length;
                            // Add word to the text of this line
                            if (bOldEnglish)
                            {
                                strLine += VernToEnglish(ndxList[intI].Attributes["Text"].Value);
                            }
                            else
                            {
                                strLine += ndxList[intI].Attributes["Text"].Value;
                            }
                            // Get the correct ending point of the word
                            intTo = strLine.Length;
                            // Normally each word should be followed by a space
                            bNeedSpace = true;
                            break;

                        case "Punct":
                            // Are we supposed to add a space?
                            if (bNeedSpace)
                            {
                                // Check if this punctuation should be PRECEDED by a space
                                switch (ndxList[intI].Attributes["Text"].Value)
                                {
                                case ":":
                                case ",":
                                case ".":
                                case "!":
                                case "?":
                                case ";":
                                case ">>":
                                    // A space may NOT precede this punctuation
                                    break;

                                case "»":
                                    // A space may NOT precede this punctuation
                                    break;

                                case "«":
                                case "<<": // A space must precede this punctuation
                                    strLine += " ";
                                    break;

                                case "'":
                                case "\"":
                                    // Check if a word is preceding or not
                                    if (intI > 0)
                                    {
                                        // We are not at the beginning...
                                        if (ndxList[intI - 1].Attributes["Type"].Value != "Vern")
                                        {
                                            // There is NO word preceding, so DO add a space
                                            strLine += " ";
                                        }
                                    }
                                    break;

                                default:
                                    // In all other cases a space has to be added
                                    strLine += " ";
                                    break;
                                }
                            }
                            // Get the starting point of the word
                            intFrom = strLine.Length;
                            // Add word to the text of this line
                            strLine += ndxList[intI].Attributes["Text"].Value;
                            // Get the correct ending point of the word
                            intTo = strLine.Length;
                            // Check if this punctuation should be FOLLOWED by a space
                            switch (ndxList[intI].Attributes["Text"].Value)
                            {
                            case ":":
                            case ",":
                            case ".":
                            case "!":
                            case "?":
                            case ";":
                            case ">>":
                                // A space must follow
                                bNeedSpace = true;
                                break;

                            case "»":
                                // A space should follow this punctuation
                                bNeedSpace = true;
                                break;

                            case "«":
                                // A space should not follow
                                bNeedSpace = false;
                                break;

                            case "'":
                            case "\"":
                                // Check if a word is preceding or not
                                if (intI > 0)
                                {
                                    // We are not at the beginning...
                                    if (ndxList[intI - 1].Attributes["Type"].Value == "Vern")
                                    {
                                        // There is a word preceding, so DO add a space
                                        bNeedSpace = true;
                                    }
                                }
                                break;

                            default:
                                // Reset spacing
                                bNeedSpace = false;
                                break;
                            }
                            break;

                        case "Star":
                            // A star item must contain at least a space
                            intFrom = strLine.Length;
                            // Add this space
                            strLine   += " ";
                            bNeedSpace = false;
                            // Get the correct ending point of the word
                            intTo = strLine.Length;
                            break;

                        case "Zero":
                            // Get the starting point of the word
                            intFrom = strLine.Length;
                            intTo   = intFrom;
                            break;
                        }
                        // Validate existence of from and to
                        XmlNode ndxListItem = ndxList[intI];
                        if (ndxList[intI].Attributes["from"] == null)
                        {
                            oXmlTools.AddAttribute(ndxListItem, "from", "0");
                        }
                        if (ndxList[intI].Attributes["to"] == null)
                        {
                            oXmlTools.AddAttribute(ndxListItem, "to", "0");
                        }
                        // Adapt the start and end of the word
                        intFrom += 1;
                        if (ndxList[intI].Attributes["from"].Value != intFrom.ToString())
                        {
                            ndxList[intI].Attributes["from"].Value = intFrom.ToString();
                            bChanged = true;
                        }
                        if (ndxList[intI].Attributes["to"].Value != intTo.ToString())
                        {
                            ndxList[intI].Attributes["to"].Value = intTo.ToString();
                            bChanged = true;
                        }
                    }
                    // Adapt the sentence in the vernacular
                    ndxVern.InnerText = strLine;
                    // Make sure editor is set to dirty
                    // bEdtDirty = true;
                }
                // Get all the <eTree> nodes
                ndxList = ndxFor.SelectNodes("./descendant::eTree");
                // Treat them all
                for (intI = 0; intI < ndxList.Count; intI++)
                {
                    // Access this one
                    // Determine their @from and @to values
                    ndxLeaf = ndxList[intI].SelectSingleNode("./descendant::eLeaf[1]");
                    if (ndxLeaf != null)
                    {
                        // Double check
                        if (ndxLeaf.Attributes["from"] == null)
                        {
                            oXmlTools.AddXmlAttribute(pdxCurrentFile, ref ndxLeaf, "from", "0");
                        }
                        // Get the value
                        intFrom = Convert.ToInt32(ndxLeaf.Attributes["from"].Value);
                        // Validate
                        if (ndxList[intI].Attributes["from"] == null)
                        {
                            XmlNode ndxListItem = ndxList[intI];
                            oXmlTools.AddAttribute(ndxListItem, "from", intFrom.ToString());
                        }
                        else
                        {
                            // See if we need changing
                            if (ndxList[intI].Attributes["from"].Value != intFrom.ToString())
                            {
                                ndxList[intI].Attributes["from"].Value = intFrom.ToString();
                                bChanged = true;
                            }
                        }
                    }
                    ndxLeaf = ndxList[intI].SelectSingleNode("./descendant::eLeaf[last()]");
                    if (ndxLeaf != null)
                    {
                        // Double check
                        if (ndxLeaf.Attributes["to"] == null)
                        {
                            oXmlTools.AddXmlAttribute(pdxCurrentFile, ref ndxLeaf, "to", "0");
                        }
                        // Get the value
                        intTo = Convert.ToInt32(ndxLeaf.Attributes["to"].Value);
                        // Validate
                        if (ndxList[intI].Attributes["to"] == null)
                        {
                            XmlNode ndxListItem = ndxList[intI];
                            oXmlTools.AddAttribute(ndxListItem, "to", intTo.ToString());
                        }
                        else
                        {
                            // See if we need changing
                            if (ndxList[intI].Attributes["to"].Value != intTo.ToString())
                            {
                                ndxList[intI].Attributes["to"].Value = intTo.ToString();
                                bChanged = true;
                            }
                        }
                    }
                }
                // We end with the same node we started with
                // NO!! then we change it... ndxNew = ndxThis
                // Give message to user
                if ((bChanged) && (bVerbose))
                {
                    errHandle.Status("Word positions in line " + ndxFor.Attributes["forestId"].Value);
                    //Else
                    //  Logging("No changes were needed")
                }
                // Return success
                return(bChanged);
            } catch (Exception ex) {
                // Show error
                errHandle.DoError("modEditor/eTreeSentence", ex);
                // Return failure
                return(false);
            }
        }