Thật không may, không. Khi xstring bang gói:
Các macro của gói này không phải là hoàn toàn có thể mở rộng
(Phần 3.2 của xtring_doc_en.pdf.)
"mở rộng" Khái niệm này, nếu bạn 'không quen thuộc với nó, là một chủ đề khá nhiều trong TeX. Nói một cách đơn giản, cái gì đó không thể mở rộng không thể được đánh giá như một đối số. Bất cứ điều gì sử dụng một bài tập ở đâu đó được đảm bảo không thể mở rộng được trong hầu hết các giống TeX, nhưng các trình kích hoạt không mở rộng khác cũng tồn tại. Giải pháp cho các vấn đề như vậy là khá khó khăn đối với bất kỳ ai không quen thuộc với các hoạt động bên trong của "miệng" TeX (một phần của TeX xử lý những thứ như mở rộng).
Gợi ý: Nếu mã LaTeX được tạo bởi tập lệnh: sử dụng tập lệnh để chuyển đổi biểu thức thời gian, vì mọi ngôn ngữ lập trình đều dễ sử dụng hơn TeX khi nói đến thao tác chuỗi. (Hoặc chỉ là về bất cứ điều gì khác cho rằng vấn đề.)
Các xstring gói không gợi ý tại một lối thoát: Bạn có thể lưu trữ các kết quả của hầu hết các hoạt động trong một biến, bằng cách thêm [\variable]
đến khi kết thúc cuộc gọi. Điều này có nghĩa là bạn cần phải viết lại \timetominutes
vào thứ gì đó tích hợp từng mảnh kết quả, sau đó lưu trữ kết quả đó trong một chuỗi lệnh để sử dụng sau này.
Cách sử dụng:
\timetominutesinto\somevar{8:00A} % \somevar contains 48
\expandafter\myfunc\expandafter{\somevar} % calls \myfunc{48}
Lưu ý việc sử dụng \expandafter
, mà nói với TeX để làm một mở rộng một cấp đơn giản (đánh giá) của một chuỗi lệnh sau tiếp theo.Nếu bạn không sử dụng hai số \expandafter
, bạn sẽ nhận được \somevar
làm đối số cho \myfunc
, chứ không phải 48
.
:
\makeatletter % allow @ in command names
\def\timetominutesinto#1#2{%
% #1 = command to store the result in
% #2 = the text to parse
% \[email protected] and \[email protected] are temporary variables for this macro
\let\[email protected]\empty % make the command empty
\IfSubStr{#2}{P}{%
\def\[email protected]{720+}% set tempa to "720+"
\StrBetween{#2}{:}{P}[\[email protected]]% store substring between : and P into tempb
\edef\[email protected]{\[email protected] \[email protected]}% set tempa to tempa + tempb
}{%
\def\[email protected]{0+}% set tempa to 0+
\StrBetween{#2}{:}{A}[\[email protected]]% store substring between : and A into tempb
\edef\[email protected]{\[email protected] \[email protected]}% set tempa to tempa + tempb
}%
\edef\[email protected]{\[email protected]+60*}% set tempa to tempa + "+60*"
\StrBefore{#2}{:}[\[email protected]]% store substring before : into tempb
% now, set #1 to the result of evaluating the formula returned by concatenating
% tempa and tempb
\edef#1{\numexpr \[email protected] \[email protected]}%
}
\def
là TeX nguyên thủy tương ứng với LaTeX của \newcommand
/\renewcommand
(Chú ý xấu xí đang TeX trước!). \edef
nghĩa là Mở rộng \def
, đánh giá định nghĩa trước khi gán kết quả cho chuỗi lệnh. \numexpr
đánh giá một biểu thức số đơn giản, như x + m + h * 60 được tạo bởi lệnh ở trên.
Cũng có thể tính kết quả ngay lập tức dưới dạng số, không xây dựng công thức, bằng cách sử dụng số học số nguyên. Nhưng điều đó sẽ làm cho mã thậm chí còn xa hơn so với ý định ban đầu của bạn.
Có thể thực hiện các thao tác chuỗi này thông qua chính TeX mà không cần sử dụng gói xstring
(thậm chí có thể mở rộng trong trường hợp cụ thể này). Nhưng đó là công cụ cấp độ khá thấp, không thể lặp lại dễ dàng nếu bạn không phải là một trận bão tuyết TeX.
Tại sao bạn muốn thực hiện điều này trong LaTeX? Bạn có thể viết một kịch bản bằng một số ngôn ngữ khác để đọc chuỗi, xử lý, sau đó xuất ra TikZ. –
giống như một công việc cho luatex. Tôi xin lỗi tôi không thể cung cấp một giải pháp trong Lua. Tôi chắc rằng người khác có thể mặc dù. – Mica
Tôi lấy cảm hứng từ khả năng mở rộng cú pháp của TikZ và nghĩ rằng tôi có thể tạo ra một thứ tương tự như vậy. Khi nó quay ra, tôi đã sai. – Ethan