diff --git a/Src/LexText/ParserCore/M3ToXAmpleTransformer.cs b/Src/LexText/ParserCore/M3ToXAmpleTransformer.cs index ee912d98b6..442b0c8a2c 100644 --- a/Src/LexText/ParserCore/M3ToXAmpleTransformer.cs +++ b/Src/LexText/ParserCore/M3ToXAmpleTransformer.cs @@ -11,6 +11,7 @@ using System.Linq; using SIL.Utils; using SIL.WordWorks.GAFAWS.PositionAnalysis; +using System.Collections.Generic; namespace SIL.FieldWorks.WordWorks.Parser { @@ -94,6 +95,7 @@ public void PrepareTemplatesForXAmpleFiles(XDocument domModel, XDocument domTemp foreach (XElement templateElem in domTemplate.Root.Elements("PartsOfSpeech").Elements("PartOfSpeech") .Where(pe => pe.DescendantsAndSelf().Elements("AffixTemplates").Elements("MoInflAffixTemplate").Any(te => te.Element("PrefixSlots") != null || te.Element("SuffixSlots") != null))) { + DefineUndefinedSlots(templateElem); // transform the POS that has templates to GAFAWS format string gafawsFile = m_database + "gafawsData.xml"; TransformPosInfoToGafawsInputFormat(templateElem, gafawsFile); @@ -103,6 +105,62 @@ public void PrepareTemplatesForXAmpleFiles(XDocument domModel, XDocument domTemp } } + /// + /// Define undefined slots found in templateElem in AffixSlots. + /// + private void DefineUndefinedSlots(XElement templateElem) + { + ISet undefinedSlots = new HashSet(); + GetUndefinedSlots(templateElem, undefinedSlots); + if (undefinedSlots.Count == 0) + return; + // Add undefined slots to AffixSlots. + foreach (XElement elem in templateElem.Elements()) + { + if (elem.Name == "AffixSlots") + { + foreach (string slotId in undefinedSlots) + { + XElement slot = new XElement("MoInflAffixSlot"); + slot.SetAttributeValue("Id", slotId); + elem.Add(slot); + } + break; + } + } + } + + /// + /// Get slots that are not defined in the scope of their use. + /// Slots are used in PrefixSlots and SuffixSlots. + /// Slots are defined in AffixSlots. + /// + /// + /// + private void GetUndefinedSlots(XElement element, ISet undefinedSlots) + { + // Get undefined slots recursively to handle scope correctly. + foreach (XElement elem in element.Elements()) + { + GetUndefinedSlots(elem, undefinedSlots); + } + // Record slots where they are used. + if (element.Name == "PrefixSlots" || element.Name == "SuffixSlots") + { + undefinedSlots.Add((string) element.Attribute("dst")); + } + // Remove undefined slots from below that are defined at this level. + // NB: This must happen after we recursively get undefined slots. + XElement affixSlotsElem = element.Element("AffixSlots"); + if (affixSlotsElem != null) + { + foreach (XElement slot in affixSlotsElem.Elements()) + { + undefinedSlots.Remove((string)slot.Attribute("Id")); + } + } + } + private void InsertOrderclassInfo(XDocument domModel, string resultFile) { // Check for a valid filename (see LT-6472).