diff --git a/Src/xWorks/LcmWordGenerator.cs b/Src/xWorks/LcmWordGenerator.cs index 958ee86c9f..b3294152e0 100644 --- a/Src/xWorks/LcmWordGenerator.cs +++ b/Src/xWorks/LcmWordGenerator.cs @@ -260,16 +260,17 @@ public static void LinkStyleOrInheritParentStyle(IFragment content, Configurable if (!string.IsNullOrEmpty(config.Style)) { - frag.AddStyleLink(config.Style, config.StyleType); + frag.AddStyleLink(config.Style, config, config.StyleType); } else if (!string.IsNullOrEmpty(config.Parent?.Style)) { - frag.AddStyleLink(config.Parent.Style, config.Parent.StyleType); + frag.AddStyleLink(config.Parent.Style, config.Parent, config.Parent.StyleType); } } - public void AddStyleLink(string styleName, ConfigurableDictionaryNode.StyleTypes styleType) + public void AddStyleLink(string styleName, ConfigurableDictionaryNode config, ConfigurableDictionaryNode.StyleTypes styleType) { + styleName = GetWsStyleName(styleName, config); if (string.IsNullOrEmpty(styleName)) return; @@ -314,9 +315,12 @@ private void LinkCharStyle(string styleName) WP.Run run = GetLastRun(); if (run.RunProperties != null) { - // if a style is already linked to the run, return without adding another link + // if a style is already linked to the run, replace the stylename and return without adding another link if (run.RunProperties.Descendants().Any()) + { + run.RunProperties.Descendants().Last().Val = styleName; return; + } run.RunProperties.Append(new RunStyle() { Val = styleName }); } @@ -329,6 +333,29 @@ private void LinkCharStyle(string styleName) } } + public static string GetWsStyleName(string styleName, ConfigurableDictionaryNode config) + { + if (config.DictionaryNodeOptions is DictionaryNodeWritingSystemOptions) + { + foreach (var opt in ((DictionaryNodeWritingSystemOptions)config.DictionaryNodeOptions).Options) + { + if (opt.IsEnabled) + { + if (opt.Id == "vernacular" || opt.Id == "all vernacular") + return styleName; + + // else, the DictionaryNodeOption Id specifies a particular writing system + // if there is no base style, return just the ws style + if (styleName == null) + return WordStylesGenerator.GetWsString(opt.Id); + // if there is a base style, return the ws-specific version of that style + return styleName + WordStylesGenerator.GetWsString(opt.Id); + } + } + } + return styleName; + } + /// /// Returns content of the doc fragment as a string. /// Be careful using this as document styles won't be preserved in a string. @@ -664,9 +691,18 @@ public void Insert(IFragment frag) /// /// Add a new run to the WordFragment DocBody. /// - public void CreateRun() + public void CreateRun(string writingSystem) { - WordFragment.DocBody.AppendChild(new WP.Run()); + if (writingSystem == null) + WordFragment.DocBody.AppendChild(new WP.Run()); + else + { + var wsString = WordStylesGenerator.GetWsString(writingSystem); + var run = new WP.Run(); + run.Append(new RunProperties()); + run.RunProperties.Append(new RunStyle() { Val = "span"+wsString }); + WordFragment.DocBody.AppendChild(run); + } } } #endregion WordFragmentWriter class @@ -694,6 +730,7 @@ public IFragment WriteProcessedCollection(bool isBlock, IFragment elementContent { return WriteProcessedElementContent(elementContent, config, className); } + private IFragment WriteProcessedElementContent(IFragment elementContent, ConfigurableDictionaryNode config, string className) { // Use the style name and type of the config node or its parent to link a style to the elementContent fragment where the processed contents are written. @@ -783,10 +820,10 @@ public IFragment AddCollectionItem(bool isBlock, string collectionItemClass, Con if (!string.IsNullOrEmpty(config.Style)) { if (isBlock && (config.StyleType == ConfigurableDictionaryNode.StyleTypes.Paragraph)) - ((DocFragment)content).AddStyleLink(config.Style, ConfigurableDictionaryNode.StyleTypes.Paragraph); + ((DocFragment)content).AddStyleLink(config.Style, config, ConfigurableDictionaryNode.StyleTypes.Paragraph); else if (!isBlock) - ((DocFragment)content).AddStyleLink(config.Style, ConfigurableDictionaryNode.StyleTypes.Character); + ((DocFragment)content).AddStyleLink(config.Style, config,ConfigurableDictionaryNode.StyleTypes.Character); } var collData = CreateFragment(); @@ -869,7 +906,7 @@ public void EndBiDiWrapper(IFragmentWriter writer) /// public void StartRun(IFragmentWriter writer, string writingSystem) { - ((WordFragmentWriter)writer).CreateRun(); + ((WordFragmentWriter)writer).CreateRun(writingSystem); } public void EndRun(IFragmentWriter writer) { @@ -888,7 +925,7 @@ public void SetRunStyle(IFragmentWriter writer, ConfigurableDictionaryNode confi if (!string.IsNullOrEmpty(runStyle)) { // Add the style link. - ((WordFragmentWriter)writer).WordFragment.AddStyleLink(runStyle, ConfigurableDictionaryNode.StyleTypes.Character); + ((WordFragmentWriter)writer).WordFragment.AddStyleLink(runStyle, config, ConfigurableDictionaryNode.StyleTypes.Character); // Only add the style to the styleSheet if not already there. if (!_styleSheet.ChildElements.Any(p => ((Style)p).StyleId == runStyle)) @@ -903,7 +940,7 @@ public void StartLink(IFragmentWriter writer, ConfigurableDictionaryNode config, { if (config != null && !string.IsNullOrEmpty(config.Style)) { - ((WordFragmentWriter)writer).WordFragment.AddStyleLink(config.Style, ConfigurableDictionaryNode.StyleTypes.Character); + ((WordFragmentWriter)writer).WordFragment.AddStyleLink(config.Style, config, ConfigurableDictionaryNode.StyleTypes.Character); } return; } @@ -911,7 +948,7 @@ public void StartLink(IFragmentWriter writer, ConfigurableDictionaryNode config, { if (config != null && !string.IsNullOrEmpty(config.Style)) { - ((WordFragmentWriter)writer).WordFragment.AddStyleLink(config.Style, ConfigurableDictionaryNode.StyleTypes.Character); + ((WordFragmentWriter)writer).WordFragment.AddStyleLink(config.Style, config, ConfigurableDictionaryNode.StyleTypes.Character); } return; } @@ -1211,9 +1248,9 @@ public void AddCollection(IFragmentWriter writer, bool isBlockProperty, string c { var frag = ((WordFragmentWriter)writer).WordFragment; if (isBlockProperty && (config.StyleType == ConfigurableDictionaryNode.StyleTypes.Paragraph)) - frag.AddStyleLink(config.Style, ConfigurableDictionaryNode.StyleTypes.Paragraph); + frag.AddStyleLink(config.Style, config, ConfigurableDictionaryNode.StyleTypes.Paragraph); else if (!isBlockProperty) - frag.AddStyleLink(config.Style, ConfigurableDictionaryNode.StyleTypes.Character); + frag.AddStyleLink(config.Style, config, ConfigurableDictionaryNode.StyleTypes.Character); if (!string.IsNullOrEmpty(content)) { @@ -1262,7 +1299,7 @@ public IFragment AddImageCaption(string captionContent) public IFragment GenerateSenseNumber(string formattedSenseNumber, string senseNumberWs, ConfigurableDictionaryNode senseConfigNode) { DocFragment senseNum = new DocFragment(formattedSenseNumber); - senseNum.AddStyleLink(WordStylesGenerator.SenseNumberStyleName, ConfigurableDictionaryNode.StyleTypes.Character); + senseNum.AddStyleLink(WordStylesGenerator.SenseNumberStyleName, senseConfigNode, ConfigurableDictionaryNode.StyleTypes.Character); return senseNum; } public IFragment AddLexReferences(bool generateLexType, IFragment lexTypeContent, ConfigurableDictionaryNode config, string className, string referencesContent, bool typeBefore) @@ -1401,7 +1438,7 @@ public string AddStyles(ConfigurableDictionaryNode node, bool addEntryContinuati { _styleDictionary[styleName] = style; } - // If the content is the same, we don't need to do anything--the style is alread in the dictionary. + // If the content is the same, we don't need to do anything--the style is already in the dictionary. // But if the content is NOT the same, re-name this style and add it to the dictionary. else if (!WordStylesGenerator.AreStylesEquivalent(_styleDictionary[styleName], style)) { diff --git a/Src/xWorks/WordStylesGenerator.cs b/Src/xWorks/WordStylesGenerator.cs index 782cf25858..ae8d2d3c02 100644 --- a/Src/xWorks/WordStylesGenerator.cs +++ b/Src/xWorks/WordStylesGenerator.cs @@ -373,7 +373,6 @@ public static Styles GenerateWordStylesFromConfigurationNode( //selectors.AddRange(GenerateWordStylesForWritingSystems(baseSelection + " span", configNode.Style, propertyTable)); } - //rule.StyleId = styleName; if (configNode.Style != null) rule.StyleId = configNode.Style; rules.AppendChild(rule.CloneNode(true)); @@ -439,7 +438,8 @@ private static Styles GenerateWordStylesForWritingSystems(string selector, strin foreach (var aws in cache.ServiceLocator.WritingSystems.AllWritingSystems) { Style wsCharStyle = GetOnlyCharacterStyle(GenerateWordStyleFromLcmStyleSheet(styleName, aws.Handle, propertyTable)); - wsCharStyle.StyleId = selector + String.Format("[lang=\'{0}\']", aws.LanguageTag); + wsCharStyle.StyleId = selector + GetWsString(aws.LanguageTag); + wsCharStyle.StyleName = new StyleName() { Val = wsCharStyle.StyleId }; styleRules.Append(wsCharStyle); } @@ -457,16 +457,17 @@ private static Style GenerateWordStyleFromWsOptions(ConfigurableDictionaryNode c // if the writing system isn't a magic name just use it otherwise find the right one from the magic list var wsIdString = possiblyMagic == 0 ? ws.Id : WritingSystemServices.GetWritingSystemList(cache, possiblyMagic, true).First().Id; var wsId = cache.LanguageWritingSystemFactoryAccessor.GetWsFromStr(wsIdString); - var wsString = String.Format("[lang=\'{0}\']", wsIdString).Trim('.'); + var wsString = GetWsString(wsIdString).Trim('.'); var wsStyle = new Style(); if (!string.IsNullOrEmpty(configNode.Style)) wsStyle = GenerateWordStyleFromLcmStyleSheet(configNode.Style, wsId, propertyTable); - //style should be based on the span for the current ws as well as the style info for the current node that is independent from the ws + // Any given style can only be based on one style. + // This style should be based on the span for the current ws; + // style info for the current node (independent of WS) should be added during creation of this style. wsStyle.Append(new BasedOn() { Val = "span" + wsString }); - wsStyle.Append(new BasedOn() { Val = configNode.Style }); wsStyle.StyleId = configNode.Style + wsString; wsStyle.StyleName = new StyleName(){ Val = wsStyle.StyleId }; @@ -631,10 +632,10 @@ private static StyleRunProperties AddFontInfoWordStyles(BaseStyleInfo projectSty if (fontName != null) { - // TODO: test with a named font set in FLex - // Roman is the openxml font family option for serif font - var fontFamily = new Font(){Name = fontName, FontFamily = new FontFamily(){Val = FontFamilyValues.Roman}}; - charDefaults.Append(fontFamily); + // Note: if desired, multiple fonts can be used for different text types in a single run + // by separately specifying font names to use for ASCII, High ANSI, Complex Script, and East Asian content. + var font = new RunFonts(){Ascii = fontName}; + charDefaults.Append(font); } // For the following additions, wsFontInfo is a publicly accessible InheritableStyleProp value if set (ie. m_fontSize, m_bold, etc.). @@ -749,6 +750,11 @@ private static StyleRunProperties AddFontInfoWordStyles(BaseStyleInfo projectSty return charDefaults; } + public static string GetWsString(string wsId) + { + return String.Format("[lang=\'{0}\']", wsId); + } + /// /// This method will set fontValue to the font value from the writing system info falling back to the /// default info. It will return false if the value is not set in either info.