文字の下に線を引っ張って説明

文字の下に線を引っ張って説明

- あ い の投稿
返信数: 22
写真のような出力を得たいです。

【特徴】
・最初の説明の方が後よりも下にくる
・説明が元の語句より長くても元の文の空白などが変わらない。

個人的にはtcboxをずらして左側の枠線を利用し,説明文の直前に置いた水平線とつなげようと思い立ちました。
高さ問題についてはcounterを使おうと思ったのですが,番号をリセットする場所に困ったのでtcboxの中にtcboxを入れるという構図にしようと思いました。
ところが試しに作ってみようと思ったところ問題が発生しました。

【問題点】
・単位にemを持ちているのに文字の大きさが変わった時に若干の誤差が発生する。
・自前の環境からstyファイルなしに変えたところ枠線を左だけにするという設定などにエラーが発生した。
・tcboxだと説明が長い場合に元の文に空白が開いてしまう。

どなたか解決策をごお教示いただければ幸いです。

【コード】(lualatex)

% documentclass=========================================================

\documentclass{ltjsarticle}% compiler: lualatex-------------------------

%=======================================================================


% preamble==============================================================

% 書式------------------------------------------------------------------

\usepackage{luatexja}% lualatexの日本語設定

\usepackage{tcolorbox,ulem,calc,ifthen,color,graphics}%

\newlength{\blocklength}%

\newtcbox{subblock}

{%

%enhanced,%

on line,%

%boxrule=0.5pt,%

sharp corners,%

left=0em,right=0em,top=0em,bottom=0em,%

colback=white,%

%tcbox raise=-4.5em,%

%borderline west={0.1pt}{-0.1pt}{black},%

%frame style={left color=black,right color=white,top color=white,bottom color=white}%

}%

\newcommand{\block}[2]%

{%

\settowidth{\blocklength}{\uline{#1}}%

\uline{#1}\hspace{-\blocklength+0.5em}

\raisebox{-1.7em}[1em][0em]%

{%

\subblock%

{%

\raisebox{-0.5em}[1em][0em]%

{%

\hspace{-0.5em}\sout{\quad}#2%

}%

}%

}%

}%


% document================================================================

\begin{document}%


\normalsize%

There is something \block{to}{目的} talk about.\vspace{1cm}%

 

\Large%

There is something \block{to}{目的} talk about.\vspace{1cm}%

 

\LARGE%

There is something \block{to}{目的} talk about.\vspace{1cm}%


\end{document}%

添付 block.jpg
あ い への返信

Re: 文字の下に線を引っ張って説明

- 和田 勇 の投稿
  • そのままではコンパイルできないので修正しました

    • 「\newtcbox{subblock}」は「\newtcbox{\subblock}」
    • 問題にはなっていないのですが「\hspace{-\blocklength+0.5em}」は場合によっては「+0.5em」が表示されてしまうので二つに分けて検証しました
  • 質問1 単位にemを持ちいているのに文字の大きさが変わった時に若干の誤差が発生する。

    • 質問の意図がよく掴めないので、 PDF イメージにお絵描きエディタで「誤差」と言われているとことに印をつけて示してください
  • 質問2 自前の環境からstyファイルなしに変えたところ枠線を左だけにするという設定などにエラーが発生した。

    • エラーが起きた時のソースとログファイルを添付してください。
  • 質問3 tcboxだと説明が長い場合に元の文に空白が開いてしまう。

    • 逆に短いと元の文が重なってしまっています。これらの現象は \raisebox が終了した時は、縦方向の位置は元に戻りますが、横方向は最後に対応セットしたところからになるからです。

      発想を変えて「説明文」を所定位置で組版した後、組版位置を元に戻して「元の文」を組版するようにしてみました。

    • 元の文や説明文どちらかで改行や解ページが発生するケースがあればそれらを考慮しなければなりません。
    • オリジナルのマクロに近い形で、暫定で対処したソースなどを添付します。
    • ただし、縦方向に移動して説明文を対応セットしたことを考慮していないので、次行、次段落などと文字が重なるケースが発生してしまいますが未対応です。
  • その他

    • 説明文が小さな文字でよければ英文用の下ルビを使う方法があります
    • tcolorbox を使っているのなら 同マニュアルの p103-104 にある footnote を使う方法も別解としてはあるかしら?
あ い への返信

Re: 文字の下に線を引っ張って説明

- 伊藤 直人 の投稿

回答とも叩き台とも呼べないものですが添付のようなものを考えてみました。

特に質問者であるあいさんやTeXフォーラムにご参加の皆様に役立つものではないと思いますが何か少しでもお役に立てればと思い,投稿させていただきます。

私が考えたこと

  • はじめに縦棒の初期長さを決めておいて,そこから長さを短くすることで「最初の説明の方が後よりも下にくる」を実現する。
  • カウンターでコマンドを使った回数を数えておいて,縦棒が一定の長さまで短くなったら長さをもとに戻す。

課題(不具合)

  • 単語間のスペースが空きすぎる。
  • 現状では,一文に対して4つまでの注釈がベスト←これを解消するためには一文ごとの注釈の個数に対して,縦棒の初期長さを決めるようにしたらいいと思うがその方法が分からない。
  • 英文であれば注釈の個数に限らず一文ごとに縦棒長さは,リセットするようにしたい。(英語の教科書のような例文に注釈をつけるイメージ)
  • 注釈をするのが一文に対して一つの場合,スペースの無駄が大きい。
伊藤 直人 への返信

Re: 文字の下に線を引っ張って説明

- 和田 勇 の投稿
  • 訳あって、ちょっと前の投稿はキャンセルして、再投稿です

  • 伊藤さんの案をかなりパクって組み込んでみました。

    • 座標指定のほか ++ を使って「right:距離」「down:距離」などを使い修正しやすいようにしました
    • 縦方向の距離は \baselineskip を使ってみました(もう少し詰めても良いかもしれない)
  • 単語間のスペース問題は以下のように対応しました

    • \savebox を使って 「元の文」と「元の文と説明文」の箱を作成
    • 「元の文と説明文」の箱を \usebox で組版
    • 「元の文と説明文」の箱の幅分、一旦左に \hspace で戻す
    • 「元の文」の幅だけ \hspace で右に移動
  • 「元の文と説明文」の組み合わせはいくつあっても構いません

  • また行跨りがあっても、前の行の説明文にも重ならないようになりました
  • 縦棒は第三パラメータで調整してください
和田 勇 への返信

Re: 文字の下に線を引っ張って説明

- 伊藤 直人 の投稿
和田様

改良していただきありがとうございます。

投稿されたソースを拝見しました。

\saveboxというのは知らなかったので大変勉強になりました。
伊藤 直人 への返信

Re: 文字の下に線を引っ張って説明

- 帯田 木偶太 の投稿
若干の変更(改善になっているか改悪かは微妙なところ)を加えてみました。

注釈対象、注釈内容ともに、そこそこ単純で、なおかつ充分に短いことを
前提にしています。


\documentclass{ltjsarticle}
\usepackage{tikz}
\makeatletter
\newcounter{kosuu}
\newlength{\tatenagasa}
\newcommand{\annotation}[2]{%
\leavevmode
\rlap{%
\tikz[baseline=(text.base)]{
\node [inner sep=1pt,outer sep=0pt] (text) {\phantom{\strut \kern -1.5\p@ #1\kern -1.5\p@}};
\draw (text.south west) -- (text.south east);
\draw (text.south) -- (0,-\tatenagasa);
\draw (0,-\tatenagasa) -- (0.3,-\tatenagasa) node [inner sep=0pt, outer sep=0pt, right]{#2};
%\fill[green, opacity=0.2](current bounding box.south west) rectangle (current bounding box.south east);
}% 
}%
#1%
\advance\tatenagasa by-\baselineskip
}%
\def\AnnotatedText#1{%
\setcounter{kosuu}{0}%
\setbox\@tempboxa=\hbox{%
\def\annotation##1##2{%
\addtocounter{kosuu}{1}%
}%
#1%
}%
\setbox\@tempboxa=\null
\tatenagasa=.5\baselineskip
\advance\tatenagasa by\c@kosuu\baselineskip
#1\par
}

\begin{document}

\AnnotatedText{%
\annotation{ab}{ABCDE} \annotation{abcdefgh}{ABCDE}
\annotation{abcde}{ABCDE} \annotation{abcde}{ABCDE}
}
\AnnotatedText{%
\annotation{abcde}{ABCDE}\annotation{ab}{ABCDE}
\annotation{abcdefgh}{ABCDE} \annotation{abcde}{ABCDE}
}
\AnnotatedText{%
\annotation{abcde}{ABCDE} \annotation{abcde}{ABCDE}
}

\LARGE
\AnnotatedText{%
\annotation{ab}{ABCDE} \annotation{abcdefgh}{ABCDE}
\annotation{abcde}{ABCDE} \annotation{abcde}{ABCDE}
}
\AnnotatedText{%
\annotation{abcde}{ABCDE}\annotation{ab}{ABCDE}
\annotation{abcdefgh}{ABCDE} \annotation{abcde}{ABCDE}
}
\AnnotatedText{%
\annotation{abcde}{ABCDE} \annotation{abcde}{ABCDE}
}

\footnotesize
\AnnotatedText{%
\annotation{ab}{ABCDE} \annotation{abcdefgh}{ABCDE}
\annotation{abcde}{ABCDE} \annotation{abcde}{ABCDE}
}
\AnnotatedText{%
\annotation{abcde}{ABCDE}\annotation{ab}{ABCDE}
\annotation{abcdefgh}{ABCDE} \annotation{abcde}{ABCDE}
}
\AnnotatedText{%
\annotation{abcde}{ABCDE} \annotation{abcde}{ABCDE}
}

\end{document}
帯田 木偶太 への返信

Re: 文字の下に線を引っ張って説明

- 和田 勇 の投稿
  • 質問者さんが最初に添付されていた画像イメージのデータを投入したところ、「元の文1」と「元の文2」のような場合、空白が削除されてしまうので対処してみました。

  • また、添付された画像イメージだと関係線は「元の文」の左下からやや右のところから始まっているので、その補正もしました。

  • 関係線を座標でなく相対的に行ったので \tatenagasa から .5\baselineskip を調整しています。

  • さらに関係線の終端と「説明文」が接触していたので空白を開けてみました。

  • 行跨りが起きても大丈夫なのですが、\rlap を使っているので、1行目のところに空白が目立ってしまいます。まぁ、これは適宜ブロック分けするなどの運用で良いかと思います。

  • 差分情報

    @@ -9,12 +9,13 @@
         \tikz[baseline=(text.base)]{
           \node [inner sep=1pt,outer sep=0pt] (text) {\phantom{\strut \kern -1.5\p@ #1\kern -1.5\p@}};
           \draw (text.south west) -- (text.south east);
    -      \draw (text.south) -- (0,-\tatenagasa);
    -      \draw (0,-\tatenagasa) -- (0.3,-\tatenagasa) node [inner sep=0pt, outer sep=0pt, right]{#2};
    +      \draw (text.south west) -- ++(right:1mm) -- ++
    +      (down:\tatenagasa-.5\baselineskip) % 関係線の起点を「元の文」の左端から 1mm 離れた所から
    +      -- ++(right:3mm) node [inner sep=0pt, outer sep=0pt, right]{\,#2}; % 関係線の終端と「説明文」の間に空白
           % \fill[green, opacity=0.2](current bounding box.south west) rectangle (current bounding box.south east);
         }%
       }%
    -  #1%
    +  #1 % 「元の文」の直後に空白か \, を入れておいた方が良い
       \advance\tatenagasa by-\baselineskip
     }%
     \def\AnnotatedText#1{%
    @@ -34,6 +35,13 @@
     \begin{document}
    
     \AnnotatedText{%
    +  \annotation{There is}{there is 構文}
    +  \annotation{something}{何か}
    +  \annotation{to}{目的}
    +  talk about.
    +}
    +
    +\AnnotatedText{%
       \annotation{ab}{ABCDE} \annotation{abcdefgh}{ABCDE}
       \annotation{abcde}{ABCDE} \annotation{abcde}{ABCDE}
     }
    
あ い への返信

Re: 文字の下に線を引っ張って説明

- あ い の投稿
伊藤 直人さま,和田勇さま,帯田木偶太さま,回答ありがとうございます!
自分が学校に行っている間に議論が進み最終的に望んでいたものが完全に再現されており,感激しております。
tikzを使うという方法も頭をよぎったのですが,自分では到底こんなマクロは組むことができませんでした。
応用して上バージョンの関係線や似たものを作ってみようと思います。
回答していただき本当にありがとうございました!
あ い への返信

Re: 文字の下に線を引っ張って説明

- しっぽ 愛好家 の投稿

(TikZ あるいは tcolorbox を使う必要があるというのでなければ) 添付のサンプルファイルのようなことも可能です(本質的なことではないので,サンプルテキストの中身は気にしないでください).

しっぽ 愛好家 への返信

Re: 文字の下に線を引っ張って説明

- あ い の投稿
しっぽ 愛好家さま,返信ありがとうございます。

ご提示いただいたzipファイルをまっさらなcloud latexでコンパイルしてみたのですが,文字化けでエラーが出てしまったので一応その箇所を削除してみました。

noteに引数を取るかどうかによって自動/手動高さ調節を切り替えられるのがすごいですね!

恐縮ですが,一応本来のtex fileも拝見したいので,直接書き込んでいただくことは可能でしょうか。。。?

よろしくお願いします。
あ い への返信

Re: 文字の下に線を引っ張って説明

- あ い の投稿
また,lualatex非対応のようでしたので,zwを\zwにしたり色々調べてみたのですが,uplatex(platex)にできてlualatexにできないことがよくわからず,またコードも難解なので,どうすれば良いかわかりません。

lualatexへの対応が面倒・不可能であれば無視していただいて結構です。
あ い への返信

Re: 文字の下に線を引っ張って説明

- しっぽ 愛好家 の投稿

(1) まず,「本来の TeX file」については,それをそのまま(圧縮せずに)添付しています (約 500 行のファイルをそのまま貼り付けるのは差し控えます). 「文字化け」に関しては,あのファイルは SJIS で書かれていますので,UTF-8 しか受け付けない処理系をお使いなのでしたら,あらかじめ文字コード変換を行ってください.

(2) LuaTeX 対応に関しては,(別のところでも書きましたが)「仕事では LuaTeX を一切使用しない」私には期待なさらないでください.もっとも,勘で適当なことを言えば,文字コードを UTF-8 にしたうえで単位 zw が使われている箇所をつぶせばよさそうな気もします(今回のサンプルでは pTeX 限定の機能は用いていませんので).

しっぽ 愛好家 への返信

Re: 文字の下に線を引っ張って説明

- 和田 勇 の投稿
  • sjis のファイルをタイプセットするには --kanji=sjis のオプションを利用してください

  • 恒久的に utf-8 にするなら ... 以下の方法を検討(添付のファイルは utf-8 化などの処置は行なっています)

  • notepad や vscode で別名ファイル書き込みをするときなどに utf-8 を指定してください

  • perl がインストールされていれば https://tyablog.net/2017/08/25/perl-oneliner/ を参考に

    perl -MEncode -i -pe 'Encode::from_to($_,"shiftjis","utf-8");' 20220704.tex 
    
  • nkf がインストールされていればこのフォラームで nkf scoop で検索していただいたものなどを参考に

     nkf -w --overwrite 20220704.tex
    
  • lualatex 対応(未完)

    • documentclass はとりあえず ltjsarticle で検証
    • [1-9][0-9]*zw → [1-9][0-9]*\zw に変更
    • \pdfsavepos \pdflastxpos \pdflastypos から pdf を削除して名称変更

      https://zrbabbler.hatenablog.com/entry/20151013/1444700367 の対応表を参考

    • 未完の理由→明日やっつけれればなぁ

      • parabox のような感じで表現されると思われる説明文が mbox のような表現になってしまう箇所が一部あるため
和田 勇 への返信

Re: 文字の下に線を引っ張って説明

- 和田 勇 の投稿

検証未完了の件は documentclass による \textwidth の違いだと判明しました。

  • 問題としていたところは以下の箇所

     \note{$\pm \infty$になる}{数列$\{a_n\}$が上下どちらかに非有界な場合}
    
    • 元々の原稿は、jarticle でしたので上記注釈部分近傍で行溢れを起こし次行に組版されていましたが、 ltjsarticle に変更したため行溢れが発生しなくなり、注釈部分が行をはみ出してしまっていたためでした。

      端的にゆえば \textwidth の差によるものなので、原稿を作る時点で気がつくのできっと \parbox に書き変えていた箇所だと思います。

  • documentclass

    • ltj で始まる lualatex用 documentclass は、twocolumn を含む \textwidth の問題もありますが、縦書きも含め、適宜 \note を \parbox を使って記述すれば問題なく処理できると判断しました。
和田 勇 への返信

Re: 文字の下に線を引っ張って説明

- 本田 知亮 の投稿
しっぽ愛好家さんのコードの中のzwを\zwに置換して,
\documentclassのところを

\ifdefined\directlua
\documentclass{ltjarticle}
\let\pdfsavepos\savepos
\let\pdflastxpos\lastxpos
\let\pdflastypos\lastypos
\else
\documentclass{jarticle}
\newdimen\zw
\zw=1zw\relax
\fi

と変えれば,LuaTeXか(u)pLaTeXかは
勝手に判別すると思います(他のTeXは考えてないですけども,
処理的にzw/savepos/lastxpos/lastyposの手当てで問題ないと推測します).

\parboxの部分は・・・
「注釈の1行の最大の長さ」をあらかじめ設定しておいて,
当該の部分をボックスをvarwidthパッケージで処理すれば,
ちょっと楽できるかもしれません.
linegoalパッケージ(これもsaveposの応用)的な処理を追加して,
はみ出さないような幅の自動取得もできるかなと思うのですが,
いうだけにします.
本田 知亮 への返信

Re: 文字の下に線を引っ張って説明

- しっぽ 愛好家 の投稿

皆様,LuaTeX 関係の考察に感謝します.さて,

>linegoalパッケージ(これもsaveposの応用)的な処理を追加して,
>はみ出さないような幅の自動取得もできるかなと思うのですが,

については私も思い至ってはいましたが, 「\note を \parbox の類の中で用いた場合」にうまくいかないので導入しませんでした. また,注釈部分の行長を版面からはみ出さない寸法に機械的に設定した場合, 行の末端付近で長い注釈テキストをもった \note を用いると,「縦に長い」注釈ができかねません. そういった場合にはむしろ,\note の直前で手動で強制改行するといった判断をユーザに委ねるのもまた, TeX 的ではないかなと.

しっぽ 愛好家 への返信

Re: 文字の下に線を引っ張って説明

- あ い の投稿
和田勇さま,本田知亮さま,しっぽ 愛好家さま,返信ありがとうございます。

和田さまに提示していただいたtex fileは無事コンパイルできたのですが,話題に上がっている(?)textwidthの問題がなんのことかよくわからず(説明文が行を跨いでしまう時の不具合でしょうか?。。。),色々とnoteを使ってみたのですが,和田さまに最後に送っていただいたtex fileの最後に

\note{There is}{there is構文} \note{something}{~がある} \note{to}{目的用法} \note{important}{重要な} \note{to}{目的用法} \note{talk}{話す} \note{about}{前置詞} \note{.}{ピリオドを忘れずに}

\note{あ}{いううううゆううううううう} \note{あ}{いいいいいいいいいいいい} \note{あ}{いお} \note{あ}{いぉ} \note{あ}{いうう}

を加えると,写真のようになります。
後者は綺麗に階段状になっているのに対し前者は途中でそれが崩れてしまってい
ます。
これはそのtextwidthが関係したことなのでしょうか?
添付 スクリーンショット_2022-07-05_16.28.55.png
あ い への返信

Re: 文字の下に線を引っ張って説明

- しっぽ 愛好家 の投稿
# \textwidth 云々については関係ありません.
# あれは,\note での注釈は「自動改行ではない」ので
# 版面からはみ出す場合もある(そのような場合は手動で
# \note の注釈文に \parbox か何かを適用することを想定)
# というだけの話(と私は認識したもの)です.

次に,提示してある出力結果は,「定義通り」の出力です. \note では,個々の注釈の移動量を「衝突しない範囲で最低限」に設定します (注釈「~がある」が余分に下がっているのは \notesep の効果). もし,注釈「重要な」が注釈「目的用法」よりもさらに下がった位置に出力されるような (衝突の有無に関係なく,無条件に手前にある注釈ほど下に下げる)結果が ご所望でしたら,\@checknotedata@elt の定義をほんの少し変更(\ifdim\@thisx sp<\dimen@ と これに対応する \fi をコメントアウト)します.

しっぽ 愛好家 への返信

Re: 文字の下に線を引っ張って説明

- しっぽ 愛好家 の投稿

「衝突の有無に関係なく,無条件に手前にある注釈ほど下に下げる」出力を得る方法の別案: マクロ定義本体に手を入れなくても,\notesep の値を \textwidth くらいの極端な値にすれば (同一行にある注釈は互いに衝突しているかのような扱いになるので)手前にある注釈ほど下に下がります.

しっぽ 愛好家 への返信

Re: 文字の下に線を引っ張って説明

- あ い の投稿
しっぽ 愛好家さま,返信ありがとうございます。
関係線の高さを一律で設定するかいなかも設定でき,大変感謝しております。

parboxについては自動設定が難しいようなので,手動で設定したいと思います。

関わってくださった方々,本当にありがとうございました!
あ い への返信

Re: 文字の下に線を引っ張って説明

- あ い の投稿
少し前の投稿を掘り返してしまい申し訳ありません。

しっぽ愛好家さまからご提示いただいた原案を,(少し変えはしましたが,)cloud latexでlualatexとともに使うことができたのですが,macに入れているTeX Shopで同じドキュメントをコンパイルすると,結果が異なってしまうことに気がつきました。

具体的には,TeX Shopでは全ての階層の項目が\note[1]と同じ最初の階で表示されてしまうということです。
長い文を引数に取っても自動で階層が分かれずに,項目が重なってしまいます。

普通は同じ結果になるはずなのに,現にそうではないので,私の使っているmac環境に問題があるのでしょうか。

情報が少なすぎると思いますので,必要な情報があれば指示をお願いします。

よろしくお願いします。
あ い への返信

Re: 文字の下に線を引っ張って説明

- 和田 勇 の投稿
「sudo tlmgr update --self --all」したら解消しました。

その他のチェック方法としては cloud 側のログを mac にダウンロードし
比較検討することかな。

mac と clound は確か install directory などは同じだったと思いますので
以下のようなコマンドで比較できると思います。


diff -u 「cloudのログファイル名」 out/note.log

ですので、何度かお願いしたと思いますが、検証用のサンプル tex ファイルとログファイルの提示も、今後お願いします。
和田 勇 への返信

Re: 文字の下に線を引っ張って説明

- あ い の投稿
和田勇さま,返信ありがとうございます。

うっかりしていて,ローカルの方でlualatex用のemathを読み込んでいました。。。

emathの読み込みをnoteの後に記述することで解決しました。

大変申し訳ありませんでした。