diff --git a/Src/xWorks/ConfiguredLcmGenerator.cs b/Src/xWorks/ConfiguredLcmGenerator.cs index ddcaacd052..014aea60a2 100644 --- a/Src/xWorks/ConfiguredLcmGenerator.cs +++ b/Src/xWorks/ConfiguredLcmGenerator.cs @@ -2512,18 +2512,15 @@ private static IFragment GenerateContentForValue(object field, object propertyVa if (propertyValue is int) { - var cssClassName = settings.StylesGenerator.AddStyles(config).Trim('.'); ; - return settings.ContentGenerator.AddProperty(config, cssClassName, false, propertyValue.ToString()); + return GenerateContentForSimpleString(config, settings, false, propertyValue.ToString()); } if (propertyValue is DateTime) { - var cssClassName = settings.StylesGenerator.AddStyles(config).Trim('.'); ; - return settings.ContentGenerator.AddProperty(config, cssClassName, false, ((DateTime)propertyValue).ToLongDateString()); + return GenerateContentForSimpleString(config, settings, false, ((DateTime)propertyValue).ToLongDateString()); } else if (propertyValue is GenDate) { - var cssClassName = settings.StylesGenerator.AddStyles(config).Trim('.'); ; - return settings.ContentGenerator.AddProperty(config, cssClassName, false, ((GenDate)propertyValue).ToLongString()); + return GenerateContentForSimpleString(config, settings, false, ((GenDate)propertyValue).ToLongString()); } else if (propertyValue is IMultiAccessorBase) { @@ -2533,8 +2530,7 @@ private static IFragment GenerateContentForValue(object field, object propertyVa } else if (propertyValue is string) { - var cssClassName = settings.StylesGenerator.AddStyles(config).Trim('.'); - return settings.ContentGenerator.AddProperty(config, cssClassName, false, propertyValue.ToString()); + return GenerateContentForSimpleString(config, settings, false, propertyValue.ToString()); } else if (propertyValue is IStText) { @@ -2570,16 +2566,18 @@ private static IFragment GenerateContentForValue(object field, object propertyVa } } - private static IFragment WriteElementContents(object propertyValue, - ConfigurableDictionaryNode config, GeneratorSettings settings) + /// + /// This method will add a property containing the string, using the first selected writing system, + /// or the first analysis writing system if no writing system is selected. + /// + private static IFragment GenerateContentForSimpleString(ConfigurableDictionaryNode config, + GeneratorSettings settings, bool isBlockProperty, string simpleString) { - var content = propertyValue.ToString(); - if (!String.IsNullOrEmpty(content)) - { - return settings.ContentGenerator.AddProperty(config, GetClassNameAttributeForConfig(config), IsBlockProperty(config), content); - } + var writingSystem = GetLanguageFromFirstOptionOrAnalysis(config.DictionaryNodeOptions as DictionaryNodeWritingSystemOptions, + settings.Cache); + var cssClassName = settings.StylesGenerator.AddStyles(config).Trim('.'); + return settings.ContentGenerator.AddProperty(config, settings.PropertyTable, cssClassName, false, simpleString, writingSystem); - return settings.ContentGenerator.CreateFragment(); } private static IFragment GenerateContentForStrings(IMultiStringAccessor multiStringAccessor, ConfigurableDictionaryNode config, @@ -3084,6 +3082,30 @@ internal static bool IsBlockProperty(ConfigurableDictionaryNode config) /// /// This method returns the lang attribute value from the first selected writing system in the given options. + /// It defaults to the first analysis writing system if no options are given, and English if no analysis writing system is specified. + /// + /// + /// + /// + private static string GetLanguageFromFirstOptionOrAnalysis(DictionaryNodeWritingSystemOptions wsOptions, LcmCache cache) + { + const string defaultLang = "en"; + var analWs = cache.WritingSystemFactory.GetStrFromWs(cache.DefaultAnalWs); + + if (wsOptions == null) + { + if (analWs == null) + return defaultLang; + + return analWs; + } + + return GetLanguageFromFirstWs(wsOptions, cache); + } + + /// + /// This method returns the lang attribute value from the first selected writing system in the given options. + /// It defaults to English if no options are given. /// /// /// @@ -3093,6 +3115,21 @@ private static string GetLanguageFromFirstOption(DictionaryNodeWritingSystemOpti const string defaultLang = "en"; if (wsOptions == null) return defaultLang; + return GetLanguageFromFirstWs(wsOptions, cache); + } + + /// + /// This method returns the lang attribute value from the first selected writing system in the given options. + /// Returns null if no options are given. + /// + /// + /// + /// + private static string GetLanguageFromFirstWs(DictionaryNodeWritingSystemOptions wsOptions, LcmCache cache) + { + if (wsOptions == null) + return null; + foreach (var option in wsOptions.Options) { if (option.IsEnabled) diff --git a/Src/xWorks/ILcmContentGenerator.cs b/Src/xWorks/ILcmContentGenerator.cs index 753a07dc08..32cf1fc4f5 100644 --- a/Src/xWorks/ILcmContentGenerator.cs +++ b/Src/xWorks/ILcmContentGenerator.cs @@ -24,7 +24,7 @@ IFragment GenerateGroupingNode(ConfigurableDictionaryNode config, object field, Func childContentGenerator); IFragment AddSenseData(ConfigurableDictionaryNode config, IFragment senseNumberSpan, Guid ownerGuid, IFragment senseContent, bool first); IFragment AddCollectionItem(ConfigurableDictionaryNode config, bool isBlock, string collectionItemClass, IFragment content, bool first); - IFragment AddProperty(ConfigurableDictionaryNode config, string className, bool isBlockProperty, string content); + IFragment AddProperty(ConfigurableDictionaryNode config, ReadOnlyPropertyTable propTable, string className, bool isBlockProperty, string content, string writingSystem); IFragment CreateFragment(); IFragment CreateFragment(string str); IFragmentWriter CreateWriter(IFragment fragment); diff --git a/Src/xWorks/LcmJsonGenerator.cs b/Src/xWorks/LcmJsonGenerator.cs index 6c4b4bb036..483ad7a64d 100644 --- a/Src/xWorks/LcmJsonGenerator.cs +++ b/Src/xWorks/LcmJsonGenerator.cs @@ -124,7 +124,7 @@ public IFragment AddCollectionItem(ConfigurableDictionaryNode config, bool isBlo return fragment; } - public IFragment AddProperty(ConfigurableDictionaryNode config, string className, bool isBlockProperty, string content) + public IFragment AddProperty(ConfigurableDictionaryNode config, ReadOnlyPropertyTable propTable, string className, bool isBlockProperty, string content, string writingSystem) { var fragment = new StringFragment($"\"{className}\": \"{content}\","); return fragment; diff --git a/Src/xWorks/LcmWordGenerator.cs b/Src/xWorks/LcmWordGenerator.cs index 388879ee1c..c47ba49dc8 100644 --- a/Src/xWorks/LcmWordGenerator.cs +++ b/Src/xWorks/LcmWordGenerator.cs @@ -1121,39 +1121,35 @@ config.DictionaryNodeOptions is IParaOption && return collData; } - public IFragment AddProperty(ConfigurableDictionaryNode config, string className, bool isBlockProperty, string content) + public IFragment AddProperty(ConfigurableDictionaryNode config, ReadOnlyPropertyTable propTable, string className, bool isBlockProperty, string content, string writingSystem) { var propFrag = new DocFragment(); Run contentRun = null; string styleDisplayName = null; - // Add the content with the style. - if (!string.IsNullOrEmpty(content)) + if (content == null) { - if (!string.IsNullOrEmpty(config.Style)) - { - string displayNameBase = !string.IsNullOrEmpty(config.DisplayLabel) ? config.DisplayLabel : config.Style; - - Style style = GetOrCreateCharacterStyle(config.Style, displayNameBase, _propertyTable); - if (style != null) - { - styleDisplayName = style.StyleId; - } - } - contentRun = CreateRun(content, styleDisplayName); + // In this case, we should not generate the run or any before/after text for it. + return propFrag; } + // Create a run with the correct style. + var writer = CreateWriter(propFrag); + ((WordFragmentWriter)writer).AddRun(Cache, config, propTable, writingSystem, true); + + // Add the content to the run. + AddToRunContent(writer, content); + var currentRun = ((WordFragmentWriter)writer).WordFragment.GetLastRun(); + + // Get the run's styleDisplayName for use in before/after text runs. + if (currentRun.RunProperties != null) + styleDisplayName = currentRun.RunProperties.RunStyle?.Val; + // Add Before text. if (!string.IsNullOrEmpty(config.Before)) { var beforeRun = CreateBeforeAfterBetweenRun(config.Before, styleDisplayName); - propFrag.DocBody.Append(beforeRun); - } - - // Add the content. - if (contentRun != null) - { - propFrag.DocBody.Append(contentRun); + propFrag.DocBody.PrependChild(beforeRun); } // Add After text. diff --git a/Src/xWorks/LcmXhtmlGenerator.cs b/Src/xWorks/LcmXhtmlGenerator.cs index 841f51a381..fa15493e7e 100644 --- a/Src/xWorks/LcmXhtmlGenerator.cs +++ b/Src/xWorks/LcmXhtmlGenerator.cs @@ -1076,7 +1076,7 @@ public IFragment AddCollectionItem(ConfigurableDictionaryNode config, bool isBlo } } - public IFragment AddProperty(ConfigurableDictionaryNode config, string className, bool isBlockProperty, string content) + public IFragment AddProperty(ConfigurableDictionaryNode config, ReadOnlyPropertyTable propTable, string className, bool isBlockProperty, string content, string writingSystem) { var bldr = new StringBuilder(); var fragment = new StringFragment(bldr); diff --git a/Src/xWorks/WordStylesGenerator.cs b/Src/xWorks/WordStylesGenerator.cs index cf3579ad1a..5e7bd1f548 100644 --- a/Src/xWorks/WordStylesGenerator.cs +++ b/Src/xWorks/WordStylesGenerator.cs @@ -515,6 +515,13 @@ private static StyleRunProperties AddFontInfoWordStyles(BaseStyleInfo projectSty var fontName = wsFontInfo.m_fontName.ValueIsSet ? wsFontInfo.m_fontName.Value : defaultFontInfo.FontName.ValueIsSet ? defaultFontInfo.FontName.Value : null; + // If font is explicitly set in FLEx to "", this gets picked up as the fontname. + // In that case, we want to set fontNome to null in the word style so that it can be inherited from the WS. + if (fontName == "") + { + fontName = null; + } + // fontName still null means not set in Normal Style, then get default fonts from WritingSystems configuration. // Comparison, projectStyle.Name == "Normal", required to limit the font-family definition to the // empty span (ie span[lang="en"]{}. If not included, font-family will be added to many more spans.