大枠の作成
早速エディタを作ってみます。
パパっと作って記事にしたいのでHTMLでいいか。
まずHTMLをこのように記述します。
<!DOCTYPE html>
<html>
<head>
<title>editor</title>
<script src="text/convert.js"></script>
<link rel="stylesheet" media="all" href="article.css" />
</head>
<body>
<div class="position-fix">
<div class="con">
<textarea>#hoge</textarea>
<div class="buttons">
<button class="conv">Convert</button>
</div>
</div>
</div>
<div class="result">
<div></div>
</div>
</body>
</html>
CSSは笹錆ログで普段使いしてるものに、次のコードを追記しましょう。
.position-fix{
width: 50%;
height: 100%;
position:fixed;
}
.con{
margin-left: auto;
margin-right: auto;
width: 100%;
height: 90%;
float: left;
}
.con textarea{
width: 100%;
height: 52em;
resize: none;
overflow-y: scroll;
}
.buttons{
height: 10%;
}
.result{
width: 50%;
float: right;
}
すると、こんな感じになります。
不格好ですが、使えないことはないので続行します。
このままではMarkdown→HTMLの変換が行えないので、Javascriptで処理しましょう。
変換用の関数はこんな感じです。
function convertMarkdownToHtml(markdown) {
var html = markdown;
// ヘッダー(#)の変換
html = html.replace(/^#\s+(.*)$/gm, "<h1>$1</h1><p>");
html = html.replace(/^##\s+(.*)$/gm, "<h2>$1</h2><p>");
// 強調(**テキスト**)の変換
html = html.replace(/\*\*(.*?)\*\*/g, "<strong>$1</strong>");
// 斜体(*テキスト*)の変換
html = html.replace(/\*(.*?)\*/g, "<em>$1</em>");
// リンク([テキスト](URL))の変換
html = html.replace(/\[(.*?)\]\((.*?)\)/g, '<a href="$2">$1</a>');
// 改行の変換
html = html.replace(/\n\n/g, "<br>");
html = html.replace(/\n/g, "<br>");
html = html + "</p>";
html = html.replace(/<p><br>/g, "<p>");
return html;
}
笹錆ログで登場するのはh1、h2、p、strong、italic、aの6つですので、これらが変換できればよしとしています。
今回はやってないですが、h1~6までの変換はこのような関数を書くと楽だったりします。
html = html.replace(/(^|\n)(#+)(.*)/g, function (match, p1, p2, p3) {
var headerLevel = p2.length;
return (
p1 + "<h" + headerLevel + ">" + p3.trim() + "</h" + headerLevel + ">"
);
});
あとはtextarea内の要素を取り出して、この関数に通してからresult内に出力すればいいだけです。
というわけで、こんな感じのをJavascriptに追記しましょう。
function convertAndDisplay() {
const markdownInput = document.getElementById("markdownInput");
const htmlOutput = document.getElementById("htmlOutput");
const markdownText = markdownInput.value;
var convertedHtml = "";
convertedHtml +=
'<div class="toppage"><div class="window">' +
convertMarkdownToHtml(paragraph) +
'</div></div>';
htmlOutput.innerHTML = convertedHtml;
}
この記述で、HTML内でidがmarkdownInputのものを取り出し、関数に通してからidがhtmlOutputに出力します。
というわけで、最後にHTMLの一部をこのように変更します。
<!DOCTYPE html>
<html>
<head>
<title>editor_test</title>
<script src="text/convert.js"></script>
<link rel="stylesheet" media="all" href="text/article.css" />
</head>
<body>
<div class="position-fix">
<div class="con">
<textarea id="markdownInput">#hoge</textarea>
<div class="buttons">
<button onclick="convertAndDisplay()" class="conv">Convert</button>
</div>
</div>
</div>
<div class="result">
<div id="htmlOutput"></div>
</div>
</body>
</html>
これで左に打ち込んだものを右に出力できるようになりました。
オリジナル記法の作成
次にオリジナルの記法をMarkdownに追加しましょう。
追加するのは吹き出し、メモ、ウィンドウの始めと終わり、マーカー見出しの4つです。
メモは名古屋旅行に一度、マーカー見出しはLegal Infoに一度出ていますね。
H君
このサイトを知ってるやつ全員がLegal Infoまで見てると思うなよ。
記法を追加するのは楽で、ConvertHtmlに書き加えるだけです。
吹き出しは-(人名)「(内容)」、メモは-m(タイトル)「(内容)」、マーカー見出しは-p (タイトル)、ウィンドウの区切りは---で設定できるようにしました。
コードは次のようになります。
// メモ(-m(タイトル)「(内容)」)の変換
html = html.replace(
/-m(.*?)「(.*?)」/g,
'</p>\n\t\t<div class="art-memo"><h2>$1</h2><p class="memo-text">$2</p></div>\n\t\t<p>'
);
// 吹き出し(-(人名)「(内容)」)の変換
html = html.replace(/-(.*?)「(.*?)」/g, (match, title, content) => {
let replacement =
'</p>\n\t\t<div class="balloon-set-box"><div class="icon-box"><img src="';
if (dictionary.hasOwnProperty(title.trim())) {
replacement += `${dictionary[title.trim()]}`;
}
replacement += `" class="icon"><p>${title.trim()}</p></div><div class="balloon"><p>${content.trim()}</p></div></div>\n\t\t<p>`;
return replacement;
});
// 付箋見出し(-p (タイトル))の変換
html = html.replace(
/-p\s+(.*?)$/gm,
'</p><p><strong class="p-str">$1</strong></p><p>'
);
function convertAndDisplay(mark: vscode.TextEditor) {
var convertedHtml = "";
var markdown = mark.document.getText();
const pages = markdown.split("--p");
for (var k = 0; k < pages.length; k++) {
const paragraphs = pages[k].split("---"); // 「---」で文章を区切る
for (var i = 0; i < paragraphs.length; i++) {
var paragraph = paragraphs[i].trim();
if (i === 0) {
convertedHtml +=
'<div class="toppage"><div class="window">' +
convert(paragraph, dictional) +
'</div></div><div class="headline">';
} else if (i === 1) {
if (i === paragraphs.length - 1) {
convertedHtml +=
'<div class="top-window window-end">' +
convert(paragraph, dictional) +
"</div>";
} else {
convertedHtml +=
'<div class="top-window">' +
convert(paragraph, dictional) +
"</div>";
}
} else if (i === paragraphs.length - 1) {
convertedHtml +=
'<div class="window window-end">' +
convert(paragraph, dictional) +
"</div>";
} else {
convertedHtml +=
'<div class="window">' + convert(paragraph, dictional) + "</div>";
}
}
convertedHtml += "</div>";
}
return prevcss + convertedHtml;
}
はじめにウィンドウごとに区切り、区切ったウィンドウごとに変換させています。
吹き出しの方は名前と画像を対応させる必要があったので、名前をkeyにした辞書配列を作っています。
いい感じですね。
ダウンロード処理の作成
最後にダウンロードをさせましょう。
今はボタンを押すとコンバートできるような形式にしていますが、このボタンをダウンロードに変え、コンバートは自動で行うように変更します。
このようにHTML、Javascriptを書き換えてください。
<!DOCTYPE html>
<html>
<head>
<title>editor_test</title>
<script src="text/convert.js"></script>
<link rel="stylesheet" media="all" href="text/article.css" />
</head>
<body>
<div class="position-fix">
<div class="con">
<textarea id="markdownInput">#hoge</textarea>
<div class="buttons">
<button onclick="downloadHtmlFile()" class="down">download</button>
</div>
</div>
</div>
<div class="result">
<div id="htmlOutput"></div>
</div>
</body>
</html>
var htmlContent = "";
function downloadHtmlFile() {
const element = document.createElement("a");
element.setAttribute(
"href",
"data:text/html;charset=utf-8," + encodeURIComponent(htmlContent)
);
element.setAttribute("download", "converted.html");
element.style.display = "none";
document.body.appendChild(element);
element.click();
document.body.removeChild(element);
}
window.onload = function () {
//500ミリ秒ごとにコンバート処理を行なう
setInterval("convertAndDisplay()", 500);
};
コンバートは0.5秒に1度行うようにしました。
この状態でボタンを押すと、このようになります。
さて、これで早速クソサイトを量産し、アフィリエイト収益をガツガツ得たいと思います。
とりあえず記事をポチポチ書いて…..
やりずらっ!!!
特にtextareaの部分が見にくいです。
このままでも記事を書けないことはないですが、やはり使い慣れたソフトであるVScodeで同じようなことがしたいですね。
それと、このままではNotionを使っている意味がない気もしますね。
というわけで、VScodeの拡張機能を作り、もっと楽な環境を作りましょう。