Permalink
Switch branches/tags
Nothing to show
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
162 lines (153 sloc) 8.95 KB
<html>
<head>
<title>Markdown対応文字数カウンター</title>
<meta charset="UTF-8" />
<meta name="keywords" content="文字数,カウント,計算,カウンター,markdown,記事,ブログ,github" />
<meta name="description" content="Markdownで書いた文章の文字数を計算できます。Markdownの文法や空白、スペースなどは無視して文字数をカウントできます。また、引用部分は文字数に含めない、コードブロックを文字数に含めない、見出しを文字数に含めないといったカスタマイズも可能です。執筆したブログ記事の文字数を確認したい!といった場合にご活用ください。" />
<meta property="og:type" content="website" />
<meta property="og:title" content="Markdown対応文字数カウンター" />
<meta property="og:url" content="https://yoshikyoto.github.io/markdown_string_counter/" />
<meta property="og:image" content="assets/images/englishbiscuit.jpg" />
<meta property="og:image:type" content="image/jpeg" />
<meta property="og:locale" content="ja_JP" />
<link rel="stylesheet" href="assets/styles/main.css"></link>
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
<script src="assets/scripts/lib/marked.js"></script>
<!-- Global site tag (gtag.js) - Google Analytics -->
<script async src="https://www.googletagmanager.com/gtag/js?id=UA-77941335-3"></script>
<script>
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('js', new Date());
gtag('config', 'UA-77941335-3');
</script>
</head>
<body>
<h1><a href="/markdown_string_counter">Markdown対応文字数カウンター</a></h1>
<div id="app">
<h2>設定</h2>
<div>
<input type="checkbox" v-model="ignoreCodeBlock" true-value="yes" false-value="no">コードブロック(```〜```)を文字数に含めない</input><br>
<input type="checkbox" v-model="ignoreBlockQuote" true-value="yes" false-value="no">引用(>)を文字数に含めない</input><br>
<input type="checkbox" v-model="ignoreHeading" true-value="yes" false-value="no">見出し(## ...)を文字数に含めない</input><br>
<input type="checkbox" disabled="true" checked>空白や改行、Markdownの記法は文字数に含まれません</input><br>
<input type="checkbox" disabled="true" checked>HTMLタグは文字数に含まれません(コードブロックを除く)</input>
</div>
<h2>文字数: {{ getCount() }}</h2>
<div><textarea v-model="text" cols="100" rows="25"></textarea></div>
<div>
処理後の文字列: <input type="text" :value="getFormattedText()" size="100"></input>
</div>
<h2>Markdown対応文字数カウンターとは?</h2>
Markdownで書かれた文章の文字数を(Markdown文法部分の文字数は除いて)カウントできます。ブログ記事執筆時の文字数確認などにご利用ください。
もちろん、設定を変更すればMarkdown出ない文章の文字数も計算できます。
<h2>お問い合わせ</h2>
機能改善や要望、バグなどのお問い合わせは以下の方法で受け付けております。
<ul>
<li>Twitter: <a href="https://twitter.com/yoshiki_utakata" target="_blank">@yoshiki_utakata</a> へのリプライ・DM等</li>
<li>GitHub: <a href="https://github.com/yoshikyoto/markdown_string_counter" target="_blank">yoshikyoto/markdown_string_counter</a>へのIssue/プルリクエスト</li>
</ul>
<h2>リンク</h2>
<ul>
<li><a href="https://github.com/yoshikyoto/markdown_string_counter" target="_blank">yoshikyoto/markdown_string_counter - GitHub</a></li>
<li>Twitter: <a href="https://twitter.com/yoshiki_utakata" target="_blank">@yoshiki_utakata</a></li>
<li><a href="http://yoshiki-utakata.hatenablog.com/" target="_blank">作者ブログ</a> の記事
<ul>
<li><a href="http://yoshiki-utakata.hatenablog.com/entry/20180113/1515823998" target="_blank">Markdownで書かれた文章の文字数をカウントできるサービスを作りました</a></li>
<li><a href="http://yoshiki-utakata.hatenablog.com/entry/20180110/1515574086" target="_blank">JavaScript で new RegExp('[\s\S]', 'gm') して、改行も含めた全ての文字列とマッチさせようとしてもうまくマッチしない</a></li>
</ul>
</li>
</ul>
</div>
<script>
var app = new Vue({
el: '#app',
data: {
/** 入力された文字列 */
text: 'ここに入力した文字をカウントしてくれます\n\n' +
'### 見出しの文字は無視するかどうか決められます(21文字)\n\n\n' +
'### 以下のコードブロックは無視するかどうか決められます\n\n```\ncode\n```\n(0文字 or 4文字)\n\n\n' +
'### 以下のコードブロックは文字数に含まれます\n\n`code`(4文字)\n\n\n' +
'### 引用は無視するかどうか決められます\n\n> quote\n\n(0文字or5文字)\n\n\n' +
'### その他要素も文字部分のみカウントされます\n\n* list(4文字)\n- list(4文字)\n\n**太字**(2文字)',
/** 改行を文字数に含まない(markdownコンパイル時にいろいろおこるので基本yes固定) */
ignoreNewLine: 'yes',
/** 空白を文字数に含まない(markdownコンパイル時にいろいろ起こるのでyes固定) */
ignoreWhiteSpace: 'yes',
/** コードブロックを文字数に含まない */
ignoreCodeBlock: 'yes',
/** 引用を文字数に含まない */
ignoreBlockQuote: 'yes',
/** 見出しを文字数に含まない */
ignoreHeading: 'no',
},
methods: {
/** markdownをhtmlに変換 */
render(text) {
return marked(text);
},
/** すべてのhtmlタグを除去 */
removeAllHtmlTag(html) {
return html.replace(/<("[^"]*"|'[^']*'|[^'">])*>/gm, '')
},
/** <tag> と </tag> を除去 */
removeHtmlTag(tag, html) {
return html.replace(new RegExp("</?" + tag + "(\"[^\"]*\"|'[^']*'|[^'\">])*>", 'gim'), '')
},
/** <tag>...</tag> をまるごと削除する */
removeHtmlTagBlock(tag, html) {
return html.replace(new RegExp('<' + tag + '("[^"]*"|\'[^\']*\'|[^\'">])*>[\\s\\S]*?</' + tag + '>' , 'gim'), '');
},
/** <blockquote>...</blockquote>を除去 */
removeBlockQuote(html) {
return this.removeHtmlTagBlock('blockquote', html);
},
/** <h1>...</h1> <h2>...</h2> など(見出し)を除去 */
removeHtmlHeading(html) {
return this.removeHtmlTagBlock('h[1-6]', html);
},
/** ``` code... ``` を除去 */
removeCodeBlock(text) {
return text.replace(new RegExp('```[\\s\\S]*?```', 'gm'), '');
},
/** 無視するコンポーネントを除去した文字列を返す */
getFormattedText() {
text = this.text
// コードブロック除去
// markdownのコードブロックには`と```があるがhtmlになると両方<code>になってしまうので
// ```だけ除去するためにrenderするまえにコードブロックをremove
if (this.ignoreCodeBlock === 'yes') {
text = this.removeCodeBlock(text);
}
// markdownをhtml化
html = this.render(text);
// 引用
if (this.ignoreBlockQuote === 'yes') {
html = this.removeBlockQuote(html);
}
// 見出し
if (this.ignoreHeading === 'yes') {
html = this.removeHtmlHeading(html);
}
// htmlタグを全て削除
html = this.removeAllHtmlTag(html);
return html;
},
/** 無視する文字列を除去した後文字列をカウントして返す */
getCount() {
text = this.getFormattedText();
// 改行
if (this.ignoreNewLine === 'yes') {
text = text.replace(/\r?\n/g, '')
}
// 空白
if (this.ignoreWhiteSpace === 'yes') {
text = text.replace(/\s/g, '')
}
return text.length;
}
},
});
</script>
</body>
</html>