Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Qiita / Qiita:Team における Markdown レンダリングの歴史
Search
Yuji Nakayama
August 29, 2017
Technology
9
11k
Qiita / Qiita:Team における Markdown レンダリングの歴史
Markdown Night 2017 Summer
https://connpass.com/event/63383/
Yuji Nakayama
August 29, 2017
Tweet
Share
More Decks by Yuji Nakayama
See All by Yuji Nakayama
How the RSpec team and I built the smooth upgrade process for RSpec 3
yujinakayama
0
230
Other Decks in Technology
See All in Technology
AI AgentをLangflowでサクッと作って、1日働かせてみた!
yano13
1
130
ソフトウェアエンジニアの生成AI活用と、これから
lycorptech_jp
PRO
0
840
Wasmの気になる最新情報
askua
0
180
アウトプットから始めるOSSコントリビューション 〜eslint-plugin-vueの場合〜 #vuefes
bengo4com
3
410
個人でデジタル庁の デザインシステムをVue.jsで 作っている話
nishiharatsubasa
2
3.9k
Implementing and Evaluating a High-Level Language with WasmGC and the Wasm Component Model: Scala’s Case
tanishiking
0
170
Oracle Base Database Service 技術詳細
oracle4engineer
PRO
12
81k
Introduction to Sansan Meishi Maker Development Engineer
sansan33
PRO
0
310
AI時代の開発を加速する組織づくり - ブログでは書けなかったリアル
hiro8ma
1
260
[2025年10月版] Databricks Data + AI Boot Camp
databricksjapan
1
240
「REALITY」3Dアバターシステムの7年分の拡張の歴史について
gree_tech
PRO
0
130
Databricks AI/BI Genie の「値ディクショナリー」をAmazonの奥地(S3)まで見に行く
kameitomohiro
1
380
Featured
See All Featured
A designer walks into a library…
pauljervisheath
209
24k
個人開発の失敗を避けるイケてる考え方 / tips for indie hackers
panda_program
115
20k
Optimizing for Happiness
mojombo
379
70k
It's Worth the Effort
3n
187
28k
How To Stay Up To Date on Web Technology
chriscoyier
791
250k
Documentation Writing (for coders)
carmenintech
75
5.1k
Code Review Best Practice
trishagee
72
19k
Raft: Consensus for Rubyists
vanstee
140
7.2k
GraphQLの誤解/rethinking-graphql
sonatard
73
11k
Rails Girls Zürich Keynote
gr2m
95
14k
The MySQL Ecosystem @ GitHub 2015
samlambert
251
13k
Responsive Adventures: Dirty Tricks From The Dark Corners of Front-End
smashingmag
253
22k
Transcript
2JJUB2JJUB5FBNʹ͓͚Δ .BSLEPXOϨϯμϦϯάͷྺ࢙ Yuji Nakayama @nkym37 @yujinakayama
None
None
None
None
None
࠷ॳQ&AαʔϏεͩͬͨ
None
࠷ॳ MarkdownະରԠͩͬͨ
ࠓ͢͜ͱ .BSLEPXOυΩϡϝϯτΛϗετ͢Δ8FCαʔϏεΛӡ Ӧ͢Δ্Ͱ໘͖ͯͨ͠ɺ.BSLEPXOϨϯμϥʔपΓͷ టष͍ࣄ
2JJUBͷॳظͷ.BSLEPXOαϙʔτ ݄ 2JJUBϦϦʔεͷϲ݄ޙ
ॳظͷ2JJUBͷ.BSLEPXOϨϯμϥʔ w ࣮SFEDBSQFU ΧελϜϨϯμϥʔ w SFEDBSQFU$Ͱॻ͔Εͨ.BSLEPXOύʔαʔͷSVCZHFN w ࣌ͷ(JU)VC'MBWPSFE.BSLEPXOͷ࣮SFEDBSQFUͷ ϕʔεͰ͋ΔTVOEPXOΛϕʔεʹ͍ͯͨ͠ʢͱࢥΘΕΔʣ w
·ͩ$PNNPO.BSLͳ͔ͬͨ
class Qiita::Markdown::Renderer < Redcarpet::Render::HTML # ... end renderer = Qiita::Markdown::Renderer(
filter_html: true, hard_wrap: true ) parser = Redcarpet::Markdown.new( renderer, autolink: true, fenced_code_blocks: true ) html = parser.render(markdown)
ॳظͷ༷ w ༷తʹ(JU)VC'MBWPSFE.BSLEPXOʹد͍ͤͯͨ w BVUPMJOL63-ͬΆ͍จࣈྻΛࣗಈͰϦϯΫʹ w GFODFE@DPEF@CMPDLT```\nsome code\n``` w IBSE@XSBQ.BSLEPXOͷվߦͰ<br>ग़ྗ
w ΧελϜϨϯμϥʔͰγϯλοΫεϋΠϥΠτ w ͷͪʹଧͪফ͠ઢςʔϒϧه๏ʹରԠ
ϝϯγϣϯه๏ͷಋೖ ݄ @username
2JJUB5FBNϦϦʔε ݄ αχλΠζͷϧʔϧ͕2JJUBͱएׯҟͳΔ
ֆจࣈͷαϙʔτ ݄ :tada:
qiita-markdown gem ݄
qiita-markdown gem w IUNMQJQFMJOF SFEDBSQFU OPLPHJSJ w IUNMQJQFMJOF)5.-ॲཧͷ3VCZϑϨʔϜϫʔΫ w ίΞϨϯμϥʔͱͯ͠SFEDBSQFUΛ͍ɺͦͷग़ྗʹର͠
ͯෳͷϑΟϧλʔʹΑΔޙॲཧΛద༻ w 044Խ
Redcarpet filter Emoji filter Syntax highlight filter Mention filter Markdown
string HTML tree HTML tree HTML tree HTML tree HTML tree HTML tree HTML tree
IUNMQJQFMJOFͷԿ͕خ͍͔͠ w ͝ͱʹϑΟϧλʔΛ͚ΒΕΔͷͰɺίʔυͷݟ௨͕͠ྑ͘ͳΔ w ϑΟϧλʔͷద༻ॱং͕໌֬ w جຊσʔλߏͱͯ͠OPLPHJSJͷ)5.-USFFΛ࠾༻͍ͯ͠ΔͨΊ )5.-ͷૢ࡞͕ݎ࿚ w ҎલͷϨϯμϥʔͰҰ෦ਖ਼نදݱΛ͍ͬͯΔՕॴ͕͋ͬͨ
ϢʔβʔͷաڈͷίϝϯτҰཡ ݄
None
None
ίϝϯτҰཡΛදࣔ͢Δ w هࣄҰཡͳΒλΠτϧΛදࣔ͢Εྑ͍͕ɺίϝϯτʹ λΠτϧ͕ͳ͍ͷͰɺຊจͷཁΛදࣔ͢Δඞཁ͕͋Δ w ͗͢ΔίϝϯτશจΛදࣔͨ͘͠ͳ͍ w ཁͱͯ͠දࣔ͢Δͷ͕͍͠ɺෳࡶͳϚʔΫΞοϓΛऔ Γআ͖͍ͨ
None
Qiita::Markdown::SummaryProcessor w ϒϩοΫཁૉͷதͭͭ͠λάΛআ͢Δ͜ͱͰɺΠϯϥΠϯԽ •<p>foo<em>bar</em></p>ˠfoo<em>bar</em> w ςʔϒϧͷΑ͏ͳɺΠϯϥΠϯԽͯ͠ෳࡶ͗ͯ͢ҙຯΛͳ͞ͳ͍ཁ ૉத͝ͱআ w )5.-ͷυΩϡϝϯτߏΛߟྀͭͭ͠USVODBUF
None
ϝϯγϣϯͰ͖ͳ͍Ϣʔβʔ ݄
ϝϯγϣϯͰ͖ͳ͍ਓ͕͍ΔΜͰ͕͢ʜ
@qiitan Markdown HTML <a href="/qiitan">@qiitan</a> @<strong>gfx</strong> @__gfx__ <em> Hi <a
href="/foo">@foo</a> </em> _Hi @foo_
w__foo__Λ<strong>foo</strong>ʹม͢Δॲཧ SFEDBSQFU͕͍ͬͯΔ w@fooΛ<a href="/foo">@foo</a>ʹม͢Δॲཧɺ SFEDBSQFUΑΓޙఔͷ.FOUJPOϑΟϧλʔ͕͍ͬͯΔ wͭ·Γ.FOUJPOϑΟϧλʔͷೖྗͷ࣌Ͱɺ@__gfx__ @<strong>gfx</strong>ʹͳͬͯ͠·͍ͬͯΔ
Redcarpet filter Mention filter @__gfx__ @<strong>gfx</strong> @<strong>gfx</strong> ͳΜ͔<strong>λά͍ͭͯΔ͠ ͜Εϝϯγϣϯ͡Όͳ͍ͳ ͳΜ͔ઌ಄ʹ@͍ͭͯΔ͚Ͳ
ڧௐه๏ʹϚον͢Δ͔Βڧௐ͠ͱ͜
w ࠜຊతʹ͜ͷʹରॲ͢ΔʹɺSFEDBSQFUʹखΛՃ͑ͯϝϯγϣϯه๏ ͷࣝΛ༩͑ΔʢϝϯγϣϯͷҰ෦ͩͬͨΒڧௐ͠ͳ͍ʣඞཁ͕͋Δ w ͔͠͠SFEDBSQFUͷGPSL࠷ऴखஈͰ͋ΓɺͰ͖ΕΓͨ͘ͳ͍ w ϫʔΫΞϥϯυͱͯ͠ɺ.FOUJPOϑΟϧλʔʹ@<strong>gfx</ strong>͕͞ΕͨΒɺ@__gfx__ʹͯ͠ϝϯγϣϯͱͯ͠ѻ͑ྑ͍ʁ w ڧௐه๏_͚ͩͰͳ͘*͑ΔͷͰ@<strong>gfx</strong>ͷݩ
ͷ.BSLEPXOιʔε͕ɺ@**gfx**ͩͬͨՄೳੑ͋Δ
None
(JU)VC͜ͷʹ Ͳ͏ରॲ͍ͯ͠Δͷ͔
None
None
.BSLEPXOͰϝϯγϣϯͰ͖ΔαʔϏεΛ࡞ΔͳΒɺ Ϣʔβʔ໊ʹ_Λ͑ͳ͍Α͏ʹͨ͠ํ͕ྑ͍ গͳ͘ͱઌ಄ͱඌͷ_ආ͚͍ͨ
ݹ͍Ωϟογϡ ݄
.BSLEPXOϨϯμϦϯάͷύϑΥʔϚϯε w 8FCαʔϏεͱͯ͠ɺϢʔβʔʹͱͬͯշదͳϨεϙϯελΠ ϜΛୡ͢Δͱ͍͏จ຺Ͱɺ.BSLEPXO RJJUBNBSLEPXO ͷ ϨϯμϦϯάॏ͍ w ຊจͷ༰͞ʹΑͬͯॲཧ͕࣌ؒେ͖͘มΘΔ w
ڊେͳςʔϒϧΛؚΜͩهࣄɺϨϯμϦϯάʹඵ͔͔ۙ͘ Δ͜ͱ͋Δ
ϨϯμϦϯά݁ՌΛΩϟογϡ͢Δ w ߘ࣌ʹҰ͚ͩϨϯμϦϯάͯ͠ɺ݁ՌΛΩϟογϡ ͓ͯ͘͠ w هࣄϖʔδӾཡϦΫΤετʹରͯ͠ຖճϨϯμϦϯά ͠ͳ͍
ݹ͍Ωϟογϡ w RJJUBNBSLEPXOʑਐԽ͍ͯ͠ΔͨΊɺߘ࣌ʹΩϟο γϡ͞ΕͨϨϯμϦϯά݁Ռͱɺ࠷৽ͷϨϯμϥʔͰϨϯ μϦϯάͨ͠߹ͷ݁Ռʹဃ͕ͰΔ w ࠣࡉͳมߋͰ͋Εݹ͍ΩϟογϡΛࢀর͠ଓ͚ͯྑ͍ ͕ɺ944ͳͲͷ੬ऑੑରԠͷ߹৽͍͠ϨϯμϥʔͰ֬ ࣮ʹϨϯμϦϯά͍ͨ͠͠
࠶ϨϯμϦϯάػߏ w *ODSFNFOUBMͳSFOEFSFSWFSTJPO *OUFHFS Λఆٛ͢Δ w ϨϯμϦϯά݁ՌͷΩϟογϡʹɺͦͷ࣌ͰͷSFOEFSFSWFSTJPOΛҰॹʹ֨ೲ͓ͯ͘͠ w هࣄΫϥεͷϨϯμϦϯά݁ՌΛฦ͢ϝιουͰɺΩϟογϡͷSFOEFSFSWFSTJPO͕ݱ ࡏͷWFSTJPOΑΓݹ͍߹ࣗಈతʹ࠶ϨϯμϦϯάΛ࣮ߦ͢Δ
w ࣮ࡍʹશϦΫΤετͰ࠶ϨϯμϦϯά͕Δͱෛՙͷ͕͋ΔͷͰɺ֬తʹ࣮ ߦ͞ΕΔΑ͏ʹ͠ɺ࣌ؒͱڞʹΛঃʑʹ্͍͛ͯ͘ w RJJUBNBSLEPXOʹखΛՃ͑ͨ߹ɺԿΒ͔ͷཧ༝Ͱશهࣄͷ࠶ϨϯμϦϯάΛ࣮ߦ͠ ͍ͨ߹SFOEFSFSWFSTJPOΛ ͢Δ
class Article < ActiveRecord::Base CURRENT_RENDERER_VERSION = 3 def rendered_body if
cached_body_renderer_version < CURRENT_RENDERER_VERSION self.cached_body = render(markdown_body) self.cached_body_renderer_version = CURRENT_RENDERER_VERSION end cached_body end end
݄
None
None
None
None
.BSLEPXO)5.-λάΛೖྗͰ͖Δ ໌Β͔ʹةݥͳλάଐੑαχλΠζ͍͕ͯͨ͠ɺ DMBTTଐੑڐՄ͍ͯͨ͠ <span class="fa fa-spin"> ·ΘΔίϝϯτ </span>
None
ΑΓݫ֨ͳαχλΠζ w 2JJUBͷ6*ʹΘΕ͍ͯΔDMBTTΛࢦఆ͢Δ͜ͱͰɺ2JJUBΛ฿ͨ͠ϑΟογϯάϖʔδΛ࡞ Ͱ͖ͯ͠·͏ w FH2JJUBͷϩάΠϯϖʔδΛ฿ͨ͠ϑΥʔϜΛ࡞Γɺ֎෦αΠτύεϫʔυΛૹ৴͢Δ w ͜Ε·ͰαχλΠζ͍͕ͯͨ͠ɺϗϫΠτϦετϧʔϧΛΑΓݫ֨ʹ͠ɺར༻Ͱ͖Δ )5.-ཁૉଐੑΛݶఆతʹͨ͠ w
HSFFONBU SFEDBSQFU ʹ͓͍ͯɺதؒϝλσʔλΛDMBTTଐੑͱͯ͠ग़ྗ͍ͯ͠ΔՕॴ͕͋ͬ ͨͷͰɺผͷEBUB ଐੑʹग़ྗ͢ΔΑ͏ʹมߋ͠ɺϢʔβʔʹΑΔೖྗͱ۠ผͰ͖ΔΑ͏ ʹͨ͠
͜Ε͔Β
$PNNPO.BSLʁ w ظతʹҠߦ͍ͨ͠ʢݸਓͷײʣ͕ɺطଘͷهࣄσʔ λͷҠߦ͕େมͦ͏ w (JU)VC$PNNPO.BSLͷҠߦ࣌ɺ৽چͷϨϯμϥʔͰ ղऍ͕ҟͳΔυΩϡϝϯτมॲஔΛߦͳͬͨ w IUUQTHJUIVCFOHJOFFSJOHDPNBGPSNBMTQFDGPS HJUIVCNBSLEPXO
Thank you