Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

LT-21761: Fix indenting for the first line after a Table #37

Merged
merged 4 commits into from
May 2, 2024
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
75 changes: 71 additions & 4 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 @@ -1064,12 +1105,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 @@ -1318,6 +1366,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 +1385,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
30 changes: 27 additions & 3 deletions Src/xWorks/WordStylesGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ 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)
Expand Down Expand Up @@ -81,7 +82,7 @@ internal static Style GenerateWordStyleFromLcmStyleSheet(
ConfigurableDictionaryNode node, ReadOnlyPropertyTable propertyTable)
{
return GenerateWordStyleFromLcmStyleSheet(styleName, wsId, node, propertyTable,
false);
false, true);
}

/// <summary>
Expand All @@ -95,10 +96,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 +179,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 +581,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
Loading