Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 25 additions & 0 deletions src/Terminal.Gui.Cli/CliHost.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System.Reflection;
using Terminal.Gui.App;
using Terminal.Gui.Drivers;

namespace Terminal.Gui.Cli;

Expand Down Expand Up @@ -181,6 +182,30 @@ private static CommandResult CreateCancelledResult ()
null);
}

/// <summary>
/// Creates, initializes, and disposes a headless ANSI-driver Terminal.Gui application around
/// <paramref name="render" />. Centralizes the Terminal.Gui lifecycle here (constitution C1) so
/// helpers such as <see cref="MarkdownRenderer" /> never call lifecycle entrypoints directly.
/// </summary>
internal static void RunHeadlessRender (int width, int height, Action<IApplication> render)
{
var previousDriverIO = Environment.GetEnvironmentVariable ("DisableRealDriverIO");
Environment.SetEnvironmentVariable ("DisableRealDriverIO", "1");
IApplication app = Application.Create ();

try
{
app.Init (DriverRegistry.Names.ANSI);
app.Driver?.SetScreenSize (width, height);
render (app);
}
finally
{
app.Dispose ();
Environment.SetEnvironmentVariable ("DisableRealDriverIO", previousDriverIO);
}
}

private async Task<CommandResult> RunWithTerminalGuiAsync (ICliCommand command, CommandRunOptions runOptions,
CancellationToken cancellationToken)
{
Expand Down
65 changes: 29 additions & 36 deletions src/Terminal.Gui.Cli/MarkdownRenderer.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
using System.Text;
using Terminal.Gui.App;
using Terminal.Gui.Drivers;
using Terminal.Gui.ViewBase;
using Terminal.Gui.Views;

Expand Down Expand Up @@ -62,46 +60,41 @@ public static void RenderToAnsi (string markdown, TextWriter output)
height = 24;
}

var previousDriverIO = Environment.GetEnvironmentVariable ("DisableRealDriverIO");
Environment.SetEnvironmentVariable ("DisableRealDriverIO", "1");
IApplication app = Application.Create ();

try
{
app.Init (DriverRegistry.Names.ANSI);
app.Driver?.SetScreenSize (width, height);

Markdown markdownView = new ()
// CliHost owns the Terminal.Gui lifecycle (constitution C1); this helper only
// performs view layout and drawing inside the callback.
CliHost.RunHeadlessRender (width, height, app =>
{
App = app,
UseThemeBackground = false,
ShowCopyButtons = false,
Width = Dim.Fill (),
Height = Dim.Fill (),
Text = markdown
};

markdownView.SetRelativeLayout (app.Screen.Size);
markdownView.Layout ();

var contentHeight = markdownView.GetContentHeight ();
app.Driver?.SetScreenSize (width, contentHeight);
markdownView.SetRelativeLayout (app.Screen.Size);
markdownView.Frame = app.Screen with { X = 0, Y = 0 };
markdownView.Layout ();

app.Driver?.ClearContents ();
markdownView.Draw ();

var rendered = app.Driver?.ToAnsi () ?? string.Empty;
rendered = TerminalEscapeSanitizer.SanitizeRenderedOutput (rendered);
target.WriteLine (rendered);
Markdown markdownView = new ()
{
App = app,
UseThemeBackground = false,
ShowCopyButtons = false,
Width = Dim.Fill (),
Height = Dim.Fill (),
Text = markdown
};

markdownView.SetRelativeLayout (app.Screen.Size);
markdownView.Layout ();

var contentHeight = markdownView.GetContentHeight ();
app.Driver?.SetScreenSize (width, contentHeight);
markdownView.SetRelativeLayout (app.Screen.Size);
markdownView.Frame = app.Screen with { X = 0, Y = 0 };
markdownView.Layout ();

app.Driver?.ClearContents ();
markdownView.Draw ();

var rendered = app.Driver?.ToAnsi () ?? string.Empty;
rendered = TerminalEscapeSanitizer.SanitizeRenderedOutput (rendered);
target.WriteLine (rendered);
});
}
finally
{
app.Dispose ();
Environment.SetEnvironmentVariable ("DisableRealDriverIO", previousDriverIO);

if (previousEncoding is not null)
{
Console.OutputEncoding = previousEncoding;
Expand Down
Loading