protected bool ProcessParagraphs(OfficeDocumentProcessor aWordProcessor, Word.Paragraphs aParagraphs) { foreach (Word.Paragraph aParagraph in aParagraphs) { // get the Range object for this paragraph Word.Range aParagraphRange = aParagraph.Range; // if we're picking up where we left off and we're not there yet... int nCharIndex = 0; if (aWordProcessor.AreLeftOvers) { if (aWordProcessor.LeftOvers.Start > aParagraphRange.End) continue; // skip to the next paragraph nCharIndex = aWordProcessor.LeftOvers.StartIndex; aWordProcessor.LeftOvers = null; // turn off "left overs" } WordRange aThisParagraph = new WordRange(aParagraphRange); if (!ProcessRangeAsWords(aWordProcessor, aThisParagraph, nCharIndex)) return false; } return true; }
protected override void ApplyEntry(WordRange range, object source) { var product = source as IProduct; if (product == null) { return; } string text = range.Text; string argument = GetArgumentName(text); if (string.IsNullOrEmpty(argument)) { return; } string line = ComposeLine(product, argument); if (line == null) { return; } if (string.Equals(argument, "title", StringComparison.InvariantCultureIgnoreCase)) { range.AddHyperLink(product.Url, line); } else { InsertLines(range, new string[] { line }); } }
private static ICommand CreateCommand(WordRange commandRange) { string sheetnamePattern = "#[Ss][Hh][Ee][Ee][Tt][Nn][Aa][Mm][Ee]#"; string directReferencePattern = @"#(([^-]+)-)?([^#]+)#"; Match match; match = Regex.Match(commandRange.Text, sheetnamePattern); if (match.Success) { return(new SheetNameReference(commandRange)); } match = Regex.Match(commandRange.Text, directReferencePattern); if (match.Success) { string bookID = match.Groups[2].Value; string cellReference = match.Groups[3].Value; if (string.IsNullOrWhiteSpace(bookID)) { bookID = null; } return(new DirectReference(bookID, commandRange, cellReference)); } return(null); }
private static void AddBookmark(object item, WordRange nextEntry) { var bookmark = item as IBookmark; if (bookmark != null) { nextEntry.AddBookmark(bookmark.BookmarkName); } }
public void Apply(WordRange range, object source) { foreach (IReplacement replacement in Replacements) { replacement.Apply(range, source); } foreach (KeyValuePair <string, ReplacementsTree> entry in _subRanges) { string tagName = entry.Key; WordRange nextEntry = GetNextEntry(range, tagName); int index = 0; ReplacementsTree replacementsTree = entry.Value; IList <object> items = replacementsTree.GetItems(source); while (nextEntry != null) { if (items.Count == 0) { nextEntry.Replace(tagName, string.Empty); } else { if (index < items.Count) { if (index < items.Count - 1) { nextEntry.InsertAfter(nextEntry); } object item = items[index]; replacementsTree.Apply(nextEntry, item); AddBookmark(item, nextEntry); index++; if (index == items.Count) { index = 0; } } WordRange expandedRange = nextEntry.GetExpandedRange(0, 1); string expandedText = expandedRange.Text; if (!(expandedText.Length > nextEntry.Text.Length && expandedText[expandedText.Length - 1] == '\r')) { expandedRange = nextEntry; } string[] tags = tagName.Split('*'); for (int i = 0; i < tags.Length; i++) { DeleteTag(expandedRange, tags[i]); } } nextEntry = GetNextEntry(range, tagName); } } }
private void DeleteTag(WordRange range, string tag) { string[] stringsToDelete = { tag + "^13", tag }; for (int i = 0; i < stringsToDelete.Length; i++) { if (range.Delete(stringsToDelete[i])) { ; } } }
public void Apply(WordRange range, object source) { WordRange nextEntry = GetNextEntry(range); while (nextEntry != null) { ApplyEntry(nextEntry, source); ClearoutPatternEntries(nextEntry); nextEntry = GetNextEntry(range); } }
protected override void ApplyEntry(WordRange range, object source) { var product = source as IProduct; if (product != null) { if (!string.IsNullOrEmpty(product.ImageFileName)) { if (File.Exists(product.ImageFileName)) { range.InsertPicture(product.ImageFileName); } } } }
protected void InsertLines(WordRange range, string[] lines) { if (lines == null || lines.Length == 0) { return; } int linesCount = lines.Length; for (int i = 0; i < linesCount - 1; i++) { range.InsertAfter(lines[i] + "\n"); } range.InsertAfter(lines[linesCount - 1]); }
private static List <ICommand> CollectCommands(Document template) { template.Activate(); WordRange searchRange = template.Range(); searchRange.Find.Text = "#<*>#"; searchRange.Find.MatchWildcards = true; searchRange.Find.MatchWholeWord = true; var results = new List <ICommand>(); while (searchRange.Find.Execute()) { var command = CreateCommand(searchRange.Duplicate); if (command != null) { results.Add(command); } } return(results); }
public bool ProcessParagraphsIsoFormat(OfficeDocumentProcessor aWordProcessor, Word.Paragraphs aParagraphs) { foreach (Word.Paragraph aParagraph in aParagraphs) { // get the Range object for this paragraph Word.Range aParagraphRange = aParagraph.Range; // if we're picking up where we left off and we're not there yet... int nCharIndex = 0; if (aWordProcessor.AreLeftOvers) { if (aWordProcessor.LeftOvers.Start > aParagraphRange.End) continue; // skip to the next paragraph nCharIndex = aWordProcessor.LeftOvers.StartIndex; aWordProcessor.LeftOvers = null; // turn off "left overs" } WordRange aRunRange = new WordRange(aParagraphRange); int nStartIndex = aRunRange.StartIndex; System.Diagnostics.Debug.Assert(nStartIndex == 0); // if we have mixed character formatting, then use a binary search algorithm to find // the maximum run. if (MixedCharacterFormatting(aRunRange)) { int nWidth = aRunRange.EndIndex / 2; do { aRunRange.EndIndex++; } while (!MixedCharacterFormatting(aRunRange)); aRunRange.EndIndex--; // back up one } else { // the whole paragraph seems to be iso formatted, so exclude the paragraph end and // process it as a whole unit aRunRange.EndIndex--; if (!aWordProcessor.Process(aRunRange, ref nCharIndex)) { aWordProcessor.LeftOvers = aRunRange; return false; } } } return true; }
protected override void ApplyEntry(WordRange range, object source) { InsertLines(range, new string[] { DateTime.Now.ToString("dd.MM.yyyy") }); }
public SheetNameReference(WordRange target) { this.target = target; }
public DirectReference(string workbookID, WordRange target, string cellReference) { this.target = target; this.cellReference = cellReference; this.workbookID = workbookID; }
private WordRange GetNextEntry(WordRange range, string tagName) { return(range.Find(tagName, false, true)); }
protected override void ApplyEntry(WordRange range, object source) { InsertLines(range, new string[] { DateTime.Now.ToString("dd MMMM yyyy г", CultureInfo.GetCultureInfo("RU-ru")) }); }
// determine if this section of text (some portion of one or more paragraphs) has the find what text in it public FindResult FindReplaceCompare(WordRange aRunRange, ref int SearchAreaStart, ref int FoundAreaLength) { FindResult res = FindResult.eNothingFound; string strInput = aRunRange.Text; if (String.IsNullOrEmpty(strInput) || (m_aECRegex == null)) return res; // otherwise 'convert' it to see if the 'Find what' string is in it string strOutput = m_aECRegex.Convert(strInput); // if the input string is different from the output string, then the FindWhat string was found. if (strInput != strOutput) { #if !DefineToNotUseSplitAndConvert // The way the convert works is that it will replace each instance of the input string that matches // the FindWhat syntax (i.e. there may be more than one replacement we have to deal with). // here's the problem: if there was more than one replacment, then I really can't tell what portion // of the FindWhat text each replacement goes with. Consider the string "ababbbbbabb". If the 'Find // what' string is "ab+", then it breaks up to: "ab", "abbbbb", and "abb", but if these three are // right in a row and the replacement is "", then the resulting strOutput will be <delim><delim>... // repeated 3 times. So there's no way to tell which portion of the input text corresponds to which // portion of the output text. My original stab at it just treated them evenly and divide by the // number of consecutive replacements... this works if the 'FindWhat' is something like "ab". But all // bets are off if the user uses the "+" (eat-em-up) expression code. // I think the only solution is to always only deal with a single replacement... So... if we have more // than one match in a particular output (which we can tell by the Length of astrSegments), do a binary // search until we have only one. string[] astrSegments = GetFirstReplacementSplitArray(ref strInput, ref strOutput); // get the index to the first character of the replacement (which is the same as the first character // of the 'Find what' string as well). int nIndex = astrSegments[0].Length; // remember this so we pick up here later SearchAreaStart += nIndex; if (nIndex > 0) aRunRange.Start = SearchAreaStart; // the replacement string is easy. It's just whatever's in the one'th element of the Split array. string strReplacementString = astrSegments[1]; // There might be some stuff between the end of the replacement and the end of the input string. string strStuffFollowingMatch = astrSegments[2]; // may be null // get the index to the end of the 'Find what' string int nEndOfFindWhatSelection; if (String.IsNullOrEmpty(strStuffFollowingMatch)) nEndOfFindWhatSelection = strInput.Length; else nEndOfFindWhatSelection = strInput.Length - strStuffFollowingMatch.Length; #else // this could probably be done more elegantly with Split rather than what I do in the #else case string[] astrSegments = strOutput.Split(m_achDelimiter); // must be odd (before, ||: replace, following :||), where any or all can be null int nTotalSegments = astrSegments.Length; System.Diagnostics.Debug.Assert((nTotalSegments % 2) == 1); // get the index to the first character of the replacement (which is the same as the first character // of the 'Find what' as well). int nIndex = astrSegments[0].Length; // remember this so we pick up here later SearchAreaStart += nIndex; if (nIndex > 0) aRunRange.Start = SearchAreaStart; // the replacement string is easy. It's just whatever's in the 1st element of the Split array. // but we have to figure out what the 'Find what' text is so that we can select it (so we can replace // it). This is not so easy, because it could be anything and not just a string of text like in a normal // find. string strReplacementString = astrSegments[1]; // Between the end of the first replacement and the beginning of the next (if multiple replacments) // is a string which should match something in the original, which we can search for string strStuffFollowingMatch = astrSegments[2]; // may be null int nEndOfFindWhatSelection; if (String.IsNullOrEmpty(strStuffFollowingMatch)) { // If the 'Find what' is repeated twice in a row, then the stuff in-between the two instances of // replacement text will be null. // Detect this by looking at the length of the even number string array elements (2, 4, etc), // which are the segments following the replacements. This tells us what we have to divide by // to get the proportion for only one find. int nNumReplacmentsInARow = 1; int nNextReplacementIndex = 2; nTotalSegments--; while ((nNextReplacementIndex < nTotalSegments) && String.IsNullOrEmpty(astrSegments[nNextReplacementIndex])) { nNumReplacmentsInARow++; nNextReplacementIndex += 2; } if (nNextReplacementIndex < astrSegments.Length) strStuffFollowingMatch = astrSegments[nNextReplacementIndex]; int numerator; if (String.IsNullOrEmpty(strStuffFollowingMatch)) numerator = strInput.Length; else numerator = strInput.IndexOf(strStuffFollowingMatch, nIndex + 1); nEndOfFindWhatSelection = ((numerator - nIndex) / nNumReplacmentsInARow) + nIndex; } else nEndOfFindWhatSelection = strInput.IndexOf(strStuffFollowingMatch, nIndex + 1); /* int nIndex = strOutput.IndexOf(m_achDelimiter[0]); System.Diagnostics.Debug.Assert(nIndex != -1); SearchAreaStart += nIndex; if (nIndex > 0) aRunRange.Start = SearchAreaStart; int nEndOfReplacement = strOutput.IndexOf(m_achDelimiter[0], nIndex + 1); System.Diagnostics.Debug.Assert(nEndOfReplacement != -1); // the replacement string is what's between these two string strReplacementString = strOutput.Substring(nIndex + 1, (nEndOfReplacement - nIndex - 1)); // now the complicated part. Between the end of the first replacement and the next // one is a string which should match something in the original. But if the replacement // were null, then it could be the very next character... // This also handles the situation where there may be several "found whats" int nNumReplacmentsInARow = 1; int nNextIndex = nEndOfReplacement + 1; while ((nNextIndex < strOutput.Length) && (strOutput[nNextIndex] == m_achDelimiter[0])) { nNumReplacmentsInARow++; nEndOfReplacement = strOutput.IndexOf(m_achDelimiter[0], nNextIndex + 1); nNextIndex = nEndOfReplacement + 1; } if (nNextIndex < strOutput.Length) { nEndOfReplacement = strOutput.IndexOf(m_achDelimiter[0], nNextIndex + 1); if (nEndOfReplacement == -1) nEndOfReplacement = strOutput.Length; } else if (nNextIndex == strOutput.Length) nNextIndex--; string strStuffFollowingMatch = strOutput.Substring(nNextIndex, nEndOfReplacement - nNextIndex); nEndOfFindWhatSelection = ((strInput.Length - nIndex) / nNumReplacmentsInARow) + nIndex; if (!String.IsNullOrEmpty(strStuffFollowingMatch)) { nEndOfFindWhatSelection = strInput.IndexOf(strStuffFollowingMatch, nIndex + 1) / nNumReplacmentsInARow; } */ #endif // !UseSplitToFindReplacements FoundAreaLength = nEndOfFindWhatSelection - nIndex; aRunRange.End = SearchAreaStart + FoundAreaLength; // if we're doing ReplaceAll or Replace when the FindWhat string has been found... System.Diagnostics.Debug.Assert(FormButton != FormButtons.Cancel); // means it wasn't initialized if (!DontReplaceOnNextFind && ((ReplaceAll) || ((FormButton == FormButtons.ReplaceOnce) && (nIndex == 0)))) { if (FormButton == FormButtons.ReplaceOnce) DontReplaceOnNextFind = true; // so we do a virtual find next after this // this means replace the word in situ, with what was converted ReplaceText(aRunRange, strReplacementString); NumOfReplacements++; // start the next search after this replaced value string strReplacedText = aRunRange.Text; // this may not be exactly the same as strReplace (e.g. after replacing final '\r') if (!String.IsNullOrEmpty(strReplacedText)) { FoundAreaLength = strReplacedText.Length; SearchAreaStart += FoundAreaLength; } res = FindResult.eReplaceFound; } else { // select just the search string and return as if cancelled so the outer loop can prompt for it. IsFound = true; // select the FindWhat text found aRunRange.Select(); res = FindResult.eFindFound; } } else if (FormButton == FormButtons.ReplaceOnce) { // otherwise, if the user clicked ReplaceOnce and we didn't find it right away, // then change it to function like Find instead. DontReplaceOnNextFind = true; // so we do a virtual find next after this } return res; }
public bool ProcessWholeParagraphs(OfficeDocumentProcessor aWordProcessor, Word.Paragraphs aParagraphs) { foreach (Word.Paragraph aParagraph in aParagraphs) { // get the Range object for this paragraph Word.Range aParagraphRange = aParagraph.Range; // if we're picking up where we left off and we're not there yet... int nCharIndex = 0; if (aWordProcessor.AreLeftOvers) { if (aWordProcessor.LeftOvers.Start > aParagraphRange.End) continue; // skip to the next paragraph nCharIndex = aWordProcessor.LeftOvers.StartIndex; aWordProcessor.LeftOvers = null; // turn off "left overs" } WordRange aRunRange = new WordRange(aParagraphRange); int nEndIndex = --aRunRange.EndIndex; int nLastIndex = nCharIndex; // exclude the paragraph end and process it as a whole unit (we may have to do this multiple times bool bStop = false; while (!bStop && (nCharIndex < nEndIndex)) { aRunRange.StartIndex = nCharIndex; if (aRunRange.EndIndex != nEndIndex) aRunRange.EndIndex = nEndIndex; nLastIndex = nCharIndex; System.Diagnostics.Trace.WriteLine(String.Format("Start: {0}, End: {1}, text: {2}, length: {3}", aRunRange.Start, aRunRange.End, aRunRange.Text, aRunRange.Text.Length)); if (!aWordProcessor.Process(aRunRange, ref nCharIndex)) { aWordProcessor.LeftOvers = aRunRange; return false; } if (nLastIndex == nCharIndex) break; } } return true; }
private void ClearoutPatternEntries(WordRange range) { range.Replace(TagName, string.Empty); }
private WordRange GetNextEntry(WordRange range) { return(range.Find(TagName, false, true)); }
protected override void ApplyEntry(WordRange range, object source) { var category = (ICategory)source; InsertLines(range, new string[] { category.CategoryName }); }
public override bool ProcessWordByWord(OfficeDocumentProcessor aWordProcessor) { // if multiple paragraphs... int nCharIndex = 0; WordParagraphs aParagraphRanges = new WordParagraphs(Document.Application.Selection); foreach (Word.Range aRange in aParagraphRanges) { WordRange aThisParagraph = new WordRange(aRange); if (!ProcessRangeAsWords(aWordProcessor, aThisParagraph, nCharIndex)) return false; } return true; }
public void ReplaceText(WordRange aRunRange, string strNewText) { try { aRunRange.Text = strNewText; } catch (Exception ex) { if (ex.Message == "The range cannot be deleted.") { aRunRange.End++; string strText = aRunRange.Text; if (strText[strText.Length - 1] == '\n') { throw new ApplicationException(String.Format("The paragraphs in this document end with both a carriage return (i.e. \\r) and a line feed character (i.e. \\n).{0}You need to change your 'Find what' string to include both (i.e. '\r\n'), or the found text can't be replaced.", Environment.NewLine)); } } } }
protected abstract void ApplyEntry(WordRange range, object source);
public void ProcessParagraphsFindAndReplace(FindWordProcessor aWordProcessor, Word.Range theRangeToSearch, BackgroundWorker worker) { // get Range object we can manipulate for searching (i.e. don't muck with the original WordRange aRunRange = GetStartingRange(theRangeToSearch); if (aRunRange == null) return; // how many paragraphs ahead we have to look for a match int nEndRangeToSearch = -1; // might change from loop to loop if we do replacements (so update inside loop) object nOffsetParagraph = aWordProcessor.NumOfParagraphsToSearch - 1; do { SearchAreaStart = aRunRange.Start; // this updates the progress bar worker.ReportProgress(SearchAreaStart); // if the search string contains multiple '\r's, then we have to look ahead that many paragraphs int SearchAreaEnd; nEndRangeToSearch = theRangeToSearch.End; // might change from loop to loop if we do replacements if (0 < (int)nOffsetParagraph) { Word.Paragraph aEndParagraph = m_paraSearch.Next(ref nOffsetParagraph); if (aEndParagraph == null) return; // means we can't possibly find it now SearchAreaEnd = Math.Min(aEndParagraph.Range.End, nEndRangeToSearch); aRunRange.End = SearchAreaEnd; } else { int nEndOfRun = aRunRange.End; if (nEndOfRun > nEndRangeToSearch) { aRunRange.End = SearchAreaEnd = nEndRangeToSearch; } else SearchAreaEnd = nEndOfRun; } // loop until the end of the paragraph and process it as a whole unit (we may have to do this multiple times) bool bGoToNext = true; while (SearchAreaStart < SearchAreaEnd) { // keep track of the last index so we can tell whether anything was found or not FindWordProcessor.FindResult res = aWordProcessor.FindReplaceCompare(aRunRange, ref SearchAreaStart, ref FoundAreaLength); // if we found it and need to stop (or if the user had cancelled the search)... bGoToNext = true; // assume we will if ((res == FindWordProcessor.FindResult.eFindFound) || worker.CancellationPending) return; // otherwise, it might have been a replacement and we have to update the end of the paragraph // value and the end of the range and do it again (e.g. find the next occurrence to replace) else if (res == FindWordProcessor.FindResult.eReplaceFound) { // we might have actually removed the paragraph mark, in which case the next paragraph // is now part of the current paragraph. Unfortunately, the aParagraphRange isn't // updated. // if the search string contained '\r's, then we have to look ahead all over again if (aWordProcessor.IsAnyCRs) { bGoToNext = false; break; } else { Word.Range aParagraphRange = m_paraSearch.Range; SearchAreaEnd = aParagraphRange.End; aRunRange.End = SearchAreaEnd; aRunRange.Start = SearchAreaStart; } } // otherwise, it means we didn't find it here and we're done with this paragraph else { System.Diagnostics.Debug.Assert(!aWordProcessor.IsFound); break; } } // advance to the next paragraph if (bGoToNext) m_paraSearch = m_paraSearch.Next(ref offset1); if (m_paraSearch != null) { aRunRange = new WordRange(m_paraSearch.Range); // in the case we replace some CRs, we re-start where we left off (after the replaced text) if (!bGoToNext) aRunRange.Start = SearchAreaStart; } } while ((m_paraSearch != null) && (aRunRange.Start < nEndRangeToSearch)); }
protected override void ApplyEntry(WordRange range, object source) { var section = (Section)source; InsertLines(range, new string[] { section.SectionName }); }