Javascriptで数式番号の記載を実装したい
- 評価 -2
- クリップ 0
- VIEW 313
やりたいこと
- TeXでいうところの\label,\refみたいな数式番号をJavascriptで実装したい。
- 今回のサンプルでは、UL要素の入れ子の深さも加味した数式番号にしたい。
- ただし、条件として、兄弟要素間では通し番号をキープしておく。”いとこ要素”同士では例え同じ深さでも通し番号はリセットする。です。
現状、ここまで考えました:
- 数式番号を記載されるべき場所には、span要素を置いておく。
- こんな表記で:<span class="label" id="[1-2]" />
(1-2は、深さ1の2番目の数式番号という意味です。) - 呼び出す側は、<span class="ref" title="fukasa2"></span>とし、
fukasa2という文字列を手がかりに、それに対応した数式番号をJavaScriptを使って引き出してくる。 - 数式番号に書くために準備したラベルとそのラベルに対応した数式番号はハッシュで覚えておく。
- 要素の探索には、jQueryを使いつつ、再帰関数を定義しています。
- 詳しくはサンプルコードを見て下さい。
問題点・要望
- サンプルコードが機能しない。
- JavascriptもしくはHTMLで私の要望を満たすようなもっと上手いやり方があれば教えて下さい。
追記
サンプルコードの場合の望むべき結果は、
<li>3 ここから<span class="ref" title="fukasa2">to be removed</span></li>
と書かれている部分について、
ここからto be removed
と出力されるのではなくて、
ここから(3-1)
と出力されることです。
サンプルコード
<script type="text/javascript">
var hash_map_label = {};
function checkLabelNode(node, depth, num){
if(node == undefined){
return;
}
var newDepth = depth;
var newNum = num;
if(node.prop("tagName") == "UL"){
newDepth = newDepth+1;
} else if(node.prop("tagName") == "SPAN" && node.attr("class") == "label"){
newNum = newNum+1;
hash_map_label[node.attr("id")] = "(" + newDepth + "-" + newNum + ")";
node.replaceWith("it is ok.");
}
if(node.children() != undefined){
checkLabelNode(node.children().first(), newDepth, newNum);
}
checkLabelNode(node.next(), newDepth, newNum);
return;
}
$(function(){
checkLabelNode($('.functest').first(), 0, 0);
$("span.ref").each(function(index){
$(this).replaceWith(hash_map_label[$(this).attr("title")]);
});
});
</script>
<div class="functest">
<ul>
<li>1</li>
<li>2<span class="label" id="sample" />
<ul>
<li>1-1<span class="label" id="[1-1]" /></li>
<li>1-2<span class="label" id="[1-2]" />
<ul>
<li>2-1</li>
<li>2-2</li>
<li>2-3<span class="label" id="fukasa2" /></li>
</ul>
</li>
<li>1-3</li>
<li>1-4
<ul>
<li>2-1<span class="label" id="2番目の深さ1" /></li>
<li>2-2</li>
<li>2-3<span class="label" id="2番目の深さ2" /></li>
</ul>
</li>
</ul>
</li>
<li>3 ここから<span class="ref" title="fukasa2">to be removed</span></li>
</ul>
</div>
-
気になる質問をクリップする
クリップした質問は、後からいつでもマイページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
クリップを取り消します
-
良い質問の評価を上げる
以下のような質問は評価を上げましょう
- 質問内容が明確
- 自分も答えを知りたい
- 質問者以外のユーザにも役立つ
評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。
質問の評価を上げたことを取り消します
-
評価を下げられる数の上限に達しました
評価を下げることができません
- 1日5回まで評価を下げられます
- 1日に1ユーザに対して2回まで評価を下げられます
質問の評価を下げる
teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。
- プログラミングに関係のない質問
- やってほしいことだけを記載した丸投げの質問
- 問題・課題が含まれていない質問
- 意図的に内容が抹消された質問
- 広告と受け取られるような投稿
評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。
質問の評価を下げたことを取り消します
この機能は開放されていません
評価を下げる条件を満たしてません
質問の評価を下げる機能の利用条件
この機能を利用するためには、以下の事項を行う必要があります。
- 質問回答など一定の行動
-
メールアドレスの認証
メールアドレスの認証
-
質問評価に関するヘルプページの閲覧
質問評価に関するヘルプページの閲覧
+6
しっかり自分で考えて悩んでいるみたいだから、面識も無い相手にわざわざ時間を掛けて回答文を作ったにもかかわらず、俺が知っていることが何でお前が知らんのやみたいなエスパーな返答が送られたり、そんなの相手に無駄に労力割かされたり散々な目に会ったのに、設計のまずさを棚にあげつつ自分が思った結果が来なかったからブチ切れる結末で、本当に不毛な質問に出会ってしまったと実感してます。
もっと人生経験つまないかんですよ。対価も出さずに質問して気に入らなかったら暴言吐きまくりって何様よ?
プログラマー2年目っていうけど実世界でもこんなことしてたらレビューアから無視されちゃうよ。
自分のハテブだけで使うから俺仕様でOKなんだろうけど、そこはそちらが言わないとわかんないでしょ。
数学の[証明]のよう自分が求めたいものを自分一人で答え出せた時は気持ち良いだろうよ。答えが出ない時は自分にムカムカするでしょ?今回自分で答え出せないものを質問しといて、答えが得られなかったのを他人のせいにするのはおかしいですよね?
[証明]俺がこの問題を証明できないのは、この問題が悪い
ベストアンサーを’授ける’つもりで質問してたの?それなら対価アリできちんと仕事を依頼したほうがいいですよ。
…1文がなげーよ。
投稿
score 840
-
回答の評価を上げる
以下のような回答は評価を上げましょう
- 正しい回答
- わかりやすい回答
- ためになる回答
評価が高い回答ほどページの上位に表示されます。
-
回答の評価を下げる
下記のような回答は推奨されていません。
- 間違っている回答
- 質問の回答になっていない投稿
- スパムや攻撃的な表現を用いた投稿
評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。
+4
批判の意図はないのですが、質問者は望まない回答になると思います。ただ、teratailはQAプラットフォームであり、将来訪問されるかたに、ここにref/labelについて有益な質問・回答がないことを告知するために回答を残します。
回答:
仕様を見直されるべきかと思います。
理由:
以下、texのlabel/refっぽいものがつくりたい、が前提であり目的であると仮定しています。
理想の不整合
ここから(3-1)
と出力されることです。
はおかしいと思います。これがrefであるならlabel側の数値を持ってこないといけない。labelのfukasa2は「やりたいこと」の要件に照らしても"2-2-3"だと考えられる。そこのliにあるものを使うとしても"2-3"。"3-1"にはならない。と思う
idの設計
タグを書く時点でユーザが、深さや番号を指定するというのはおかしい。番号は機械が付与すべき。texのrefやlabelでもそのようなことはしないはず。参照番号の記入は、refは何らかの方法で対応付けられたlabelが所属する文脈に付与される数値を取ってくる、という仕様だと考えられます。
idを人間が指定するのは端的に手間であるのみならず、万一間違った番号が書かれていた場合ulとliの階層から取れる番号を付与するのか、間違っていても書かれた値を採用するのかの迷いを生むだけで、有害無益です。
(texを使っておられるくらいなので、一旦書いたあとにパラグラフを移動させたいことがあることは想像ができると思います。そのときにidを直すのでしょうか?)
liのinner
ここに数値をかくのはおかしいです。前段と同じですが、番号を手で入れるのはおかしい。説明としての仮の値を入れているのだとしたら、もっと誤解をまねかない文字列にしたほうがよいです。
処理の流れ
- ノードに番号を付与する(labelの値が決まる)
- 参照先に番号を付与する(refの数値を埋める)
という異なる2つの動作をする必要があると思います。
labelのidには[1-1]や"2番目の深さの1"などではなく、refで使う名前だけを入れるだけで十分だと思います。
投稿
score 2459
-
回答の評価を上げる
以下のような回答は評価を上げましょう
- 正しい回答
- わかりやすい回答
- ためになる回答
評価が高い回答ほどページの上位に表示されます。
-
回答の評価を下げる
下記のような回答は推奨されていません。
- 間違っている回答
- 質問の回答になっていない投稿
- スパムや攻撃的な表現を用いた投稿
評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。
+1
https://lesguillemets.github.io/blog/2014/09/18/katex0.html
javascript でtexの実装があります、これを使ってみては?
投稿
score 840
-
回答の評価を上げる
以下のような回答は評価を上げましょう
- 正しい回答
- わかりやすい回答
- ためになる回答
評価が高い回答ほどページの上位に表示されます。
-
回答の評価を下げる
下記のような回答は推奨されていません。
- 間違っている回答
- 質問の回答になっていない投稿
- スパムや攻撃的な表現を用いた投稿
評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。
+1
・質問
checkLabelNodeが無限ループになってブラウザがフリーズするが、素人なので問題の特定ができずスタックしている
・回答
jQueryの基本なんですが、メソッドチェーンをする都合上、多くのメソッドがjQueryオブジェクトを返します。!= undefined
をしても、jQueryオブジェクトはundefinedではないから再帰が止まりません。
if(node.children().length > 0){
checkLabelNode(node.children().first(), newDepth, newNum);
}
if(node.next().length > 0) {
checkLabelNode(node.next(), newDepth, newNum);
}
return;
}
こうやれば、to be removedのところに(3-3)と表示されます。一旦は3-1と出したいとおっしゃってましたが、番号に何をふるのかは俺の勝手だ、という設計のようなのでこれで。
投稿
score 2459
-
回答の評価を上げる
以下のような回答は評価を上げましょう
- 正しい回答
- わかりやすい回答
- ためになる回答
評価が高い回答ほどページの上位に表示されます。
-
回答の評価を下げる
下記のような回答は推奨されていません。
- 間違っている回答
- 質問の回答になっていない投稿
- スパムや攻撃的な表現を用いた投稿
評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。
0
後学のために逆に質問します。
MathJaxを使わなくなった理由って何でしょうか?
レスポンス?融通が効かない?
投稿
score 840
-
回答の評価を上げる
以下のような回答は評価を上げましょう
- 正しい回答
- わかりやすい回答
- ためになる回答
評価が高い回答ほどページの上位に表示されます。
-
回答の評価を下げる
下記のような回答は推奨されていません。
- 間違っている回答
- 質問の回答になっていない投稿
- スパムや攻撃的な表現を用いた投稿
評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。
check解決した方法
-13
結局自己解決できました。
一応、参考までに私が作ったテストコードを載せておきます。
<script type="text/javascript">
var hash_map_label = {};
function checkLabelNode(node, depth, num){
var newDepth = depth;
var newNum = num;
if(node.is('ul')){
newDepth = newDepth+1;
newNum = 0;
} else if(node.is('span.label')){
newNum++;
var str = "(" + newDepth + "-" + newNum + ")";
hash_map_label[node.attr("id")] = str;
node.text(str);
}
if(node.children()[0]){
newNum = checkLabelNode(node.children().first(), newDepth, newNum);
}
if(node.next().length){
checkLabelNode(node.next(), newDepth, newNum);
}
return newNum;
}
$(function(){
checkLabelNode($('.functest').first(), 0, 0);
$('span.ref').each(function(index){
$(this).text(hash_map_label[$(this).text()]);
});
});
</script>
<div class="functest">
<ul>
<li>1</li>
<li>2<span class="label" id="sample" />
<ul>
<li>1-1<span class="label" id="1-1" /></li>
<li>1-2<span class="label" id="1-2" />
<ul>
<li>2-1</li>
<li>2-2</li>
<li>2-3<span class="label" id="fukasa2" /></li>
</ul>
</li>
<li>1-3<span class="label" id="1-3" /></li>
<li>1-4
<ul>
<li>2-1<span class="label" id="2番目の深さ1" /></li>
<li>2-2</li>
<li>2-3<span class="label" id="2番目の深さ2" /></li>
</ul>
</li>
</ul>
</li>
<li>2の所を引用:<span class="ref">sample</span></li>
<li>2の1-1の所を引用:<span class="ref">1-1</span></li>
<li>2の1-2の所を引用:<span class="ref">1-2</span></li>
<li>2の1-3の所を引用:<span class="ref">1-3</span></li>
<li>2の1-2の2-3の所を引用:<span class="ref">fukasa2</span></li>
<li>2の1-4の2-1の所を引用:<span class="ref">2番目の深さ1</span></li>
<li>2の1-4の2-3の所を引用:<span class="ref">2番目の深さ2</span></li>
</ul>
</div>
このサイトなら良い指針やアドバイスが得られると思って、わざわざ時間を掛けて質問文を作ったにもかかわらず、アスペみたいな見当違いの的外れの回答が送られたり、そんなのの相手に無駄に労力割かされたり散々な目に会ったのに、結局は自力で解決するという結末で、本当に不毛なことをさせられたと実感してます。
teratailはもっと経験豊かな人が居るんじゃないんですか?どうなってんの?178viewもありながら(確認時点で)…
当然、ベストレビュアーは無しとします。
投稿
score -32
-
回答の評価を上げる
以下のような回答は評価を上げましょう
- 正しい回答
- わかりやすい回答
- ためになる回答
評価が高い回答ほどページの上位に表示されます。
-
回答の評価を下げる
下記のような回答は推奨されていません。
- 間違っている回答
- 質問の回答になっていない投稿
- スパムや攻撃的な表現を用いた投稿
評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。
15分調べてもわからないことは、teratailで質問しよう!
- ただいまの回答率 90.59%
- 質問をまとめることで、思考を整理して素早く解決
- テンプレート機能で、簡単に質問をまとめられる
質問への追記・修正、ベストアンサー選択の依頼
papinianus
2018/10/03 01:34
機能しないということですが、理想系とできれば現状をかいていただけませんか?(現状は実行したらわかりますが…)
2018/10/06 12:15
複数のユーザーから「やってほしいことだけを記載した丸投げの質問」という意見がありました
「質問を編集する」ボタンから編集を行い、調査したこと・試したことを記入していただくと、回答が得られやすくなります。