├── .gitignore ├── LICENSE.md ├── LICENSE.txt ├── README.md ├── appveyor.yml ├── assets ├── icon.png └── icon.svg ├── scripts └── Initialize-SharedAssemblyInfo.ps1 └── src ├── Markdig.SyntaxHighlighting.Tests ├── Example │ ├── CodeSample.cs │ ├── README.md │ ├── _template.html │ ├── expected.html │ └── gfm.css ├── IntegrationTests.cs ├── LanguageTypeAdapterTests.cs ├── Markdig.SyntaxHighlighting.Tests.csproj ├── Properties │ └── AssemblyInfo.cs ├── SyntaxHighlightingCodeBlockRendererTests.cs ├── SyntaxHighlightingExtensionsTests.cs └── packages.config ├── Markdig.SyntaxHighlighting.sln ├── Markdig.SyntaxHighlighting.sln.DotSettings ├── Markdig.SyntaxHighlighting ├── LanguageTypeAdapter.cs ├── Markdig.SyntaxHighlighting.csproj ├── Markdig.SyntaxHighlighting.nuspec ├── Properties │ └── AssemblyInfo.cs ├── SyntaxHighlightingCodeBlockRenderer.cs ├── SyntaxHighlightingExtension.cs ├── SyntaxHighlightingExtensions.cs └── packages.config └── SharedAssemblyInfo.cs /.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | 4 | # User-specific files 5 | *.suo 6 | *.user 7 | *.userosscache 8 | *.sln.docstates 9 | 10 | # User-specific files (MonoDevelop/Xamarin Studio) 11 | *.userprefs 12 | 13 | # Build results 14 | [Dd]ebug/ 15 | [Dd]ebugPublic/ 16 | [Rr]elease/ 17 | [Rr]eleases/ 18 | x64/ 19 | x86/ 20 | build/ 21 | bld/ 22 | [Bb]in/ 23 | [Oo]bj/ 24 | 25 | # Visual Studio 2015 cache/options directory 26 | .vs/ 27 | # Uncomment if you have tasks that create the project's static files in wwwroot 28 | #wwwroot/ 29 | 30 | # MSTest test Results 31 | [Tt]est[Rr]esult*/ 32 | [Bb]uild[Ll]og.* 33 | 34 | # NUNIT 35 | *.VisualState.xml 36 | TestResult.xml 37 | 38 | # Build Results of an ATL Project 39 | [Dd]ebugPS/ 40 | [Rr]eleasePS/ 41 | dlldata.c 42 | 43 | # DNX 44 | project.lock.json 45 | artifacts/ 46 | 47 | *_i.c 48 | *_p.c 49 | *_i.h 50 | *.ilk 51 | *.meta 52 | *.obj 53 | *.pch 54 | *.pdb 55 | *.pgc 56 | *.pgd 57 | *.rsp 58 | *.sbr 59 | *.tlb 60 | *.tli 61 | *.tlh 62 | *.tmp 63 | *.tmp_proj 64 | *.log 65 | *.vspscc 66 | *.vssscc 67 | .builds 68 | *.pidb 69 | *.svclog 70 | *.scc 71 | 72 | # Chutzpah Test files 73 | _Chutzpah* 74 | 75 | # Visual C++ cache files 76 | ipch/ 77 | *.aps 78 | *.ncb 79 | *.opensdf 80 | *.sdf 81 | *.cachefile 82 | 83 | # Visual Studio profiler 84 | *.psess 85 | *.vsp 86 | *.vspx 87 | 88 | # TFS 2012 Local Workspace 89 | $tf/ 90 | 91 | # Guidance Automation Toolkit 92 | *.gpState 93 | 94 | # ReSharper is a .NET coding add-in 95 | _ReSharper*/ 96 | *.[Rr]e[Ss]harper 97 | *.DotSettings.user 98 | 99 | # JustCode is a .NET coding add-in 100 | .JustCode 101 | 102 | # TeamCity is a build add-in 103 | _TeamCity* 104 | 105 | # DotCover is a Code Coverage Tool 106 | *.dotCover 107 | 108 | # NCrunch 109 | _NCrunch_* 110 | .*crunch*.local.xml 111 | nCrunchTemp_* 112 | 113 | # MightyMoose 114 | *.mm.* 115 | AutoTest.Net/ 116 | 117 | # Web workbench (sass) 118 | .sass-cache/ 119 | 120 | # Installshield output folder 121 | [Ee]xpress/ 122 | 123 | # DocProject is a documentation generator add-in 124 | DocProject/buildhelp/ 125 | DocProject/Help/*.HxT 126 | DocProject/Help/*.HxC 127 | DocProject/Help/*.hhc 128 | DocProject/Help/*.hhk 129 | DocProject/Help/*.hhp 130 | DocProject/Help/Html2 131 | DocProject/Help/html 132 | 133 | # Click-Once directory 134 | publish/ 135 | 136 | # Publish Web Output 137 | *.[Pp]ublish.xml 138 | *.azurePubxml 139 | # TODO: Comment the next line if you want to checkin your web deploy settings 140 | # but database connection strings (with potential passwords) will be unencrypted 141 | *.pubxml 142 | *.publishproj 143 | 144 | # NuGet Packages 145 | *.nupkg 146 | # The packages folder can be ignored because of Package Restore 147 | **/packages/* 148 | # except build/, which is used as an MSBuild target. 149 | !**/packages/build/ 150 | # Uncomment if necessary however generally it will be regenerated when needed 151 | #!**/packages/repositories.config 152 | 153 | # Windows Azure Build Output 154 | csx/ 155 | *.build.csdef 156 | 157 | # Windows Store app package directory 158 | AppPackages/ 159 | 160 | # Visual Studio cache files 161 | # files ending in .cache can be ignored 162 | *.[Cc]ache 163 | # but keep track of directories ending in .cache 164 | !*.[Cc]ache/ 165 | 166 | # Others 167 | ClientBin/ 168 | [Ss]tyle[Cc]op.* 169 | ~$* 170 | *~ 171 | *.dbmdl 172 | *.dbproj.schemaview 173 | *.pfx 174 | *.publishsettings 175 | node_modules/ 176 | orleans.codegen.cs 177 | 178 | # RIA/Silverlight projects 179 | Generated_Code/ 180 | 181 | # Backup & report files from converting an old project file 182 | # to a newer Visual Studio version. Backup files are not needed, 183 | # because we have git ;-) 184 | _UpgradeReport_Files/ 185 | Backup*/ 186 | UpgradeLog*.XML 187 | UpgradeLog*.htm 188 | 189 | # SQL Server files 190 | *.mdf 191 | *.ldf 192 | 193 | # Business Intelligence projects 194 | *.rdl.data 195 | *.bim.layout 196 | *.bim_*.settings 197 | 198 | # Microsoft Fakes 199 | FakesAssemblies/ 200 | 201 | # Node.js Tools for Visual Studio 202 | .ntvs_analysis.dat 203 | 204 | # Visual Studio 6 build log 205 | *.plg 206 | 207 | # Visual Studio 6 workspace options file 208 | *.opt 209 | 210 | # Visual Studio LightSwitch build output 211 | **/*.HTMLClient/GeneratedArtifacts 212 | **/*.DesktopClient/GeneratedArtifacts 213 | **/*.DesktopClient/ModelManifest.xml 214 | **/*.Server/GeneratedArtifacts 215 | **/*.Server/ModelManifest.xml 216 | _Pvt_Extensions 217 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | Apache License 2 | ============== 3 | 4 | _Version 2.0, January 2004_ 5 | _<>_ 6 | 7 | ### Terms and Conditions for use, reproduction, and distribution 8 | 9 | #### 1. Definitions 10 | 11 | “License” shall mean the terms and conditions for use, reproduction, and 12 | distribution as defined by Sections 1 through 9 of this document. 13 | 14 | “Licensor” shall mean the copyright owner or entity authorized by the copyright 15 | owner that is granting the License. 16 | 17 | “Legal Entity” shall mean the union of the acting entity and all other entities 18 | that control, are controlled by, or are under common control with that entity. 19 | For the purposes of this definition, “control” means **(i)** the power, direct or 20 | indirect, to cause the direction or management of such entity, whether by 21 | contract or otherwise, or **(ii)** ownership of fifty percent (50%) or more of the 22 | outstanding shares, or **(iii)** beneficial ownership of such entity. 23 | 24 | “You” (or “Your”) shall mean an individual or Legal Entity exercising 25 | permissions granted by this License. 26 | 27 | “Source” form shall mean the preferred form for making modifications, including 28 | but not limited to software source code, documentation source, and configuration 29 | files. 30 | 31 | “Object” form shall mean any form resulting from mechanical transformation or 32 | translation of a Source form, including but not limited to compiled object code, 33 | generated documentation, and conversions to other media types. 34 | 35 | “Work” shall mean the work of authorship, whether in Source or Object form, made 36 | available under the License, as indicated by a copyright notice that is included 37 | in or attached to the work (an example is provided in the Appendix below). 38 | 39 | “Derivative Works” shall mean any work, whether in Source or Object form, that 40 | is based on (or derived from) the Work and for which the editorial revisions, 41 | annotations, elaborations, or other modifications represent, as a whole, an 42 | original work of authorship. For the purposes of this License, Derivative Works 43 | shall not include works that remain separable from, or merely link (or bind by 44 | name) to the interfaces of, the Work and Derivative Works thereof. 45 | 46 | “Contribution” shall mean any work of authorship, including the original version 47 | of the Work and any modifications or additions to that Work or Derivative Works 48 | thereof, that is intentionally submitted to Licensor for inclusion in the Work 49 | by the copyright owner or by an individual or Legal Entity authorized to submit 50 | on behalf of the copyright owner. For the purposes of this definition, 51 | “submitted” means any form of electronic, verbal, or written communication sent 52 | to the Licensor or its representatives, including but not limited to 53 | communication on electronic mailing lists, source code control systems, and 54 | issue tracking systems that are managed by, or on behalf of, the Licensor for 55 | the purpose of discussing and improving the Work, but excluding communication 56 | that is conspicuously marked or otherwise designated in writing by the copyright 57 | owner as “Not a Contribution.” 58 | 59 | “Contributor” shall mean Licensor and any individual or Legal Entity on behalf 60 | of whom a Contribution has been received by Licensor and subsequently 61 | incorporated within the Work. 62 | 63 | #### 2. Grant of Copyright License 64 | 65 | Subject to the terms and conditions of this License, each Contributor hereby 66 | grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, 67 | irrevocable copyright license to reproduce, prepare Derivative Works of, 68 | publicly display, publicly perform, sublicense, and distribute the Work and such 69 | Derivative Works in Source or Object form. 70 | 71 | #### 3. Grant of Patent License 72 | 73 | Subject to the terms and conditions of this License, each Contributor hereby 74 | grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, 75 | irrevocable (except as stated in this section) patent license to make, have 76 | made, use, offer to sell, sell, import, and otherwise transfer the Work, where 77 | such license applies only to those patent claims licensable by such Contributor 78 | that are necessarily infringed by their Contribution(s) alone or by combination 79 | of their Contribution(s) with the Work to which such Contribution(s) was 80 | submitted. If You institute patent litigation against any entity (including a 81 | cross-claim or counterclaim in a lawsuit) alleging that the Work or a 82 | Contribution incorporated within the Work constitutes direct or contributory 83 | patent infringement, then any patent licenses granted to You under this License 84 | for that Work shall terminate as of the date such litigation is filed. 85 | 86 | #### 4. Redistribution 87 | 88 | You may reproduce and distribute copies of the Work or Derivative Works thereof 89 | in any medium, with or without modifications, and in Source or Object form, 90 | provided that You meet the following conditions: 91 | 92 | * **(a)** You must give any other recipients of the Work or Derivative Works a copy of 93 | this License; and 94 | * **(b)** You must cause any modified files to carry prominent notices stating that You 95 | changed the files; and 96 | * **(c)** You must retain, in the Source form of any Derivative Works that You distribute, 97 | all copyright, patent, trademark, and attribution notices from the Source form 98 | of the Work, excluding those notices that do not pertain to any part of the 99 | Derivative Works; and 100 | * **(d)** If the Work includes a “NOTICE” text file as part of its distribution, then any 101 | Derivative Works that You distribute must include a readable copy of the 102 | attribution notices contained within such NOTICE file, excluding those notices 103 | that do not pertain to any part of the Derivative Works, in at least one of the 104 | following places: within a NOTICE text file distributed as part of the 105 | Derivative Works; within the Source form or documentation, if provided along 106 | with the Derivative Works; or, within a display generated by the Derivative 107 | Works, if and wherever such third-party notices normally appear. The contents of 108 | the NOTICE file are for informational purposes only and do not modify the 109 | License. You may add Your own attribution notices within Derivative Works that 110 | You distribute, alongside or as an addendum to the NOTICE text from the Work, 111 | provided that such additional attribution notices cannot be construed as 112 | modifying the License. 113 | 114 | You may add Your own copyright statement to Your modifications and may provide 115 | additional or different license terms and conditions for use, reproduction, or 116 | distribution of Your modifications, or for any such Derivative Works as a whole, 117 | provided Your use, reproduction, and distribution of the Work otherwise complies 118 | with the conditions stated in this License. 119 | 120 | #### 5. Submission of Contributions 121 | 122 | Unless You explicitly state otherwise, any Contribution intentionally submitted 123 | for inclusion in the Work by You to the Licensor shall be under the terms and 124 | conditions of this License, without any additional terms or conditions. 125 | Notwithstanding the above, nothing herein shall supersede or modify the terms of 126 | any separate license agreement you may have executed with Licensor regarding 127 | such Contributions. 128 | 129 | #### 6. Trademarks 130 | 131 | This License does not grant permission to use the trade names, trademarks, 132 | service marks, or product names of the Licensor, except as required for 133 | reasonable and customary use in describing the origin of the Work and 134 | reproducing the content of the NOTICE file. 135 | 136 | #### 7. Disclaimer of Warranty 137 | 138 | Unless required by applicable law or agreed to in writing, Licensor provides the 139 | Work (and each Contributor provides its Contributions) on an “AS IS” BASIS, 140 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, 141 | including, without limitation, any warranties or conditions of TITLE, 142 | NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are 143 | solely responsible for determining the appropriateness of using or 144 | redistributing the Work and assume any risks associated with Your exercise of 145 | permissions under this License. 146 | 147 | #### 8. Limitation of Liability 148 | 149 | In no event and under no legal theory, whether in tort (including negligence), 150 | contract, or otherwise, unless required by applicable law (such as deliberate 151 | and grossly negligent acts) or agreed to in writing, shall any Contributor be 152 | liable to You for damages, including any direct, indirect, special, incidental, 153 | or consequential damages of any character arising as a result of this License or 154 | out of the use or inability to use the Work (including but not limited to 155 | damages for loss of goodwill, work stoppage, computer failure or malfunction, or 156 | any and all other commercial damages or losses), even if such Contributor has 157 | been advised of the possibility of such damages. 158 | 159 | #### 9. Accepting Warranty or Additional Liability 160 | 161 | While redistributing the Work or Derivative Works thereof, You may choose to 162 | offer, and charge a fee for, acceptance of support, warranty, indemnity, or 163 | other liability obligations and/or rights consistent with this License. However, 164 | in accepting such obligations, You may act only on Your own behalf and on Your 165 | sole responsibility, not on behalf of any other Contributor, and only if You 166 | agree to indemnify, defend, and hold each Contributor harmless for any liability 167 | incurred by, or claims asserted against, such Contributor by reason of your 168 | accepting any such warranty or additional liability. 169 | 170 | _END OF TERMS AND CONDITIONS_ 171 | 172 | ### APPENDIX: How to apply the Apache License to your work 173 | 174 | To apply the Apache License to your work, attach the following boilerplate 175 | notice, with the fields enclosed by brackets `[]` replaced with your own 176 | identifying information. (Don't include the brackets!) The text should be 177 | enclosed in the appropriate comment syntax for the file format. We also 178 | recommend that a file or class name and description of purpose be included on 179 | the same “printed page” as the copyright notice for easier identification within 180 | third-party archives. 181 | 182 | Copyright [yyyy] [name of copyright owner] 183 | 184 | Licensed under the Apache License, Version 2.0 (the "License"); 185 | you may not use this file except in compliance with the License. 186 | You may obtain a copy of the License at 187 | 188 | http://www.apache.org/licenses/LICENSE-2.0 189 | 190 | Unless required by applicable law or agreed to in writing, software 191 | distributed under the License is distributed on an "AS IS" BASIS, 192 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 193 | See the License for the specific language governing permissions and 194 | limitations under the License. 195 | 196 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright [yyyy] [name of copyright owner] 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![GitHub issues](https://img.shields.io/github/issues/RichardSlater/Markdig.SyntaxHighlighting.svg?style=flat-square)](https://github.com/RichardSlater/Markdig.SyntaxHighlighting/issues) 2 | [![GitHub forks](https://img.shields.io/github/forks/RichardSlater/Markdig.SyntaxHighlighting.svg?style=flat-square)](https://github.com/RichardSlater/Markdig.SyntaxHighlighting/network) 3 | [![GitHub stars](https://img.shields.io/github/stars/RichardSlater/Markdig.SyntaxHighlighting.svg?style=flat-square)](https://github.com/RichardSlater/Markdig.SyntaxHighlighting/stargazers) 4 | [![GitHub license](https://img.shields.io/badge/license-Apache%202-blue.svg?style=flat-square)](https://raw.githubusercontent.com/RichardSlater/Markdig.SyntaxHighlighting/master/LICENSE.md) 5 | [![AppVeyor](https://img.shields.io/appveyor/ci/richard-slater/markdig-syntaxhighlighting.svg?style=flat-square)](https://ci.appveyor.com/project/richard-slater/markdig-syntaxhighlighting) 6 | [![NuGet](https://img.shields.io/nuget/dt/Markdig.SyntaxHighlighting.svg?style=flat-square)](https://www.nuget.org/packages/Markdig.SyntaxHighlighting/) 7 | [![NuGet](https://img.shields.io/nuget/v/Markdig.SyntaxHighlighting.svg?style=flat-square)](https://www.nuget.org/packages/Markdig.SyntaxHighlighting/) 8 | 9 | # Syntax Highlighting extension for Markdig 10 | 11 | An extension that adds Syntax Highlighting, also known as code colourization, 12 | to a [Markdig][markdig] pipeline through the power of [ColorCode][colorcode]. 13 | By simply adding this extension to your pipeline, you can add colour and style 14 | to your source code: 15 | 16 | ## Demonstration 17 | 18 | ### Before 19 | 20 | ``` 21 | namespace Amido.VersionDashboard.Web.Domain { 22 | public interface IConfigProvider { 23 | string GetSetting(string appSetting); 24 | } 25 | } 26 | ``` 27 | 28 | ### After 29 | 30 | ```csharp 31 | namespace Amido.VersionDashboard.Web.Domain { 32 | public interface IConfigProvider { 33 | string GetSetting(string appSetting); 34 | } 35 | } 36 | ``` 37 | 38 | ## Usage 39 | 40 | Simply import the nuget package, add a using statement for `Markdig.SyntaxHighlighting` and add to your pipeline: 41 | 42 | ```csharp 43 | var pipeline = new MarkdownPipelineBuilder() 44 | .UseAdvancedExtensions() 45 | .UseSyntaxHighlighting() 46 | .Build(); 47 | ``` 48 | 49 | ## Future Updates 50 | 51 | * [ ] Upgrade ColorCode to support .NET Core / .NET Standard. 52 | * [ ] Upgrade Markdig.SyntaxHighlighting to support .NET Core / .NET Standard. 53 | * [ ] Add support for Code Coverage 54 | * [ ] Add support for Dependency Checking 55 | 56 | 57 | [markdig]: https://github.com/lunet-io/markdig 58 | [colorcode]: https://colorcode.codeplex.com/ 59 | -------------------------------------------------------------------------------- /appveyor.yml: -------------------------------------------------------------------------------- 1 | - 2 | branches: 3 | only: 4 | - master 5 | 6 | version: 1.1.{build} 7 | 8 | # build configurations 9 | configuration: Release 10 | 11 | deploy: 12 | - provider: NuGet 13 | api_key: 14 | secure: V5o2cN5k44AUj5QCNS3Cw9dUgH7sp7Enuo9XXslpS+qxLoYh0CIwSHoR5dQB4TFY 15 | skip_symbols: false 16 | artifact: /.*\.nupkg/ 17 | 18 | # enable AssemblyInfo.cs patching with build version number 19 | assembly_info: 20 | patch: true 21 | file: AssemblyInfo.* 22 | assembly_version: "{version}" 23 | assembly_file_version: "{version}" 24 | assembly_informational_version: "{version}" 25 | 26 | # restore NuGet packages before running MSBuild 27 | before_build: 28 | - nuget restore src\Markdig.SyntaxHighlighting.sln 29 | 30 | cache: 31 | - src\packages -> **\packages.config # preserve "packages" directory 32 | - '%LocalAppData%\NuGet\Cache' # NuGet < v3 33 | - '%LocalAppData%\NuGet\v3-cache' # NuGet v3 34 | 35 | build: 36 | # enable MSBuild parallel builds 37 | parallel: true 38 | project: src\Markdig.SyntaxHighlighting.sln 39 | publish_nuget: true 40 | publish_nuget_symbols: true 41 | 42 | skip_commits: 43 | files: 44 | - README.md 45 | - LICENSE.md 46 | - LICENSE.txt 47 | - 'assets/**' 48 | - 'scripts/**' 49 | 50 | - 51 | version: 1.0.{build}-{branch} 52 | 53 | # build configurations 54 | configuration: Release 55 | 56 | # enable AssemblyInfo.cs patching with build version number 57 | assembly_info: 58 | patch: true 59 | file: AssemblyInfo.* 60 | assembly_version: "{version}" 61 | assembly_file_version: "{version}" 62 | assembly_informational_version: "{version}" 63 | 64 | # restore NuGet packages before running MSBuild 65 | before_build: 66 | - nuget restore src\Markdig.SyntaxHighlighting.sln 67 | 68 | cache: 69 | - packages -> **\packages.config # preserve "packages" directory 70 | - '%LocalAppData%\NuGet\Cache' # NuGet < v3 71 | - '%LocalAppData%\NuGet\v3-cache' # NuGet v3 72 | 73 | build: 74 | # enable MSBuild parallel builds 75 | parallel: true 76 | project: src\Markdig.SyntaxHighlighting.sln 77 | publish_nuget: true 78 | publish_nuget_symbols: true 79 | -------------------------------------------------------------------------------- /assets/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RichardSlater/Markdig.SyntaxHighlighting/b11781f665984e938eb486c5441406eea9db4110/assets/icon.png -------------------------------------------------------------------------------- /assets/icon.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 22 | 24 | 43 | 45 | 46 | 48 | image/svg+xml 49 | 51 | 52 | 53 | 54 | 55 | 61 | 66 | 71 | 76 | 81 | 85 | 89 | 90 | 91 | -------------------------------------------------------------------------------- /scripts/Initialize-SharedAssemblyInfo.ps1: -------------------------------------------------------------------------------- 1 | function Initialize-SharedAssemblyInfo { 2 | Param( 3 | [Parameter(Mandatory=$False)] 4 | [Switch]$RemoveComments = $False 5 | ) 6 | process { 7 | $crlf = [System.Environment]::NewLine; 8 | 9 | $current = $PSScriptRoot; 10 | while ((-Not (Test-Path "$current\src")) -Or ($current.Length -lt 4)) { 11 | $current = (Get-Item $current).Parent.FullName; 12 | } 13 | 14 | $solutions = "$current\src"; 15 | 16 | if (-Not (Test-Path $solutions)) { 17 | throw "Unable to find solutions directory."; 18 | } 19 | 20 | Write-Host -ForegroundColor Green "Found Solutions at $solutions"; 21 | 22 | $sharedAssemblyInfo = Join-Path $solutions "SharedAssemblyInfo.cs"; 23 | 24 | if (-Not (Test-Path $sharedAssemblyInfo)) { 25 | Write-Host -ForegroundColor Yellow "SharedAssemblyInfo.cs not found, supply some details and we can set it up for you..."; 26 | Set-SharedAssemblyInfo -SharedAssemblyInfoFile $sharedAssemblyInfo; 27 | } 28 | 29 | $assemblyInfoFragment = ""; 30 | $sharedAssemblyInfoFragment = "`t`t" + $crlf + "`t`t`tProperties\SharedAssemblyInfo.cs" + $crlf + "`t`t"; 31 | 32 | $sharedAttributes = Get-Content $sharedAssemblyInfo ` 33 | | Where-Object { -not [String]::IsNullOrWhiteSpace($_) } ` 34 | | Where-Object { -not $_.StartsWith("//") } ` 35 | | Where-Object { -not $_.StartsWith("using") } ` 36 | | ForEach-Object { $_.Split((' ', '('))[1] }; 37 | 38 | if (Test-Path $sharedAssemblyInfo) { 39 | Write-Host -ForegroundColor Green "Found SharedAssemblyInfo.cs in $solutions"; 40 | } else { 41 | throw "Could not find SharedAssemblyInfo.cs... exiting."; 42 | } 43 | 44 | $projects = (Get-ChildItem -Recurse $solutions *.csproj); 45 | 46 | foreach ($project in $projects) { 47 | $projectXml = [xml](Get-Content $project.VersionInfo.FileName); 48 | $assemblyInfo = ($projectXml.Project.ItemGroup ` 49 | | Where-Object { ` 50 | ($_.GetType().Name -eq "XmlElement") ` 51 | -And (($_.ChildNodes | Select-Object -Last 1).Name -eq "Compile")}).Compile.Include ` 52 | | Where-Object { $_.EndsWith("AssemblyInfo.cs") }; 53 | 54 | if ($assemblyInfo | Where-Object { $_.EndsWith("SharedAssemblyInfo.cs")}) { 55 | Write-Host -ForegroundColor Green " $project already contains SharedAssemblyInfo.cs"; 56 | } else { 57 | Write-Host -ForegroundColor Yellow -NoNewLine " $project dosn't contain SharedAssemblyInfo.cs"; 58 | 59 | Push-Location ($project.DirectoryName); 60 | $relativeSharedAssemblyPath = Resolve-Path -Relative $sharedAssemblyInfo; 61 | Pop-Location; 62 | $projectFile = (Get-Content $project.VersionInfo.FileName); 63 | $projectFile = $projectFile.Replace($assemblyInfoFragment, $assemblyInfoFragment + $crlf + ($sharedAssemblyInfoFragment -f $relativeSharedAssemblyPath)); 64 | Set-Content -Path $project.VersionInfo.FileName $projectFile; 65 | 66 | Write-Host -ForegroundColor Green "... added."; 67 | } 68 | 69 | $assemblyInfoPath = (Join-Path $project.DirectoryName "properties/AssemblyInfo.cs"); 70 | $assemblyInfo = Get-Content $assemblyInfoPath; 71 | $newAssemblyInfo = New-Object System.Text.StringBuilder ; 72 | 73 | Write-Host -ForegroundColor White " Inspecting AssemblyInfo.cs in $project" 74 | $previousLine = ""; 75 | 76 | foreach ($line in $assemblyInfo) { 77 | $found = $False; 78 | 79 | foreach ($attribute in $sharedAttributes) { 80 | if ($line.StartsWith("[assembly: $attribute")) { 81 | Write-Host -ForegroundColor Yellow " Removing shared attribute: $attribute" 82 | $found = $True; 83 | } 84 | } 85 | 86 | if (-not $found) { 87 | if ($RemoveComments -and $line.StartsWith("//")) { 88 | continue; 89 | } 90 | 91 | if ([String]::IsNullOrWhiteSpace($line) -and [String]::IsNullOrWhiteSpace($previousLine)) { 92 | continue; 93 | } 94 | 95 | $newAssemblyInfo.AppendLine($line) | Out-Null; 96 | } 97 | 98 | $previousLine = $line; 99 | } 100 | 101 | Set-Content -Path $assemblyInfoPath -Value $newAssemblyInfo.ToString().Trim() -Encoding UTF8; 102 | } 103 | } 104 | } 105 | 106 | function Set-SharedAssemblyInfo { 107 | Param( 108 | [parameter(Mandatory=$true)] 109 | $SharedAssemblyInfoFile, 110 | [parameter(Mandatory=$true)] 111 | $Company = "Amido Limited", 112 | [parameter(Mandatory=$true)] 113 | $Product = "Product", 114 | [parameter(Mandatory=$true)] 115 | $Year = (Get-Date).Year, 116 | [parameter(Mandatory=$true)] 117 | $Trademark = "" 118 | ) 119 | 120 | process { 121 | $template = "using System.Reflection; 122 | using System.Runtime.InteropServices; 123 | 124 | // General Information about an assembly is controlled through the following 125 | // set of attributes. Change these attribute values to modify the information 126 | // associated with an assembly. 127 | [assembly: AssemblyConfiguration(`"debug`")] 128 | [assembly: AssemblyCompany(`"$Company`")] 129 | [assembly: AssemblyProduct(`"$Product`")] 130 | [assembly: AssemblyCopyright(`"©$Year $Company, All Rights Reserved`")] 131 | [assembly: AssemblyTrademark(`"$Trademark`")] 132 | [assembly: AssemblyCulture(`"`")] 133 | 134 | // Setting ComVisible to false makes the types in this assembly not visible 135 | // to COM components. If you need to access a type in this assembly from 136 | // COM, set the ComVisible attribute to true on that type. 137 | [assembly: ComVisible(false)] 138 | 139 | // Version information for an assembly consists of the following four values: 140 | // 141 | // Major Version 142 | // Minor Version 143 | // Build Number 144 | // Revision 145 | // 146 | // You can specify all the values or you can default the Build and Revision Numbers 147 | // by using the '*' as shown below: 148 | // [assembly: AssemblyVersion(`"1.0.*`")] 149 | [assembly: AssemblyVersion(`"1.0.0.0`")] 150 | [assembly: AssemblyFileVersion(`"1.0.0.0`")]" 151 | 152 | Set-Content -Path $SharedAssemblyInfoFile -Value $template -Encoding UTF8; 153 | } 154 | } 155 | 156 | 157 | Initialize-SharedAssemblyInfo -RemoveComments 158 | -------------------------------------------------------------------------------- /src/Markdig.SyntaxHighlighting.Tests/Example/CodeSample.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | using System.Reflection; 4 | using Xunit; 5 | 6 | namespace Markdig.SyntaxHighlighting.Tests.Example { 7 | public class CodeSample { 8 | [Fact] 9 | public void CodeSampleWorks() { 10 | var codebase = Assembly.GetExecutingAssembly().GetName().CodeBase; 11 | var directory = Path.GetDirectoryName(codebase); 12 | if (directory == null) { 13 | throw new NullReferenceException("appPath came back null."); 14 | } 15 | var appPath = new Uri(directory).LocalPath; 16 | var folder = Path.Combine(appPath, "Example"); 17 | var inputMarkdown = Path.Combine(folder, "README.md"); 18 | var referenceFile = Path.Combine(folder, "expected.html"); 19 | var expectedHtml = File.ReadAllText(referenceFile); 20 | var markdown = File.ReadAllText(inputMarkdown); 21 | var pipeline = new MarkdownPipelineBuilder() 22 | .UseAdvancedExtensions() 23 | .UseSyntaxHighlighting() 24 | .Build(); 25 | var html = Markdown.ToHtml(markdown, pipeline); 26 | var actualHtml = File.ReadAllText(Path.Combine(folder, "_template.html")) 27 | .Replace("{{{this}}}", html); 28 | actualHtml = actualHtml.Replace("\r\n", "\n").Replace("\n", "\r\n"); 29 | expectedHtml = expectedHtml.Replace("\r\n", "\n").Replace("\n", "\r\n"); 30 | File.WriteAllText(Path.Combine(folder, "actual.html"), actualHtml); 31 | Assert.Equal(expectedHtml, actualHtml); 32 | } 33 | } 34 | } -------------------------------------------------------------------------------- /src/Markdig.SyntaxHighlighting.Tests/Example/README.md: -------------------------------------------------------------------------------- 1 | This is before the table 2 | 3 | | Heading 1 | Heading 2 | 4 | | --------- | --------- | 5 | | Row 1 | Cell 2 | 6 | 7 | This is after the table 8 | 9 | ```csharp 10 | // ©2015 Amido Limited (https://www.amido.com), Licensed under the terms of the Apache 2.0 Licence (http://www.apache.org/licenses/LICENSE-2.0) 11 | 12 | namespace Amido.VersionDashboard.Web.Domain { 13 | public interface IConfigProvider { 14 | string GetSetting(string appSetting); 15 | } 16 | } 17 | ``` 18 | -------------------------------------------------------------------------------- /src/Markdig.SyntaxHighlighting.Tests/Example/_template.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | {{{this}}} 7 | 8 | 9 | -------------------------------------------------------------------------------- /src/Markdig.SyntaxHighlighting.Tests/Example/expected.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 |

This is before the table

7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 |
Heading 1Heading 2
Row 1Cell 2
21 |

This is after the table

22 |
23 | // ©2015 Amido Limited (https://www.amido.com), Licensed under the terms of the Apache 2.0 Licence (http://www.apache.org/licenses/LICENSE-2.0)
24 | 
25 | namespace Amido.VersionDashboard.Web.Domain {
26 |     public interface IConfigProvider {
27 |         string GetSetting(string appSetting);
28 |     }
29 | }
30 | 
31 |
32 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /src/Markdig.SyntaxHighlighting.Tests/Example/gfm.css: -------------------------------------------------------------------------------- 1 | @font-face { 2 | font-family: octicons-link; 3 | src: url(data:font/woff;charset=utf-8;base64,d09GRgABAAAAAAZwABAAAAAACFQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABEU0lHAAAGaAAAAAgAAAAIAAAAAUdTVUIAAAZcAAAACgAAAAoAAQAAT1MvMgAAAyQAAABJAAAAYFYEU3RjbWFwAAADcAAAAEUAAACAAJThvmN2dCAAAATkAAAABAAAAAQAAAAAZnBnbQAAA7gAAACyAAABCUM+8IhnYXNwAAAGTAAAABAAAAAQABoAI2dseWYAAAFsAAABPAAAAZwcEq9taGVhZAAAAsgAAAA0AAAANgh4a91oaGVhAAADCAAAABoAAAAkCA8DRGhtdHgAAAL8AAAADAAAAAwGAACfbG9jYQAAAsAAAAAIAAAACABiATBtYXhwAAACqAAAABgAAAAgAA8ASm5hbWUAAAToAAABQgAAAlXu73sOcG9zdAAABiwAAAAeAAAAME3QpOBwcmVwAAAEbAAAAHYAAAB/aFGpk3jaTY6xa8JAGMW/O62BDi0tJLYQincXEypYIiGJjSgHniQ6umTsUEyLm5BV6NDBP8Tpts6F0v+k/0an2i+itHDw3v2+9+DBKTzsJNnWJNTgHEy4BgG3EMI9DCEDOGEXzDADU5hBKMIgNPZqoD3SilVaXZCER3/I7AtxEJLtzzuZfI+VVkprxTlXShWKb3TBecG11rwoNlmmn1P2WYcJczl32etSpKnziC7lQyWe1smVPy/Lt7Kc+0vWY/gAgIIEqAN9we0pwKXreiMasxvabDQMM4riO+qxM2ogwDGOZTXxwxDiycQIcoYFBLj5K3EIaSctAq2kTYiw+ymhce7vwM9jSqO8JyVd5RH9gyTt2+J/yUmYlIR0s04n6+7Vm1ozezUeLEaUjhaDSuXHwVRgvLJn1tQ7xiuVv/ocTRF42mNgZGBgYGbwZOBiAAFGJBIMAAizAFoAAABiAGIAznjaY2BkYGAA4in8zwXi+W2+MjCzMIDApSwvXzC97Z4Ig8N/BxYGZgcgl52BCSQKAA3jCV8CAABfAAAAAAQAAEB42mNgZGBg4f3vACQZQABIMjKgAmYAKEgBXgAAeNpjYGY6wTiBgZWBg2kmUxoDA4MPhGZMYzBi1AHygVLYQUCaawqDA4PChxhmh/8ODDEsvAwHgMKMIDnGL0x7gJQCAwMAJd4MFwAAAHjaY2BgYGaA4DAGRgYQkAHyGMF8NgYrIM3JIAGVYYDT+AEjAwuDFpBmA9KMDEwMCh9i/v8H8sH0/4dQc1iAmAkALaUKLgAAAHjaTY9LDsIgEIbtgqHUPpDi3gPoBVyRTmTddOmqTXThEXqrob2gQ1FjwpDvfwCBdmdXC5AVKFu3e5MfNFJ29KTQT48Ob9/lqYwOGZxeUelN2U2R6+cArgtCJpauW7UQBqnFkUsjAY/kOU1cP+DAgvxwn1chZDwUbd6CFimGXwzwF6tPbFIcjEl+vvmM/byA48e6tWrKArm4ZJlCbdsrxksL1AwWn/yBSJKpYbq8AXaaTb8AAHja28jAwOC00ZrBeQNDQOWO//sdBBgYGRiYWYAEELEwMTE4uzo5Zzo5b2BxdnFOcALxNjA6b2ByTswC8jYwg0VlNuoCTWAMqNzMzsoK1rEhNqByEyerg5PMJlYuVueETKcd/89uBpnpvIEVomeHLoMsAAe1Id4AAAAAAAB42oWQT07CQBTGv0JBhagk7HQzKxca2sJCE1hDt4QF+9JOS0nbaaYDCQfwCJ7Au3AHj+LO13FMmm6cl7785vven0kBjHCBhfpYuNa5Ph1c0e2Xu3jEvWG7UdPDLZ4N92nOm+EBXuAbHmIMSRMs+4aUEd4Nd3CHD8NdvOLTsA2GL8M9PODbcL+hD7C1xoaHeLJSEao0FEW14ckxC+TU8TxvsY6X0eLPmRhry2WVioLpkrbp84LLQPGI7c6sOiUzpWIWS5GzlSgUzzLBSikOPFTOXqly7rqx0Z1Q5BAIoZBSFihQYQOOBEdkCOgXTOHA07HAGjGWiIjaPZNW13/+lm6S9FT7rLHFJ6fQbkATOG1j2OFMucKJJsxIVfQORl+9Jyda6Sl1dUYhSCm1dyClfoeDve4qMYdLEbfqHf3O/AdDumsjAAB42mNgYoAAZQYjBmyAGYQZmdhL8zLdDEydARfoAqIAAAABAAMABwAKABMAB///AA8AAQAAAAAAAAAAAAAAAAABAAAAAA==) format('woff'); 4 | } 5 | 6 | .markdown-body { 7 | -ms-text-size-adjust: 100%; 8 | -webkit-text-size-adjust: 100%; 9 | color: #333; 10 | font-family: "Helvetica Neue", Helvetica, "Segoe UI", Arial, freesans, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol"; 11 | font-size: 16px; 12 | line-height: 1.6; 13 | word-wrap: break-word; 14 | } 15 | 16 | .markdown-body a { 17 | -webkit-text-decoration-skip: objects; 18 | background-color: transparent; 19 | } 20 | 21 | .markdown-body a:active, 22 | .markdown-body a:hover { outline-width: 0; } 23 | 24 | .markdown-body strong { font-weight: inherit; } 25 | 26 | .markdown-body strong { font-weight: bolder; } 27 | 28 | .markdown-body h1 { 29 | font-size: 2em; 30 | margin: 0.67em 0; 31 | } 32 | 33 | .markdown-body img { border-style: none; } 34 | 35 | .markdown-body svg:not(:root) { overflow: hidden; } 36 | 37 | .markdown-body code, 38 | .markdown-body kbd, 39 | .markdown-body pre { 40 | font-family: monospace, monospace; 41 | font-size: 1em; 42 | } 43 | 44 | .markdown-body hr { 45 | box-sizing: content-box; 46 | height: 0; 47 | overflow: visible; 48 | } 49 | 50 | .markdown-body input { 51 | font: inherit; 52 | margin: 0; 53 | } 54 | 55 | .markdown-body input { overflow: visible; } 56 | 57 | .markdown-body button:-moz-focusring, 58 | .markdown-body [type="button"]:-moz-focusring, 59 | .markdown-body [type="reset"]:-moz-focusring, 60 | .markdown-body [type="submit"]:-moz-focusring { outline: 1px dotted ButtonText; } 61 | 62 | .markdown-body [type="checkbox"] { 63 | box-sizing: border-box; 64 | padding: 0; 65 | } 66 | 67 | .markdown-body table { 68 | border-collapse: collapse; 69 | border-spacing: 0; 70 | } 71 | 72 | .markdown-body td, 73 | .markdown-body th { padding: 0; } 74 | 75 | .markdown-body * { box-sizing: border-box; } 76 | 77 | .markdown-body input { font: 13px/1.4 Helvetica, arial, nimbussansl, liberationsans, freesans, clean, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol"; } 78 | 79 | .markdown-body a { 80 | color: #4078c0; 81 | text-decoration: none; 82 | } 83 | 84 | .markdown-body a:hover, 85 | .markdown-body a:active { text-decoration: underline; } 86 | 87 | .markdown-body hr { 88 | background: transparent; 89 | border: 0; 90 | border-bottom: 1px solid #ddd; 91 | height: 0; 92 | margin: 15px 0; 93 | overflow: hidden; 94 | } 95 | 96 | .markdown-body hr::before { 97 | content: ""; 98 | display: table; 99 | } 100 | 101 | .markdown-body hr::after { 102 | clear: both; 103 | content: ""; 104 | display: table; 105 | } 106 | 107 | .markdown-body h1, 108 | .markdown-body h2, 109 | .markdown-body h3, 110 | .markdown-body h4, 111 | .markdown-body h5, 112 | .markdown-body h6 { 113 | line-height: 1.5; 114 | margin-bottom: 0; 115 | margin-top: 0; 116 | } 117 | 118 | .markdown-body h1 { font-size: 30px; } 119 | 120 | .markdown-body h2 { font-size: 21px; } 121 | 122 | .markdown-body h3 { font-size: 16px; } 123 | 124 | .markdown-body h4 { font-size: 14px; } 125 | 126 | .markdown-body h5 { font-size: 12px; } 127 | 128 | .markdown-body h6 { font-size: 11px; } 129 | 130 | .markdown-body p { 131 | margin-bottom: 10px; 132 | margin-top: 0; 133 | } 134 | 135 | .markdown-body blockquote { margin: 0; } 136 | 137 | .markdown-body ul, 138 | .markdown-body ol { 139 | margin-bottom: 0; 140 | margin-top: 0; 141 | padding-left: 0; 142 | } 143 | 144 | .markdown-body ol ol, 145 | .markdown-body ul ol { list-style-type: lower-roman; } 146 | 147 | .markdown-body ul ul ol, 148 | .markdown-body ul ol ol, 149 | .markdown-body ol ul ol, 150 | .markdown-body ol ol ol { list-style-type: lower-alpha; } 151 | 152 | .markdown-body dd { margin-left: 0; } 153 | 154 | .markdown-body code { 155 | font-family: Consolas, "Liberation Mono", Menlo, Courier, monospace; 156 | font-size: 12px; 157 | } 158 | 159 | .markdown-body pre { 160 | font: 12px Consolas, "Liberation Mono", Menlo, Courier, monospace; 161 | margin-bottom: 0; 162 | margin-top: 0; 163 | } 164 | 165 | .markdown-body .pl-0 { padding-left: 0 !important; } 166 | 167 | .markdown-body .pl-1 { padding-left: 3px !important; } 168 | 169 | .markdown-body .pl-2 { padding-left: 6px !important; } 170 | 171 | .markdown-body .pl-3 { padding-left: 12px !important; } 172 | 173 | .markdown-body .pl-4 { padding-left: 24px !important; } 174 | 175 | .markdown-body .pl-5 { padding-left: 36px !important; } 176 | 177 | .markdown-body .pl-6 { padding-left: 48px !important; } 178 | 179 | .markdown-body .form-select::-ms-expand { opacity: 0; } 180 | 181 | .markdown-body:before { 182 | content: ""; 183 | display: table; 184 | } 185 | 186 | .markdown-body:after { 187 | clear: both; 188 | content: ""; 189 | display: table; 190 | } 191 | 192 | .markdown-body > *:first-child { margin-top: 0 !important; } 193 | 194 | .markdown-body > *:last-child { margin-bottom: 0 !important; } 195 | 196 | .markdown-body a:not([href]) { 197 | color: inherit; 198 | text-decoration: none; 199 | } 200 | 201 | .markdown-body .anchor { 202 | display: inline-block; 203 | margin-left: -18px; 204 | padding-right: 2px; 205 | } 206 | 207 | .markdown-body .anchor:focus { outline: none; } 208 | 209 | .markdown-body h1, 210 | .markdown-body h2, 211 | .markdown-body h3, 212 | .markdown-body h4, 213 | .markdown-body h5, 214 | .markdown-body h6 { 215 | font-weight: bold; 216 | line-height: 1.4; 217 | margin-bottom: 16px; 218 | margin-top: 1em; 219 | } 220 | 221 | .markdown-body h1 .octicon-link, 222 | .markdown-body h2 .octicon-link, 223 | .markdown-body h3 .octicon-link, 224 | .markdown-body h4 .octicon-link, 225 | .markdown-body h5 .octicon-link, 226 | .markdown-body h6 .octicon-link { 227 | color: #000; 228 | vertical-align: middle; 229 | visibility: hidden; 230 | } 231 | 232 | .markdown-body h1:hover .anchor, 233 | .markdown-body h2:hover .anchor, 234 | .markdown-body h3:hover .anchor, 235 | .markdown-body h4:hover .anchor, 236 | .markdown-body h5:hover .anchor, 237 | .markdown-body h6:hover .anchor { text-decoration: none; } 238 | 239 | .markdown-body h1:hover .anchor .octicon-link, 240 | .markdown-body h2:hover .anchor .octicon-link, 241 | .markdown-body h3:hover .anchor .octicon-link, 242 | .markdown-body h4:hover .anchor .octicon-link, 243 | .markdown-body h5:hover .anchor .octicon-link, 244 | .markdown-body h6:hover .anchor .octicon-link { visibility: visible; } 245 | 246 | .markdown-body h1 { 247 | border-bottom: 1px solid #eee; 248 | font-size: 2.25em; 249 | line-height: 1.2; 250 | padding-bottom: 0.3em; 251 | } 252 | 253 | .markdown-body h1 .anchor { line-height: 1; } 254 | 255 | .markdown-body h2 { 256 | border-bottom: 1px solid #eee; 257 | font-size: 1.75em; 258 | line-height: 1.225; 259 | padding-bottom: 0.3em; 260 | } 261 | 262 | .markdown-body h2 .anchor { line-height: 1; } 263 | 264 | .markdown-body h3 { 265 | font-size: 1.5em; 266 | line-height: 1.43; 267 | } 268 | 269 | .markdown-body h3 .anchor { line-height: 1.2; } 270 | 271 | .markdown-body h4 { font-size: 1.25em; } 272 | 273 | .markdown-body h4 .anchor { line-height: 1.2; } 274 | 275 | .markdown-body h5 { font-size: 1em; } 276 | 277 | .markdown-body h5 .anchor { line-height: 1.1; } 278 | 279 | .markdown-body h6 { 280 | color: #777; 281 | font-size: 1em; 282 | } 283 | 284 | .markdown-body h6 .anchor { line-height: 1.1; } 285 | 286 | .markdown-body p, 287 | .markdown-body blockquote, 288 | .markdown-body ul, 289 | .markdown-body ol, 290 | .markdown-body dl, 291 | .markdown-body table, 292 | .markdown-body pre { 293 | margin-bottom: 16px; 294 | margin-top: 0; 295 | } 296 | 297 | .markdown-body hr { 298 | background-color: #e7e7e7; 299 | border: 0 none; 300 | height: 4px; 301 | margin: 16px 0; 302 | padding: 0; 303 | } 304 | 305 | .markdown-body ul, 306 | .markdown-body ol { padding-left: 2em; } 307 | 308 | .markdown-body ul ul, 309 | .markdown-body ul ol, 310 | .markdown-body ol ol, 311 | .markdown-body ol ul { 312 | margin-bottom: 0; 313 | margin-top: 0; 314 | } 315 | 316 | .markdown-body li > p { margin-top: 16px; } 317 | 318 | .markdown-body dl { padding: 0; } 319 | 320 | .markdown-body dl dt { 321 | font-size: 1em; 322 | font-style: italic; 323 | font-weight: bold; 324 | margin-top: 16px; 325 | padding: 0; 326 | } 327 | 328 | .markdown-body dl dd { 329 | margin-bottom: 16px; 330 | padding: 0 16px; 331 | } 332 | 333 | .markdown-body blockquote { 334 | border-left: 4px solid #ddd; 335 | color: #777; 336 | padding: 0 15px; 337 | } 338 | 339 | .markdown-body blockquote > :first-child { margin-top: 0; } 340 | 341 | .markdown-body blockquote > :last-child { margin-bottom: 0; } 342 | 343 | .markdown-body table { 344 | display: block; 345 | overflow: auto; 346 | width: 100%; 347 | word-break: normal; 348 | word-break: keep-all; 349 | } 350 | 351 | .markdown-body table th { font-weight: bold; } 352 | 353 | .markdown-body table th, 354 | .markdown-body table td { 355 | border: 1px solid #ddd; 356 | padding: 6px 13px; 357 | } 358 | 359 | .markdown-body table tr { 360 | background-color: #fff; 361 | border-top: 1px solid #ccc; 362 | } 363 | 364 | .markdown-body table tr:nth-child(2n) { background-color: #f8f8f8; } 365 | 366 | .markdown-body img { 367 | background-color: #fff; 368 | box-sizing: content-box; 369 | max-width: 100%; 370 | } 371 | 372 | .markdown-body code { 373 | background-color: rgba(0, 0, 0, 0.04); 374 | border-radius: 3px; 375 | font-size: 85%; 376 | margin: 0; 377 | padding: 0; 378 | padding-bottom: 0.2em; 379 | padding-top: 0.2em; 380 | } 381 | 382 | .markdown-body code:before, 383 | .markdown-body code:after { 384 | content: "\00a0"; 385 | letter-spacing: -0.2em; 386 | } 387 | 388 | .markdown-body pre > code { 389 | background: transparent; 390 | border: 0; 391 | font-size: 100%; 392 | margin: 0; 393 | padding: 0; 394 | white-space: pre; 395 | word-break: normal; 396 | } 397 | 398 | .markdown-body .highlight { margin-bottom: 16px; } 399 | 400 | .markdown-body .highlight pre, 401 | .markdown-body pre { 402 | background-color: #f7f7f7; 403 | border-radius: 3px; 404 | font-size: 85%; 405 | line-height: 1.45; 406 | overflow: auto; 407 | padding: 16px; 408 | } 409 | 410 | .markdown-body .highlight pre { 411 | margin-bottom: 0; 412 | word-break: normal; 413 | } 414 | 415 | .markdown-body pre { word-wrap: normal; } 416 | 417 | .markdown-body pre code { 418 | background-color: transparent; 419 | border: 0; 420 | display: inline; 421 | line-height: inherit; 422 | margin: 0; 423 | max-width: initial; 424 | overflow: initial; 425 | padding: 0; 426 | word-wrap: normal; 427 | } 428 | 429 | .markdown-body pre code:before, 430 | .markdown-body pre code:after { content: normal; } 431 | 432 | .markdown-body kbd { 433 | background-color: #fcfcfc; 434 | border: solid 1px #ccc; 435 | border-bottom-color: #bbb; 436 | border-radius: 3px; 437 | box-shadow: inset 0 -1px 0 #bbb; 438 | color: #555; 439 | display: inline-block; 440 | font-size: 11px; 441 | line-height: 10px; 442 | padding: 3px 5px; 443 | vertical-align: middle; 444 | } 445 | 446 | .markdown-body .pl-c { color: #969896; } 447 | 448 | .markdown-body .pl-c1, 449 | .markdown-body .pl-s .pl-v { color: #0086b3; } 450 | 451 | .markdown-body .pl-e, 452 | .markdown-body .pl-en { color: #795da3; } 453 | 454 | .markdown-body .pl-s .pl-s1, 455 | .markdown-body .pl-smi { color: #333; } 456 | 457 | .markdown-body .pl-ent { color: #63a35c; } 458 | 459 | .markdown-body .pl-k { color: #a71d5d; } 460 | 461 | .markdown-body .pl-pds, 462 | .markdown-body .pl-s, 463 | .markdown-body .pl-s .pl-pse .pl-s1, 464 | .markdown-body .pl-sr, 465 | .markdown-body .pl-sr .pl-cce, 466 | .markdown-body .pl-sr .pl-sra, 467 | .markdown-body .pl-sr .pl-sre { color: #183691; } 468 | 469 | .markdown-body .pl-v { color: #ed6a43; } 470 | 471 | .markdown-body .pl-id { color: #b52a1d; } 472 | 473 | .markdown-body .pl-ii { 474 | background-color: #b52a1d; 475 | color: #f8f8f8; 476 | } 477 | 478 | .markdown-body .pl-sr .pl-cce { 479 | color: #63a35c; 480 | font-weight: bold; 481 | } 482 | 483 | .markdown-body .pl-ml { color: #693a17; } 484 | 485 | .markdown-body .pl-mh, 486 | .markdown-body .pl-mh .pl-en, 487 | .markdown-body .pl-ms { 488 | color: #1d3e81; 489 | font-weight: bold; 490 | } 491 | 492 | .markdown-body .pl-mq { color: #008080; } 493 | 494 | .markdown-body .pl-mi { 495 | color: #333; 496 | font-style: italic; 497 | } 498 | 499 | .markdown-body .pl-mb { 500 | color: #333; 501 | font-weight: bold; 502 | } 503 | 504 | .markdown-body .pl-md { 505 | background-color: #ffecec; 506 | color: #bd2c00; 507 | } 508 | 509 | .markdown-body .pl-mi1 { 510 | background-color: #eaffea; 511 | color: #55a532; 512 | } 513 | 514 | .markdown-body .pl-mdr { 515 | color: #795da3; 516 | font-weight: bold; 517 | } 518 | 519 | .markdown-body .pl-mo { color: #1d3e81; } 520 | 521 | .markdown-body kbd { 522 | background-color: #fcfcfc; 523 | border: solid 1px #ccc; 524 | border-bottom-color: #bbb; 525 | border-radius: 3px; 526 | box-shadow: inset 0 -1px 0 #bbb; 527 | color: #555; 528 | display: inline-block; 529 | font: 11px Consolas, "Liberation Mono", Menlo, Courier, monospace; 530 | line-height: 10px; 531 | padding: 3px 5px; 532 | vertical-align: middle; 533 | } 534 | 535 | .markdown-body .full-commit .btn-outline:not(:disabled):hover { 536 | border: 1px solid #4078c0; 537 | color: #4078c0; 538 | } 539 | 540 | .markdown-body :checked + .radio-label { 541 | border-color: #4078c0; 542 | position: relative; 543 | z-index: 1; 544 | } 545 | 546 | .markdown-body .octicon { 547 | display: inline-block; 548 | fill: currentColor; 549 | vertical-align: text-top; 550 | } 551 | 552 | .markdown-body .task-list-item { list-style-type: none; } 553 | 554 | .markdown-body .task-list-item + .task-list-item { margin-top: 3px; } 555 | 556 | .markdown-body .task-list-item input { 557 | margin: 0 0.2em 0.25em -1.6em; 558 | vertical-align: middle; 559 | } 560 | 561 | .markdown-body hr { border-bottom-color: #eee; } -------------------------------------------------------------------------------- /src/Markdig.SyntaxHighlighting.Tests/IntegrationTests.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using Xunit; 7 | 8 | namespace Markdig.SyntaxHighlighting.Tests 9 | { 10 | public class IntegrationTests 11 | { 12 | 13 | [Fact] 14 | public void ShouldUseDefaultRendererIfLanguageIsNotIndicated() { 15 | string testString = @" 16 | # This is a test 17 | 18 | ``` 19 | { 20 | ""jsonProperty"": 1 21 | } 22 | ```"; 23 | var pipeline = new MarkdownPipelineBuilder() 24 | .UseAdvancedExtensions() 25 | .UseSyntaxHighlighting() 26 | .Build(); 27 | var html = Markdown.ToHtml(testString, pipeline); 28 | Assert.True(html.Contains("
"));
29 |             Assert.True(html.Contains("jsonProperty"));
30 |             Assert.False(html.Contains("lang-"));
31 |         }
32 | 
33 |         [Fact]
34 |         public void ShouldColorizeSyntaxWhenLanguageIsIndicated()
35 |         {
36 |             string testString = @"
37 | # This is a test
38 | 
39 | ```json
40 | {
41 |     ""jsonProperty"": 1
42 | }
43 | ```";
44 |             var pipeline = new MarkdownPipelineBuilder()
45 |                 .UseAdvancedExtensions()
46 |                 .UseSyntaxHighlighting()
47 |                 .Build();
48 |             var html = Markdown.ToHtml(testString, pipeline);
49 |             Assert.True(html.Contains("";
 6 | 
 7 |         [Theory]
 8 |         [InlineData("csharp", "c#", null)]
 9 |         [InlineData("cplusplus", "cpp", null)]
10 |         [InlineData("css", "css", null)]
11 |         [InlineData("aspx", "aspx(c#)", AspxCsFirstLine)]
12 |         [InlineData("javascript", "javascript", "var myVar = 1;")]
13 |         public void CanParse(string inputLanguage, string expectedId, string firstLine) {
14 |             var adapter = new LanguageTypeAdapter();
15 |             var result = adapter.Parse(inputLanguage, firstLine);
16 |             Assert.Equal(expectedId, result.Id);
17 |         }
18 | 
19 |         [Theory]
20 |         [InlineData(null)]
21 |         [InlineData("fubar")]
22 |         public void CanNotParse(string inputLanguage) {
23 |             var adapter = new LanguageTypeAdapter();
24 |             var result = adapter.Parse(inputLanguage);
25 |             Assert.Null(result);
26 |         }
27 |     }
28 | }


--------------------------------------------------------------------------------
/src/Markdig.SyntaxHighlighting.Tests/Markdig.SyntaxHighlighting.Tests.csproj:
--------------------------------------------------------------------------------
  1 | 
  2 | 
  3 |   
  4 |   
  5 |   
  6 |     Debug
  7 |     AnyCPU
  8 |     {B0696B7B-33C0-49B3-B8B2-DE07A7FCFBE9}
  9 |     Library
 10 |     Properties
 11 |     Markdig.SyntaxHighlighting.Tests
 12 |     Markdig.SyntaxHighlighting.Tests
 13 |     v4.6.1
 14 |     512
 15 |     
 16 |     
 17 |   
 18 |   
 19 |     true
 20 |     full
 21 |     false
 22 |     bin\Debug\
 23 |     DEBUG;TRACE
 24 |     prompt
 25 |     4
 26 |   
 27 |   
 28 |     pdbonly
 29 |     true
 30 |     bin\Release\
 31 |     TRACE
 32 |     prompt
 33 |     4
 34 |   
 35 |   
 36 |     
 37 |       ..\packages\Castle.Core.3.3.3\lib\net45\Castle.Core.dll
 38 |       True
 39 |     
 40 |     
 41 |       ..\packages\ColorCode.Portable.1.0.3\lib\portable45-net45+win8+wp8+wpa81\ColorCode.dll
 42 |       True
 43 |     
 44 |     
 45 |       ..\packages\Markdig.0.11.0\lib\net40\Markdig.dll
 46 |     
 47 |     
 48 |       ..\packages\Moq.4.5.16\lib\net45\Moq.dll
 49 |       True
 50 |     
 51 |     
 52 |     
 53 |     
 54 |     
 55 |     
 56 |     
 57 |     
 58 |     
 59 |     
 60 |       ..\packages\xunit.abstractions.2.0.0\lib\net35\xunit.abstractions.dll
 61 |       True
 62 |     
 63 |     
 64 |       ..\packages\xunit.assert.2.1.0\lib\dotnet\xunit.assert.dll
 65 |       True
 66 |     
 67 |     
 68 |       ..\packages\xunit.extensibility.core.2.1.0\lib\dotnet\xunit.core.dll
 69 |       True
 70 |     
 71 |     
 72 |       ..\packages\xunit.extensibility.execution.2.1.0\lib\net45\xunit.execution.desktop.dll
 73 |       True
 74 |     
 75 |   
 76 |   
 77 |     
 78 |     
 79 |     
 80 |     
 81 |     
 82 |     
 83 |       Properties\SharedAssemblyInfo.cs
 84 |     
 85 |     
 86 |   
 87 |   
 88 |     
 89 |       PreserveNewest
 90 |     
 91 |     
 92 |   
 93 |   
 94 |     
 95 |       {5d1e4e89-83a2-4b14-bb11-deb3c69665f0}
 96 |       Markdig.SyntaxHighlighting
 97 |     
 98 |   
 99 |   
100 |     
101 |       PreserveNewest
102 |     
103 |     
104 |       PreserveNewest
105 |     
106 |     
107 |       PreserveNewest
108 |     
109 |   
110 |   
111 |     
112 |   
113 |   
114 |   
115 |     
116 |       This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them.  For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.
117 |     
118 |     
119 |   
120 |   
127 | 


--------------------------------------------------------------------------------
/src/Markdig.SyntaxHighlighting.Tests/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.InteropServices;
3 | 
4 | [assembly: AssemblyTitle("Markdig.SyntaxHighlighting.Tests")]
5 | [assembly: AssemblyDescription("")]
6 | [assembly: Guid("b0696b7b-33c0-49b3-b8b2-de07a7fcfbe9")]


--------------------------------------------------------------------------------
/src/Markdig.SyntaxHighlighting.Tests/SyntaxHighlightingCodeBlockRendererTests.cs:
--------------------------------------------------------------------------------
  1 | using System.IO;
  2 | using System.Text;
  3 | using Markdig.Helpers;
  4 | using Markdig.Parsers;
  5 | using Markdig.Renderers;
  6 | using Markdig.Renderers.Html;
  7 | using Markdig.Syntax;
  8 | using Moq;
  9 | using Xunit;
 10 | 
 11 | namespace Markdig.SyntaxHighlighting.Tests {
 12 |     public class SyntaxHighlightingCodeBlockRendererTests {
 13 |         public string scriptBlock = @"```csharp
 14 | var desktop = Environment.SpecialFolder.DesktopDirectory;
 15 | ```";
 16 | 
 17 |         private static FencedCodeBlock GetFencedCodeBlock(string language = "language-csharp") {
 18 |             return new FencedCodeBlock(new FencedCodeBlockParser()) {
 19 |                 Info = language,
 20 |                 Lines = new StringLineGroup(3) {
 21 |                     new StringSlice("```csharp"),
 22 |                     new StringSlice("var desktop = Environment.SpecialFolder.DesktopDirectory;"),
 23 |                     new StringSlice("```")
 24 |                 }
 25 |             };
 26 |         }
 27 | 
 28 |         [Fact]
 29 |         public void ConstructorDoesNotThrow() {
 30 |             var renderer = new SyntaxHighlightingCodeBlockRenderer();
 31 |             Assert.NotNull(renderer);
 32 |         }
 33 | 
 34 |         [Fact]
 35 |         public void DivWritten() {
 36 |             var underlyingRendererMock = new Mock();
 37 |             underlyingRendererMock
 38 |                 .Setup(x => x.Write(It.IsAny(), It.IsAny()));
 39 |             var renderer = new SyntaxHighlightingCodeBlockRenderer(underlyingRendererMock.Object);
 40 |             var builder = new StringBuilder();
 41 |             var markdownRenderer = new HtmlRenderer(new StringWriter(builder));
 42 |             var codeBlock = GetFencedCodeBlock();
 43 |             renderer.Write(markdownRenderer, codeBlock);
 44 |             Assert.Contains("", builder.ToString());
 46 |         }
 47 | 
 48 |         [Fact]
 49 |         public void DivWrittenUnrecognisedLanguage()
 50 |         {
 51 |             var underlyingRendererMock = new Mock();
 52 |             underlyingRendererMock
 53 |                 .Setup(x => x.Write(It.IsAny(), It.IsAny()));
 54 |             var renderer = new SyntaxHighlightingCodeBlockRenderer(underlyingRendererMock.Object);
 55 |             var builder = new StringBuilder();
 56 |             var markdownRenderer = new HtmlRenderer(new StringWriter(builder));
 57 |             var codeBlock = GetFencedCodeBlock("language-made-up-language"); //
 58 |             renderer.Write(markdownRenderer, codeBlock);
 59 |             Assert.Contains("", builder.ToString());
 61 |         }
 62 | 
 63 |         [Fact]
 64 |         public void EditorColorsCssClassAdded() {
 65 |             var underlyingRendererMock = new Mock();
 66 |             underlyingRendererMock
 67 |                 .Setup(x => x.Write(It.IsAny(), It.IsAny()));
 68 |             var renderer = new SyntaxHighlightingCodeBlockRenderer(underlyingRendererMock.Object);
 69 |             var builder = new StringBuilder();
 70 |             var markdownRenderer = new HtmlRenderer(new StringWriter(builder));
 71 |             var codeBlock = GetFencedCodeBlock();
 72 |             renderer.Write(markdownRenderer, codeBlock);
 73 |             Assert.Contains("editor-colors", builder.ToString());
 74 |         }
 75 | 
 76 |         [Fact]
 77 |         public void LangCssClassAdded() {
 78 |             var underlyingRendererMock = new Mock();
 79 |             underlyingRendererMock
 80 |                 .Setup(x => x.Write(It.IsAny(), It.IsAny()));
 81 |             var renderer = new SyntaxHighlightingCodeBlockRenderer(underlyingRendererMock.Object);
 82 |             var builder = new StringBuilder();
 83 |             var markdownRenderer = new HtmlRenderer(new StringWriter(builder));
 84 |             var codeBlock = GetFencedCodeBlock();
 85 |             renderer.Write(markdownRenderer, codeBlock);
 86 |             Assert.Contains("lang-csharp", builder.ToString());
 87 |         }
 88 | 
 89 |         [Fact]
 90 |         public void UnderlyingRendererCalledIfNotFencedCodeBlock() {
 91 |             var underlyingRendererMock = new Mock();
 92 |             underlyingRendererMock
 93 |                 .Setup(x => x.Write(It.IsAny(), It.IsAny()))
 94 |                 .Verifiable("Write was not called on the underlying renderer mock.");
 95 |             var renderer = new SyntaxHighlightingCodeBlockRenderer(underlyingRendererMock.Object);
 96 |             var writer = new StringWriter();
 97 |             var markdownRenderer = new HtmlRenderer(writer);
 98 |             var codeBlock = new CodeBlock(new IndentedCodeBlockParser());
 99 |             renderer.Write(markdownRenderer, codeBlock);
100 |             underlyingRendererMock.VerifyAll();
101 |         }
102 | 
103 |         [Fact]
104 |         public void WritesOutCode() {
105 |             var underlyingRendererMock = new Mock();
106 |             underlyingRendererMock
107 |                 .Setup(x => x.Write(It.IsAny(), It.IsAny()));
108 |             var renderer = new SyntaxHighlightingCodeBlockRenderer(underlyingRendererMock.Object);
109 |             var builder = new StringBuilder();
110 |             var markdownRenderer = new HtmlRenderer(new StringWriter(builder));
111 |             var codeBlock = GetFencedCodeBlock();
112 |             renderer.Write(markdownRenderer, codeBlock);
113 |             Assert.Contains("var", builder.ToString());
114 |         }
115 | 
116 |         [Fact]
117 |         public void WritesOutColouredCode() {
118 |             var underlyingRendererMock = new Mock();
119 |             underlyingRendererMock
120 |                 .Setup(x => x.Write(It.IsAny(), It.IsAny()));
121 |             var renderer = new SyntaxHighlightingCodeBlockRenderer(underlyingRendererMock.Object);
122 |             var builder = new StringBuilder();
123 |             var markdownRenderer = new HtmlRenderer(new StringWriter(builder));
124 |             var codeBlock = GetFencedCodeBlock();
125 |             renderer.Write(markdownRenderer, codeBlock);
126 |             Assert.Contains("var", builder.ToString());
127 |         }
128 |     }
129 | }


--------------------------------------------------------------------------------
/src/Markdig.SyntaxHighlighting.Tests/SyntaxHighlightingExtensionsTests.cs:
--------------------------------------------------------------------------------
 1 | using System;
 2 | using System.IO;
 3 | using Markdig.Renderers;
 4 | using Markdig.Renderers.Html;
 5 | using Xunit;
 6 | 
 7 | namespace Markdig.SyntaxHighlighting.Tests {
 8 |     public class SyntaxHighlightingExtensionsTests {
 9 |         private class FakeRenderer : TextRendererBase {
10 |             public FakeRenderer(TextWriter writer) : base(writer) {}
11 |         }
12 | 
13 |         [Fact]
14 |         public void CodeBlockRendererReplaced() {
15 |             var extension = new SyntaxHighlightingExtension();
16 |             var writer = new StringWriter();
17 |             var markdownRenderer = new HtmlRenderer(writer);
18 | 
19 |             var oldRendererCount = markdownRenderer.ObjectRenderers.Count;
20 |             Assert.Equal(1,
21 |                 markdownRenderer.ObjectRenderers.FindAll(x => x.GetType() == typeof(CodeBlockRenderer)).Count);
22 |             extension.Setup(null, markdownRenderer);
23 |             Assert.Equal(0,
24 |                 markdownRenderer.ObjectRenderers.FindAll(x => x.GetType() == typeof(CodeBlockRenderer)).Count);
25 |             Assert.Equal(1,
26 |                 markdownRenderer.ObjectRenderers.FindAll(x => x.GetType() == typeof(SyntaxHighlightingCodeBlockRenderer))
27 |                     .Count);
28 |             Assert.Equal(oldRendererCount, markdownRenderer.ObjectRenderers.Count);
29 |         }
30 | 
31 |         [Fact]
32 |         public void DoesntThrowWhenSetupPipeline() {
33 |             var extension = new SyntaxHighlightingExtension();
34 |             extension.Setup(new MarkdownPipelineBuilder());
35 |         }
36 | 
37 |         [Fact]
38 |         public void PipelineChangedIfHtmlRenderer() {
39 |             var extension = new SyntaxHighlightingExtension();
40 |             var writer = new StringWriter();
41 |             var markdownRenderer = new HtmlRenderer(writer);
42 |             markdownRenderer.ObjectRenderers.RemoveAll(x => true);
43 |             extension.Setup(null, markdownRenderer);
44 |             Assert.Equal(1, markdownRenderer.ObjectRenderers.Count);
45 |         }
46 | 
47 |         [Fact]
48 |         public void PipelineChangedIfHtmlRendererUsingExtensionMethod() {
49 |             var pipelineBuilder = new MarkdownPipelineBuilder();
50 |             pipelineBuilder.UseSyntaxHighlighting();
51 |             var pipeline = pipelineBuilder.Build();
52 |             var writer = new StringWriter();
53 |             var markdownRenderer = new HtmlRenderer(writer);
54 |             pipeline.Setup(markdownRenderer);
55 |             var renderer = markdownRenderer.ObjectRenderers.FindExact();
56 |             Assert.NotNull(renderer);
57 |         }
58 | 
59 |         [Fact]
60 |         public void PipelineIntactIfNotHtmlRenderer() {
61 |             var extension = new SyntaxHighlightingExtension();
62 |             var writer = new StringWriter();
63 |             var markdownRenderer = new FakeRenderer(writer);
64 |             var oldRendererCount = markdownRenderer.ObjectRenderers.Count;
65 |             extension.Setup(null, markdownRenderer);
66 |             Assert.Equal(oldRendererCount, markdownRenderer.ObjectRenderers.Count);
67 |         }
68 | 
69 |         [Fact]
70 |         public void ThrowsIfRendererIsNull() {
71 |             var extension = new SyntaxHighlightingExtension();
72 |             var extensionSetup = new Action(() => extension.Setup(null, null));
73 |             Assert.Throws(extensionSetup);
74 |         }
75 |     }
76 | }


--------------------------------------------------------------------------------
/src/Markdig.SyntaxHighlighting.Tests/packages.config:
--------------------------------------------------------------------------------
 1 | 
 2 | 
 3 |   
 4 |   
 5 |   
 6 |   
 7 |   
 8 |   
 9 |   
10 |   
11 |   
12 |   
13 |   
14 | 


--------------------------------------------------------------------------------
/src/Markdig.SyntaxHighlighting.sln:
--------------------------------------------------------------------------------
 1 | 
 2 | Microsoft Visual Studio Solution File, Format Version 12.00
 3 | # Visual Studio 14
 4 | VisualStudioVersion = 14.0.25420.1
 5 | MinimumVisualStudioVersion = 10.0.40219.1
 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Markdig.SyntaxHighlighting.Tests", "Markdig.SyntaxHighlighting.Tests\Markdig.SyntaxHighlighting.Tests.csproj", "{B0696B7B-33C0-49B3-B8B2-DE07A7FCFBE9}"
 7 | EndProject
 8 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Markdig.SyntaxHighlighting", "Markdig.SyntaxHighlighting\Markdig.SyntaxHighlighting.csproj", "{5D1E4E89-83A2-4B14-BB11-DEB3C69665F0}"
 9 | EndProject
10 | Global
11 | 	GlobalSection(SolutionConfigurationPlatforms) = preSolution
12 | 		Debug|Any CPU = Debug|Any CPU
13 | 		Release|Any CPU = Release|Any CPU
14 | 	EndGlobalSection
15 | 	GlobalSection(ProjectConfigurationPlatforms) = postSolution
16 | 		{B0696B7B-33C0-49B3-B8B2-DE07A7FCFBE9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
17 | 		{B0696B7B-33C0-49B3-B8B2-DE07A7FCFBE9}.Debug|Any CPU.Build.0 = Debug|Any CPU
18 | 		{B0696B7B-33C0-49B3-B8B2-DE07A7FCFBE9}.Release|Any CPU.ActiveCfg = Release|Any CPU
19 | 		{B0696B7B-33C0-49B3-B8B2-DE07A7FCFBE9}.Release|Any CPU.Build.0 = Release|Any CPU
20 | 		{5D1E4E89-83A2-4B14-BB11-DEB3C69665F0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
21 | 		{5D1E4E89-83A2-4B14-BB11-DEB3C69665F0}.Debug|Any CPU.Build.0 = Debug|Any CPU
22 | 		{5D1E4E89-83A2-4B14-BB11-DEB3C69665F0}.Release|Any CPU.ActiveCfg = Release|Any CPU
23 | 		{5D1E4E89-83A2-4B14-BB11-DEB3C69665F0}.Release|Any CPU.Build.0 = Release|Any CPU
24 | 	EndGlobalSection
25 | 	GlobalSection(SolutionProperties) = preSolution
26 | 		HideSolutionNode = FALSE
27 | 	EndGlobalSection
28 | EndGlobal
29 | 


--------------------------------------------------------------------------------
/src/Markdig.SyntaxHighlighting.sln.DotSettings:
--------------------------------------------------------------------------------
 1 | 
 2 | 	END_OF_LINE
 3 | 	END_OF_LINE
 4 | 	END_OF_LINE
 5 | 	END_OF_LINE
 6 | 	END_OF_LINE
 7 | 	END_OF_LINE
 8 | 	END_OF_LINE
 9 | 	END_OF_LINE
10 | 	TOGETHER_SAME_LINE
11 | 	ALWAYS_ADD
12 | 	ALWAYS_ADD
13 | 	ALWAYS_ADD
14 | 	ALWAYS_ADD
15 | 	ALWAYS_ADD
16 | 	ALWAYS_ADD
17 | 	1
18 | 	1
19 | 	False
20 | 	False
21 | 	False
22 | 	True
23 | 	SEPARATE_LINES_FOR_NONSINGLE
24 | 	ALWAYS_ADD
25 | 	True
26 | 	SingleQuoted
27 | 	<Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" />
28 | 	<Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" />
29 | 	<Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" />
30 | 	<Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" />
31 | 	<Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" />
32 | 	<Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" />
33 | 	<Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" />
34 | 	<Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" />
35 | 	<Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" />
36 | 	<Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" />
37 | 	<Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" />
38 | 	<Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" />
39 | 	<Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" />
40 | 	<Policy Inspect="True" Prefix="I" Suffix="" Style="AaBb" />
41 | 	<Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" />
42 | 	<Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" />
43 | 	<Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" />
44 | 	<Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" />
45 | 	<Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" />
46 | 	<Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" />
47 | 	<Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" />
48 | 	<Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" />
49 | 	<Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" />
50 | 	<Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" />
51 | 	<Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" />
52 | 	<Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" />
53 | 	<Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" />
54 | 	<Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" />
55 | 	<Policy Inspect="True" Prefix="T" Suffix="" Style="AaBb" />
56 | 	<Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" />
57 | 	<Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" />
58 | 	<Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" />
59 | 	<Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" />
60 | 	<Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" />
61 | 	<Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" />
62 | 	<Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" />
63 | 	©$CURRENT_YEAR$ Amido Limited (https://www.amido.com), Licensed under the terms of the Apache 2.0 Licence (http://www.apache.org/licenses/LICENSE-2.0)
64 | 	<?xml version="1.0" encoding="utf-16"?><Profile name="General Cleanup"><CSReorderTypeMembers>True</CSReorderTypeMembers><CSUpdateFileHeader>True</CSUpdateFileHeader><RemoveCodeRedundancies>True</RemoveCodeRedundancies><CSUseAutoProperty>True</CSUseAutoProperty><CSMakeFieldReadonly>True</CSMakeFieldReadonly><CSMakeAutoPropertyGetOnly>True</CSMakeAutoPropertyGetOnly><CSArrangeQualifiers>True</CSArrangeQualifiers><CSFixBuiltinTypeReferences>True</CSFixBuiltinTypeReferences><CSEnforceVarKeywordUsageSettings>True</CSEnforceVarKeywordUsageSettings><CSOptimizeUsings><OptimizeUsings>True</OptimizeUsings><EmbraceInRegion>False</EmbraceInRegion><RegionName></RegionName></CSOptimizeUsings><CSShortenReferences>True</CSShortenReferences><CSReformatCode>True</CSReformatCode><CSharpFormatDocComments>True</CSharpFormatDocComments><AspOptimizeRegisterDirectives>True</AspOptimizeRegisterDirectives><HtmlReformatCode>True</HtmlReformatCode><FormatAttributeQuoteDescriptor>True</FormatAttributeQuoteDescriptor><JsInsertSemicolon>True</JsInsertSemicolon><CorrectVariableKindsDescriptor>True</CorrectVariableKindsDescriptor><VariablesToInnerScopesDescriptor>True</VariablesToInnerScopesDescriptor><StringToTemplatesDescriptor>True</StringToTemplatesDescriptor><JsReformatCode>True</JsReformatCode><JsFormatDocComments>True</JsFormatDocComments><CssAlphabetizeProperties>True</CssAlphabetizeProperties><CssReformatCode>True</CssReformatCode><VBShortenReferences>True</VBShortenReferences><VBOptimizeImports>True</VBOptimizeImports><VBReformatCode>True</VBReformatCode><VBFormatDocComments>True</VBFormatDocComments></Profile>
65 | 	C42+,FF38+,IE10+,O28+,S6+
66 | 	True
67 | 	True
68 | 	True
69 | 	True
70 | 	True
71 | 	<data><IncludeFilters /><ExcludeFilters><Filter ModuleMask="Markdig.SyntaxHighlighting.Tests" ModuleVersionMask="*" ClassMask="*" FunctionMask="*" IsEnabled="True" /></ExcludeFilters></data>


--------------------------------------------------------------------------------
/src/Markdig.SyntaxHighlighting/LanguageTypeAdapter.cs:
--------------------------------------------------------------------------------
 1 | using System.Collections.Generic;
 2 | using System.Text.RegularExpressions;
 3 | using ColorCode;
 4 | 
 5 | namespace Markdig.SyntaxHighlighting {
 6 |     public class LanguageTypeAdapter {
 7 |         private readonly Dictionary languageMap = new Dictionary {
 8 |             {"csharp", Languages.CSharp},
 9 |             {"cplusplus", Languages.Cpp}
10 |         };
11 | 
12 |         public ILanguage Parse(string id, string firstLine = null) {
13 |             if (id == null) {
14 |                 return null;
15 |             }
16 | 
17 |             if (languageMap.ContainsKey(id)) {
18 |                 return languageMap[id];
19 |             }
20 | 
21 |             if (!string.IsNullOrWhiteSpace(firstLine)) {
22 |                 foreach (var lang in Languages.All) {
23 |                     if (lang.FirstLinePattern == null) {
24 |                         continue;
25 |                     }
26 | 
27 |                     var firstLineMatcher = new Regex(lang.FirstLinePattern, RegexOptions.IgnoreCase);
28 | 
29 |                     if (firstLineMatcher.IsMatch(firstLine)) {
30 |                         return lang;
31 |                     }
32 |                 }
33 |             }
34 | 
35 |             var byIdCanidate = Languages.FindById(id);
36 | 
37 |             return byIdCanidate;
38 |         }
39 |     }
40 | }


--------------------------------------------------------------------------------
/src/Markdig.SyntaxHighlighting/Markdig.SyntaxHighlighting.csproj:
--------------------------------------------------------------------------------
 1 | 
 2 | 
 3 |   
 4 |   
 5 |     10.0
 6 |     Debug
 7 |     AnyCPU
 8 |     {5D1E4E89-83A2-4B14-BB11-DEB3C69665F0}
 9 |     Library
10 |     Properties
11 |     Markdig.SyntaxHighlighting
12 |     Markdig.SyntaxHighlighting
13 |     en-US
14 |     512
15 |     {786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}
16 |     Profile259
17 |     v4.5
18 |   
19 |   
20 |     true
21 |     full
22 |     false
23 |     bin\Debug\
24 |     DEBUG;TRACE
25 |     prompt
26 |     4
27 |   
28 |   
29 |     pdbonly
30 |     true
31 |     bin\Release\
32 |     TRACE
33 |     prompt
34 |     4
35 |   
36 |   
37 |     
38 |     
39 |     
40 |       Properties\SharedAssemblyInfo.cs
41 |     
42 |     
43 |     
44 |     
45 |   
46 |   
47 |     
48 |       ..\packages\ColorCode.Portable.1.0.3\lib\portable45-net45+win8+wp8+wpa81\ColorCode.dll
49 |       True
50 |     
51 |     
52 |       ..\packages\Markdig.0.11.0\lib\portable40-net40+sl5+win8+wp8+wpa81\Markdig.dll
53 |     
54 |   
55 |   
56 |     
57 |   
58 |   
59 |   
66 | 


--------------------------------------------------------------------------------
/src/Markdig.SyntaxHighlighting/Markdig.SyntaxHighlighting.nuspec:
--------------------------------------------------------------------------------
 1 | 
 2 | 
 3 |   
 4 |     $id$
 5 |     $version$
 6 |     $title$
 7 |     $author$
 8 |     $author$
 9 |     https://github.com/RichardSlater/Markdig.SyntaxHighlighting/blob/master/LICENSE.md
10 |     https://github.com/RichardSlater/Markdig.SyntaxHighlighting/
11 |     https://cdn.rawgit.com/RichardSlater/Markdig.SyntaxHighlighting/56be978d313c4199396ca1ac0b1407d2c1cb7dfa/assets/icon.png
12 |     false
13 |     Syntax Highlighting for Markdig.
14 |     Initial Version.
15 |     Copyright 2016 Richard Slater
16 |     markdown code syntax highlighting
17 |   
18 | 
19 | 


--------------------------------------------------------------------------------
/src/Markdig.SyntaxHighlighting/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Resources;
3 | 
4 | [assembly: AssemblyTitle("Markdig.SyntaxHighlighting")]
5 | [assembly: AssemblyDescription("")]
6 | [assembly: NeutralResourcesLanguage("en")]


--------------------------------------------------------------------------------
/src/Markdig.SyntaxHighlighting/SyntaxHighlightingCodeBlockRenderer.cs:
--------------------------------------------------------------------------------
 1 | using System.IO;
 2 | using System.Text;
 3 | using ColorCode;
 4 | using Markdig.Parsers;
 5 | using Markdig.Renderers;
 6 | using Markdig.Renderers.Html;
 7 | using Markdig.Syntax;
 8 | 
 9 | namespace Markdig.SyntaxHighlighting {
10 |     public class SyntaxHighlightingCodeBlockRenderer : HtmlObjectRenderer {
11 |         private readonly CodeBlockRenderer _underlyingRenderer;
12 |         private readonly IStyleSheet _customCss;
13 | 
14 |         public SyntaxHighlightingCodeBlockRenderer(CodeBlockRenderer underlyingRenderer = null, IStyleSheet customCss = null) {
15 |             _underlyingRenderer = underlyingRenderer ?? new CodeBlockRenderer();
16 |             _customCss = customCss;
17 |         }
18 | 
19 |         protected override void Write(HtmlRenderer renderer, CodeBlock obj) {
20 |             var fencedCodeBlock = obj as FencedCodeBlock;
21 |             var parser = obj.Parser as FencedCodeBlockParser;
22 |             if (fencedCodeBlock == null || parser == null) {
23 |                 _underlyingRenderer.Write(renderer, obj);
24 |                 return;
25 |             }
26 | 
27 |             var attributes = obj.TryGetAttributes() ?? new HtmlAttributes();
28 | 
29 |             var languageMoniker = fencedCodeBlock.Info.Replace(parser.InfoPrefix, string.Empty);
30 |             if (string.IsNullOrEmpty(languageMoniker)) {
31 |                 _underlyingRenderer.Write(renderer, obj);
32 |                 return;
33 |             }
34 | 
35 |             attributes.AddClass($"lang-{languageMoniker}");
36 |             attributes.Classes.Remove($"language-{languageMoniker}");
37 | 
38 |             attributes.AddClass("editor-colors");
39 | 
40 |             string firstLine;
41 |             var code = GetCode(obj, out firstLine);
42 | 
43 |             renderer
44 |                 .Write("");
47 | 
48 |             var markup = ApplySyntaxHighlighting(languageMoniker, firstLine, code);
49 | 
50 |             renderer.WriteLine(markup);
51 |             renderer.WriteLine("");
52 |         }
53 | 
54 |         private string ApplySyntaxHighlighting(string languageMoniker, string firstLine, string code) {
55 |             var languageTypeAdapter = new LanguageTypeAdapter();
56 |             var language = languageTypeAdapter.Parse(languageMoniker, firstLine);
57 | 
58 |             if (language == null) { //handle unrecognised language formats, e.g. when using mermaid diagrams
59 |                 return code;
60 |             }
61 | 
62 |             var codeBuilder = new StringBuilder();
63 |             var codeWriter = new StringWriter(codeBuilder);
64 |             var styleSheet = _customCss ?? StyleSheets.Default;
65 |             var colourizer = new CodeColorizer();
66 |             colourizer.Colorize(code, language, Formatters.Default, styleSheet, codeWriter);
67 |             return codeBuilder.ToString();
68 |         }
69 | 
70 |         private static string GetCode(LeafBlock obj, out string firstLine) {
71 |             var code = new StringBuilder();
72 |             firstLine = null;
73 |             foreach (var line in obj.Lines.Lines) {
74 |                 var slice = line.Slice;
75 |                 if (slice.Text == null) {
76 |                     continue;
77 |                 }
78 | 
79 |                 var lineText = slice.Text.Substring(slice.Start, slice.Length);
80 | 
81 |                 if (firstLine == null) {
82 |                     firstLine = lineText;
83 |                 } else {
84 |                     code.AppendLine();
85 |                 }
86 | 
87 |                 code.Append(lineText);
88 |             }
89 |             return code.ToString();
90 |         }
91 |     }
92 | }
93 | 


--------------------------------------------------------------------------------
/src/Markdig.SyntaxHighlighting/SyntaxHighlightingExtension.cs:
--------------------------------------------------------------------------------
 1 | using System;
 2 | using ColorCode;
 3 | using Markdig.Renderers;
 4 | using Markdig.Renderers.Html;
 5 | 
 6 | namespace Markdig.SyntaxHighlighting {
 7 |     public class SyntaxHighlightingExtension : IMarkdownExtension {
 8 |         private readonly IStyleSheet _customCss;
 9 | 
10 |         public SyntaxHighlightingExtension(IStyleSheet customCss = null)
11 |         {
12 |             _customCss = customCss;
13 |         }
14 | 
15 |         public void Setup(MarkdownPipelineBuilder pipeline) {}
16 | 
17 |         public void Setup(MarkdownPipeline pipeline, IMarkdownRenderer renderer) {
18 |             if (renderer == null) {
19 |                 throw new ArgumentNullException(nameof(renderer));
20 |             }
21 | 
22 |             var htmlRenderer = renderer as TextRendererBase;
23 |             if (htmlRenderer == null) {
24 |                 return;
25 |             }
26 | 
27 |             var originalCodeBlockRenderer = htmlRenderer.ObjectRenderers.FindExact();
28 |             if (originalCodeBlockRenderer != null) {
29 |                 htmlRenderer.ObjectRenderers.Remove(originalCodeBlockRenderer);
30 |             }
31 | 
32 |             htmlRenderer.ObjectRenderers.AddIfNotAlready(
33 |                 new SyntaxHighlightingCodeBlockRenderer(originalCodeBlockRenderer, _customCss));
34 |         }
35 |     }
36 | }
37 | 


--------------------------------------------------------------------------------
/src/Markdig.SyntaxHighlighting/SyntaxHighlightingExtensions.cs:
--------------------------------------------------------------------------------
 1 | using ColorCode;
 2 | 
 3 | namespace Markdig.SyntaxHighlighting {
 4 |     public static class SyntaxHighlightingExtensions {
 5 |         public static MarkdownPipelineBuilder UseSyntaxHighlighting(this MarkdownPipelineBuilder pipeline, IStyleSheet customCss = null) {
 6 |             pipeline.Extensions.Add(new SyntaxHighlightingExtension(customCss));
 7 |             return pipeline;
 8 |         }
 9 |     }
10 | }
11 | 


--------------------------------------------------------------------------------
/src/Markdig.SyntaxHighlighting/packages.config:
--------------------------------------------------------------------------------
1 | 
2 | 
3 |   
4 |   
5 | 


--------------------------------------------------------------------------------
/src/SharedAssemblyInfo.cs:
--------------------------------------------------------------------------------
 1 | using System.Reflection;
 2 | using System.Runtime.InteropServices;
 3 | 
 4 | // General Information about an assembly is controlled through the following
 5 | // set of attributes. Change these attribute values to modify the information
 6 | // associated with an assembly.
 7 | 
 8 | [assembly: AssemblyConfiguration("debug")]
 9 | [assembly: AssemblyCompany("Amido Limited")]
10 | [assembly: AssemblyProduct("Markdig.SyntaxHighlighting")]
11 | [assembly: AssemblyCopyright("©2017 Amido Limited, All Rights Reserved")]
12 | [assembly: AssemblyTrademark("")]
13 | [assembly: AssemblyCulture("")]
14 | 
15 | // Setting ComVisible to false makes the types in this assembly not visible
16 | // to COM components.  If you need to access a type in this assembly from
17 | // COM, set the ComVisible attribute to true on that type.
18 | 
19 | [assembly: ComVisible(false)]
20 | 
21 | // Version information for an assembly consists of the following four values:
22 | //
23 | //      Major Version
24 | //      Minor Version
25 | //      Build Number
26 | //      Revision
27 | //
28 | // You can specify all the values or you can default the Build and Revision Numbers
29 | // by using the '*' as shown below:
30 | // [assembly: AssemblyVersion("1.0.*")]
31 | 
32 | [assembly: AssemblyVersion("0.0.1.0")]
33 | [assembly: AssemblyInformationalVersion("0.0.1")]
34 | [assembly: AssemblyFileVersion("0.0.1.0")]


--------------------------------------------------------------------------------