Skip to content

Commit

Permalink
Merge branch 'release/9.1' into LT-21777
Browse files Browse the repository at this point in the history
  • Loading branch information
jasonleenaylor authored May 3, 2024
2 parents 044a91d + 29defce commit 39aad31
Show file tree
Hide file tree
Showing 2 changed files with 132 additions and 22 deletions.
119 changes: 100 additions & 19 deletions Src/xWorks/LcmWordGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -428,15 +428,56 @@ public void Append(WP.Table table)
}

/// <summary>
/// Appends a new run inside the last paragraph of the doc fragment--creates a new paragraph if none exists or if forceNewParagraph is true.
/// Appends a new run inside the last paragraph of the doc fragment--creates a new paragraph if none
/// exists or if forceNewParagraph is true.
/// The run will be added to the end of the paragraph.
/// </summary>
/// <param name="run">The run to append.</param>
/// <param name="forceNewParagraph">Even if a paragraph exists, force the creation of a new paragraph.</param>
public void AppendToParagraph(IFragment fragToCopy, OpenXmlElement run, bool forceNewParagraph)
{
WP.Paragraph lastPar = null;

if (forceNewParagraph)
{
// When forcing a new paragraph use a 'continuation' style for the new paragraph.
// The continuation style is based on the style used in the last paragraph.
string style = null;
WP.Paragraph lastParagraph = DocBody.OfType<WP.Paragraph>().LastOrDefault();
if (lastParagraph != null)
{
WP.ParagraphProperties paraProps = lastParagraph.OfType<WP.ParagraphProperties>().FirstOrDefault();
if (paraProps != null)
{
ParagraphStyleId styleId = paraProps.OfType<WP.ParagraphStyleId>().FirstOrDefault();
if (styleId != null && styleId.Val != null && styleId.Val.Value != null)
{
if (styleId.Val.Value.EndsWith(WordStylesGenerator.EntryStyleContinue))
{
style = styleId.Val.Value;
}
else
{
style = styleId.Val.Value + WordStylesGenerator.EntryStyleContinue;
}
}
}
}

lastPar = GetNewParagraph();
if (!string.IsNullOrEmpty(style))
{
WP.ParagraphProperties paragraphProps = new WP.ParagraphProperties(
new ParagraphStyleId() { Val = style });
lastPar.Append(paragraphProps);
}
}
else
{
lastPar = GetLastParagraph();
}

// Deep clone the run b/c of its tree of properties and to maintain styles.
WP.Paragraph lastPar = forceNewParagraph ? GetNewParagraph() : GetLastParagraph();
lastPar.AppendChild(CloneRun(fragToCopy, run));
}

Expand Down Expand Up @@ -665,21 +706,15 @@ config.DictionaryNodeOptions is IParaOption &&
// Add Before text, if it is not going to be displayed in it's own paragraph.
if (!displayEachInAParagraph && !string.IsNullOrEmpty(config.Before))
{
WP.Text txt = new WP.Text(config.Before);
txt.Space = SpaceProcessingModeValues.Preserve;
var beforeRun = new WP.Run(txt);
var beforeRun = CreateBeforeAfterBetweenRun(config.Before);
((DocFragment)elementContent).DocBody.PrependChild(beforeRun);
}

// Add After text, if it is not going to be displayed in it's own paragraph.
if (!displayEachInAParagraph && !string.IsNullOrEmpty(config.After))
{
WP.Text txt = new WP.Text(config.After);
txt.Space = SpaceProcessingModeValues.Preserve;
var afterRun = new WP.Run(txt);
var afterRun = CreateBeforeAfterBetweenRun(config.After);
((DocFragment)elementContent).DocBody.Append(afterRun);
// To be consistent with the xhtml output, only the after text uses the same style.
DocFragment.LinkStyleOrInheritParentStyle(elementContent, config);
}

return elementContent;
Expand Down Expand Up @@ -778,7 +813,8 @@ config.DictionaryNodeOptions is IParaOption &&
!eachInAParagraph &&
!string.IsNullOrEmpty(config.Between))
{
((DocFragment)collData).Append(config.Between);
var betweenRun = CreateBeforeAfterBetweenRun(config.Between);
((DocFragment)collData).DocBody.Append(betweenRun);
}

collData.Append(content);
Expand Down Expand Up @@ -1064,12 +1100,19 @@ public void EndTable(IFragmentWriter writer, ConfigurableDictionaryNode config)
}
public void StartEntry(IFragmentWriter writer, ConfigurableDictionaryNode config, string className, Guid entryGuid, int index, RecordClerk clerk)
{
// Each entry starts a new paragraph, and any entry data added will be added within the same paragraph.
// Each entry starts a new paragraph, and any entry data added will usually be added within the same paragraph.
// The paragraph will end whenever a data type that cannot be in a paragraph is encounter (Tables or Pictures).
// A new 'continuation' paragraph will be started after the Table or Picture if there is other data that still
// needs to be added to the entry.
// Create a new paragraph for the entry.
DocFragment wordDoc = ((WordFragmentWriter)writer).WordFragment;
WP.Paragraph entryPar = wordDoc.GetNewParagraph();
WP.ParagraphProperties paragraphProps = new WP.ParagraphProperties(new ParagraphStyleId() {Val = config.Style});
entryPar.Append(paragraphProps);

// Create the 'continuation' style for the entry. This style will be the same as the style for the entry with the only
// difference being that it does not contain the first line indenting (since it is a continuation of the same entry).
AddStyles(config, true);
}
public void AddEntryData(IFragmentWriter writer, List<ConfiguredLcmGenerator.ConfigFragment> pieces)
{
Expand Down Expand Up @@ -1253,18 +1296,14 @@ public IFragment WriteProcessedSenses(bool isBlock, IFragment senseContent, Conf
// Add Before text for the sharedGramInfo.
if (!string.IsNullOrEmpty(config.Before))
{
WP.Text txt = new WP.Text(config.Before);
txt.Space = SpaceProcessingModeValues.Preserve;
var beforeRun = new WP.Run(txt);
var beforeRun = CreateBeforeAfterBetweenRun(config.Before);
((DocFragment)sharedGramInfo).DocBody.PrependChild(beforeRun);
}

// Add After text for the sharedGramInfo.
if (!string.IsNullOrEmpty(config.After))
{
WP.Text txt = new WP.Text(config.After);
txt.Space = SpaceProcessingModeValues.Preserve;
var afterRun = new WP.Run(txt);
var afterRun = CreateBeforeAfterBetweenRun(config.After);
((DocFragment)sharedGramInfo).DocBody.Append(afterRun);
}

Expand Down Expand Up @@ -1303,6 +1342,10 @@ public void AddGlobalStyles(DictionaryConfigurationModel model, ReadOnlyProperty
if (letterHeaderStyle != null)
_styleSheet.Append(letterHeaderStyle);

var beforeAfterBetweenStyle = WordStylesGenerator.GenerateBeforeAfterBetweenStyle(propertyTable);
if (beforeAfterBetweenStyle != null)
_styleSheet.Append(beforeAfterBetweenStyle);

Styles defaultStyles = WordStylesGenerator.GetDefaultWordStyles(propertyTable, propStyleSheet, model);
if (defaultStyles != null)
{
Expand All @@ -1318,6 +1361,17 @@ public void AddGlobalStyles(DictionaryConfigurationModel model, ReadOnlyProperty
//WordStylesGenerator.GenerateWordStyleForAudioWs(_styleSheet, cache);
}
public string AddStyles(ConfigurableDictionaryNode node)
{
return AddStyles(node, false);
}

/// <summary>
/// Generates styles that are needed by this node and adds them to the dictionary.
/// </summary>
/// <param name="addEntryContinuationStyle">If true then generate the 'continuation' style for the node.
/// If false then generate the regular (non-continuation) styles for the node.</param>
/// <returns></returns>
public string AddStyles(ConfigurableDictionaryNode node, bool addEntryContinuationStyle)
{
// The css className isn't important for the Word export.
// Styles should be stored in the dictionary based on their stylenames.
Expand All @@ -1326,7 +1380,15 @@ public string AddStyles(ConfigurableDictionaryNode node)

lock (_styleDictionary)
{
var styleContent = WordStylesGenerator.CheckRangeOfStylesForEmpties(WordStylesGenerator.GenerateWordStylesFromConfigurationNode(node, className, _propertyTable));
Styles styleContent = null;
if (addEntryContinuationStyle)
{
styleContent = WordStylesGenerator.CheckRangeOfStylesForEmpties(WordStylesGenerator.GenerateContinuationWordStyles(node, _propertyTable));
}
else
{
styleContent = WordStylesGenerator.CheckRangeOfStylesForEmpties(WordStylesGenerator.GenerateWordStylesFromConfigurationNode(node, className, _propertyTable));
}
if (styleContent == null)
return className;
if (!styleContent.Any())
Expand Down Expand Up @@ -1533,5 +1595,24 @@ public static string GetBestUniqueNameForNode(Dictionary<string, Style> styles,
}
return className;
}

/// <summary>
/// Creates a BeforeAfterBetween run using the text provided and using the BeforeAfterBetween style.
/// </summary>
/// <param name="text">Text for the run.</param>
/// <returns>The BeforeAfterBetween run.</returns>
private WP.Run CreateBeforeAfterBetweenRun(string text)
{
WP.Run run = new WP.Run();
WP.RunProperties runProps =
new WP.RunProperties(new RunStyle() { Val = WordStylesGenerator.BeforeAfterBetweenStyleName });
run.Append(runProps);

WP.Text txt = new WP.Text(text);
txt.Space = SpaceProcessingModeValues.Preserve;
run.Append(txt);

return run;
}
}
}
35 changes: 32 additions & 3 deletions Src/xWorks/WordStylesGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -32,13 +32,19 @@ public class WordStylesGenerator
internal const string WritingSystemPrefix = "writingsystemprefix";
internal const string WritingSystemStyleName = "Writing System Abbreviation";
internal const string PictureAndCaptionTextframeStyle = "Image-Textframe-Style";
internal const string EntryStyleContinue = "-Continue";

public static Style GenerateLetterHeaderStyle(
ReadOnlyPropertyTable propertyTable, LcmStyleSheet mediatorStyleSheet)
{
return GenerateWordStyleFromLcmStyleSheet(LetterHeadingStyleName, 0, propertyTable);
}

public static Style GenerateBeforeAfterBetweenStyle(ReadOnlyPropertyTable propertyTable)
{
return GenerateWordStyleFromLcmStyleSheet(BeforeAfterBetweenStyleName, 0, propertyTable);
}

public static Styles GetDefaultWordStyles(ReadOnlyPropertyTable propertyTable, LcmStyleSheet propStyleSheet, DictionaryConfigurationModel model)
{
var styles = new Styles();
Expand Down Expand Up @@ -81,7 +87,7 @@ internal static Style GenerateWordStyleFromLcmStyleSheet(
ConfigurableDictionaryNode node, ReadOnlyPropertyTable propertyTable)
{
return GenerateWordStyleFromLcmStyleSheet(styleName, wsId, node, propertyTable,
false);
false, true);
}

/// <summary>
Expand All @@ -95,10 +101,11 @@ internal static Style GenerateWordStyleFromLcmStyleSheet(
/// <param name="wsId">writing system id</param>
/// <param name="node">The configuration node to use for generating paragraph margin in context</param>
/// <param name="propertyTable">To retrieve styles</param>
/// <param name="allowFirstLineIndent">Indicates if the style returned should include FirstLineIndent.</param>
/// <returns></returns>
internal static Style GenerateWordStyleFromLcmStyleSheet(
string styleName, int wsId, ConfigurableDictionaryNode node,
ReadOnlyPropertyTable propertyTable, bool calculateFirstSenseStyle)
ReadOnlyPropertyTable propertyTable, bool calculateFirstSenseStyle, bool allowFirstLineIndent)
{
var styleSheet = FontHeightAdjuster.StyleSheetFromPropertyTable(propertyTable);
if (styleSheet == null || !styleSheet.Styles.Contains(styleName))
Expand Down Expand Up @@ -177,7 +184,10 @@ internal static Style GenerateWordStyleFromLcmStyleSheet(
hangingIndent = firstLineIndentValue;
}

parProps.Append(new Indentation() { FirstLine = firstLineIndentValue.ToString() });
if (allowFirstLineIndent)
{
parProps.Append(new Indentation() { FirstLine = firstLineIndentValue.ToString() });
}
}

if (exportStyleInfo.HasKeepWithNext)
Expand Down Expand Up @@ -576,6 +586,25 @@ private static Styles GenerateWordStylesForWritingSystemPrefix(ConfigurableDicti
return styleRules;
}

/// <summary>
/// Create the 'continuation' style for the entry, which is needed when an entry contains multiple paragraphs. This
/// style will be used for all but the first paragraph. It is the same as the style for the first paragraph except
/// that it does not contain the first line indenting.
/// </summary>
/// <returns>Returns the continuation style.</returns>
internal static Styles GenerateContinuationWordStyles(
ConfigurableDictionaryNode node, ReadOnlyPropertyTable propertyTable)
{
Style contStyle = GenerateWordStyleFromLcmStyleSheet(node.Style, DefaultStyle, node,
propertyTable, false, false);
contStyle.StyleName.Val = node.Style + EntryStyleContinue;
contStyle.StyleId = node.Style + EntryStyleContinue;

var retStyles = new Styles();
retStyles.AppendChild(contStyle.CloneNode(true));
return retStyles;
}

/// <summary>
/// Builds the word styles for font info properties using the writing system overrides
/// </summary>
Expand Down

0 comments on commit 39aad31

Please sign in to comment.