Определение повторно используемых и легко редактируемых ключевых слов

Определение повторно используемых и легко редактируемых ключевых слов

Я пишу статью, в которой я еще не сделал все стилистические решения. То есть я не решил, какие длинные слова я хочу сократить и как я хочу их сократить, является ли автор статьи «я», «мы», «автор» или «авторы» и т. д. Поэтому я хочу определить несколько ключевых слов, которые будут использоваться много раз.

Я хочу, чтобы в верхней части моего документа было что-то вроде этого, \newcommand{\auth}{we}и всякий раз, когда я пишу \auth{}в своем документе, должно появляться слово «мы». Теперь, более опытные из вас заметят, что то, что я описываю здесь, на самом деле будет делать то, что я хочу, так что перейдем к настоящему вопросу.

Что я действительно хочу сделать, так это связать слово в английском словаре с командой и при передаче аргумента этой команде иметь возможность немного изменить ее вывод. Так, например, если я определяю \auth{}выплевывать "we", я хочу \auth{upper}выплевывать "We" вместо этого. Я также хотел бы иметь возможность получать притяжательные формы из него, такие как "Ours" и "ours", вызывая \auth{upper, possessive}или \auth{possessive}что-то подобное. Как лучше всего этого добиться? Могу ли я создать своего рода словарь или что вы порекомендуете?

Большое спасибо!

решение1

Ну, я пробовал. Кстати, это работает только в LuaLaTeX:

%!TEX program = lualatex
\documentclass{article}
\usepackage{polyglossia}
\usepackage{luacode}
\begin{luacode*}
dofile(kpse.find_file("l-lpeg.lua"))
dofile(kpse.find_file("util-sto.lua"))
dofile(kpse.find_file("util-prs.lua"))
Pronouns = {
    ["formal"] = {
        ["possessive"] = "ours",
        ["nominative"] = "we",
        ["oblique"] = "us"
    },
    ["informal"] = {
        ["possessive"] = "mine",
        ["nominative"] = "I",
        ["oblique"] = "me"
    }
}
function Auth(keywords)
    local dummy = utilities.parsers.settings_to_array(keywords)
    for i,v in ipairs(dummy) do
        if Pronouns[dummy[i]] ~= nil then result = Pronouns[dummy[i]] end
    end
    for i,v in ipairs(dummy) do
        if result[dummy[i]] ~= nil then result = result[dummy[i]] end
    end
    return result
end
function Upper(string)
    return unicode.utf8.upper(unicode.utf8.sub(string,1,1))..unicode.utf8.sub(string,2,utf8.len(string))
end
\end{luacode*}
\def\auth#1{\directlua{tex.print(Auth("#1"))}}
\def\Auth#1{\directlua{tex.print(Upper(Auth("#1")))}}
\begin{document}
\auth{oblique,informal} \Auth{formal,possessive}
\end{document}

решение2

Это оказалось на удивление сложно, но вот решение, работающее с любым TeX*

\begingroup
\catcode`!=11 % for private macros
\endlinechar=-1
\catcode`\^^M=12 \catcode`\^^?=12\relax
\gdef\!stop{^^?}
\gdef\!fi{\fi}
\newtoks\!before \newtoks\!after

% some convenient shorthands
\gdef\!csnm#1{\csname#1\endcsname} 
\gdef\!ecsnm#1#2{\expandafter#1\csname#2\endcsname}

% the main command sets up the catcodes for reading in
% the definitions of the second argument
\gdef\newvarcommand#1{
  \begingroup\catcode`\^^M=12 \catcode`\^^?=12\relax
  {\escapechar=-1 \xdef\!name{\string#1}}
  \!ecsnm\newtoks{toks:\!name}
  \gdef#1##1{
    {\escapechar=-1 \xdef\!name{\string#1}}
    \begingroup
    \!processnextkey##1,^^?,
    \!ecsnm\the{toks:\!name}
    \!result
    \endgroup
  }
  \!newvarcommand
}

% for each modifier in the argument, set the corresponding
% conditional true
\gdef\!processnextkey#1,{\def\arg{#1}
  \ifx\!stop\arg\else
    \ifx\empty\arg\def\!key{default}\else\def\!key{#1}\fi
    \!ecsnm\ifx{ifkey:\!name:\!key}\relax
      \errmessage{Unknown key \!key\space for command \!name}
    \else\!csnm{key:\!name:\!key true}\fi
  \expandafter\!processnextkey\fi
}

% here we read the argument line by line
\gdef\!newvarcommand#1{\!getnext#1^^M^^?^^M}
\gdef\!getnext#1^^M{\def\arg{#1} 
  \ifx\!stop\arg\endgroup\else
  \ifx\empty\arg\else\!parse#1^^M\fi
  \expandafter\!getnext\fi
}

% for each entry, new conditionals are created to test whether a
% modifier is present or not, and a token list containing the
% conditionals and the word to be printed is appended to the
% token list read by the command to be defined
\gdef\!parse#1:#2^^M{\!before={}\!after={}\def\arg{#1}
  \ifx\empty\arg
    {\globaldefs=1 \!ecsnm\newif{ifkey:\!name:default}}
    \!before=\expandafter{\csname ifkey:\!name:default\endcsname}
    \!after=\expandafter{\!fi}
  \else\!setupnextkey#1,^^?,\fi
  \edef\!addtoks{\!ecsnm\the{toks:\!name}
    \the\!before\def\noexpand\!result{#2}\the\!after}
  \global\!csnm{toks:\!name}=\expandafter{\!addtoks}
}

% creating \newifs for each modifier
\gdef\!setupnextkey#1,{\def\arg{#1}
  \ifx\!stop\arg\else
    {\globaldefs=1 \!ecsnm\newif{ifkey:\!name:#1}}
    \!before=\expandafter{\the\expandafter\expandafter
      \expandafter\!before\!csnm{ifkey:\!name:#1}}
    \!after=\expandafter{\the\expandafter\!after\!fi}
  \expandafter\!setupnextkey\fi
}
\endgroup

Затем вы можете определить свой «словарь» следующим образом:

\newvarcommand\auth{
  :we
  upper:We
  possessive:ours
  upper,possessive:Ours
}

В каждой строке вы пишете через запятую слова, которые хотите использовать в качестве аргументов, а затем после двоеточия слово, которое должно появиться. Значение по умолчанию можно указать с помощью :valили default:val.Важный:Записи должны располагаться в порядке увеличения количества спецификаторов (т. е. сначала должны быть все записи из одного слова, затем те, которые содержат два слова, разделенных запятыми, затем те, которые содержат три и т. д.), в противном случае вы можете получить неверные результаты.

\auth{} \auth{default} % these two are the same, "we"
\auth{upper} % "We"
\auth{possessive} % "ours"
\auth{upper,possessive} \auth{possessive,upper} % both "Ours"
\auth{lower} % this gives an "Unknown key" error

Позвольте мне объяснить, upper,possessive:Oursкак работает код для строки. В основном, когда строка читается, она сначала создает условные операторы \ifkey:auth:upperи \ifkey:auth:possessive. Затем список токенов

\ifkey:auth:upper
  \ifkey:auth:possessive
    \def\!result{Ours}
  \fi
\fi

создается и добавляется к списку токенов с именем \toks:auth. Если вы используете \auth{upper,possessive}, аргументы считываются и соответствующие условные операторы \ifkey:auth:upperи ifkey:auth:possessiveустанавливаются в значение true, toks:authсписок токенов распаковывается и \!resultпечатается.


*Хотя предполагается, что это не внешний формат \newif, как в LaTeX, но для простого TeX потребуются некоторые адаптации.

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