diff --git a/CSharp/Plugins/UniversalEditor.Essential/DataFormats/RichTextMarkup/RTML/RTMLDataFormat.cs b/CSharp/Plugins/UniversalEditor.Essential/DataFormats/RichTextMarkup/RTML/RTMLDataFormat.cs new file mode 100644 index 00000000..4653c8b6 --- /dev/null +++ b/CSharp/Plugins/UniversalEditor.Essential/DataFormats/RichTextMarkup/RTML/RTMLDataFormat.cs @@ -0,0 +1,73 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using UniversalEditor.IO; + +using UniversalEditor.ObjectModels.RichTextMarkup; + +namespace UniversalEditor.DataFormats.RichTextMarkup.RTML +{ + /// + /// Data format for expressing Rich Text Format files as MarkupObjectModel. + /// + public class RTMLDataFormat : DataFormat + { + private static DataFormatReference _dfr = null; + protected override DataFormatReference MakeReferenceInternal() + { + if (_dfr == null) + { + _dfr = base.MakeReferenceInternal(); + _dfr.Capabilities.Add(typeof(RichTextMarkupObjectModel), DataFormatCapabilities.All); + } + return _dfr; + } + + protected override void LoadInternal(ref ObjectModel objectModel) + { + } + + protected override void SaveInternal(ObjectModel objectModel) + { + Writer writer = base.Accessor.Writer; + + RichTextMarkupObjectModel rtml = (objectModel as RichTextMarkupObjectModel); + if (rtml == null) throw new ObjectModelNotSupportedException(); + + foreach (RichTextMarkupItem item in rtml.Items) + { + RenderItem(writer, item); + } + } + + private RichTextMarkupItem lastItemRendered = null; + + private void RenderItem(Writer writer, RichTextMarkupItem item) + { + if (item is RichTextMarkupItemGroup) + { + RichTextMarkupItemGroup itm = (item as RichTextMarkupItemGroup); + writer.Write("{"); + foreach (RichTextMarkupItem item1 in itm.Items) + { + RenderItem(writer, item1); + } + writer.Write("}"); + } + else if (item is RichTextMarkupItemTag) + { + RichTextMarkupItemTag itm = (item as RichTextMarkupItemTag); + writer.Write("\\"); + writer.Write(itm.Name); + } + else if (item is RichTextMarkupItemLiteral) + { + RichTextMarkupItemLiteral itm = (item as RichTextMarkupItemLiteral); + if (!(lastItemRendered is RichTextMarkupItemLiteral)) writer.Write(" "); + writer.Write(itm.Content); + } + lastItemRendered = item; + } + } +} diff --git a/CSharp/Plugins/UniversalEditor.Essential/DataFormats/Text/Formatted/RichText/RTFCharacterSet.cs b/CSharp/Plugins/UniversalEditor.Essential/DataFormats/Text/Formatted/RichText/RTFCharacterSet.cs new file mode 100644 index 00000000..7fdd1311 --- /dev/null +++ b/CSharp/Plugins/UniversalEditor.Essential/DataFormats/Text/Formatted/RichText/RTFCharacterSet.cs @@ -0,0 +1,28 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace UniversalEditor.DataFormats.Text.Formatted.RichText +{ + public enum RTFCharacterSet + { + /// + /// ANSI (ansi) + /// + ANSI, + /// + /// Apple Macintosh (mac) + /// + AppleMacintosh, + /// + /// IBM PC code page 437 (pc) + /// + IBMPC437, + /// + /// IBM PC code page 850, used by IBM Personal System/2 (not implemented in version 1 of + /// Microsoft Word for OS/2) (pca) + /// + IBMPC850 + } +} diff --git a/CSharp/Plugins/UniversalEditor.Essential/DataFormats/Text/Formatted/RichText/RTFDataFormat.cs b/CSharp/Plugins/UniversalEditor.Essential/DataFormats/Text/Formatted/RichText/RTFDataFormat.cs index d9ee731f..9fb8d270 100644 --- a/CSharp/Plugins/UniversalEditor.Essential/DataFormats/Text/Formatted/RichText/RTFDataFormat.cs +++ b/CSharp/Plugins/UniversalEditor.Essential/DataFormats/Text/Formatted/RichText/RTFDataFormat.cs @@ -2,13 +2,16 @@ using System.Collections.Generic; using System.Linq; using System.Text; -using UniversalEditor.IO; + using UniversalEditor.ObjectModels.Text.Formatted; using UniversalEditor.ObjectModels.Text.Formatted.Items; +using UniversalEditor.ObjectModels.RichTextMarkup; +using UniversalEditor.DataFormats.RichTextMarkup.RTML; + namespace UniversalEditor.DataFormats.Text.Formatted.RichText { - public class RTFDataFormat : DataFormat + public class RTFDataFormat : RTMLDataFormat { private static DataFormatReference _dfr = null; protected override DataFormatReference MakeReferenceInternal() @@ -21,67 +24,131 @@ namespace UniversalEditor.DataFormats.Text.Formatted.RichText return _dfr; } - protected override void LoadInternal(ref ObjectModel objectModel) + private RTFCharacterSet mvarCharacterSet = RTFCharacterSet.ANSI; + /// + /// The character set used in this document. + /// + public RTFCharacterSet CharacterSet { get { return mvarCharacterSet; } set { mvarCharacterSet = value; } } + + private int mvarCodePage = 1252; + /// + /// The ANSI code page which is used to perform the Unicode to ANSI conversion when writing + /// RTF text. + /// + public int CodePage { get { return mvarCodePage; } set { mvarCodePage = value; } } + + protected override void BeforeLoadInternal(Stack objectModels) { + base.BeforeLoadInternal(objectModels); + objectModels.Push(new RichTextMarkupObjectModel()); } - - protected override void SaveInternal(ObjectModel objectModel) + protected override void AfterLoadInternal(Stack objectModels) { - FormattedTextObjectModel ftom = (objectModel as FormattedTextObjectModel); - if (ftom == null) throw new ObjectModelNotSupportedException(); + base.AfterLoadInternal(objectModels); - Writer writer = base.Accessor.Writer; - writer.Write("{\\rtf1"); - // writer.WriteLine("\\ansi\\ansicpg1252"); + RichTextMarkupObjectModel mom = (objectModels.Pop() as RichTextMarkupObjectModel); + FormattedTextObjectModel ftom = (objectModels.Pop() as FormattedTextObjectModel); + } + protected override void BeforeSaveInternal(Stack objectModels) + { + base.BeforeSaveInternal(objectModels); + FormattedTextObjectModel ftom = (objectModels.Pop() as FormattedTextObjectModel); + RichTextMarkupObjectModel rtml = new RichTextMarkupObjectModel(); + + RichTextMarkupItemGroup grpRTF1 = new RichTextMarkupItemGroup(new RichTextMarkupItemTag("rtf1")); + switch (mvarCharacterSet) + { + case RTFCharacterSet.ANSI: + { + grpRTF1.Items.Add(new RichTextMarkupItemTag("ansi")); + break; + } + case RTFCharacterSet.AppleMacintosh: + { + grpRTF1.Items.Add(new RichTextMarkupItemTag("mac")); + break; + } + case RTFCharacterSet.IBMPC437: + { + grpRTF1.Items.Add(new RichTextMarkupItemTag("pc")); + break; + } + case RTFCharacterSet.IBMPC850: + { + grpRTF1.Items.Add(new RichTextMarkupItemTag("pca")); + break; + } + } + grpRTF1.Items.Add(new RichTextMarkupItemTag("ansicpg" + mvarCodePage.ToString())); if (ftom.DefaultFont != null && ftom.Fonts.Contains(ftom.DefaultFont)) { - writer.Write("\\deff" + ftom.Fonts.IndexOf(ftom.DefaultFont)); + RichTextMarkupItemTag tagDEFF = new RichTextMarkupItemTag("deff" + ftom.Fonts.IndexOf(ftom.DefaultFont)); + grpRTF1.Items.Add(tagDEFF); } // writer.Write("\\deflang1033\\uc1"); if (ftom.Fonts.Count > 0) { - writer.Write("{\\fonttbl"); + RichTextMarkupItemGroup grpFontTbl = new RichTextMarkupItemGroup(new RichTextMarkupItemTag("fonttbl")); foreach (FormattedTextFont font in ftom.Fonts) { - writer.Write("{\\f" + ftom.Fonts.IndexOf(font).ToString() + " " + font.Name + ";}"); + grpFontTbl.Items.Add(new RichTextMarkupItemTag("f" + ftom.Fonts.IndexOf(font))); + switch (font.Family) + { + case FormattedTextFontFamily.Bidi: grpFontTbl.Items.Add(new RichTextMarkupItemTag("fbidi")); break; + case FormattedTextFontFamily.Decor: grpFontTbl.Items.Add(new RichTextMarkupItemTag("fdecor")); break; + case FormattedTextFontFamily.Modern: grpFontTbl.Items.Add(new RichTextMarkupItemTag("fmodern")); break; + case FormattedTextFontFamily.Roman: grpFontTbl.Items.Add(new RichTextMarkupItemTag("froman")); break; + case FormattedTextFontFamily.Script: grpFontTbl.Items.Add(new RichTextMarkupItemTag("fscript")); break; + case FormattedTextFontFamily.Swiss: grpFontTbl.Items.Add(new RichTextMarkupItemTag("fswiss")); break; + case FormattedTextFontFamily.Tech: grpFontTbl.Items.Add(new RichTextMarkupItemTag("ftech")); break; + } + grpFontTbl.Items.Add(new RichTextMarkupItemLiteral(font.Name + ";")); } - writer.Write("}"); + grpRTF1.Items.Add(grpFontTbl); } - foreach (FormattedTextItem item in ftom.Items) { - RenderItem(writer, item); + RenderItem(grpRTF1, item); } - writer.WriteLine(" }"); + + rtml.Items.Add(grpRTF1); + objectModels.Push(rtml); } - private void RenderItem(Writer writer, FormattedTextItem item) + private void RenderItem(RichTextMarkupItemGroup parent, FormattedTextItem item) { if (item is FormattedTextItemHyperlink) { FormattedTextItemHyperlink itm = (item as FormattedTextItemHyperlink); - writer.Write("{\\field{\\*\\fldinst {HYPERLINK \"" + itm.TargetURL + "\"}}{\\fldrslt {"); + + RichTextMarkupItemGroup grpField = new RichTextMarkupItemGroup(new RichTextMarkupItemTag("field")); + RichTextMarkupItemGroup grpAsterisk = new RichTextMarkupItemGroup(new RichTextMarkupItemTag("*"), new RichTextMarkupItemTag("fldinst")); + grpAsterisk.Items.Add(new RichTextMarkupItemGroup(new RichTextMarkupItemLiteral("HYPERLINK \"" + itm.TargetURL + "\""))); + grpField.Items.Add(grpAsterisk); + + RichTextMarkupItemGroup group = new RichTextMarkupItemGroup(); foreach (FormattedTextItem itm1 in itm.Items) { - RenderItem(writer, itm1); + RenderItem(group, itm1); } - writer.Write("}}}"); + grpField.Items.Add(new RichTextMarkupItemGroup(new RichTextMarkupItemTag("fldrslt"), group)); + parent.Items.Add(grpField); } else if (item is FormattedTextItemBold) { - writer.Write("{\b "); + RichTextMarkupItemGroup group = new RichTextMarkupItemGroup(new RichTextMarkupItemTag("b")); FormattedTextItemBold itm = (item as FormattedTextItemBold); foreach (FormattedTextItem itm1 in itm.Items) { - RenderItem(writer, itm1); + RenderItem(group, itm1); } - writer.Write("}"); + parent.Items.Add(group); } else if (item is FormattedTextItemLiteral) { - writer.Write((item as FormattedTextItemLiteral).Text); + parent.Items.Add(new RichTextMarkupItemLiteral((item as FormattedTextItemLiteral).Text)); } } } diff --git a/CSharp/Plugins/UniversalEditor.Essential/ObjectModels/RichTextMarkup/RichTextMarkupItem.cs b/CSharp/Plugins/UniversalEditor.Essential/ObjectModels/RichTextMarkup/RichTextMarkupItem.cs new file mode 100644 index 00000000..d7a52d49 --- /dev/null +++ b/CSharp/Plugins/UniversalEditor.Essential/ObjectModels/RichTextMarkup/RichTextMarkupItem.cs @@ -0,0 +1,18 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace UniversalEditor.ObjectModels.RichTextMarkup +{ + public abstract class RichTextMarkupItem : ICloneable + { + public class RichTextMarkupItemCollection + : System.Collections.ObjectModel.Collection + { + + } + + public abstract object Clone(); + } +} diff --git a/CSharp/Plugins/UniversalEditor.Essential/ObjectModels/RichTextMarkup/RichTextMarkupItemGroup.cs b/CSharp/Plugins/UniversalEditor.Essential/ObjectModels/RichTextMarkup/RichTextMarkupItemGroup.cs new file mode 100644 index 00000000..dfe3de8a --- /dev/null +++ b/CSharp/Plugins/UniversalEditor.Essential/ObjectModels/RichTextMarkup/RichTextMarkupItemGroup.cs @@ -0,0 +1,31 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace UniversalEditor.ObjectModels.RichTextMarkup +{ + public class RichTextMarkupItemGroup : RichTextMarkupItem + { + private RichTextMarkupItem.RichTextMarkupItemCollection mvarItems = new RichTextMarkupItemCollection(); + public RichTextMarkupItem.RichTextMarkupItemCollection Items { get { return mvarItems; } } + + public RichTextMarkupItemGroup(params RichTextMarkupItem[] items) + { + foreach (RichTextMarkupItem item in items) + { + mvarItems.Add(item); + } + } + + public override object Clone() + { + RichTextMarkupItemGroup clone = new RichTextMarkupItemGroup(); + foreach (RichTextMarkupItem item in mvarItems) + { + clone.Items.Add(item.Clone() as RichTextMarkupItem); + } + return clone; + } + } +} diff --git a/CSharp/Plugins/UniversalEditor.Essential/ObjectModels/RichTextMarkup/RichTextMarkupItemLiteral.cs b/CSharp/Plugins/UniversalEditor.Essential/ObjectModels/RichTextMarkup/RichTextMarkupItemLiteral.cs new file mode 100644 index 00000000..17a1efbc --- /dev/null +++ b/CSharp/Plugins/UniversalEditor.Essential/ObjectModels/RichTextMarkup/RichTextMarkupItemLiteral.cs @@ -0,0 +1,24 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace UniversalEditor.ObjectModels.RichTextMarkup +{ + public class RichTextMarkupItemLiteral : RichTextMarkupItem + { + private string mvarContent = String.Empty; + public string Content { get { return mvarContent; } set { mvarContent = value; } } + + public RichTextMarkupItemLiteral(string content = "") + { + mvarContent = content; + } + + public override object Clone() + { + RichTextMarkupItemLiteral clone = new RichTextMarkupItemLiteral(mvarContent.Clone() as string); + return clone; + } + } +} diff --git a/CSharp/Plugins/UniversalEditor.Essential/ObjectModels/RichTextMarkup/RichTextMarkupItemTag.cs b/CSharp/Plugins/UniversalEditor.Essential/ObjectModels/RichTextMarkup/RichTextMarkupItemTag.cs new file mode 100644 index 00000000..0d44d546 --- /dev/null +++ b/CSharp/Plugins/UniversalEditor.Essential/ObjectModels/RichTextMarkup/RichTextMarkupItemTag.cs @@ -0,0 +1,24 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace UniversalEditor.ObjectModels.RichTextMarkup +{ + public class RichTextMarkupItemTag : RichTextMarkupItem + { + private string mvarName = String.Empty; + public string Name { get { return mvarName; } set { mvarName = value; } } + + public RichTextMarkupItemTag(string name) + { + mvarName = name; + } + + public override object Clone() + { + RichTextMarkupItemTag clone = new RichTextMarkupItemTag(mvarName.Clone() as string); + return clone; + } + } +} diff --git a/CSharp/Plugins/UniversalEditor.Essential/ObjectModels/RichTextMarkup/RichTextMarkupObjectModel.cs b/CSharp/Plugins/UniversalEditor.Essential/ObjectModels/RichTextMarkup/RichTextMarkupObjectModel.cs new file mode 100644 index 00000000..0a1c1d25 --- /dev/null +++ b/CSharp/Plugins/UniversalEditor.Essential/ObjectModels/RichTextMarkup/RichTextMarkupObjectModel.cs @@ -0,0 +1,26 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace UniversalEditor.ObjectModels.RichTextMarkup +{ + public class RichTextMarkupObjectModel : ObjectModel + { + private RichTextMarkupItem.RichTextMarkupItemCollection mvarItems = new RichTextMarkupItem.RichTextMarkupItemCollection(); + public RichTextMarkupItem.RichTextMarkupItemCollection Items { get { return mvarItems; } } + + public override void Clear() + { + mvarItems.Clear(); + } + public override void CopyTo(ObjectModel where) + { + RichTextMarkupObjectModel clone = (where as RichTextMarkupObjectModel); + foreach (RichTextMarkupItem item in mvarItems) + { + clone.Items.Add(item.Clone() as RichTextMarkupItem); + } + } + } +} diff --git a/CSharp/Plugins/UniversalEditor.Essential/ObjectModels/Text/Formatted/FormattedTextFont.cs b/CSharp/Plugins/UniversalEditor.Essential/ObjectModels/Text/Formatted/FormattedTextFont.cs index c5c38f5e..125f7bd5 100644 --- a/CSharp/Plugins/UniversalEditor.Essential/ObjectModels/Text/Formatted/FormattedTextFont.cs +++ b/CSharp/Plugins/UniversalEditor.Essential/ObjectModels/Text/Formatted/FormattedTextFont.cs @@ -16,6 +16,9 @@ namespace UniversalEditor.ObjectModels.Text.Formatted private string mvarName = String.Empty; public string Name { get { return mvarName; } set { mvarName = value; } } + private FormattedTextFontFamily mvarFamily = FormattedTextFontFamily.None; + public FormattedTextFontFamily Family { get { return mvarFamily; } set { mvarFamily = value; } } + public object Clone() { FormattedTextFont clone = new FormattedTextFont(); diff --git a/CSharp/Plugins/UniversalEditor.Essential/ObjectModels/Text/Formatted/FormattedTextFontFamily.cs b/CSharp/Plugins/UniversalEditor.Essential/ObjectModels/Text/Formatted/FormattedTextFontFamily.cs new file mode 100644 index 00000000..d11cdb46 --- /dev/null +++ b/CSharp/Plugins/UniversalEditor.Essential/ObjectModels/Text/Formatted/FormattedTextFontFamily.cs @@ -0,0 +1,43 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace UniversalEditor.ObjectModels.Text.Formatted +{ + public enum FormattedTextFontFamily + { + /// + /// Unknown or default fonts + /// + None = 0, + /// + /// Roman, proportionally spaced serif fonts (e.g. Times New Roman, Palatino) + /// + Roman = 1, + /// + /// Swiss, proportionally spaced sans serif fonts (e.g. Arial) + /// + Swiss = 2, + /// + /// Fixed-pitch serif and sans serif fonts (e.g. Courier New, Pica) + /// + Modern = 3, + /// + /// Script fonts (e.g. Cursive) + /// + Script = 4, + /// + /// Decorative fonts (e.g. Old English, ITC Zapf Chancery) + /// + Decor = 5, + /// + /// Technical, symbol, and mathematical fonts (e.g. Symbol) + /// + Tech = 6, + /// + /// Arabic, Hebrew, or other bidirectional font (e.g. Miriam) + /// + Bidi = 7 + } +} diff --git a/CSharp/Plugins/UniversalEditor.Essential/UniversalEditor.Essential.csproj b/CSharp/Plugins/UniversalEditor.Essential/UniversalEditor.Essential.csproj index 55944d77..d6d99e70 100644 --- a/CSharp/Plugins/UniversalEditor.Essential/UniversalEditor.Essential.csproj +++ b/CSharp/Plugins/UniversalEditor.Essential/UniversalEditor.Essential.csproj @@ -48,6 +48,7 @@ + @@ -64,6 +65,7 @@ + @@ -100,10 +102,16 @@ + + + + + +