Возможно ли в Latex преобразовать все числа из имперской системы мер в метрическую и наоборот?

Возможно ли в Latex преобразовать все числа из имперской системы мер в метрическую и наоборот?

Этот вопрос привел к новому пакету:
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. Он использует имя макроса ( \smartmetervs \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}!

становится таким:

введите описание изображения здесь

Связанный контент