@Niebelschutz,
Regarding WORDSNET-20396, it is to update you that we have completed the work on this issue and concluded to close this issue with “Not a Bug” status. Please see the following analysis details.
We have discovered that Aspose.Words does process white-spaces in the merge field values correctly. Example (see attachment.zip (18.0 KB)):
var document = new Document("mm.docx");
document.MailMerge.Execute(
new[] { "left", "right", "true", "false" },
new object[]
{
"this is an expression",
"this is an expression",
"this is a true argument",
"this is a false argument"
});
document.Save("mm Out.docx");
As you can see, the output is totally correct and the white-spaces are preserved. You are experiencing the issues because you are manually inserting nodes into merge fields:
_builder.MoveToMergeField(e.FieldName);
_builder.InsertDocument(rtfDoc, ImportFormatMode.UseDestinationStyles);
This excludes mail merge engine from the process of merge field update and therefore it does not correctly handle white-spaces (breaks).
Also, you can use the following sample code to enclose child merge fields in double quotes to make the IF field keep the white-spaces in the arguments:
public class MergeFieldQuoteEnsurer : DocumentVisitor
{
public override VisitorAction VisitRun(Run run)
{
if (!IsInIfField)
return VisitorAction.Continue;
bool isEscaped = false;
foreach (char c in run.Text)
{
switch (c)
{
case '\\':
isEscaped = !isEscaped;
break;
case '"':
if (!isEscaped)
mQuoteCount++;
break;
}
if (c != '\\' && isEscaped)
isEscaped = false;
}
return VisitorAction.Continue;
}
public override VisitorAction VisitFieldStart(FieldStart fieldStart)
{
switch (fieldStart.FieldType)
{
case FieldType.FieldIf:
mIfCount++;
// Ideally we need to have a stack of quote counters for each nested IF, but for simplicity just reset it for the outermost.
if (mIfCount == 1)
mQuoteCount = 0;
break;
case FieldType.FieldMergeField:
if (IsInIfField && !IsInQuotes)
mFieldsToProcess.Add(fieldStart.GetField());
break;
}
return VisitorAction.Continue;
}
public override VisitorAction VisitFieldEnd(FieldEnd fieldEnd)
{
switch (fieldEnd.FieldType)
{
case FieldType.FieldIf:
mIfCount--;
break;
}
return VisitorAction.Continue;
}
public override VisitorAction VisitDocumentEnd(Document doc)
{
InsertQuotes();
return VisitorAction.Continue;
}
private void InsertQuotes()
{
foreach (var field in mFieldsToProcess)
{
var fieldStart = field.Start;
var fieldEnd = field.End;
fieldStart.ParentNode.InsertBefore(new Run(fieldStart.Document, "\""), fieldStart);
fieldEnd.ParentNode.InsertAfter(new Run(fieldEnd.Document, "\""), fieldEnd);
}
}
private bool IsInIfField
{
get { return mIfCount > 0; }
}
private bool IsInQuotes
{
get { return (mQuoteCount & 1) == 1; }
}
private int mIfCount;
private int mQuoteCount;
private List<Field> mFieldsToProcess = new List<Field>();
}
Usage:
var quoteEnsurer = new MergeFieldQuoteEnsurer();
doc.Accept(quoteEnsurer);
Hope, this helps.