/// <summary> /// 输出内容到FlowDocument /// </summary> /// <param name="disThis">要输出的内容</param> /// <param name="fd">显示的FlowDocument</param> /// <param name="OAld">全局,可不填</param> public static void Output(LineDisplay disThis, FlowDocument fd, LineDisplay OAld = null, bool UseRun = true) { if (disThis.OutPut == "") { return; } //***一个比较有用的案例: (读取的时候也可以使用这个) //TextBox1.Document.Blocks.Add(new Paragraph(new Run("内容") { })) if (OAld == null) { if (fd.Blocks.Count != 0 && fd.Blocks.LastBlock.GetType().ToString() == "System.Windows.Documents.Paragraph") { ((Paragraph)fd.Blocks.LastBlock).Inlines.Add(disThis.OutPutRun()); } else { fd.Blocks.Add(disThis.OutPutParagraph()); } } else if (UseRun && disThis.UseRun(OAld)) { if (fd.Blocks.Count != 0 && fd.Blocks.LastBlock.GetType().ToString() == "System.Windows.Documents.Paragraph") { ((Paragraph)fd.Blocks.LastBlock).Inlines.Add(disThis.OutPutRun());//OutPutRun\Prargraph 真的没有用?emm } else { fd.Blocks.Add(disThis.OutPutParagraph()); } } else { fd.Blocks.Add(disThis.OutPutParagraph()); } }
/// <summary> /// 将行显示行(实意)转换成行(文本) //注 |:| 会直接输出成行 /// </summary> /// <param name="OA">全局变量</param> /// <returns>行(文本)</returns> public Line ToLine(LineDisplay OA) { if (OutPut.StartsWith("|") && OutPut.EndsWith(":|")) { return(new Line(OutPut.Substring(1))); } return(new Line("linedisplay", "", OutPut, ToSubs(OA))); }
/// <summary> /// 将多个实意转换成Lps文档 /// </summary> /// <param name="displays">实意行显示</param> /// <param name="OA">全局变量</param> /// <returns></returns> public static LpsDocument LineDisplaysToLpsDocument(LineDisplay[] displays, LineDisplay OA) { LpsDocument lps = new LpsDocument(); foreach (LineDisplay ld in displays) { lps.AddLine(ld.ToLine(OA)); } return(lps); }
/// <summary> /// 输出Run /// </summary> /// <param name="OA">覆盖通用格式</param> /// <returns></returns> public Run OutPutRun(LineDisplay OA) { Run run = new Run(OutPut); if (OA.Bold != Bold) { if (Bold) { run.FontWeight = FontWeights.Bold; } } if (OA.Italic != Italic) { if (Italic) { run.FontStyle = FontStyles.Italic; } } if (OA.Underline != Underline) { if (Underline) { run.TextDecorations = TextDecorations.Underline; } } if (OA.Strikethrough != Strikethrough) { if (Strikethrough) { run.TextDecorations = TextDecorations.Strikethrough; } } if (OA.FontSize.ToString("f1") != FontSize.ToString("f1")) { run.FontSize = FontSize; } if (OA.FontFamily != FontFamily) { run.FontFamily = FontFamily; } if (OA.BackColor != BackColor) { run.Background = new SolidColorBrush(BackColor); } if (OA.FontColor != FontColor) { run.Foreground = new SolidColorBrush(FontColor); } //run.TextAlignment = Alignment; return(run); }
//xml操作 /// <summary> /// 将FlowDocument(Xaml)转换成实意显示行 /// </summary> /// <param name="xaml">FlowDocument(Xaml)</param> /// <param name="OA">全局变量</param> /// <returns></returns> public static LineDisplay[] XamlToLPT(FlowDocument xaml, LineDisplay OA) { List <LineDisplay> lps = new List <LineDisplay>(); MemoryStream ms = new MemoryStream(); // write XAML out to a MemoryStream TextRange tr = new TextRange( xaml.ContentStart, xaml.ContentEnd); tr.Save(ms, DataFormats.Xaml); ms.Seek(0, SeekOrigin.Begin); XmlDocument xml = new XmlDocument(); xml.Load(XmlReader.Create(ms, new XmlReaderSettings() { IgnoreComments = true })); //读取XAML转换成LineDisplay //得到顶层节点列表 XmlNodeList topM = xml.DocumentElement.ChildNodes; foreach (XmlElement element in topM) { if (element.Name == "Paragraph") { GetLineDisplaysFromLoopXmlElement(element, lps, OA); if (lps.Count == 0) { lps.Add(new LineDisplay(OA) { OutPut = "\n" }); } else { lps.Last().OutPut += '\n'; } } else {//ToDo:支持图片 MessageBox.Show(element.Name); } //清空多余的回车 } if (lps.Count != 0)//空的退回空 { lps.Last().OutPut = lps.Last().OutPut.TrimEnd('\n'); } return(lps.ToArray()); }
/// <summary> /// 从别处复制一份参数到本LD,(注意不包含Output) /// </summary> /// <param name="ld">样本</param> public void Set(LineDisplay ld) { FontSize = ld.FontSize; FontColor = ld.FontColor; BackColor = ld.BackColor; FontFamily = ld.FontFamily; Alignment = ld.Alignment; Bold = ld.Bold; Italic = ld.Italic; Underline = ld.Underline; Strikethrough = ld.Strikethrough; }
/// <summary> /// 循环获取文本输出从xml元素 /// </summary> /// <param name="element">xml元素</param> /// <param name="displays">显示行列表</param> /// <param name="OA">全局/临时全局变量</param> public static void GetLineDisplaysFromLoopXmlElement(XmlElement element, List <LineDisplay> displays, LineDisplay OA) { //先读这个element LineDisplay tmp = GetLineDisplayFormXmlElement(element, OA); if (tmp.OutPut != "")//如果有内容就先输出 { displays.Add(tmp); } foreach (XmlNode xn in element.ChildNodes) { //由于不可能有注释 直接转换 //放入循环中进行读取 switch (xn.NodeType) { case XmlNodeType.Text: if (tmp.OutPut == "") { tmp.OutPut = xn.Value; displays.Add(tmp); } else { tmp.OutPut = xn.Value; } break; case XmlNodeType.Element: GetLineDisplaysFromLoopXmlElement((XmlElement)xn, displays, tmp); break; case XmlNodeType.SignificantWhitespace: if (displays.Count == 0) { displays.Add(new LineDisplay(OA) { OutPut = xn.InnerText }); } else { displays.Last().OutPut += xn.InnerText; } break; default: //ToDo:支持图片 MessageBox.Show(xn.Name); break; } } }
/// <summary> /// 核心方法:显示文档内容 /// </summary> /// <param name="Document">FlowDocument</param> /// <param name="lpt">LPT文档</param> public static void DisplayDocument(FlowDocument Document, LptDocument lpt) { Document.Blocks.Clear(); Document.Background = new SolidColorBrush(lpt.OADisplay.BackColor); LineDisplay IADisplay = new LineDisplay(lpt.OADisplay);//清空旧的IA Document.Foreground = new SolidColorBrush(lpt.OADisplay.FontColor); Document.Background = new SolidColorBrush(lpt.OADisplay.BackColor); //用于判断下一行要不要用run 主要方法是判断行末是否有\n bool NextUseRun = false; lpt.LineNode = 1; while (lpt.ReadCanNext()) { DisplayLine(lpt.ReadNext(), Document, IADisplay, ref NextUseRun); } }
/// <summary> /// 显示其中一行的内容//只是单纯的显示(编辑用) /// </summary> /// <param name="line">哪一行的内容是</param> /// <param name="fd">要被显示的文档</param> public static void DisplayLine(Line line, FlowDocument fd, LineDisplay IAld, ref bool NextUseRun) { //Note: //pageend等指令插入使用|pageend:| line = new Line(line); //复制一个Line//(不会更改提供的内容) line.InsertSub(0, line); //Line将会被加进去,以至于可以直接在遍历中找到Line.Name+info //输出的这一行将会用什么 LineDisplay disThis = new LineDisplay(IAld); //IAld = new LineDisplay(OAld);//不new 在外部完成 毕竟不止有一个line //区别:OA=全局,不会更变 IA=局部,会被更改 foreach (Sub sub in line) { switch (sub.Name.ToLower()) { case "": case "ia": //防止和IAdisplay头重叠 case "linedisplay": //防止自动生成的代码中linedisplay混淆 break; //case "cls":Cls不可能出现 出现就是bug // fd.Blocks.Clear(); // break; case "pageend": case "end": Output(new LineDisplay(IAld) { OutPut = $"|{sub.Name.ToLower()}:|" }, fd); break; case "shell": case "goto": case "img": case "open": case "mov": case "msg": Output(new LineDisplay(IAld) { OutPut = $"|{sub.Name.ToLower()}#{sub.info}:|" }, fd); break; case "font": case "fontfamily": if (sub.info == null) { //log.Append(sub.Name + ":未找到颜色记录\n"); } else { disThis.FontFamily = new FontFamily(sub.Info); } break; case "allfont": case "allfontfamily": if (sub.info == null) { //log.Append(sub.Name + ":未找到颜色记录\n"); } else { disThis.FontFamily = new FontFamily(sub.Info); IAld.FontFamily = disThis.FontFamily; fd.FontFamily = disThis.FontFamily; } break; case "fontcolor": if (sub.info == null) { //log.Append(sub.Name + ":未找到颜色记录\n"); } else { disThis.FontColor = HEXToColor(sub.info); } break; case "allfontcolor": if (sub.info == null) { //log.Append(sub.Name + ":未找到颜色记录\n"); } else { disThis.FontColor = HEXToColor(sub.info); IAld.FontColor = disThis.FontColor; fd.Foreground = new SolidColorBrush(disThis.FontColor); } break; case "fontsize": if (sub.info == null) { //log.Append(sub.Name + ":未找到字体大小记录\n"); } else { disThis.FontSize = Convert.ToSingle(sub.info); } break; case "allfontsize": if (sub.info == null) { //log.Append(sub.Name + ":未找到字体大小记录\n"); } else { disThis.FontSize = Convert.ToSingle(sub.info); IAld.FontSize = disThis.FontSize; } break; case "backcolor": if (sub.info == null) { //log.Append(sub.Name + ":未找到颜色记录\n"); } else { disThis.BackColor = HEXToColor(sub.info); } break; case "allbackcolor": if (sub.info == null) { //log.Append(sub.Name + ":未找到颜色记录\n"); } else { disThis.BackColor = HEXToColor(sub.info); IAld.BackColor = disThis.BackColor; } break; case "backgroundcolor": if (sub.info == null) { //log.Append(sub.Name + ":未找到颜色记录\n"); } else { disThis.BackColor = HEXToColor(sub.info); IAld.BackColor = disThis.BackColor; fd.Background = new SolidColorBrush(HEXToColor(sub.info)); } break; case "u": case "underline": disThis.Underline = !disThis.Underline; break; case "b": case "bold": disThis.Bold = !disThis.Bold; break; case "i": case "italic": disThis.Italic = !disThis.Italic; break; case "d": case "deleteline": disThis.Strikethrough = !disThis.Strikethrough; break; case "l": case "left": disThis.Alignment = TextAlignment.Left; break; case "r": case "right": disThis.Alignment = TextAlignment.Right; break; case "c": case "center": disThis.Alignment = TextAlignment.Center; break; case "j": case "justify": disThis.Alignment = TextAlignment.Justify; break; //不兼容em case "h1": disThis.FontSize = 48; break; case "h2": disThis.FontSize = 36; break; case "h3": disThis.FontSize = 24; break; case "h4": disThis.FontSize = 16; break; case "h5": disThis.FontSize = 12; break; case "h6": disThis.FontSize = 9; break; default: //支持行内其他代码,为以后的支持插件做准备 //ToDo:跳转(goto)做成官方内置插件 使用委托 Output(new LineDisplay(IAld) { OutPut = '|' + sub.ToString() }, fd); break; } } disThis.OutPut += TextDeReplaceMD(line.text);//注:这个是用魔改/stop还是/stop 之所以这么用是因为这个是编辑用不是展示用 bool nextnextuserun = !disThis.OutPut.EndsWith("\n"); if (!nextnextuserun) { disThis.OutPut = disThis.OutPut.Substring(0, disThis.OutPut.Length - 1); } Output(disThis, fd, IAld, NextUseRun);//输出 NextUseRun = nextnextuserun; }
/// <summary> /// 判断两个实意行是否有相同的格式 (不对比文本) /// </summary> /// <param name="ld">被对比的实意行</param> /// <returns></returns> public bool Equals(LineDisplay ld) { return(!(FontSize != ld.FontSize || FontColor != ld.FontColor || BackColor != ld.BackColor || FontFamily != ld.FontFamily || Alignment != ld.Alignment || Bold != ld.Bold || Italic != ld.Italic || Underline != ld.Underline || Strikethrough != ld.Strikethrough)); }
/// <summary> /// 复制实体行格式(不包括输出) /// </summary> /// <param name="ld"></param> public LineDisplay(LineDisplay ld) { Set(ld); }
/// <summary> /// 获取这一xml元素的全部数据 /// </summary> /// <param name="element">ml元素</param> /// <param name="OA">全局/临时全局变量</param> /// <returns></returns> public static LineDisplay GetLineDisplayFormXmlElement(XmlElement element, LineDisplay OA) { LineDisplay tmp = new LineDisplay(OA); foreach (XmlAttribute atr in element.Attributes) { switch (atr.NodeType) { case XmlNodeType.Text: tmp.OutPut += atr.Value; break; case XmlNodeType.Attribute: switch (atr.Name) { case "": case "Margin": case "xml:lang": //弃用的参数 break; default: MessageBox.Show(atr.Name); break; //ToDo:支持图片 case "FontFamily": tmp.FontFamily = new FontFamily(atr.Value); break; case "Foreground": tmp.FontColor = LptDocument.HEXToColor(atr.Value); break; case "FontSize": tmp.FontSize = Convert.ToSingle(atr.Value); break; case "Background": tmp.BackColor = LptDocument.HEXToColor(atr.Value); break; case "FontWeight": tmp.Bold = (atr.Value == "Bold"); break; case "FontStyle": tmp.Italic = (atr.Value == "Italic"); break; case "TextDecorations": if (atr.Value == "Strikethrough") { tmp.Strikethrough = !tmp.Strikethrough; } else if (atr.Value == "Underline") { tmp.Underline = !tmp.Underline; } else { tmp.Strikethrough = false; tmp.Underline = false; } break; case "TextAlignment": switch (atr.Value) { case "Left": tmp.Alignment = TextAlignment.Left; break; case "Right": tmp.Alignment = TextAlignment.Right; break; case "Center": tmp.Alignment = TextAlignment.Center; break; case "Justify": tmp.Alignment = TextAlignment.Justify; break; default: tmp.Alignment = TextAlignment.Justify; break; } break; } break; case XmlNodeType.Element: MessageBox.Show(atr.Name); break; default: MessageBox.Show(atr.Name); break; //case XmlNodeType.Attribute: // tmp =GetLineDisplayFormXmlElement((XmlElement)atr, tmp); // break; } } return(tmp); }
/// <summary> /// 将显示行(实意)转换成Sub集合 /// </summary> /// <param name="OA">全局变量</param> /// <returns>行(文本)</returns> public Sub[] ToSubs(LineDisplay OA) { List <Sub> subs = new List <Sub>(); if (OA.Bold != Bold) { if (Bold) { subs.Add(new Sub("Bold", "")); } } if (OA.Italic != Italic) { if (Italic) { subs.Add(new Sub("Italic", "")); } } if (OA.Underline != Underline) { if (Underline) { subs.Add(new Sub("Underline", "")); } } if (OA.Strikethrough != Strikethrough) { if (Strikethrough) { subs.Add(new Sub("Deleteline", "")); } } if (OA.FontSize.ToString("f1") != FontSize.ToString("f1")) { subs.Add(new Sub("FontSize", FontSize.ToString("f2"))); } if (OA.FontFamily != FontFamily) { subs.Add(new Sub("FontFamily", FontFamily.ToString())); } if (OA.BackColor != BackColor) { subs.Add(new Sub("BackColor", LptDocument.ColorToHEX(BackColor))); } if (OA.FontColor != FontColor) { subs.Add(new Sub("FontColor", LptDocument.ColorToHEX(FontColor))); } if (OA.Alignment != Alignment) { switch (Alignment) { case TextAlignment.Left: subs.Add(new Sub("Left", "")); break; case TextAlignment.Right: subs.Add(new Sub("Right", "")); break; case TextAlignment.Center: subs.Add(new Sub("Center", "")); break; case TextAlignment.Justify: subs.Add(new Sub("Justify", "")); break; } } return(subs.ToArray()); }
/// <summary> /// 在什么情况下用Paragraph或者Run: 有非默认的TextAlignment /// </summary> /// <param name="OA"></param> /// <returns></returns> public bool UseRun(LineDisplay OA) { return(OA.Alignment == TextAlignment.Left); }