É possível no Latex converter todos os números entre imperiais e métricos?

É possível no Latex converter todos os números entre imperiais e métricos?

Esta questão levou a um novo pacote:
smartunits

Atualmente estou escrevendo um documento que gostaria de divulgar tanto para o público europeu como para o público americano. O problema é, como sempre, a escolha entre unidades imperiais e métricas.

O texto não é científico e não se destina a um público científico, por isso não posso simplesmente usar unidades métricas do começo ao fim e encerrar o dia. Como muitas das unidades estão ocultas no texto, encontrá-las todas e alterá-las é bastante complicado (mesmo com o uso de comentários ocultos como sinalizadores de orientação).

O que procuro é um método para oferecer o melhor dos dois mundos. Estou procurando algo que possa converter todas as unidades métricas em imperiais e vice-versa. O esquema ideal seria assim:

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

O que deve resultar em:

Oscar Wilde's height is said to have been 6'3''

A ideia seria que as unidades pudessem ser controladas a partir do preâmbulo, sem a necessidade de alterar o texto.

Existe tal pacote disponível ou é facilmente possível criar minha própria solução (não sou muito bom em codificação e nunca tentei escrever nada em Tex antes)?

Dei uma olhada no pacote siunitx, mas não há nada nele sobre a conversão de unidades entre si.

Editar: conforme comentário de Joseph Wright, mais alguns detalhes: As unidades a serem convertidas seriam, no mínimo, peso, comprimento e tempo (sendo a última opcional, mas vantajosa). A conversão deve ser do sistema métrico padrão (quilogramas, metros, formato 24:00) para imperial (libras, pés, formato 12 AM/PM).

Se eu pessoalmente estivesse escrevendo um pacote, provavelmente permitiria certos sinalizadores de comando (por exemplo: quilômetro deveria ser traduzido para milhas, não para milhares de pés), e a altura do corpo (digamos 189 cm) deveria ser convertida para 6'2'', não para "2 jardas".

Eu percebo que acertar isso para todos os cenários possíveis (altura do corpo, altura da montanha, distância pequena, distância grande, etc. etc.) é um tanto complexo (principalmente graças às partes estranhas do sistema imperial). Quanto à precisão: como não foi escrito para um público científico, qualquer arredondamento até a vírgula é aceitável. Ou seja: 1 metro pode facilmente ser convertido em 3 pés, mesmo que não seja exatamente exato. É claro que, se fosse necessária mais precisão, seria necessário um arredondamento.

Segunda edição: Um truque simples que acho que também pode funcionar (mesmo que não seja muito elegante), é uma forma em látex de definir duas palavras. Por exemplo:

Oscar Wilde's height is said to have been \twowords{191cm}{6'3''}.

Com alguma possibilidade de escolher qual será selecionado no preâmbulo. Isso forçaria o usuário a converter tudo sozinho, mas permitiria, pelo menos, uma troca fácil entre unidades.

Responder1

Implementar seu hack é bastante fácil:

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

Então você pode simplesmente usar \MyUnit{191cm}{6'3''}em seu documento e mudar entre métrico e imperial a qualquer momento usando \Metrictruee \Metricfalse.

Aqui está um exemplo completo (com um uso grosseiro deUnidades SIconforme solicitado nos comentários):

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

e a saída:

insira a descrição da imagem aqui

Editar: o pacote smartunits

Quando escrevi este post pela primeira vez, eu disse que deveria ser possível fazer isso corretamente usandoteclas pgf. Em parte como uma prova de conceito e em parte como um exercício para aprender como usar o pgfkeys, existe agora umunidades inteligentespacote para conversão entre unidades métricas e imperiais.

Aqui está um 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}

e aqui está a saída que isso produz:

insira a descrição da imagem aqui (Há alguns truques usando olistagenspacote para que o LateX digite os comandos após os %em cada linha.)

Responder2

Para completar, uma opção é apenas fazer as conversões de unidades em LaTeX, usando algo como pgf/tikz ouFP. Pessoalmente, sou de opinião que esta não é a solução ideal, uma vez que existem muitos casos extremos (como, por exemplo, quando converter entre metros e quilómetros, ou quanto arredondar). No entanto, pode ser suficiente para um uso não científico. Com essa ressalva fora do caminho, aqui está uma possível implementação.

Primeiro, configuramos uma bandeira para selecionar entre unidades métricas e imperiais.

\newif\ifmetric\metrictrue

Podemos então começar implementando uma macro que alterna entre 24 horas e 12 horas, dependendo do estado deste sinalizador. Assumiremos que inserimos um horário no formato de 24 horas e o convertemos para 12 horas, se necessário.

\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%
}

Basicamente, o que isto faz é verificar se o primeiro argumento (as horas) é maior que 12. Se for, então usa o pacote fp \FPevalpara subtrair 12 do número de horas. A hora é então esse novo número de horas, seguido pelos minutos e PM. Caso contrário, apenas adicionamos um AM ao final do horário. Na verdade, isso deve funcionar perfeitamente para as suas necessidades.

A seguir, vamos fazer a conversão entre duas unidades, digamos quilogramas e libras.

\def\smartkilogram#1{%
  \ifmetric%
    #1 kg%
  \else%
    \FPeval{\result}{round(#1 * 2.204:1)}%
    \result\ lbs%
  \fi%
}

Novamente, apenas fazemos as contas usando \FPevalnossa bandeira para alternar entre unidades métricas e imperiais.

A conversão entre metros e pés mais polegadas é um pouco mais complicada, mas não é fundamentalmente diferente de como fizemos quilogramas em libras.

% 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%
}

Se você também estiver trabalhando com quilômetros, pode fazer sentido definir algo assim:

\def\smartkilometer#1{\FPeval{\result}{trunc((#1 * 1000):0)}\smartmeter{\result}}

O que isso faz é multiplicar qualquer número fornecido por 1000 e colocá-lo na \smartmetermacro. Ele usa o nome da macro ( \smartmetervs \smartkilometer) para controlar as unidades.

Com essas macros definidas, o seguinte código:

\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}!

fica assim:

insira a descrição da imagem aqui

informação relacionada