How to find the index of a paragraph in word 2010 - c#

I am reading a word document in c#,where after reading it, I need to enter a comment for selected paragraphs.
So I need to find the index of paragraph through c#, is it possible??
foreach (Microsoft.Office.Interop.Word.Paragraph aPar in oDoc.Paragraphs) // looping through all the paragh in document
{
Microsoft.Office.Interop.Word.Range parRng = aPar.Range;
string sText = parRng.Text;
if (sText == para[1].ToString()) // found the paragraph and i need the index of this paragraph
{
oDoc.Comments.Add(oDoc.Paragraphs[0].Range, ref comments); // to add the comment in document
}
}
If I found the index of that paragraph, Can I insert the comment on that paragraph? Is it possible?
Or is there any other way to do this?

Try this
foreach (Microsoft.Office.Interop.Word.Paragraph aPar in oDoc.Paragraphs) // loads all words in document
{
Microsoft.Office.Interop.Word.Range parRng = aPar.Range;
string sText = parRng.Text.Replace("\r","");
if (sText == txtBoxParagraph.Text ) // found the paragraph and i need the index of this paragraph
{
oDoc.Comments.Add(parRng, txtBoxComments.Text); // to add the comment in document
}
}
It works for me.

int i = 1;
foreach (Word.Paragraph aPar in oDoc.Paragraphs)
{
string sText = aPar.Range.Text;
if (sText != "\r")
{
if (sText == para[1].ToString() + "\r")
{
Word.Range range = oDoc.Paragraphs[i + 1].Range;
if (!range.Text.Contains("GUID:"))
{
int pEnd = aPar.Range.End;
string guid = "GUID:" + para[0].Replace("{", "").Replace("}", "");
int length = guid.Length;
aPar.Range.InsertAfter(guid);
Word.Range parRng = oDoc.Range(pEnd, pEnd + length);
parRng.Font.Hidden = 1;
parRng.InsertParagraphAfter();
}
}
}
i++;
}

Related

Find Superscript and Subscript in ms word?

I want to convert word files to html for insert to database and I can't find subscript and superscript.
How can I find these from Microsot Word file?
I found this solution for my question:
if (range.Font.Subscript > 0 || range.Font.Superscript > 0)
{
foreach (var subItem in range.Words)
{
var supTempRange = doc.Paragraphs[i + 1].Range;
supTempRange.Find.ClearFormatting();
supTempRange.Find.Format = true;
supTempRange.Find.Font.Superscript = 1;
while (supTempRange.Find.Execute())
{
MessageBox.Show(supTempRange.Text);
}
var subTempRange = doc.Paragraphs[i + 1].Range;
subTempRange.Find.ClearFormatting();
subTempRange.Find.Format = true;
subTempRange.Find.Font.Subscript = 1;
while (subTempRange.Find.Execute())
{
MessageBox.Show(subTempRange.Text);
}
}}

(C# WPF) "TextPointer.GetTextInRun" method ignores characters like "\r\n"

In C# WPF, I have a function to retrieve text from flowdocumentreader:
static string GetText(TextPointer textStart, TextPointer textEnd)
{
StringBuilder output = new StringBuilder();
TextPointer tp = textStart;
while (tp != null && tp.CompareTo(textEnd) < 0)
{
if (tp.GetPointerContext(LogicalDirection.Forward) ==
TextPointerContext.Text)
{
output.Append(tp.GetTextInRun(LogicalDirection.Forward));
}
tp = tp.GetNextContextPosition(LogicalDirection.Forward);
}
return output.ToString();
}
Then I use the function as follow:
string test = GetText(rtb.Document.ContentStart, rtb.Document.ContentEnd);
However, the string "test" ignores all the line breaks, which means "\r\n". It does keep the tab character, "\t".
My question is how to keep all the line breaks? I want to automatically highlight the first sentence of each paragraph, so I need to detect the line break characters, "\r\n".
Thanks in advance for your time.
Update:
I load the .rtf document into flowdocumentreader like this:
if (dlg.FileName.LastIndexOf(".rtf") != -1)
{
paraBodyText.Inlines.Clear();
string temp = File.ReadAllText(dlg.FileName, Encoding.UTF8);
MemoryStream stream = new MemoryStream(Encoding.UTF8.GetBytes(temp));
TextRange textRange = new TextRange(flow.ContentStart, flow.ContentEnd);
textRange.Load(stream, DataFormats.Rtf);
myDocumentReader.Document = flow;
stream.Close();
}
Edited
assuming that each paragraph has at least one sentence that ends with a dot, you can use the following code to make the first sentence bold:
List<TextRange> ranges = new List<TextRange>();
foreach (Paragraph p in rtb.Document.Blocks.OfType<Paragraph>())
{
TextPointer pointer = null;
foreach (Run r in p.Inlines.OfType<Run>())
{
int index = r.Text.IndexOf(".");
if (index != -1)
{
pointer = r.ContentStart.GetPositionAtOffset(index);
}
}
if (pointer == null)
continue;
var firsSentence = new TextRange(p.ContentStart, pointer);
ranges.Add(firsSentence);
}
foreach (var r in ranges)
{
r.ApplyPropertyValue(TextElement.FontWeightProperty, FontWeights.Bold);
}

Docx - Removing section of document

Is there a way to remove sections of a document where i can specify the beginning and ending tags?
i need a way that i can remove a section of the document by passing in both my start and end catches, (##DELETEBEGIN and ##DELETEEND)
for example i have this in my document:
Hello, welcome to this document
##DELETEBEGIN{Some values to check in the code}
Some text that will be removed if the value is true
##DELETEEND
Final Line
If you need to delete text from ##DELETEBEGIN to ##DELETEEND, where ##DELETEBEGIN is not at the beginning of a Paragraph and ##DELETEEND is not at the end of a Paragraph, this code should work.
DocX document = DocX.Load("C:\\Users\\phil\\Desktop\\text.docx");
bool flag = false;
List<List<string>> list1 = new List<List<string>>();
List<string> list2 = new List<string>();
foreach (Novacode.Paragraph item in document.Paragraphs)
{
//use this if you need whole text of a paragraph
string paraText = item.Text;
var result = paraText.Split(' ');
int count = 0;
list2 = new List<string>();
//use this if you need word by word
foreach (var data in result)
{
string word = data.ToString();
if (word.Contains("##DELETEBEGIN")) flag = true;
if (word.Contains("##DELETEEND"))
{
flag = false;
list2.Add(word);
}
if (flag) list2.Add(word);
count++;
}
list1.Add(list2);
}
for (int i = 0; i < list1.Count(); i++)
{
string temp = "";
for (int y = 0; y < list1[i].Count(); y++)
{
if (y == 0)
{
temp = list1[i][y];
continue;
}
temp += " " + list1[i][y];
}
if (!temp.Equals("")) document.ReplaceText(temp, "");
}
document.Save();
I have to give some credit to this post for looping through each word.
I think i have found a solution to this, at least it works for me, please let me know if there is anything i can do better:
the deleteCommand would be the ##DELETEBEGIN string and the deleteEndCommand would be the ##DELETEEND
private void RemoveSection(DocX doc, string deleteCommand, string deleteEndCommand)
{
try
{
int deleteStart = 0;
int deleteEnd = 0;
//Get the array of the paragraphs containing the start and end catches
for (int i = 0; i < doc.Paragraphs.Count; i++)
{
if (doc.Paragraphs[i].Text.Contains(deleteCommand))
deleteStart = i;
if (doc.Paragraphs[i].Text.Contains(deleteEndCommand))
deleteEnd = i;
}
if (deleteStart > 0 && deleteEnd > 0)
{
//delete from the paraIndex as the arrays will shift when a paragraph is deleted
int paraIndex = deleteStart;
for (int i = deleteStart; i <= deleteEnd; i++)
{
doc.RemoveParagraphAt(paraIndex);
}
}
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
}

Highlighting User Defined Keywords in RichTextBox

I am searching XML files to see if there are contents which match the words inserted in these textboxes txtComKeyword1, txtComKeyword2, txtComKeyword3 and/or txtComKeyword4. The function below is working, but may I know how can I highlight the keywords that user entered in the four textboxes that match that appear in my richComResults richtextbox?
For example, my user will fill in those four textboxes ie. txtComKeyword1, txtComKeyword2, txtComKeyword3 and txtComKeyword4. Then, my code will parse the XML file to see if the nodes contain these four keywords, if yes, the nodes' data will be output on my richComResults, I wanna highlight those four keywords (eg txtComKeyword1=hello, txtComKeyword2=bye, txtComKeyword3=morning, txtComKeyword4=night). These 4 words, if found and appear in richComResults, will be highlighted with color.
I have no clue after searching for a while, my case is much different from other questions. I am a newbie in programming, your help would be much appreciated. Thank you!
My Code:
private void searchComByKeywords()
{
// Process the list of files found in the directory.
string[] fileEntries = Directory.GetFiles(sourceDir);
foreach (string fileName in fileEntries)
{
XmlDocument xmlDoc = new XmlDocument(); //* create an xml document object.
string docPath = fileName;
xmlDoc.Load(docPath); //* load the XML document from the specified file.
XmlNodeList nodeList = xmlDoc.GetElementsByTagName("item");
foreach (XmlNode node in nodeList)
{
XmlElement itemElement = (XmlElement) node;
string itemDescription = itemElement.GetElementsByTagName("description")[0].InnerText;
if (txtComKeyword1.Text != (String.Empty) && itemDescription.ToLower().Contains(txtComKeyword1.Text.ToLower()) ||
txtComKeyword2.Text != (String.Empty) && itemDescription.ToLower().Contains(txtComKeyword2.Text.ToString()) ||
txtComKeyword3.Text != (String.Empty) && itemDescription.ToLower().Contains(txtComKeyword3.Text.ToString()) ||
txtComKeyword4.Text != (String.Empty) && itemDescription.ToLower().Contains(txtComKeyword4.Text.ToString()))
{
string itemTitle = itemElement.GetElementsByTagName("title")[0].InnerText;
string itemDate = itemElement.GetElementsByTagName("pubDate")[0].InnerText;
string itemAuthor = itemElement.GetElementsByTagName("author")[0].InnerText;
richComResults.AppendText("Author: " + itemAuthor + "\nDate: " + itemDate + "\nTitle: " + itemTitle + "\nDescription: " + itemDescription + "\n\n--------\n\n");
}
}
}
}
Try this:
int pointer = 0;
int index = 0;
string keyword = "txtComKeyword1";
while (true)
{
index = richComResults.Text.IndexOf(keyword, pointer);
//if keyword not found
if (index == -1)
{
break;
}
richComResults.Select(index, keyword.Length);
richComResults.SelectionFont = new System.Drawing.Font(richComResults.Font, FontStyle.Bold);
pointer = index + keyword.Length;
}
This searches for the keyword and highlights it. Then it continues the search after the found keyword. The pointer is used to keep track of the search position in your text. The index marks the position of the found keyword.
Jan's answer contains great content, but I shuddered mildly at the while(true) and break aspect! Here's my tweaked (case-insensitive) version...
int nextHigh = RTF.Text.IndexOf(txSearch, 0, StringComparison.OrdinalIgnoreCase);
while (nextHigh >= 0)
{
RTF.Select(nextHigh, txSearch.Length);
RTF.SelectionColor = Color.Red; // Or whatever
RTF.SelectionFont = new Font("Arial", 12, FontStyle.Bold); // you like
nextHigh = RTF.Text.IndexOf(txSearch, nextHigh + txSearch.Length, StringComparison.OrdinalIgnoreCase);
}
try this code :
void ParseLine(string line)
{
Regex r = new Regex("([ \\t{}():;])");
String[] tokens = r.Split(line);
foreach (string token in tokens)
{
// Set the tokens default color and font.
richTextBox1.SelectionColor = Color.Black;
richTextBox1.SelectionFont = new Font("Courier New", 10, FontStyle.Regular);
// Check whether the token is a keyword.
String[] keywords = { "Author", "Date", "Title", "Description", };
for (int i = 0; i < keywords.Length; i++)
{
if (keywords[i] == token)
{
// Apply alternative color and font to highlight keyword.
richTextBox1.SelectionColor = Color.Blue;
richTextBox1.SelectionFont = new Font("Courier New", 10, FontStyle.Bold);
break;
}
}
richTextBox1.SelectedText = token;
}
richTextBox1.SelectedText = "\n";
}
and after fill your string str with your method call my method :
string strRich =
"Author : Habib\nDate : 2012-08-10 \nTitle : mytitle \nDescription : desc\n";
Regex r = new Regex("\\n");
String[] lines = r.Split(strRich);
foreach (string l in lines)
{
ParseLine(l);
}
enjoy.

Select Range by string

How I can change this feature so I select the range of characters in a word document between the characters "E" and "F", if I have; xasdasdEcdscasdcFvfvsdfv is underlined to me the range -> cdscasdc
private void Rango()
{
Word.Range rng;
Word.Document document = this.Application.ActiveDocument;
object startLocation = "E";
object endLocation = "F";
// Supply a Start and End value for the Range.
rng = document.Range(ref startLocation, ref endLocation);
// Select the Range.
rng.Select();
}
This function will not let me pass by reference two objects of string type.......
Thanks
You need to pass the position in the document you want the range to cover, see:
How to: Define and Select Ranges in Documents
I have added some example code below:
var word = new Microsoft.Office.Interop.Word.Application();
string document = null;
using (OpenFileDialog dia = new OpenFileDialog())
{
dia.Filter = "MS Word (*.docx)|*.docx";
if (dia.ShowDialog() == DialogResult.OK)
{
document = dia.FileName;
}
}
if (document != null)
{
Document doc = word.Documents.Open(document, ReadOnly: false, Visible: true);
doc.Activate();
string text = doc.Content.Text;
int start = text.IndexOf('E') + 1;
int end = text.IndexOf('F');
if (start >= 0 && end >= 0 && end > start)
{
Range range = doc.Range(Start: start, End: end);
range.Select();
}
}
Do not forget to close the document and Word etc.

Categories

Resources