
Я пытаюсь создать новый макрос, который принимает либо размер масштаба, либо другой параметр масштабирования (например, width=\textwidth) для изменения размера изображений. Вот что у меня есть:
\newcommand{\pic}[3]{\begin{figure}[H]
\centering
\if\instring{#1}{=}\def \arg{#1}\else\def\arg{scale=#1}\fi
\includegraphics[\arg]{#2}
\caption{#3}
\end{figure}}
Далее в моем файле есть следующая строка:
\pic{1}{lpm_block.png}{Block diagram for the LPM multiplier}
что дает ошибку "package keyval error: scale=1 undefined". Без оператора 'if' все работает нормально. Что мне нужно изменить? Есть ли лучший способ сделать это? Спасибо!
РЕДАКТИРОВАТЬ:
Вот еще код, который должен скомпилироваться без проблем.
\documentclass{article}
\usepackage{siunitx}
\usepackage{graphicx}
\usepackage{apacite}
\usepackage{amsmath} % Required for some math elements
\usepackage{multicol} % multiple columns
\usepackage{float} % place graphics
\usepackage{subfig} % graphics on same line
\usepackage{geometry} % fill empty margins
\usepackage[square,sort,comma,numbers]{natbib}
\usepackage[hyphens]{url}
\usepackage{minted}
\renewcommand\theFancyVerbLine{\normalsize\arabic{FancyVerbLine}}
\geometry{letterpaper, top=0.75in, left=0.75in, bottom=0.75in, right=0.75in}
\setlength\parindent{0pt} % Removes all indentation from paragraphs
%\usepackage{times} % Uncomment to use the Times New Roman font
\newcommand{\pic}[3]{\begin{figure}[H]
%\if\instring{#1}{=}\def \arg{#1}\else\def\arg{scale=#1}\fi
\centering
\includegraphics[scale=#1]{#2}
\caption{#3}
\end{figure}}
\begin{document}
\section{Design Files}
\subsection{Serial Multiplier}
\pic{0.55}{serial_block.png}{Block diagram for the serial multiplier. high9 and low8 are simply registers, so they do not have separate design files}
\end{document}
Моя цель при попытке сделать это с латексом состояла в том, чтобы повысить уровень знакомства с созданием новых команд с использованием условных операторов. Я не осознавал, что нюансы сделают это немного сложнее. Спасибо за вклад на данный момент!
решение1
Я воспринимаю это как упражнение, как вы говорите. Комментарии позже.
Вам нужно решить, =
появляется ли в первом аргументе.
\documentclass{article}
\usepackage{graphicx}
\newcommand{\pic}[3]{%
\begin{figure}
\centering
\checkequals{#1}%
\expandafter\includegraphics\expandafter[\picarg]{#2}
\caption{#3}
\end{figure}%
}
\makeatletter
\newcommand\checkequals[1]{\check@equals{#1}#1=\@nil}
\def\check@equals#1#2=#3\@nil{%
\if\relax\detokenize{#3}\relax
% no =
\def\picarg{scale=#2}%
\else
\def\picarg{#1}%
\fi
}
\makeatother
\begin{document}
\pic{0.55}{example-image}{First example}
\pic{scale=0.55}{example-image}{Second example}
\pic{width=2cm,height=1cm}{example-image}{Third example}
\end{document}
Макрос \checkequals
вызывает вспомогательный \check@equals
, который принимает разделенные аргументы; в случае, =
если не появляется, мы определяем \picarg
как scale=#1
, предполагая, что масштабный коэффициент указан. В противном случае исходный аргумент сохраняется в \picarg
.
Теперь проблема: вам действительно нужен такой макрос? Нет, по нескольким причинам.
Нет большого преимущества в
\pic{0.55}{x}{y}
более чем\pic{scale=0.55}{x}{y}
.scale
это неправильный ключ для использования, потому что вы, вероятно, не знаете ни размер изображения, ни окончательный размер документа. Небольшое изменение ширины текста заставит вас изменить масштаб нескольких изображений.Нет смысла прятаться
figure
;\pic
если у вас есть две картинки, которые можно разместить на одной линии, вы можете разместить их рядом.Этот
[H]
вариант идеально подходит для того, чтобы испортить ваш документ. Если цифра должна остатьсятам и нигде больше, то ему не нужна подпись, потому что его описание будет рядом с ним в любом случае. Использование плавающих элементов помогает лучше организовать материал, чтобы иметь хорошую пагинацию в качестве бонуса.
Последнее замечание. Ваш код
%\usepackage{times} % Uncomment to use the Times New Roman font
говорит неправду. times
Пакет только измениттекстшрифты, а не математические шрифты. Если вы действительно хотите использовать Times, сделайте
\usepackage{newtxtext}
\usepackage{newtxmath}% with possible option, see the manual for newtx
решение2
Пакет keyval
использует запятую ,
в качестве разделителя пар ключ-значение и знак равенства =
для отделения ключа от значения. Он не расширяет макросы. Поэтому эти символы синтаксиса не должны быть скрыты в макросах.
Пример в вопросе исправлен путем расширения \arg
через \expandafter
before \includegraphics
processing его необязательного аргумента:
\if\instring{#1}{=}\def \arg{#1}\else\def\arg{scale=#1}\fi
\expandafter\includegraphics\expandafter[\arg]{#2}%
решение3
Если вы используете необязательный аргумент, значением по умолчанию которого является scale=1
, то вам не нужно проверять, является ли он пустым:
\documentclass{article}
\usepackage{mwe}
\newcommand{\pic}[3][scale=1]{%
\begin{figure}
\centering
\includegraphics[#1]{#2}
\caption{#3}
\end{figure}%
}
\begin{document}
\pic{example-image-1x1}{Example image}
\pic[width=\textwidth]{example-image-1x1}{Wider image}
\end{document}
В результате получатся следующие две страницы:
решение4
Обратите внимание, что я не считаю это мудрым и рекомендую переосмыслить ваши desiderata. Однако, если бы я намеревался совершить бессмысленное разрушение, я бы использовал LaTeX 3, чтобы его осуществить. Но это, вероятно, не лучшее место для начала, если вы только изучаете LaTeX 2e. Поэтому, если вам необходимо это сделать, то один из способов, которым вы можете попытаться это сделать, следующий.
\documentclass{article}
\usepackage{graphicx,caption}
\makeatletter
\def\pict@aux#1=#2\@nil{#2}
\newcommand{\pict}[3]{%
\begin{figure}
\centering
\edef\tempa{\expandafter\pict@aux#1=\@nil}%
\edef\tempb{}%
\ifx\tempa\tempb
\includegraphics[scale=#1]{#2}%
\else
\includegraphics[#1]{#2}%
\fi
\captionof{figure}{#3}%
\end{figure}%
}
\makeatother
\begin{document}
\section{Design Files}
\subsection{Serial Multiplier}
\pict{0.55}{\jobname-cx}{Block diagram for the serial multiplier. high9 and low8 are simply registers, so they do not have separate design files}
\pict{width=0.55cm}{\jobname-cx}{Block diagram for the serial multiplier. high9 and low8 are simply registers, so they do not have separate design files}
\end{document}
Однако, по моему мнению, это неуклюжий дизайн, который с презрением плюет на своих пользователей. Поэтому я бы этого не делал — по крайней мере, если бы я был среди пользователей. Ваши километры могут, как всегда, отличаться.