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).