A couple of things involving environments



Similar documents
bankstatement.cls A L A T E X class for bank statements based on csv data 2015/11/14 Package author: Josef Kleber

Command Line - Part 1

ESPResSo Summer School 2012

The collect package. Jonathan Sauer 2004/09/10

Python Lists and Loops

Paper An Introduction to SAS PROC SQL Timothy J Harrington, Venturi Partners Consulting, Waukegan, Illinois

A package for rotated objects in L A TEX

Drawing Gantt Charts in L A TEX with TikZ The pgfgantt package

Exercise 1: Python Language Basics

Moving from CS 61A Scheme to CS 61B Java

Python Loops and String Manipulation

Dialog planning in VoiceXML

Tralics, a LaTeX to XML translator Partie II

WA2099 Introduction to Java using RAD 8.0 EVALUATION ONLY. Student Labs. Web Age Solutions Inc.

University of Hull Department of Computer Science. Wrestling with Python Week 01 Playing with Python

Context sensitive markup for inline quotations

CS 1133, LAB 2: FUNCTIONS AND TESTING

VI(Visual) Editor Reference manual

Section 1.5 Exponents, Square Roots, and the Order of Operations

Introduction to Object-Oriented Programming

NewsletterAdmin 2.4 Setup Manual

6. Control Structures

Technical problems. Taking notes. Mentioning documents. Answering questions. Problems with the questions. Asking questions.

Creating Medical Pedigrees with PSTricks and L A TEX.

Using SQL Queries in Crystal Reports

A Babel language definition file for Icelandic

Microsoft Access 3: Understanding and Creating Queries

Chapter 13 - The Preprocessor

7JjX Macros for COBOL Syntax Diagrams

Perl in a nutshell. First CGI Script and Perl. Creating a Link to a Script. print Function. Parsing Data 4/27/2009. First CGI Script and Perl

COLLEGE ALGEBRA. Paul Dawkins

First Java Programs. V. Paúl Pauca. CSC 111D Fall, Department of Computer Science Wake Forest University. Introduction to Computer Science

May 20, MyCV * Author: Andrea Ghersi. Abstract

Excel for Mac Text Functions

MARK MEADS Tele: +44(0) Head of Sales, Individual Protection Direct: +44(0)

Programming Languages CIS 443

Welcome to Smart. Your guide to our new service

Querying a Database Using the Select Query Window

Outlook 2007: Managing your mailbox

MAIL MERGE AND RELATED OPERATIONS Form letters and mailing labels

Magit-Popup User Manual

To add a data form to excel - you need to have the insert form table active - to make it active and add it to excel do the following:

A package for making sticky labels in L A TEX

We will learn the Python programming language. Why? Because it is easy to learn and many people write programs in Python so we can share.

Writing an essay. This seems obvious - but it is surprising how many people don't really do this.

1.1 AppleScript Basics

Practical Problem Solving Dr. Chris Williams

Eventia Log Parsing Editor 1.0 Administration Guide

How To Build An Intranet In Sensesnet.Com

Internationalization and Web Services

Rake Task Management Essentials

Lecture 2 Notes: Flow of Control

Bash shell programming Part II Control statements

MICROSOFT ACCESS STEP BY STEP GUIDE

How to Copy Photos to a CD Using Microsoft Windows XP or Microsoft Windows Vista

Install Java Development Kit (JDK) 1.8

NFS File Sharing. Peter Lo. CP582 Peter Lo

The 2010 British Informatics Olympiad

Extensions to the ltxdoc class

AVOIDING THE GIT OF DESPAIR

The different kinds of variables in a Java program

0 Introduction to Data Analysis Using an Excel Spreadsheet

Lesson 20: Latex Picture environment

Writing cleaner and more powerful SAS code using macros. Patrick Breheny

Coding conventions and C++-style

CS1102: Adding Error Checking to Macros

Microsoft Word 2010 Mail Merge (Level 3)

Name: Class: Date: 9. The compiler ignores all comments they are there strictly for the convenience of anyone reading the program.

Raptor K30 Gaming Software

Turtle Power. Introduction: Python. In this project, you ll learn how to use a turtle to draw awesome shapes and patterns. Activity Checklist

Introducing VBA Message Boxes

Cathy Benedict, Ed.D Florida International University NAfME Nashville, 2013 Doing Away With Classroom Management: Teaching for Musical Transitions

How-To: Write simple sieve scripts

Interview with Hugh McLaughlin and Helen Scholar, editors of Social Work Education: The International Journal

PROJECT ON MICROSOFT ACCESS (HOME TAB AND EXTERNAL DATA TAB) SUBMITTED BY: SUBMITTED TO: NAME: ROLL NO: REGN NO: BATCH:

A Python Tour: Just a Brief Introduction CS 303e: Elements of Computers and Programming

Setting Up a Development Server

GAP CLOSING. Volume and Surface Area. Intermediate / Senior Student Book

Advanced Bash Scripting. Joshua Malone

A Crash Course on UNIX

Network Time Protocol and Meinberg NTP Time Server Monitor ~ Installation Guide. 1. Introduction. 2. NTP Installation

Test Driven Development

Creating Drawings in Pro/ENGINEER

Programming LEGO NXT Robots using NXC

Chapter One Love Is the Foundation. For Group Discussion. Notes

COSC 6397 Big Data Analytics. 2 nd homework assignment Pig and Hive. Edgar Gabriel Spring 2015

Introduction to Statistical Computing in Microsoft Excel By Hector D. Flores; and Dr. J.A. Dobelman

How To Use Excel With A Calculator

Creating Database Tables in Microsoft SQL Server

Training Needs Analysis

Chapter 5 More SQL: Complex Queries, Triggers, Views, and Schema Modification

Transcription:

A couple of things involving environments Will Robertson 2014/05/04 v0.3 Abstract This package provides two things, one for document authors and one for macro authors. For the document authors, a new method, \NewEnviron, fo defining environments that might be more convenient on occasion. And for the package writers, amsmath s \collect@body command, and a long version of the same, \Collect@Body. 1 Introduction This packages provides new commands for defining environments: \NewEnviron{test}{% \fbox{\box{1.5cm}{\body}}\color{red} \fbox{\box{1.5cm}{\body}}} \ \RenewEnviron has the same syntax to redefine a pre-existing environment. 2 For the document author LATEX s standard method of defining environments looks like this (ignoring arguments for now): \newenvironment{ name }{ pre code }{ post code }. The advantage to using environments is that their contents are not treated as a macro argument, so there are fewer restrictions on what can exist inside, and the processing can be more efficient for long pieces of document text. The disadvantage of environments is that sometimes you really do want to collect up their body and apply some sort of command to the whole thing. This package provides a way to define such environments: \NewEnviron{ name }{ macro code }[ final code ]. You saw an example in the introduction; the body of the environment is contained within the macro \BODY, and [ final code ] is the code executed at \end{ name } (more on this later). 1

2.1 Environment arguments If you want to use arguments to the environment, these are specified as usual: \NewEnviron{ name }[ N. args ][ opt. arg. ]{ macro code }[ final code ] where { macro code } has arguments #1, #2,..., as per traditional LATEX environment mandatory and optional arguments. Here s an example with two arguments; one optional argument (#1, which is \today if omitted) and one mandatory argument (#2): Title (May 4, 2014) Title (Yesterday) \NewEnviron{test}[2][\today]{% \fbox{\box{3cm}{% \textbf{#2}\\ \BODY\\ (#1)}}} {Title} \ [Yesterday]{Title} \ 2.2 [ final code ] \environfinalcode This is the code executed at \end{ name } of the environment. For the purposes of this package it is only designed (but is very useful indeed) for cleanup code such as space gobbling in the input text. This macro sets a default value for the [ final code ] (unless manually specified) in each subsequent environment created with \NewEnviron. The default is to define each new environment postfixed by \ignorespacesafterend, like this: \environfinalcode{\ignorespacesafterend} Here s a silly example: (finish) \environfinalcode{(finish)} \NewEnviron{test}{\fbox{\box{3cm}{\BODY}}} \ Careful, \environfinalcode cannot contain square brackets without first protecting them with braces (e.g., \environfinalcode{[end]} will not work but \environfinalcode{{[end]}} will). This is because the optional argument to \NewEnviron itself uses square brackets as argument delimiters. 2

2.3 The \BODY command \environbodyname Using \BODY as the body of the environment might clash with a command defined by another package. To overcome such conflicts, rename this command with \environbodyname\ command at which point \NewEnviron will use \ command instead of \BODY. Here s an example: FOO foo \NewEnviron{FOO}{\fbox{\BODY}} \environbodyname\envbody \NewEnviron{foo}{\fbox{\envbody}} \begin{foo}foo\end{foo} \begin{foo}foo\end{foo} 3 For the macro author The amsmath package contains a macro that facilitates the functionality in the previous section, which package writers may wish to use directly. The canonical command is \collect@body, which I ve also defined in \long form to be useable for multi-agraph environments (\Collect@Body). Here s how it s used: [ hello there ] \long\def\wrap#1{[#1]} \newenvironment{test}{\collect@body\wrap}{} hello there And here s a crude example with environment arguments: [ arg hello there ] \long\def\wrap#1{[\arg#1]} \def\arg#1{---#1---\} \newenvironment{test}{\collect@body\wrap}{} {arg} hello there 3

4 Test Here s an example or two to ensure everything that you d think should work, in fact, does: outer *aa* inner (bb) inner (bb) outer *aa* inner (bb) inner (bb) \NewEnviron{test}{% \fbox{\box{\linewidth- 0.1cm*\currentgrouplevel}{\BODY}} \setlength\fboxrule{2\fboxrule} \fbox{\box{\linewidth- 0.1cm*\currentgrouplevel}{ \BODY }}} outer\ \def\tmp#1{*#1*}% \tmp{aa}\ inner\ \def\tmp#1{(#1)}\tmp{bb} 4

File I environ implementation This is the package. 1 \ProvidesPackage{environ}[2014/05/04 v0.3 A new way to define environments] 2 \RequirePackage{trimspaces} Change History v0.2 \NewEnviron: Added. 8 v0.3 \environbodyname: Works properly and now documented. 5 \RenewEnviron: Fixed for non-environ commands. 7 5 Begin \environbodyname \environfinalcode \longdef@c {#1}: control sequence Changes the control sequence used to represent the environment body in its definition. Not to be used as a user command; but maybe one day it will be. Don t change this after defining any \NewEnviron environments! 3 \def\environbodyname#1{\def\env@body{#1}} 4 \environbodyname\body {#1}: code This is the { code } that s executed by default at \end{ env. name }: 5 \def\environfinalcode#1{% 6 \def\env@finalcode{#1}} 7 \environfinalcode{\ignorespacesafterend} LATEX3-inspired shorthands. 8 \def\longdef@c#1{% 9 \expandafter\long\expandafter\def\csname#1\endcsname} 6 \collect@body-related code \collect@body Now, amsmath defines \collect@body for us. But that package may not be loaded, and we don t want to have to load the whole thing just for this one macro. 10 \unless\ifdefined\collect@body 11 \newtoks\@envbody 12 \def\collect@body#1{% 13 \@envbody{\expandafter#1\expandafter{\the\@envbody}}% 5

14 \edef\process@envbody{\the\@envbody\noexpand\end{\@currenvir}}% 15 \@envbody={}% 16 \def\begin@stack{b}% 17 \begingroup 18 \expandafter\let\csname\@currenvir\endcsname\collect@@body 19 \edef\process@envbody{% 20 \expandafter\noexpand\csname\@currenvir\endcsname}% 21 \process@envbody 22 } 23 \def\push@begins#1\begin#2{% 24 \ifx\end#2\else 25 b\expandafter\push@begins 26 \fi} 27 \def\addto@envbody#1{% 28 \global\@envbody\expandafter{\the\@envbody#1}} 29 \def\collect@@body#1\end#2{% 30 \edef\begin@stack{% 31 \push@begins#1\begin\end \expandafter\@gobble\begin@stack}% 32 \ifx\@empty\begin@stack 33 \endgroup 34 \@checkend{#2}% 35 \addto@envbody{#1}% 36 \else 37 \addto@envbody{#1\end{#2}}% 38 \fi 39 \process@envbody} 40 \fi \Collect@Body And now we define our own long version. 41 \long\def\collect@body#1{% 42 \@envbody{\expandafter#1\expandafter{\the\@envbody}}% 43 \edef\process@envbody{\the\@envbody\noexpand\end{\@currenvir}}% 44 \@envbody={}% 45 \def\begin@stack{b}% 46 \begingroup 47 \expandafter\let\csname\@currenvir\endcsname\collect@@body 48 \edef\process@envbody{% 49 \expandafter\noexpand\csname\@currenvir\endcsname}% 50 \process@envbody 51 } 52 \long\def\push@begins#1\begin#2{% 53 \ifx\end#2\else 54 b\expandafter\push@begins 55 \fi} 56 \long\def\addto@envbody#1{% 57 \global\@envbody\expandafter{\the\@envbody#1}} 58 \long\def\collect@@body#1\end#2{% 59 \edef\begin@stack{% 60 \Push@Begins#1\begin\end\expandafter\@gobble\begin@stack}% 6

61 \ifx\@empty\begin@stack 62 \endgroup 63 \@checkend{#2}% 64 \Addto@Envbody{#1}% 65 \else 66 \Addto@Envbody{#1\end{#2}}% 67 \fi 68 \process@envbody} 7 User-level syntax \RenewEnviron \NewEnviron This is the new one. 69 \def\newenviron{% 70 \let\env@newenvironment\newenvironment 71 \env@newenviron} 72 \def\renewenviron{% 73 \let\env@newenvironment\renewenvironment 74 \env@newenviron} Input argument sing 75 \def\env@newenviron#1{% 76 \@ifnextchar[ 77 {\env@new@i{#1}} 78 {\env@new@iii{#1}{}}} And the second: 79 \def\env@new@i#1[#2]{% 80 \@ifnextchar[ 81 {\env@new@ii{#1}[#2]} 82 {\env@new@iii{#1}{[#2]}}} And the second: (cont.) 83 \def\env@new@ii#1[#2][#3]{% 84 \env@new@iii{#1}{[#2][#3]}} The final optional argument: 85 \long\def\env@new@iii#1#2#3{% The first optional argument: 86 \@temptokena={\env@new{#1}{#2}{#3}}% 87 \@ifnextchar[{% 88 \the\@temptokena 89 }{% 90 \expandafter\the\expandafter 91 \@temptokena\expandafter[\env@finalcode]% 92 }} Environment creation code \env@new {#1}: name of the environment {#2}: possible optional args (either empty or [N] or [N][default] ) 7

{#3}: environment code [#4]: final code 93 \long\def\env@new#1#2#3[#4]{% Save the definition of \env@body so we know what to look for. 94 \longdef@c{env@#1@body\expandafter}\expandafter{\env@body}% Define the new environment to Collect its body and execute env@#1@se on it. 95 \env@newenvironment{#1}{% 96 \expandafter\collect@body\csname env@#1@se\endcsname 97 }{#4}% env@#1@se executes the body twice: the first time to save the body while ignoring the arguments; and the second time to process the environment definition itself while ignoring the environment body: 98 \longdef@c{env@#1@se}##1{% 99 \csname env@#1@save@env\endcsname##1\env@nil 100 \csname env@#1@process\endcsname##1\env@nil}% These must be defined on a per-environment basis in order to get the argument gobbling right: (because there are a variable number of arguments) 101 \expandafter\let\csname env@#1@save@env\endcsname\relax 102 \expandafter\let\csname env@#1@process\endcsname\relax 103 \expandafter\newcommand 104 \csname env@#1@save@env\endcsname#2{% 105 \expandafter\expandafter\expandafter 106 \env@save\csname env@#1@body\endcsname}% 107 \expandafter\newcommand 108 \csname env@#1@process\endcsname#2{#3\env@ignore}% 109 } \env@save If \env@body were variable, this macro would have to be saved for every environment definition individually; at the moment we just use a global definition. Use \trim@spaces to remove surrounding space: 110 \long\def\env@save#1#2\env@nil{% 111 \edef#1{% 112 \unexpanded\expandafter 113 \expandafter\expandafter{\trim@spaces{#2}}}} This is the same as a \@gobblenil but long and less likely to exist in the environment body: 114 \long\def\env@ignore#1\env@nil{} 8