Latechの計算? はい、簡単に!

サービスよりも複雑なテキストを作成しなければならない人は、latehが技術に対する便利なアドオンであることを知っています。現時点では、複雑な品質のテキストをすばやく作成する方法はほとんど唯一です。 しかし、単一のテキストではありません... Latehは、Techの作成者であるDonald Knuthがおそらく考えなかった他の目的に使用できます。

プレゼンテーションラテックスの作成方法はすでに書いています。 次に、ラテックスの力によって単純な計算を直接実行する方法について説明します。



多くのさまざまなパッケージがさまざまな人々によってラテックス用に作成されており、その機能を拡張し、レイアウト設計者の作業を促進しています。 数値データを操作するのに役立つツールは忘れられていません。 浮動小数点数(単精度)を使用した単純な計算は、技術者が直接実行できます。 これがfpパッケージの目的です。 私はすぐに注意してください、外部コマンドを実行するlatechの能力により、コンパイル段階でより複雑なアクションを実行することさえできます(たとえば、Octaveで何かを計算し、MathGLでグラフを構築し、それらをテキストに挿入します)が、おそらくこれについて話している別の時間を教えましょう。

fpパッケージのマニュアルをコピーアンドペーストするつもりはありません(特に小さいので)が、あらゆる種類の技術的なタスク、レポートなどの準備で、このパッケージを単純な計算に使用する方法を教えたいと思います。 また、「スプレッドシート」の基本機能を実装するためにそれを使用する方法も示します。

最初に、さまざまな情報(つまり、後で変更できるいくつかのパラメーター)を挿入できるコマンドを作成し、これらの挿入を赤い上付き文字とマージンノートで赤い印刷モードでマークします。 ドキュメントの色は、 colorxパッケージによって提供されます。

このチームは次の3つの方法で作業します。 コード自体は次のとおりです。



\newcounter{InsC@unt@r} \def\Ind@x{\stepcounter{InsC@unt@r}% \hbox to 0pt{\raisebox{1ex}{\tiny\red{\arabic{InsC@unt@r}}}}} \def\Insm@rgimp@r#1{\marginpar{\red{\tiny\arabic{InsC@unt@r}:#1}}} \ifx\TextOut\undefined \def\InsTxt@#1#2{#1\Ind@x\Insm@rgimp@r{#2}} \else \def\InsTxt@#1#2{#1} \fi \def\Ins{\futurelet\next\Ins@i} \def\Ins@i{\ifx\next\bgroup\expandafter\Ins@ii\else\expandafter\Ins@end\fi} \def\Ins@ii#1{\def\temp@rg{#1}\futurelet\next\Ins@iii} \def\Ins@iii{\ifx\next\bgroup\expandafter\Ins@two@rgs% \else\expandafter\Ins@one@rg\fi} \def\Ins@two@rgs#1{\InsWFP{\temp@rg}{#1}} %   \def\InsWFP#1#2{\expandafter\FPset\csname #1\endcsname{#2}\InsTxt@{#2}{#1}} \def\Ins@one@rg{\InsTxt@{\temp@rg}{}} %   \def\Ins@end{\red{\Square\Ind@x}\Insm@rgimp@r{?}\xspace} %  
      
      







説明します。 まず、挿入インデックスの番号付けに使用する新しいカウンターを発表します。 次に、メイン\Ins



コマンドに対してさまざまな補助コマンドが定義されます。これにより、テキストにデータを挿入します。

ドラフトモードで挿入をマークするには、コマンド\Ind@x



および\Insm@rgimp@r



が必要です。 最初のコマンドは、挿入カウンターをインクリメントし、スペースを占有しないボックスを作成し、挿入番号を含む赤い上付き文字を配置します。 2番目のコマンドは、フィールドにマークを付けます。 ドラフトモード自体は、 \TextOut



によって規制されます。このコードの前に定義する場合( \def\TextOut{}



)、 \def\InsTxt



(「ホワイト」レイアウトモード)にマークは付けられません。

次に、可変数の引数を取る\Ins



コマンドを定義します。 それはただ一つのことをします:次のトークン( \futurelet



)を\next



マクロに読み込み、ドロップバックして\Ins@i



コマンドを実行します。 次に、 \Ins



続くトークンの種類を確認します。開始中括弧( \bgroup



)の場合、 \Ins@ii



コマンドが実行され、次のパラメーターの予備読み取りが行われます(そうでない場合、このコマンドは「 )が表示されます。 トークンが角かっこでない場合、 \Ins



コマンドには引数がなく、 \Ins@end



が呼び出され、テキストとマージンノートに空のボックスが配置されます。

\Ins@ii



コマンドは、 \Ins



コマンドの最初の引数を\temp@rg



マクロに入れ、次の引数( \Ins@iii



)を再度チェックします:ある場合、 \Ins@two@rgs



、変数が初期化\Ins@two@rgs



、その値が挿入されますテキスト内のタグ。 存在しない場合、 \Ins@one@rg



コマンドが実行されます。このコマンドは、テキストにデータを挿入し、マークを付けます。

計算結果の出力を容易にするために、fpパッケージから\FPprint



への書き込みと同様に\FPrint



を作成しますが、他のことを行います:引数は:



で、



は計算またはコマンドであり、



は小数点以下の桁数です結果を丸める必要があります。 丸められた数字が表示されます。 ここではすべてが非常に簡単に実装されているため、あまりコメントしません。



 \def\FPrint#1{\@@print@@#1} \def\@@print@@#1:#2{\FPeval{\res@lt}{round(#1:#2)}\res@lt}
      
      







テキスト全体に共通するデータ(たとえば、ドキュメントの複数のセクションで計算される値、および各セクションで一部が計算され、テキストの最後に金額を表示する必要がある)を保存するには、 \Ini



コマンドを定義します(初期化ユーザー変数には、1つの必須引数-変数の名前、および1つのオプション-変数を初期化する値)、 \Add



(2番目のパラメーターから式を最初のパラメーターから変数に追加)、 \Sub



(変数から数値を減算)、 \Show



( テキスト内の変数を表示し、小数点以下2桁またはオプションのパラメーターで指定された桁数に丸めます)。



 \newcommand{\Ini}[2][0]{\expandafter\gdef\csname cntr#2\endcsname{#1}} \def\Add#1#2{\expandafter\FPeval\csname cntr#1\endcsname{cntr#1+(#2)}} \def\Sub#1#2{\expandafter\FPeval\csname cntr#1\endcsname{cntr#1-(#2)}} \newcommand{\Show}[2][2]{\FPrint{cntr#2:#1}}
      
      







接頭辞cntrがユーザー定義の変数名に追加されるという事実により、ラテックスマクロを誤ってオーバーライドする可能性はほとんどなくなります。

次に、「スプレッドシート」に進みましょう。 開始するには、自動番号付けを開始します。



 \newcount\@row@num\@row@num=15 \def\@@nonum{} \def\@shownum{\ifx\@@nonum\empty\global\advance\@row@num1 \the\@row@num\else \gdef\@@nonum{}\fi} \def\NumIni{\global\@row@num=0\gdef\@@nonum{1}} \def\NoNum{\gdef\@@nonum{1}} \newcolumntype{N}[1]{>{\strut}#1<{\@shownum}}
      
      







カウンターの初期化は、テーブルの先頭に\NumIni



コマンドを配置して手動で行う必要があります(または、テーブル\everypage



\everypage



などを作成します)。 配列パッケージを使用して、目的の列の各セルに対して定義したコマンドを実行します。 同じパッケージを使用すると、新しいタイプの列を定義できます。自動番号を挿入するテーブルの列には、タイプNのマークを付ける必要があります セルに数字を挿入する必要がない場合は、 \NoNum



マクロでマークします。

次に、数値変数を使用した加算、減算、乗算、および除算を許可する列のタイプの定義に進みます。 これらすべてのコマンドのコードはほぼ同じであるため( \FPeval



実行される算術演算を除く)、最初に新しいコマンドの定義を容易にするマクロを定義します。

事前に警告します: テーブルセルの数字の終わりを明確に判断するには、文字ごとにスキャンする必要があります(テキストのコンパイル時間が大幅に増加します)。 各セルの終わりには、アンパサンド記号の前にスペースを挿入する必要があります。これは、セル内のデータの終わりを明確に象徴します。 このギャップを忘れると、「奇妙なエラー」が表示される場合があります。

次のマクロについては詳しく説明しません。表面的な説明に限定します。 コマンド\@@def@cmd



使用すると、2番目のパラメーターから算術演算を実行する新しいマクロ(最初のパラメーターで名前が指定される)を定義し、新しいタイプのテーブル列(3番目のパラメーター)を作成できます このコマンドは他のコマンドを初期化するために使用され、さらにパラメーターから名前で新しいコマンドを定義するため、 \expandafter



(次のトークン\xdef



1つのトークンの後に\xdef



れるまで次のトークンの展開を抑制する)などの構造が使用されます。 \xdef



(これは\global\edef



と同じです) \global\edef



あり、以前に本文からマクロを\global\edef



していた新しいマクロを定義します)、 \noexpand



(「最初の読み取り」でトークンを\noexpand



ことの禁止)、 \csname



(テキストをマクロ名に変換します)。



 \def\@@def@cmd#1#2#3{% \expandafter\xdef\csname #1\endcsname##1\ignorespaces{% \xdef\noexpand\@fst@rg{##1}\futurelet\noexpand\next\expandafter\noexpand\csname @@#1@\endcsname} \expandafter\xdef\csname @@#1@\endcsname{% \noexpand\ifx\noexpand\next\unskip\relax \noexpand\else\noexpand\expandafter\expandafter\noexpand\csname @testminus@#1\endcsname\noexpand\fi} \expandafter\xdef\csname @testminus@#1\endcsname{% \noexpand\ifx\noexpand\next-\noexpand\expandafter\expandafter\noexpand \csname @@m@#1\endcsname\noexpand\else \noexpand\expandafter\expandafter\noexpand \csname @@@#1\endcsname\noexpand\fi} \expandafter\xdef\csname @@@#1\endcsname##1 {% \noexpand\ifnum1=1##1{}\noexpand\else##1 \noexpand#2{##1}\noexpand\fi} \expandafter\xdef\csname @@m@#1\endcsname##1 {##1 \noexpand#2{##1}} \newcolumntype{#3}[2]{>{\csname #1\endcsname{##1}}##2} }
      
      







汚い作業を行ったので、基本的なコマンドを定義できます。



 \def\@SET#1{\expandafter\xdef\csname cntr\@fst@rg\endcsname{#1}} \def\@ADD#1{\FPeval{\res@lt}{cntr\@fst@rg+(#1)}\@SET{\res@lt}} \def\@SUB#1{\FPeval{\res@lt}{cntr\@fst@rg-(#1)}\@SET{\res@lt}} \def\@MUL#1{\FPeval{\res@lt}{cntr\@fst@rg*(#1)}\@SET{\res@lt}} \def\@DIV#1{\FPeval{\res@lt}{cntr\@fst@rg/(#1)}\@SET{\res@lt}} \@@def@cmd{TAdd}{\@ADD}{+} \@@def@cmd{TSub}{\@SUB}{-} \@@def@cmd{TMul}{\@MUL}{*} \@@def@cmd{TDiv}{\@DIV}{/} \@@def@cmd{TSet}{\@SET}{X}
      
      







これで、2つの引数(変数名と標準セル配置タイプ)を受け取る次の新しい列タイプができました。 型+-*および/は、セル型の最初の引数の変数とセルに含まれる数値の間で対応する操作を実行します。 タイプXは、変数をセルに含まれる値に設定します。 列Xで初期化せずに変数を使用する場合、テーブルの前に\Ini



コマンドで初期化する必要があります。 セルの内容がチェックされます。数字がない場合、アクションは実行されません。

ここで、計算の結果を表示できるようにする(および必要に応じて合計を計算する)別のタイプの列を宣言する必要があります。



 \def\@@plus#1#2{\gdef\@fst@rg{#1}\@ADD{cntr#2}} \def\@Sho@@#1{\ifx\@@nonum\empty\@@plus{#1}{\temp@rg}\else\gdef\@@nonum{}\fi} \def\@Sh@{\ifx\next\bgroup\expandafter\@Sho@@\else\gdef\@@nonum{}\fi} \def\Sho#1{\ifx\@@nonum\empty\Show{#1}\fi\def\temp@rg{#1}\futurelet\next\@Sh@} \newcolumntype{S}[3]{>{\strut}#3<{\Sho{#1}{#2}}}
      
      







新しい列タイプ-Sを作成します。これには、表示される変数の名前、アキュムレーター変数の名前、および配置タイプの3つのパラメーターがあります。 このコマンドは\NoNum



\NoNum



ます。 タイプSを実装する\Sho



コマンドは、単独で実行できます。 この場合、変数に結果を蓄積する必要がない場合、このコマンドに引数を1つだけ指定します。

そして最後に、ちょっとしたエンターテイメント。 ifthenパッケージを接続して、複雑な条件付き命令(ネストされたifが許可されていない場合)を実装し、ループとスタックの実装を行います。

最も単純なforループ(ネストされたものなし)は、次のように定義できます。



 \newcounter{f@rc@unter} \newcommand{\forplus}[4][1]{% \setcounter{f@rc@unter}{#2}\ifthenelse{\value{f@rc@unter} < #3}{#4% \addtocounter{f@rc@unter}{#1}% \forplus[#1]{\value{f@rc@unter}}{#3}{#4}}{}} \newcommand{\forminus}[4][-1]{% \setcounter{f@rc@unter}{#2}\ifthenelse{\value{f@rc@unter} > #3}{#4% \addtocounter{f@rc@unter}{#1}% \forminus[#1]{\value{f@rc@unter}}{#3}{#4}}{}} \def\iterator{\arabic{f@rc@unter}} \def\Loop#1#2{\forplus{0}{#1}{#2}}
      
      







ここには4つのコマンドが実装されています。 \forplus



使用すると、3番目のパラメーターの内容を実行するたびに、最初のパラメーターで指定された数値から2番目のパラメーターの数値まで増分してループできます。 オプションのマクロ引数はループステップです。 \forminus



は、デクリメントループを実装します。 \iterator



使用すると、ループイテレータの内容を表示できます。 \iterator



ループ-2番目の引数の内容をN回実行します(Nは最初の引数です)。

スタックを操作するには、コマンド\push



および\pop



、および\pop



\stacklen



(スタック内の要素の数)、 \popall



(スタックのコンテンツ全体を出力)、 \popalldel



(区切り文字付きのコンテンツを出力)を\popalldel



ます。



 \newcount\@buflen\@buflen=0 \newtoks\@@stack \@@stack={\empty} \def\push#1{\advance\@buflen1\begingroup\toks0={{#1}}% \edef\act{\endgroup\global\@@stack={\the\toks0 \the\@@stack}}\act} \def\pop{\ifnum\@buflen>0\advance\@buflen-1\fi\begingroup% \edef\act{\endgroup\noexpand\splitList\the\@@stack(tail)\@@stack}\act} \def\splitList#1#2(tail)#3{\ifx#1\empty\red{ !}\else{#1}\global#3={#2}\fi} \def\stacklen{\the\@buflen\xspace} \def\popalldel#1{\ifthenelse{\the\@buflen > 1}{\pop#1\popalldel{#1}}% {\ifnum\@buflen=1\pop\fi}} \def\popall{\popalldel{}}
      
      







スタックは、単純なトークンリストを通じて実装されます。 スタックに置くと、新しいトークンがリストの先頭に追加され、スタックから選択すると、リストが最初のトークンで分割されて返されます。





テーブルの使用例:



 \Ini[1]{yy} \Ini{zz} \begin{table}[!th] \begin{tabular}{|N{c}|X{xx}{c}|*{xx}{c}|S{xx}{zz}{c}|*{yy}{c}|} \hline \bf \NumIni \No{} / & A & B & A$\cdot$B\NoNum& C \\ \hline & -3.5 & 4.4 &&43.3 \\ & 31.31 &200.21 &&3 \\ & 1.23 &3.33 &&1.2 \\ \hline \NoNum&&&\NoNum $\sum(A\cdot B)=\,$\Show{zz}&$\prod C=\,$\Show{yy} \\ \hline \end{tabular} \end{table}
      
      











初期化された変数と計算の使用例:



 \Ini{totalmass}    {\tt totalmass}      -,          .          . ,    -,  \Ins{m1p}{45.1},\FPeval{m1}{3*m1p}      : $m_1=3\cdot\FPrint{m1p:1}=\FPrint{m1:1}$.     .\Add{totalmass}{m1} : {\tt totalmass}$\,=\Show[1]{totalmass}$. ,      , , , \Ins{moreaddtoa}{3.45},     ,     . : {\tt totalmass}$\,\Add{totalmass}{moreaddtoa}=\Show[2]{totalmass}$.      -.   -  $\rho=\,$\Ins{therho}{5.43},    $V=\,$\Ins{theV}{12.44},    \FPeval{mi}{therho*theV}$m_i=\rho\cdot V=\FPrint{mi:3}$.      .\Add{totalmass}{mi}   : {\tt totalmass}$\,=\Show[3]{totalmass}$.  \verb'\Ini', \verb'\Show'  \verb'\FPrint'    .  \verb'\Ins'     {\tt fp}    :  -   ,  "--- - ,       \verb'\global'  ,   ,     .
      
      











ループとスタックの使用例:



     a=\Ins{a}{2.5}, b=\Ins{b}{3},     $c=\sqrt{a^2+b^2}=\FPrint{root(2, (a^2 + b^2)):2}$   1  4: \forplus{1}{5}{\iterator~}   1  10   3: \forplus[3]{1}{11}{\iterator~}   4  1: \forminus{4}{0}{\iterator~}   10  1   -3: \forminus[-3]{10}{0}{\iterator~} \Loop5{ ! } \push{}\push{}\push{}\push{}    : \popalldel{, }. : \stacklen .
      
      











サンプルテキスト

結果のpdf



All Articles