慣性聚合 関心のあるブログ、ニュース、テクノロジーを効率的に追跡
原文を読む 慣性聚合で開く

おすすめ購読元

博客园 - 司徒正美
V
V2EX
T
Tailwind CSS Blog
有赞技术团队
有赞技术团队
aimingoo的专栏
aimingoo的专栏
Apple Machine Learning Research
Apple Machine Learning Research
IT之家
IT之家
Blog — PlanetScale
Blog — PlanetScale
A
About on SuperTechFans
月光博客
月光博客
T
The Blog of Author Tim Ferriss
宝玉的分享
宝玉的分享
Martin Fowler
Martin Fowler
博客园 - 聂微东
The GitHub Blog
The GitHub Blog
V
Visual Studio Blog
WordPress大学
WordPress大学
酷 壳 – CoolShell
酷 壳 – CoolShell
Engineering at Meta
Engineering at Meta
GbyAI
GbyAI

Все публикации подряд на Хабре

Ловим музу за клавиатуру: как айтишнику стать автором Что умеет Midjourney в 2026? Мой немного грустный разбор этого шикарного инструмента Никто не любит писать тесты, но ИИ может исправить это IPv8 выглядит как мечта. Поэтому почти наверняка не взлетит Производители вернули в продажу материнки с DDR3. Что происходит? Управление агентом с телефона через Telegram теперь в KodaCode От координации к лидерству: как меняется роль руководителя разработки Я сделала родителям бизнес вместо пенсии: зарабатываем 70 тысяч, мама не даёт продать В три раза быстрее приемка товара и оптимизация трудозатрат на 73%: как «РСТ-Инвент» помог Gulliver Group ИИ-шечный мир победил? О влиянии искусственного интеллекта на игропром Кремль снижает давление на Телеграмм пока Европа строит интернет по паспорту Как CEO, CTO и CIO за 8 часов собрали ИИ-директора, который умеет держать позицию под давлением Как (не) потерять домен за выходные Вместо 8 разных VPS: как я организовал практику студентам на одном сервере Почему твой Open Source проект не замечают? R&D: искусство управления неопределенностью в разработке AI-дефляция: вакансий для разработчиков больше, а рост зарплат — худший за 15 лет Мы отдали управление роботами OpenClaw. Что из этого вышло Галактический ID: система идентификации для всех форм разумной жизни Кто решает судьбу вашего проекта? Разбираем заинтересованные стороны. BABOK #1 Код-ревью, в котором дело не в коде Данные переехали. Команда — нет Системной подход к сдаче OSWE в 2025 Почему комната управления реактором покрашена в цвет морской пены 4 YAML-файла вместо PySpark: как аналитикам строить пайплайны без разработчиков LLM-агент для поиска свободных доменов: автоматизируем подбор Когда, зачем и как правильно начинать новую сессию в Claude Code? Как я заставил нейросеть писать макросы для FreeCAD Анатомия ИИ‑агента для подбора персонала. От тысячи резюме к топ‑10 за минуты Опыт разработчика как экономика внимания Автономность как точка невозврата: кто будет субъектом в цифровом будущем Обучение ИИ в «диких» условиях: как рутинные действия превращаются в датасеты Как измерить LLM для задач кибербеза: обзор открытых бенчмарков Где хранить код? Сравнение GitHub, GitLab и Bitbucket Математика объясняет, почему нормальное распределение встречается повсюду Почему ваш FinOps не работает: 12 тезисов от практиков Как подписать проектную документацию УКЭП с использованием бесплатных лицензий Pilot Адаптивное администрирование Sigla Vision Я грузил уран в бочки, а потом 20 лет строил ИТ в атомной отрасли Чем позвонить с Эвереста? История и обзор спутниковой связи. Часть 2 Как языковая модель помогает контролировать качество инструктажей по охране труда в металлургии Как не передать на desktop свой IP в РКН Анатомия SAP Privileges: как устроено управление правами в macOS MoneyDev: Сказка про три главных слова Обновлённый токенизатор видео K-VAE 2.0 от Сбера Как сделать диспетчеризацию дома на 1284 квартиры почти бесплатно Как мы разогнали железную дорогу Мы дали агентам рутину. Теперь надо решить — что делать с освободившимся временем Токсичный контент, промпт-хакинг и защита ИИ — всё о Guardrails для LLM Умный город начинается с точного взгляда: как Фалькон Тех меняет пространство к лучшему
Marcli: マークダウン ターミナル
amcured · 2026-05-24 · via Все публикации подряд на Хабре

RustのCLIエコシステムでは静かに流行病が発生しています。症状:参照テキストが網膜炎を疑わせる、エラーメッセージが平面的でドアの下に置けそうな、文書化が売店のレシートほど表現力がない。それでも現代のどのテキストエミュレーターも太字、イタリック、色、Unicodeの枠線描画文字をサポートしています。 テキストエミュレーターができることと を表示し、また、大多数の CLI ツールが を表示することを許しているため、その規模はグランド・キャニオンと比較し、深さはマリアナ海溝のユーザーに対する無関心と比較できる。

Marcli この разрывを閉じる。CommonMark Markdownを取り込み、スタイリッシュなANSI出力をターミナルに提供する。あなたはMarkdownを書く。あなたのユーザーは美しく装飾されたテキストを見る。すべてのアイデアは一つの文に凝縮されており、これで十分である.

Marcli terminal output

Marcli terminal output

何をするのか

MarcliはMarkdownをcomrakを通じてパースする — GitHubでレンダリングを動かしている同じパーサー — は、ASTを巡回し、サポートされている各要素に対してANSIエスケープシーケンスを生成します。囲まれたコードブロックの構文ハイライトはsyntectによって提供されます。 — Sublime Textで使われている同じ文法です。Pygmentsの呼び出しはありません、実行時のロードもありません、設定の儀式もありません。ただ動作する — これは他のエコシステムが、見ているように、急進的な概念です.

関数の1つの呼び出し:

let output = marcli::render("# Hello\n\nSome **bold** text.", &Default::default());
println!("{}", output);

これは典型的なケースの全ての公開APIです。関数renderはMarkdownの文字列とRenderOptionsの構造を受け取り、返しますString に埋め込まれた ANSI 文字列シーケンス。チェーンで17回呼び出される「ビルダー」パターンはありません。事前に実装する必要があるトレイトはありません。依存関係の木に隠れた非同期ランタイムは、あなたのビルドを食い荒らすのに都合の良い機会を待っています.

対応する要素

Marcli は CommonMark の完全な仕様に加え、いくつかの拡張を処理します:

  • タイトル — h1は黄色く太字、h2は青く太字、h3以下は白く太字です。3つの視覚的階層が、1行の設定コードなしで構成されます。

  • 行内フォーマット — 太字、イタリック、打ち消し線、行内コード、それぞれ異なるANSIスタイルです。

  • 箇条書き — 三角形のマーカー(▸)で代わりに一般的なASCIIハイフンを使用。些細なことですが、読みやすさが不釣り合いに向上します.

  • 番号付きリスト — 円囲みされた数値文字(①, ②, ③, …)が20項目まで。20を超えると括弧内の数値になります。たとえ誰も苦情を言わなかったとしても、健全な判断力を持っているなら21項目のリストを作成することはありません.

  • 囲まれたコードブロック — Unicodeの描画枠内に言語のタイトルを表示。言語を指定すると、自動的にシンタックスハイライトが有効になります。

  • 引用 — 左に薄い縦線で囲まれ、周囲のテキストと視覚的に区別可能で、感情を表現せず。

  • — 符号で作られた完全な枠組みで、列の整列が正しく行われている(左端、右端、中央)。見出しは太字で強調されています。

  • タスクリスト — チェックボックス付きのマーカー(☑ / ☐)。

  • トピック用区切り線 — 疲れたような水平線(符号で作成)。

  • リンク — 文字が青く強調表示され、その後にURLが薄いフォントで表示されます.

  • 画像 — URLと括弧内の代替テキストが表示されます。なぜなら、ターミナルは、我々の必死の努力にもかかわらず、まだ画像を表示するプログラムではありませんから.

これは貧しい人のサブセットではありません。賢い人がターミナルで表示したいもの全てであり、それ以上のものではありません.

コンフィギュレーションなしで動作するシンタックスハイライト

言語を指定した囲まれたコードブロックは、syntectの組み込み文法によって自動的にハイライトされます。Rust、Python、Elixir、JavaScript、Go、C、SQL、TOML、YAML、Markdown自身も含め、syntectが言語を認識している場合、Marcliがそれをハイライトします。認識できない場合、そのブロックは同じ枠内で単なるスタイリッシュなテキストとして描画されます。クラッシュ、警告、経験値の減退は一切ありません。単に色なしのコードです。業界が地質学的なスピードで進むとされる「未知の入力からクラッシュしない」という革新的なコンセプトです。

fn main() {
    let md = "```rust\nfn greet(name: &str) {\n    println!(\"Hello, {}!\", name);\n}\n```";
    let output = marcli::render(md, &Default::default());
    println!("{}", output);
}

キーワードは一つの色で、行は別の色で色付けされ、コメントは弱調表示されイタリック体で強調され、関数名は背景に強調表示されます。TextMateスコープからのsyntectへのマッピングはANSIシーケンスに統合されており、主要なトークンカテゴリをすべてカバーしています:キーワード、文字列、数値、コメント、演算子、名前、格納修飾子、エンティティ名、サポートマクロ、定数、変数、および差分マーカー。各カテゴリにはデフォルトで適切な意味付けがあり、それぞれを上書きすることができます。

構文のハイライトを完全に無効にすることができます:

let mut theme = marcli::Theme::default();
theme.syntax_highlight = false;
let opts = marcli::RenderOptions { theme, ..Default::default() };

TOMLを通じて色テーマを完全に設定

Marcliの出力の視覚的な側面はすべて構造によって制御されますTheme:見出しの色、リストマーカー、コードブロックの枠線、テーブル記号、構文ハイライトのトークンスタイル、トピックセクションの区切り線の幅、引用のプレフィックス——すべて。デフォルト値は現実的ですが、企業の色やアクセシビリティのための高コントラストテーマが必要な場合は、興味のあるフィールドを正確に上書きします。他のものは変更しません。Marcliは、1つのパラメータを変更すると「一貫性」とか言ってすべての設定をゼロから再構築するようなライブラリではありません。

トピックはTOMLファイルから読み込まれます:

let theme = marcli::Theme::load(".marcli.toml").unwrap_or_default();
let opts = marcli::RenderOptions { theme, ..Default::default() };
let output = marcli::render(markdown, &opts);

部分のTOMLファイルは指定されたフィールドのみを上書きします;他はすべてデフォルトのままです。未知のキーは無視されるので、トピックは将来のバージョンと互換性を保ちます。

テーマシステムは後付けでfeatureフラグを通じてつけられた手前でありません。これはアーキテクチャです。レンダラーにはハードコードされたANSIシーケンスは一つも含まれていません — 各スタイルは構造から読み取られます。Themeレンダリングの際に。これは、生成できることを意味します。完全非装饰化すべてのスタイルを出力する際に空の行に設定するか、特定のターミナルの能力に合わせて出力を調整し、必要なシーケンスのみを変更する。デザインは非常に明確なので、なぜ説明する必要があるのか不思議である。

xterm.jsおよびウェブターミナルのCRLFサポート

もし CLI ツールがウェブ ターミナルでも動作する場合(xterm.js のような)、改行文字は重要です。Marcli では、改行のシーケンスを設定することができます:

let opts = marcli::RenderOptions {
    newline: "\r\n".into(),
    ..Default::default()
};
let output = marcli::render(markdown, &opts);

リストの要素の間、コード ブロック内、段落の間の各内部改行は、設定されたシーケンスを使用します。後処理のための正規表現は不要です。\n を「置き換えろ」というようなものも不要です。\r\n とお祈りします」。構文が正しい——このアプローチは、一部の開発者にとって文化的ショックに近い状態を引き起こします.

ANSIを削除して純粋なテキスト

時には、色なしで構造化されたレンダリングが必要です——ログ記録のために、ファイルへのリダイレクトのために、エスケープシーケンスで圧迫されるアクセシビリティツールのために。オプション escape_sequences がこれを解決します:

let opts = marcli::RenderOptions {
    escape_sequences: false,
    ..Default::default()
};
let output = marcli::render(markdown, &opts);
// output содержит структурированный текст
// с маркерами и отступами, но без ANSI-кодов

Marcliは、必要に応じてエスケープシーケンスをクリーンアップする任意のテキストをstrip_ansiとして公開関数でエクスポートします:

let plain = marcli::strip_ansi(some_ansi_string);

依存関係の歴史

Marcliは6つのライブラリに依存しています:comrak (Markdownのパース)、syntect (シンタックスハイライト)、serdetoml (テーマのシリアライゼーション)、regex (ANSIの削除)およびonce_cell (怠惰な静的ファイル)。可能な限りデフォルトで機能が無効化されている。tokio はなし。hyper はなし。tower はなし。serde_json はなし。組み合わせ爆発的な feature-フラグはなし。serde が要求する以外のプロシージャルマクロはなし。

。依存関係の木は意図的に狭い。CLI ツールは、出力のレンダリングに Marcli を追加する。--help またはエラーデバッグ、突然 HTTPクライアントやTLSスタックを継承しない。Rustの世界では、日付のフォーマット用のクレートを追加するだけで、ネットワークスタックの半分が引きずられることがあるので、これは特に注目に値する——おそらく、シャンパン一杯の価値がある。

なぜMarcliなのか、代替案は何か

Rustのエコシステムはターミナルでの装飾された出力に複数のアプローチを提供し、それぞれが独自の課題を解決します。問題は、それらの多くがあなたの課題を解決しないことです.

「塗りつぶす」ためのクレート(例えば、coloredowo-colorsansi_term はブラシです。個々の行を着色することができます。構造を解析したり、リストを処理したり、テーブルをレンダリングしたり、コードをハイライトしたりしません。コンテンツが既に構造化されている場合、フォーマットのロジックをすべて自分で書きます。Marcli は 非構造化された Markdown を取り込み、完全に構造化されたターミナル出力を生成します。 は全く別の抽象化レベルです。それらを比較するのは、ハンマーと家のどちらが良いかと問うるのと同じです。

TUI フレームワーク(例えば、ratatuitui-rs は、完全なターミナル UI のツールセットです。レイアウト、ウィジェット、イベントループ、代替スクリーンバッファーを管理します。インタラクティブなアプリケーションを構築しているなら、これらは最高です。スタイリッシュなヘルプを表示して終了したいなら、これは文房具のボタン用の大鎚です。Marcli は、文房具のボタンほどのサイズのツールです。それ以上の主張はありません。それでよかったのです。

termimad — 最も近い代替品です。これもMarkdownをターミナルでレンダリングします。しかしtermimadは独自のパーサーを使用しており(CommonMarkと互換性がありません)、別の(より不透明な)テーマ化モデルを持ち、syntectを通じて構文ハイライトを提供しません。Marcliはcomrakを使用してパース(CommonMark、GitHubと互換性があります)、syntectを使用してハイライト(Sublime Textの文法)、そしてすべてのビジュアルパラメータを平面的でシリアライズ可能な構造を通じて設定します。Theme は、仕様に合致し、設定可能であることを重視するならば、選択肢は明らかです.

mdcat — コマンドラインインターフェースの独立したツールであり、ライブラリではありません。あなたはそれをバイナリに組み込んで render() を呼び出すことができません。それが外部プロセスとして実行されるか、あるいはユーザーのマシン上に自分のバイナリが必要です。Marcli はライブラリです:追加してください。Cargo.toml は機能を呼び出し、文字列を取得します。共同生活の義務はありません。

軽さの利点

RustのCLIライブラリで人と交流するものは、同じ問題に直面しています:構造化されたテキストをどう提示するか?答えはほぼ常に三つに分かれます:ⓐ生のテキストを出力してユーザーが読むことを願う(病的な楽観主義)、ⓑANSIフォーマット化を数十回の呼び出しで手動で適用format! はハードコーディングされたエスケープシーケンスで(職人技にマゾヒズムの混じったもの)、ⓒフレームワークを引き上げる、それがアプリケーション自体よりも重い(node modules の世界のアーキテクチャ的解決策)。

Marcliはオプションⓓとして、Markdown形式でメッセージ、参照テキスト、エラーメッセージの説明、変更ログ、診断を書くことを提案しています——これはあなたのチームが既に知っている形式であり、あなたのエディタが既にハイライト表示しており、あなたのドキュメントパイプラインが既にレンダリングしている形式であり——そして一つの関数呼び出しでこれを人々が読みたいターミナル出力に変換することができます。

価格—関数を呼び出すだけで6つの推移的依存関係があります。利点—あなたのCLIが世界に出すテキストの各断片は、太字、イタリック、構文ハイライト、マークアップ、表形式、引用可能で、テーマを完全にサポートし、ANSIシーケンスの手動操作を0にしています。

あなたのターミナルはもっと良いものを заслуживаетです。println! Marcli — それに最適なものを与える方法です。もし価値がないなら — とにかく、あなたのユーザーは価値があります.

リンク

▸ リポジトリ: github.com/Oeditus/marcli-rust
▸ ドキュメント: docs.rs/marcli
▸ クレート: crates.io/crates/marcli