Skip to content

Markdownの中でfigureタグを使えるようにした #8545

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 10 commits into
base: main
Choose a base branch
from

Conversation

sugiwe
Copy link
Contributor

@sugiwe sugiwe commented Apr 9, 2025

Issue

概要

Markdown記法の追加機能としてfigureタグを使えるようにしました。

:::figure
<a href="https://example.com/image.jpg"><img src="https://example.com/image.jpg"></a>
キャプション本文
:::

上記のように書くと、

<figure>
<a href="https://example.com/image.jpg"><img src="https://example.com/image.jpg"></a>
<figcaption>キャプション本文</figcaption>
</figure>

というHTMLに変換されます。

変更確認方法

  1. {feature/ebable-to-use-figure-tag-in-markdown}をローカルに取り込む
    • git fetch origin pull/8545/head:feature/ebable-to-use-figure-tag-in-markdown
    • git switch feature/ebable-to-use-figure-tag-in-markdown
  2. foreman start -f Procfile.devでローカルサーバを立ち上げる
  3. 任意のユーザーでログインし、日報作成ページ等のテキスト入力欄に下記をコピー&ペーストする
:::figure
<a href="https://example.com/image.jpg"><img src="https://example.com/image.jpg"></a>
キャプション本文
:::
  1. DevTools等を使い、プレビュー欄側で下記のようにHTMLが出力されていることを確認する
  • figureブロック全体がfigureタグで囲まれていること
  • キャプション部分がfigcaptionタグで囲まれていること

※上記のサンプルコードでもfigureタグ・figcaptionタグは確認できますが画像は表示されないので、任意の画像をアップロードしていただくと画像の表示も含めて確認が可能です。

Screenshot

変更前

1_before

変更後

2_after

@sugiwe
Copy link
Contributor Author

sugiwe commented Apr 9, 2025

@machida
お疲れ様です!
こちらの件、figureタグ及びfigcaptionタグで囲うことができるようになりましたので、デザインの追加をお願いできますでしょうか🙏
どうぞよろしくお願いいたします。

@machida
Copy link
Member

machida commented Apr 9, 2025

@sugiwe デザイン承知しました👍実装ありがとうございます🙏

@machida machida force-pushed the feature/ebable-to-use-figure-tag-in-markdown branch from 763a231 to 15b8fae Compare April 14, 2025 06:53
@machida
Copy link
Member

machida commented Apr 14, 2025

@sugiwe
お待たせしました🙇‍♂️
デザイン入れましたー

最新のmainブランチを取り込んだので、git pull --rebase origin main をお願いします。

@sugiwe
Copy link
Contributor Author

sugiwe commented Apr 15, 2025

@machida
デザイン反映ありがとうございます!手元で無事確認できました✨

@sugiwe
Copy link
Contributor Author

sugiwe commented Apr 15, 2025

@mousu-a
お疲れ様です☕️

こちらのレビューをお願いしたいのですが、可能でしょうか?
markdown追加機能のPRでして、リンクカード実装をご対応されているmousuさんに見ていただけたら嬉しいなと思いご連絡いたしました。

急いではおりませんので1〜2週間くらいでご対応いただけたら大変嬉しいですが、厳しいようでしたら遠慮なくおっしゃってください!

どうぞよろしくお願いいたします🙏

@sugiwe sugiwe requested a review from mousu-a April 15, 2025 05:48
@machida
Copy link
Member

machida commented Apr 15, 2025

@sugiwe 確認ありがとうございますー🙏

@sugiwe sugiwe marked this pull request as ready for review April 15, 2025 05:48
@mousu-a
Copy link
Contributor

mousu-a commented Apr 15, 2025

@sugiwe
レビュー依頼ありがとうございます!!
ぜひ引き受けさせていただきますー🙌

余談ですがsugiweさんの文章はいつも相手への気遣いが見えてこちらとしてはとても嬉しいです😊

一週間ほどを目安にレビューさせていただきますのでしばしお待ちください🙏

@sugiwe
Copy link
Contributor Author

sugiwe commented Apr 15, 2025

@mousu-a
レビュー快諾いただきありがとうございます!
(そしてなんと、とても嬉しい言葉もいただきありがとうございます✨)
どうぞよろしくお願いいたします🙏

Copy link
Contributor

@mousu-a mousu-a left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@sugiwe
お疲れ様です🍵
レビューお待たせいたしました!(一週間はだいぶ嘘ついてしまいました😅)
いくつかコメントさせていただいていますのでご確認ください🙏

余談です

今回の実装は、renderer(のカスタマイズ)とruleの追加(プラグイン)を2つ使って実装しているようだったので、パッと見た時に「どうにかどちらか1つで出来ないかな〜」とあれこれやってみましたが中々難しいですね🤔

rule(プラグイン)であればrule1つで出来そうですけど、:::figure:::記法の捕捉はrendererを使った方が収まりが良さそうですし、かといってrenderer1つではどうやら実装は難しそうでした。(既存のmessage記法やdetails記法とはちょっと勝手が違って)

結果的にこの実装(renderer(のカスタマイズ)とrule(プラグイン)の二刀流)がベストとなったわけですね。(身をもって体験しました😅)

isInContainerFigure = true
figureIndexes.push(i)
}
if (isInContainerFigure && token.type === 'inline') {
Copy link
Contributor

@mousu-a mousu-a Apr 16, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ここをこんな感じにするとremoveFigureParagraphしなくても良いかもです👀

if (isInContainerFigure && token.type === 'inline') {
        const linkedImageMatch = token.content.match(
          /<a [^>]+>\s*<img [^>]+>\s*<\/a>/
        )
        const linkedImageTag = linkedImageMatch ? linkedImageMatch[0] : ''
        const caption = token.content.replace(linkedImageTag, '').trim()
        token.content = `${linkedImageTag}${`<figcaption>${caption}</figcaption>`}`

        // markdown-itが自動出力してしまうfigureタグ内のpタグを出力しないようにする
        const pOpen = state.tokens[i - 1]
        const pClose = state.tokens[i + 1]
        pOpen.hidden = true
        pClose.hidden = true
      }

https://markdown-it.github.io/markdown-it/#Token.prototype.hidden

Copy link
Contributor Author

@sugiwe sugiwe Apr 17, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

こちらありがとうございます!
確かにToken#hiddenを使うとシンプルになりますね、というかこうすればrenderer無しで実装できるのですね…!
とても勉強になりました、こちら取り入れさせていただきます🙏

const buildFigureContent = (md) => {
md.core.ruler.after('block', 'extracting_caption_from_figure', (state) => {
let isInContainerFigure = false
const figureIndexes = []
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

使われていなさそうなので何かの消し忘れかも?figureIndexes

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ありがとうございます、消し忘れでした🙏

/<a [^>]+>\s*<img [^>]+>\s*<\/a>/
)
const linkedImageTag = linkedImageMatch ? linkedImageMatch[0] : ''
const caption = token.content.replace(linkedImageTag, '').trim()
Copy link
Contributor

@mousu-a mousu-a Apr 16, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

提案です!
ここなんですが、
linkedImageTag = match[0]
caption = match[1]
といった感じで書けたらコードがもっと読みやすくなると思うのですがどうでしょうか?(token.contentに対してaタグ部分とキャプション部分をそれぞれ正規表現でグルーピングして取り出す感じです)

token.content.replace(linkedImageTag, '')の部分が、本来のreplace関数の意味するところの"置き換える"という意味で使っていないのでちょっとテクニカルかも?🤔

Copy link
Contributor

@mousu-a mousu-a Apr 16, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ここの処理に関係することなんですが意図していなさそうな挙動を発見しました🔍


どうやらaタグとキャプション(テキスト)の間に空行が入っていると余計なfigcaptionタグが発生してしまうようです。

キャプチャ

スクリーンショット_2025-04-16_12_53_50-2

理由

おそらく、空行が入ることでtokenの配列に空行の文ズレが生じ、aタグのtokenとキャプション(テキスト)のtokenが別々に分かれてしまうことで発生していると思われます。

イメージとしては、本来意図している挙動はtoken.content #=> "<a>...</a>\nキャプション"なんですが、間に空行が入ると↓のようにtokenがバラバラになってしまう感じです。
aタグのtoken.content #=> "<a>...</a>"
空行のtoken.content #=> "\n"
キャプションのtoken.content #=> "キャプション"
tokentoken.contentindexをログに出して見てみるとわかりやすいかもです。


「aタグとキャプション(テキスト)の間に空行が入っていても同じように対応するかどうか」など、お手数ですがmachidaさんに一度ご確認いただけますでしょうか🙏
ただどちらにせよ、余分なタグが発生しないように調整する必要はありそうです💦

@sugiwe
Copy link
Contributor Author

sugiwe commented Apr 16, 2025

@mousu-a
お疲れ様です!
とても迅速にレビューしていただきありがとうございます、感謝です✨

余談のところもありがとうございます。
そうなんです、僕も初めもっとシンプルにできないものかと色々試してみたのですが、message記法やdetails記法と異なり、:::で挟まれるブロックの中にhtmlタグが含まれている関係で(?)今回のfigureはちょっと事情が異なることがわかり、一旦現在の状態に落ち着いたという感じです😅

それ以外で諸々コメントいただいた部分に関しまして、逆に僕の方が1週間くらいかかってしまうかもですが汗、詳細確認してまた修正・お返事させていただきます🙏

@mousu-a
Copy link
Contributor

mousu-a commented Apr 16, 2025

@sugiwe
お忙しい中お返事ありがとうございます😄
こちらも全然急いでないので大丈夫ですよ〜🙆‍♂️
のんびりお待ちしております🍵

@sugiwe sugiwe force-pushed the feature/ebable-to-use-figure-tag-in-markdown branch from 7436daf to 5d09fa6 Compare April 18, 2025 03:33
@mousu-a
Copy link
Contributor

mousu-a commented Apr 18, 2025

@sugiwe
再レビュー前にすみません🙏
ここなんですが、if(!match) returnとしておけば三項演算子で存在確認をしなくても良くなるかもです!(すみませんレビュー漏れでした〜💦)

(あとすみません、提案させていただいたコード内のmatchという変数名はあくまでも例なので変数名はご自由に変えてもらって大丈夫ですので🙇‍♂️)

@komagata
Copy link
Member

@sugiwe 途中で申し訳ないのですが下記のプラグインは使えないですかね。

https://github.com/rbottomley/markdown-it-figure

@sugiwe
Copy link
Contributor Author

sugiwe commented Apr 24, 2025

@komagata
お疲れ様です、ご連絡ありがとうございます!

共有していただいたmarkdown-it-figureですが、自分としては今回使うにはフィットしていないのではと感じました。

大きな理由は、markdown-it-figureが想定している入力方法が#[Caption](/url/to/image.png)のような形であるということです。

現在のbootcampアプリの仕様では、画像をアップロードすると自動的にimgタグをaタグで囲んだ状態、例えば以下のような状態で入力欄に入ります。

<a href="画像URL"><img src="画像URL" width="" height="" alt="ファイル名"></a>

これを、markdown-it-figureが想定している入力方法の#[Caption](/url/to/image.png)のような形になるように手作業で打ち込み直すとか、自動処理でそうなるようなカスタマイズを加えていくのはあまりシンプルではないと思いました。

それよりは、元々の画像アップロードの仕様として入力される<a href="画像URL"><img src="画像URL" width="" height="" alt="ファイル名"></a>::: figureのブロックで囲むという方法のほうがシンプルで良さそうかなと思ったのですが、いかがでしょうか?

@komagata
Copy link
Member

@sugiwe なるほどですね。発案者の @machida さんにも聞いてみたいと思います。

@machida こちらいかがでしょうか。

僕の考えとしては、

markdown-it-figureというデファクトなnpmがあるのであればそちらにFBCの仕様を合わせた方が今後のメンテナンスや他のタグでの実装など便利になるように思います。

今回の実装がmarkdown-it-figureに合わないのであればmarkdown-it-figureとの違い・メリットがわかるような名前としてmakrdown-it-xxxxxというプラグインとして実装するべきかなと思いました。

そして今後も新しいタグを実装する場合はmarkdown-itプラグインとして実装するという包括的な仕組みができると思います。

@sugiwe
Copy link
Contributor Author

sugiwe commented Apr 24, 2025

@komagata
早速お返事ありがとうございます!

補足としましては、今回::: figure 〜〜〜 :::という形で囲むということで、同様に::: で囲む形式としてbootcampアプリ内で実装済みのmarkdown-it-container-message.jsmarkdown-it-container-details.jsなどと一貫性を持たせる意図でmarkdown-it-container-figure.jsという名前で実装を進めております。
:::で囲んでいる実装ということでcontainerをつけており、結果的にmarkdown-it-figureとの違いも表現できているかなと思いました)

@machida
お手数ですがご確認の程よろしくお願いいたします🙏

@machida
Copy link
Member

machida commented Apr 24, 2025

@sugiwe @komagata
npmの方を確認しました!
npmの仕様だと画像の表示サイズを変更できないので、ブログ記事などを書く際は現状のようにHTMLを手書きすることを継続することになってしまいます。
なので、今のsugiweさんが実装している方で進めたいです。

@sugiwe
Copy link
Contributor Author

sugiwe commented Apr 27, 2025

@machida
ご確認ありがとうございます!
それでは駒形さんのお返事を待った上で現状のままで進行していければと思います🙏

@sugiwe
Copy link
Contributor Author

sugiwe commented Apr 27, 2025

@komagata
お疲れ様です、町田さんからご回答いただいた方針で、現状の実装のまま進めるということでよろしいでしょうか。
大丈夫そうであればメンバーレビューを再開できればと思いますので、お手数ですがお返事いただければ幸いです🙏

@komagata
Copy link
Member

@machida (CC: @sugiwe ) なるほどです。
markdown-itのプラグインとして作成し、npmとして作っていただきたいと思っているのですがそちらはいかがでしょうか?

@machida
Copy link
Member

machida commented Apr 30, 2025

@komagata それに関して僕としては特に意見はないですー

@sugiwe
Copy link
Contributor Author

sugiwe commented Apr 30, 2025

@komagata
お返事ありがとうございます!
「markdown-itのプラグインとして作成し、npmとして作る」というのは、僕のnpmアカウントで公開するということでよろしいでしょうか?
良い機会なのでチャレンジできればと思いますが、その場合、issueのポイントを2ポイントほどアップしていただきたいのですがいかがでしょうか?

@sugiwe
Copy link
Contributor Author

sugiwe commented Apr 30, 2025

@komagata
すみません、元々2ポイントなので2を足すと4になってしまいますね。4ポイントは無いと思うので3か5になると思いますが、できれば5ポイントにしていただきたいのですがいかがでしょうか?
理由として、元々調査と実装を進めるにあたりかなり時間を要してしまい、2ポイントから3ポイントに変更する相談をしようか迷っていたという背景があります。そこにnpm化の話も加わったので、さらにプラス2で5ポイントにできないかという相談になります。
全体のポイントバランスを踏まえたときに5にするのは難しいようでしたら何なりとおっしゃってください🙇🏻‍♂️

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants