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

實施你的 hack 非常簡單:

\newif\ifMetric\Metrictrue% metric by default
\newcommand\MyUnit[2]{\ifMetric #1\else #2\fi}% \MyUnits{metric}{imperial}

然後,您可以在文件中使用和\MyUnit{191cm}{6'3''}隨時在公制和英制之間進行更改。\Metrictrue\Metricfalse

這是一個完整的例子(粗略地使用國際單位制按照評論中的要求):

\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 包

當我第一次寫這篇文章時,我說應該可以使用正確的方法來做到這一點pgf鍵。部分作為概念驗證,部分作為學習如何使用的練習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在每行的 '之後排版命令。

答案2

為了完整起見,一種選擇是僅在 LaTeX 中進行單位轉換,使用 pgf/tikz 或FP。我個人認為這不是一個理想的解決方案,因為存在許多邊緣情況(例如,何時在米和公里之間轉換,或捨入多少)。不過,對於非科學用途來說,這可能就足夠了。消除了這個警告後,這裡有一個可能的實現。

首先,我們設定一個標誌來在公制和英制單位之間進行選擇。

\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 \FPeval。時間就是新的小時數,然後是分鐘和 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}!

變成這樣:

在此輸入影像描述

相關內容