追記情報
- 2018.12.10: 機能追加
- 2018.12.14: Chrome Extension公開
お前の二番煎じじゃね?
はい、そうですけど?
そうですけど、ガチなChrome拡張作ったから、とりあえず見て!!!!!
#TwitterMD pic.twitter.com/WfR1O0Moor
— Ryosuke Suzuki (@GentleClarinet) 2018年12月8日
ということで、明治大学advent calendarやっていきます。
Abstract
Twitterという素晴らしいSNSにマークダウンを画像として投稿できるようにする、ガチなChrome拡張を作った。
Introduction
皆さん、Twitterは使ってる????
僕は身体の一部って思っているレベルで使ってる。いや、もはや息を吸うレベルで使ってる。信じるか信じないはあなた次第。
Twitterは最高なんですけど、以下のような仕方がない問題があるよね。(多分、エンジニアとか理系な人たちが特に思っているんだろうな。)
- 数式が書けない
- コードが書けない
- 280文字ぐらい制限
上記のような問題に対して、Twitterユーザーは以下のようなことをするよね。
- 数式はtex記法か画像
- コードはplainか画像
これ、正直どうにかしたい。
Related works
どうやら、解決策が幾つかあるそう。
1. TwitterでMarkdownを使えるようにした
Chrome拡張で、Twitterでmarkdownをレンダリングするやりかた。
Pros
- markdownが使える
- sytax highlightされる
Cons
- Chrome拡張をインストールしているデバイスでのみmarkdownがレンダリングされる
- Twitterのeditorでmarkdownを書く必要がある
- 数式が使えない
2. Mathtodon
あの、一時期、流行ってた分散型Twitterであるマストドン。マストドンに数式をレンダリングする機能を追加したインスタンス。(使ったことないからよくわからん。)
Pros
- 数式が書ける
Cons
- Twitterじゃない
3. ritwee
WYSWYGエディターでrichなツイートできるサービス。画像化してツイートするやり方。
Pros
- 画像としてツイートされるので、デバイス依存無し
- syntax highlight
- WYSWYG
Cons
- Ritweeのサイトに行かないとダメで、めんどい
- 数式が使えない
- WYSWYGが好きじゃない(個人的な好みだけど、皆、markdown好きでしょ?)
My method
色々な解決策があるとはいえ、consの部分が痛いので、only prosな解決策を考えた。
Overview
Chrome拡張でmarkdownを画像にし、Twitter APIで画像をツイートする。
Chrome拡張
どのウェブサイトを見ていても、クローム拡張のポップアップならアクセシビリティが良い。Twitterを拡張するにはもってこい。
md to html
markdown-it
なり、marked
なりのmd parserを使い、mdをhtmlにする。今回はmarkdown-it
にした。
import markdownIt from "markdown-it";
const mdParser = markdownIt({
html: true,
xhtmlOut: true,
breaks: true,
langPrefix: "language-",
linkify: true,
});
sytax highlight
syntax highlightする。今回はhighlihghtjs
を使う。
import hljs from "highlightjs";
const mdParser = markdownIt({
//...
highlight: function(str, lang) {
if (lang && hljs.getLanguage(lang)) {
try {
return hljs.highlight(lang, str).value;
} catch (__) {}
}
return ""; // use external default escaping
}
})
Checkbox
markdown-itのcheckbox記法をパースしてくれるをpluginがある。
import markdownCheckbox from "markdown-it-checkbox";
mdParser.use(markdownCheckbox);
Math formula
有名どころだとMathjax
があるが、重いので使いたくない。今回は高速で有名なkatex
を使う。面倒なので、markdown-itにkatex pluginを使う。
import markdownKatex from "markdown-it-katex";
mdParser.use(markdownKatex)
html to image
画像に変換することが大事。これでデバイス依存無しにマークダウンをレンダリングできるようになる。
今回は、html2canvas
というOSSを使い、domをcanvasにし、canvasからpngにする。ここで注意が必要なのは、html to canvasではなく、dom to canvasであること。しかも、domもinnerHtmlとかはダメだったりして、工夫が必要。
まずは、htmlからdomを作る。
const parser = new DOMParser()
const wrapper = parser.parseFromString(html, "text/html");
wrapper.body以下のdomをブラウザでレンダリングさせる。
const nodes = wrapper.body.childNodes;
const markdownBody = document.createElement("div");
nodes.forEach(node => {
markdownBody.append(node);
});
document.body.appendChild(markdownBody);
すると、canvasに変換することができるようになる。
html2canvas(markdownBody)
.then(canvas => {
//...
});
そして、画像にする。
html2canvas(markdownBody)
.then(canvas => {
canvas.toBlob(blob => {
//...
});
});
ここで、注意なのが、canvasで別オリジンの画像をレンダリングできないこと。なので、Access-Control-Allow-Origin
ヘッダーを付与するためのproxy層が必要になる。
どうやら、html2canvas
がCORS用のexpress middlewareを提供してくれているのでそれを使う。
const express = require("express");
const app = express();
const proxy = require("html2canvas-proxy");
app.use("/corsProxy", proxy());
そして、html2canvas
のオプションを設定する。
html2canvas(markdownBody, {
proxy: `${config.apiUrl}/corsProxy`,
useCORS: true
})
これで、mdを完璧にレンダリングできるようになる。
Twitter api
nodejsのtwitter
モジュールを使う。まずは画像をアップロードしてから、ツイートする。
const twitterClient = new Twitter({
consumer_key: config.consumerKey,
consumer_secret: config.consumerSecret,
access_token_key: user.access_token,
access_token_secret: user.access_token_secret
});
twitterClient.post("media/upload", { media: image }, (err, media) => {
if (err) return
const status = {
status: "something",
media_ids: media.media_id_string // Pass the media id string
};
twitterClient.post("statuses/update", status, function(err, tweet) {
if (!err) console.log('done')
});
});
あとは、reactなりvueなりを使ってホゲホゲして最高の拡張を作って、終わり。
My work
Chrome拡張を作った。名前は TwitterMD。Github
現在、chrome web storeに申請中。リジェクトされたった👿
We may remove your item if it has an unclear description field, or missing icons or screenshots, and appears to be suspicious
description書くの忘れてた。。。。
とりあえず、Chrome拡張はGithubに置いておきます。申請通ったら追記します。
数日で開発してソースコードが汚いのと、API KEYを直書きしてしまっているので、ソースコードは載せてません。いつか、綺麗にして公開します。create-react-app使わなければよかった。。。
追記: 12/10 - Published Chrome Extension
- chrome web storeにrejectされまくっていて辛い👿
- 機能追加
- markdownのcssをカスタマイズ可能に
- ツイート時の本文を設定可能に
- Front Matter
追記: 12/14
- chrome web extension ようやく公開できました。
おわりに
僕/私も機能追加したい!なんて方が居たら連絡ください!
連絡はここ(twitter)までお願いします。