概要

当サイトで使っている縦組み表示用のjQueryプラグインです。

読み込んだテキストデータを、1ページあたりの行数と1行あたりの字数を指定してページ単位で書き出します。

小文字などの位置調整や横書き用文字の回転などはCSSで行っています。

使い方

jQueryプラグインなのでjQueryが無いと動きません。

下記のスクリプトを適当なJavaScriptファイルとして保存し、jQueryと一緒に読み込んでください。

srcは各ファイルを正しく参照できるように書き換えてください。

<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript" src="VerticalTypesetter.js"></script>

修正履歴

2013/06

  • 特殊文字を使えるようにスクリプトを修正(28-33行目)
  • webkit 系ブラウザ以外は transform がそのまま使えるようになったので CSS を修正(49-50行目)

スクリプト

プレーンテキストを読み込むことを前提としているので、urlで参照するファイルにタグやスクリプトが含まれていてもそのまま表示されます。

読み込むテキストデータの文字コードはUTF-8にしてください。Shift-JISの場合、jQuery本体をいじらないと文字化けします。

禁則処理の対象となる文字や約物として扱う文字などについては、適当にcaseを追加・削除してください。

当サイトのフリックスクロールのように、completeに任意の関数を組み込むことで、書き出したHTMLに対してjQueryエフェクトを設定することもできます。(261-262行目)

1文字ずつ処理するので、ブラウザによっては動作が重いことがあります。

/* 縦組みjQueryプラグイン( Ver1.1 ) */
$.fn.Vertical_Typesetter = function(lines, chrs, page, url){ // lines:1ページあたりの行数, chrs:1行あたりの字数, page:出力ページ, url:読み込み元URL

	var target_element = this;	// 置換元要素
	var null_flag = false;		// 空文字チェックフラグ

	return this.each(function(){
		$.ajax({						// $.ajax関数
			url: url,					// リクエスト送信先URL
			type: "get",				// HTTP通信の種類
			success: function(data){	// AJAX通信成功時に呼び出されるAjax Event(data:XMLHttpRequestオブジェクト)

				var txt = data;						// 読み込みデータ
				var vhtml = "<div id='vts_doc'>";   // 縦組みHTML(全体開始タグ)
				var lhtml = "";						// 行HTML
				var thtml = "";						// 作業用HTML
				var c = "";							// 文字格納変数
				var cn = "";						// 次文字格納変数
				var cc = 0;							// 字数カーソル
				var end_flg = false;				// 行終了チェックフラグ

				for(var l = 0; l < page * lines; l++){	// 行ループ
					if(l >= (page - 1) * lines){			// 指定より前のページは無視
						thtml = "<div class='ibox'>";    // 行開始タグ
					}
					for(var i = 0; i < chrs; i++){ // 列ループ
						c = txt.charAt(cc);
						if(c == "&"){ // 特殊文字処理
							while(txt.charAt(cc) != ";"){
								cc++;
								c += txt.charAt(cc);
							}
						}
						cn = txt.charAt(cc + 1);
						switch(c){ // 改行コードエスケープ処理
							case "\r\n":
							case "\r":
							case "\n":
								c = "";
								end_flg = true;
								break;
						}
						if(i == chrs - 1){ // 行末禁則処理
							switch(c){
								case "「":
								case "『":
								case "【":
								case "[":
								case "[":
								case "{":
								case "{":
								case "(":
								case "(":
								case "<":
								case "〈":
								case "≪":
								case "《":
									c = "";
									end_flg = true;
									break;
							}
						}
						switch(c){ // 文字タグ生成
							case "。":
							case "、":
							case ".":
							case ",":
								/* 句読点タグ */
								thtml += "<div class='pbox'><span>" + c + "</span></div>";
								break;
							case "ー": 
							case "-": 
							case "―":
							case "~":
							case "…":
							case "「":
							case "」":
							case "『":
							case "』":
							case "【":
							case "】":
							case "[":
							case "]":
							case "[":
							case "]":
							case "{":
							case "}":
							case "{":
							case "}":
							case "(":
							case ")":
							case "(":
							case ")":
							case "<":
							case ">":
							case "〈":
							case "〉":
							case "≪":
							case "≫":
							case "《":
							case "》":
							case ":":
							case ";":
								/* 横書文字タグ */
								thtml += "<div class='rtbox'><span>" + c + "</span></div>";
								break;
							case "“":
								/* 引用符(開き)タグ */
								thtml += "<div class='oqbox'><span>" + c + "</span></div>";
								break;
							case "”":
								/* 引用符(閉じ)タグ */
								thtml += "<div class='cqbox'><span>" + c + "</span></div>";
								break;
							case "ぁ":
							case "ぃ":
							case "ぅ":
							case "ぇ":
							case "ぉ":
							case "っ":
							case "ゃ":
							case "ゅ":
							case "ょ":
							case "ァ":
							case "ィ":
							case "ゥ":
							case "ェ":
							case "ォ":
							case "ッ":
							case "ャ":
							case "ュ":
							case "ョ":
								/* 小文字タグ */
								thtml += "<div class='sbox'><span>" + c + "</span></div>";
								break;
							default:
								/* 普通文字タグ */
								thtml += "<div class='cbox'><span>" + c + "</span></div>";
								break;
						}
						if(i == chrs - 1){ // 行頭禁則処理
							switch(cn){
								case "。":
								case "、":
									/* 句読点タグ */
									thtml += "<div class='pbox'><span>" + cn + "</span></div>";
									cc++;
									brc = txt.charAt(cc + 1);
									switch(brc){ // 改行コードエスケープ処理
										case "\r\n":
										case "\r":
										case "\n":
											cc++;
											break;
									}
									break;
								case "」":
								case "』":
								case "】":
								case "]":
								case "]":
								case "}":
								case "}":
								case ")":
								case ")":
								case ">":
								case "〉":
								case "≫":
								case "》":
								case ":":
								case ";":
									/* 横書文字タグ */
									thtml += "<div class='rtbox'><span>" + cn + "</span></div>";
									cc++;
									brc = txt.charAt(cc + 1);
									switch(brc){ // 改行コードエスケープ処理
										case "\r\n":
										case "\r":
										case "\n":
											cc++;
											break;
									}
									break;
								case "”":
									/* 引用符(閉じ)タグ */
									thtml += "<div class='cqbox'><span>" + cn + "</span></div>";
									cc++;
									brc = txt.charAt(cc + 1);
									switch(brc){ // 改行コードエスケープ処理
										case "\r\n":
										case "\r":
										case "\n":
											cc++;
											break;
									}
									break;
								case "°":
								case "’":
								case "′":
								case "″":
								case "々":
								case "゛":
								case "゜":
								case "ゝ":
								case "ゞ":
								case "ヽ":
								case "ヾ":
								case "!":
								case ",":
								case ".":
								case "?":
								case "。":
									/* 普通文字タグ */
									thtml += "<div class='cbox'><span>" + cn + "</span></div>";
									cc++;
									brc = txt.charAt(cc + 1);
									switch(brc){ // 改行コードエスケープ処理
										case "\r\n":
										case "\r":
										case "\n":
											cc++;
											break;
									}
									break;
								case "\r\n":
								case "\r":
								case "\n":
									if(c != ""){
										cc++;
									}
									break;
							}
						}
						if(end_flg == false){ // 1行分の文字数に満たない場合
							cc++;
						}
					}
					if(l >= (page - 1) * lines){              // 指定より前のページは無視
						if(thtml != "<div class='ibox'>"){ // 文字タグがある場合
							thtml += "</div>";             // 行終了タグ
							lhtml = thtml + lhtml;
						}
					}
					if(end_flg){
						cc++;
					}
					end_flg = false
					if(l == page * lines - 1){ // 指定行数チェック
						break;
					}
				}
				vhtml += lhtml + "</div>"; // 全体終了タグ
				if($(vhtml).text() == ""){ // 空文字判定
					null_flag = true;
					return false;
				}
				else{
					$(target_element).replaceWith(vhtml); // タグ置換
				}
			},
			complete: function(){ // AJAX通信完了時に呼ばれる関数
			}
		});
	});
}

CSS

ブラウザで拡大縮小を行ってもレイアウトが崩れないように、単位は基本的にemを使っています。

横書き用文字の回転については、ブラウザエンジンごとの独自拡張も使っています。(49-50行目)

#vts_doc { /* 縦組み全体 */
	margin: 0;
	padding: 0;
	right: 0;
	font-size: 18px;
	white-space: nowrap;
	position: relative;
	overflow: hidden;
}

.ibox { /* 行ボックス */
	display: inline-block;
	vertical-align: top;
	margin: 0 3px;
}

.cbox, .sbox, .pbox, .oqbox, .cqbox, .rtbox { /* 文字ボックス */
	width: 1.5em;
	height: 1.5em;
	border: 1px solid #eeeeee;
}

.cbox { /* 普通文字 */
	text-align: center;
}

.sbox { /* 小文字(ぁぃぅぇぉっ等)の位置調整 */
	text-indent: 0.5em;
	line-height: 1em;
}

.pbox { /* 句読点の位置調整 */
	text-indent: 1em;
	line-height: 0.4em;
}

.oqbox { /* 引用符(開始)の位置調整 */
	text-indent: 0em;
	line-height: 2.5em;
}

.cqbox { /* 引用符(終了)の位置調整 */
	text-indent: 1em;
	line-height: 1.5em;
}

.rtbox { /* 横書文字の位置調整と回転(90℃) */
	text-indent: 0.2em;
	transform: rotate(90deg);
	-webkit-transform: rotate(90deg); /* WebKit系ブラウザ用(Google Chrome, Safari等) */
}

免責事項

このページに掲載しているスクリプト及びCSS(以下、本スクリプト及びCSS)を使用したことによって生じたあらゆる結果(障害・損害・不具合等)に関しては、作者と作者の関係者および所属するいかなる団体・組織も一切の責任を負いませんので、本スクリプト及びCSSを使用する際は、その点を了承した上で各自の責任においてご使用ください。