Sử dụng \ DTLfetch bên trong \ href
Tôi đang cố tạo một lệnh mới trong LaTeX để tạo một URL Google Map trỏ đến tọa độ được liên kết với địa điểm được chỉ định làm tham số trong lệnh được gọi (một loại chức năng "tra cứu bảng"). Các địa điểm và tọa độ tương đối được lưu trữ bên trong coords.CSVtệp và phải được đọc bằng cách sử dụng datatoolgói.
URL Google Map phải có cấu trúc như sau:
https://www.google.com/maps/?q=<LAT>,<LNG>
nơi <LAT>và <LNG>là những vĩ độ và kinh độ tải từ coords.CSVtập tin, mà được cấu trúc theo cách này:
Place,LAT,LNG
Test,42.0000,42.0000
...
Đây là cách lệnh được định nghĩa:
\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}
}
Cuối cùng, tôi sử dụng lệnh mới theo cách này:
\coords{Test}
Tôi đã quản lý để tải đúng tọa độ của địa điểm được gọi bên trong lệnh (trong trường hợp này là "Kiểm tra"), nhưng khi tôi cố gắng tạo URL, LaTeX cho tôi rất nhiều lỗi, hầu hết là lỗi ! Undefined control sequence. Nếu tôi xóa \LATvà \LNGkhỏi dòng nơi URL được tạo (bên trong định nghĩa lệnh), tôi không gặp bất kỳ lỗi nào, nhưng tất nhiên URL không chứa bất kỳ tọa độ nào, vì chúng được lưu trữ bên trong biến \LATvà \LNG.
Có cách nào để tạo URL đúng cách bằng cách sử dụng các biến được xác định bên trong \hreflệnh không?
Đây là một ví dụ thử nghiệm:
\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}
Trả lời
Bạn có thể sử dụng thủ thuật tương tự như trong câu trả lời của tôi để truy xuất chuỗi con của `\ 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}
Tôi đã từng \jobnametránh làm tắc nghẽn các tệp của mình. Bạn có thể sử dụng bất kỳ tên tệp nào bạn muốn cho cơ sở dữ liệu.
Tải cơ sở dữ liệu một lần, không phải mọi lần bạn gọi \coords.
Tôi đề xuất cách tiếp cận sau:
\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}
Tôi đề xuất phương pháp này vì với mã của bạn có một số vấn đề:
Vấn đề 1:
\coordsLệnh của bạn tạo ra các mã không gian và mã thông báo không mong muốn \par:
Tôi viết lại nó với các nhận xét cho biết nơi các mã thông báo không mong muốn này ra đời:
\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
}
Vấn đề 2:
Siêu hướng dẫn sử dụng nói rằng các mã thông báo trong đối số URL của \hrefphải có thể mở rộng hoàn toàn.
Các lệnh của bạn \LATvà \LNGkhông thể mở rộng hoàn toàn vì định nghĩa của chúng chứa mã thông báo từ điều khiển \DTLfetchtrong khi hướng dẫn sử dụng gói dữ liệu nói rõ ràng rằng
\DTLfetch{students}{regnum}{\RegNum}{forename} bằng
điều này chỉ ra rằng\dtlgetrowforvalue{students}{\dtlcolumnindex{students}{regnum}}{\RegNum}%
\dtlgetentryfromcurrentrow{\dtlcurrentvalue}{\dtlcolumnindex{students}{forename}}% \dtlcurrentvalue
\DTLfetch(và do đó mọi macro mà việc mở rộng ở một số giai đoạn tạo ra mã thông báo
\DTLfetch) không thể mở rộng hoàn toàn như một macro
\dtlcurrentvalueđược xác định bởi
\dtlgetentryfromcurrentrow.
Vấn đề 3:
Tôi nghi ngờ rằng cần phải tải cơ sở dữ liệu với mỗi lần gọi đến \coords.
Vấn đề 4:
Bạn sử dụng lệnh \DTLsetseparatorđể đặt dấu phân cách cho các mục nhập của cơ sở dữ liệu thành dấu phẩy mặc dù đây là lệnh mặc định. Vì vậy, điều này có lẽ là lỗi thời.