diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/ShowMarkdownCommand.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/ShowMarkdownCommand.cs
index 024e41d0620..35e157b74b0 100644
--- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/ShowMarkdownCommand.cs
+++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/ShowMarkdownCommand.cs
@@ -6,6 +6,7 @@
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics;
+using System.Globalization;
using System.IO;
using System.Management.Automation;
using System.Management.Automation.Internal;
@@ -20,6 +21,7 @@ namespace Microsoft.PowerShell.Commands
///
[Cmdlet(
VerbsCommon.Show, "Markdown",
+ DefaultParameterSetName = "Path",
HelpUri = "https://go.microsoft.com/fwlink/?linkid=2006266")]
[OutputType(typeof(string))]
public class ShowMarkdownCommand : PSCmdlet
@@ -28,28 +30,43 @@ public class ShowMarkdownCommand : PSCmdlet
/// Gets or sets InputObject of type Microsoft.PowerShell.MarkdownRender.MarkdownInfo to display.
///
[ValidateNotNullOrEmpty]
- [Parameter(Mandatory = true, ValueFromPipeline = true)]
+ [Parameter(Mandatory = true, ValueFromPipeline = true, ParameterSetName = "InputObject")]
public PSObject InputObject { get; set; }
+ ///
+ /// Gets or sets path to markdown file(s) to display.
+ ///
+ [ValidateNotNullOrEmpty]
+ [Parameter(Position = 0, Mandatory = true,
+ ValueFromPipelineByPropertyName = true, ParameterSetName = "Path")]
+ public string[] Path { get; set; }
+
+ ///
+ /// Gets or sets the literal path parameter to markdown files(s) to display.
+ ///
+ [Parameter(ParameterSetName = "LiteralPath",
+ Mandatory = true, ValueFromPipeline = false, ValueFromPipelineByPropertyName = true)]
+ [Alias("PSPath", "LP")]
+ public string[] LiteralPath
+ {
+ get { return Path; }
+ set { Path = value; }
+ }
+
///
/// Gets or sets the switch to view Html in default browser.
///
[Parameter]
public SwitchParameter UseBrowser { get; set; }
- private SteppablePipeline stepPipe;
+ private System.Management.Automation.PowerShell _powerShell;
///
/// Override BeginProcessing.
///
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);
- }
+ _powerShell = System.Management.Automation.PowerShell.Create(RunspaceMode.CurrentRunspace);
}
///
@@ -57,114 +74,148 @@ protected override void BeginProcessing()
///
protected override void ProcessRecord()
{
- object inpObj = InputObject.BaseObject;
+ switch (ParameterSetName)
+ {
+ case "InputObject":
+ if (InputObject.BaseObject is MarkdownInfo markdownInfo)
+ {
+ ProcessMarkdownInfo(markdownInfo);
+ }
+ else
+ {
+ ConvertFromMarkdown("InputObject", InputObject.BaseObject);
+ }
+
+ break;
- if (inpObj is MarkdownInfo markdownInfo)
+ case "Path":
+ case "LiteralPath":
+ ConvertFromMarkdown(ParameterSetName, Path);
+ break;
+
+ default:
+ throw new InvalidOperationException(string.Format(CultureInfo.InvariantCulture, ConvertMarkdownStrings.InvalidParameterSet, ParameterSetName));
+ }
+ }
+
+ ///
+ /// Process markdown as path.
+ ///
+ /// Name of parameter to pass to `ConvertFrom-Markdown`.
+ /// Value of parameter.
+ private void ConvertFromMarkdown(string parameter, object input)
+ {
+ _powerShell.AddCommand("Microsoft.PowerShell.Utility\\ConvertFrom-Markdown").AddParameter(parameter, input);
+ if (!UseBrowser)
{
- if (UseBrowser)
+ _powerShell.AddParameter("AsVT100EncodedString");
+ }
+
+ Collection output = _powerShell.Invoke();
+
+ if (_powerShell.HadErrors)
+ {
+ foreach (ErrorRecord errorRecord in _powerShell.Streams.Error)
{
- var html = markdownInfo.Html;
+ WriteError(errorRecord);
+ }
+ }
- if (!string.IsNullOrEmpty(html))
- {
- string tmpFilePath = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString() + ".html");
+ foreach (MarkdownInfo result in output)
+ {
+ ProcessMarkdownInfo(result);
+ }
+ }
- 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;
- }
+ ///
+ /// Process markdown as input objects.
+ ///
+ /// Markdown object to process.
+ private void ProcessMarkdownInfo(MarkdownInfo markdownInfo)
+ {
+ if (UseBrowser)
+ {
+ var html = markdownInfo.Html;
- if (InternalTestHooks.ShowMarkdownOutputBypass)
- {
- WriteObject(html);
- return;
- }
+ if (!string.IsNullOrEmpty(html))
+ {
+ string tmpFilePath = System.IO.Path.Combine(System.IO.Path.GetTempPath(), Guid.NewGuid().ToString() + ".html");
- try
- {
- ProcessStartInfo startInfo = new ProcessStartInfo();
- startInfo.FileName = tmpFilePath;
- startInfo.UseShellExecute = true;
- Process.Start(startInfo);
- }
- catch (Exception e)
+ try
+ {
+ using (var writer = new StreamWriter(new FileStream(tmpFilePath, FileMode.Create, FileAccess.Write, FileShare.Write)))
{
- var errorRecord = new ErrorRecord(
- e,
- "ErrorLaunchingDefaultApplication",
- ErrorCategory.InvalidOperation,
- targetObject : null);
-
- WriteError(errorRecord);
- return;
+ writer.Write(html);
}
}
- else
+ catch (Exception e)
{
- string errorMessage = StringUtil.Format(ConvertMarkdownStrings.MarkdownInfoInvalid, "Html");
var errorRecord = new ErrorRecord(
- new InvalidDataException(errorMessage),
- "HtmlIsNullOrEmpty",
- ErrorCategory.InvalidData,
- html);
+ e,
+ "ErrorWritingTempFile",
+ ErrorCategory.WriteError,
+ tmpFilePath);
WriteError(errorRecord);
+ return;
}
- }
- else
- {
- var vt100String = markdownInfo.VT100EncodedString;
- if (!string.IsNullOrEmpty(vt100String))
+ if (InternalTestHooks.ShowMarkdownOutputBypass)
{
- if (InternalTestHooks.ShowMarkdownOutputBypass)
- {
- WriteObject(vt100String);
- return;
- }
+ WriteObject(html);
+ return;
+ }
- if (stepPipe != null)
- {
- stepPipe.Process(vt100String);
- }
+ try
+ {
+ ProcessStartInfo startInfo = new ProcessStartInfo();
+ startInfo.FileName = tmpFilePath;
+ startInfo.UseShellExecute = true;
+ Process.Start(startInfo);
}
- else
+ catch (Exception e)
{
- string errorMessage = StringUtil.Format(ConvertMarkdownStrings.MarkdownInfoInvalid, "VT100EncodedString");
var errorRecord = new ErrorRecord(
- new InvalidDataException(errorMessage),
- "VT100EncodedStringIsNullOrEmpty",
- ErrorCategory.InvalidData,
- vt100String);
+ 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
{
- string errorMessage = StringUtil.Format(ConvertMarkdownStrings.InvalidInputObjectType, inpObj.GetType());
- var errorRecord = new ErrorRecord(
- new ArgumentException(errorMessage),
- "InvalidInputObject",
- ErrorCategory.InvalidArgument,
- InputObject);
-
- WriteError(errorRecord);
+ var vt100String = markdownInfo.VT100EncodedString;
+
+ if (!string.IsNullOrEmpty(vt100String))
+ {
+ WriteObject(vt100String);
+ }
+ else
+ {
+ string errorMessage = StringUtil.Format(ConvertMarkdownStrings.MarkdownInfoInvalid, "VT100EncodedString");
+ var errorRecord = new ErrorRecord(
+ new InvalidDataException(errorMessage),
+ "VT100EncodedStringIsNullOrEmpty",
+ ErrorCategory.InvalidData,
+ vt100String);
+
+ WriteError(errorRecord);
+ }
}
}
@@ -173,9 +224,9 @@ protected override void ProcessRecord()
///
protected override void EndProcessing()
{
- if (stepPipe != null)
+ if (_powerShell != null)
{
- stepPipe.End();
+ _powerShell.Dispose();
}
}
}
diff --git a/src/Microsoft.PowerShell.Commands.Utility/resources/ConvertMarkdownStrings.resx b/src/Microsoft.PowerShell.Commands.Utility/resources/ConvertMarkdownStrings.resx
index 14d745ee5f9..d37509d0f50 100644
--- a/src/Microsoft.PowerShell.Commands.Utility/resources/ConvertMarkdownStrings.resx
+++ b/src/Microsoft.PowerShell.Commands.Utility/resources/ConvertMarkdownStrings.resx
@@ -129,4 +129,7 @@
The property {0} of the given object is null or empty.
+
+ Invalid parameter set name: {0}.
+
diff --git a/test/powershell/Modules/Microsoft.PowerShell.Utility/MarkdownCmdlets.Tests.ps1 b/test/powershell/Modules/Microsoft.PowerShell.Utility/MarkdownCmdlets.Tests.ps1
index 246909b0deb..1d6d5fd4935 100644
--- a/test/powershell/Modules/Microsoft.PowerShell.Utility/MarkdownCmdlets.Tests.ps1
+++ b/test/powershell/Modules/Microsoft.PowerShell.Utility/MarkdownCmdlets.Tests.ps1
@@ -448,7 +448,7 @@ bool function()`n{`n}
[System.Management.Automation.Internal.InternalTestHooks]::SetTestHook("ShowMarkdownOutputBypass", $false)
}
- It "can show VT100 converted from markdown" {
+ It "Can show VT100 converted from markdown" {
$text = "Bold"
$mdText = "**$text**"
$expectedString = GetExpectedString -ElementType 'Bold' -Text $text -VT100Support $true
@@ -457,7 +457,7 @@ bool function()`n{`n}
$result | Should -BeExactly $expectedString
}
- It "can show HTML converted from markdown" {
+ It "Can show HTML converted from markdown" {
$text = "Bold"
$mdText = "**$text**"
$expectedString = GetExpectedHTML -ElementType 'Bold' -Text $text
@@ -466,7 +466,45 @@ bool function()`n{`n}
$result | Should -BeExactly $expectedString
}
- It "Gets an error if the input object is missing the property." -TestCases @(@{propertyname = 'Html'}, @{propertyname = 'VT100EncodedString'}) {
+ It "Markdown files work with cmdlet: " -TestCases @(
+ @{ pathParam = "Path" }
+ @{ pathParam = "LiteralPath" }
+ ) {
+ param($pathParam)
+
+ $text = "Header"
+ $mdText = "# $text"
+ $expectedString = GetExpectedString -ElementType Header1 -Text $text -VT100Support $true
+ $mdFile = Join-Path $TestDrive "test.md"
+ Set-Content -Path $mdFile -Value $mdText
+
+ $params = @{ $pathParam = $mdFile }
+ $result = Show-Markdown @params
+ $result | Should -BeExactly $expectedString
+ }
+
+ It "Can show markdown piped directly to cmdlet" {
+ $text = "Header"
+ $mdText = "# $text"
+ $expectedString = GetExpectedString -ElementType Header1 -Text $text -VT100Support $true
+
+ $result = $mdText | Show-Markdown
+ $result | Should -BeExactly $expectedString
+ }
+
+ It "Can show markdown piped directly to cmdlet as HTML" {
+ $text = "Header"
+ $mdText = "# $text"
+ $expectedString = GetExpectedHTML -ElementType Header1 -Text $text
+
+ $result = $mdText | Show-Markdown -UseBrowser
+ $result | Should -BeExactly $expectedString
+ }
+
+ It "Gets an error if the input object is missing the property." -TestCases @(
+ @{ propertyname = 'Html' }
+ @{ propertyname = 'VT100EncodedString' }
+ ) {
param($propertyname)
$markdownInfo = [Microsoft.PowerShell.MarkdownRender.MarkdownInfo]::new()