├── Doc └── viewer.png ├── TcPluginCore ├── QSWrapper.dll ├── WcxWrapper.dll ├── WdxWrapper.dll ├── WfxWrapper.dll ├── WlxWrapper.dll ├── TcPluginTools.dll ├── WrapperBuilder.exe ├── TcPluginInterface.dll └── WrapperBuilder.exe.config ├── Lib ├── Pek.Markdig.HighlightJs.dll └── README.md ├── MarkdownViewer ├── App.config ├── Properties │ ├── Settings.settings │ ├── AssemblyInfo.cs │ ├── Settings.Designer.cs │ ├── Resources.Designer.cs │ └── Resources.resx ├── packages.config ├── markdown_tmpl.txt ├── ViewerControl.Designer.cs ├── ViewerControl.cs ├── MarkdownViewer.cs ├── MarkdownViewer.csproj ├── ViewerControl.resx └── markdown_css.txt ├── README_zh.md ├── README.md ├── MarkdownViewer.sln └── .gitignore /Doc/viewer.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangzhfeng/MarkdownViewer/HEAD/Doc/viewer.png -------------------------------------------------------------------------------- /TcPluginCore/QSWrapper.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangzhfeng/MarkdownViewer/HEAD/TcPluginCore/QSWrapper.dll -------------------------------------------------------------------------------- /TcPluginCore/WcxWrapper.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangzhfeng/MarkdownViewer/HEAD/TcPluginCore/WcxWrapper.dll -------------------------------------------------------------------------------- /TcPluginCore/WdxWrapper.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangzhfeng/MarkdownViewer/HEAD/TcPluginCore/WdxWrapper.dll -------------------------------------------------------------------------------- /TcPluginCore/WfxWrapper.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangzhfeng/MarkdownViewer/HEAD/TcPluginCore/WfxWrapper.dll -------------------------------------------------------------------------------- /TcPluginCore/WlxWrapper.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangzhfeng/MarkdownViewer/HEAD/TcPluginCore/WlxWrapper.dll -------------------------------------------------------------------------------- /Lib/Pek.Markdig.HighlightJs.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangzhfeng/MarkdownViewer/HEAD/Lib/Pek.Markdig.HighlightJs.dll -------------------------------------------------------------------------------- /TcPluginCore/TcPluginTools.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangzhfeng/MarkdownViewer/HEAD/TcPluginCore/TcPluginTools.dll -------------------------------------------------------------------------------- /TcPluginCore/WrapperBuilder.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangzhfeng/MarkdownViewer/HEAD/TcPluginCore/WrapperBuilder.exe -------------------------------------------------------------------------------- /TcPluginCore/TcPluginInterface.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangzhfeng/MarkdownViewer/HEAD/TcPluginCore/TcPluginInterface.dll -------------------------------------------------------------------------------- /Lib/README.md: -------------------------------------------------------------------------------- 1 | update Pek.Markdig.HighlightJs 2 | 3 | - ignore `flow`, `sequence`, `mermaid` fenced code blocks 4 | - support .net4 5 | -------------------------------------------------------------------------------- /MarkdownViewer/App.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /MarkdownViewer/Properties/Settings.settings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /MarkdownViewer/packages.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /README_zh.md: -------------------------------------------------------------------------------- 1 | # MarkdownViewer 2 | 3 | MarkdownViewer是一款Total Commander的插件,用于浏览markdown文件,支持后缀为md和markdown的文件。 4 | 5 | ![](./Doc/viewer.png) 6 | 7 | # 版本历史 8 | 9 | ## v0.1 10 | 11 | - 支持查看markdown 12 | 13 | ## v0.2 14 | 15 | - fixed: 不支持Esc键关闭窗口的问题 [\#4](https://github.com/wangzhfeng/MarkdownViewer/issues/4) 16 | - 使用NuGet安装markdig库,方便本地开发 17 | 18 | 以上,多谢[thorn0](https://github.com/thorn0)提供的Commit。 19 | 20 | ## v0.3 21 | 22 | - feature: 支持打印文件,可使用本地打印机将预览结果打印为pdf 23 | - fixed: 无法预览本地文件 24 | - fixed: 无法选中并复制内容 [\#7](https://github.com/wangzhfeng/MarkdownViewer/issues/7) 25 | - fixed: 无法将依赖dll文件打包到最终结果包 26 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [中文](./README_zh.md) 2 | 3 | # MarkdownViewer 4 | 5 | MarkdownViewer is a Total Commander plugin, using preview markdown file which suffixed with md markdown and mk. 6 | 7 | ![](./Doc/viewer.png) 8 | 9 | # Version 10 | 11 | ## v0.1 12 | 13 | - support preview markdown file 14 | 15 | ## v0.2 16 | 17 | - fixed: cannot close window with Esc [\#4](https://github.com/wangzhfeng/MarkdownViewer/issues/4) 18 | - using Nuget to manage dependency 19 | 20 | Thanks to [thorn0](https://github.com/thorn0) for your commit. 21 | 22 | ## v0.3 23 | 24 | - feature: support print, can print to pdf through local printer 25 | - fixed: cannot preview local image 26 | - fixed: cannot select and copy [\#7](https://github.com/wangzhfeng/MarkdownViewer/issues/7) 27 | - fixed: dependented dll not package in output zip 28 | -------------------------------------------------------------------------------- /TcPluginCore/WrapperBuilder.exe.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /MarkdownViewer.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 15 4 | VisualStudioVersion = 15.0.26430.16 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MarkdownViewer", "MarkdownViewer\MarkdownViewer.csproj", "{D8467740-7A0C-4C43-A3E1-7523B4A782E3}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|Any CPU = Debug|Any CPU 11 | Release|Any CPU = Release|Any CPU 12 | EndGlobalSection 13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 14 | {D8467740-7A0C-4C43-A3E1-7523B4A782E3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 15 | {D8467740-7A0C-4C43-A3E1-7523B4A782E3}.Debug|Any CPU.Build.0 = Debug|Any CPU 16 | {D8467740-7A0C-4C43-A3E1-7523B4A782E3}.Release|Any CPU.ActiveCfg = Release|Any CPU 17 | {D8467740-7A0C-4C43-A3E1-7523B4A782E3}.Release|Any CPU.Build.0 = Release|Any CPU 18 | EndGlobalSection 19 | GlobalSection(SolutionProperties) = preSolution 20 | HideSolutionNode = FALSE 21 | EndGlobalSection 22 | EndGlobal 23 | -------------------------------------------------------------------------------- /MarkdownViewer/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // 有关程序集的一般信息由以下 6 | // 控制。更改这些特性值可修改 7 | // 与程序集关联的信息。 8 | [assembly: AssemblyTitle("MarkdownViewer")] 9 | [assembly: AssemblyDescription("Markdown Viewer")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("wangzhf")] 12 | [assembly: AssemblyProduct("MarkdownViewer")] 13 | [assembly: AssemblyCopyright("Copyright © 2017")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // 将 ComVisible 设置为 false 会使此程序集中的类型 18 | //对 COM 组件不可见。如果需要从 COM 访问此程序集中的类型 19 | //请将此类型的 ComVisible 特性设置为 true。 20 | [assembly: ComVisible(false)] 21 | 22 | // 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID 23 | [assembly: Guid("d8467740-7a0c-4c43-a3e1-7523b4a782e3")] 24 | 25 | // 程序集的版本信息由下列四个值组成: 26 | // 27 | // 主版本 28 | // 次版本 29 | // 生成号 30 | // 修订号 31 | // 32 | // 可以指定所有值,也可以使用以下所示的 "*" 预置版本号和修订号 33 | // 方法是按如下所示使用“*”: : 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /MarkdownViewer/Properties/Settings.Designer.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // This code was generated by a tool. 4 | // Runtime Version:4.0.30319.42000 5 | // 6 | // Changes to this file may cause incorrect behavior and will be lost if 7 | // the code is regenerated. 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | namespace MarkdownViewer.Properties 12 | { 13 | 14 | 15 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 16 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.0.0.0")] 17 | internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase 18 | { 19 | 20 | private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); 21 | 22 | public static Settings Default 23 | { 24 | get 25 | { 26 | return defaultInstance; 27 | } 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /MarkdownViewer/markdown_tmpl.txt: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | {2} 16 |
17 | 18 | 19 | 20 | 22 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /MarkdownViewer/ViewerControl.Designer.cs: -------------------------------------------------------------------------------- 1 | namespace MarkdownViewer 2 | { 3 | partial class ViewerControl 4 | { 5 | /// 6 | /// 必需的设计器变量。 7 | /// 8 | private System.ComponentModel.IContainer components = null; 9 | 10 | /// 11 | /// 清理所有正在使用的资源。 12 | /// 13 | /// 如果应释放托管资源,为 true;否则为 false。 14 | protected override void Dispose(bool disposing) 15 | { 16 | if (disposing && (components != null)) 17 | { 18 | components.Dispose(); 19 | } 20 | base.Dispose(disposing); 21 | } 22 | 23 | #region 组件设计器生成的代码 24 | 25 | /// 26 | /// 设计器支持所需的方法 - 不要修改 27 | /// 使用代码编辑器修改此方法的内容。 28 | /// 29 | private void InitializeComponent() 30 | { 31 | this.webBrowser1 = new System.Windows.Forms.WebBrowser(); 32 | this.SuspendLayout(); 33 | // 34 | // webBrowser1 35 | // 36 | this.webBrowser1.AllowWebBrowserDrop = false; 37 | this.webBrowser1.Dock = System.Windows.Forms.DockStyle.Fill; 38 | this.webBrowser1.IsWebBrowserContextMenuEnabled = false; 39 | this.webBrowser1.Location = new System.Drawing.Point(0, 0); 40 | this.webBrowser1.MinimumSize = new System.Drawing.Size(20, 20); 41 | this.webBrowser1.Name = "webBrowser1"; 42 | this.webBrowser1.Size = new System.Drawing.Size(406, 361); 43 | this.webBrowser1.TabIndex = 0; 44 | this.webBrowser1.WebBrowserShortcutsEnabled = true; 45 | this.webBrowser1.IsWebBrowserContextMenuEnabled = true; 46 | this.webBrowser1.DocumentCompleted += new System.Windows.Forms.WebBrowserDocumentCompletedEventHandler(this.webBrowser1_DocumentCompleted); 47 | // 48 | // ViewerControl 49 | // 50 | this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F); 51 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; 52 | this.Controls.Add(this.webBrowser1); 53 | this.Name = "ViewerControl"; 54 | this.Size = new System.Drawing.Size(406, 361); 55 | this.ResumeLayout(false); 56 | 57 | } 58 | 59 | #endregion 60 | 61 | internal System.Windows.Forms.WebBrowser webBrowser1; 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /MarkdownViewer/Properties/Resources.Designer.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // 此代码由工具生成。 4 | // 运行时版本:4.0.30319.42000 5 | // 6 | // 对此文件的更改可能会导致不正确的行为,并且如果 7 | // 重新生成代码,这些更改将会丢失。 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | namespace MarkdownViewer.Properties { 12 | using System; 13 | 14 | 15 | /// 16 | /// 一个强类型的资源类,用于查找本地化的字符串等。 17 | /// 18 | // 此类是由 StronglyTypedResourceBuilder 19 | // 类通过类似于 ResGen 或 Visual Studio 的工具自动生成的。 20 | // 若要添加或移除成员,请编辑 .ResX 文件,然后重新运行 ResGen 21 | // (以 /str 作为命令选项),或重新生成 VS 项目。 22 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "16.0.0.0")] 23 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 24 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 25 | internal class Resources { 26 | 27 | private static global::System.Resources.ResourceManager resourceMan; 28 | 29 | private static global::System.Globalization.CultureInfo resourceCulture; 30 | 31 | [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] 32 | internal Resources() { 33 | } 34 | 35 | /// 36 | /// 返回此类使用的缓存的 ResourceManager 实例。 37 | /// 38 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 39 | internal static global::System.Resources.ResourceManager ResourceManager { 40 | get { 41 | if (object.ReferenceEquals(resourceMan, null)) { 42 | global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("MarkdownViewer.Properties.Resources", typeof(Resources).Assembly); 43 | resourceMan = temp; 44 | } 45 | return resourceMan; 46 | } 47 | } 48 | 49 | /// 50 | /// 重写当前线程的 CurrentUICulture 属性 51 | /// 重写当前线程的 CurrentUICulture 属性。 52 | /// 53 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 54 | internal static global::System.Globalization.CultureInfo Culture { 55 | get { 56 | return resourceCulture; 57 | } 58 | set { 59 | resourceCulture = value; 60 | } 61 | } 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /MarkdownViewer/ViewerControl.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Text; 3 | using System.Windows.Forms; 4 | using System.IO; 5 | using Markdig; 6 | using OY.TotalCommander.TcPluginInterface.Lister; 7 | using System.Linq; 8 | using System.Reflection; 9 | using Pek.Markdig.HighlightJs; 10 | using System.Threading; 11 | 12 | namespace MarkdownViewer 13 | { 14 | public partial class ViewerControl : UserControl 15 | { 16 | private Encoding encoding = Encoding.UTF8; 17 | private const String TMPL_FILE_NAME = "markdown_tmpl.txt"; 18 | private const String CSS_FILE_NAME = "markdown_css.txt"; 19 | 20 | private ListerPlugin listerPlugin; 21 | 22 | public ViewerControl(ListerPlugin listerPlugin) 23 | { 24 | InitializeComponent(); 25 | this.listerPlugin = listerPlugin; 26 | } 27 | 28 | 29 | public void FileLoad(String fileName) 30 | { 31 | 32 | // parse markdown file in worker thread 33 | Thread threadObj = new Thread(new ThreadStart(delegate 34 | { 35 | ParseMarkdownFile(fileName); 36 | })); 37 | threadObj.Start(); 38 | 39 | } 40 | 41 | private void ParseMarkdownFile(String fileName) 42 | { 43 | using (StreamReader sr = new StreamReader(fileName, encoding)) 44 | { 45 | String markdownContent = sr.ReadToEnd(); 46 | var pipeline = new MarkdownPipelineBuilder() 47 | .UseAdvancedExtensions() 48 | .UseEmojiAndSmiley() 49 | .UseYamlFrontMatter() 50 | .UseFootnotes() 51 | .UseHighlightJs() 52 | .Build(); 53 | String markdownHTML = Markdown.ToHtml(markdownContent, pipeline); 54 | 55 | // read markdown tmpl from file 56 | var buildDir = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location); 57 | var tmplFilePath = buildDir + @"\" + TMPL_FILE_NAME; 58 | var markdownTmpl = File.ReadAllText(tmplFilePath); 59 | 60 | // read style content from file 61 | var styleFilePath = buildDir + @"\" + CSS_FILE_NAME; 62 | var style = File.ReadAllText(styleFilePath); 63 | 64 | String html = String.Format(markdownTmpl, Path.GetDirectoryName(fileName), style, markdownHTML); 65 | 66 | Action act = delegate () { this.webBrowser1.DocumentText = html; }; 67 | // fixed 在创建窗口句柄之前,不能在控件上调用 Invoke 或 BeginInvoke 68 | while (!this.IsHandleCreated) 69 | { 70 | ; 71 | } 72 | this.Invoke(act); 73 | 74 | } 75 | } 76 | 77 | private void webBrowser1_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e) 78 | { 79 | webBrowser1.Document.Body.KeyPress += MyKeyPressHandler; 80 | } 81 | 82 | private void MyKeyPressHandler(object sender, HtmlElementEventArgs e) 83 | { 84 | int[] keys = new int[] { 27, 49, 50, 51, 52, 53, 54, 55 }; // Esc, 1-7 85 | if (keys.Contains(e.KeyPressedCode)) 86 | { 87 | listerPlugin.SendKeyToParentWindow(e.KeyPressedCode); 88 | } 89 | 90 | } 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /MarkdownViewer/MarkdownViewer.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Specialized; 3 | using System.Collections; 4 | using OY.TotalCommander.TcPluginInterface.Lister; 5 | using System.IO; 6 | using System.Windows.Forms; 7 | using System.Drawing.Printing; 8 | 9 | namespace MarkdownViewer 10 | { 11 | public class MarkdownViewer : ListerPlugin 12 | { 13 | 14 | public const String AllowedExtensions = ".md,.markdown,.mk"; 15 | 16 | public MarkdownViewer(StringDictionary pluginSettings) : base(pluginSettings) 17 | { 18 | 19 | if (String.IsNullOrEmpty(Title)) 20 | { 21 | Title = "Markdown Viewer"; 22 | } 23 | 24 | DetectString = "EXT=\"MD\" | EXT=\"MARKDOWN\" | EXT=\"MK\""; 25 | 26 | } 27 | 28 | private ArrayList controls = new ArrayList(); 29 | 30 | /// 31 | /// 载入插件 32 | /// 33 | /// 34 | /// 35 | /// 36 | public override object Load(string fileToLoad, ShowFlags showFlags) 37 | { 38 | ViewerControl viewerControl = null; 39 | if (!String.IsNullOrEmpty(fileToLoad)) 40 | { 41 | 42 | String ext = Path.GetExtension(fileToLoad); 43 | String fileName = Path.GetFileNameWithoutExtension(fileToLoad); 44 | 45 | TraceProc(System.Diagnostics.TraceLevel.Info, "fileName: " + fileName + ", ext: " + ext); 46 | 47 | // 如果文件扩展名不在支持之列则直接返回 48 | if (AllowedExtensions.IndexOf(ext, StringComparison.InvariantCultureIgnoreCase) < 0) 49 | { 50 | return null; 51 | } 52 | 53 | viewerControl = new ViewerControl(this); 54 | viewerControl.FileLoad(fileToLoad); 55 | FocusedControl = viewerControl.webBrowser1; 56 | viewerControl.Focus(); 57 | 58 | controls.Add(viewerControl); 59 | 60 | } 61 | 62 | return viewerControl; 63 | } 64 | 65 | /// 66 | /// 67 | /// Is called when a user closes lister, or loads a different file. 68 | /// 69 | /// 70 | public override void CloseWindow(object control) 71 | { 72 | controls.Remove(control); 73 | } 74 | 75 | /// 76 | /// Is called when click print button 77 | /// 78 | /// 79 | /// 80 | /// 81 | /// 82 | /// 83 | /// 84 | public override ListerResult Print(object control, string fileToPrint, string defPrinter, PrintFlags printFlags, PrintMargins margins) 85 | { 86 | 87 | TraceProc(System.Diagnostics.TraceLevel.Info, "Print fileToPrint:" + fileToPrint + ", defPrinter: " + defPrinter); 88 | ViewerControl viewerControl = (ViewerControl)control; 89 | viewerControl.webBrowser1.ShowPrintDialog(); 90 | return ListerResult.OK; 91 | } 92 | 93 | public override ListerResult SendCommand(object control, ListerCommand command, ShowFlags parameter) 94 | { 95 | ViewerControl viewerControl = (ViewerControl)control; 96 | switch (command) 97 | { 98 | case ListerCommand.Copy: 99 | viewerControl.webBrowser1.Document.ExecCommand("Copy", false, null); 100 | break; 101 | case ListerCommand.SelectAll: 102 | viewerControl.webBrowser1.Document.ExecCommand("SelectAll", false, null); 103 | break; 104 | } 105 | return ListerResult.OK; 106 | } 107 | 108 | 109 | public override ListerResult SearchText(object control, string searchString, SearchParameter searchParameter) 110 | { 111 | ViewerControl viewerControl = (ViewerControl)control; 112 | 113 | return ListerResult.OK; 114 | } 115 | 116 | public override int NotificationReceived(object control, int message, int wParam, int lParam) 117 | { 118 | ViewerControl viewerControl = (ViewerControl)control; 119 | return 0; 120 | } 121 | 122 | } 123 | 124 | } 125 | -------------------------------------------------------------------------------- /MarkdownViewer/MarkdownViewer.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {D8467740-7A0C-4C43-A3E1-7523B4A782E3} 8 | Library 9 | MarkdownViewer 10 | MarkdownViewer 11 | v4.5.2 12 | 512 13 | true 14 | 15 | 16 | AnyCPU 17 | true 18 | full 19 | false 20 | bin\Debug\ 21 | DEBUG;TRACE 22 | prompt 23 | 4 24 | 25 | 26 | AnyCPU 27 | pdbonly 28 | true 29 | bin\Release\ 30 | TRACE 31 | prompt 32 | 4 33 | 34 | 35 | 36 | 37 | 38 | 39 | ..\packages\Jurassic.3.0.0\lib\net45\Jurassic.dll 40 | 41 | 42 | ..\packages\Markdig.0.17.1\lib\net40\Markdig.dll 43 | 44 | 45 | 46 | ..\Lib\Pek.Markdig.HighlightJs.dll 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | False 55 | ..\TcPluginCore\TcPluginInterface.dll 56 | 57 | 58 | 59 | 60 | 61 | 62 | UserControl 63 | 64 | 65 | ViewerControl.cs 66 | 67 | 68 | ResXFileCodeGenerator 69 | Resources.Designer.cs 70 | Designer 71 | 72 | 73 | True 74 | Resources.resx 75 | True 76 | 77 | 78 | ViewerControl.cs 79 | 80 | 81 | 82 | SettingsSingleFileGenerator 83 | Settings.Designer.cs 84 | 85 | 86 | True 87 | Settings.settings 88 | True 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | PreserveNewest 100 | 101 | 102 | PreserveNewest 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | $(SolutionDir)TcPluginCore\WrapperBuilder.exe /wlx /p=$(TargetPath) /v /$(ConfigurationName) 111 | zip -m $(TargetName).zip Markdig.dll 112 | zip -m $(TargetName).zip Pek.Markdig.HighlightJs.dll 113 | zip -m $(TargetName).zip Jurassic.dll 114 | zip -m $(TargetName).zip markdown_tmpl.txt 115 | zip -m $(TargetName).zip markdown_css.txt 116 | echo add dependency to package 117 | 118 | 119 | -------------------------------------------------------------------------------- /MarkdownViewer/ViewerControl.resx: -------------------------------------------------------------------------------- 1 | 2 | 3 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | text/microsoft-resx 110 | 111 | 112 | 2.0 113 | 114 | 115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 116 | 117 | 118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 119 | 120 | -------------------------------------------------------------------------------- /MarkdownViewer/Properties/Resources.resx: -------------------------------------------------------------------------------- 1 | 2 | 3 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | text/microsoft-resx 110 | 111 | 112 | 2.0 113 | 114 | 115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 116 | 117 | 118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 119 | 120 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | ## 4 | ## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore 5 | 6 | # User-specific files 7 | *.suo 8 | *.user 9 | *.userosscache 10 | *.sln.docstates 11 | 12 | # User-specific files (MonoDevelop/Xamarin Studio) 13 | *.userprefs 14 | 15 | # Build results 16 | [Dd]ebug/ 17 | [Dd]ebugPublic/ 18 | [Rr]elease/ 19 | [Rr]eleases/ 20 | x64/ 21 | x86/ 22 | bld/ 23 | [Bb]in/ 24 | [Oo]bj/ 25 | [Ll]og/ 26 | 27 | # Visual Studio 2015 cache/options directory 28 | .vs/ 29 | # Uncomment if you have tasks that create the project's static files in wwwroot 30 | #wwwroot/ 31 | 32 | # MSTest test Results 33 | [Tt]est[Rr]esult*/ 34 | [Bb]uild[Ll]og.* 35 | 36 | # NUNIT 37 | *.VisualState.xml 38 | TestResult.xml 39 | 40 | # Build Results of an ATL Project 41 | [Dd]ebugPS/ 42 | [Rr]eleasePS/ 43 | dlldata.c 44 | 45 | # Benchmark Results 46 | BenchmarkDotNet.Artifacts/ 47 | 48 | # .NET Core 49 | project.lock.json 50 | project.fragment.lock.json 51 | artifacts/ 52 | **/Properties/launchSettings.json 53 | 54 | *_i.c 55 | *_p.c 56 | *_i.h 57 | *.ilk 58 | *.meta 59 | *.obj 60 | *.pch 61 | *.pdb 62 | *.pgc 63 | *.pgd 64 | *.rsp 65 | *.sbr 66 | *.tlb 67 | *.tli 68 | *.tlh 69 | *.tmp 70 | *.tmp_proj 71 | *.log 72 | *.vspscc 73 | *.vssscc 74 | .builds 75 | *.pidb 76 | *.svclog 77 | *.scc 78 | 79 | # Chutzpah Test files 80 | _Chutzpah* 81 | 82 | # Visual C++ cache files 83 | ipch/ 84 | *.aps 85 | *.ncb 86 | *.opendb 87 | *.opensdf 88 | *.sdf 89 | *.cachefile 90 | *.VC.db 91 | *.VC.VC.opendb 92 | 93 | # Visual Studio profiler 94 | *.psess 95 | *.vsp 96 | *.vspx 97 | *.sap 98 | 99 | # TFS 2012 Local Workspace 100 | $tf/ 101 | 102 | # Guidance Automation Toolkit 103 | *.gpState 104 | 105 | # ReSharper is a .NET coding add-in 106 | _ReSharper*/ 107 | *.[Rr]e[Ss]harper 108 | *.DotSettings.user 109 | 110 | # JustCode is a .NET coding add-in 111 | .JustCode 112 | 113 | # TeamCity is a build add-in 114 | _TeamCity* 115 | 116 | # DotCover is a Code Coverage Tool 117 | *.dotCover 118 | 119 | # Visual Studio code coverage results 120 | *.coverage 121 | *.coveragexml 122 | 123 | # NCrunch 124 | _NCrunch_* 125 | .*crunch*.local.xml 126 | nCrunchTemp_* 127 | 128 | # MightyMoose 129 | *.mm.* 130 | AutoTest.Net/ 131 | 132 | # Web workbench (sass) 133 | .sass-cache/ 134 | 135 | # Installshield output folder 136 | [Ee]xpress/ 137 | 138 | # DocProject is a documentation generator add-in 139 | DocProject/buildhelp/ 140 | DocProject/Help/*.HxT 141 | DocProject/Help/*.HxC 142 | DocProject/Help/*.hhc 143 | DocProject/Help/*.hhk 144 | DocProject/Help/*.hhp 145 | DocProject/Help/Html2 146 | DocProject/Help/html 147 | 148 | # Click-Once directory 149 | publish/ 150 | 151 | # Publish Web Output 152 | *.[Pp]ublish.xml 153 | *.azurePubxml 154 | # Note: Comment the next line if you want to checkin your web deploy settings, 155 | # but database connection strings (with potential passwords) will be unencrypted 156 | *.pubxml 157 | *.publishproj 158 | 159 | # Microsoft Azure Web App publish settings. Comment the next line if you want to 160 | # checkin your Azure Web App publish settings, but sensitive information contained 161 | # in these scripts will be unencrypted 162 | PublishScripts/ 163 | 164 | # NuGet Packages 165 | *.nupkg 166 | # The packages folder can be ignored because of Package Restore 167 | **/packages/* 168 | # except build/, which is used as an MSBuild target. 169 | !**/packages/build/ 170 | # Uncomment if necessary however generally it will be regenerated when needed 171 | #!**/packages/repositories.config 172 | # NuGet v3's project.json files produces more ignorable files 173 | *.nuget.props 174 | *.nuget.targets 175 | 176 | # Microsoft Azure Build Output 177 | csx/ 178 | *.build.csdef 179 | 180 | # Microsoft Azure Emulator 181 | ecf/ 182 | rcf/ 183 | 184 | # Windows Store app package directories and files 185 | AppPackages/ 186 | BundleArtifacts/ 187 | Package.StoreAssociation.xml 188 | _pkginfo.txt 189 | *.appx 190 | 191 | # Visual Studio cache files 192 | # files ending in .cache can be ignored 193 | *.[Cc]ache 194 | # but keep track of directories ending in .cache 195 | !*.[Cc]ache/ 196 | 197 | # Others 198 | ClientBin/ 199 | ~$* 200 | *~ 201 | *.dbmdl 202 | *.dbproj.schemaview 203 | *.jfm 204 | *.pfx 205 | *.publishsettings 206 | orleans.codegen.cs 207 | 208 | # Since there are multiple workflows, uncomment next line to ignore bower_components 209 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) 210 | #bower_components/ 211 | 212 | # RIA/Silverlight projects 213 | Generated_Code/ 214 | 215 | # Backup & report files from converting an old project file 216 | # to a newer Visual Studio version. Backup files are not needed, 217 | # because we have git ;-) 218 | _UpgradeReport_Files/ 219 | Backup*/ 220 | UpgradeLog*.XML 221 | UpgradeLog*.htm 222 | 223 | # SQL Server files 224 | *.mdf 225 | *.ldf 226 | *.ndf 227 | 228 | # Business Intelligence projects 229 | *.rdl.data 230 | *.bim.layout 231 | *.bim_*.settings 232 | 233 | # Microsoft Fakes 234 | FakesAssemblies/ 235 | 236 | # GhostDoc plugin setting file 237 | *.GhostDoc.xml 238 | 239 | # Node.js Tools for Visual Studio 240 | .ntvs_analysis.dat 241 | node_modules/ 242 | 243 | # Typescript v1 declaration files 244 | typings/ 245 | 246 | # Visual Studio 6 build log 247 | *.plg 248 | 249 | # Visual Studio 6 workspace options file 250 | *.opt 251 | 252 | # Visual Studio 6 auto-generated workspace file (contains which files were open etc.) 253 | *.vbw 254 | 255 | # Visual Studio LightSwitch build output 256 | **/*.HTMLClient/GeneratedArtifacts 257 | **/*.DesktopClient/GeneratedArtifacts 258 | **/*.DesktopClient/ModelManifest.xml 259 | **/*.Server/GeneratedArtifacts 260 | **/*.Server/ModelManifest.xml 261 | _Pvt_Extensions 262 | 263 | # Paket dependency manager 264 | .paket/paket.exe 265 | paket-files/ 266 | 267 | # FAKE - F# Make 268 | .fake/ 269 | 270 | # JetBrains Rider 271 | .idea/ 272 | *.sln.iml 273 | 274 | # CodeRush 275 | .cr/ 276 | 277 | # Python Tools for Visual Studio (PTVS) 278 | __pycache__/ 279 | *.pyc 280 | 281 | # Cake - Uncomment if you are using it 282 | # tools/** 283 | # !tools/packages.config 284 | 285 | # Tabs Studio 286 | *.tss 287 | 288 | # Telerik's JustMock configuration file 289 | *.jmconfig 290 | 291 | # BizTalk build output 292 | *.btp.cs 293 | *.btm.cs 294 | *.odx.cs 295 | *.xsd.cs -------------------------------------------------------------------------------- /MarkdownViewer/markdown_css.txt: -------------------------------------------------------------------------------- 1 | @font-face { 2 | font-family: octicons-link; 3 | src: url(data:font/woff;charset=utf-8;base64,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) format('woff'); 4 | } 5 | 6 | nav{ 7 | padding: 10px 300px; 8 | } 9 | 10 | .markdown-body { 11 | -ms-text-size-adjust: 100%; 12 | -webkit-text-size-adjust: 100%; 13 | line-height: 1.5; 14 | color: #24292e; 15 | font-family: serif; 16 | font-size: 16px; 17 | line-height: 1.5; 18 | word-wrap: break-word; 19 | max-width: 80%; 20 | margin: 0 auto; 21 | } 22 | 23 | .markdown-body .pl-c { 24 | color: #6a737d; 25 | } 26 | 27 | .markdown-body .pl-c1, 28 | .markdown-body .pl-s .pl-v { 29 | color: #005cc5; 30 | } 31 | 32 | .markdown-body .pl-e, 33 | .markdown-body .pl-en { 34 | color: #6f42c1; 35 | } 36 | 37 | .markdown-body .pl-smi, 38 | .markdown-body .pl-s .pl-s1 { 39 | color: #24292e; 40 | } 41 | 42 | .markdown-body .pl-ent { 43 | color: #22863a; 44 | } 45 | 46 | .markdown-body .pl-k { 47 | color: #d73a49; 48 | } 49 | 50 | .markdown-body .pl-s, 51 | .markdown-body .pl-pds, 52 | .markdown-body .pl-s .pl-pse .pl-s1, 53 | .markdown-body .pl-sr, 54 | .markdown-body .pl-sr .pl-cce, 55 | .markdown-body .pl-sr .pl-sre, 56 | .markdown-body .pl-sr .pl-sra { 57 | color: #032f62; 58 | } 59 | 60 | .markdown-body .pl-v, 61 | .markdown-body .pl-smw { 62 | color: #e36209; 63 | } 64 | 65 | .markdown-body .pl-bu { 66 | color: #b31d28; 67 | } 68 | 69 | .markdown-body .pl-ii { 70 | color: #fafbfc; 71 | background-color: #b31d28; 72 | } 73 | 74 | .markdown-body .pl-c2 { 75 | color: #fafbfc; 76 | background-color: #d73a49; 77 | } 78 | 79 | .markdown-body .pl-c2::before { 80 | content: "^M"; 81 | } 82 | 83 | .markdown-body .pl-sr .pl-cce { 84 | font-weight: bold; 85 | color: #22863a; 86 | } 87 | 88 | .markdown-body .pl-ml { 89 | color: #735c0f; 90 | } 91 | 92 | .markdown-body .pl-mh, 93 | .markdown-body .pl-mh .pl-en, 94 | .markdown-body .pl-ms { 95 | font-weight: bold; 96 | color: #005cc5; 97 | } 98 | 99 | .markdown-body .pl-mi { 100 | font-style: italic; 101 | color: #24292e; 102 | } 103 | 104 | .markdown-body .pl-mb { 105 | font-weight: bold; 106 | color: #24292e; 107 | } 108 | 109 | .markdown-body .pl-md { 110 | color: #b31d28; 111 | background-color: #ffeef0; 112 | } 113 | 114 | .markdown-body .pl-mi1 { 115 | color: #22863a; 116 | background-color: #f0fff4; 117 | } 118 | 119 | .markdown-body .pl-mc { 120 | color: #e36209; 121 | background-color: #ffebda; 122 | } 123 | 124 | .markdown-body .pl-mi2 { 125 | color: #f6f8fa; 126 | background-color: #005cc5; 127 | } 128 | 129 | .markdown-body .pl-mdr { 130 | font-weight: bold; 131 | color: #6f42c1; 132 | } 133 | 134 | .markdown-body .pl-ba { 135 | color: #586069; 136 | } 137 | 138 | .markdown-body .pl-sg { 139 | color: #959da5; 140 | } 141 | 142 | .markdown-body .pl-corl { 143 | text-decoration: underline; 144 | color: #032f62; 145 | } 146 | 147 | .markdown-body .octicon { 148 | display: inline-block; 149 | vertical-align: text-top; 150 | fill: currentColor; 151 | } 152 | 153 | .markdown-body a { 154 | background-color: transparent; 155 | -webkit-text-decoration-skip: objects; 156 | } 157 | 158 | .markdown-body a:active, 159 | .markdown-body a:hover { 160 | outline-width: 0; 161 | } 162 | 163 | .markdown-body strong { 164 | font-weight: inherit; 165 | } 166 | 167 | .markdown-body strong { 168 | font-weight: bolder; 169 | } 170 | 171 | .markdown-body h1 { 172 | font-size: 2em; 173 | margin: 0.67em 0; 174 | } 175 | 176 | .markdown-body img { 177 | border-style: none; 178 | } 179 | 180 | .markdown-body svg:not(:root) { 181 | overflow: hidden; 182 | } 183 | 184 | .markdown-body code, 185 | .markdown-body kbd, 186 | .markdown-body pre { 187 | font-family: monospace, monospace; 188 | font-size: 1em; 189 | } 190 | 191 | .markdown-body hr { 192 | box-sizing: content-box; 193 | height: 0; 194 | overflow: visible; 195 | } 196 | 197 | .markdown-body input { 198 | font: inherit; 199 | margin: 0; 200 | } 201 | 202 | .markdown-body input { 203 | overflow: visible; 204 | } 205 | 206 | .markdown-body [type="checkbox"] { 207 | box-sizing: border-box; 208 | padding: 0; 209 | } 210 | 211 | .markdown-body * { 212 | box-sizing: border-box; 213 | } 214 | 215 | .markdown-body input { 216 | font-family: inherit; 217 | font-size: inherit; 218 | line-height: inherit; 219 | } 220 | 221 | .markdown-body a { 222 | color: #0366d6; 223 | text-decoration: none; 224 | } 225 | 226 | .markdown-body a:hover { 227 | text-decoration: underline; 228 | } 229 | 230 | .markdown-body strong { 231 | font-weight: 600; 232 | } 233 | 234 | .markdown-body hr { 235 | height: 0; 236 | margin: 15px 0; 237 | overflow: hidden; 238 | background: transparent; 239 | border: 0; 240 | border-bottom: 1px solid #dfe2e5; 241 | } 242 | 243 | .markdown-body hr::before { 244 | display: table; 245 | content: ""; 246 | } 247 | 248 | .markdown-body hr::after { 249 | display: table; 250 | clear: both; 251 | content: ""; 252 | } 253 | 254 | .markdown-body table { 255 | border-spacing: 0; 256 | border-collapse: collapse; 257 | } 258 | 259 | .markdown-body td, 260 | .markdown-body th { 261 | padding: 0; 262 | } 263 | 264 | .markdown-body h1, 265 | .markdown-body h2, 266 | .markdown-body h3, 267 | .markdown-body h4, 268 | .markdown-body h5, 269 | .markdown-body h6 { 270 | margin-top: 0; 271 | margin-bottom: 0; 272 | } 273 | 274 | .markdown-body h1 { 275 | font-size: 32px; 276 | font-weight: 600; 277 | } 278 | 279 | .markdown-body h2 { 280 | font-size: 24px; 281 | font-weight: 600; 282 | } 283 | 284 | .markdown-body h3 { 285 | font-size: 20px; 286 | font-weight: 600; 287 | } 288 | 289 | .markdown-body h4 { 290 | font-size: 16px; 291 | font-weight: 600; 292 | } 293 | 294 | .markdown-body h5 { 295 | font-size: 14px; 296 | font-weight: 600; 297 | } 298 | 299 | .markdown-body h6 { 300 | font-size: 12px; 301 | font-weight: 600; 302 | } 303 | 304 | .markdown-body p { 305 | margin-top: 0; 306 | margin-bottom: 10px; 307 | } 308 | 309 | .markdown-body blockquote { 310 | margin: 0; 311 | } 312 | 313 | .markdown-body ul, 314 | .markdown-body ol { 315 | padding-left: 0; 316 | margin-top: 0; 317 | margin-bottom: 0; 318 | } 319 | 320 | .markdown-body ol ol, 321 | .markdown-body ul ol { 322 | list-style-type: lower-roman; 323 | } 324 | 325 | .markdown-body ul ul ol, 326 | .markdown-body ul ol ol, 327 | .markdown-body ol ul ol, 328 | .markdown-body ol ol ol { 329 | list-style-type: lower-alpha; 330 | } 331 | 332 | .markdown-body dd { 333 | margin-left: 0; 334 | } 335 | 336 | .markdown-body code { 337 | font-family: "SFMono-Regular", Consolas, "Liberation Mono", Menlo, Courier, monospace; 338 | } 339 | 340 | .markdown-body pre { 341 | margin-top: 0; 342 | margin-bottom: 0; 343 | font: 1em "SFMono-Regular", Consolas, "Liberation Mono", Menlo, Courier, monospace; 344 | } 345 | 346 | .markdown-body .octicon { 347 | vertical-align: text-bottom; 348 | } 349 | 350 | .markdown-body .pl-0 { 351 | padding-left: 0 !important; 352 | } 353 | 354 | .markdown-body .pl-1 { 355 | padding-left: 4px !important; 356 | } 357 | 358 | .markdown-body .pl-2 { 359 | padding-left: 8px !important; 360 | } 361 | 362 | .markdown-body .pl-3 { 363 | padding-left: 16px !important; 364 | } 365 | 366 | .markdown-body .pl-4 { 367 | padding-left: 24px !important; 368 | } 369 | 370 | .markdown-body .pl-5 { 371 | padding-left: 32px !important; 372 | } 373 | 374 | .markdown-body .pl-6 { 375 | padding-left: 40px !important; 376 | } 377 | 378 | .markdown-body::before { 379 | display: table; 380 | content: ""; 381 | } 382 | 383 | .markdown-body::after { 384 | display: table; 385 | clear: both; 386 | content: ""; 387 | } 388 | 389 | .markdown-body>*:first-child { 390 | margin-top: 0 !important; 391 | } 392 | 393 | .markdown-body>*:last-child { 394 | margin-bottom: 0 !important; 395 | } 396 | 397 | .markdown-body a:not([href]) { 398 | color: inherit; 399 | text-decoration: none; 400 | } 401 | 402 | .markdown-body .anchor { 403 | float: left; 404 | padding-right: 4px; 405 | margin-left: -20px; 406 | line-height: 1; 407 | } 408 | 409 | .markdown-body .anchor:focus { 410 | outline: none; 411 | } 412 | 413 | .markdown-body p, 414 | .markdown-body blockquote, 415 | .markdown-body ul, 416 | .markdown-body ol, 417 | .markdown-body dl, 418 | .markdown-body table, 419 | .markdown-body pre { 420 | margin-top: 0; 421 | margin-bottom: 16px; 422 | } 423 | 424 | .markdown-body hr { 425 | height: 0.25em; 426 | padding: 0; 427 | margin: 24px 0; 428 | background-color: #e1e4e8; 429 | border: 0; 430 | } 431 | 432 | .markdown-body blockquote { 433 | padding: 0 1em; 434 | color: #6a737d; 435 | border-left: 0.25em solid #dfe2e5; 436 | } 437 | 438 | .markdown-body blockquote>:first-child { 439 | margin-top: 0; 440 | } 441 | 442 | .markdown-body blockquote>:last-child { 443 | margin-bottom: 0; 444 | } 445 | 446 | .markdown-body kbd { 447 | display: inline-block; 448 | padding: 3px 5px; 449 | font-size: 11px; 450 | line-height: 10px; 451 | color: #444d56; 452 | vertical-align: middle; 453 | background-color: #fafbfc; 454 | border: solid 1px #c6cbd1; 455 | border-bottom-color: #959da5; 456 | border-radius: 3px; 457 | box-shadow: inset 0 -1px 0 #959da5; 458 | } 459 | 460 | .markdown-body h1, 461 | .markdown-body h2, 462 | .markdown-body h3, 463 | .markdown-body h4, 464 | .markdown-body h5, 465 | .markdown-body h6 { 466 | margin-top: 24px; 467 | margin-bottom: 16px; 468 | font-weight: 600; 469 | line-height: 1.25; 470 | } 471 | 472 | .markdown-body h1 .octicon-link, 473 | .markdown-body h2 .octicon-link, 474 | .markdown-body h3 .octicon-link, 475 | .markdown-body h4 .octicon-link, 476 | .markdown-body h5 .octicon-link, 477 | .markdown-body h6 .octicon-link { 478 | color: #1b1f23; 479 | vertical-align: middle; 480 | visibility: hidden; 481 | } 482 | 483 | .markdown-body h1:hover .anchor, 484 | .markdown-body h2:hover .anchor, 485 | .markdown-body h3:hover .anchor, 486 | .markdown-body h4:hover .anchor, 487 | .markdown-body h5:hover .anchor, 488 | .markdown-body h6:hover .anchor { 489 | text-decoration: none; 490 | } 491 | 492 | .markdown-body h1:hover .anchor .octicon-link, 493 | .markdown-body h2:hover .anchor .octicon-link, 494 | .markdown-body h3:hover .anchor .octicon-link, 495 | .markdown-body h4:hover .anchor .octicon-link, 496 | .markdown-body h5:hover .anchor .octicon-link, 497 | .markdown-body h6:hover .anchor .octicon-link { 498 | visibility: visible; 499 | } 500 | 501 | .markdown-body h1 { 502 | padding-bottom: 0.3em; 503 | font-size: 2em; 504 | border-bottom: 1px solid #eaecef; 505 | } 506 | 507 | .markdown-body h2 { 508 | padding-bottom: 0.3em; 509 | font-size: 1.5em; 510 | border-bottom: 1px solid #eaecef; 511 | } 512 | 513 | .markdown-body h3 { 514 | font-size: 1.25em; 515 | } 516 | 517 | .markdown-body h4 { 518 | font-size: 1em; 519 | } 520 | 521 | .markdown-body h5 { 522 | font-size: 0.875em; 523 | } 524 | 525 | .markdown-body h6 { 526 | font-size: 0.85em; 527 | color: #6a737d; 528 | } 529 | 530 | .markdown-body ul, 531 | .markdown-body ol { 532 | padding-left: 2em; 533 | } 534 | 535 | .markdown-body ul ul, 536 | .markdown-body ul ol, 537 | .markdown-body ol ol, 538 | .markdown-body ol ul { 539 | margin-top: 0; 540 | margin-bottom: 0; 541 | } 542 | 543 | .markdown-body li>p { 544 | margin-top: 16px; 545 | } 546 | 547 | .markdown-body li+li { 548 | margin-top: 0.25em; 549 | } 550 | 551 | .markdown-body dl { 552 | padding: 0; 553 | } 554 | 555 | .markdown-body dl dt { 556 | padding: 0; 557 | margin-top: 16px; 558 | font-size: 1em; 559 | font-style: italic; 560 | font-weight: 600; 561 | } 562 | 563 | .markdown-body dl dd { 564 | padding: 0 16px; 565 | margin-bottom: 16px; 566 | } 567 | 568 | .markdown-body table { 569 | display: table; 570 | width: 100%; 571 | overflow: auto; 572 | } 573 | 574 | .markdown-body table th { 575 | font-weight: 600; 576 | } 577 | 578 | .markdown-body table th, 579 | .markdown-body table td { 580 | padding: 6px 13px; 581 | border: 1px solid #dfe2e5; 582 | } 583 | 584 | .markdown-body table tr { 585 | background-color: #fff; 586 | border-top: 1px solid #c6cbd1; 587 | } 588 | 589 | .markdown-body table tr:nth-child(2n) { 590 | background-color: #f6f8fa; 591 | } 592 | 593 | .markdown-body img { 594 | max-width: 100%; 595 | box-sizing: content-box; 596 | background-color: #fff; 597 | } 598 | 599 | .markdown-body code { 600 | border-radius: 3px; 601 | } 602 | 603 | .markdown-body code::before, 604 | .markdown-body code::after { 605 | letter-spacing: -0.2em; 606 | content: "\00a0"; 607 | } 608 | 609 | .markdown-body pre { 610 | word-wrap: normal; 611 | } 612 | 613 | .markdown-body pre>code { 614 | word-break: normal; 615 | white-space: pre; 616 | border: 0; 617 | } 618 | 619 | .markdown-body .highlight { 620 | margin-bottom: 16px; 621 | } 622 | 623 | .markdown-body .highlight pre { 624 | margin-bottom: 0; 625 | word-break: normal; 626 | } 627 | 628 | .markdown-body .highlight pre, 629 | .markdown-body pre { 630 | overflow: auto; 631 | line-height: 1.45; 632 | border-radius: 3px; 633 | } 634 | 635 | .markdown-body pre code { 636 | max-width: auto; 637 | line-height: inherit; 638 | word-wrap: normal; 639 | border: 0; 640 | } 641 | 642 | .markdown-body pre code::before, 643 | .markdown-body pre code::after { 644 | content: normal; 645 | } 646 | 647 | .markdown-body .full-commit .btn-outline:not(:disabled):hover { 648 | color: #005cc5; 649 | border-color: #005cc5; 650 | } 651 | 652 | .markdown-body kbd { 653 | display: inline-block; 654 | padding: 3px 5px; 655 | font: 11px "SFMono-Regular", Consolas, "Liberation Mono", Menlo, Courier, monospace; 656 | line-height: 10px; 657 | color: #444d56; 658 | vertical-align: middle; 659 | background-color: #fafbfc; 660 | border: solid 1px #d1d5da; 661 | border-bottom-color: #c6cbd1; 662 | border-radius: 3px; 663 | box-shadow: inset 0 -1px 0 #c6cbd1; 664 | } 665 | 666 | .markdown-body :checked+.radio-label { 667 | position: relative; 668 | z-index: 1; 669 | border-color: #0366d6; 670 | } 671 | 672 | .markdown-body .task-list-item { 673 | list-style-type: none; 674 | } 675 | 676 | .markdown-body .task-list-item+.task-list-item { 677 | margin-top: 3px; 678 | } 679 | 680 | .markdown-body .task-list-item input { 681 | margin: 0 0.2em 0.25em -1.6em; 682 | vertical-align: middle; 683 | } 684 | 685 | .markdown-body hr { 686 | border-bottom-color: #eee; 687 | } 688 | --------------------------------------------------------------------------------