Этот вопрос привел к новому пакету:
smartunits
В настоящее время я пишу документ, который я хотел бы представить как европейской, так и американской аудитории. Проблема, как обычно, заключается в выборе между имперскими и метрическими единицами.
Текст не является научным и не предназначен для научной аудитории, поэтому я не могу просто использовать метрические единицы измерения и на этом закончить. Поскольку многие единицы измерения зарыты в тексте, их поиск и изменение — довольно обременительная задача (даже с использованием скрытых комментариев в качестве направляющих флагов).
Я ищу метод, который предлагает лучшее из обоих миров. Я ищу что-то, что может преобразовать все метрические единицы в имперские и наоборот. Идеальная схема будет выглядеть так:
\usepackage{smart_unit_package}
\smart_unit_convert{imperial}
...
\begin{document}
Oscar Wilde's height is said to have been \smart_unit{1.91}{meter}.
\end{document}
Что, как мы надеемся, должно привести к:
Oscar Wilde's height is said to have been 6'3''
Идея заключается в том, что подразделениями можно управлять из преамбулы, не изменяя текст.
Существует ли такой пакет или можно ли легко создать собственное решение (я не очень хорош в кодировании и никогда раньше не пробовал писать что-либо на Tex)?
Я посмотрел пакет siunitx, но там нет ничего о конвертации единиц измерения туда и обратно.
Редактировать: Согласно комментарию Джозефа Райта, еще несколько деталей: Единицами для преобразования, как минимум, будут вес, длина и время (последнее необязательно, но желательно). Преобразование должно быть из стандартной метрической системы (килограммы, метры, формат 24:00) в имперскую (фунты, футы, формат 12 AM/PM).
Если бы я сам писал пакет, я бы, вероятно, разрешил использовать определенные командные флаги (например, километры следует переводить в мили, а не в тысячи футов), а рост (скажем, 189 см) следует переводить в 6'2'', а не в «2 ярда».
Я понимаю, что сделать это правильно для каждого возможного сценария (рост тела, высота горы, небольшое расстояние, большое расстояние и т. д. и т. п.) довольно сложно (в основном из-за странностей имперской системы). Что касается точности: поскольку это не написано для научной аудитории, любое округление до десятичной точки допустимо. То есть: 1 метр можно легко преобразовать в 3 фута, даже если это не совсем точно. Конечно, если бы требовалась большая точность, потребовалась бы точка округления.
Второе редактирование: Простой трюк, который, как мне кажется, тоже может сработать (даже если он не очень элегантен), — это способ в латексе определить два слова. Например:
Oscar Wilde's height is said to have been \twowords{191cm}{6'3''}.
С некоторой возможностью выбора того, что будет выбрано в преамбуле. Это заставило бы пользователя конвертировать все самому, но это позволило бы легко менять единицы, по крайней мере.
решение1
Реализовать ваш взлом довольно просто:
\newif\ifMetric\Metrictrue% metric by default
\newcommand\MyUnit[2]{\ifMetric #1\else #2\fi}% \MyUnits{metric}{imperial}
Затем вы можете просто использовать \MyUnit{191cm}{6'3''}
в своем документе и переключаться между метрической и имперской системами в любой момент с помощью \Metrictrue
и \Metricfalse
.
Вот полный пример (с грубым использованиемSIединицыкак и просили в комментариях):
\documentclass{article}
\usepackage{SIunits}
\newif\ifMetric\Metrictrue% metric by default
\newcommand\MyUnit[2]{\ifMetric #1\else #2\fi}% \MyUnits{metric}{imperial}
\begin{document}
Metric: \MyUnit{191 \centi\meter}{$6'3''$}
\Metricfalse Imperial: \MyUnit{191 \centi\meter}{$6'3''$}
\Metrictrue Metric: \MyUnit{191 \centi\meter}{$6'3''$}
\end{document}
и вывод:
Редактировать: пакет smartunits
Когда я впервые написал этот пост, я сказал, что это можно сделать правильно, используяpgfkeysЧастично как доказательство концепции, а частично как упражнение, чтобы научиться использовать pgfkeys
, теперь естьсмартюнитыпакет для преобразования метрических и имперских единиц.
Вот MWE:
\documentclass{article}
\usepackage{smartunits}
\usepackage{xcolor}
\usepackage{listings}\lstset{language=[LaTeX]TeX}
\lstset{language=[LaTeX]TeX,
texcsstyle=*\bfseries\color{blue},
keywordstyle=\color{blue},
commentstyle=\color{brown},
morekeywords={SmartUnit,SmartUnitSettings,sisetup},
}
\begin{document}
\begin{lstlisting}[texcl]
\SmartUnitSettings{metric imperial, places=1}
\SmartUnit{km=100.0,figures=1} % \SmartUnit{km=100.0,figures=1}
\SmartUnit{miles=62.15,places=1} % \SmartUnit{miles=62.15,places=1}
\SmartUnit{cm=10} % \SmartUnit{cm=10}
\SmartUnit{celsius=20} % \SmartUnit{celsius=20}
\SmartUnit{miles=5.0, figures=1} % \SmartUnit{miles=5.0, figures=1}
\SmartUnit{miles=5.0,places=2} % \SmartUnit{miles=5.0, places=2}
\SmartUnit{hours=0, minutes=59} % \SmartUnit{hours=0, minutes=59}
\SmartUnit{hours=12, minutes=12} % \SmartUnit{hours=12, minutes=12}
\SmartUnit{kg=10.0, places=1} % \SmartUnit{kg=10.0, places=1}
\SmartUnit{pound=10.0,figures=1} % \SmartUnit{pound=10.0,figures=1}
\SmartUnit{l=10.0, places=1} % \SmartUnit{l=10.0, places=1}
\SmartUnit{L=10.0, places=1,uk} % \SmartUnit{L=10.0, places=1,uk}
\end{lstlisting}
\end{document}
и вот что это дает на выходе:
(Есть некоторые хитрости с использованиемсписки(Пакет, позволяющий LateX набирать команды после %
's в каждой строке.)
решение2
Для полноты картины одним из вариантов является простое преобразование единиц измерения в LaTeX, используя что-то вроде pgf/tikz илифп. Лично я считаю, что это не идеальное решение, поскольку существует множество пограничных случаев (например, когда переводить метры в километры или сколько округлять). Однако для ненаучного использования этого может быть достаточно. С этой оговоркой вот возможная реализация.
Сначала мы устанавливаем флаг для выбора между метрическими и имперскими единицами измерения.
\newif\ifmetric\metrictrue
Затем мы можем начать с реализации макроса, который переключается между 24-часовым и 12-часовым форматом времени в зависимости от состояния этого флага. Предположим, что мы вводим время в 24-часовом формате и преобразуем его в 12-часовой формат при необходимости.
\def\smarttime#1#2{%
\ifmetric%
#1:#2%
\else%
\ifnum#1>12%
\FPeval{\result}{trunc(#1 - 12:0)}%
\result:#2 PM%
\else%
#1:#2 AM%
\fi%
\fi%
}
По сути, это проверяет, больше ли первый аргумент (часы) 12. Если да, то он использует пакет fp \FPeval
для вычитания 12 из количества часов. Тогда время — это новое количество часов, за которым следуют минуты и PM. В противном случае мы просто добавляем AM в конец времени. Это должно полностью подойти для ваших нужд.
Далее давайте выполним преобразование между двумя единицами измерения, скажем, килограммами и фунтами.
\def\smartkilogram#1{%
\ifmetric%
#1 kg%
\else%
\FPeval{\result}{round(#1 * 2.204:1)}%
\result\ lbs%
\fi%
}
Опять же, мы просто выполняем математические вычисления \FPeval
и используем наш флаг для переключения между метрическими и имперскими единицами.
Перевод метров в футы и дюймы немного сложнее, но принципиально не отличается от того, как мы переводили килограммы в фунты.
% Conditionally converts meters to miles/feet/inches
\def\smartmeter#1{%
% Use metric units (meters)
\ifmetric%
\FPeval{\result}{trunc(#1:0)}%
\ifnum\result>1000%
\FPeval{\result}{trunc(#1/1000:1)}%
\result\ km%
\else%
\FPeval{\result}{trunc(#1:2)}%
\result\ m%
\fi%
% Use imperial units (feet and inches)
\else
\FPeval{\result}{trunc((3.281 * #1):0)}%
\ifnum\result<5280%
\FPeval{\result}{(3.281 * #1)}%
\FPeval{\feet}{trunc((\result):0)}%
\FPeval{\inch}{trunc((12 * ((\result) - (\feet))):0)}%
\feet'\inch"%
\else
\FPeval{\feet}{trunc((\result):0)}%
\FPeval{\miles}{trunc((\feet / 5280):1)}%
\miles\ miles%
\fi%
\fi%
}
Если вы также работаете с километрами, возможно, имеет смысл определить что-то вроде этого:
\def\smartkilometer#1{\FPeval{\result}{trunc((#1 * 1000):0)}\smartmeter{\result}}
Что он делает, так это умножает любое число, которое вы ему даете, на 1000 и помещает это в макрос \smartmeter
. Он использует имя макроса ( \smartmeter
vs \smartkilometer
) для отслеживания единиц.
После определения этих макросов следующий код:
\subsection*{Metric Units}
\metrictrue
Oscar Wilde's height is said to have been \smartmeter{1.91}.\\
Five kilometers is \smartkilometer{5}.\\
It is \smarttime{9}{00}. Later it will be \smarttime{13}{30}.\\
That ostrich weights \smartkilogram{100}!
\subsection*{Imperial Units}
\metricfalse
Oscar Wilde's height is said to have been \smartmeter{1.91}.\\
Five kilometers is \smartkilometer{5}.\\
It is \smarttime{9}{00}. Later it will be \smarttime{13}{30}.\\
That ostrich weights \smartkilogram{100}!
становится таким: