Skip to content

Commit

Permalink
LT-21751: Implement writing system styles (#38)
Browse files Browse the repository at this point in the history
- When starting a run, add a writing system style
if the run has a WS specified.

- If the run should have an additional style associated
with it, replace the writing system style with a link to
the writing system specific version of the additional style.

- Use RunFonts object instead of Font object
to specify fonts for character styles in word
  • Loading branch information
aror92 authored May 3, 2024
1 parent 29defce commit 9a21ec4
Show file tree
Hide file tree
Showing 2 changed files with 68 additions and 25 deletions.
69 changes: 53 additions & 16 deletions Src/xWorks/LcmWordGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -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<RunStyle>().Any())
{
run.RunProperties.Descendants<RunStyle>().Last().Val = styleName;
return;
}

run.RunProperties.Append(new RunStyle() { Val = styleName });
}
Expand All @@ -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;
}

/// <summary>
/// Returns content of the doc fragment as a string.
/// Be careful using this as document styles won't be preserved in a string.
Expand Down Expand Up @@ -664,9 +691,18 @@ public void Insert(IFragment frag)
/// <summary>
/// Add a new run to the WordFragment DocBody.
/// </summary>
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
Expand Down Expand Up @@ -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.
Expand Down Expand Up @@ -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();
Expand Down Expand Up @@ -869,7 +906,7 @@ public void EndBiDiWrapper(IFragmentWriter writer)
/// <param name="writingSystem"></param>
public void StartRun(IFragmentWriter writer, string writingSystem)
{
((WordFragmentWriter)writer).CreateRun();
((WordFragmentWriter)writer).CreateRun(writingSystem);
}
public void EndRun(IFragmentWriter writer)
{
Expand All @@ -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))
Expand All @@ -903,15 +940,15 @@ 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;
}
public void StartLink(IFragmentWriter writer, ConfigurableDictionaryNode config, string externalDestination)
{
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;
}
Expand Down Expand Up @@ -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))
{
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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))
{
Expand Down
24 changes: 15 additions & 9 deletions Src/xWorks/WordStylesGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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));
Expand Down Expand Up @@ -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);
}
Expand All @@ -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 };
Expand Down Expand Up @@ -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.).
Expand Down Expand Up @@ -749,6 +750,11 @@ private static StyleRunProperties AddFontInfoWordStyles(BaseStyleInfo projectSty
return charDefaults;
}

public static string GetWsString(string wsId)
{
return String.Format("[lang=\'{0}\']", wsId);
}

/// <summary>
/// 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.
Expand Down

0 comments on commit 9a21ec4

Please sign in to comment.