-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathProgram.cs
More file actions
143 lines (124 loc) · 3.57 KB
/
Copy pathProgram.cs
File metadata and controls
143 lines (124 loc) · 3.57 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
using MdTerm.Cli;
using MdTerm.Models;
using MdTerm.Parsing;
using MdTerm.Rendering;
using MdTerm.Rendering.Ascii;
using Spectre.Console;
using System.Diagnostics;
namespace MdTerm;
internal class Program
{
static async Task Main(string[] args)
{
var parser = new CommandLineParser();
var options = parser.Parse(args);
if (options.ShowHelp)
{
HelpWriter.ShowHelp();
return;
}
if (options.ShowVersion)
{
HelpWriter.ShowVersion(typeof(Program));
return;
}
if (options.ListStyles)
{
HelpWriter.ListStyles();
return;
}
if (options.FilePath == null)
{
HelpWriter.ShowHelp();
return;
}
if (!File.Exists(options.FilePath))
{
AnsiConsole.MarkupLine($"[red]File not found: {options.FilePath}[/]");
return;
}
var markdown = await File.ReadAllTextAsync(options.FilePath);
IMarkdownParser mdParser = new HtmlMarkdownParser();
var parsed = await mdParser.ParseAsync(markdown);
// Render output through pager where available so long content is navigable
var nodeRenderers = new INodeRenderer[]
{
new HeadingRenderer(),
new CodeBlockRenderer(),
new ParagraphRenderer(),
new TableRenderer(),
new ListRenderer(),
new TextRenderer()
};
IDocumentRenderer renderer = new AsciiDocumentRenderer(nodeRenderers);
WriteWithPager(() =>
{
RenderTableOfContents(parsed.TableOfContents);
renderer.RenderBody(parsed.Document);
});
}
private static void WriteWithPager(Action renderAction)
{
// Capture Console output while rendering
var originalOut = Console.Out;
var sw = new StringWriter();
Console.SetOut(sw);
try
{
renderAction();
}
finally
{
Console.SetOut(originalOut);
}
var content = sw.ToString();
if (string.IsNullOrEmpty(content))
return;
// Choose pager depending on OS. Try to start it; fall back to writing to stdout.
string pager = null;
string pagerArgs = null;
if (OperatingSystem.IsWindows())
{
pager = "more";
}
else
{
pager = "less";
pagerArgs = "-R"; // allow raw ANSI sequences
}
try
{
var psi = new ProcessStartInfo
{
FileName = pager,
Arguments = pagerArgs ?? string.Empty,
RedirectStandardInput = true,
UseShellExecute = false,
CreateNoWindow = true
};
using var proc = Process.Start(psi);
if (proc != null)
{
using var writer = proc.StandardInput;
writer.Write(content);
writer.Close();
proc.WaitForExit();
return;
}
}
catch
{
// ignore and fall through to write to console
}
Console.Write(content);
}
private static void RenderTableOfContents(IReadOnlyList<TocEntry> toc)
{
AnsiConsole.MarkupLine("[underline]Table of Contents[/]");
foreach (var entry in toc)
{
AnsiConsole.MarkupLine($"[bold]{entry.Anchor}[/] {entry.Text}");
}
AnsiConsole.WriteLine();
}
}