Introduction
LaTeX’s true power emerges through custom commands and macros. Rather than repeatedly typing complex formatting or remembering inconsistent syntax, you can define shortcuts that ensure consistency while dramatically improving productivity.
This guide covers creating custom commands, environments, and package-level configurations that streamline your document creation.
Basic Command Definitions
Simple Commands with \newcommand
\newcommand{\companyname}{Acme Corporation}
\newcommand{\productname}{SuperWidget}
The \productname\ is produced by \companyname.
This creates expandable text substitutionsโno formatting, just consistent text replacement.
Commands with Arguments
% One argument
\newcommand{\highlight}[1]{\textbf{#1}}
This is \highlight{important text}.
% Multiple arguments (up to 9)
\newcommand{\term}[2]{\textit{#1} (#2)}
\term{Algorithm}{A step-by-step procedure}
Argument syntax: #1 through #9 represent each argument.
Default Arguments
% First argument has default value
\newcommand{\emphasize}[2][red]{\textcolor{#1}{\textbf{#2}}}
\emphasize{Red text} % Uses default red
\emphasize[blue]{Blue emphasized text} % Overrides default
Advanced Command Features
Optional Arguments
\usepackage{xparse}
\NewDocumentCommand{\highlight}{O{blue} m}{%
\textcolor{#1}{\textbf{#2}}%
}
\highlight{Default blue}
\highlight[red]{Red highlight}
\highlight[green]{Green highlight}
The xparse package provides more flexible argument parsing than \newcommand.
Conditional Commands
\newif\ifdebug
\debugfalse
\ifdebug
\newcommand{\trace}[1]{\textit{#1}}
\else
\newcommand{\trace}[1]{}
\fi
\trace{This shows in debug mode}
Robust Commands
Commands using fragile content should be robust:
\usepackage{etoolbox}
\robustcommand{\myst command}[1]{%
\textbf{#1}%
}
Or use \DeclareRobustCommand:
\DeclareRobustCommand{\strong}[1]{%
\textbf{#1}%
}
Custom Environments
Basic Environment Definition
\newenvironment{important}%
{\begin{trivlist}\item[\hskip\labelsep\bfseries Important:]}%
{\end{trivlist}}
\begin{important}
This is an important note that stands out from regular text.
\end{important}
Environments with Arguments
\newenvironment{boxed}[1][Warning]%
{\begin{trivlist}\item[\hskip\labelsep\sbox0{#1}\textbf{\usebox0}:]}%
{\end{trivlist}}
\begin{boxed}{Note}
This is a note in a box.
\end{boxed}
\begin{boxed}
This uses the default "Warning" title.
\end{boxed}
Counter Environments
\newcounter{example}
\newenvironment{example}%
{\refstepcounter{example}%
\par\medskip\noindent\textbf{Example \theexample:}%
\nopagebreak\par\nobreak%
\nopagebreak}
{\par\medskip}
\begin{example}
First example content.
\end{example}
\begin{example}
Second example content.
\end{example}
Programming Constructs
Definitions and Assignments
% Simple definitions
\def\myvar{value}
% Math definitions
\gdef\constant{42}
% Conditional definitions
\ifdefined\existing
% Use existing definition
\else
\def\existing{default}
\fi
Length and Counters
% Length variables
\newlength{\mylength}
\setlength{\mylength}{2cm}
\addtolength{\mylength}{5mm}
\the\mylength
% Counter operations
\newcounter{mycounter}
\stepcounter{mycounter}
\addtocounter{mycounter}{5}
\them ycounter
Arithmetic
\usepackage{calc}
\newlength{\computed}
\setlength{\computed}{\linewidth - 2cm}
\newcounter{computed}
\settocounter{computed}{\linewidth / 50}
Package Development Basics
Creating a Style Package
% mypackage.sty
\NeedsTeXFormat{LaTeX2e}
\ProvidesPackage{mypackage}[2026/01/01 Custom Package]
% Package options
\DeclareOption{compact}{\gdef\pack@option{compact}}
\DeclareOption{verbose}{\gdef\pack@option{verbose}}
\ExecuteOptions{compact}
\ProcessOptions\relax
% Required packages
\RequirePackage{xcolor}
\RequirePackage{todonotes}
% Custom commands
\newcommand{\mypackagecmd}[1]{\textbf{#1}}
% Configuration
\gdef\mypackage@version{1.0}
\endinput
Using Your Package
\documentclass{article}
\usepackage[verbose]{mypackage}
\begin{document}
\mypackagecmd{Content}
\end{document}
Utility Commands
Helper Macros
% Check if command is defined
\ifdefined\command
\command is defined
\else
\command is not defined
\fi
% Provide command if not defined
\providecommand{\maybeDefined}{default value}
% Check for empty arguments
\newcommand{\checkempty}[1]{%
\ifx&%
Argument is empty
\else%
Argument: #1
\fi%
}
String Manipulation
\usepackage{xstring}
\StrGobbleLeft{string}{1}[\result] % Remove first char
\StrGobbleRight{string}{1}[\result] % Remove last char
\StrMid{string}{3}{7}[\result] % Extract substring
\StrLen{string}[\result] % Get length
Iteration
\usepackage{pgffor}
\foreach \x in {1,2,3,4,5} {
Item \x
}
\foreach \x/\y in {a/1,b/2,c/3} {
\x = \y
}
Document-Specific Automation
Metadata Commands
\newcommand{\docauthor}[1]{\gdef\@author{#1}}
\newcommand{\docdate}[1]{\gdef\@date{#1}}
\newcommand{\docversion}[1]{\gdef\doc@version{#1}}
\docauthor{Your Name}
\docversion{1.0}
% Use in document
Version \doc@version\ by \@author
Section Styling
% Custom section command
\newcommand{\mysection}[1]{%
\section*{#1}%
\addcontentsline{toc}{section}{#1}%
}
% Numbered custom sections
\newcommand{\specialsection}[1]{%
\section{#1}%
\sectionmark{#1}%
}
Table and Figure Helpers
% Quick figure
\newcommand{\fig}[3]{%
\begin{figure}[htbp]
\centering
\includegraphics[width=#2]{#1}
\caption{#3}
\end{figure}%
}
% Usage
\fig{image}{0.8\linewidth}{My caption}
% Quick table
\newcommand{\simpletable}[3]{%
\begin{table}[htbp]
\centering
\caption{#3}
\begin{tabular}{#1}#2\end{tabular}
\end{table}%
}
LaTeX Programming Patterns
Hooks and Filters
% At beginning of document
\AtBeginDocument{%
\hypersetup{colorlinks=true}
}
% At end of document
\AtEndDocument{%
\clearpage
\begin{center}
Document version: \doc@version
\end{center}
}
% Before/after specific commands
\let\oldsection\section
\RenewDocumentCommand\section{som+O{}}{\oldsection[#1]{#2}}
Expansion Control
% Prevent expansion
\noexpand\command
% Expand once
\expandafter\command
% Fully expand
\edef\expanded{\detokenize\expandafter{\somecommand}}
Performance Optimization
Efficient Macros
% Store repeated calculations
\newlength{\cachedlen}
\settowidth{\cachedlen}{\textbf{Some Text}}
% Reuse cached values
\the\cachedlen
% Use token registers for large text
\newtoks\mytoks
\mytoks={Some text content}
\the\mytoks
Conditional Loading
\@ifpackageloaded{package}{true}{false}
\@ifclassloaded{article}{yes}{no}
\@ifdefined\command{exists}{undefined}
Best Practices
Command Naming
- Use meaningful, descriptive names
- Avoid conflicting with existing commands
- Prefix project-specific commands
- Document all custom commands
Error Handling
\newcommand{\critical}[1]{%
\ifmmode
\PackageError{mypkg}{Use \string\critical\space in text mode only}%
\else
\textbf{#1}%
\fi
}
Testing Macros
% Debug output
\show\mycommand
% Trace expansion
\tracingonline=1
\meaning\mycommand
Conclusion
Custom commands and macros transform LaTeX from a typesetting system into a programmable document creation environment. The techniques in this guide enable automation that ensures consistency while dramatically improving productivity.
Start with simple text substitutions, progress to argument-based commands, and eventually develop custom packages for large projects. Each level of sophistication brings new capabilities.
Comments