Skip to content

Commit b276b9a

Browse files
authored
Merge pull request #116 from adityapatwardhan/MDRendering
RFC for native markdown parsing on console
2 parents 929c013 + fad1e81 commit b276b9a

32 files changed

+239
-0
lines changed
Lines changed: 239 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,239 @@
1+
---
2+
RFC:
3+
Author: Aditya Patwardhan
4+
Status: Draft
5+
SupercededBy:
6+
Version: 0.3
7+
Area: Formatting and Output
8+
Comments Due: 03/26/2018
9+
Plan to implement: Yes
10+
---
11+
12+
# Native Markdown Rendering
13+
14+
Render markdown content on console to improve readability.
15+
16+
## Motivation
17+
18+
Markdown is a common authoring format used by the community.
19+
There is no easy way in PowerShell to visualize a markdown document on console.
20+
Since the PowerShell help is authored in markdown, these components will be used for rendering help content.
21+
22+
## Specification
23+
24+
This RFC proposes to use `VT100` escape sequences to render markdown content.
25+
`ConvertFrom-Markdown` cmdlet as part of `Microsoft.PowerShell.Utility` PowerShell module would consume a string or a file path and output a PSObject containing three properties, `Tokens`, `Html`, `VT100EncodedString`.
26+
The `Tokens` property has the AST for the markdown document from `markdig`.
27+
The `Html` property has the markdown document converted to `HTML`.
28+
The `VT100EncodedString` property has the markdown documented with `VT100` escape sequences.
29+
By default, the `Html` property will be populated.
30+
The `VT100EncodedString` property will be populated only when `-AsVT100EncodedString` is specified.
31+
The `Tokens` property will be populated in all cases.
32+
33+
For converting strings to VT100 coded strings, we will be writing an extension to [markdig](https://github.com/lunet-io/markdig).
34+
The extension will insert VT100 escape sequences as appropriate.
35+
36+
### Specification for `ConvertFrom-Markdown`
37+
38+
```PowerShell
39+
40+
ConvertFrom-Markdown [-Path] <string[]> [-AsVT100EncodedString] [<CommonParameters>]
41+
42+
ConvertFrom-Markdown [-LiteralPath] <string[]> [-AsVT100EncodedString] [<CommonParameters>]
43+
44+
ConvertFrom-Markdown [-InputObject] <psobject> [-AsVT100EncodedString] [<CommonParameters>]
45+
46+
```
47+
48+
#### Parameters
49+
50+
- **Path** : Accepts an array of file paths with markdown content.
51+
- **LiteralPath** : Accepts an array of literal paths with markdown content.
52+
- **InputObject** : Accepts an InputObject of `System.IO.FileInfo`, `string` type.
53+
- **AsVT100EncodedString** : When selected, the `VT100EncodedString` property is populated.
54+
55+
There will be support for changing the colors for various elements using the `Set-MarkdownOption` cmdlet. To retrieve the current settings `Get-MarkdownOption` cmdlet can be used.
56+
57+
#### Output Type
58+
59+
The output type will be `MarkdownInfo` object with properties for `Html`, `VT100EncodedString` and `Tokens`.
60+
61+
### Specification for `Set-MarkdownOption`
62+
63+
```PowerShell
64+
65+
Set-MarkdownOption [-Header1Color <string>] [-Header2Color <string>] [-Header3Color <string>] [-Header4Color <string>] [-Header5Color <string>] [-Header6Color <string>] [-CodeBlockForegroundColor <string>] [-CodeBlockBackgroundColor <string>] [-ImageAltTextForegroundColor <string>] [-LinkForegroundColor <string>] [-ItalicsForegroundColor <string>] [<CommonParameters>]
66+
67+
Set-MarkdownOption -Theme <string> [<CommonParameters>]
68+
69+
Set-MarkdownOption -InputObject <psobject> [<CommonParameters>]
70+
71+
```
72+
73+
The properties can individually customize the rendering on console.
74+
The properties for color must be expressed as a `VT100` escape sequence, like
75+
76+
```PowerShell
77+
78+
Set-MarkdownOption -Header1Color "$([char]0x1b)[7m"
79+
80+
```
81+
82+
Dark will be the default theme.
83+
The individual colors for the dark theme are specified in the subsequent sections.
84+
85+
### Specification for `Get-MarkdownOption`
86+
87+
```PowerShell
88+
89+
Get-MarkdownOption [<CommonParameters>]
90+
91+
```
92+
93+
### Specification for `Export-MarkdownOption`
94+
95+
```PowerShell
96+
97+
Export-MarkdownOption -Path <string> [<CommonParameters>]
98+
99+
Export-MarkdownOption -LiteralPath <string> [<CommonParameters>]
100+
101+
```
102+
103+
Export the current markdown settings to a JSON file.
104+
105+
### Specification for `Import-MarkdownOption`
106+
107+
```PowerShell
108+
109+
Import-MarkdownOption -Path <string> [<CommonParameters>]
110+
111+
Import-MarkdownOption -LiteralPath <string> [<CommonParameters>]
112+
113+
```
114+
115+
Import the markdown settings from the specified file and returns a PSObject of the options.
116+
This can be used as an `InputObject` for `Set-MarkdownOption`.
117+
118+
### Specification for `Show-Markdown`
119+
120+
```Powershell
121+
122+
Show-Markdown -InputObject <psobject[]> [<CommonParameters>]
123+
124+
Show-Markdown -InputObject <psobject[]> -UseBrowser [<CommonParameters>]
125+
126+
```
127+
128+
Render the `VT100EncodedString` property of `MarkdownInfo` on console.
129+
If the `VT100EncodedString` property is null, then a non-terminating error will be thrown.
130+
131+
If the switch `-UseBrowser` is specified, display the content of `Html` property in a web browser.
132+
If the `Html` property is null, then a non-terminating error will be thrown.
133+
134+
## Supported Markdown Elements
135+
136+
We will be supporting a limited set of markdown elements in the initial version.
137+
138+
### Block Elements
139+
140+
The block elements include paragraphs and line breaks, headers, block quotes, code blocks and horizontal rules.
141+
142+
#### Paragraphs and line breaks
143+
144+
These will be rendered as plain text.
145+
Semantic line breaks will be rendered as paragraphs.
146+
147+
#### Headers
148+
149+
VT100 escape sequences for headers are as follows:
150+
151+
| Element | Markdown | Rendered | Escape Sequences (Dark Theme) | Escape Sequences (Light Theme) |
152+
|---------|-------------|----------|----------|------------|
153+
| ATX Header 1 | ![](../assets/MarkdownRendering/Header1-MD.png) | ![](../assets/MarkdownRendering/Header1.png) | ESC[7mHeader 1ESC[0m | ESC[7mHeader 1ESC[0m |
154+
| ATX Header 2 | ![](../assets/MarkdownRendering/Header2-MD.png) | ![](../assets/MarkdownRendering/Header2.png) | ESC[4;93mHeader 1ESC[0m | ESC[4;33mHeader 1ESC[0m |
155+
| ATX Header 3 | ![](../assets/MarkdownRendering/Header3-MD.png) | ![](../assets/MarkdownRendering/Header3.png) | ESC[4;94mHeader 1ESC[0m | ESC[4;34mHeader 1ESC[0m |
156+
| ATX Header 4 | ![](../assets/MarkdownRendering/Header4-MD.png) | ![](../assets/MarkdownRendering/Header4.png) | ESC[4;95mHeader 1ESC[0m | ESC[4;35mHeader 1ESC[0m |
157+
| ATX Header 5 | ![](../assets/MarkdownRendering/Header5-MD.png) | ![](../assets/MarkdownRendering/Header5.png) | ESC[4;96mHeader 1ESC[0m | ESC[4;36mHeader 1ESC[0m |
158+
| ATX Header 6 | ![](../assets/MarkdownRendering/Header6-MD.png) | ![](../assets/MarkdownRendering/Header6.png) | ESC[4;97mHeader 1ESC[0m | ESC[4;30mHeader 1ESC[0m |
159+
| Setext Header 1 | ![](../assets/MarkdownRendering/SetextHeader1-MD.png) | ![](../assets/MarkdownRendering/SetextHeader1.png) | ESC[7mHeader 1ESC[0m | ESC[7mHeader 1ESC[0m |
160+
| Setext Header 2 | ![](../assets/MarkdownRendering/SetextHeader2-MD.png) | ![](../assets/MarkdownRendering/SetextHeader2.png) | ESC[4;93mHeader 1ESC[0m | ESC[4;33mHeader 1ESC[0m |
161+
162+
#### Code Blocks
163+
164+
Code blocks will be rendered with a lighter background color and a dark foreground text.
165+
Background color will be applied for the console width.
166+
No syntax highlighting will be done.
167+
`ESC[500@` is used to have sufficiently wide background color.
168+
169+
| Markdown | Rendered | Escape Sequences |
170+
|-------------|----------|----------|
171+
| ![](../assets/MarkdownRendering/CodeBlock-MD.png) | ![](../assets/MarkdownRendering/CodeBlock.png) | ESC[48;2;155;155;155;38;2;30;30;30mTextESC[500@ESC[0m |
172+
173+
### Span Elements
174+
175+
Span elements will have varying degree of support depending on element type.
176+
177+
#### Links
178+
179+
Links in paragraphs will add double quotes around the link label and append the link URL surrounded by parenthesis.
180+
The link will be colored to differentiate from plain text.
181+
182+
| Markdown | Rendered | Escape Sequences |
183+
|----------|----------|-------------|
184+
| ![](../assets/MarkdownRendering/Link-MD.png) | ![](../assets/MarkdownRendering/Link.png) | ESC[4;34m( )ESC[0m |
185+
186+
If the links are part of a container like a pipe table, block quote or list; then just the link label will be shown.
187+
188+
#### Emphasis
189+
190+
Emphasis will be rendered using escape sequence `ESC[1mBold TextESC[0m` and `ESC[36mItalics TextESC[0m` for bold text and italics text respectively.
191+
192+
| Element | Markdown | Rendered | Escape Sequences |
193+
|---------|-------------|----------|----------|
194+
| Bold | ![](../assets/MarkdownRendering/Bold-MD.png) | ![](../assets/MarkdownRendering/Bold.png) | ESC[1mBold TextESC[0m |
195+
| Italics | ![](../assets/MarkdownRendering/Italics-MD.png) | ![](../assets/MarkdownRendering/Italics.png)| ESC[36mItalics TextESC[0m |
196+
197+
#### Code
198+
199+
Inline code elements will be rendered similar to code blocks, with the exception on background color to not extend beyond the markdown element.
200+
201+
| Markdown | Rendered | Escape Sequences |
202+
|-------------|----------|----------|
203+
| ![](../assets/MarkdownRendering/Code-MD.png) | ![](../assets/MarkdownRendering/Code.png) | ESC[48;2;155;155;155;38;2;30;30;30mTextESC[0m`|
204+
205+
#### Images
206+
207+
The alt-text of the image will be surrounded by `[` and `]` and colorized to differentiate from plain text.
208+
Escape code for images alt-text
209+
210+
| Markdown | Rendered | Escape Sequences |
211+
|-------------|----------|----------|
212+
| ![](../assets/MarkdownRendering/Image-MD.png) | ![](../assets/MarkdownRendering/Image.png) | ESC[33m[alt-text]ESC[0m |
213+
214+
### Rendered output
215+
216+
#### Input Markdown
217+
218+
![](../assets/MarkdownRendering/SampleMD.png)
219+
220+
#### VT100 Rendered output
221+
222+
![](../assets/MarkdownRendering/SampleVT100.png)
223+
224+
## Future Work
225+
226+
`Paragraphs and Line Breaks`, `Block Quotes`, `Lists`, `Horizontal Rules`, `Pipe tables` and `HTML code` will be considered for future versions and rendered as plain text in this version.
227+
228+
## Alternate Proposals and Considerations
229+
230+
Introduce a new sigil to define a markdown string.
231+
This would be later rendered using formating files.
232+
The limitations of this approach are:
233+
234+
1. Can be used only in script.
235+
2. Adds a new dependency of `markdig` to `System.Management.Automation`.
236+
237+
## Open Questions
238+
239+
- Investigate paging behavior.

assets/MarkdownRendering/Bold-MD.png

1.39 KB
Loading

assets/MarkdownRendering/Bold.png

946 Bytes
Loading

assets/MarkdownRendering/Code-MD.png

900 Bytes
Loading

assets/MarkdownRendering/Code.png

642 Bytes
Loading
2.19 KB
Loading
2.23 KB
Loading
1 KB
Loading

assets/MarkdownRendering/Header1.png

749 Bytes
Loading
1.34 KB
Loading

0 commit comments

Comments
 (0)