MS Word has the ability to insert line breaks to keep paragraphs wrapped at certain length when saving as plain text. It is achieved via save format ( wdFormatDOSTextLineBreaks 5 Microsoft DOS text with line breaks preserved.) Is something similar possible in Aspose?
Please see these sample Word and TXT files: conversion of line breaks to txt format.zip (9.7 KB)
C# code of Aspose.Words for .NET that was used to convert to TXT format:
Document doc = new Document("C:\\Temp\\line break.docx");
// Specify any options here
TxtSaveOptions txtSaveOptions = new TxtSaveOptions();
doc.Save("C:\\Temp\\21.1.txt", txtSaveOptions);
Do you see any problems in above 21.1.txt? Can you please ZIP and upload your sample source Word document containing line breaks and your expected TXT file showing the desired output here for our reference? You may manually create expected Text (.txt) file by using MS Word. We will then investigate the scenario further on our end and provide you more information.
I am looking for automatically inserted line breaks, not hard entered. The wdFormatDOSTextLineBreaks when saving from Word, will auto insert line breaks to make a long sentence wrap to fit within margins. Please see attached samples.zip (10.7 KB).
We have logged your requirement in our issue tracking system. Your ticket number is WORDSNET-21716. We will further look into the details of this requirement and will keep you updated on the status of the linked ticket.
Any updates on this?
Thank you
@Peter_V2 You can use TxtSaveOptions.MaxCharactersPerLine property to achieve this:
Document doc = new Document();
DocumentBuilder builder = new DocumentBuilder(doc);
builder.Write("Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. " +
"Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.");
// Set 30 characters as maximum allowed per one line.
TxtSaveOptions saveOptions = new TxtSaveOptions { MaxCharactersPerLine = 30 };
doc.Save(@"C:\Temp\out.txt", saveOptions);
Is it what you are looking for?
Not quite. While this is helpful for controlling max characters per line at the program level, wdFormatDOSTextLineBreaks allows doing so at the word document level. If I set the font to a fixed width font and adjust the page width and font size, with wdFormatDOSTextLineBreaks I can export the text exactly as it appears in the word document. With MaxCharactersPerLine, this is controlled externally. WdSaveFormat enumeration (Word)
@Peter_V2 Unfortunately, this feature is not implemented yet and is not scheduled for development. Please accept our apologies for your inconvenience.
Though, you can use LayoutCollector and LayoutEnumerator classes to get limited information about document layout. The following code demonstrates a basic technique, which can be used to get document content line by line:
Document doc = new Document(@"C:\Temp\in.docx");
// Split all Run nodes in the document to make them not more than one word.
Node[] runs = doc.GetChildNodes(NodeType.Run, true).ToArray();
foreach (Node n in runs)
{
Run current = (Run)n;
while (current.Text.IndexOf(' ') >= 0)
current = SplitRun(current, current.Text.IndexOf(' ') + 1);
}
// Wrap all runs in the document with bookmarks to make it possible to work with LayoutCollector and LayoutEnumerator
runs = doc.GetChildNodes(NodeType.Run, true).ToArray();
List<string> tmpBookmakrs = new List<string>();
int bkIndex = 0;
foreach (Node r in runs)
{
// LayoutCollector and LayoutEnumerator does not work with nodes in header/footer or in textboxes.
if (r.GetAncestor(NodeType.HeaderFooter) != null || r.GetAncestor(NodeType.Shape) != null)
continue;
BookmarkStart start = new BookmarkStart(doc, "r" + bkIndex);
BookmarkEnd end = new BookmarkEnd(doc, start.Name);
r.ParentNode.InsertBefore(start, r);
r.ParentNode.InsertAfter(end, r);
tmpBookmakrs.Add(start.Name);
bkIndex++;
}
// Now we can use collector and enumerator to get runs per line in MS Word document.
LayoutCollector collector = new LayoutCollector(doc);
LayoutEnumerator enumerator = new LayoutEnumerator(doc);
object currentLine = null;
foreach (string bkName in tmpBookmakrs)
{
Bookmark bk = doc.Range.Bookmarks[bkName];
enumerator.Current = collector.GetEntity(bk.BookmarkStart);
while (enumerator.Type != LayoutEntityType.Line)
enumerator.MoveParent();
if (!enumerator.Current.Equals(currentLine))
{
currentLine = enumerator.Current;
Console.WriteLine();
Console.WriteLine("-------=========Start Of Line=========-------");
}
Node nextNode = bk.BookmarkStart.NextSibling;
if (nextNode != null && nextNode.NodeType == NodeType.Run)
Console.Write(((Run)nextNode).Text);
}
private static Run SplitRun(Run run, int position)
{
Run afterRun = (Run)run.Clone(true);
run.ParentNode.InsertAfter(afterRun, run);
afterRun.Text = run.Text.Substring(position);
run.Text = run.Text.Substring(0, position);
return afterRun;
}
Thank you. I will try this to see if it will work for us.
Just out of curiosity, what happened with the WORDSNET-21716 ticket?
@Peter_V2 The issue WORDSNET-21716 has been postponed due to low demand and complexity of this feature implementation.