如何扩展元素包以打印熔点和沸点?

如何扩展元素包以打印熔点和沸点?

根据我的计划,我想扩展该elements包以打印化学元素的熔点和沸点。使用elements包中使用的相同逻辑,我考虑创建如下命令:

% default: unit=kelvin    
\DeclareAtomMeltingPoint[unit=kelvin|celsius|fahrenheit]{<atomic number>}{<temperature>}

调用以下命令之一:

% Used before begin document or in packages/classes    
\DeclareAtomMeltingPointKelvin{<atomic number}{<temperature in kelvin>}
\DeclareAtomMeltingPointCelsius{<atomic number}{<temperature in celsius>}
\DeclareAtomMeltingPointFahrenheit{<atomic number}{<temperature in fahrenheit>}

要打印文档内的温度,我会使用如下命令:

% Used inside document
\meltingpoint[<unit=kelvin|celsius|fahrenheit>]{<atomic number>|<element symbol>|<element name>}

我该如何实现这个呢?

答案1

我不会使用unit=,因为这会妨碍可扩展性。

我采用使用属性列表的方法。

\documentclass{article}
\usepackage{xparse,siunitx}

\DeclareSIUnit{\fahrenheit}{\degree F}

\ExplSyntaxOn
\NewDocumentCommand{\DeclareAtomMeltingPoint}{O{kelvin}mm}
 {
  \group_begin:
  \keys_set:nn { grs/meltingpoint } { #1 }
  \prop_gput:Nnx \g_grs_meltingpoint_prop { #2 }
   {
    \__grs_meltingpoint_store:n { #3 }
   }
  \group_end:
 }

\prop_new:N \g_grs_meltingpoint_prop

\keys_define:nn { grs/meltingpoint }
 {
  kelvin     .code:n = \cs_set_eq:NN \__grs_meltingpoint_store:n \__grs_meltingpoint_in_kelvin:n,
  K          .code:n = \cs_set_eq:NN \__grs_meltingpoint_store:n \__grs_meltingpoint_in_kelvin:n,
  celsius    .code:n = \cs_set_eq:NN \__grs_meltingpoint_store:n \__grs_meltingpoint_in_celsius:n,
  C          .code:n = \cs_set_eq:NN \__grs_meltingpoint_store:n \__grs_meltingpoint_in_celsius:n,
  fahrenheit .code:n = \cs_set_eq:NN \__grs_meltingpoint_store:n \__grs_meltingpoint_in_fahrenheit:n,
  F          .code:n = \cs_set_eq:NN \__grs_meltingpoint_store:n \__grs_meltingpoint_i_fahrenheit:n,
 }

\cs_new:Nn \__grs_meltingpoint_in_kelvin:n
 {
  \fp_eval:n { #1 }
 }
\cs_new:Nn \__grs_meltingpoint_in_celsius:n
 {
  \fp_eval:n { #1 + 273.15 }
 }
\cs_new:Nn \__grs_meltingpoint_in_fahrenheit:n
 {
  \fp_eval:n { (#1 + 459.67)*5/9 }
 }

\NewExpandableDocumentCommand{\meltingpoint}{sO{kelvin}m}
 {
  \IfBooleanTF{#1}
   { % we want the unit
    \str_case:nn { #2 }
     {
      {kelvin}{\SI{\__grs_meltingpoint_out_kelvin:n{#3}}{\kelvin}}
      {K}{\SI{\__grs_meltingpoint_out_kelvin:n{#3}}{\kelvin}}
      {celsius}{\SI{\__grs_meltingpoint_out_celsius:n{#3}}{\celsius}}
      {C}{\SI{\__grs_meltingpoint_out_celsius:n{#3}}{\celsius}}
      {fahrenheit}{\SI{\__grs_meltingpoint_out_fahrenheit:n{#3}}{\fahrenheit}}
      {F}{\SI{\__grs_meltingpoint_out_fahrenheit:n{#3}}{\fahrenheit}}
     }
   }
   { % no unit
    \str_case:nn { #2 }
     {
      {kelvin}{\__grs_meltingpoint_out_kelvin:n{#3}}
      {K}{\__grs_meltingpoint_out_kelvin:n{#3}}
      {celsius}{\__grs_meltingpoint_out_celsius:n{#3}}
      {C}{\__grs_meltingpoint_out_celsius:n{#3}}
      {fahrenheit}{\__grs_meltingpoint_out_fahrenheit:n{#3}}
      {F}{\__grs_meltingpoint_out_fahrenheit:n{#3}}
     }
   }
 }

\cs_new:Nn \__grs_meltingpoint_out_kelvin:n
 {
  \prop_item:Nn \g_grs_meltingpoint_prop { #1 }
 }
\cs_new:Nn \__grs_meltingpoint_out_celsius:n
 {
  \fp_eval:n { \prop_item:Nn \g_grs_meltingpoint_prop { #1 } - 273.15 }
 }
\cs_new:Nn \__grs_meltingpoint_out_fahrenheit:n
 {
  \fp_eval:n { \prop_item:Nn \g_grs_meltingpoint_prop { #1 } * 9/5 - 459.67 }
 }

\ExplSyntaxOff

\DeclareAtomMeltingPoint[celsius]{79}{1064}

\begin{document}

\meltingpoint*[kelvin]{79}
\meltingpoint[kelvin]{79}
\meltingpoint*[K]{79}
\meltingpoint[K]{79}

\meltingpoint*[celsius]{79}
\meltingpoint[celsius]{79}
\meltingpoint*[C]{79}
\meltingpoint[C]{79}

\meltingpoint*[fahrenheit]{79}
\meltingpoint[fahrenheit]{79}
\meltingpoint*[F]{79}
\meltingpoint[F]{79}

\end{document}

您可以使用长名称或首字母,以方便输入。*-version 用于使用\SI所需单位排版值。

声明可以使用任何单位,值以开尔文为单位存储。

在此处输入图片描述

略有不同的版本也支持沸点并避免代码重复。

\documentclass{article}
\usepackage{xparse,siunitx}

\DeclareSIUnit{\fahrenheit}{\degree F}

\ExplSyntaxOn
\NewDocumentCommand{\DeclareAtomMeltingPoint}{O{kelvin}mm}
 {
  \prop_gput:Nnx \g_grs_meltingpoint_prop { #2 }
   {
    \use:c { __grs_temperature_in_#1:n } { #3 }
   }
 }
\NewDocumentCommand{\DeclareAtomBoilingPoint}{O{kelvin}mm}
 {
  \prop_gput:Nnx \g_grs_boilingpoint_prop { #2 }
   {
    \use:c { __grs_temperature_in_#1:n } { #3 }
   }
 }

\NewExpandableDocumentCommand{\meltingpoint}{sO{kelvin}m}
 {
  \IfBooleanTF{#1}
   { % we want the unit
    \grs_point_si:Nnn \g_grs_meltingpoint_prop { #2 } { #3 }
   }
   {
    \grs_point:Nnn \g_grs_meltingpoint_prop { #2 } { #3 }
   }
 }
\NewExpandableDocumentCommand{\boilingpoint}{sO{kelvin}m}
 {
  \IfBooleanTF{#1}
   { % we want the unit
    \grs_point_si:Nnn \g_grs_boilingpoint_prop { #2 } { #3 }
   }
   {
    \grs_point:Nnn \g_grs_boilingpoint_prop { #2 } { #3 }
   }
 }

\prop_new:N \g_grs_meltingpoint_prop
\prop_new:N \g_grs_boilingpoint_prop

\cs_new:Nn \__grs_temperature_in_kelvin:n
 {
  \fp_eval:n { #1 }
 }
\cs_set_eq:NN \__grs_temperature_in_K:n \__grs_temperature_in_kelvin:n

\cs_new:Nn \__grs_temperature_in_celsius:n
 {
  \fp_eval:n { #1 + 273.15 }
 }
\cs_set_eq:NN \__grs_temperature_in_C:n \__grs_temperature_in_celsius:n

\cs_new:Nn \__grs_temperature_in_fahrenheit:n
 {
  \fp_eval:n { (#1 + 459.67)*5/9 }
 }
\cs_set_eq:NN \__grs_temperature_in_F:n \__grs_temperature_in_fahrenheit:n

\cs_new:Nn \__grs_temperature_out_kelvin:Nn
 {
  \prop_item:Nn #1 { #2 }
 }
\cs_new:Nn \__grs_temperature_out_celsius:Nn
 {
  \fp_eval:n { (\prop_item:Nn #1 { #2 }) - 273.15 }
 }
\cs_new:Nn \__grs_temperature_out_fahrenheit:Nn
 {
  \fp_eval:n { (\prop_item:Nn #1 { #2 }) * 9/5 - 459.67 }
 }

\cs_new:Nn \grs_point_si:Nnn
 {
  \str_case:nn { #2 }
   {
    {kelvin}{\__grs_point_si:NNnn #1 \__grs_temperature_out_kelvin:Nn {#3} {\kelvin}}
    {K}{\__grs_point_si:NNnn #1 \__grs_temperature_out_kelvin:Nn {#3} {\kelvin}}
    {celsius}{\__grs_point_si:NNnn #1 \__grs_temperature_out_celsius:Nn {#3} {\celsius}}
    {C}{\__grs_point_si:NNnn #1 \__grs_temperature_out_celsius:Nn {#3} {\celsius}}
    {fahrenheit}{\__grs_point_si:NNnn #1 \__grs_temperature_out_fahrenheit:Nn {#3} {\fahrenheit}}
    {F}{\__grs_point_si:NNnn #1 \__grs_temperature_out_fahrenheit:Nn {#3} {\fahrenheit}}
   }
 }
\cs_new:Nn \grs_point:Nnn
 {
  \str_case:nn { #2 }
   {
    {kelvin}{\__grs_point:NNn #1 \__grs_temperature_out_kelvin:Nn {#3}}
    {K}{\__grs_point:NNn #1 \__grs_temperature_out_kelvin:Nn {#3}}
    {celsius}{\__grs_point:NNn #1 \__grs_temperature_out_celsius:Nn {#3}}
    {C}{\__grs_point:NNn #1 \__grs_temperature_out_celsius:Nn {#3}}
    {fahrenheit}{\__grs_point:NNn #1 \__grs_temperature_out_fahrenheit:Nn {#3} }
    {F}{\__grs_point:NNn #1 \__grs_temperature_out_fahrenheit:Nn {#3} }
   }
 }

\cs_new_protected:Nn \__grs_point_si:NNnn
 {
  \SI{#2 #1 {#3}}{#4}
 }
\cs_new:Nn \__grs_point:NNn
 {
  #2 #1 {#3}
 }

\ExplSyntaxOff

\DeclareAtomMeltingPoint[celsius]{79}{1064}
\DeclareAtomBoilingPoint[celsius]{1}{-252.9}

\begin{document}

\meltingpoint*[kelvin]{79}
\meltingpoint[kelvin]{79}
\meltingpoint*[K]{79}
\meltingpoint[K]{79}

\meltingpoint*[celsius]{79}
\meltingpoint[celsius]{79}
\meltingpoint*[C]{79}
\meltingpoint[C]{79}

\meltingpoint*[fahrenheit]{79}
\meltingpoint[fahrenheit]{79}
\meltingpoint*[F]{79}
\meltingpoint[F]{79}

\boilingpoint*[kelvin]{1}
\boilingpoint[kelvin]{1}
\boilingpoint*[K]{1}
\boilingpoint[K]{1}

\boilingpoint*[celsius]{1}
\boilingpoint[celsius]{1}
\boilingpoint*[C]{1}
\boilingpoint[C]{1}

\boilingpoint*[fahrenheit]{1}
\boilingpoint[fahrenheit]{1}
\boilingpoint*[F]{1}
\boilingpoint[F]{1}

\end{document}

在此处输入图片描述

答案2

就是这样:

unit(默认为kelvin)设置输入单位为\DeclareAtomMeltingPoint,输出单位为\meltingpoint。内部温度以开尔文为单位存储。数字打印时无需进一步格式化。

的声明\DeclareAtomMeltingPoint和使用都\meltingpoint使用原子序数。元素符号和名称不太容易检索,因此代码变得更加复杂。

\documentclass{article}

\usepackage{elements}
\usepackage{xparse}

\ExplSyntaxOn
\keys_define:nn { grs / elements }
  {
    , unit .choice:
    , unit / kelvin .code:n = { \cs_set_eq:NN \__grs_select_unit:nnn \use_i:nnn }
    , unit / celsius .code:n = { \cs_set_eq:NN \__grs_select_unit:nnn \use_ii:nnn }
    , unit / fahrenheit .code:n = { \cs_set_eq:NN \__grs_select_unit:nnn \use_iii:nnn }
    , unit .initial:n = kelvin
    , unit .value_required:n = true
  }
\NewDocumentCommand \DeclareAtomMeltingPoint { o m m }
  {
    \group_begin:
      \IfValueT {#1}
        { \keys_set:nn { grs / elements } {#1} }
      \cs_gset:cpx { @elements@atom@meltpoint@ \int_to_roman:n {#2} }
        {
          \__grs_select_unit:nnn
            { \fp_eval:n {#3} } % kelvin
            { \fp_eval:n {#3 + 273.15} } % celsius
            { \fp_eval:n {(#3 + 459.67)*5/9} } % fahrenheit
        }
    \group_end:
  }
\NewDocumentCommand \meltingpoint { o m }
  {
    \group_begin:
      \IfValueT {#1}
        { \keys_set:nn { grs / elements } {#1} }
      \exp_args:Nv \__grs_meltingpoint:n
        { @elements@atom@meltpoint@ \int_to_roman:n {#2} }
    \group_end:
  }
\cs_new:Npn \__grs_meltingpoint:n #1
  {
    \__grs_select_unit:nnn
      { #1 } % kelvin
      { \fp_eval:n {#1 - 273.15} } % celsius
      { \fp_eval:n {#1 * 9/5 - 459.67} } % fahrenheit
  }
\ExplSyntaxOff

\begin{document}

\DeclareAtomMeltingPoint[unit=celsius]{79}{1064}

\meltingpoint[unit=kelvin]{79}

\meltingpoint[unit=celsius]{79}

\meltingpoint[unit=fahrenheit]{79}

\end{document}

相关内容