การใช้ \ DTLfetch ภายใน \ href
ฉันกำลังพยายามสร้างคำสั่งใหม่ใน LaTeX ที่สร้าง Google Map URL ที่ชี้ไปยังพิกัดที่เชื่อมโยงกับสถานที่ที่ระบุเป็นพารามิเตอร์ในคำสั่งที่เรียก (ฟังก์ชัน "การค้นหาตาราง" ประเภทหนึ่ง) สถานที่และพิกัดสัมพัทธ์จะถูกเก็บไว้ในcoords.CSVไฟล์และต้องอ่านโดยใช้datatoolแพ็คเกจ
URL ของ Google Map ควรมีโครงสร้างเช่นนี้:
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 ! Undefined control sequenceที่น้ำยางให้ฉันข้อผิดพลาดมากซึ่งส่วนใหญ่เป็น หากฉันลบ\LATและออก\LNGจากบรรทัดที่สร้าง URL (ภายในนิยามคำสั่ง) ฉันจะไม่ได้รับข้อผิดพลาดใด ๆ แต่แน่นอนว่า URL นั้นไม่มีพิกัดใด ๆ เนื่องจากถูกเก็บไว้ในตัวแปร\LATและ\LNG
มีวิธีสร้าง URL อย่างถูกต้องโดยใช้ตัวแปรที่กำหนดไว้ภายใน\hrefคำสั่งหรือไม่?
นี่คือตัวอย่างการทดสอบ:
\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หลีกเลี่ยงการโคลนไฟล์ของฉัน คุณสามารถใช้ชื่อไฟล์ใดก็ได้ที่คุณต้องการสำหรับฐานข้อมูล
\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คำสั่งของคุณสร้างโทเค็นพื้นที่และ - โทเค็นที่ไม่ต้องการ\par:
ฉันเขียนอีกครั้งพร้อมกับความคิดเห็นที่ระบุว่าโทเค็นที่ไม่ต้องการเหล่านี้เกิดขึ้นที่ใด:
\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สำหรับตั้งค่าตัวคั่นสำหรับรายการของฐานข้อมูลเป็นลูกน้ำแม้ว่านี่จะเป็นค่าเริ่มต้น ดังนั้นสิ่งนี้อาจล้าสมัย