Blogger の記事を Markdown で書けるようにテーマを改修
## 経緯
前記事で以下のようなことを言いました。
> [Hello, World! - ginokent (tech)? blog](https://ginokent.blogspot.com/2022/08/20220806-01-hello-world.html)
>
> 頑張って Markdown エディタとか使うより気合で HTML マークアップした方が楽そう
全くもってそんなことはなかった。
素の HTML はつらい。なめてました。
2 記事目にしてマークダウンで書きたくなってしまったので、書けるように改造しました。
## テンプレートテーマを改造
Blogger Template テーマの HTML の body の閉じタグの直前に以下を記載します。
`<markdownContent>` タグの中身をマークダウンとして parse して、そのコンテンツを追加しています。
```html
<!-- NOTE: </body> の直前に書く -->
<script src="//cdnjs.cloudflare.com/ajax/libs/marked/4.0.18/marked.min.js"></script>
<script>
document.querySelectorAll('markdownContent').forEach(e => {
e.insertAdjacentHTML('afterend', marked.parse(e.textContent));
e.remove();
});
</script>
```
あとは、 Blogger の HTML エディタから以下のようにマークダウンを記述するだけです。
```html
<markdownContent>
# ここにマークダウンを記述
</markdownContent>
```
簡単!
## マークダウン render 結果例
(注) HTML タグを Markdown 文中に書きたい場合はエスケープする必要あり。例: <kbd>Command</kbd> + <kbd>C</kbd>
インラインコードはこんな感じ: `curl -I https://ginokent.blogspot.com/`
コードブロックはこんな感じ:
```go
package main
import "fmt"
func main() {
fmt.Println("Hello, World!")
}
```
表はこんな感じ:
| | GCP | AWS | Aure |
| :-- | :-- | :-- | :-- |
| オブジェクトストレージ | Google Cloud Storage | Amazon S3 | Azure Blob Storage |
| コンピューティング | Google Compute Engine | Amazon EC2 | Azure Virtual Machine |
| NewSQL | Cloud Spanner | 無い | 知らん |
いい感じな気がする。
## 結論
Markdown 書きやすすぎ!!!!
Markdown 最高!!!!
Markdown 万歳!!!!!
## メモ
2022-08-07 時点でのテーマの `diff` 結果。
```diff
--- original/ContempoDark.xml 2022-08-06 08:04:52.000000000 +0900
+++ ContempoDark.xml 2022-08-07 20:10:04.000000000 +0900
@@ -3,7 +3,13 @@
<html b:css='false' b:defaultwidgetversion='2' b:layoutsVersion='3' b:responsive='true' b:templateUrl='indie.xml' b:templateVersion='1.3.3' expr:dir='data:blog.languageDirection' expr:lang='data:blog.locale' xmlns='http://www.w3.org/1999/xhtml' xmlns:b='http://www.google.com/2005/gml/b' xmlns:data='http://www.google.com/2005/gml/data' xmlns:expr='http://www.google.com/2005/gml/expr'>
<head>
<meta content='width=device-width, initial-scale=1' name='viewport'/>
+ <!-- <title><data:view.title.escaped/></title> -->
+ <!-- NOTE: トップページを除いて「ページ名 - ブログ名」 になるように修正 -->
+ <b:if cond='data:view.title.escaped == data:blog.title'>
<title><data:view.title.escaped/></title>
+ <b:else/>
+ <title><data:view.title.escaped/> - <data:blog.title/></title>
+ </b:if>
<b:include data='blog' name='all-head-content'/>
<b:skin version='1.3.3'><![CDATA[/*! normalize.css v3.0.1 | MIT License | git.io/normalize */html{font-family:sans-serif;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}body{margin:0}article,aside,details,figcaption,figure,footer,header,hgroup,main,nav,section,summary{display:block}audio,canvas,progress,video{display:inline-block;vertical-align:baseline}audio:not([controls]){display:none;height:0}[hidden],template{display:none}a{background:transparent}a:active,a:hover{outline:0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:bold}dfn{font-style:italic}h1{font-size:2em;margin:.67em 0}mark{background:#ff0;color:#000}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sup{top:-0.5em}sub{bottom:-0.25em}img{border:0}svg:not(:root){overflow:hidden}figure{margin:1em 40px}hr{-moz-box-sizing:content-box;box-sizing:content-box;height:0}pre{overflow:auto}code,kbd,pre,samp{font-family:monospace,monospace;font-size:1em}button,input,optgroup,select,textarea{color:inherit;font:inherit;margin:0}button{overflow:visible}button,select{text-transform:none}button,html input[type="button"],input[type="reset"],input[type="submit"]{-webkit-appearance:button;cursor:pointer}button[disabled],html input[disabled]{cursor:default}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}input{line-height:normal}input[type="checkbox"],input[type="radio"]{box-sizing:border-box;padding:0}input[type="number"]::-webkit-inner-spin-button,input[type="number"]::-webkit-outer-spin-button{height:auto}input[type="search"]{-webkit-appearance:textfield;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;box-sizing:content-box}input[type="search"]::-webkit-search-cancel-button,input[type="search"]::-webkit-search-decoration{-webkit-appearance:none}fieldset{border:1px solid #c0c0c0;margin:0 2px;padding:.35em .625em .75em}legend{border:0;padding:0}textarea{overflow:auto}optgroup{font-weight:bold}table{border-collapse:collapse;border-spacing:0}td,th{padding:0}
@@ -3938,6 +3944,10 @@
<b:includable id='userProfile'>
<b:include name='userProfileImage'/>
<b:include name='userProfileInfo'/>
+ <!-- START CUSTOM PROFILE BLOCK -->
+ <a href="https://github.com/ginokent/" rel="noopener noreferrer"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>.github-icon{fill:#fafafa;}</style><path class="github-icon" d="M12 0c-6.626 0-12 5.373-12 12 0 5.302 3.438 9.8 8.207 11.387.599.111.793-.261.793-.577v-2.234c-3.338.726-4.033-1.416-4.033-1.416-.546-1.387-1.333-1.756-1.333-1.756-1.089-.745.083-.729.083-.729 1.205.084 1.839 1.237 1.839 1.237 1.07 1.834 2.807 1.304 3.492.997.107-.775.418-1.305.762-1.604-2.665-.305-5.467-1.334-5.467-5.931 0-1.311.469-2.381 1.236-3.221-.124-.303-.535-1.524.117-3.176 0 0 1.008-.322 3.301 1.23.957-.266 1.983-.399 3.003-.404 1.02.005 2.047.138 3.006.404 2.291-1.552 3.297-1.23 3.297-1.23.653 1.653.242 2.874.118 3.176.77.84 1.235 1.911 1.235 3.221 0 4.609-2.807 5.624-5.479 5.921.43.372.823 1.102.823 2.222v3.293c0 .319.192.694.801.576 4.765-1.589 8.199-6.086 8.199-11.386 0-6.627-5.373-12-12-12z"/></svg></a>
+ <a href="https://twitter.com/ginokentdev/" rel="noopener noreferrer"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>.twitter-icon{fill:#1DA1F2;}</style><path class="twitter-icon" d="M24 4.557c-.883.392-1.832.656-2.828.775 1.017-.609 1.798-1.574 2.165-2.724-.951.564-2.005.974-3.127 1.195-.897-.957-2.178-1.555-3.594-1.555-3.179 0-5.515 2.966-4.797 6.045-4.091-.205-7.719-2.165-10.148-5.144-1.29 2.213-.669 5.108 1.523 6.574-.806-.026-1.566-.247-2.229-.616-.054 2.281 1.581 4.415 3.949 4.89-.693.188-1.452.232-2.224.084.626 1.956 2.444 3.379 4.6 3.419-2.07 1.623-4.678 2.348-7.29 2.04 2.179 1.397 4.768 2.212 7.548 2.212 9.142 0 14.307-7.721 13.995-14.646.962-.695 1.797-1.562 2.457-2.549z"/></svg></a>
+ <!-- END CUSTOM PROFILE BLOCK -->
</b:includable>
<b:includable id='userProfileData'>
<dt class='profile-data'>
@@ -4088,5 +4098,128 @@
</aside>
<b:template-script async='true' name='indie' version='1.0.0'/>
+
+ <!-- START CUSTOM BODY BLOCK -->
+ <!-- NOTE: </body> の直前に書く -->
+ <!-- NOTE: https://github.com/markedjs/marked を使うときはこっち -->
+ <script src="//cdnjs.cloudflare.com/ajax/libs/marked/4.0.18/marked.min.js"></script>
+ <script>
+ document.querySelectorAll('markdownContent').forEach(e => {
+ e.insertAdjacentHTML('afterend', marked.parse(e.textContent));
+ e.remove();
+ });
+ </script>
+ <!-- NOTE: https://github.com/markdown-it/markdown-it を使うときはこっち -->
+ <!-- <script src="//cdnjs.cloudflare.com/ajax/libs/markdown-it/13.0.1/markdown-it.min.js"></script>
+ <script>
+ document.querySelectorAll('markdownContent').forEach(e => {
+ e.insertAdjacentHTML('afterend', window.markdownit().render(e.textContent));
+ e.remove();
+ });
+ </script> -->
+ <link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/highlight.js/11.6.0/styles/github.min.css" media="print" onload="this.media='all'"/>
+ <script src="//cdnjs.cloudflare.com/ajax/libs/highlight.js/11.6.0/highlight.min.js"></script>
+ <script src="//cdnjs.cloudflare.com/ajax/libs/highlight.js/11.6.0/languages/awk.min.js"></script>
+ <script src="//cdnjs.cloudflare.com/ajax/libs/highlight.js/11.6.0/languages/dos.min.js"></script>
+ <script src="//cdnjs.cloudflare.com/ajax/libs/highlight.js/11.6.0/languages/erlang.min.js"></script>
+ <script src="//cdnjs.cloudflare.com/ajax/libs/highlight.js/11.6.0/languages/erlang-repl.min.js"></script>
+ <script src="//cdnjs.cloudflare.com/ajax/libs/highlight.js/11.6.0/languages/go.min.js"></script>
+ <script src="//cdnjs.cloudflare.com/ajax/libs/highlight.js/11.6.0/languages/ldif.min.js"></script>
+ <script src="//cdnjs.cloudflare.com/ajax/libs/highlight.js/11.6.0/languages/scheme.min.js"></script>
+ <script src="//cdnjs.cloudflare.com/ajax/libs/highlight.js/11.6.0/languages/yaml.min.js"></script>
+ <script src="//cdnjs.cloudflare.com/ajax/libs/highlightjs-line-numbers.js/2.8.0/highlightjs-line-numbers.min.js"></script>
+ <script>
+ hljs.highlightAll();
+ hljs.initLineNumbersOnLoad();
+ </script>
+ <!-- NOTE: cf. https://github.com/wcoder/highlightjs-line-numbers.js/#usage -->
+ <style>
+ /* NOTE: コードブロックの行番号用スタイル */
+ /* for block of numbers */
+ .hljs-ln-numbers {
+ -webkit-touch-callout: none;
+ -webkit-user-select: none;
+ -khtml-user-select: none;
+ -moz-user-select: none;
+ -ms-user-select: none;
+ user-select: none;
+
+ text-align: center;
+ color: #999;
+ border-right: 1px solid #999;
+ vertical-align: top;
+ padding-right: 5px !important; /* !important が無いと padding 0 で上書きされて消滅する。使用テーマの仕業っぽい */
+
+ /* your custom style here */
+ }
+
+ /* for block of code */
+ .hljs-ln-code {
+ padding-left: 10px !important; /* !important が無いと padding 0 で上書きされて消滅する。使用テーマの仕業っぽい */
+ }
+ </style>
+ <style>
+ /* NOTE: highlight.js (?) によって table が破壊されるので別途スタイルを適用 */
+ table:not(.hljs-ln) tr:nth-child(even) {
+ ackground: #e9faf9;
+ }
+ table:not(.hljs-ln) {
+ margin: 20px 0px;
+ }
+ table:not(.hljs-ln) th,
+ table:not(.hljs-ln) td {
+ padding: 4px 10px;
+ border-bottom: solid 1px #778ca3;
+ }
+ </style>
+ <style>
+ /* NOTE: h タグの下線スタイル */
+ .entry-content h1 { border-bottom: solid 3px #aaa }
+ .entry-content h2 { border-bottom: solid 2px #aaa }
+ .entry-content h3 { border-bottom: solid 0.5px #aaa }
+ /* NOTE: h タグを Markdown のような見た目にするスタイル */
+ .entry-content h1::before {
+ content: '# '; /* Safari 用のフォールバック */
+ content: '# ' / ''; /* 読み上げ等に対しては空文字として認識させる */
+ }
+ .entry-content h2::before {
+ content: '## '; /* Safari 用のフォールバック */
+ content: '## ' / ''; /* 読み上げ等に対しては空文字として認識させる */
+ }
+ .entry-content h3::before {
+ content: '### '; /* Safari 用のフォールバック */
+ content: '### ' / ''; /* 読み上げ等に対しては空文字として認識させる */
+ }
+ .entry-content h4::before {
+ content: '#### '; /* Safari 用のフォールバック */
+ content: '#### ' / ''; /* 読み上げ等に対しては空文字として認識させる */
+ }
+ .entry-content h5::before {
+ content: '##### '; /* Safari 用のフォールバック */
+ content: '##### ' / ''; /* 読み上げ等に対しては空文字として認識させる */
+ }
+ .entry-content h6::before {
+ content: '###### '; /* Safari 用のフォールバック */
+ content: '###### ' / ''; /* 読み上げ等に対しては空文字として認識させる */
+ }
+ /* NOTE: コンテンツ内の引用文用スタイル */
+ .entry-content blockquote {
+ position: relative;
+ margin: 2em;
+ padding: 0.1em 0em 0.1em 2.2em;
+ text-align: left;
+ font-size: 0.9em;
+ font-style: italic;
+ color: #788897;
+ border-left: 5px solid #788897;
+ border-radius: 3px;
+ }
+ </style>
+ <style>code{font-family:'Ricty Diminished',Ricty,'Noto Sans Mono CJK JP','Myrica M','MyricaM M','Rounded M+ 1m regular','Rounded M+ 2m regular','Rounded Mgen+ 1m regular','Rounded Mgen+ 2m regular','Migu 1M','Migu 2M','M+ 1m','M+ 2m',Osaka-Mono,Menlo,Monaco,Inconsolata,Consolas,'Andale Mono','Roboto Mono','Ubuntu Mono','Courier New',monospace}</style>
+ <style>.entry-content pre code{color:#222;background:#f0f0f0}</style>
+ <style>.entry-content code{color:#222;background:#ccc}</style>
+ <style>kbd{padding:.1em .6em;border:1px solid rgba(63,63,63,0.25);-webkit-box-shadow:0 1px 0 rgba(63,63,63,0.25);box-shadow:0 1px 0 rgba(63,63,63,0.25);font-size:.7em;font-family:sans-serif;background-color:#fff;color:#333;border-radius:3px;display:inline-block;margin:0 .1em;white-space:nowrap}</style>
+ <!-- NOTE: </body> の直前に書く -->
+ <!-- END CUSTOM BODY BLOCK -->
</body>
</html>
```