private static void UpgradeToWordGloss(Word word, ref IAnalysis analysis) { FdoCache cache = analysis.Cache; var tsStrFactory = cache.ServiceLocator.GetInstance<ITsStrFactory>(); var wsFact = cache.WritingSystemFactory; if (s_importOptions.AnalysesLevel == ImportAnalysesLevel.WordGloss) { // test for adding multiple glosses in the same language. If so, create separate analyses with separate glosses. bool fHasMultipleGlossesInSameLanguage = false; var dictMapLangToGloss = new Dictionary<string, string>(); foreach (var wordGlossItem in word.Items.Select(i => i).Where(i => i.type == "gls")) { string gloss; if (!dictMapLangToGloss.TryGetValue(wordGlossItem.lang, out gloss)) { dictMapLangToGloss.Add(wordGlossItem.lang, wordGlossItem.Value); continue; } if (wordGlossItem.Value == gloss) continue; fHasMultipleGlossesInSameLanguage = true; break; } AnalysisTree analysisTree = null; foreach (var wordGlossItem in word.Items.Select(i => i).Where(i => i.type == "gls")) { if (wordGlossItem == null) continue; if (wordGlossItem.analysisStatusSpecified && wordGlossItem.analysisStatus != analysisStatusTypes.humanApproved) continue; // first make sure that an existing gloss does not already exist. (i.e. don't add duplicate glosses) int wsNewGloss = GetWsEngine(wsFact, wordGlossItem.lang).Handle; ITsString newGlossTss = tsStrFactory.MakeString(wordGlossItem.Value, wsNewGloss); var wfiWord = analysis.Wordform; bool hasGlosses = wfiWord.AnalysesOC.Any(wfia => wfia.MeaningsOC.Any()); IWfiGloss matchingGloss = null; if (hasGlosses) { foreach (var wfa in wfiWord.AnalysesOC) { matchingGloss = wfa.MeaningsOC.FirstOrDefault(wfg => wfg.Form.get_String(wsNewGloss).Equals(newGlossTss)); if (matchingGloss != null) break; } } if (matchingGloss != null) analysis = matchingGloss; else { // TODO: merge with analysis having same morpheme breakdown (or at least the same stem) if (analysisTree == null || dictMapLangToGloss.Count == 1 || fHasMultipleGlossesInSameLanguage) { // create a new WfiAnalysis to store a new gloss analysisTree = WordAnalysisOrGlossServices.CreateNewAnalysisTreeGloss(wfiWord); } // else, reuse the same analysisTree for setting a gloss alternative analysisTree.Gloss.Form.set_String(wsNewGloss, wordGlossItem.Value); // Make sure this analysis is marked as user-approved (green check mark) cache.LangProject.DefaultUserAgent.SetEvaluation(analysisTree.WfiAnalysis, Opinions.approves); // Create a morpheme form that matches the wordform. var morphemeBundle = cache.ServiceLocator.GetInstance<IWfiMorphBundleFactory>().Create(); var wordItem = word.Items.Select(i => i).First(i => i.type == "txt"); int wsWord = GetWsEngine(wsFact, wordItem.lang).Handle; analysisTree.WfiAnalysis.MorphBundlesOS.Add(morphemeBundle); morphemeBundle.Form.set_String(wsWord, wordItem.Value); analysis = analysisTree.Gloss; } } } }
internal void ImportWordsFrag(Word[] words, ImportAnalysesLevel analysesLevel) { s_importOptions = new ImportInterlinearOptions {AnalysesLevel = analysesLevel}; var tsStrFactory = m_cache.ServiceLocator.GetInstance<ITsStrFactory>(); NonUndoableUnitOfWorkHelper.Do(m_cache.ActionHandlerAccessor, () => { foreach (var word in words) { CreateWordAnalysisStack(m_cache, word, tsStrFactory); } }); }
/// <summary> /// add any alternative forms (in alternative writing systems) to the wordform. /// Overwrite any existing alternative form in a given alternative writing system. /// </summary> /// <param name="analysis"></param> /// <param name="word"></param> /// <param name="wsMainVernWs"></param> /// <param name="strFactory"></param> private static void AddAlternativeWssToWordform(IAnalysis analysis, Word word, ILgWritingSystem wsMainVernWs, ITsStrFactory strFactory) { ILgWritingSystemFactory wsFact = analysis.Cache.WritingSystemFactory; var wf = analysis.Wordform; foreach (var wordItem in word.Items) { ITsString wffAlt = null; switch (wordItem.type) { case "txt": var wsAlt = GetWsEngine(wsFact, wordItem.lang); if (wsAlt.Handle == wsMainVernWs.Handle) continue; wffAlt = strFactory.MakeString(wordItem.Value, wsAlt.Handle); if (wffAlt.Length > 0) wf.Form.set_String(wsAlt.Handle, wffAlt); break; } } }
private static IAnalysis CreateWordAnalysisStack(FdoCache cache, Word word, ITsStrFactory strFactory) { if (word.Items == null || word.Items.Length <= 0) return null; IAnalysis analysis = null; var wsFact = cache.WritingSystemFactory; ILgWritingSystem wsMainVernWs = null; foreach (var wordItem in word.Items) { ITsString wordForm = null; switch (wordItem.type) { case "txt": wsMainVernWs = GetWsEngine(wsFact, wordItem.lang); wordForm = strFactory.MakeString(wordItem.Value, wsMainVernWs.Handle); analysis = WfiWordformServices.FindOrCreateWordform(cache, wordForm); break; case "punct": wordForm = strFactory.MakeString(wordItem.Value, GetWsEngine(wsFact, wordItem.lang).Handle); analysis = WfiWordformServices.FindOrCreatePunctuationform(cache, wordForm); break; } if (wordForm != null) break; } // now add any alternative word forms. (overwrite any existing) if (analysis != null && analysis.HasWordform) { AddAlternativeWssToWordform(analysis, word, wsMainVernWs, strFactory); } if (analysis != null) { UpgradeToWordGloss(word, ref analysis); } else { Debug.Assert(analysis != null, "What else could this do?"); } //Add any morphemes to the thing if (word.morphemes != null && word.morphemes.morphs.Length > 0) { //var bundle = newSegment.Cache.ServiceLocator.GetInstance<IWfiMorphBundleFactory>().Create(); //analysis.Analysis.MorphBundlesOS.Add(bundle); //foreach (var morpheme in word.morphemes) //{ // //create a morpheme // foreach(item item in morpheme.items) // { // //fill in morpheme's stuff // } //} } return analysis; }
private static void AddWordToSegment(ISegment newSegment, Word word, ITsStrFactory strFactory) { //use the items under the word to determine what kind of thing to add to the segment var cache = newSegment.Cache; IAnalysis analysis = CreateWordAnalysisStack(cache, word, strFactory); // Add to segment if (analysis != null) { newSegment.AnalysesRS.Add(analysis); } }
private static void MergeWordToSegment(ISegment newSegment, Word word, ITsStrFactory tsStrFactory) { if(!String.IsNullOrEmpty(word.guid)) { ICmObject repoObj; newSegment.Cache.ServiceLocator.ObjectRepository.TryGetObject(new Guid(word.guid), out repoObj); IAnalysis modelWord = repoObj as IAnalysis; if(modelWord != null) { UpgradeToWordGloss(word, ref modelWord); newSegment.AnalysesRS.Add(modelWord); } else { AddWordToSegment(newSegment, word, tsStrFactory); } } else { AddWordToSegment(newSegment, word, tsStrFactory); } }
/// <summary> /// This method will update the phraseText ref item with the contents of the item entries under the word /// </summary> /// <param name="wsFactory"></param> /// <param name="tsStrFactory"></param> /// <param name="phraseText"></param> /// <param name="word"></param> /// <param name="lastWasWord"></param> /// <param name="space"></param> private static void UpdatePhraseTextForWordItems(ILgWritingSystemFactory wsFactory, ITsStrFactory tsStrFactory, ref ITsString phraseText, Word word, ref bool lastWasWord, char space) { bool isWord = false; foreach (var item in word.Items) { switch (item.type) { case "txt": //intentional fallthrough isWord = true; goto case "punct"; case "punct": ITsString wordString = tsStrFactory.MakeString(item.Value, GetWsEngine(wsFactory, item.lang).Handle); if (phraseText == null) { phraseText = wordString; } else { var phraseBldr = phraseText.GetBldr(); if (lastWasWord && isWord) //two words next to each other deserve a space between { phraseBldr.ReplaceTsString(phraseText.Length, phraseText.Length, tsStrFactory.MakeString("" + space, GetWsEngine(wsFactory, item.lang).Handle)); } else if (!isWord) //handle punctuation { wordString = GetSpaceAdjustedPunctString(wsFactory, tsStrFactory, item, wordString, space, lastWasWord); } phraseBldr.ReplaceTsString(phraseBldr.Length, phraseBldr.Length, wordString); phraseText = phraseBldr.GetString(); } lastWasWord = isWord; return; // only handle the baseline "txt" or "punct" once per "word" bundle, especially don't want extra writing system content in the baseline. } } }