IntelliJプラグインのAnActionと登録設定を実装・変更し、表示文言やアイコンの定義、非同期処理の起動方法を整えます。
- IDEに新しいアクションを追加したいとき
- アクションの登録やアイコンを変更したいとき
- 表示名と説明文の定義を整理したいとき
JewelのMarkdownを解析・表示する処理を組み立て、見た目の調整、独自構文やHTML変換、画像・コード表示の拡張を支援します。
Build or debug Jewel Markdown parsing, rendering, and styling.
実行スコア 未検証
インストール方法を見るJewel Markdownの解析と表示を、目的に合った拡張方法で実装・デバッグするための指針です。Markdown文字列はMarkdownProcessorでMarkdownBlockやInlineMarkdownに変換され、そのモデルをComposeのレンダラーで表示します。見た目だけならMarkdownStyling、既存ブロックやインラインの表示変更なら対応するレンダラー拡張、新しい構文なら解析側と表示側の拡張を組み合わせます。GFMの表・取り消し線・アラート、画像表示、コードのシンタックスハイライト、埋め込みHTML、編集内容に追随するプレビューなどの構成も扱います。独自レンダラーでは、文字揃えや色、画像などのインライン表示、無効状態、プレビューのスクロール同期を保つ点も確認します。
JewelのMarkdown表示をアプリに組み込みたいときや、既存の表示スタイル・ブロック動作を変えたいときに使えます。独自記法やHTMLタグを追加する場合、画像やコードの表示が必要な場合、編集画面とプレビューを連動させたい場合にも適しています。チャットのMarkdown表示では、メッセージ管理と表示処理を分ける構成を案内します。
画像拡張の例にはCoil3があります。コードハイライトは、IDEプラグインと単体実行で既定の提供方法が異なります。埋め込みHTMLの解析は既定で無効です。
この紹介文は、公開されている SKILL.md をもとに AI(OpenAI Codex)が作成しました。正確な仕様は下の原文を確認してください。
インストールする前に、エージェントに与えられる指示の中身を確認できます。
Jewel Markdown is a two-stage renderer: parse raw Markdown into Jewel's MarkdownBlock / InlineMarkdown model, then render that model
with Jewel Compose renderers. Choose the smallest customization point that matches the job.
The Jewel Markdown sources live in JetBrains intellij-community under platform/jewel/markdown/. Confirm exact API/file/symbol names by reading those sources (grep/read) rather than trusting memory before proposing code. For deeper topic detail, read the matching reference only when that topic is in play:
references/CODE-HIGHLIGHTING.md — fenced/indented code highlighting, CodeHighlighter, why code is unstyled by default.references/IMAGE-LOADING.md — ImageRendererExtension + ImageSourceResolver, Coil3, path resolution.references/SCROLL-SYNC.md — editor-preview scroll synchronization and its ScrollState-only limitation.references/HTML-PARSING.md — embedded HTML, built-in tag conversion, MarkdownHtmlConverterExtension, alignment.MarkdownStyling and theme-specific styling helpers.MarkdownBlockRenderer, usually by subclassing DefaultMarkdownBlockRenderer and overriding
the specific Render* method.InlineMarkdownRenderer, usually by subclassing DefaultInlineMarkdownRenderer.ImageRendererExtension, not a general block renderer.parseEmbeddedHtml on the MarkdownProcessor, and for custom HTML→Markdown mapping add a
MarkdownHtmlConverterExtension.MarkdownMode.EditorPreview with a dedicated MarkdownProcessor instance and render with LazyMarkdown.Do not start with a custom renderer when styling or an extension solves the problem.
MarkdownProcessor parses raw Markdown into List<MarkdownBlock>.InlineMarkdown nodes.Markdown renders short/simple content in a Column; LazyMarkdown renders larger or editor-preview content in a LazyColumn.MarkdownBlockRenderer renders block nodes and delegates inline content to InlineMarkdownRenderer.ProvideMarkdownStyling wires LocalMarkdownStyling, LocalMarkdownProcessor, LocalMarkdownBlockRenderer, and code/image support
into JewelTheme.Prefer processing Markdown outside composition for non-trivial or frequently changing text. The string-taking Markdown(...) overload is
convenient, but it parses from composition and is best for small, mostly static snippets.
Use the existing extension modules before inventing syntax:
AutolinkProcessorExtension to the MarkdownProcessor.GitHubTableProcessorExtension and GitHubTableRendererExtension. The processor extension also bundles a
MarkdownHtmlConverterExtension for <table> (active when parseEmbeddedHtml = true).GitHubStrikethroughProcessorExtension and GitHubStrikethroughRendererExtension. The processor extension also
bundles a MarkdownHtmlConverterExtension for <s>, <strike>, and <del> (active when parseEmbeddedHtml = true).GitHubAlertProcessorExtension and GitHubAlertRendererExtension.ImageRendererExtension, commonly Coil3ImageRendererExtension, to the renderer extensions and provide an image source
resolver where needed. For details read references/IMAGE-LOADING.md.Project-aware bridge ProvideMarkdownStyling, which wires an IJPL-backed highlighter by
default; in standalone (or a bridge overload without a Project) the default is a no-op and you must provide a CodeHighlighter. For
details read references/CODE-HIGHLIGHTING.md.For a worked example of combining several extensions (processor + renderer + theme-specific styling, parsing off composition, LazyMarkdown), read the standalone sample at platform/jewel/samples/standalone/src/main/kotlin/org/jetbrains/jewel/samples/standalone/markdown/MarkdownPreview.kt.
Keep parser and renderer extensions paired when a feature has both sides. If a processor creates a custom block or inline node and no renderer extension claims it, the content will not render usefully. Do not invent renderer extensions for parse-only features such as autolink, and do not invent processor extensions for renderer-only image loading.
HTML support is off by default: a MarkdownProcessor ignores embedded HTML unless you construct it with parseEmbeddedHtml = true. There
are two distinct HTML paths, do not conflate them:
parseEmbeddedHtml is on, a fixed set of built-in tags is converted into normal MarkdownBlocks (
p, li, ol, ul, h1-h6, code, pre, img). These render through the standard block/inline renderers, not through a raw-HTML
renderer.<table> to a tables block),
implement a MarkdownHtmlConverterExtension and expose it from your MarkdownProcessorExtension.htmlConverterExtension. It declares
supportedTags and returns an HtmlElementConverter per tag; the converter turns an HTML element into a MarkdownBlock (or inline
list), delegating children/inlines via the provided lambdas. Existing GFM extensions ship these: gfm-tables converts <table> (block),
and gfm-strikethrough converts <s>/<strike>/<del> (inline). Use them as references and add the extension whose tags you need
rather than reimplementing it.For full details, models, and wiring, read references/HTML-PARSING.md.
Key points and gotchas:
htmlConverterExtensions are only collected when parseEmbeddedHtml = true; adding one without enabling embedded HTML does nothing.HtmlBlock (raw HTML string) or inline HTML; the default renderer shows it via the
htmlBlock styling, it is not interpreted as native UI. Jewel does not do general inline-HTML rendering.align attribute) becomes a MarkdownBlock.HtmlBlockWithAttributes wrapping the converted
block; the default renderer reads the align attribute and propagates text alignment to children. A custom renderer that overrides this
path must preserve that alignment behavior (see Gotchas for custom renderers).MarkdownMode.EditorPreview optimizes for small, frequent edits (a user typing): the MarkdownProcessor keeps state between calls and
re-parses only the block(s) that changed instead of the whole document. That statefulness is why an editor-preview processor is tied to one
evolving document and must not be shared across unrelated documents (doing so busts the cache and is slower than Standalone). Use
MarkdownMode.Standalone (the default, stateless) for content that is parsed once and doesn't change.
For a side-by-side editor and preview:
MarkdownProcessor(markdownMode = MarkdownMode.EditorPreview(scrollingSynchronizer = ...)) per editable document/preview
stream. Do not share editor-preview processors across unrelated documents.LazyMarkdown for documents and previews.references/SCROLL-SYNC.md — note the synchronizer currently supports ScrollState, not LazyListState.For chat timelines, do not make Markdown own the chat architecture.
Use a presenter/coordinator to project message state, roles, streaming status, and parsed Markdown blocks. The UI should render a
LazyColumn of message rows and use Markdown or LazyMarkdown inside text-bearing rows as appropriate. Keep networking, agent protocol,
message mutation, and Markdown parsing policy outside leaf composables. Use stable lazy-list keys and content types for heterogeneous chat
rows.
Write a custom extension when the Markdown input language changes, e.g., task list items, custom admonitions, ::file:/path/foo.kt::, or
another syntax that must parse into a domain model.
Write a custom renderer when the existing parsed model is right, but the UI should change, e.g., headings need link buttons, code blocks need copy buttons, list markers need different layout, or inline images need product-specific treatment.
Many features need both: an extension to parse syntax into model nodes, and a renderer to display those nodes. Some may need more than two parts. See the examples below.
Use gfm-alerts and gfm-tables as templates.
MarkdownBlock.CustomBlock.MarkdownProcessorExtension.ParserExtension.MarkdownBlockProcessorExtension that checks canProcess(CustomBlock) and returns your MarkdownBlock.CustomBlock from
processMarkdownBlock.allowsMergingWithNextBlock = true only when incremental editor parsing must reparse a following block that can merge into this one,
as tables do.MarkdownRendererExtension exposing a MarkdownBlockRendererExtension.RenderCustomBlock, render native Jewel Compose UI and delegate nested Markdown back to the provided MarkdownBlockRenderer /
InlineMarkdownRenderer where possible.AutoScrollableBlock in RenderCustomBlock. See references/SCROLL-SYNC.md.Use gfm-strikethrough as the template.
InlineMarkdown.CustomDelimitedNode.MarkdownProcessorExtension with a CommonMark parser extension if needed.MarkdownDelimitedInlineProcessorExtension that turns supported CommonMark Delimited nodes into your custom inline node.MarkdownRendererExtension exposing MarkdownDelimitedInlineRendererExtension.AnnotatedString, recursively delegating nested inline content to the supplied InlineMarkdownRenderer.MarkdownDelimitedInlineRendererExtension returns only an AnnotatedString. If custom inline syntax must show an icon or other
InlineTextContent — for example ::file:/my/path/foo.kt:: with the file icon and name — plan for an extension encompassing parsing plus
renderer customization:
Paragraph, headings, table cells, or whichever contexts you support) so the Jewel
Text receives the matching inlineContent map.IconKey, AllIconsKeys, or platform file-type icon APIs in bridge/plugin context) inside the InlineTextContent.Do not claim Jewel already supports GFM task lists. They are listed as missing/roadmap in Jewel docs. To support - [ ] / - [x] task list
items, create and validate a new extension:
[ ] or [x] in text).When overriding or replacing rendering, preserve the behaviors the default renderer relies on. Each item below is something a custom renderer can silently break.
DefaultMarkdownBlockRenderer passes textAlign = LocalTextAlignment.current to its Jewel
Text. That composition local is set when an aligned block (e.g., an HTML block with an align attribute) wraps its children, so
alignment propagates into nested text. A custom Render* override or a renderer written from scratch that emits Text without forwarding
the current text alignment will silently lose center/right alignment. Always apply the provided text alignment in custom text rendering.
Note LocalTextAlignment is internal to DefaultMarkdownBlockRenderer; prefer subclassing it (and still forwarding textAlign in your
override) rather than reimplementing block rendering and dropping this wiring.LocalContentColor. Preserve that
fallback instead of hardcoding a color.inlineContent map. If you override paragraph or other
text-bearing rendering, keep passing the inlineContent map so images and other inline placeholders still appear.enabled flag (links non-interactive, disabled styling) rather than always rendering the enabled
appearance.MarkdownBlockRenderer / InlineMarkdownRenderer so styling, extensions,
and these behaviors stay consistent.ScrollSyncMarkdownBlockRenderer (a DefaultMarkdownBlockRenderer
subclass that wraps blocks in AutoScrollableBlock and reports layout). If you supply your own block renderer for an editor preview, you
bypass that subclass and lose scroll sync. Subclass ScrollSyncMarkdownBlockRenderer instead of DefaultMarkdownBlockRenderer (calling
super from your overrides), or re-implement the AutoScrollableBlock wiring yourself. See references/SCROLL-SYNC.md.General rule: when you override one Render* method, mirror the default implementation's wiring (alignment, color, inline content, enabled
state, and editor-preview scroll sync) and change only what you intend to change.
Before finishing Jewel Markdown work:
MarkdownProcessor editor-preview instances are not shared across unrelated documents.LazyColumn item body.LocalTextAlignment (text alignment), preserves the content-color fallback, keeps the
inlineContent map, and honors enabled.parseEmbeddedHtml = true; custom tag mapping needs a MarkdownHtmlConverterExtension;
and unconverted/inline HTML is shown as raw text, not interpreted as native UI.まだレビューはありません。使ってみた感想をお寄せください。
ログインなしで書き込めます。使ってみた感想、質問、動かなかった環境などを気軽にどうぞ。
まだコメントはありません。最初のコメントを書いてみませんか。
IntelliJプラグインのAnActionと登録設定を実装・変更し、表示文言やアイコンの定義、非同期処理の起動方法を整えます。
IntelliJのJPSテストモジュールをBazelへ移行し、Bazelだけで起きる失敗を依存関係や実行環境から切り分ける手順を案内します。
IntelliJのKotlin・Javaコードを新規作成やレビューする際に、言語の選び方、書式、型の扱い、例外処理などのプロジェクト規約に沿って整えるスキルです。
IntelliJ向けの変更を適切な単位に分け、チケットの有無に応じた形式で、理由や判断も伝わるコミットメッセージを作成・修正するスキルです。
Pythonコードの型推論や型エラーを複数の型チェッカーで比較し、各ツールの判定と診断内容をまとめたレポートを作成します。
Compose Desktopの画面で状態や副作用をどこに持たせるか整理し、表示と判断の境界、再利用部品やリストの設計を整えます。