2024-09-04 23:05:14 +08:00

414 lines
16 KiB
C#

//using Microsoft.Office.Interop.Word;
using System.Drawing;
using UtilLib;
using System.Collections.Generic;
using System;
using Newtonsoft.Json;
using Microsoft.Office.Interop.Word;
using Microsoft.Office.Tools.Word;
using Bookmark = Microsoft.Office.Tools.Word.Bookmark;
using Section = Microsoft.Office.Interop.Word.Section;
using WdColor = Microsoft.Office.Interop.Word.WdColor;
namespace AIProofread
{
public class DocumentUtil
{
static int markId = 0;
/// <summary>
/// 添加一个书签
/// </summary>
/// <param name="color"></param>
/// <param name="start"></param>
/// <param name="end"></param>
/// <returns></returns>
public static Bookmark AddBookmark(string color, int start, int end)
{
var doc = Globals.ThisAddIn.Application.ActiveDocument;
var maxOffset = doc.Range().End;
if (start > maxOffset || end > maxOffset)
{
return null;
}
var document = Globals.Factory.GetVstoObject(doc);
var r = document.Range(start, end);
var mark = document.Controls.AddBookmark(r, string.Format("ai_mark_{0}", markId++));
mark.Tag = "ai_proofread";
if (color != null)
{
// 给选区添加背景颜色
r.Shading.BackgroundPatternColor = (WdColor)ColorTranslator.ToOle(Colors.FromHex(color));
}
return mark;
}
public static void SectionAddMark(string color)
{
var document = Globals.Factory.GetVstoObject(Globals.ThisAddIn.Application.ActiveDocument);
// 获取当前文档对象
var doc = Globals.ThisAddIn.Application.ActiveDocument;
// 获取选中
var sections = document.Sections;
foreach (Section section in sections)
{
var r = section.Range;
//Bookmark mark = r.Bookmarks.Add();
var mark = document.Controls.AddBookmark(r, string.Format("ai_mark_{0}", markId++));
mark.Tag = "ai_proofread";
// 给选区添加背景颜色
r.Shading.BackgroundPatternColor = (WdColor)ColorTranslator.ToOle(Colors.FromHex(color));
}
}
public static System.Collections.Generic.List<string> GetAllBookmark()
{
var bookmarks = Globals.ThisAddIn.Application.ActiveDocument.Bookmarks;
System.Collections.Generic.List<string> list = new System.Collections.Generic.List<string>();
foreach (Microsoft.Office.Interop.Word.Bookmark mark in bookmarks)
{
list.Add(mark.Name);
}
return list;
}
/// <summary>
/// 删除所有标签
/// </summary>
public static void RemoveBookmark()
{
RemoveBookmark(null);
}
public static void ClearProofreadMarks()
{
var document = Globals.ThisAddIn.Application.ActiveDocument;
var bookmarks = document.Bookmarks;
ControlCollection controls = Globals.Factory.GetVstoObject(document).Controls;
foreach (Microsoft.Office.Interop.Word.Bookmark mark in bookmarks)
{
if (Config.IsProofreadMark(mark.Name))
{
// 去除高亮
mark.Range.Shading.BackgroundPatternColor = WdColor.wdColorAutomatic;
// 去除下划线
//mark.Range.Underline = WdUnderline.wdUnderlineNone;
try
{
mark.Delete();
}
catch (Exception e)
{
Logger.Log("remove mark", e);
}
}
}
}
/// <summary>
/// 删除标签
/// </summary>
/// <param name="markId"></param>
public static void RemoveBookmark(string markId)
{
var document = Globals.Factory.GetVstoObject(Globals.ThisAddIn.Application.ActiveDocument);
if (document.Bookmarks.Count == 0) return;
// 不存在要移除的标签
if (null != markId && !document.Bookmarks.Exists(markId)) return;
var bookmarks = Globals.ThisAddIn.Application.ActiveDocument.Bookmarks;
foreach (Microsoft.Office.Interop.Word.Bookmark mark in bookmarks)
{
if (mark.Name == markId)
{
mark.Range.Shading.BackgroundPatternColor = (WdColor)WdColorIndex.wdAuto;
mark.Delete();
}
}
//foreach (var mark in document.Bookmarks)
//{
// if (markId != null)
// {
// if (mark.Name == markId)
// {
// // 删除
// mark.Delete();
// mark.Range.Shading.BackgroundPatternColor = (WdColor)WdColorIndex.wdAuto;
// return;
// }
// }
// else
// {
// mark.Delete();
// }
//}
}
public static System.Collections.Generic.List<string> GetSectionText()
{
var document = Globals.Factory.GetVstoObject(Globals.ThisAddIn.Application.ActiveDocument);
System.Collections.Generic.List<string> list = new System.Collections.Generic.List<string>();
if (document.Sections.Count == 0) return list;
foreach (Section item in document.Sections)
{
list.Add(item.Range.Text);
}
return list;
}
/// <summary>
/// 查找偏移量
/// </summary>
private static readonly int INSERT_FIND_OFFSET = 5;
/// <summary>
/// 查找校对项对应的range
/// </summary>
/// <param name="correct">校对项</param>
/// <param name="sentense">当前校对项所在句子</param>
/// <param name="prevOffset">上一个校对项结束位置</param>
/// <param name="document"></param>
/// <param name="range"></param>
/// <returns></returns>
public static Range FindRange(CorrectedContent correct, DocumentCorrectItem sentense,ref int prevOffset, Microsoft.Office.Interop.Word.Document document, Range range)
{
var paragraphText = range.Text;
string findText = correct.origin;
int wordStart = correct.start;
int wordEnd = correct.end;
int offset = sentense.SentenceOffset;
string originText = sentense.Insert;
object Start = range.Start + offset + wordStart;
object End = range.Start + offset + wordEnd;
try
{
var activeDocument = document;
// 查找对象位置
End = range.Start + offset + wordEnd;
Start = range.Start + offset + wordStart;
// 直接找到
var findRange = activeDocument.Range(ref Start,ref End);
// 判断对应选区是否是要找的文本
if (findRange.Text == findText)
{
return findRange;
}
#region 使
// 找前缀
var prefix = wordStart > 2 ? (
wordStart > INSERT_FIND_OFFSET
? originText.Substring(wordStart - INSERT_FIND_OFFSET, INSERT_FIND_OFFSET)
: originText.Substring(0, wordStart)
) : null;
// 找后缀
var suffix = prefix == null ? (
wordEnd + INSERT_FIND_OFFSET < originText.Length
? originText.Substring(wordStart, INSERT_FIND_OFFSET)
: originText.Substring(wordStart, originText.Length - wordStart)
) : null;
var start = prefix != null || suffix != null
? paragraphText.IndexOf(prefix ?? suffix, prevOffset) // item.start +
: -1;
if (start != -1)
{
var findOffset = range.Start + start + (prefix != null ? prefix.Length : 0);
findRange = document.Range(findOffset, findOffset + wordEnd - wordStart);
if (findRange.Text == findText) { return findRange; }
}
#endregion
// 使用段落字符串进行强匹配
start = paragraphText.IndexOf(findText, prevOffset);
if (start != -1)
{
start += range.Start;
return document.Range(start, start + findText.Length);
}
var msg1 = new Dictionary<string, object>{
{"message",range.Find.Found?"搜索到可用位置":"没有搜索到可用位置" },
{ "search_start",range.Start },
{ "search_end",range.End },
{ "search_text",range.Text }
};
Logger.Log(JsonConvert.SerializeObject(msg1));
//while (range.Find.Found)
//{
// var obj4 = range.Document;
// MatchControl = range.Start;
// MatchAlefHamza = range.End;
// var range2 = obj4.Range(ref MatchControl, ref MatchAlefHamza);
// num3 = range2.End;
// if (range2.Text == findText)
// {
// return range2;
// }
// break;
// //if (findIndex == num)
// //{
// //}
// //num++;
// //range.Find.MatchByte = true;
// //Find find2 = range.Find;
// //MatchAlefHamza = missword;
// //MatchControl = true;
// //MatchDiacritics = Type.Missing;
// //MatchKashida = Type.Missing;
// //Replace = Type.Missing;
// //ReplaceWith = Type.Missing;
// //Format = Type.Missing;
// //Wrap = Type.Missing;
// //Forward = Type.Missing;
// //MatchAllWordForms = Type.Missing;
// //MatchSoundsLike = Type.Missing;
// //MatchWildcards = Type.Missing;
// //MatchWholeWord = Type.Missing;
// //Start = Type.Missing;
// //End = Type.Missing;
// //// 再次重复查找
// //find2.Execute(ref MatchAlefHamza, ref MatchControl, ref MatchDiacritics, ref MatchKashida, ref Replace, ref ReplaceWith, ref Format, ref Wrap, ref Forward, ref MatchAllWordForms, ref MatchSoundsLike, ref MatchWildcards, ref MatchWholeWord, ref Start, ref End);
//}
//if (num3 == 0)
//{
// return null;
//}
}
catch (Exception ex)
{
Logger.Log(ex);
}
return null;
}
public static Bookmark FindRangeAndCreateBookmark(CorrectedContent correct, DocumentCorrectItem sentense, Microsoft.Office.Interop.Word.Document document, ref int prevOffset)
{
Bookmark bookmark = null;
try
{
ControlCollection controls = Globals.Factory.GetVstoObject(document).Controls;
var markName = Config.BuildBookmarkName(correct.id);
// 判断是否已经存在
if (controls.Contains(markName))
{
try
{
controls.Remove(markName);
}
catch (Exception) { }
}
// 判断段落是否存在
if (sentense.ParagraphNumber > document.Paragraphs.Count) return null;
var paragraph = document.Paragraphs[sentense.ParagraphNumber];
var findRange = FindRangeByCorrect(sentense, correct, paragraph, document, prevOffset);
if (findRange != null)
{
// 更新查找的结束位置
//prevOffset = findRange.End - paragraphStart;
bookmark = controls.AddBookmark(findRange, markName);
bookmark.Tag = "ai_proofread";
}
}
catch (Exception ex)
{
Logger.Log("create mark error:" + ex.Message + "\n" + ex.StackTrace + "\n\n");
}
return bookmark;
}
private static Range FindRangeByCorrect(DocumentCorrectItem c, CorrectedContent item, Paragraph paragraph, Microsoft.Office.Interop.Word.Document document, int prevOffset)
{
var paraRange = paragraph.Range;
var paraText = paraRange.Text;
var paraStart = paraRange.Start;
// 定位句子的其实位置
var offset = paraStart + c.SentenceOffset;
//var cutLength = Math.Min(c.InsertLen, paraText.Length - offset);
var sentence = paraText.Substring(c.SentenceOffset, c.InsertLength);
if (sentence == c.Insert)
{ // 比对原始内容与校对原文是否一致
var range = document.Range(offset + item.start, offset + item.end);
//
if (range.Text == item.origin) return range;
}
var originText = c.Insert;
// 如果是新增 则查找定位
if (item.tag == "i")
{
// 找前缀
var prefix1 = item.start > 2 ? (
item.start > INSERT_FIND_OFFSET
? originText.Substring(item.start - INSERT_FIND_OFFSET, INSERT_FIND_OFFSET)
: originText.Substring(0, item.start)
) : null;
// 找后缀
var suffix1 = prefix1 == null ? (
item.end + INSERT_FIND_OFFSET < originText.Length
? originText.Substring(item.start, INSERT_FIND_OFFSET)
: originText.Substring(item.start, originText.Length - item.start)
) : null;
// 偏移量
var start1 = prefix1 != null || suffix1 != null
? paraText.IndexOf(prefix1 ?? suffix1, prevOffset)
: -1;
if (start1 != -1)
{
var findOffset = paraStart + start1 + (prefix1 != null ? prefix1.Length : 0);
return document.Range(findOffset, findOffset);
}
}
// 执行查找
int wordStart = item.start;
int wordEnd = item.end;
// 找前缀
var prefix = wordStart > 2 ? (
wordStart > INSERT_FIND_OFFSET
? originText.Substring(wordStart - INSERT_FIND_OFFSET, INSERT_FIND_OFFSET)
: originText.Substring(0, wordStart)
) : null;
// 找后缀
var suffix = prefix == null ? (
wordEnd + INSERT_FIND_OFFSET < originText.Length
? originText.Substring(wordStart, INSERT_FIND_OFFSET)
: originText.Substring(wordStart, originText.Length - wordStart)
) : null;
var start = prefix != null || suffix != null
? paraText.IndexOf(prefix ?? suffix, prevOffset) // item.start +
: -1;
if (start != -1)
{
var findOffset = paraRange.Start + start + (prefix != null ? prefix.Length : 0);
var range = document.Range(findOffset, findOffset + wordEnd - wordStart);
if (range.Text == item.origin) { return range; }
}
// 直接定位查找
start = paraText.IndexOf(item.origin, prevOffset);
if (start == -1) return null;
// 定位整体开始位置
start = paraStart + start;
return document.Range(start, start + item.origin.Length);
}
}
}