|
| 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 |  |  | ESC[7mHeader 1ESC[0m | ESC[7mHeader 1ESC[0m | |
| 154 | +| ATX Header 2 |  |  | ESC[4;93mHeader 1ESC[0m | ESC[4;33mHeader 1ESC[0m | |
| 155 | +| ATX Header 3 |  |  | ESC[4;94mHeader 1ESC[0m | ESC[4;34mHeader 1ESC[0m | |
| 156 | +| ATX Header 4 |  |  | ESC[4;95mHeader 1ESC[0m | ESC[4;35mHeader 1ESC[0m | |
| 157 | +| ATX Header 5 |  |  | ESC[4;96mHeader 1ESC[0m | ESC[4;36mHeader 1ESC[0m | |
| 158 | +| ATX Header 6 |  |  | ESC[4;97mHeader 1ESC[0m | ESC[4;30mHeader 1ESC[0m | |
| 159 | +| Setext Header 1 |  |  | ESC[7mHeader 1ESC[0m | ESC[7mHeader 1ESC[0m | |
| 160 | +| Setext Header 2 |  |  | 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 | +|  |  | 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 | +|  |  | 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 |  |  | ESC[1mBold TextESC[0m | |
| 195 | +| Italics |  | | 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 | +|  |  | 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 | +|  |  | ESC[33m[alt-text]ESC[0m | |
| 213 | + |
| 214 | +### Rendered output |
| 215 | + |
| 216 | +#### Input Markdown |
| 217 | + |
| 218 | + |
| 219 | + |
| 220 | +#### VT100 Rendered output |
| 221 | + |
| 222 | + |
| 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. |
0 commit comments