
Фон
Привет, и заранее спасибо за любые идеи, которые вы можете предложить! Извините за очень длинный пост, но я заметил, что большинство новых пользователей ругают за то, что они не делятся достаточным контекстом.Версия TLDR: я не могу понять, как использовать значения ячеек, считанные с помощью pgfplottable, внутри логических выражений из etools..
Я борюсь с форматированием определенных фрагментов текста на основе значений, считываемых из csv. Каждый год мне приходится создавать документ с более или менее одинаковым планом, но с разными значениями в определенных местах каждый год. Например, в 2015 году документ может быть таким:
Общая номинальная мощность для Соединенных Штатов в 2015 году составила 1,159,748 МВт.
но в 2016 году это предложение следует изменить на:
Общая номинальная мощность для Соединенных Штатов в 2015 году составила 1,174,115 МВт.
Мы пытаемся перевести это на более эффективный процесс с использованием Python + LaTeX, при котором фактические данные/цифры сохраняются в CSV-файлы с помощью Python, а документы автоматически обновляются с помощью LaTeX, считывающего эти CSV-файлы. Идея заключается в том, что мы можем воссоздать все документы с помощью одного скрипта командной строки.
До сих пор,с помощью этого ответа, у меня нет никаких проблем с чтением CSV-файлов и их «встроенной» печатью в LaTeX. MWE:
\documentclass[16pt]{article}
\usepackage{pgfplotstable, pgfplots, etoolbox, xcolor}
\pgfplotstableread[col sep=comma]{data_values_test.csv}\sectionIIvars
\def\getcell#1#2#3{
\pgfplotstablegetelem{#1}{#2}\of{#3}\pgfplotsretval%
}
\begin{document}
Renewable electricity in was \textbf{\getcell{8}{all_re}{\sectionIIvars}\% of total installed electricity capacity and \getcell{3}{all_re}\sectionIIvars}\% of total annual generation in the United States}.
\end{document}
Который выплевывает:
Я могу придумать, как поделиться с вами настоящими CSV-файлами, но они довольно просты: 1-я строка — это заголовок/имена (например, вы можете видеть из кода, что есть столбец с названием «all_re»). Первый столбец — это просто имена (строки символов), которые помогают нам отслеживать, какая строка соответствует какой переменной. Остальная часть CSV — это просто числа. Функция «\getcell{8}{all_re}{\sectionIIvars}» позволяет мне получить доступ к содержимому ячейки для строки 8, столбца «all_re» из предопределенной таблицы «\sectionIIvars».
Проблема
Выходные данные LaTeX здесь будут переданы команде, которая сделает их «готовыми к публикации», и нам часто нужно передавать этой команде несколько итераций документа, поскольку рисунки постоянно обновляются вплоть до окончательной публикации. Чтобы сократить время, необходимое этой внешней команде для обновления черновиков «готовых к публикации», мы хотим иметь возможность автоматически форматировать значения, которые изменились между итерациями. Например, если второе значение в приведенном выше фрагменте кода изменилось с 15,55 до 17,56 между итерациями, мы хотим, чтобы это 17,56 отображалось красным цветом. Даже если никакой код в файле «.tex» не изменился, только в базовом csv. Смотрите ниже:
К сожалению, я не могу заставить это работать! Несколько вещей, которые я пробовал, но безрезультатно:
Latexdiff
Я сразу же исключил это, потому что, насколько я мог судить, это фиксирует только изменения в самих файлах '.tex'. Поскольку сами файлы .tex здесь не меняются, это не поможет.
ifboolexpr
Большую часть времени я провел здесь. Все это основано на команде, написаннойв этом ответе. В каждом случае я пытаюсь заставить булеву функцию сравнить ответ в одном csv с ответом в другом csv. Идея в том, что скрипт Python может сравнивать ответы в таблице '\sectionIIvars' между итерациями и записывать, изменился ли фактический ответ во втором csv (назовем его '\booltestsecII'). Затем Latex может вывести ответы в '\sectionIIvars'но отформатируйте их на основе '\booltestsecII'. «\booltestsecII» будет иметь тот же размер и форму, что и «\sectionIIvars», но только с нулями и единицами (для «не изменилось» и «изменилось!» соответственно).
Попытка 1
Сначала я попробовал переписать функцию getcell так, чтобы она принимала дополнительный аргумент, чтобы она сравнивала одну и ту же строку и ячейку между '\sectionIIvars' и \booltestsecII':
\documentclass[16pt]{article}
\usepackage{pgfplotstable, pgfplots, etoolbox, xcolor}
\pgfplotstableread[col sep=comma]{data_values_test.csv}\sectionIIvars
\pgfplotstableread[col sep=comma]{Boolean_change_test.csv}\booltestsecII
\newcommand{\getcell}[4]{
\ifboolexpr{ test {\ifnumcomp{\pgfplotstablegetelem{#1}{#2}\of{#4}\pgfplotsretval}{=}{1}}}
{\pgfplotstablegetelem{#1}{#2}\of{#3}\pgfplotsretval}
{\textcolor{red}{\pgfplotstablegetelem{#1}{#2}\of{#3}\pgfplotsretval}}
}
\begin{document}
Renewable electricity in was \textbf{\getcell{8}{all_re}{\sectionIIvars}{\booltestsecII}\% of total installed electricity capacity and \getcell{3}{all_re}{\sectionIIvars}{\booltestsecII}\% of total annual generation in the United States}.
\end{document}
Это привело к ошибке "! Отсутствует число, рассматривается как ноль." (которая обычно указывает на отсутствие требуемого входного значения функции), хотя я думал, что предоставил все необходимые входные данные. Если я попытаюсь продолжить, то выдаст ошибку "Отсутствует = вставлено для \ifnum.". Если я попытаюсь продолжить еще раз, то выдаст ошибку "! Вы не можете использовать `\numexpr' в горизонтальном режиме.'
Попытка 2
Я подумал, что это как-то связано с вложенными макросами, поэтому попробовал изменить определение функции следующим образом (на основе этого вопроса):
\newcommand{\getcell}[4]{
\ifboolexpr{ test {\ifnumcomp{\pgfplotstablegetelem{##1}{##2}\of{##4}\pgfplotsretval}{=}{1}}}
{\pgfplotstablegetelem{##1}{##2}\of{##3}\pgfplotsretval}
{\textcolor{red}{\pgfplotstablegetelem{##1}{##2}\of{##4}\pgfplotsretval}}
}
Но это привело к тем же ошибкам.
Попытка 3
Я попытался немного упростить и просто сосредоточиться на считывании значения из CSV-файла, а затем сравнить его с числовым значением с помощью «ifboolexpr», но это тоже не сработало:
\documentclass[16pt]{article}
\usepackage{pgfplotstable, pgfplots, etoolbox, xcolor}
\pgfplotstableread[col sep=comma]{Boolean_change_test.csv}\booltestsecII
\newcommand{\checkchangesecII}[3]{
\ifboolexpr{ test {\value{\pgfplotstablegetelem{#1}{#2}\of{#3}\pgfplotsretval}{=}{1}}}
{do this}
{\textcolor{red}{do that}}
}
\begin{document}
\checkchangesecII{0}{solar}{\booltestsecII}
\end{document}
Это приводит к ошибке '! Missing \endcsname added.', а затем к ошибке '! Extra \endcsname.', после чего в конце концов выводится сообщение "1=1do that":
Краткое содержание
Пока что я никуда не продвинулся, но мне очень интересно услышать чьи-нибудь теории. Я думаю, что, возможно, хотя LaTeX и считывает числовые значения, он не распознает их как таковые и поэтому не может сравнить «числовую 1» со «строкой символов 1»? Я не знаю, как это проверить или исправить, поэтому я и пишу здесь.
Спасибо за любые отзывы. Извините, если вопрос плохо отформатирован, пожалуйста, дайте мне знать, и я отредактирую его как можно лучше.
решение1
Вы были довольно близки:
В попытке 1 вы использовали
\ifboolexpr{ test {\ifnumcomp{\pgfplotstablegetelem{#1}{#2}\of{#4}\pgfplotsretval}{=}{1}}}
Здесь \pgfplotstablegetelem{#1}{#2}\of{#4}
присваивает 1
или 0
в \pgfplotsretval
и после этого вы используете \pgfplotsretval
. Зачем это нужно? Почему напрямую не \pgfplotstablegetelem{#1}{#2}\of{#4}
дает возвращаемое значение? Проблема в том, что некоторые операции, такие как присваивания и другие вещи, которые необходимы в , \pgfplotstablegetelem
не являются «расширяемыми». Это в основном означает, что они могут быть выполнены, но они не могут стоять там, где требуется значение. Поэтому использование \pgfplotstablegetelem
внутри \test
того, где ожидается значение, которое вы хотите проверить, не сработает. Вот где \pgfplotsretval
вступает в игру: вы можете переместиться \pgfplotstablegetelem
перед тестом и использовать расширяемое только \pgfplotsretval
внутри:
\documentclass[16pt]{article}
\usepackage{pgfplotstable, pgfplots, etoolbox, xcolor}
\pgfplotstableread[col sep=comma]{data_values_test.csv}\sectionIIvars
\pgfplotstableread[col sep=comma]{Boolean_change_test.csv}\booltestsecII
\newcommand{\getcell}[4]{
\pgfplotstablegetelem{#1}{#2}\of{#4}
\ifboolexpr{ test {\ifnumcomp{\pgfplotsretval}{=}{1}}}
{\pgfplotstablegetelem{#1}{#2}\of{#3}\pgfplotsretval}
{\textcolor{red}{\pgfplotstablegetelem{#1}{#2}\of{#3}\pgfplotsretval}}
}
\begin{document}
Renewable electricity in was \textbf{\getcell{8}{all_re}{\sectionIIvars}{\booltestsecII}\% of total installed electricity capacity and \getcell{3}{all_re}{\sectionIIvars}{\booltestsecII}\% of total annual generation in the United States}.
\end{document}