mirror of
https://github.com/PowerShell/PowerShell
synced 2026-06-08 12:12:50 +00:00
Added Markdown rendering cmdlets (#6926)
- `ConvertFrom-Markdown` is used for converting a markdown document or string to a MarkdownInfo object. It can optionally return an HTML or a VT100 encoded string in addition to an AST of the markdown document. - `Show-Markdown` is used to either display the VT100 encoded string on the console or redirect the HTML string to the browser. - `Set/Get-MarkdownOption` cmdlets are used to view or set markdown rendering options.
This commit is contained in:
+60
-60
@@ -1,7 +1,6 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio 15
|
||||
# https://github.com/dotnet/project-system/blob/master/docs/opening-with-new-project-system.md#project-type-guids
|
||||
VisualStudioVersion = 15.0.26730.12
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "powershell-win-core", "src\powershell-win-core\powershell-win-core.csproj", "{8359D422-E0C4-4A0D-94EB-3C9DD16B7932}"
|
||||
@@ -30,15 +29,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.WSMan.Runtime", "
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "powershell-unix", "src\powershell-unix\powershell-unix.csproj", "{73EA0BE6-C0C5-4B56-A5AA-DADA4C01D690}"
|
||||
EndProject
|
||||
# Configuration mapping comment
|
||||
# All global configurations must be mapped to project configurations
|
||||
#
|
||||
# 4BC19063-1F66-467B-87DE-80449C72BCD6 - Microsoft.PowerShell.SDK
|
||||
# 8359D422-E0C4-4A0D-94EB-3C9DD16B7932 - PowerShell-Win
|
||||
# Linux is invalid and mapped to Release
|
||||
#
|
||||
# 73EA0BE6-C0C5-4B56-A5AA-DADA4C01D690 - powershell-unix
|
||||
# Only Linux is valid, all configurations mapped to Linux
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.PowerShell.MarkdownRender", "src\Microsoft.PowerShell.MarkdownRender\Microsoft.PowerShell.MarkdownRender.csproj", "{43D4F8DA-A7DE-494B-81B0-BDE3CFD7B1F1}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
CodeCoverage|Any CPU = CodeCoverage|Any CPU
|
||||
@@ -47,52 +39,52 @@ Global
|
||||
Release|Any CPU = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{8359D422-E0C4-4A0D-94EB-3C9DD16B7932}.CodeCoverage|Any CPU.ActiveCfg = CodeCoverage|Any CPU
|
||||
{8359D422-E0C4-4A0D-94EB-3C9DD16B7932}.CodeCoverage|Any CPU.Build.0 = CodeCoverage|Any CPU
|
||||
{8359D422-E0C4-4A0D-94EB-3C9DD16B7932}.CodeCoverage|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{8359D422-E0C4-4A0D-94EB-3C9DD16B7932}.CodeCoverage|Any CPU.Build.0 = Release|Any CPU
|
||||
{8359D422-E0C4-4A0D-94EB-3C9DD16B7932}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{8359D422-E0C4-4A0D-94EB-3C9DD16B7932}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{8359D422-E0C4-4A0D-94EB-3C9DD16B7932}.Linux|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{8359D422-E0C4-4A0D-94EB-3C9DD16B7932}.Linux|Any CPU.Build.0 = Release|Any CPU
|
||||
{8359D422-E0C4-4A0D-94EB-3C9DD16B7932}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{8359D422-E0C4-4A0D-94EB-3C9DD16B7932}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{AF660EE7-0183-4B79-A93F-221B6AC1C24B}.CodeCoverage|Any CPU.ActiveCfg = CodeCoverage|Any CPU
|
||||
{AF660EE7-0183-4B79-A93F-221B6AC1C24B}.CodeCoverage|Any CPU.Build.0 = CodeCoverage|Any CPU
|
||||
{AF660EE7-0183-4B79-A93F-221B6AC1C24B}.CodeCoverage|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{AF660EE7-0183-4B79-A93F-221B6AC1C24B}.CodeCoverage|Any CPU.Build.0 = Release|Any CPU
|
||||
{AF660EE7-0183-4B79-A93F-221B6AC1C24B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{AF660EE7-0183-4B79-A93F-221B6AC1C24B}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{AF660EE7-0183-4B79-A93F-221B6AC1C24B}.Linux|Any CPU.ActiveCfg = Linux|Any CPU
|
||||
{AF660EE7-0183-4B79-A93F-221B6AC1C24B}.Linux|Any CPU.Build.0 = Linux|Any CPU
|
||||
{AF660EE7-0183-4B79-A93F-221B6AC1C24B}.Linux|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{AF660EE7-0183-4B79-A93F-221B6AC1C24B}.Linux|Any CPU.Build.0 = Release|Any CPU
|
||||
{AF660EE7-0183-4B79-A93F-221B6AC1C24B}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{AF660EE7-0183-4B79-A93F-221B6AC1C24B}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{EAB203E1-2A68-4166-BE54-5C44DE825229}.CodeCoverage|Any CPU.ActiveCfg = CodeCoverage|Any CPU
|
||||
{EAB203E1-2A68-4166-BE54-5C44DE825229}.CodeCoverage|Any CPU.Build.0 = CodeCoverage|Any CPU
|
||||
{EAB203E1-2A68-4166-BE54-5C44DE825229}.CodeCoverage|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{EAB203E1-2A68-4166-BE54-5C44DE825229}.CodeCoverage|Any CPU.Build.0 = Release|Any CPU
|
||||
{EAB203E1-2A68-4166-BE54-5C44DE825229}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{EAB203E1-2A68-4166-BE54-5C44DE825229}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{EAB203E1-2A68-4166-BE54-5C44DE825229}.Linux|Any CPU.ActiveCfg = Linux|Any CPU
|
||||
{EAB203E1-2A68-4166-BE54-5C44DE825229}.Linux|Any CPU.Build.0 = Linux|Any CPU
|
||||
{EAB203E1-2A68-4166-BE54-5C44DE825229}.Linux|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{EAB203E1-2A68-4166-BE54-5C44DE825229}.Linux|Any CPU.Build.0 = Release|Any CPU
|
||||
{EAB203E1-2A68-4166-BE54-5C44DE825229}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{EAB203E1-2A68-4166-BE54-5C44DE825229}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{981D3972-343D-4E17-935B-037E1C622771}.CodeCoverage|Any CPU.ActiveCfg = CodeCoverage|Any CPU
|
||||
{981D3972-343D-4E17-935B-037E1C622771}.CodeCoverage|Any CPU.Build.0 = CodeCoverage|Any CPU
|
||||
{981D3972-343D-4E17-935B-037E1C622771}.CodeCoverage|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{981D3972-343D-4E17-935B-037E1C622771}.CodeCoverage|Any CPU.Build.0 = Release|Any CPU
|
||||
{981D3972-343D-4E17-935B-037E1C622771}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{981D3972-343D-4E17-935B-037E1C622771}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{981D3972-343D-4E17-935B-037E1C622771}.Linux|Any CPU.ActiveCfg = Linux|Any CPU
|
||||
{981D3972-343D-4E17-935B-037E1C622771}.Linux|Any CPU.Build.0 = Linux|Any CPU
|
||||
{981D3972-343D-4E17-935B-037E1C622771}.Linux|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{981D3972-343D-4E17-935B-037E1C622771}.Linux|Any CPU.Build.0 = Release|Any CPU
|
||||
{981D3972-343D-4E17-935B-037E1C622771}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{981D3972-343D-4E17-935B-037E1C622771}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{8FFE645D-F0C9-4220-9A88-83062ED211D2}.CodeCoverage|Any CPU.ActiveCfg = CodeCoverage|Any CPU
|
||||
{8FFE645D-F0C9-4220-9A88-83062ED211D2}.CodeCoverage|Any CPU.Build.0 = CodeCoverage|Any CPU
|
||||
{8FFE645D-F0C9-4220-9A88-83062ED211D2}.CodeCoverage|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{8FFE645D-F0C9-4220-9A88-83062ED211D2}.CodeCoverage|Any CPU.Build.0 = Release|Any CPU
|
||||
{8FFE645D-F0C9-4220-9A88-83062ED211D2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{8FFE645D-F0C9-4220-9A88-83062ED211D2}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{8FFE645D-F0C9-4220-9A88-83062ED211D2}.Linux|Any CPU.ActiveCfg = Linux|Any CPU
|
||||
{8FFE645D-F0C9-4220-9A88-83062ED211D2}.Linux|Any CPU.Build.0 = Linux|Any CPU
|
||||
{8FFE645D-F0C9-4220-9A88-83062ED211D2}.Linux|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{8FFE645D-F0C9-4220-9A88-83062ED211D2}.Linux|Any CPU.Build.0 = Release|Any CPU
|
||||
{8FFE645D-F0C9-4220-9A88-83062ED211D2}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{8FFE645D-F0C9-4220-9A88-83062ED211D2}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{FCE53A5E-5FAC-48BE-BAD8-2110040B5C2E}.CodeCoverage|Any CPU.ActiveCfg = CodeCoverage|Any CPU
|
||||
{FCE53A5E-5FAC-48BE-BAD8-2110040B5C2E}.CodeCoverage|Any CPU.Build.0 = CodeCoverage|Any CPU
|
||||
{FCE53A5E-5FAC-48BE-BAD8-2110040B5C2E}.CodeCoverage|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{FCE53A5E-5FAC-48BE-BAD8-2110040B5C2E}.CodeCoverage|Any CPU.Build.0 = Release|Any CPU
|
||||
{FCE53A5E-5FAC-48BE-BAD8-2110040B5C2E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{FCE53A5E-5FAC-48BE-BAD8-2110040B5C2E}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{FCE53A5E-5FAC-48BE-BAD8-2110040B5C2E}.Linux|Any CPU.ActiveCfg = Linux|Any CPU
|
||||
{FCE53A5E-5FAC-48BE-BAD8-2110040B5C2E}.Linux|Any CPU.Build.0 = Linux|Any CPU
|
||||
{FCE53A5E-5FAC-48BE-BAD8-2110040B5C2E}.Linux|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{FCE53A5E-5FAC-48BE-BAD8-2110040B5C2E}.Linux|Any CPU.Build.0 = Release|Any CPU
|
||||
{FCE53A5E-5FAC-48BE-BAD8-2110040B5C2E}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{FCE53A5E-5FAC-48BE-BAD8-2110040B5C2E}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{4BC19063-1F66-467B-87DE-80449C72BCD6}.CodeCoverage|Any CPU.ActiveCfg = Release|Any CPU
|
||||
@@ -111,54 +103,62 @@ Global
|
||||
{131A8527-92D7-468F-822D-5354229A865C}.Linux|Any CPU.Build.0 = Release|Any CPU
|
||||
{131A8527-92D7-468F-822D-5354229A865C}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{131A8527-92D7-468F-822D-5354229A865C}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{439A24FC-8E0A-48B6-8227-44C297311F49}.CodeCoverage|Any CPU.ActiveCfg = CodeCoverage|Any CPU
|
||||
{439A24FC-8E0A-48B6-8227-44C297311F49}.CodeCoverage|Any CPU.Build.0 = CodeCoverage|Any CPU
|
||||
{439A24FC-8E0A-48B6-8227-44C297311F49}.CodeCoverage|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{439A24FC-8E0A-48B6-8227-44C297311F49}.CodeCoverage|Any CPU.Build.0 = Release|Any CPU
|
||||
{439A24FC-8E0A-48B6-8227-44C297311F49}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{439A24FC-8E0A-48B6-8227-44C297311F49}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{439A24FC-8E0A-48B6-8227-44C297311F49}.Linux|Any CPU.ActiveCfg = Linux|Any CPU
|
||||
{439A24FC-8E0A-48B6-8227-44C297311F49}.Linux|Any CPU.Build.0 = Linux|Any CPU
|
||||
{439A24FC-8E0A-48B6-8227-44C297311F49}.Linux|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{439A24FC-8E0A-48B6-8227-44C297311F49}.Linux|Any CPU.Build.0 = Release|Any CPU
|
||||
{439A24FC-8E0A-48B6-8227-44C297311F49}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{439A24FC-8E0A-48B6-8227-44C297311F49}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{07BFD271-8992-4F34-9091-6CFC3E224A24}.CodeCoverage|Any CPU.ActiveCfg = CodeCoverage|Any CPU
|
||||
{07BFD271-8992-4F34-9091-6CFC3E224A24}.CodeCoverage|Any CPU.Build.0 = CodeCoverage|Any CPU
|
||||
{07BFD271-8992-4F34-9091-6CFC3E224A24}.CodeCoverage|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{07BFD271-8992-4F34-9091-6CFC3E224A24}.CodeCoverage|Any CPU.Build.0 = Release|Any CPU
|
||||
{07BFD271-8992-4F34-9091-6CFC3E224A24}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{07BFD271-8992-4F34-9091-6CFC3E224A24}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{07BFD271-8992-4F34-9091-6CFC3E224A24}.Linux|Any CPU.ActiveCfg = Linux|Any CPU
|
||||
{07BFD271-8992-4F34-9091-6CFC3E224A24}.Linux|Any CPU.Build.0 = Linux|Any CPU
|
||||
{07BFD271-8992-4F34-9091-6CFC3E224A24}.Linux|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{07BFD271-8992-4F34-9091-6CFC3E224A24}.Linux|Any CPU.Build.0 = Release|Any CPU
|
||||
{07BFD271-8992-4F34-9091-6CFC3E224A24}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{07BFD271-8992-4F34-9091-6CFC3E224A24}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{8F63D134-E413-4181-936D-D82F3F5F1D85}.CodeCoverage|Any CPU.ActiveCfg = CodeCoverage|Any CPU
|
||||
{8F63D134-E413-4181-936D-D82F3F5F1D85}.CodeCoverage|Any CPU.Build.0 = CodeCoverage|Any CPU
|
||||
{8F63D134-E413-4181-936D-D82F3F5F1D85}.CodeCoverage|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{8F63D134-E413-4181-936D-D82F3F5F1D85}.CodeCoverage|Any CPU.Build.0 = Release|Any CPU
|
||||
{8F63D134-E413-4181-936D-D82F3F5F1D85}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{8F63D134-E413-4181-936D-D82F3F5F1D85}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{8F63D134-E413-4181-936D-D82F3F5F1D85}.Linux|Any CPU.ActiveCfg = Linux|Any CPU
|
||||
{8F63D134-E413-4181-936D-D82F3F5F1D85}.Linux|Any CPU.Build.0 = Linux|Any CPU
|
||||
{8F63D134-E413-4181-936D-D82F3F5F1D85}.Linux|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{8F63D134-E413-4181-936D-D82F3F5F1D85}.Linux|Any CPU.Build.0 = Release|Any CPU
|
||||
{8F63D134-E413-4181-936D-D82F3F5F1D85}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{8F63D134-E413-4181-936D-D82F3F5F1D85}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{C4F81816-C87A-4ABF-8A37-24AC16A0A6CF}.CodeCoverage|Any CPU.ActiveCfg = CodeCoverage|Any CPU
|
||||
{C4F81816-C87A-4ABF-8A37-24AC16A0A6CF}.CodeCoverage|Any CPU.Build.0 = CodeCoverage|Any CPU
|
||||
{C4F81816-C87A-4ABF-8A37-24AC16A0A6CF}.CodeCoverage|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{C4F81816-C87A-4ABF-8A37-24AC16A0A6CF}.CodeCoverage|Any CPU.Build.0 = Release|Any CPU
|
||||
{C4F81816-C87A-4ABF-8A37-24AC16A0A6CF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{C4F81816-C87A-4ABF-8A37-24AC16A0A6CF}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{C4F81816-C87A-4ABF-8A37-24AC16A0A6CF}.Linux|Any CPU.ActiveCfg = Linux|Any CPU
|
||||
{C4F81816-C87A-4ABF-8A37-24AC16A0A6CF}.Linux|Any CPU.Build.0 = Linux|Any CPU
|
||||
{C4F81816-C87A-4ABF-8A37-24AC16A0A6CF}.Linux|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{C4F81816-C87A-4ABF-8A37-24AC16A0A6CF}.Linux|Any CPU.Build.0 = Release|Any CPU
|
||||
{C4F81816-C87A-4ABF-8A37-24AC16A0A6CF}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{C4F81816-C87A-4ABF-8A37-24AC16A0A6CF}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{D9CCCB67-4EBE-4854-AB52-C0129DC5BAE4}.CodeCoverage|Any CPU.ActiveCfg = CodeCoverage|Any CPU
|
||||
{D9CCCB67-4EBE-4854-AB52-C0129DC5BAE4}.CodeCoverage|Any CPU.Build.0 = CodeCoverage|Any CPU
|
||||
{D9CCCB67-4EBE-4854-AB52-C0129DC5BAE4}.CodeCoverage|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{D9CCCB67-4EBE-4854-AB52-C0129DC5BAE4}.CodeCoverage|Any CPU.Build.0 = Release|Any CPU
|
||||
{D9CCCB67-4EBE-4854-AB52-C0129DC5BAE4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{D9CCCB67-4EBE-4854-AB52-C0129DC5BAE4}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{D9CCCB67-4EBE-4854-AB52-C0129DC5BAE4}.Linux|Any CPU.ActiveCfg = Linux|Any CPU
|
||||
{D9CCCB67-4EBE-4854-AB52-C0129DC5BAE4}.Linux|Any CPU.Build.0 = Linux|Any CPU
|
||||
{D9CCCB67-4EBE-4854-AB52-C0129DC5BAE4}.Linux|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{D9CCCB67-4EBE-4854-AB52-C0129DC5BAE4}.Linux|Any CPU.Build.0 = Release|Any CPU
|
||||
{D9CCCB67-4EBE-4854-AB52-C0129DC5BAE4}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{D9CCCB67-4EBE-4854-AB52-C0129DC5BAE4}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{73EA0BE6-C0C5-4B56-A5AA-DADA4C01D690}.Linux|Any CPU.ActiveCfg = Linux|Any CPU
|
||||
{73EA0BE6-C0C5-4B56-A5AA-DADA4C01D690}.Linux|Any CPU.Build.0 = Linux|Any CPU
|
||||
{73EA0BE6-C0C5-4B56-A5AA-DADA4C01D690}.Release|Any CPU.ActiveCfg = Linux|Any CPU
|
||||
{73EA0BE6-C0C5-4B56-A5AA-DADA4C01D690}.Release|Any CPU.Build.0 = Linux|Any CPU
|
||||
{73EA0BE6-C0C5-4B56-A5AA-DADA4C01D690}.Debug|Any CPU.ActiveCfg = Linux|Any CPU
|
||||
{73EA0BE6-C0C5-4B56-A5AA-DADA4C01D690}.Debug|Any CPU.Build.0 = Linux|Any CPU
|
||||
{73EA0BE6-C0C5-4B56-A5AA-DADA4C01D690}.CodeCoverage|Any CPU.ActiveCfg = Linux|Any CPU
|
||||
{73EA0BE6-C0C5-4B56-A5AA-DADA4C01D690}.CodeCoverage|Any CPU.Build.0 = Linux|Any CPU
|
||||
{73EA0BE6-C0C5-4B56-A5AA-DADA4C01D690}.CodeCoverage|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{73EA0BE6-C0C5-4B56-A5AA-DADA4C01D690}.CodeCoverage|Any CPU.Build.0 = Debug|Any CPU
|
||||
{73EA0BE6-C0C5-4B56-A5AA-DADA4C01D690}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{73EA0BE6-C0C5-4B56-A5AA-DADA4C01D690}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{73EA0BE6-C0C5-4B56-A5AA-DADA4C01D690}.Linux|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{73EA0BE6-C0C5-4B56-A5AA-DADA4C01D690}.Linux|Any CPU.Build.0 = Debug|Any CPU
|
||||
{73EA0BE6-C0C5-4B56-A5AA-DADA4C01D690}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{73EA0BE6-C0C5-4B56-A5AA-DADA4C01D690}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{43D4F8DA-A7DE-494B-81B0-BDE3CFD7B1F1}.CodeCoverage|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{43D4F8DA-A7DE-494B-81B0-BDE3CFD7B1F1}.CodeCoverage|Any CPU.Build.0 = Debug|Any CPU
|
||||
{43D4F8DA-A7DE-494B-81B0-BDE3CFD7B1F1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{43D4F8DA-A7DE-494B-81B0-BDE3CFD7B1F1}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{43D4F8DA-A7DE-494B-81B0-BDE3CFD7B1F1}.Linux|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{43D4F8DA-A7DE-494B-81B0-BDE3CFD7B1F1}.Linux|Any CPU.Build.0 = Debug|Any CPU
|
||||
{43D4F8DA-A7DE-494B-81B0-BDE3CFD7B1F1}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{43D4F8DA-A7DE-494B-81B0-BDE3CFD7B1F1}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
||||
+31
-102
@@ -103,108 +103,6 @@ COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
-------------------------------------------------
|
||||
WebListener
|
||||
-------------------------------------------------
|
||||
|
||||
Microsoft.AspNetCore.App 2.1.0
|
||||
Copyright (c) .NET Foundation and Contributors
|
||||
All rights reserved.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License"); you may not use
|
||||
this file except in compliance with the License. You may obtain a copy of the
|
||||
License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software distributed
|
||||
under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||
CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||
specific language governing permissions and limitations under the License.
|
||||
|
||||
-------------------------------------------------
|
||||
XUnit tests
|
||||
-------------------------------------------------
|
||||
|
||||
Xunit.SkippableFact v bnm
|
||||
Copyright (c) Andrew Arnott
|
||||
|
||||
This software is licensed under the Microsoft Public License
|
||||
http://opensource.org/licenses/ms-pl
|
||||
|
||||
This license governs use of the accompanying software. If you use the software, you
|
||||
accept this license. If you do not accept the license, do not use the software.
|
||||
|
||||
1. Definitions
|
||||
The terms "reproduce," "reproduction," "derivative works," and "distribution" have the
|
||||
same meaning here as under U.S. copyright law.
|
||||
A "contribution" is the original software, or any additions or changes to the software.
|
||||
A "contributor" is any person that distributes its contribution under this license.
|
||||
"Licensed patents" are a contributor's patent claims that read directly on its contribution.
|
||||
|
||||
2. Grant of Rights
|
||||
(A) Copyright Grant- Subject to the terms of this license, including the license conditions and limitations in section 3, each contributor grants you a non-exclusive, worldwide, royalty-free copyright license to reproduce its contribution, prepare derivative works of its contribution, and distribute its contribution or any derivative works that you create.
|
||||
(B) Patent Grant- Subject to the terms of this license, including the license conditions and limitations in section 3, each contributor grants you a non-exclusive, worldwide, royalty-free license under its licensed patents to make, have made, use, sell, offer for sale, import, and/or otherwise dispose of its contribution in the software or derivative works of the contribution in the software.
|
||||
|
||||
3. Conditions and Limitations
|
||||
(A) No Trademark License- This license does not grant you rights to use any contributors' name, logo, or trademarks.
|
||||
(B) If you bring a patent claim against any contributor over patents that you claim are infringed by the software, your patent license from such contributor to the software ends automatically.
|
||||
(C) If you distribute any portion of the software, you must retain all copyright, patent, trademark, and attribution notices that are present in the software.
|
||||
(D) If you distribute any portion of the software in source code form, you may do so only under this license by including a complete copy of this license with your distribution. If you distribute any portion of the software in compiled or object code form, you may only do so under a license that complies with this license.
|
||||
(E) The software is licensed "as-is." You bear the risk of using it. The contributors give no express warranties, guarantees or conditions. You may have additional consumer rights under your local laws which this license cannot change. To the extent permitted under your local laws, the contributors exclude the implied warranties of merchantability, fitness for a particular purpose and non-infringement.
|
||||
|
||||
------------------------------------------------------
|
||||
Libmi.so
|
||||
------------------------------------------------------
|
||||
Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
All rights reserved.
|
||||
MIT License
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this
|
||||
software and associated documentation files (the "Software"), to deal in the Software
|
||||
without restriction, including without limitation the rights to use, copy, modify,
|
||||
merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to the following
|
||||
conditions:
|
||||
The above copyright notice and this permission notice shall be included in all copies
|
||||
or substantial portions of the Software.
|
||||
THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
||||
INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
|
||||
PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
|
||||
CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
|
||||
OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
The following components are governed by the MIT license, a copy of which appears
|
||||
below the list of components:
|
||||
------------------------------------------------------
|
||||
Newtonsoft.Json
|
||||
------------------------------------------------------
|
||||
Copyright (c) 2007 James Newton-King
|
||||
All rights reserved.
|
||||
MIT License
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this
|
||||
software and associated documentation files (the "Software"), to deal in the Software
|
||||
without restriction, including without limitation the rights to use, copy, modify,
|
||||
merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to the following
|
||||
conditions:
|
||||
The above copyright notice and this permission notice shall be included in all copies
|
||||
or substantial portions of the Software.
|
||||
THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
||||
INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
|
||||
PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
|
||||
CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
|
||||
OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
---------------------------------------------------------
|
||||
Libuv v.1.9.0
|
||||
---------------------------------------------------------
|
||||
|
||||
https://raw.githubusercontent.com/aspnet/libuv-package/dev/content/License.txt
|
||||
|
||||
This software is licensed to you by Microsoft Corporation under the original terms of
|
||||
the copyright holder provided below:
|
||||
|
||||
=========================================
|
||||
|
||||
libuv is part of the Node project: http://nodejs.org/
|
||||
libuv may be distributed alone under Node's license:
|
||||
@@ -899,3 +797,34 @@ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
=======
|
||||
|
||||
-------------------------------------------------
|
||||
File: markdig
|
||||
-------------------------------------------------
|
||||
|
||||
https://github.com/lunet-io/markdig
|
||||
|
||||
"Copyright (c) 2016, Alexandre Mutel
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification
|
||||
, are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ""AS IS"" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
|
||||
|
||||
@@ -1189,6 +1189,18 @@
|
||||
<Component Id="cmp51F2F26684B5C4D0FFFFFBD72174D1BC" Guid="{3383D3BD-2174-4FC4-BC14-4AB4309D3E88}">
|
||||
<File Id="fil3EEF1D08102F0A83F48EFBB44396FCBA" KeyPath="yes" Source="$(env.ProductSourcePath)\api-ms-win-core-libraryloader-l1-1-1.dll" />
|
||||
</Component>
|
||||
<Component Id="cmp09b8252b795440eca75bc6a0811a3f10" Guid="{1334ea0d-abb9-4f4d-948d-17d7602e63be}">
|
||||
<File Id="fil0a4b944b312642a4a68181302623e0b5" KeyPath="yes" Source="$(env.ProductSourcePath)\Markdig.dll" />
|
||||
</Component>
|
||||
<Component Id="cmpf2a3c81eb19246b6be74af07e70a06f0" Guid="{678cb6a4-49e8-41be-a5cb-67a77c3cf612}">
|
||||
<File Id="fil90f9e9f09d6744f68331100e6d7da03d" KeyPath="yes" Source="$(env.ProductSourcePath)\Microsoft.PowerShell.MarkdownRender.dll" />
|
||||
</Component>
|
||||
<Component Id="cmp918c5338524c41a2ac739a0ded94cc0d" Guid="{4f1ade18-360c-4510-ba4a-94f86f8d7f63}">
|
||||
<File Id="fil2d5d94e7f192444584831a1a48d8d9dd" KeyPath="yes" Source="$(env.ProductSourcePath)\Microsoft.PowerShell.MarkdownRender.pdb" />
|
||||
</Component>
|
||||
<Component Id="cmp75c6b7b418bb4f439dd5519c570a14e0" Guid="{0043d5f4-4ea7-4193-8825-8a8f80e4224b}">
|
||||
<File Id="fil1c8a95614a8348f9ac6982b3340a303c" KeyPath="yes" Source="$(env.ProductSourcePath)\Microsoft.PowerShell.MarkdownRender.xml" />
|
||||
</Component>
|
||||
<Directory Id="dir23E9C47466D341314C603F5C7118348B" Name="ref">
|
||||
<Component Id="cmp889E7B16C996100DE4B6402D1CD4F4F2" Guid="{81695AC9-25BB-48E1-AF84-45C9C496F1E3}">
|
||||
<File Id="fil3F0371EFF48A0EFBA363818F8E2C7423" KeyPath="yes" Source="$(env.ProductSourcePath)\ref\Microsoft.CSharp.dll" />
|
||||
@@ -2314,6 +2326,10 @@
|
||||
<ComponentRef Id="cmp30357FCEAC7B88BDCF0B20D55C22F61F" />
|
||||
<ComponentRef Id="cmp557A49B03E72CD07149A6CD0595C9245" />
|
||||
<ComponentRef Id="cmp51F2F26684B5C4D0FFFFFBD72174D1BC" />
|
||||
<ComponentRef Id="cmp09b8252b795440eca75bc6a0811a3f10" />
|
||||
<ComponentRef Id="cmpf2a3c81eb19246b6be74af07e70a06f0" />
|
||||
<ComponentRef Id="cmp918c5338524c41a2ac739a0ded94cc0d" />
|
||||
<ComponentRef Id="cmp75c6b7b418bb4f439dd5519c570a14e0" />
|
||||
<ComponentRef Id="cmp889E7B16C996100DE4B6402D1CD4F4F2" />
|
||||
<ComponentRef Id="cmp4B013FDCB7F1B636E32467682F21EC3C" />
|
||||
<ComponentRef Id="cmp4B013FDCB7F1B636E32467682F21EC3D" />
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\System.Management.Automation\System.Management.Automation.csproj" />
|
||||
<ProjectReference Include="..\Microsoft.PowerShell.MarkdownRender\Microsoft.PowerShell.MarkdownRender.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<PropertyGroup>
|
||||
|
||||
+228
@@ -0,0 +1,228 @@
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.IO;
|
||||
using System.Management.Automation;
|
||||
using System.Management.Automation.Internal;
|
||||
using System.Security;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.PowerShell.MarkdownRender;
|
||||
using Dbg = System.Management.Automation;
|
||||
|
||||
namespace Microsoft.PowerShell.Commands
|
||||
{
|
||||
/// <summary>
|
||||
/// Converts a Markdown string to a MarkdownInfo object.
|
||||
/// The conversion can be done into a HTML text or VT100 encoding string.
|
||||
/// </summary>
|
||||
[Cmdlet(
|
||||
VerbsData.ConvertFrom, "Markdown",
|
||||
DefaultParameterSetName = PathParameterSet,
|
||||
HelpUri = "TBD")]
|
||||
[OutputType(typeof(Microsoft.PowerShell.MarkdownRender.MarkdownInfo))]
|
||||
public class ConvertFromMarkdownCommand : PSCmdlet
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets path to the file to convert from Markdown to MarkdownInfo.
|
||||
/// </summary>
|
||||
[ValidateNotNullOrEmpty]
|
||||
[Parameter(ParameterSetName = PathParameterSet, Mandatory = true)]
|
||||
public string[] Path { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the path to the file to convert from Markdown to MarkdownInfo.
|
||||
/// </summary>
|
||||
[ValidateNotNullOrEmpty]
|
||||
[Parameter(ParameterSetName = LiteralPathParameterSet, Mandatory = true)]
|
||||
public string[] LiteralPath { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the InputObject of type System.IO.FileInfo or string with content to convert from Markdown to MarkdownInfo.
|
||||
/// </summary>
|
||||
[ValidateNotNullOrEmpty]
|
||||
[Parameter(ParameterSetName = InputObjParamSet, Mandatory = true, ValueFromPipeline = true)]
|
||||
public PSObject InputObject { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets if the Markdown document should be converted to a VT100 encoded string.
|
||||
/// </summary>
|
||||
[Parameter]
|
||||
public SwitchParameter AsVT100EncodedString { get; set; }
|
||||
|
||||
private const string PathParameterSet = "PathParamSet";
|
||||
private const string LiteralPathParameterSet = "LiteralParamSet";
|
||||
private const string InputObjParamSet = "InputObjParamSet";
|
||||
private MarkdownConversionType conversionType = MarkdownConversionType.HTML;
|
||||
private MarkdownOptionInfo mdOption = null;
|
||||
|
||||
/// <summary>
|
||||
/// Read the MarkdownOptionInfo set in SessionState.
|
||||
/// </summary>
|
||||
protected override void BeginProcessing()
|
||||
{
|
||||
mdOption = SessionState.PSVariable.GetValue("MarkdownOptionInfo", new MarkdownOptionInfo()) as MarkdownOptionInfo;
|
||||
|
||||
if (mdOption == null)
|
||||
{
|
||||
throw new InvalidOperationException();
|
||||
}
|
||||
|
||||
if (AsVT100EncodedString)
|
||||
{
|
||||
conversionType = MarkdownConversionType.VT100;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Override ProcessRecord.
|
||||
/// </summary>
|
||||
protected override void ProcessRecord()
|
||||
{
|
||||
switch (ParameterSetName)
|
||||
{
|
||||
case InputObjParamSet:
|
||||
object baseObj = InputObject.BaseObject;
|
||||
|
||||
if (baseObj is FileInfo fileInfo)
|
||||
{
|
||||
WriteObject(
|
||||
MarkdownConverter.Convert(
|
||||
ReadContentFromFile(fileInfo.FullName)?.Result,
|
||||
conversionType,
|
||||
mdOption));
|
||||
}
|
||||
else if (baseObj is string inpObj)
|
||||
{
|
||||
WriteObject(MarkdownConverter.Convert(inpObj, conversionType, mdOption));
|
||||
}
|
||||
else
|
||||
{
|
||||
string errorMessage = StringUtil.Format(ConvertMarkdownStrings.InvalidInputObjectType, baseObj.GetType());
|
||||
ErrorRecord errorRecord = new ErrorRecord(
|
||||
new InvalidDataException(errorMessage),
|
||||
"InvalidInputObject",
|
||||
ErrorCategory.InvalidData,
|
||||
InputObject);
|
||||
|
||||
WriteError(errorRecord);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case PathParameterSet:
|
||||
ConvertEachFile(Path, conversionType, isLiteral: false, optionInfo: mdOption);
|
||||
break;
|
||||
|
||||
case LiteralPathParameterSet:
|
||||
ConvertEachFile(LiteralPath, conversionType, isLiteral: true, optionInfo: mdOption);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void ConvertEachFile(IEnumerable<string> paths, MarkdownConversionType conversionType, bool isLiteral, MarkdownOptionInfo optionInfo)
|
||||
{
|
||||
foreach (var path in paths)
|
||||
{
|
||||
var resolvedPaths = ResolvePath(path, isLiteral);
|
||||
|
||||
foreach (var resolvedPath in resolvedPaths)
|
||||
{
|
||||
WriteObject(
|
||||
MarkdownConverter.Convert(
|
||||
ReadContentFromFile(resolvedPath)?.Result,
|
||||
conversionType,
|
||||
optionInfo));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private async Task<string> ReadContentFromFile(string filePath)
|
||||
{
|
||||
ErrorRecord errorRecord = null;
|
||||
|
||||
try
|
||||
{
|
||||
using (StreamReader reader = new StreamReader(new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read)))
|
||||
{
|
||||
string mdContent = await reader.ReadToEndAsync();
|
||||
return mdContent;
|
||||
}
|
||||
}
|
||||
catch (FileNotFoundException fnfe)
|
||||
{
|
||||
errorRecord = new ErrorRecord(
|
||||
fnfe,
|
||||
"FileNotFound",
|
||||
ErrorCategory.ResourceUnavailable,
|
||||
filePath);
|
||||
}
|
||||
catch (SecurityException se)
|
||||
{
|
||||
errorRecord = new ErrorRecord(
|
||||
se,
|
||||
"FileSecurityError",
|
||||
ErrorCategory.SecurityError,
|
||||
filePath);
|
||||
}
|
||||
catch (UnauthorizedAccessException uae)
|
||||
{
|
||||
errorRecord = new ErrorRecord(
|
||||
uae,
|
||||
"FileUnauthorizedAccess",
|
||||
ErrorCategory.SecurityError,
|
||||
filePath);
|
||||
}
|
||||
|
||||
WriteError(errorRecord);
|
||||
return null;
|
||||
}
|
||||
|
||||
private List<string> ResolvePath(string path, bool isLiteral)
|
||||
{
|
||||
ProviderInfo provider = null;
|
||||
PSDriveInfo drive = null;
|
||||
List<string> resolvedPaths = new List<string>();
|
||||
|
||||
try
|
||||
{
|
||||
if (isLiteral)
|
||||
{
|
||||
resolvedPaths.Add(Context.SessionState.Path.GetUnresolvedProviderPathFromPSPath(path, out provider, out drive));
|
||||
}
|
||||
else
|
||||
{
|
||||
resolvedPaths.AddRange(Context.SessionState.Path.GetResolvedProviderPathFromPSPath(path, out provider));
|
||||
}
|
||||
}
|
||||
catch (ItemNotFoundException infe)
|
||||
{
|
||||
var errorRecord = new ErrorRecord(
|
||||
infe,
|
||||
"FileNotFound",
|
||||
ErrorCategory.ResourceUnavailable,
|
||||
path);
|
||||
|
||||
WriteError(errorRecord);
|
||||
}
|
||||
|
||||
if (!provider.Name.Equals("FileSystem", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
string errorMessage = StringUtil.Format(ConvertMarkdownStrings.FileSystemPathsOnly, path);
|
||||
ErrorRecord errorRecord = new ErrorRecord(
|
||||
new ArgumentException(),
|
||||
"OnlyFileSystemPathsSupported",
|
||||
ErrorCategory.InvalidArgument,
|
||||
path);
|
||||
|
||||
WriteError(errorRecord);
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
return resolvedPaths;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,262 @@
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.IO;
|
||||
using System.Management.Automation;
|
||||
using System.Management.Automation.Internal;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.PowerShell.MarkdownRender;
|
||||
|
||||
namespace Microsoft.PowerShell.Commands
|
||||
{
|
||||
/// <summary>
|
||||
/// Class for implementing Set-MarkdownOption cmdlet.
|
||||
/// </summary>
|
||||
[Cmdlet(
|
||||
VerbsCommon.Set, "MarkdownOption",
|
||||
DefaultParameterSetName = IndividualSetting,
|
||||
HelpUri = "TBD")]
|
||||
[OutputType(typeof(Microsoft.PowerShell.MarkdownRender.MarkdownOptionInfo))]
|
||||
public class SetMarkdownOptionCommand : PSCmdlet
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the VT100 escape sequence for Header Level 1.
|
||||
/// </summary>
|
||||
[ValidatePattern(@"^\[*[0-9;]*?m{1}")]
|
||||
[Parameter(ParameterSetName = IndividualSetting)]
|
||||
public string Header1Color { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the VT100 escape sequence for Header Level 2.
|
||||
/// </summary>
|
||||
[ValidatePattern(@"^\[*[0-9;]*?m{1}")]
|
||||
[Parameter(ParameterSetName = IndividualSetting)]
|
||||
public string Header2Color { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the VT100 escape sequence for Header Level 3.
|
||||
/// </summary>
|
||||
[ValidatePattern(@"^\[*[0-9;]*?m{1}")]
|
||||
[Parameter(ParameterSetName = IndividualSetting)]
|
||||
public string Header3Color { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the VT100 escape sequence for Header Level 4.
|
||||
/// </summary>
|
||||
[ValidatePattern(@"^\[*[0-9;]*?m{1}")]
|
||||
[Parameter(ParameterSetName = IndividualSetting)]
|
||||
public string Header4Color { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the VT100 escape sequence for Header Level 5.
|
||||
/// </summary>
|
||||
[ValidatePattern(@"^\[*[0-9;]*?m{1}")]
|
||||
[Parameter(ParameterSetName = IndividualSetting)]
|
||||
public string Header5Color { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the VT100 escape sequence for Header Level 6.
|
||||
/// </summary>
|
||||
[ValidatePattern(@"^\[*[0-9;]*?m{1}")]
|
||||
[Parameter(ParameterSetName = IndividualSetting)]
|
||||
public string Header6Color { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the VT100 escape sequence for code block background.
|
||||
/// </summary>
|
||||
[ValidatePattern(@"^\[*[0-9;]*?m{1}")]
|
||||
[Parameter(ParameterSetName = IndividualSetting)]
|
||||
public string Code { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the VT100 escape sequence for image alt text foreground.
|
||||
/// </summary>
|
||||
[ValidatePattern(@"^\[*[0-9;]*?m{1}")]
|
||||
[Parameter(ParameterSetName = IndividualSetting)]
|
||||
public string ImageAltTextForegroundColor { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the VT100 escape sequence for link foreground.
|
||||
/// </summary>
|
||||
[ValidatePattern(@"^\[*[0-9;]*?m{1}")]
|
||||
[Parameter(ParameterSetName = IndividualSetting)]
|
||||
public string LinkForegroundColor { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the VT100 escape sequence for italics text foreground.
|
||||
/// </summary>
|
||||
[ValidatePattern(@"^\[*[0-9;]*?m{1}")]
|
||||
[Parameter(ParameterSetName = IndividualSetting)]
|
||||
public string ItalicsForegroundColor { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the VT100 escape sequence for bold text foreground.
|
||||
/// </summary>
|
||||
[ValidatePattern(@"^\[*[0-9;]*?m{1}")]
|
||||
[Parameter(ParameterSetName = IndividualSetting)]
|
||||
public string BoldForegroundColor { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the switch to PassThru the values set.
|
||||
/// </summary>
|
||||
[Parameter]
|
||||
public SwitchParameter PassThru { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the Theme.
|
||||
/// </summary>
|
||||
[ValidateNotNullOrEmpty]
|
||||
[Parameter(ParameterSetName = ThemeParamSet, Mandatory = true)]
|
||||
[ValidateSet(DarkThemeName, LightThemeName)]
|
||||
public string Theme { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets InputObject.
|
||||
/// </summary>
|
||||
[ValidateNotNullOrEmpty]
|
||||
[Parameter(ParameterSetName = InputObjectParamSet, Mandatory = true, ValueFromPipeline = true)]
|
||||
public PSObject InputObject { get; set; }
|
||||
|
||||
private const string IndividualSetting = "IndividualSetting";
|
||||
private const string InputObjectParamSet = "InputObject";
|
||||
private const string ThemeParamSet = "Theme";
|
||||
private const string MarkdownOptionInfoVariableName = "MarkdownOptionInfo";
|
||||
private const string LightThemeName = "Light";
|
||||
private const string DarkThemeName = "Dark";
|
||||
|
||||
/// <summary>
|
||||
/// Override EndProcessing.
|
||||
/// </summary>
|
||||
protected override void EndProcessing()
|
||||
{
|
||||
MarkdownOptionInfo mdOptionInfo = null;
|
||||
|
||||
switch (ParameterSetName)
|
||||
{
|
||||
case ThemeParamSet:
|
||||
mdOptionInfo = new MarkdownOptionInfo();
|
||||
if (string.Equals(Theme, LightThemeName, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
mdOptionInfo.SetLightTheme();
|
||||
}
|
||||
else if (string.Equals(Theme, DarkThemeName, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
mdOptionInfo.SetDarkTheme();
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case InputObjectParamSet:
|
||||
object baseObj = InputObject.BaseObject;
|
||||
mdOptionInfo = baseObj as MarkdownOptionInfo;
|
||||
|
||||
if (mdOptionInfo == null)
|
||||
{
|
||||
var errorMessage = StringUtil.Format(ConvertMarkdownStrings.InvalidInputObjectType, baseObj.GetType());
|
||||
|
||||
ErrorRecord errorRecord = new ErrorRecord(
|
||||
new ArgumentException(errorMessage),
|
||||
"InvalidObject",
|
||||
ErrorCategory.InvalidArgument,
|
||||
InputObject);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case IndividualSetting:
|
||||
mdOptionInfo = new MarkdownOptionInfo();
|
||||
SetOptions(mdOptionInfo);
|
||||
break;
|
||||
}
|
||||
|
||||
var sessionVar = SessionState.PSVariable;
|
||||
sessionVar.Set(MarkdownOptionInfoVariableName, mdOptionInfo);
|
||||
|
||||
if(PassThru.IsPresent)
|
||||
{
|
||||
WriteObject(mdOptionInfo);
|
||||
}
|
||||
}
|
||||
|
||||
private void SetOptions(MarkdownOptionInfo mdOptionInfo)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(Header1Color))
|
||||
{
|
||||
mdOptionInfo.Header1 = Header1Color;
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(Header2Color))
|
||||
{
|
||||
mdOptionInfo.Header2 = Header2Color;
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(Header3Color))
|
||||
{
|
||||
mdOptionInfo.Header3 = Header3Color;
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(Header4Color))
|
||||
{
|
||||
mdOptionInfo.Header4 = Header4Color;
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(Header5Color))
|
||||
{
|
||||
mdOptionInfo.Header5 = Header5Color;
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(Header6Color))
|
||||
{
|
||||
mdOptionInfo.Header6 = Header6Color;
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(Code))
|
||||
{
|
||||
mdOptionInfo.Code = Code;
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(ImageAltTextForegroundColor))
|
||||
{
|
||||
mdOptionInfo.Image = ImageAltTextForegroundColor;
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(LinkForegroundColor))
|
||||
{
|
||||
mdOptionInfo.Link = LinkForegroundColor;
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(ItalicsForegroundColor))
|
||||
{
|
||||
mdOptionInfo.EmphasisItalics = ItalicsForegroundColor;
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(BoldForegroundColor))
|
||||
{
|
||||
mdOptionInfo.EmphasisBold = BoldForegroundColor;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Implements the cmdlet for getting the Markdown options that are set.
|
||||
/// </summary>
|
||||
[Cmdlet(
|
||||
VerbsCommon.Get, "MarkdownOption",
|
||||
HelpUri = "TBD")]
|
||||
[OutputType(typeof(Microsoft.PowerShell.MarkdownRender.MarkdownOptionInfo))]
|
||||
public class GetMarkdownOptionCommand : PSCmdlet
|
||||
{
|
||||
private const string MarkdownOptionInfoVariableName = "MarkdownOptionInfo";
|
||||
|
||||
/// <summary>
|
||||
/// Override EndProcessing.
|
||||
/// </summary>
|
||||
protected override void EndProcessing()
|
||||
{
|
||||
WriteObject(SessionState.PSVariable.GetValue(MarkdownOptionInfoVariableName, new MarkdownOptionInfo()));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,182 @@
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Management.Automation;
|
||||
using System.Management.Automation.Internal;
|
||||
using Microsoft.PowerShell.MarkdownRender;
|
||||
|
||||
namespace Microsoft.PowerShell.Commands
|
||||
{
|
||||
/// <summary>
|
||||
/// Show the VT100EncodedString or Html property of on console or show.
|
||||
/// VT100EncodedString will be displayed on console.
|
||||
/// Html will be displayed in default browser.
|
||||
/// </summary>
|
||||
[Cmdlet(
|
||||
VerbsCommon.Show, "Markdown",
|
||||
HelpUri = "TBD")]
|
||||
[OutputType(typeof(string))]
|
||||
public class ShowMarkdownCommand : PSCmdlet
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets InputObject of type Microsoft.PowerShell.MarkdownRender.MarkdownInfo to display.
|
||||
/// </summary>
|
||||
[ValidateNotNullOrEmpty]
|
||||
[Parameter(Mandatory = true, ValueFromPipeline = true)]
|
||||
public PSObject InputObject { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the switch to view Html in default browser.
|
||||
/// </summary>
|
||||
[Parameter]
|
||||
public SwitchParameter UseBrowser { get; set; }
|
||||
|
||||
private SteppablePipeline stepPipe;
|
||||
|
||||
/// <summary>
|
||||
/// Override BeginProcessing.
|
||||
/// </summary>
|
||||
protected override void BeginProcessing()
|
||||
{
|
||||
if (!UseBrowser.IsPresent)
|
||||
{
|
||||
// Since UseBrowser is not bound, we use proxy to Out-Default
|
||||
stepPipe = ScriptBlock.Create(@"Microsoft.PowerShell.Core\Out-Default @PSBoundParameters").GetSteppablePipeline(this.MyInvocation.CommandOrigin);
|
||||
stepPipe.Begin(this);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Override ProcessRecord.
|
||||
/// </summary>
|
||||
protected override void ProcessRecord()
|
||||
{
|
||||
object inpObj = InputObject.BaseObject;
|
||||
|
||||
if (inpObj is MarkdownInfo markdownInfo)
|
||||
{
|
||||
if (UseBrowser)
|
||||
{
|
||||
var html = markdownInfo.Html;
|
||||
|
||||
if (!string.IsNullOrEmpty(html))
|
||||
{
|
||||
string tmpFilePath = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString() + ".html");
|
||||
|
||||
try
|
||||
{
|
||||
using (var writer = new StreamWriter(new FileStream(tmpFilePath, FileMode.Create, FileAccess.Write, FileShare.Write)))
|
||||
{
|
||||
writer.Write(html);
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
var errorRecord = new ErrorRecord(
|
||||
e,
|
||||
"ErrorWritingTempFile",
|
||||
ErrorCategory.WriteError,
|
||||
tmpFilePath);
|
||||
|
||||
WriteError(errorRecord);
|
||||
return;
|
||||
}
|
||||
|
||||
if (InternalTestHooks.ShowMarkdownOutputBypass)
|
||||
{
|
||||
WriteObject(html);
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
ProcessStartInfo startInfo = new ProcessStartInfo();
|
||||
startInfo.FileName = tmpFilePath;
|
||||
startInfo.UseShellExecute = true;
|
||||
Process.Start(startInfo);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
var errorRecord = new ErrorRecord(
|
||||
e,
|
||||
"ErrorLaunchingDefaultApplication",
|
||||
ErrorCategory.InvalidOperation,
|
||||
targetObject : null);
|
||||
|
||||
WriteError(errorRecord);
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
string errorMessage = StringUtil.Format(ConvertMarkdownStrings.MarkdownInfoInvalid, "Html");
|
||||
var errorRecord = new ErrorRecord(
|
||||
new InvalidDataException(errorMessage),
|
||||
"HtmlIsNullOrEmpty",
|
||||
ErrorCategory.InvalidData,
|
||||
html);
|
||||
|
||||
WriteError(errorRecord);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
var vt100String = markdownInfo.VT100EncodedString;
|
||||
|
||||
if (!string.IsNullOrEmpty(vt100String))
|
||||
{
|
||||
if (InternalTestHooks.ShowMarkdownOutputBypass)
|
||||
{
|
||||
WriteObject(vt100String);
|
||||
return;
|
||||
}
|
||||
|
||||
if (stepPipe != null)
|
||||
{
|
||||
stepPipe.Process(vt100String);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
string errorMessage = StringUtil.Format(ConvertMarkdownStrings.MarkdownInfoInvalid, "VT100EncodedString");
|
||||
var errorRecord = new ErrorRecord(
|
||||
new InvalidDataException(errorMessage),
|
||||
"VT100EncodedStringIsNullOrEmpty",
|
||||
ErrorCategory.InvalidData,
|
||||
vt100String);
|
||||
|
||||
WriteError(errorRecord);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
string errorMessage = StringUtil.Format(ConvertMarkdownStrings.InvalidInputObjectType, inpObj.GetType());
|
||||
var errorRecord = new ErrorRecord(
|
||||
new ArgumentException(errorMessage),
|
||||
"InvalidInputObject",
|
||||
ErrorCategory.InvalidArgument,
|
||||
InputObject);
|
||||
|
||||
WriteError(errorRecord);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Override EndProcessing.
|
||||
/// </summary>
|
||||
protected override void EndProcessing()
|
||||
{
|
||||
if (stepPipe != null)
|
||||
{
|
||||
stepPipe.End();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,132 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="https://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="https://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<data name="InvalidInputObjectType" xml:space="preserve">
|
||||
<value>The type of the input object '{0}' is invalid.</value>
|
||||
</data>
|
||||
<data name="InputFileNotFound" xml:space="preserve">
|
||||
<value>The file is not found: '{0}'.</value>
|
||||
</data>
|
||||
<data name="FileSystemPathsOnly" xml:space="preserve">
|
||||
<value>Only FileSystem Provider paths are supported. The file path is not supported: '{0}'.</value>
|
||||
</data>
|
||||
<data name="MarkdownInfoInvalid" xml:space="preserve">
|
||||
<value>The property {0} of the given object is null or empty.</value>
|
||||
</data>
|
||||
</root>
|
||||
@@ -0,0 +1,22 @@
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
using Markdig;
|
||||
using Markdig.Renderers;
|
||||
using Markdig.Syntax.Inlines;
|
||||
|
||||
namespace Microsoft.PowerShell.MarkdownRender
|
||||
{
|
||||
/// <summary>
|
||||
/// Renderer for adding VT100 escape sequences for inline code elements.
|
||||
/// </summary>
|
||||
internal class CodeInlineRenderer : VT100ObjectRenderer<CodeInline>
|
||||
{
|
||||
protected override void Write(VT100Renderer renderer, CodeInline obj)
|
||||
{
|
||||
renderer.Write(renderer.EscapeSequences.FormatCode(obj.Content, isInline : true));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
using Markdig;
|
||||
using Markdig.Renderers;
|
||||
using Markdig.Syntax.Inlines;
|
||||
|
||||
namespace Microsoft.PowerShell.MarkdownRender
|
||||
{
|
||||
/// <summary>
|
||||
/// Renderer for adding VT100 escape sequences for bold and italics elements.
|
||||
/// </summary>
|
||||
internal class EmphasisInlineRenderer : VT100ObjectRenderer<EmphasisInline>
|
||||
{
|
||||
protected override void Write(VT100Renderer renderer, EmphasisInline obj)
|
||||
{
|
||||
renderer.Write(renderer.EscapeSequences.FormatEmphasis(obj.FirstChild.ToString(), isBold : obj.IsDouble ? true : false));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
using Markdig;
|
||||
using Markdig.Renderers;
|
||||
using Markdig.Syntax;
|
||||
|
||||
namespace Microsoft.PowerShell.MarkdownRender
|
||||
{
|
||||
/// <summary>
|
||||
/// Renderer for adding VT100 escape sequences for code blocks with language type.
|
||||
/// </summary>
|
||||
internal class FencedCodeBlockRenderer : VT100ObjectRenderer<FencedCodeBlock>
|
||||
{
|
||||
protected override void Write(VT100Renderer renderer, FencedCodeBlock obj)
|
||||
{
|
||||
foreach (var codeLine in obj.Lines.Lines)
|
||||
{
|
||||
if (!string.IsNullOrWhiteSpace(codeLine.ToString()))
|
||||
{
|
||||
// If the code block is of type YAML, then tab to right to improve readability.
|
||||
// This specifically helps for parameters help content.
|
||||
if (string.Equals(obj.Info, "yaml", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
renderer.Write("\t").WriteLine(codeLine.ToString());
|
||||
}
|
||||
else
|
||||
{
|
||||
renderer.WriteLine(renderer.EscapeSequences.FormatCode(codeLine.ToString(), isInline: false));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Add a blank line after the code block for better readability.
|
||||
renderer.WriteLine();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
using Markdig;
|
||||
using Markdig.Renderers;
|
||||
using Markdig.Syntax;
|
||||
|
||||
namespace Microsoft.PowerShell.MarkdownRender
|
||||
{
|
||||
/// <summary>
|
||||
/// Renderer for adding VT100 escape sequences for headings.
|
||||
/// </summary>
|
||||
internal class HeaderBlockRenderer : VT100ObjectRenderer<HeadingBlock>
|
||||
{
|
||||
protected override void Write(VT100Renderer renderer, HeadingBlock obj)
|
||||
{
|
||||
// Format header and then add blank line to improve readability.
|
||||
switch (obj.Level)
|
||||
{
|
||||
case 1:
|
||||
renderer.WriteLine(renderer.EscapeSequences.FormatHeader1(obj.Inline.FirstChild.ToString()));
|
||||
renderer.WriteLine();
|
||||
break;
|
||||
|
||||
case 2:
|
||||
renderer.WriteLine(renderer.EscapeSequences.FormatHeader2(obj.Inline.FirstChild.ToString()));
|
||||
renderer.WriteLine();
|
||||
break;
|
||||
|
||||
case 3:
|
||||
renderer.WriteLine(renderer.EscapeSequences.FormatHeader3(obj.Inline.FirstChild.ToString()));
|
||||
renderer.WriteLine();
|
||||
break;
|
||||
|
||||
case 4:
|
||||
renderer.WriteLine(renderer.EscapeSequences.FormatHeader4(obj.Inline.FirstChild.ToString()));
|
||||
renderer.WriteLine();
|
||||
break;
|
||||
|
||||
case 5:
|
||||
renderer.WriteLine(renderer.EscapeSequences.FormatHeader5(obj.Inline.FirstChild.ToString()));
|
||||
renderer.WriteLine();
|
||||
break;
|
||||
|
||||
case 6:
|
||||
renderer.WriteLine(renderer.EscapeSequences.FormatHeader6(obj.Inline.FirstChild.ToString()));
|
||||
renderer.WriteLine();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
using Markdig;
|
||||
using Markdig.Renderers;
|
||||
using Markdig.Syntax.Inlines;
|
||||
|
||||
namespace Microsoft.PowerShell.MarkdownRender
|
||||
{
|
||||
/// <summary>
|
||||
/// Renderer for adding VT100 escape sequences for leaf elements like plain text in paragraphs.
|
||||
/// </summary>
|
||||
internal class LeafInlineRenderer : VT100ObjectRenderer<LeafInline>
|
||||
{
|
||||
protected override void Write(VT100Renderer renderer, LeafInline obj)
|
||||
{
|
||||
// If the next sibling is null, then this is the last line in the paragraph.
|
||||
// Add new line character at the end.
|
||||
// Else just write without newline at the end.
|
||||
if (obj.NextSibling == null)
|
||||
{
|
||||
renderer.WriteLine(obj.ToString());
|
||||
}
|
||||
else
|
||||
{
|
||||
renderer.Write(obj.ToString());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
using Markdig;
|
||||
using Markdig.Renderers;
|
||||
using Markdig.Syntax.Inlines;
|
||||
|
||||
namespace Microsoft.PowerShell.MarkdownRender
|
||||
{
|
||||
/// <summary>
|
||||
/// Renderer for adding VT100 escape sequences for line breaks.
|
||||
/// </summary>
|
||||
internal class LineBreakRenderer : VT100ObjectRenderer<LineBreakInline>
|
||||
{
|
||||
protected override void Write(VT100Renderer renderer, LineBreakInline obj)
|
||||
{
|
||||
// If it is a hard line break add new line at the end.
|
||||
// Else, add a space for after the last character to improve readability.
|
||||
if (obj.IsHard)
|
||||
{
|
||||
renderer.WriteLine();
|
||||
}
|
||||
else
|
||||
{
|
||||
renderer.Write(" ");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
using Markdig;
|
||||
using Markdig.Renderers;
|
||||
using Markdig.Syntax.Inlines;
|
||||
|
||||
namespace Microsoft.PowerShell.MarkdownRender
|
||||
{
|
||||
/// <summary>
|
||||
/// Renderer for adding VT100 escape sequences for links.
|
||||
/// </summary>
|
||||
internal class LinkInlineRenderer : VT100ObjectRenderer<LinkInline>
|
||||
{
|
||||
protected override void Write(VT100Renderer renderer, LinkInline obj)
|
||||
{
|
||||
// Format link as image or link.
|
||||
if (obj.IsImage)
|
||||
{
|
||||
renderer.Write(renderer.EscapeSequences.FormatImage(obj.FirstChild.ToString()));
|
||||
}
|
||||
else
|
||||
{
|
||||
renderer.Write(renderer.EscapeSequences.FormatLink(obj.FirstChild.ToString(), obj.Url));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
using Markdig;
|
||||
using Markdig.Renderers;
|
||||
using Markdig.Syntax;
|
||||
|
||||
namespace Microsoft.PowerShell.MarkdownRender
|
||||
{
|
||||
/// <summary>
|
||||
/// Renderer for adding VT100 escape sequences for list blocks.
|
||||
/// </summary>
|
||||
internal class ListBlockRenderer : VT100ObjectRenderer<ListBlock>
|
||||
{
|
||||
protected override void Write(VT100Renderer renderer, ListBlock obj)
|
||||
{
|
||||
// start index of a numbered block.
|
||||
int index = 1;
|
||||
|
||||
foreach (var item in obj)
|
||||
{
|
||||
if (item is ListItemBlock listItem)
|
||||
{
|
||||
if (obj.IsOrdered)
|
||||
{
|
||||
RenderNumberedList(renderer, listItem, index++);
|
||||
}
|
||||
else
|
||||
{
|
||||
renderer.Write(listItem);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
renderer.WriteLine();
|
||||
}
|
||||
|
||||
private void RenderNumberedList(VT100Renderer renderer, ListItemBlock block, int index)
|
||||
{
|
||||
// For a numbered list, we need to make sure the index is incremented.
|
||||
foreach (var line in block)
|
||||
{
|
||||
if (line is ParagraphBlock paragraphBlock)
|
||||
{
|
||||
renderer.Write(index.ToString()).Write(". ").Write(paragraphBlock.Inline);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Threading;
|
||||
using Markdig;
|
||||
using Markdig.Renderers;
|
||||
using Markdig.Syntax;
|
||||
|
||||
namespace Microsoft.PowerShell.MarkdownRender
|
||||
{
|
||||
/// <summary>
|
||||
/// Renderer for adding VT100 escape sequences for items in a list block.
|
||||
/// </summary>
|
||||
internal class ListItemBlockRenderer : VT100ObjectRenderer<ListItemBlock>
|
||||
{
|
||||
protected override void Write(VT100Renderer renderer, ListItemBlock obj)
|
||||
{
|
||||
if (obj.Parent is ListBlock parent)
|
||||
{
|
||||
if (!parent.IsOrdered)
|
||||
{
|
||||
foreach (var line in obj)
|
||||
{
|
||||
RenderWithIndent(renderer, line, parent.BulletType, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void RenderWithIndent(VT100Renderer renderer, MarkdownObject block, char listBullet, int indentLevel)
|
||||
{
|
||||
// Indent left by 2 for each level on list.
|
||||
string indent = Padding(indentLevel * 2);
|
||||
|
||||
if (block is ParagraphBlock paragraphBlock)
|
||||
{
|
||||
renderer.Write(indent).Write(listBullet).Write(" ").Write(paragraphBlock.Inline);
|
||||
}
|
||||
else
|
||||
{
|
||||
// If there is a sublist, the block is a ListBlock instead of ParagraphBlock.
|
||||
if (block is ListBlock subList)
|
||||
{
|
||||
foreach (var subListItem in subList)
|
||||
{
|
||||
if (subListItem is ListItemBlock subListItemBlock)
|
||||
{
|
||||
foreach (var line in subListItemBlock)
|
||||
{
|
||||
// Increment indent level for sub list.
|
||||
RenderWithIndent(renderer, line, listBullet, indentLevel + 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Typical padding is at most a screen's width, any more than that and we won't bother caching.
|
||||
private const int IndentCacheMax = 120;
|
||||
private static readonly string[] IndentCache = new string[IndentCacheMax];
|
||||
|
||||
internal static string Padding(int countOfSpaces)
|
||||
{
|
||||
if (countOfSpaces >= IndentCacheMax)
|
||||
{
|
||||
return new string(' ', countOfSpaces);
|
||||
}
|
||||
|
||||
var result = IndentCache[countOfSpaces];
|
||||
|
||||
if (result == null)
|
||||
{
|
||||
Interlocked.CompareExchange(ref IndentCache[countOfSpaces], new string(' ', countOfSpaces), comparand : null);
|
||||
result = IndentCache[countOfSpaces];
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,91 @@
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
using Markdig;
|
||||
using Markdig.Renderers;
|
||||
using Markdig.Syntax;
|
||||
|
||||
namespace Microsoft.PowerShell.MarkdownRender
|
||||
{
|
||||
/// <summary>
|
||||
/// Type of conversion from Markdown.
|
||||
/// </summary>
|
||||
[Flags]
|
||||
public enum MarkdownConversionType
|
||||
{
|
||||
/// <summary>
|
||||
/// Convert to HTML.
|
||||
/// </summary>
|
||||
HTML = 1,
|
||||
|
||||
/// <summary>
|
||||
/// Convert to VT100 encoded string.
|
||||
/// </summary>
|
||||
VT100 = 2
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Object representing the conversion from Markdown.
|
||||
/// </summary>
|
||||
public class MarkdownInfo
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the Html content after conversion.
|
||||
/// </summary>
|
||||
public string Html { get; internal set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the VT100 encoded string after conversion.
|
||||
/// </summary>
|
||||
public string VT100EncodedString { get; internal set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the AST of the Markdown string.
|
||||
/// </summary>
|
||||
public Markdig.Syntax.MarkdownDocument Tokens { get; internal set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Class to convert a Markdown string to VT100, HTML or AST.
|
||||
/// </summary>
|
||||
public sealed class MarkdownConverter
|
||||
{
|
||||
/// <summary>
|
||||
/// Convert from Markdown string to VT100 encoded string or HTML. Returns MarkdownInfo object.
|
||||
/// </summary>
|
||||
/// <param name="markdownString">String with Markdown content to be converted.</param>
|
||||
/// <param name="conversionType">Specifies type of conversion, either VT100 or HTML.</param>
|
||||
/// <param name="optionInfo">Specifies the rendering options for VT100 rendering.</param>
|
||||
/// <returns>MarkdownInfo object with the converted output.</returns>
|
||||
public static MarkdownInfo Convert(string markdownString, MarkdownConversionType conversionType, MarkdownOptionInfo optionInfo)
|
||||
{
|
||||
var renderInfo = new MarkdownInfo();
|
||||
var writer = new StringWriter();
|
||||
MarkdownPipeline pipeline = null;
|
||||
|
||||
if (conversionType.HasFlag(MarkdownConversionType.HTML))
|
||||
{
|
||||
pipeline = new MarkdownPipelineBuilder().UseAdvancedExtensions().Build();
|
||||
var renderer = new Markdig.Renderers.HtmlRenderer(writer);
|
||||
renderInfo.Html = Markdig.Markdown.Convert(markdownString, renderer, pipeline).ToString();
|
||||
}
|
||||
|
||||
if (conversionType.HasFlag(MarkdownConversionType.VT100))
|
||||
{
|
||||
pipeline = new MarkdownPipelineBuilder().Build();
|
||||
|
||||
// Use the VT100 renderer.
|
||||
var renderer = new VT100Renderer(writer, optionInfo);
|
||||
renderInfo.VT100EncodedString = Markdig.Markdown.Convert(markdownString, renderer, pipeline).ToString();
|
||||
}
|
||||
|
||||
// Always have AST available.
|
||||
var parsed = Markdig.Markdown.Parse(markdownString, pipeline);
|
||||
renderInfo.Tokens = parsed;
|
||||
|
||||
return renderInfo;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk" ToolsVersion="15.0">
|
||||
<Import Project="..\..\PowerShell.Common.props" />
|
||||
|
||||
<PropertyGroup>
|
||||
<Description>PowerShell Core's Markdown Rendering project</Description>
|
||||
<AssemblyName>Microsoft.PowerShell.MarkdownRender</AssemblyName>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<!-- Source: https://github.com/lunet-io/markdig/ -->
|
||||
<PackageReference Include="Markdig.Signed" Version="0.15.1" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
@@ -0,0 +1,26 @@
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
using Markdig;
|
||||
using Markdig.Renderers;
|
||||
using Markdig.Syntax;
|
||||
|
||||
namespace Microsoft.PowerShell.MarkdownRender
|
||||
{
|
||||
/// <summary>
|
||||
/// Renderer for adding VT100 escape sequences for paragraphs.
|
||||
/// </summary>
|
||||
internal class ParagraphBlockRenderer : VT100ObjectRenderer<ParagraphBlock>
|
||||
{
|
||||
protected override void Write(VT100Renderer renderer, ParagraphBlock obj)
|
||||
{
|
||||
// Call the renderer for children, leaf inline or line breaks.
|
||||
renderer.WriteChildren(obj.Inline);
|
||||
|
||||
// Add new line at the end of the paragraph.
|
||||
renderer.WriteLine();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
using Markdig;
|
||||
using Markdig.Renderers;
|
||||
using Markdig.Syntax;
|
||||
|
||||
namespace Microsoft.PowerShell.MarkdownRender
|
||||
{
|
||||
/// <summary>
|
||||
/// Renderer for adding VT100 escape sequences for quote blocks.
|
||||
/// </summary>
|
||||
internal class QuoteBlockRenderer : VT100ObjectRenderer<QuoteBlock>
|
||||
{
|
||||
protected override void Write(VT100Renderer renderer, QuoteBlock obj)
|
||||
{
|
||||
// Iterate through each item and add the quote character before the content.
|
||||
foreach (var item in obj)
|
||||
{
|
||||
renderer.Write(obj.QuoteChar).Write(" ").Write(item);
|
||||
}
|
||||
|
||||
// Add blank line after the quote block.
|
||||
renderer.WriteLine();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,407 @@
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
using Markdig;
|
||||
using Markdig.Renderers;
|
||||
using Markdig.Syntax;
|
||||
|
||||
namespace Microsoft.PowerShell.MarkdownRender
|
||||
{
|
||||
/// <summary>
|
||||
/// Enum to name all the properties of MarkdownOptionInfo.
|
||||
/// </summary>
|
||||
public enum MarkdownOptionInfoProperty
|
||||
{
|
||||
/// <summary>
|
||||
/// Property name Header1.
|
||||
/// </summary>
|
||||
Header1,
|
||||
|
||||
/// <summary>
|
||||
/// Property name Header2.
|
||||
/// </summary>
|
||||
Header2,
|
||||
|
||||
/// <summary>
|
||||
/// Property name Header3.
|
||||
/// </summary>
|
||||
Header3,
|
||||
|
||||
/// <summary>
|
||||
/// Property name Header4.
|
||||
/// </summary>
|
||||
Header4,
|
||||
|
||||
/// <summary>
|
||||
/// Property name Header5.
|
||||
/// </summary>
|
||||
Header5,
|
||||
|
||||
/// <summary>
|
||||
/// Property name Header6.
|
||||
/// </summary>
|
||||
Header6,
|
||||
|
||||
/// <summary>
|
||||
/// Property name Code.
|
||||
/// </summary>
|
||||
Code,
|
||||
|
||||
/// <summary>
|
||||
/// Property name Link.
|
||||
/// </summary>
|
||||
Link,
|
||||
|
||||
/// <summary>
|
||||
/// Property name Image.
|
||||
/// </summary>
|
||||
Image,
|
||||
|
||||
/// <summary>
|
||||
/// Property name EmphasisBold.
|
||||
/// </summary>
|
||||
EmphasisBold,
|
||||
|
||||
/// <summary>
|
||||
/// Property name EmphasisItalics.
|
||||
/// </summary>
|
||||
EmphasisItalics
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Class to represent color preference options for various Markdown elements.
|
||||
/// </summary>
|
||||
public sealed class MarkdownOptionInfo
|
||||
{
|
||||
private const char Esc = (char)0x1b;
|
||||
private const string EndSequence = "[0m";
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets current VT100 escape sequence for header 1.
|
||||
/// </summary>
|
||||
public string Header1 { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets current VT100 escape sequence for header 2.
|
||||
/// </summary>
|
||||
public string Header2 { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets current VT100 escape sequence for header 3.
|
||||
/// </summary>
|
||||
public string Header3 { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets current VT100 escape sequence for header 4.
|
||||
/// </summary>
|
||||
public string Header4 { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets current VT100 escape sequence for header 5.
|
||||
/// </summary>
|
||||
public string Header5 { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets current VT100 escape sequence for header 6.
|
||||
/// </summary>
|
||||
public string Header6 { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets current VT100 escape sequence for code inline and code blocks.
|
||||
/// </summary>
|
||||
public string Code { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets current VT100 escape sequence for links.
|
||||
/// </summary>
|
||||
public string Link { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets current VT100 escape sequence for images.
|
||||
/// </summary>
|
||||
public string Image { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets current VT100 escape sequence for bold text.
|
||||
/// </summary>
|
||||
public string EmphasisBold { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets current VT100 escape sequence for italics text.
|
||||
/// </summary>
|
||||
public string EmphasisItalics { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Get the property as an rendered escape sequence.
|
||||
/// This is used for typesps1xml for displaying.
|
||||
/// </summary>
|
||||
/// <param name="propertyName">Name of the property to get as escape sequence.</param>
|
||||
/// <returns>Specified property name as escape sequence.</returns>
|
||||
public string AsEscapeSequence(MarkdownOptionInfoProperty propertyName)
|
||||
{
|
||||
switch (propertyName)
|
||||
{
|
||||
case MarkdownOptionInfoProperty.Header1:
|
||||
return string.Concat(Esc, Header1, Header1, Esc, EndSequence);
|
||||
|
||||
case MarkdownOptionInfoProperty.Header2:
|
||||
return string.Concat(Esc, Header2, Header2, Esc, EndSequence);
|
||||
|
||||
case MarkdownOptionInfoProperty.Header3:
|
||||
return string.Concat(Esc, Header3, Header3, Esc, EndSequence);
|
||||
|
||||
case MarkdownOptionInfoProperty.Header4:
|
||||
return string.Concat(Esc, Header4, Header4, Esc, EndSequence);
|
||||
|
||||
case MarkdownOptionInfoProperty.Header5:
|
||||
return string.Concat(Esc, Header5, Header5, Esc, EndSequence);
|
||||
|
||||
case MarkdownOptionInfoProperty.Header6:
|
||||
return string.Concat(Esc, Header6, Header6, Esc, EndSequence);
|
||||
|
||||
case MarkdownOptionInfoProperty.Code:
|
||||
return string.Concat(Esc, Code, Code, Esc, EndSequence);
|
||||
|
||||
case MarkdownOptionInfoProperty.Link:
|
||||
return string.Concat(Esc, Link, Link, Esc, EndSequence);
|
||||
|
||||
case MarkdownOptionInfoProperty.Image:
|
||||
return string.Concat(Esc, Image, Image, Esc, EndSequence);
|
||||
|
||||
case MarkdownOptionInfoProperty.EmphasisBold:
|
||||
return string.Concat(Esc, EmphasisBold, EmphasisBold, Esc, EndSequence);
|
||||
|
||||
case MarkdownOptionInfoProperty.EmphasisItalics:
|
||||
return string.Concat(Esc, EmphasisItalics, EmphasisItalics, Esc, EndSequence);
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of <see cref="MarkdownOptionInfo"/> class and sets dark as the default theme.
|
||||
/// </summary>
|
||||
public MarkdownOptionInfo()
|
||||
{
|
||||
SetDarkTheme();
|
||||
}
|
||||
|
||||
private const string Header1Dark = "[7m";
|
||||
private const string Header2Dark = "[4;93m";
|
||||
private const string Header3Dark = "[4;94m";
|
||||
private const string Header4Dark = "[4;95m";
|
||||
private const string Header5Dark = "[4;96m";
|
||||
private const string Header6Dark = "[4;97m";
|
||||
private const string CodeDark = "[48;2;155;155;155;38;2;30;30;30m";
|
||||
private const string LinkDark = "[4;38;5;117m";
|
||||
private const string ImageDark = "[33m";
|
||||
private const string EmphasisBoldDark = "[1m";
|
||||
private const string EmphasisItalicsDark = "[36m";
|
||||
|
||||
private const string Header1Light = "[7m";
|
||||
private const string Header2Light = "[4;33m";
|
||||
private const string Header3Light = "[4;34m";
|
||||
private const string Header4Light = "[4;35m";
|
||||
private const string Header5Light = "[4;36m";
|
||||
private const string Header6Light = "[4;30m";
|
||||
private const string CodeLight = "[48;2;155;155;155;38;2;30;30;30m";
|
||||
private const string LinkLight = "[4;38;5;117m";
|
||||
private const string ImageLight = "[33m";
|
||||
private const string EmphasisBoldLight = "[1m";
|
||||
private const string EmphasisItalicsLight = "[36m";
|
||||
|
||||
/// <summary>
|
||||
/// Set all preference for dark theme.
|
||||
/// </summary>
|
||||
public void SetDarkTheme()
|
||||
{
|
||||
Header1 = Header1Dark;
|
||||
Header2 = Header2Dark;
|
||||
Header3 = Header3Dark;
|
||||
Header4 = Header4Dark;
|
||||
Header5 = Header5Dark;
|
||||
Header6 = Header6Dark;
|
||||
Code = CodeDark;
|
||||
Link = LinkDark;
|
||||
Image = ImageDark;
|
||||
EmphasisBold = EmphasisBoldDark;
|
||||
EmphasisItalics = EmphasisItalicsDark;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Set all preference for light theme.
|
||||
/// </summary>
|
||||
public void SetLightTheme()
|
||||
{
|
||||
Header1 = Header1Light;
|
||||
Header2 = Header2Light;
|
||||
Header3 = Header3Light;
|
||||
Header4 = Header4Light;
|
||||
Header5 = Header5Light;
|
||||
Header6 = Header6Light;
|
||||
Code = CodeLight;
|
||||
Link = LinkLight;
|
||||
Image = ImageLight;
|
||||
EmphasisBold = EmphasisBoldLight;
|
||||
EmphasisItalics = EmphasisItalicsLight;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Class to represent default VT100 escape sequences.
|
||||
/// </summary>
|
||||
public class VT100EscapeSequences
|
||||
{
|
||||
private const char Esc = (char)0x1B;
|
||||
private string endSequence = Esc + "[0m";
|
||||
|
||||
// For code blocks, [500@ make sure that the whole line has background color.
|
||||
private const string LongBackgroundCodeBlock = "[500@";
|
||||
private MarkdownOptionInfo options;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="VT100EscapeSequences"/> class.
|
||||
/// </summary>
|
||||
/// <param name="optionInfo">MarkdownOptionInfo object to initialize with.</param>
|
||||
public VT100EscapeSequences(MarkdownOptionInfo optionInfo)
|
||||
{
|
||||
if (optionInfo == null)
|
||||
{
|
||||
throw new ArgumentNullException("optionInfo");
|
||||
}
|
||||
|
||||
options = optionInfo;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Class to represent default VT100 escape sequences.
|
||||
/// </summary>
|
||||
/// <param name="headerText">Text of the header to format.</param>
|
||||
/// <returns>Formatted Header 1 string.</returns>
|
||||
public string FormatHeader1(string headerText)
|
||||
{
|
||||
return string.Concat(Esc, options.Header1, headerText, endSequence);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Class to represent default VT100 escape sequences.
|
||||
/// </summary>
|
||||
/// <param name="headerText">Text of the header to format.</param>
|
||||
/// <returns>Formatted Header 2 string.</returns>
|
||||
public string FormatHeader2(string headerText)
|
||||
{
|
||||
return string.Concat(Esc, options.Header2, headerText, endSequence);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Class to represent default VT100 escape sequences.
|
||||
/// </summary>
|
||||
/// <param name="headerText">Text of the header to format.</param>
|
||||
/// <returns>Formatted Header 3 string.</returns>
|
||||
public string FormatHeader3(string headerText)
|
||||
{
|
||||
return string.Concat(Esc, options.Header3, headerText, endSequence);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Class to represent default VT100 escape sequences.
|
||||
/// </summary>
|
||||
/// <param name="headerText">Text of the header to format.</param>
|
||||
/// <returns>Formatted Header 4 string.</returns>
|
||||
public string FormatHeader4(string headerText)
|
||||
{
|
||||
return string.Concat(Esc, options.Header4, headerText, endSequence);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Class to represent default VT100 escape sequences.
|
||||
/// </summary>
|
||||
/// <param name="headerText">Text of the header to format.</param>
|
||||
/// <returns>Formatted Header 5 string.</returns>
|
||||
public string FormatHeader5(string headerText)
|
||||
{
|
||||
return string.Concat(Esc, options.Header5, headerText, endSequence);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Class to represent default VT100 escape sequences.
|
||||
/// </summary>
|
||||
/// <param name="headerText">Text of the header to format.</param>
|
||||
/// <returns>Formatted Header 6 string.</returns>
|
||||
public string FormatHeader6(string headerText)
|
||||
{
|
||||
return string.Concat(Esc, options.Header6, headerText, endSequence);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Class to represent default VT100 escape sequences.
|
||||
/// </summary>
|
||||
/// <param name="codeText">Text of the code block to format.</param>
|
||||
/// <param name="isInline">True if it is a inline code block, false otherwise.</param>
|
||||
/// <returns>Formatted code block string.</returns>
|
||||
public string FormatCode(string codeText, bool isInline)
|
||||
{
|
||||
if (isInline)
|
||||
{
|
||||
return string.Concat(Esc, options.Code, codeText, endSequence);
|
||||
}
|
||||
else
|
||||
{
|
||||
return string.Concat(Esc, options.Code, codeText, Esc, LongBackgroundCodeBlock, endSequence);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Class to represent default VT100 escape sequences.
|
||||
/// </summary>
|
||||
/// <param name="linkText">Text of the link to format.</param>
|
||||
/// <param name="url">URL of the link.</param>
|
||||
/// <param name="hideUrl">True url should be hidden, false otherwise. Default is true.</param>
|
||||
/// <returns>Formatted link string.</returns>
|
||||
public string FormatLink(string linkText, string url, bool hideUrl = true)
|
||||
{
|
||||
if (hideUrl)
|
||||
{
|
||||
return string.Concat(Esc, options.Link, "\"", linkText, "\"", endSequence);
|
||||
}
|
||||
else
|
||||
{
|
||||
return string.Concat("\"", linkText, "\" (", Esc, options.Link, url, endSequence, ")");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Class to represent default VT100 escape sequences.
|
||||
/// </summary>
|
||||
/// <param name="emphasisText">Text to format as emphasis.</param>
|
||||
/// <param name="isBold">True if it is to be formatted as bold, false to format it as italics.</param>
|
||||
/// <returns>Formatted emphasis string.</returns>
|
||||
public string FormatEmphasis(string emphasisText, bool isBold)
|
||||
{
|
||||
var sequence = isBold ? options.EmphasisBold : options.EmphasisItalics;
|
||||
return string.Concat(Esc, sequence, emphasisText, endSequence);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Class to represent default VT100 escape sequences.
|
||||
/// </summary>
|
||||
/// <param name="altText">Text of the image to format.</param>
|
||||
/// <returns>Formatted image string.</returns>
|
||||
public string FormatImage(string altText)
|
||||
{
|
||||
var text = altText;
|
||||
|
||||
if (string.IsNullOrEmpty(altText))
|
||||
{
|
||||
text = "Image";
|
||||
}
|
||||
|
||||
return string.Concat(Esc, options.Image, "[", text, "]", endSequence);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
using Markdig;
|
||||
using Markdig.Renderers;
|
||||
using Markdig.Syntax;
|
||||
|
||||
namespace Microsoft.PowerShell.MarkdownRender
|
||||
{
|
||||
/// <summary>
|
||||
/// Implement the MarkdownObjectRenderer with VT100Renderer.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The element type of the renderer.</typeparam>
|
||||
public abstract class VT100ObjectRenderer<T> : MarkdownObjectRenderer<VT100Renderer, T> where T : MarkdownObject
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
using Markdig;
|
||||
using Markdig.Renderers;
|
||||
using Markdig.Syntax;
|
||||
|
||||
namespace Microsoft.PowerShell.MarkdownRender
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes an instance of the VT100 renderer.
|
||||
/// </summary>
|
||||
public sealed class VT100Renderer : TextRendererBase<VT100Renderer>
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="VT100Renderer"/> class.
|
||||
/// </summary>
|
||||
/// <param name="writer">TextWriter to write to.</param>
|
||||
/// <param name="optionInfo">MarkdownOptionInfo object with options.</param>
|
||||
public VT100Renderer(TextWriter writer, MarkdownOptionInfo optionInfo) : base(writer)
|
||||
{
|
||||
EscapeSequences = new VT100EscapeSequences(optionInfo);
|
||||
|
||||
// Add the various element renderers.
|
||||
ObjectRenderers.Add(new HeaderBlockRenderer());
|
||||
ObjectRenderers.Add(new LineBreakRenderer());
|
||||
ObjectRenderers.Add(new CodeInlineRenderer());
|
||||
ObjectRenderers.Add(new FencedCodeBlockRenderer());
|
||||
ObjectRenderers.Add(new EmphasisInlineRenderer());
|
||||
ObjectRenderers.Add(new ParagraphBlockRenderer());
|
||||
ObjectRenderers.Add(new LeafInlineRenderer());
|
||||
ObjectRenderers.Add(new LinkInlineRenderer());
|
||||
ObjectRenderers.Add(new ListBlockRenderer());
|
||||
ObjectRenderers.Add(new ListItemBlockRenderer());
|
||||
ObjectRenderers.Add(new QuoteBlockRenderer());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the current escape sequences.
|
||||
/// </summary>
|
||||
public VT100EscapeSequences EscapeSequences { get; private set; }
|
||||
}
|
||||
}
|
||||
@@ -24,7 +24,7 @@ CmdletsToExport= "Format-List", "Format-Custom", "Format-Table", "Format-Wide",
|
||||
"Send-MailMessage", "Get-TraceSource", "Set-TraceSource", "Trace-Command", "Get-FileHash",
|
||||
"Get-Runspace", "Debug-Runspace", "Enable-RunspaceDebug", "Disable-RunspaceDebug",
|
||||
"Get-RunspaceDebug", "Wait-Debugger" , "Get-Uptime", "New-TemporaryFile", "Get-Verb", "Format-Hex",
|
||||
"Test-Json", "Remove-Alias"
|
||||
"Test-Json", "Remove-Alias", "ConvertFrom-Markdown", "Show-Markdown", "Set-MarkdownOption", "Get-MarkdownOption"
|
||||
FunctionsToExport= "Import-PowerShellDataFile"
|
||||
AliasesToExport= "fhx"
|
||||
NestedModules="Microsoft.PowerShell.Commands.Utility.dll","Microsoft.PowerShell.Utility.psm1"
|
||||
|
||||
@@ -24,7 +24,7 @@ CmdletsToExport= "Format-List", "Format-Custom", "Format-Table", "Format-Wide",
|
||||
"Send-MailMessage", "Get-TraceSource", "Set-TraceSource", "Trace-Command", "Get-FileHash",
|
||||
"Unblock-File", "Get-Runspace", "Debug-Runspace", "Enable-RunspaceDebug", "Disable-RunspaceDebug",
|
||||
"Get-RunspaceDebug", "Wait-Debugger" , "Get-Uptime", "Get-Verb", "Format-Hex",
|
||||
"Test-Json", "Remove-Alias"
|
||||
"Test-Json", "Remove-Alias", "ConvertFrom-Markdown", "Show-Markdown", "Set-MarkdownOption", "Get-MarkdownOption"
|
||||
FunctionsToExport= "ConvertFrom-SddlString"
|
||||
AliasesToExport= "fhx"
|
||||
NestedModules="Microsoft.PowerShell.Commands.Utility.dll","Microsoft.PowerShell.Utility.psm1"
|
||||
|
||||
@@ -114,6 +114,31 @@ namespace System.Management.Automation.Runspaces
|
||||
var td15 = new TypeData(@"Deserialized.System.Management.Automation.DebuggerStopEventArgs", true);
|
||||
td15.TargetTypeForDeserialization = typeof(Microsoft.PowerShell.DeserializingTypeConverter);
|
||||
yield return td15;
|
||||
|
||||
var td16 = new TypeData(@"Microsoft.PowerShell.MarkdownRender.MarkdownOptionInfo");
|
||||
td16.Members.Add("Header1",
|
||||
new ScriptPropertyData(@"Header1", GetScriptBlock(@"$this.AsEscapeSequence('Header1')"), setScriptBlock: null));
|
||||
td16.Members.Add("Header2",
|
||||
new ScriptPropertyData(@"Header2", GetScriptBlock(@"$this.AsEscapeSequence('Header2')"), setScriptBlock: null));
|
||||
td16.Members.Add("Header3",
|
||||
new ScriptPropertyData(@"Header3", GetScriptBlock(@"$this.AsEscapeSequence('Header3')"), setScriptBlock: null));
|
||||
td16.Members.Add("Header4",
|
||||
new ScriptPropertyData(@"Header4", GetScriptBlock(@"$this.AsEscapeSequence('Header4')"), setScriptBlock: null));
|
||||
td16.Members.Add("Header5",
|
||||
new ScriptPropertyData(@"Header5", GetScriptBlock(@"$this.AsEscapeSequence('Header5')"), setScriptBlock: null));
|
||||
td16.Members.Add("Header6",
|
||||
new ScriptPropertyData(@"Header6", GetScriptBlock(@"$this.AsEscapeSequence('Header6')"), setScriptBlock: null));
|
||||
td16.Members.Add("Code",
|
||||
new ScriptPropertyData(@"Code", GetScriptBlock(@"$this.AsEscapeSequence('Code')"), setScriptBlock: null));
|
||||
td16.Members.Add("Link",
|
||||
new ScriptPropertyData(@"Link", GetScriptBlock(@"$this.AsEscapeSequence('Link')"), setScriptBlock: null));
|
||||
td16.Members.Add("Image",
|
||||
new ScriptPropertyData(@"Image", GetScriptBlock(@"$this.AsEscapeSequence('Image')"), setScriptBlock: null));
|
||||
td16.Members.Add("EmphasisBold",
|
||||
new ScriptPropertyData(@"EmphasisBold", GetScriptBlock(@"$this.AsEscapeSequence('EmphasisBold')"), setScriptBlock: null));
|
||||
td16.Members.Add("EmphasisItalics",
|
||||
new ScriptPropertyData(@"EmphasisItalics", GetScriptBlock(@"$this.AsEscapeSequence('EmphasisItalics')"), setScriptBlock: null));
|
||||
yield return td16;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1449,6 +1449,8 @@ namespace System.Management.Automation.Internal
|
||||
internal static bool StopwatchIsNotHighResolution;
|
||||
internal static bool DisableGACLoading;
|
||||
|
||||
internal static bool ShowMarkdownOutputBypass;
|
||||
|
||||
/// <summary>This member is used for internal test purposes.</summary>
|
||||
public static void SetTestHook(string property, object value)
|
||||
{
|
||||
|
||||
@@ -682,7 +682,6 @@ namespace NativeMsh
|
||||
"Microsoft.PowerShell.Commands.Utility",
|
||||
"Microsoft.PowerShell.ConsoleHost",
|
||||
"Microsoft.PowerShell.CoreCLR.Eventing",
|
||||
"Microsoft.PowerShell.MarkdownRender",
|
||||
"Microsoft.PowerShell.SDK",
|
||||
"Microsoft.PowerShell.Security",
|
||||
"Microsoft.VisualBasic",
|
||||
|
||||
@@ -0,0 +1,339 @@
|
||||
# Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
# Licensed under the MIT License.
|
||||
|
||||
Describe 'ConvertFrom-Markdown tests' -Tags 'CI' {
|
||||
|
||||
BeforeAll {
|
||||
$esc = [char]0x1b
|
||||
|
||||
function GetExpectedString
|
||||
{
|
||||
[CmdletBinding()]
|
||||
param(
|
||||
[ValidateSet(
|
||||
"Header1", "Header2", "Header3", "Header4", "Header5", "Header6",
|
||||
"Code", "CodeBlock",
|
||||
"Link", "Image",
|
||||
"Bold", "Italics")]
|
||||
[Parameter()]
|
||||
[string] $ElementType,
|
||||
|
||||
[string] $Text,
|
||||
|
||||
[string] $CodeFormatString,
|
||||
|
||||
[string] $CodeText
|
||||
)
|
||||
|
||||
switch($elementType)
|
||||
{
|
||||
"Header1" { "$esc[7m$text$esc[0m`n`n" }
|
||||
"Header2" { "$esc[4;93m$text$esc[0m`n`n" }
|
||||
"Header3" { "$esc[4;94m$text$esc[0m`n`n" }
|
||||
"Header4" { "$esc[4;95m$text$esc[0m`n`n" }
|
||||
"Header5" { "$esc[4;96m$text$esc[0m`n`n" }
|
||||
"Header6" { "$esc[4;97m$text$esc[0m`n`n" }
|
||||
|
||||
"Code" { ($CodeFormatString -f "$esc[48;2;155;155;155;38;2;30;30;30m$CodeText$esc[0m") + "`n`n" }
|
||||
"CodeBlock" {
|
||||
$expectedString = @()
|
||||
$CodeText -split "`n" | ForEach-Object { $expectedString += "$esc[48;2;155;155;155;38;2;30;30;30m$_$esc[500@$esc[0m" }
|
||||
$returnString = $expectedString -join "`n"
|
||||
"$returnString`n`n"
|
||||
}
|
||||
|
||||
"Link" { "$esc[4;38;5;117m`"$text`"$esc[0m`n" }
|
||||
"Image" { "$esc[33m[$text]$esc[0m`n" }
|
||||
"Bold" { "$esc[1m$text$esc[0m`n" }
|
||||
"Italics" { "$esc[36m$text$esc[0m`n" }
|
||||
}
|
||||
}
|
||||
|
||||
function GetExpectedHTML
|
||||
{
|
||||
[CmdletBinding()]
|
||||
param(
|
||||
[ValidateSet(
|
||||
"Header1", "Header2", "Header3", "Header4", "Header5", "Header6",
|
||||
"Code", "CodeBlock",
|
||||
"Link", "Image",
|
||||
"Bold", "Italics")]
|
||||
[Parameter()]
|
||||
[string] $ElementType,
|
||||
|
||||
[string] $Text,
|
||||
|
||||
[string] $Url,
|
||||
|
||||
[string] $CodeFormatString,
|
||||
|
||||
[string] $CodeText
|
||||
)
|
||||
|
||||
$id = $Text.Replace(" ","-").ToLowerInvariant()
|
||||
|
||||
switch($elementType)
|
||||
{
|
||||
"Header1" { "<h1 id=`"$id`">$text</h1>`n" }
|
||||
"Header2" { "<h2 id=`"$id`">$text</h2>`n" }
|
||||
"Header3" { "<h3 id=`"$id`">$text</h3>`n" }
|
||||
"Header4" { "<h4 id=`"$id`">$text</h4>`n" }
|
||||
"Header5" { "<h5 id=`"$id`">$text</h5>`n" }
|
||||
"Header6" { "<h6 id=`"$id`">$text</h6>`n" }
|
||||
|
||||
"Code" { "<p>" + ($CodeFormatString -f "<code>$CodeText</code>") + "</p>`n" }
|
||||
"CodeBlock" { "<pre><code>$CodeText`n</code></pre>`n" }
|
||||
|
||||
"Link" { "<p><a href=`"$Url`">$text</a></p>`n" }
|
||||
"Image" { "<p><img src=`"$url`" alt=`"$text`" /></p>`n" }
|
||||
"Bold" { "<p><strong>$text</strong></p>`n" }
|
||||
"Italics" { "<p><em>$text</em></p>`n" }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Context 'Basic tests' {
|
||||
BeforeAll {
|
||||
$esc = [char]0x1b
|
||||
$mdFile = New-Item -Path $TestDrive/input.md -Value "Some **test string** to write in a file" -Force
|
||||
$mdLiteralPath = New-Item -Path $TestDrive/LiteralPath.md -Value "Some **test string** to write in a file" -Force
|
||||
$expectedStringFromFile = "Some $esc[1mtest string$esc[0m to write in a file`n`n"
|
||||
|
||||
$codeBlock = @'
|
||||
```
|
||||
bool function()
|
||||
{
|
||||
}
|
||||
```
|
||||
'@
|
||||
|
||||
$codeBlockText = @"
|
||||
bool function()`n{`n}
|
||||
"@
|
||||
|
||||
$TestCases = @(
|
||||
@{ element = 'Header1'; InputMD = '# Header 1'; Text = 'Header 1' }
|
||||
@{ element = 'Header2'; InputMD = '## Header 2'; Text = 'Header 2' }
|
||||
@{ element = 'Header3'; InputMD = '### Header 3'; Text = 'Header 3' }
|
||||
@{ element = 'Header4'; InputMD = '#### Header 4'; Text = 'Header 4' }
|
||||
@{ element = 'Header5'; InputMD = '##### Header 5'; Text = 'Header 5' }
|
||||
@{ element = 'Header6'; InputMD = '###### Header 6'; Text = 'Header 6' }
|
||||
@{ element = 'Code'; InputMD = 'This is a `code` sample'; CodeFormatString = 'This is a {0} sample'; CodeText = 'code'}
|
||||
@{ element = 'CodeBlock'; InputMD = $codeBlock; CodeText = $codeBlockText }
|
||||
@{ element = 'Link'; InputMD = '[GitHub](https://www.github.com)'; Text = 'GitHub'; Url = 'https://www.github.com'}
|
||||
@{ element = 'Image'; InputMD = ''; Text = 'alt-text'; Url = 'https://bing.com/ps.svg'}
|
||||
@{ element = 'Bold'; InputMD = '**bold text**'; Text = 'bold text' }
|
||||
@{ element = 'Italics'; InputMD = '*italics text*'; Text = 'italics text' }
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
It 'Can convert element : <element> to vt100 using pipeline input' -TestCases $TestCases {
|
||||
param($element, $inputMD, $text, $codeFormatString, $codeText)
|
||||
|
||||
$output = $inputMD | ConvertFrom-Markdown -AsVT100EncodedString
|
||||
|
||||
if($element -like 'Header?' -or
|
||||
$element -eq 'Link' -or
|
||||
$element -eq 'Image' -or
|
||||
$element -eq 'Bold' -or
|
||||
$element -eq 'Italics')
|
||||
{
|
||||
$expectedString = GetExpectedString -ElementType $element -Text $text
|
||||
}
|
||||
elseif($element -eq 'Code')
|
||||
{
|
||||
$expectedString = GetExpectedString -ElementType $element -CodeFormatString $codeFormatString -CodeText $codeText
|
||||
}
|
||||
elseif($element -eq 'CodeBlock')
|
||||
{
|
||||
$expectedString = GetExpectedString -ElementType $element -CodeText $codeText
|
||||
}
|
||||
|
||||
$output.VT100EncodedString | Should -BeExactly $expectedString
|
||||
}
|
||||
|
||||
It 'Can convert element : <element> to HTML using pipeline input' -TestCases $TestCases {
|
||||
param($element, $inputMD, $text, $codeFormatString, $codeText, $url)
|
||||
|
||||
$output = $inputMD | ConvertFrom-Markdown
|
||||
|
||||
if($element -like 'Header?' -or
|
||||
$element -eq 'Bold' -or
|
||||
$element -eq 'Italics')
|
||||
{
|
||||
$expectedString = GetExpectedHTML -ElementType $element -Text $text
|
||||
}
|
||||
elseif($element -eq 'Code')
|
||||
{
|
||||
$expectedString = GetExpectedHTML -ElementType $element -CodeFormatString $codeFormatString -CodeText $codeText
|
||||
}
|
||||
elseif($element -eq 'CodeBlock')
|
||||
{
|
||||
$expectedString = GetExpectedHTML -ElementType $element -CodeText $codeText
|
||||
}
|
||||
elseif ($element -eq 'Link')
|
||||
{
|
||||
$expectedString = GetExpectedHTML -ElementType $element -Text $text -Url $url
|
||||
}
|
||||
elseif ($element -eq 'Image')
|
||||
{
|
||||
$expectedString = GetExpectedHTML -ElementType $element -Text $text -Url $url
|
||||
}
|
||||
|
||||
$output.Html | Should -BeExactly $expectedString
|
||||
}
|
||||
|
||||
It 'Can convert input from a file path to vt100 encoded string' {
|
||||
$output = ConvertFrom-Markdown -Path $mdFile.FullName -AsVT100EncodedString
|
||||
$output.VT100EncodedString | Should -BeExactly $expectedStringFromFile
|
||||
}
|
||||
|
||||
It 'Can convert input from a fileinfo object to vt100 encoded string' {
|
||||
$ouputFromFileInfo = $mdFile | ConvertFrom-Markdown -AsVT100EncodedString
|
||||
$ouputFromFileInfo.VT100EncodedString | Should -BeExactly $expectedStringFromFile
|
||||
}
|
||||
|
||||
It 'Can convert input from a literal path to vt100 encoded string' {
|
||||
$output = ConvertFrom-Markdown -Path $mdLiteralPath -AsVT100EncodedString
|
||||
$output.VT100EncodedString | Should -BeExactly $expectedStringFromFile
|
||||
}
|
||||
}
|
||||
|
||||
Context "ConvertFrom-Markdown error cases" {
|
||||
It "Gets an error if path is not FileSystem provider path" {
|
||||
{ ConvertFrom-Markdown -Path Env:\PSModulePath -ErrorAction Stop } | Should -Throw -ErrorId 'OnlyFileSystemPathsSupported,Microsoft.PowerShell.Commands.ConvertFromMarkdownCommand'
|
||||
}
|
||||
|
||||
It "Gets an error if path does not exist" {
|
||||
{ ConvertFrom-Markdown -Path DoestnotExist -ErrorAction Stop } | Should -Throw -ErrorId 'FileNotFound,Microsoft.PowerShell.Commands.ConvertFromMarkdownCommand'
|
||||
}
|
||||
|
||||
It "Gets an error if input object type is not correct" {
|
||||
{ ConvertFrom-Markdown -InputObject 1 -ErrorAction Stop } | Should -Throw -ErrorId 'InvalidInputObject,Microsoft.PowerShell.Commands.ConvertFromMarkdownCommand'
|
||||
}
|
||||
|
||||
It "Gets an error if input file does not exist" {
|
||||
{ [System.IO.FileInfo]::new("IDoNoExist") | ConvertFrom-Markdown -ErrorAction Stop } | Should -Throw -ErrorId 'FileNotFound,Microsoft.PowerShell.Commands.ConvertFromMarkdownCommand'
|
||||
}
|
||||
}
|
||||
|
||||
Context "Get/Set-MarkdownOption tests" {
|
||||
|
||||
BeforeAll {
|
||||
$esc = [char]0x1b
|
||||
}
|
||||
|
||||
BeforeEach {
|
||||
$originalOptions = Get-MarkdownOption
|
||||
}
|
||||
|
||||
AfterEach {
|
||||
Set-MarkdownOption -InputObject $originalOptions
|
||||
}
|
||||
|
||||
It "Verify default values for MarkdownOptions" {
|
||||
$options = Get-MarkdownOption
|
||||
|
||||
$options.Header1 | Should -BeExactly "$esc[7m[7m$esc[0m"
|
||||
$options.Header2 | Should -BeExactly "$esc[4;93m[4;93m$esc[0m"
|
||||
$options.Header3 | Should -BeExactly "$esc[4;94m[4;94m$esc[0m"
|
||||
$options.Header4 | Should -BeExactly "$esc[4;95m[4;95m$esc[0m"
|
||||
$options.Header5 | Should -BeExactly "$esc[4;96m[4;96m$esc[0m"
|
||||
$options.Header6 | Should -BeExactly "$esc[4;97m[4;97m$esc[0m"
|
||||
$options.Code | Should -BeExactly "$esc[48;2;155;155;155;38;2;30;30;30m[48;2;155;155;155;38;2;30;30;30m$esc[0m"
|
||||
$options.Link | Should -BeExactly "$esc[4;38;5;117m[4;38;5;117m$esc[0m"
|
||||
$options.Image | Should -BeExactly "$esc[33m[33m$esc[0m"
|
||||
$options.EmphasisBold | Should -BeExactly "$esc[1m[1m$esc[0m"
|
||||
$options.EmphasisItalics | Should -BeExactly "$esc[36m[36m$esc[0m"
|
||||
}
|
||||
|
||||
It "Verify Set-MarkdownOption can get options" {
|
||||
Set-MarkdownOption `
|
||||
-Header1Color "[4;1m" `
|
||||
-Header2Color "[93m" `
|
||||
-Header3Color "[94m" `
|
||||
-Header4Color "[95m" `
|
||||
-Header5Color "[96m" `
|
||||
-Header6Color "[97m" `
|
||||
-ImageAltTextForegroundColor "[34m" `
|
||||
-LinkForegroundColor "[4;38;5;88m" `
|
||||
-ItalicsForegroundColor "[35m" `
|
||||
-BoldForegroundColor "[32m"
|
||||
|
||||
$newOptions = Get-MarkdownOption
|
||||
|
||||
$newOptions.Header1 | Should -BeExactly "$esc[4;1m[4;1m$esc[0m"
|
||||
$newOptions.Header2 | Should -BeExactly "$esc[93m[93m$esc[0m"
|
||||
$newOptions.Header3 | Should -BeExactly "$esc[94m[94m$esc[0m"
|
||||
$newOptions.Header4 | Should -BeExactly "$esc[95m[95m$esc[0m"
|
||||
$newOptions.Header5 | Should -BeExactly "$esc[96m[96m$esc[0m"
|
||||
$newOptions.Header6 | Should -BeExactly "$esc[97m[97m$esc[0m"
|
||||
#$options.Code | Should -BeExactly "$esc[48;2;155;155;155;38;2;30;30;30m[48;2;155;155;155;38;2;30;30;30m$esc[0m"
|
||||
$newOptions.Link | Should -BeExactly "$esc[4;38;5;88m[4;38;5;88m$esc[0m"
|
||||
$newOptions.Image | Should -BeExactly "$esc[34m[34m$esc[0m"
|
||||
$newOptions.EmphasisBold | Should -BeExactly "$esc[32m[32m$esc[0m"
|
||||
$newOptions.EmphasisItalics | Should -BeExactly "$esc[35m[35m$esc[0m"
|
||||
}
|
||||
|
||||
It "Verify defaults for light theme" {
|
||||
Set-MarkdownOption -Theme Light
|
||||
$options = Get-MarkdownOption
|
||||
|
||||
$options.Header1 | Should -BeExactly "$esc[7m[7m$esc[0m"
|
||||
$options.Header2 | Should -BeExactly "$esc[4;33m[4;33m$esc[0m"
|
||||
$options.Header3 | Should -BeExactly "$esc[4;34m[4;34m$esc[0m"
|
||||
$options.Header4 | Should -BeExactly "$esc[4;35m[4;35m$esc[0m"
|
||||
$options.Header5 | Should -BeExactly "$esc[4;36m[4;36m$esc[0m"
|
||||
$options.Header6 | Should -BeExactly "$esc[4;30m[4;30m$esc[0m"
|
||||
$options.Code | Should -BeExactly "$esc[48;2;155;155;155;38;2;30;30;30m[48;2;155;155;155;38;2;30;30;30m$esc[0m"
|
||||
$options.Link | Should -BeExactly "$esc[4;38;5;117m[4;38;5;117m$esc[0m"
|
||||
$options.Image | Should -BeExactly "$esc[33m[33m$esc[0m"
|
||||
$options.EmphasisBold | Should -BeExactly "$esc[1m[1m$esc[0m"
|
||||
$options.EmphasisItalics | Should -BeExactly "$esc[36m[36m$esc[0m"
|
||||
}
|
||||
}
|
||||
|
||||
Context "Show-Markdown tests" {
|
||||
BeforeEach {
|
||||
[System.Management.Automation.Internal.InternalTestHooks]::SetTestHook("ShowMarkdownOutputBypass", $true)
|
||||
}
|
||||
|
||||
AfterEach {
|
||||
[System.Management.Automation.Internal.InternalTestHooks]::SetTestHook("ShowMarkdownOutputBypass", $false)
|
||||
}
|
||||
|
||||
It "can show VT100 converted from markdown" {
|
||||
$text = "Bold"
|
||||
$mdText = "**$text**"
|
||||
$expectedString = GetExpectedString -ElementType 'Bold' -Text $text
|
||||
|
||||
$result = $mdText | ConvertFrom-Markdown -AsVT100EncodedString | Show-Markdown
|
||||
$result | Should -BeExactly $expectedString
|
||||
}
|
||||
|
||||
It "can show HTML converted from markdown" {
|
||||
$text = "Bold"
|
||||
$mdText = "**$text**"
|
||||
$expectedString = GetExpectedHTML -ElementType 'Bold' -Text $text
|
||||
|
||||
$result = $mdText | ConvertFrom-Markdown | Show-Markdown -UseBrowser
|
||||
$result | Should -BeExactly $expectedString
|
||||
}
|
||||
|
||||
It "Gets an error if the input object is missing the <propertyname> property." -TestCases @(@{propertyname = 'Html'}, @{propertyname = 'VT100EncodedString'}) {
|
||||
param($propertyname)
|
||||
|
||||
$markdownInfo = [Microsoft.PowerShell.MarkdownRender.MarkdownInfo]::new()
|
||||
|
||||
if($propertyname -eq 'VT100EncodedString')
|
||||
{
|
||||
{ Show-Markdown -InputObject $markdownInfo -ErrorAction Stop } | Should -Throw -ErrorId 'VT100EncodedStringIsNullOrEmpty,Microsoft.PowerShell.Commands.ShowMarkdownCommand'
|
||||
}
|
||||
else
|
||||
{
|
||||
{ Show-Markdown -UseBrowser -InputObject $markdownInfo -ErrorAction Stop } | Should -Throw -ErrorId 'HtmlIsNullOrEmpty,Microsoft.PowerShell.Commands.ShowMarkdownCommand'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -191,6 +191,7 @@ Describe "Verify approved aliases list" -Tags "CI" {
|
||||
"Cmdlet", "Connect-WSMan", , $($FullCLR -or $CoreWindows )
|
||||
"Cmdlet", "ConvertFrom-Csv", , $($FullCLR -or $CoreWindows -or $CoreUnix)
|
||||
"Cmdlet", "ConvertFrom-Json", , $($FullCLR -or $CoreWindows -or $CoreUnix)
|
||||
"Cmdlet", "ConvertFrom-Markdown", , $($CoreWindows -or $CoreUnix)
|
||||
"Cmdlet", "ConvertFrom-SecureString", , $($FullCLR -or $CoreWindows -or $CoreUnix)
|
||||
"Cmdlet", "ConvertFrom-String", , $($FullCLR )
|
||||
"Cmdlet", "ConvertFrom-StringData", , $($FullCLR -or $CoreWindows -or $CoreUnix)
|
||||
@@ -270,6 +271,7 @@ Describe "Verify approved aliases list" -Tags "CI" {
|
||||
"Cmdlet", "Get-ItemPropertyValue", , $($FullCLR -or $CoreWindows -or $CoreUnix)
|
||||
"Cmdlet", "Get-Job", , $($FullCLR -or $CoreWindows -or $CoreUnix)
|
||||
"Cmdlet", "Get-Location", , $($FullCLR -or $CoreWindows -or $CoreUnix)
|
||||
"Cmdlet", "Get-MarkdownOption", , $($CoreWindows -or $CoreUnix)
|
||||
"Cmdlet", "Get-Member", , $($FullCLR -or $CoreWindows -or $CoreUnix)
|
||||
"Cmdlet", "Get-Module", , $($FullCLR -or $CoreWindows -or $CoreUnix)
|
||||
"Cmdlet", "Get-PfxCertificate", , $($FullCLR -or $CoreWindows -or $CoreUnix)
|
||||
@@ -408,6 +410,7 @@ Describe "Verify approved aliases list" -Tags "CI" {
|
||||
"Cmdlet", "Set-Item", , $($FullCLR -or $CoreWindows -or $CoreUnix)
|
||||
"Cmdlet", "Set-ItemProperty", , $($FullCLR -or $CoreWindows -or $CoreUnix)
|
||||
"Cmdlet", "Set-Location", , $($FullCLR -or $CoreWindows -or $CoreUnix)
|
||||
"Cmdlet", "Set-MarkdownOption", , $($CoreWindows -or $CoreUnix)
|
||||
"Cmdlet", "Set-PSBreakpoint", , $($FullCLR -or $CoreWindows -or $CoreUnix)
|
||||
"Cmdlet", "Set-PSDebug", , $($FullCLR -or $CoreWindows -or $CoreUnix)
|
||||
"Cmdlet", "Set-PSSessionConfiguration", , $($FullCLR -or $CoreWindows )
|
||||
@@ -422,6 +425,7 @@ Describe "Verify approved aliases list" -Tags "CI" {
|
||||
"Cmdlet", "Show-Command", , $($FullCLR )
|
||||
"Cmdlet", "Show-ControlPanelItem", , $($FullCLR )
|
||||
"Cmdlet", "Show-EventLog", , $($FullCLR )
|
||||
"Cmdlet", "Show-Markdown", , $($CoreWindows -or $CoreUnix)
|
||||
"Cmdlet", "Sort-Object", , $($FullCLR -or $CoreWindows -or $CoreUnix)
|
||||
"Cmdlet", "Split-Path", , $($FullCLR -or $CoreWindows -or $CoreUnix)
|
||||
"Cmdlet", "Start-Job", , $($FullCLR -or $CoreWindows -or $CoreUnix)
|
||||
|
||||
Reference in New Issue
Block a user