\ href内で\ DTLfetchを使用する
呼び出されたコマンドのパラメーターとして指定された場所に関連付けられた座標を指すGoogleマップURLを作成する新しいコマンドをLaTeXで作成しようとしています(一種の「テーブルルックアップ」関数)。場所と相対座標はcoords.CSV
ファイル内に保存されており、datatool
パッケージを使用して読み取る必要があります。
GoogleマップのURLは次のように構成する必要があります。
https://www.google.com/maps/?q=<LAT>,<LNG>
ここで<LAT>
、および<LNG>
はcoords.CSV
ファイルからロードされた緯度と経度の座標であり、次のように構成されています。
Place,LAT,LNG
Test,42.0000,42.0000
...
コマンドの定義方法は次のとおりです。
\usepackage{datatool}
\newcommand{\coords}[1]{
% Loads the CSV
\DTLsetseparator{,}
\DTLloaddb{coords}{doc/coords.csv}
% Assigns the coordinates to the variables \LAT and \LNG, relative to specific place (the parameter #1)
\def \LAT {\DTLfetch{coords}{Place}{#1}{LAT}}
\def \LNG {\DTLfetch{coords}{Place}{#1}{LNG}}
% Generates the URL pointing to Google Maps
Place: \href{https://www.google.com/maps/?q=\LNG ,\LNG}{#1}
}
最後に、新しいコマンドを次のように使用します。
\coords{Test}
コマンド内で呼び出された場所(この場合は「テスト」)の座標を正しくロードできましたが、URLを生成しようとすると、LaTeXで多くのエラーが発生し、そのほとんどが! Undefined control sequence
です。URLが生成された行(コマンド定義内)を削除\LAT
し\LNG
てもエラーは発生しませんが、もちろん、URLには座標が含まれていないため、座標は\LAT
と\LNG
変数内に格納されます。
\href
コマンド内で定義された変数を使用してURLを適切に生成する方法はありますか?
これはテスト例です:
\documentclass[a4paper,10pt]{article}
\usepackage{hyperref}
\usepackage{datatool}
\newcommand{\coords}[1]{
% Loads the CSV
\DTLsetseparator{,}
\DTLloaddb{coords}{coords.csv}
% Assigns the coordinates to the variables \LAT and \LNG, relative to specific place (the parameter #1)
\def \LAT {\DTLfetch{coords}{Place}{#1}{LAT}}
\def \LNG {\DTLfetch{coords}{Place}{#1}{LNG}}
% Generates the URL pointing to Google Maps
Place: \href{https://www.google.com/maps/?q=\LAT ,\LNG}{#1}
}
\begin{document}
\coords{Test}
\end{document}
回答
`\ DTLfetch`の部分文字列を取得するための私の答えと同じトリックを使用できます
\begin{filecontents*}{\jobname.csv}
Place,LAT,LNG
Test,42.0000,42.0000
\end{filecontents*}
\documentclass{article}
\usepackage{datatool}
\usepackage{hyperref}
\DTLsetseparator{,}
\DTLloaddb{coords}{\jobname.csv}
\newcommand{\DTLfetchsave}[5]{% see https://tex.stackexchange.com/a/335489/4427
\edtlgetrowforvalue{#2}{\dtlcolumnindex{#2}{#3}}{#4}%
\dtlgetentryfromcurrentrow{\dtlcurrentvalue}{\dtlcolumnindex{#2}{#5}}%
\let#1\dtlcurrentvalue
}
\newcommand{\coords}[1]{%
\DTLfetchsave{\LAT}{coords}{Place}{#1}{LAT}%
\DTLfetchsave{\LNG}{coords}{Place}{#1}{LNG}%
% Generates the URL pointing to Google Maps
Place: \href{https://www.google.com/maps/?q=\LAT,\LNG}{#1}%
}
\begin{document}
\coords{Test}
\end{document}
私が使用\jobname
私のファイルをつかう避けるために。データベースには任意のファイル名を使用できます。
を呼び出すたびにではなく、データベースを1回ロードします\coords
。
次のアプローチをお勧めします。
\documentclass[a4paper,10pt]{article}
% Let's create the file coords.csv - the directory ./doc must exist
% and writing-permission for that directory must be given!!!
% An already existing file won't be overwritten by the
% filecontents*-environment (unless you provide the "overwrite"-option)
% and you will be informed about the fact that the file already
% exists via a message in the .log-file only. You won't get a
% message on the terminal/console.
\begin{filecontents*}{doc/coords.csv}
Place,LAT,LNG
Test,42.0000,42.0000
\end{filecontents*}
\usepackage{hyperref}
\usepackage{datatool}
\newcommand{\coords}[1]{%%%
\begingroup
% Load the CSV only if database "coords" doesn't already exist:
\DTLifdbexists{coords}{}{%%%
%\DTLsetseparator{,}% Comma is the default, so this probably is not needed.
\DTLloaddb{coords}{doc/coords.csv}%%%
}%%%
% Assign the coordinates of the place whose name is denoted by the
% parameter #1 to the macros \LAT and \LNG:
\edtlgetrowforvalue{coords}{\dtlcolumnindex{coords}{Place}}{#1}%%%
\dtlgetentryfromcurrentrow{\LAT}{\dtlcolumnindex{coords}{LAT}}%%%
\dtlgetentryfromcurrentrow{\LNG}{\dtlcolumnindex{coords}{LNG}}%%%
%%%
% Use the name (denoted by #1) of the place as a hyperlink leading
% to the corresponding URL of Google Maps:
Place: \href{https://www.google.com/maps/?q=\LAT,\LNG}{#1}%%%
\endgroup
}%%%
\begin{document}
\coords{Test}
\end{document}
コードにはいくつかの問題があるため、このアプローチをお勧めします。
問題1:
あなたの\coords
-commandは、不要なスペーストークンと生産\par
-tokensを:
これらの不要なトークンがどこで発生するかを示すコメントで書き直します。
\newcommand{\coords}[1]{ %<- unwanted space-token yields horizontal space in horizontal mode
% Loads the CSV
\DTLsetseparator{,} %<- unwanted space-token yields horizontal space in horizontal mode
\DTLloaddb{coords}{doc/coords.csv} %<- unwanted space-token yields horizontal space in horizontal mode
%<- unwanted control word token \par
% Assigns the coordinates to the variables \LAT and \LNG, relative to specific place (the parameter #1)
\def \LAT {\DTLfetch{coords}{Place}{#1}{LAT}} %<- unwanted space-token yields horizontal space in horizontal mode
\def \LNG {\DTLfetch{coords}{Place}{#1}{LNG}} %<- unwanted space-token yields horizontal space in horizontal mode
%<- unwanted control word token \par
% Generates the URL pointing to Google Maps
Place: \href{https://www.google.com/maps/?q=\LAT ,\LNG}{#1} %<- unwanted space-token yields horizontal space in horizontal mode
}
問題2:
hyperref-manualは、のURL引数のトークンは\href
完全に拡張可能でなければならないと述べています。
コマンド\LAT
と\LNG
は完全に拡張可能ではありません。これは、その定義に制御ワードトークンが含まれているの\DTLfetch
に対し、datatool-packageのマニュアルには次のように明記されているためです。
\DTLfetch{students}{regnum}{\RegNum}{forename}
に等しい
これは、マクロがによって定義される\dtlgetrowforvalue{students}{\dtlcolumnindex{students}{regnum}}{\RegNum}%
\dtlgetentryfromcurrentrow{\dtlcurrentvalue}{\dtlcolumnindex{students}{forename}}% \dtlcurrentvalue
\DTLfetch
ため、
(したがって、ある段階で展開するとトークンが生成されるすべてのマクロ
\DTLfetch
)が完全に展開できない
\dtlcurrentvalue
ことを示し
\dtlgetentryfromcurrentrow
ます。
問題3:
を呼び出すたびにデータベースをロードする必要があるとは思えません\coords
。
問題4:
\DTLsetseparator
これがデフォルトですが、データベースのエントリの区切り文字をコンマに設定するコマンドを使用します。したがって、これはおそらく廃止されています。