Showing posts with label LaTeX. Show all posts
Showing posts with label LaTeX. Show all posts

Thursday, October 6, 2011

Latex listings definitions for modeling languages

Seems as if the Latex listings package does not let me go...

After blogging about how to nicely format listing with the Latex listings package, using a Eclipse syntax coloring style, and solving some tiny yet annoying problems with hyphenations of inline listings and labels within listings, I have compiled a couple of language definitions for (Eclipse) modeling languages.

Actually, these definitions are rather small, as they basically contain a list of keywords of a language. Besides the language definition, I usually define a command for quickly writing some inline listing code. I have explained this command in an earlier blog posting.

So, here are the definitions for QVT, ATL, ETL, Xtend, and Xtext.

QVT -- Query, View, Transformations

\lstdefinelanguage{QVT}{
  morekeywords={
% relations:  
   checkonly, domain, enforce, extends, implementedby, import, 
  key, overrides, primitive, query, relation, top, 
  transformation, when, where
% operational: 
 Bag, Collection, Dict, OrderedSet, Sequence, Set, Tuple, abstract, 
access, and, any, assert, blackbox, break, case, class, collect, 
collectNested, collectOne, collectselect, collectselectOne, 
composes, compute, configuration, constructor, continue, datatype, 
default, derived, disjuncts, do, elif, else, end, endif, 
enum, except, exists, extends, exception, false, forAll, forEach , 
forOne, from, helper, if, implies, import , in, inherits, init, 
inout, intermediate, invresolve, invresolveIn, invresolveone, 
invresolveoneIn , isUnique, iterate, late, let, library, literal, 
log, main, map, mapping, merges, metamodel, modeltype, new, not, 
null, object, one, or, ordered, out, package, population, primitive, property, 
query, raise, readonly, references, refines, reject, resolve, resolveIn, resolveone, 
resolveoneIn, return, select, selectOne, sortedBy, static, 
switch, tag, then, transformation, true, try, typedef, unlimited, 
uses, var, when, where, while, with, xcollect , xmap, xor, xselect 
 },
 keywordstyle=[2]{\textbf},
 morecomment=[l]{--},
 morestring=[b]{'},
 tabsize=4}
 
\newcommand{\lstQVT}[1]{\lstinline[language=QVT,breaklines=true,basicstyle=\listingsfontinline,mathescape,literate={\-}{}{0\discretionary{-}{}{}}]§#1§}

ATL -- Atlas Transformation Language

\lstdefinelanguage{ATL}{
  morekeywords={true,false,
   Bag,Set,OrderedSet,Sequence,Tuple,Integer,Real,Boolean,String,TupleType,
  not,and,or,xor,implies,module,create,from,uses,helper,def,context,
  rule,using,derived,to,mapsTo,distinct,
  foreach,in,do,if,then,else,endif,let,
  library,query,for,div,refining,entrypoint},
 keywordstyle=[2]{\textbf},
 morecomment=[l]{--},
 morestring=[b]{'},
 tabsize=4}
 
\newcommand{\lstATL}[1]{\lstinline[language=ATL,breaklines=true,basicstyle=\listingsfontinline,mathescape,literate={\-}{}{0\discretionary{-}{}{}}]§#1§}

ETL -- Epsilon Transformation Language

\lstdefinelanguage{ETL}{
  morekeywords={true,false,
   pre, rule, operation, 
  var, transform,to,
  select, selectOne, all,
  @greedy,
  for,if,else,
  not,and,or,
  Any,String,Boolean,
  true,false,return},
 keywordstyle=[2]{\textbf},
 morecomment=[l]{//}, 
 morecomment=[s]{/*}{*/}, 
 morestring=[b]",
 tabsize=4}
 
\newcommand{\lstETL}[1]{\lstinline[language=ETL,breaklines=true,basicstyle=\listingsfontinline,mathescape,literate={\-}{}{0\discretionary{-}{}{}}]§#1§}


Xtend 1.0.1

\lstdefinelanguage{Xtend}{
 morekeywords={cached,case,default,extension,false,import,JAVA,WORKFLOWSLOT,let,new,null,private,create,switch,this,true,reexport,around,if,then,else,context},
 keywordstyle=[2]{\textbf},
 morecomment=[l]{//}, 
 morecomment=[s]{/*}{*/}, 
 morestring=[b]",
 tabsize=4}
 
\newcommand{\lstXtend}[1]{\lstinline[breaklines=true,language=Xtend,basicstyle=\listingsfontinline,mathescape,literate={\-}{}{0\discretionary{-}{}{}}]\S#1\S}

Xtext 1.0.1

\lstdefinelanguage{Xtext}{
 morekeywords={grammar, with, hidden, generate, as, import, returns, current, terminal, enum},
 keywordstyle=[2]{\textbf},
 morecomment=[l]{//}, 
 morecomment=[s]{/*}{*/}, 
 morestring=[b]",
 tabsize=4}
 
\newcommand{\lstXtext}[1]{\lstinline[breaklines=true,language=Xtext,basicstyle=\listingsfontinline,mathescape,literate={\-}{}{0\discretionary{-}{}{}}]\S#1\S}

If you need a new language definition for your own Xtext based modeling or programming or domain specific or whatever language, it is very easy to retrieve the tokens of the language. Within the project of your Xtext grammar file, a special ANTLR file containing all the tokens will be generated. You will find that file in
src-gen//parser/antlr/internal/Internal.tokens

Xpand

[Updated February 2012] A friend of mine (thank you, Jens!) just sent me a new definition for Xpand:
\lstdefinelanguage{Xpand}{
 morekeywords={IMPORT, DEFINE, ENDDEFINE, LET, ENDLET, FOR, FILE, ENDFILE, ITERATOR, FOREACH, AS, IF, ENDFOREACH, ENDIF, EXPAND, INSTANCEOF, USING, SEPARATOR, CSTART, CEND, PROTECT, ENDPROTECT, ID, EXTENSION, ERROR, WARNING, INFO},
 inputencoding=latin1,
 extendedchars=true,
 % note: first and last guillemot of comments will not appear in comment style, guillemots are not possible in delimiters
 morecomment=[s]{REM}{ENDREM},
 morestring=[s]{"}{"},
 % for use with UTF-8
 literate={«}{\guillemotleft}{1}
          {»}{\guillemotright}{1}
}
This definition is a slight modification of the definitions posted in the Eclipse M2T forum (and also at the Rtsys Group Wiki, Uni Kiel) a while ago.

Monday, May 24, 2010

LaTeX: Listings and labels

I have blogged about the listing package here several times (nicely formatting, and hyphenations). This time I will write about creating labels inside a listing. First of all, the listing package allows to define a caption and a label for a listing, e.g.:
\begin{lstlisting}[caption={myListing},label={lst:myListing}]
void foo(int x) {
 doSomething();
 doMore();
}
\end{lstlisting}
Now the listing can be referenced via \ref{lst:myListing}. The listing package also nicely supports line numbers, there are a whole bunch of settings for that. But why do we need line numbers? In most cases, line numbers are used to refer to a certain line within a listing. E.g, we maybe want to write something like
In line 2 of the listing 1 we call method 'doSomething'.
Well, "listing 1" will look like "listing \ref{lst:myListing}" in the LaTeX source code, but how do we reference the line? Fortunately, the listing packages allows us to escape to latex inside a listing and add a label which can then be referenced:
\begin{lstlisting}[caption={myListing},label={lst:myListing},numbers=left,escapeinside={@}{@}]
void foo(int x) {
 @\label{lst:myListing_2}@doSomething();
 doMore();
}
\end{lstlisting}
Now we can reference the line: In line \ref{lst:myListing_2} ... Actually, you can use any label text, however I usually use the listings label with the line number or a small marker, in order to avoid conflicts with duplicate labels. As I do not want to write "line..." and "listing ..." over and over again, I use the autoref command from the hyperref package:
In \autoref{lst:myListing_2} of \autoref{lst:myListing}
autoref automatically adds a name to the reference counter. As there is no name defined for line numbers, it has to be defined previously:
\providecommand*{\lstnumberautorefname}{line} 
If you need names in a another language, you can add a translation:
\addto\extrasngerman{% 
\def\lstlistingautorefname{Quellcode}% 
\def\lstnumberautorefname{Zeile}% 
}
OK, we can add a line label and easily create a reference to that label. However, writing line labels means a lot of work, especially if you use a listing relative name pattern. So, let's add a macro to TeXShop, which uses some shell commands (mainly sed) and AppleScript in order to automatically create the label, even adding the line number to the label:
--Applescript direct
--
-- Create a label inside a listing, must be invoked at the position at which the label is
-- to be created.
-- Precondition: the listing is defined inside a lstlisting environment and 
--   a label is defined in the parameter list of the environment (label={..}).
--
-- New newly created label consists of the label of the listing with the line number
-- appended to the label. You can configure escape characters (as specified in
-- escapeinside={..}{..}) and the separator between listing label and line number.
--
-- E.g. label={myListing}, on line 5 leads to the following output:
-- @\label{lst: myListing!5}@
--
-- (C) 2010 Jens von Pilgrim, http://jevopi.blogspot.com

property texapp : "TeXShop"
property escapeLeft : "@"
property escapeRight : "@"
property separator : "_"
property maxLength : 2000

try
 tell application texapp
  
  if texapp = "TeXShop" then
   tell application "TeXShop" to set pos to the offset of the selection of the front document
   tell application "TeXShop" to set currentSelection to the content of the selection of the front document
  else if texapp = "iTeXMac" then
   -- ??
  end if
  
  set start to 1
  if (pos > maxLength) then
   set start to pos - maxLength
  end if
  
  set preceeding_text to (characters start thru pos of (the text of the front document)) as string
  set preceeding_text to my findAndReplace(preceeding_text, "\\", "_")
  
  set lineNumbers to do shell script ¬
   "echo " & the quoted form of preceeding_text & ¬
   "| sed -n '/label[:space:]*=[:space:]*{[^}]*}/=;$ {x;=;}'"
  
  
  
  set theLines to my splitLines(lineNumbers) -- as list
  set currentLine to last item of theLines as integer
  -- set startLine to item ((length of theLines) - 1) of theLines as integer
  -- length is not working when executed as macro... workaround:
  set startLine to first item of (rest of (reverse of theLines))
  
  set lstLine to currentLine - startLine
  
  set lastLabel to do shell script ¬
   "echo " & the quoted form of preceeding_text & ¬
   "| sed -n '/label[:space:]*=[:space:]*{[^}]*}/h;$ {x;p;}'" & ¬
   "| sed -n 's/.*label[:space:]*=[:space:]*{\\([^}]*\\)}.*/\\1/g;p'"
  
  set newSelection to escapeLeft & "\\label{" & lastLabel & separator & lstLine & "}" & escapeRight & currentSelection
  
  
  if texapp = "TeXShop" then
   tell application "TeXShop" to set the selection of the front document to newSelection
  else if texapp = "iTeXMac" then
   --tell application "iTeXMac" to insert new_section in the text of the front document
  end if
  
 end tell
on error errmesg number errn
 beep
 display dialog errmesg
 return
end try


on findAndReplace(strInString, strFind, strReplace)
 set ditd to text item delimiters
 set text item delimiters to strFind
 set textItems to text items of strInString
 set text item delimiters to strReplace
 if (class of strInString is string) then
  set res to textItems as string
 else -- if (class of TheString is Unicode text) then
  set res to textItems as Unicode text
 end if
 set text item delimiters to ditd
 return res
end findAndReplace


on splitLines(strInString)
 set ditd to text item delimiters
 set text item delimiters to "
"
 set textItems to text items of strInString
 set text item delimiters to ditd
 return textItems
end splitLines
Now things are really easy: Simply activate the macro at the appropriate location in the listing, and a new label will automatically be created. Note: The listing must have a label defined! You can configure the script by changing the properties at the beginning of the macro.

Tuesday, April 20, 2010

LaTeX: Lstinline and Hyphenations

I really like the LaTeX listing package. However, there is one serious problem: Hyphenations are not supported (Option breakline does not break words)! Fortunately I found a solution which is not 100% perfect, but almost (let's say 99% ;-) ). The idea is to use the replacement feature of listings in combination with the discretionary command. Actually, this is not my idea, its Andrei Alexandrescu's idea. I slightly modified his solution. So, here it is. Actually I define a new command for inline Java code -- you may do this using a style, but I prefer this one:
newcommand{\lstJava}[1]{%
\lstinline[language=Java,breaklines=true,mathescape,%
literate={\-}{}{0\discretionary{-}{}{}}]§#1§}
As '§' is rarely used in Java, I use this character as code delimiter in lstinline. Also, '$' is seldom found in Java code, so I activate mathescape by default as I use it from time to time (that is, more often then '$' in Java). Now, the trick is the literate option. It is used to replace a string in the code with another given string. So, the well known \- - command (telling LaTeX where to hyphenate a word) is replaced here! And it is replaced by the \discretionary command. This one tells LaTeX, how to hyphenate a word, which is especially useful in German writings, where "ck" becomes "k-k". We use this command here to output the hyphen only when necessary. With this command, hyphenation is working within lstinline -- however you will have to mark it manually.
Let's have a look at a rather long Java class, called \lstJava{ThisIsA\-VeryLong\-ClassName}.

Sunday, April 18, 2010

Create BibTeX Entry from Safari Document with BibDesk

I often have to reference webpages from my papers. I use bibtex and in order to reference a webpage I define a new bibtex entry of type webpage. Since I do not want to type in these entries manually, and thanks to BibDesk, a small applescript does the trick for me:
-- (C) 2010 Jens von Pilgrim
tell application "Safari"
 set theTitle to name of front document
 set theURL to URL of front document
end tell

set theDate to (year of (current date)) & "-"
set theMonth to (month of (current date)) * 1
if theMonth < 10 then
 set theDate to theDate & "0"
end if
set theDate to theDate & theMonth & "-"
set theDay to day of (current date)
if theDay < 10 then
 set theDate to theDate & "0"
end if
set theDate to (theDate & theDay) as text

display dialog "Key for webpage " & theTitle & ": " default answer ""
set dlgResult to result

if (button returned of dlgResult = "OK") then
 set theKey to text returned of dlgResult
 
 tell application "BibDesk"
  if (count of documents) = 0 then make new document
  
  tell document 1
   set newPub to make new publication at end of publications
   set type of newPub to "webpage"
   set cite key of newPub to theKey
   set the value of field "Key" of newPub to theKey
   set the value of field "Type" of newPub to "URL"
   set the value of field "Url" of newPub to theURL
   set the value of field "Lastchecked" of newPub to theDate
   set the value of field "Title" of newPub to "{" & theTitle & ", Project Website}"
   
   show newPub
  end tell
  
 end tell
end if
This script grabs the URL from the currently active Safari document and creates a new bibtex entry. Some field are automatically filled, including "Type" which is required by some styles I use.The script asks for the key of the new entry, as this cannot be determined automatically (at least, I don't want the script to make a false guess). I added the script to the BibDesk script folder (at ~/Library/Application Support/BibDesk/Scripts), so it is accessible from within BibDesk. Example: The script produces for http://bibdesk.sourceforge.net/ the following entry:
@webpage{BibDesk,
 Date-Added = {2010-04-18 13:40:38 +0200},
 Date-Modified = {2010-04-18 13:40:38 +0200},
 Key = {BibDesk},
 Lastchecked = {2010-04-18},
 Title = {{BibDesk, Project Website}},
 Type = {URL},
 Url = {http://bibdesk.sourceforge.net/}}

Convert Text to a (TeXShop) Convenient Label

TeXShop support smart selection of words. If you double-click a text, the whole word is selected. A word in TeXShop consists of the letters 'A/a' to 'Z/z' and underscores. Spaces and hyphen '-' are not interpreted as word but as whitespaces separating words. With BibDesk installed 1), you can press the F5 key within a \ref-command and a list will pop up with all the labels defined in your text.
If you want to quickly select a label in order to copy and paste it manually to a reference (e.g., if you do not use \ref but \autoref instead, the latter is not recognized as reference command by BibDesk), spaces and hyphens (and other punctuation characters) are really annoying as you cannot simply select the label using a double click. Even more annoying: If a label is selected from the proposal list (activiated via F5), only the label characters before the first space or punctuation character are pasted.
For that reason I do not use whitespaces or punctuation characters in labels. Since I do not want to convert all characters myself, I have added a new macro to TeXShop (with a nice shortkey on Cmd+'_') which does the trick:
--Applescript direct

-- Converts spaces and punctuation characters to underscores, useable for labels
-- (C) 2010 Jens von Pilgrim
tell application "TeXShop"
set snippet to the content of the selection of the front document
-- replace commands
set snippet to do shell script ¬
"echo " & the quoted form of snippet & ¬
" | sed -E 's/([[:space:]]|[[:punct:]])/_/g'"
set the selection of the front document to snippet
end tell
Note: In a previous posting, I published a macro creating section headers automatically. I have improved this macro in order to convert the whitespaces and punctuation characters in labels as well.
1)Thank you, Herb Schulz, for reminding me that it's BibDesk which adds the completion list to TeXShop ;-)

Tuesday, April 6, 2010

BBL to BIB with BibDesk

BibDesk manages my bibliography, just like iTunes manages my music. I have a single iTunes library, and I also have only a single master bibliography. However, when writing a paper, I want to create a new bib file with only the publications cited in the paper. BibTeX nicely creates a bibliographic reference file (*.bbl), but I want a bibliography file (*.bib) in order to be able to open the paper related publications with BibDesk. So, what I needed was a tool to convert the bbl file into a bib file. Fortunately, I found everything for that on my machine: AppleScript, grep, sed and, of course, BibDesk. I wrote a small script which simply creates a new bib file using a source bib file and a selected bbl file. Simply install the script listed below to your script folder (~/Library/Scripts) and name it "Create BIB from BBL.scpt" . Open your master bib file with BibDesk, then select a bbl file and activate the script(from the script menu in the menu bar). It will automatically create a new bib file in the folder of the bbl file, with the same name as the original bbl file (but with the extension bib).
-- Creates a new bib-file from an bbl-file using BibDesk -- (C) 2010 Jens von Pilgrim -- Version: 1.1, 20100615 tell application "Finder" set selectedItems to the selection end tell if ((count of selectedItems) = 0) then display dialog "Please select at least one bbl file" buttons {"OK"} return end if -- retrieve master bib file set sourceDoc to "" tell application "BibDesk" if (count of documents) = 0 then display dialog "Please open the source bibliography with BibDesk" buttons {"OK"} return end if if (count of documents) > 1 then set listOfNames to {} as list repeat with doc in documents set listOfNames to listOfNames & name of doc end repeat set selected to (choose from list listOfNames) as string repeat with i from 1 to the count of documents set doc to (item i of documents) set strDocName to name of doc as string if (strDocName is equal to selected) then set sourceDoc to document i log "source doc set" end if end repeat if sourceDoc is equal to "" then return end if else set sourceDoc to document 1 end if end tell -- log "copy items from master bib file" -- convert all selected bbl files repeat with theItem in selectedItems set theFile to theItem as alias set posixpath to POSIX path of theFile if (offset of ".bbl" in posixpath) > 0 then set destPosixpath to (my rename(posixpath, "bbl", "bib")) set destFile to POSIX file destPosixpath tell application "Finder" if (exists destFile) then set rep to display dialog "File " & destFile & " already exists. Overwrite?" buttons {"Yes", "No"} set skip to (button returned of rep = "No") else set skip to false end if end tell if (not skip) then -- log "examine bbl file " & quoted form of posixpath -- actually, this is the most important line: set allCites to do shell script "grep -E \"\\\\\\\\bibitem[:space:]*(\\[[^]]*\\])?[:space:]*{([^}]*)}\" " & (quoted form of posixpath) & " | sed -E \"s/\\\\\\\\bibitem[:space:]*(\\[[^]]*\\])?[:space:]*{([^}]*)}/\\2/\"" set numberOfItems to length of paragraphs of allCites if numberOfItems = 0 then display dialog "No bibitems found in " & posixpath & ", maybe the file does not contain any bibitems or the search pattern does not recognize your file format." buttons {"Too bad."} else set numberOfMissedItems to 0 set missedItems to "" tell application "BibDesk" set destDoc to make new document repeat with cite in paragraphs of allCites set bibs to search sourceDoc for cite set bFound to false repeat with bib in bibs set strFoundKey to cite key of bib as string set strCite to cite as string if strFoundKey is equal to strCite then -- log strCite & " found, add to new bib" set newBib to make new publication at end of publications of destDoc duplicate bib to newBib set bFound to true end if end repeat if not bFound then set numberOfMissedItems to numberOfMissedItems + 1 if (numberOfMissedItems > 1) then set missedItems to missedItems & ", " end if set missedItems to missedItems & cite end if end repeat save destDoc in destFile end tell if numberOfMissedItems > 0 then display dialog "Did not found " & numberOfMissedItems & " out of " & numberOfItems & " items: " & missedItems & "." buttons {"Uups"} end if end if end if else display dialog "Can only extract bib entries from BBL file, was " & posixpath end if end repeat -- this sub-routine just comes up with the new name on rename(item_name, item_ext, new_extension) set the trimmed_name to text 1 thru -((length of item_ext) + 2) of the item_name set target_name to (the trimmed_name & "." & new_extension) as string return the target_name end rename
If you don't have BibDesk, you might want to have a look at Michael Zhang's Perl Script. Instead of parsing the bbl file, Zhang's script parses the latex source. I prefer parsing the bbl file, as sometimes I use a whole bunch of latex sources, and BibTeX is quite good in gathering all citations into a single bbl file. You may also want to read the comments to Zhang's post for other solutions. If you don't have a master bib file, you may look at http://www.tex.ac.uk/cgi-bin/texfaq2html?label=makebib. There's a perl scrip provided reconstructing a bib file from a bbl file only. Update 2010-06-15: I updated the script as some BBL files were not recognized. If the script doesn't work, you may have a look at your BBL file. At the moment, the script searches for bibitems like "\bibitem{key}" or "\bibitem[abbr]{key}".

Tuesday, March 23, 2010

Nicely formatted listings in LaTeX with adjusted fonts

I'm using the listings package in order to get nicely formatted listings in latex. Since many people are used to the fonts and syntax highlighting of their IDE, I tried to emulate the layout and colors of code as it is formatted in Eclipse. Thanks to XeTeX, I'm able to simply change the font in listing as well. I use two fonts for listing paragraphs and inline:

\newfontfamily\listingsfont[Scale=0.7]{Courier} 
\newfontfamily\listingsfontinline[Scale=0.8]{Courier New} 
This enables bold fonts in typewriter, another way of solving this problem is to use LuxiMono, but I haven't tried that one. Then I define the colors Eclipse uses, comments are defined a little bit darker:

\usepackage{color}
\definecolor{sh_comment}{rgb}{0.12, 0.38, 0.18 } %adjusted, in Eclipse: {0.25, 0.42, 0.30 } = #3F6A4D
\definecolor{sh_keyword}{rgb}{0.37, 0.08, 0.25}  % #5F1441
\definecolor{sh_string}{rgb}{0.06, 0.10, 0.98} % #101AF9
Sometimes I need math text in listings, e.g. when writing pseudo code. Since I scaled the fonts down, the normal math fonts (displaystyle) are a little bit too large. One possible solution of resizing the math fonts would be to use \DeclareMathSizes, however I do not want to change the font for the whole document. The listings package provides two properties "escapebegin" and "escapeend", which are inserted before and after escaping to latex or math. However, simply using escapebegin={\ \scriptstyle} would cause errors when escaping not to math but to normal latex mode. In order to solve that problem, I define a custom command:

\def\lstsmallmath{\leavevmode\ifmmode \scriptstyle \else  \fi}
\def\lstsmallmathend{\leavevmode\ifmmode  \else  \fi}
Now I'm ready to define the overall style for listings:

\lstset {
 frame=shadowbox,
 rulesepcolor=\color{black},
 showspaces=false,showtabs=false,tabsize=2,
 numberstyle=\tiny,numbers=left,
 basicstyle= \listingsfont,
 stringstyle=\color{sh_string},
 keywordstyle = \color{sh_keyword}\bfseries,
 commentstyle=\color{sh_comment}\itshape,
 captionpos=b,
 xleftmargin=0.7cm, xrightmargin=0.5cm,
 lineskip=-0.3em,
 escapebegin={\lstsmallmath}, escapeend={\lstsmallmathend}
}
Comments are printed italic for black-white prints. In order to simplify the use of \lstinline, I define some commands for my favorite languages, e.g.,

\newcommand{\lstJava}[1]{\lstinline[language=Java,breaklines=true,basicstyle= \listingsfontinline]$#1$}

Example


%:lst:Test
\begin{lstlisting}[language=Java, caption={Just a test}, label={lst:Test}]
package de.jevopi;

/*
 * This is my class
 */
public class Test {

 public void foo(String s) {
  System.out.println("Hello " + s);
 }

}
\end{lstlisting}
will produce the following output (on the left). On the right, you can see the Eclipse version of the very same code snippet. (Click to enlarge images)

Thursday, March 4, 2010

Spell Checker, LaTeX, and OS X

Spell checking is a standard feature today. With LaTeX however it is not too easy to achieve. You can certainly use the build-in spell checker of OS X, but then you have to "proof read" all LaTeX commands and their parameters, which can be annoying. So I was looking for a better solution.

Because it was automatically installed I tried Excalibur. Frankly, I don't like it at all, but maybe I have missed something. It only offers very limited options. Unfortunately it doesn't support UTF-8. Since I'm using XeTeX wiht UTF-8, a spell checker w/o UTF-8 support is useless for me.

So I tried Aspell. If you look at the Aspell webpage, you'll get this "Linux users have to compile their application" feeling. There is a darwin port of aspell triggering a "Darwin users have to compile their application" feeling...

Fortunately, I eventually found CocoAspell. (Yes, well, there's a link to it on the TeXShop website ;-) ...) It comes with an installer, so you don't have to install XCode or Fink :-D. Best of all, it installs a system preference panel -- and that's really great! With this filter shown in the screenshot you can define LaTeX commands and if their arguments are to be spell checked. For example, the argument of \section{} is to be spell checked, while labels (\label{} ) are not to be spell checked. It comes with a list of predefined commands, and I added some commands, e.g., \autoref{} (as you can see in the screenshot).

You can find dictionaries at ftp://ftp.gnu.org/gnu/aspell/dict, before downloading them read the hints at cocoAspell's webpage.

I had some problems activating the Aspell dictionaries in TeXShop. Of course, you have to activate the dictionary in cocoAspell's prefernce panel. And I had to deactivate the "check spelling" box in the TeXShop preference, I don't know why. Spell checking is activated in TeXShops edit menu, I don't know what this preference setting is good for...

Well, spell checking a document for the first time usually means to add a lot of word to the dictionary. Sometimes, you want to edit this user dictionary (maybe because you added a word by mistake of because you want to add an existing list). The user dictionaries can be found at ~/Library/Spelling. These files are simple text files and you can open and edit these files with almost any editor. However, the words are separated with an usually invisible character, so you have to use an editor which can show invisible characters, such as SubEthaEdit (unfortunately, TeXShop cannot show these characters).

OK, now that we have a nice spell checker for LaTeX, we only have to change the language in "Spelling and Grammar". However, opening that tiny window requires a bunch of mouse clicks, and often we do not want to actually spell check but only change the dictionary. I found a small applescript at maxoxhints forum, and the version provided by Eponymous works for me. Eponymous' script could be added to the apple script menu and then will be available in all applications. Note: In order to make this script work, you have to activate "Enable access for assistive devices" in the "Universal Access" panel of the system preferences.


Tuesday, March 2, 2010

Create Section Headers with TexShop and Applescript

I really like the macro feature of TexShop. One of the most common use cases of macros would probably be the definition of a section (or subsection etc.). My section-creation-macro has been quite simple in the past:

% ----------------------------------------
% \section{#SEL##INS#}
% \label{sec:#SEL#}
% ----------------------------------------
This small snippet creates a nicely formatted section header including a label. However, there's a really annoying problem: When creating a reference to a section (that is, to its label), TeXShop does not handle spaces accordingly when selecting a label from the dropdown list. For example, if your label is something like \label{sec:Hello World}, the complete label is shown in the list, but only \ref{sec:Hello} is inserted into the text. In order to overcome this problem, I always replace spaces in labels with underscores. So my label would be "sec:Hello_World", and TeXShop is working perfectly. But replacing spaces with underscores by hand is even more annoying. So I replaced my section macro with an applescript version:

--Applescript direct

-- Create a section header from selected text. A label is automatically added with a prefix
-- "sec:", spaces are converted to underscores.
-- (C) 2010 Jens von Pilgrim

property level : "section"
property cmtchar : "-"
property cmtlength : 78
property labelprefix : "sec:"
-- property newline: "\n"
tell application "TeXShop"
 
 
 tell application "TeXShop" to set title to the content of the selection of the front document
 
 set new_title to title
 if ((count of the paragraphs of title) ≥ 1) then
  set this_line to paragraph 1 of title
  set label to this_line
  set add to "true"
  
  -- replace commands
  set label to do shell script ¬
   "echo " & the quoted form of label & ¬
   " | sed -E 's/([[:space:]]|[[:punct:]])/_/g'"
  
  set comment to "% "
  repeat with ii from 1 to cmtlength
   set comment to comment & cmtchar
  end repeat
  
  set new_title to ¬
   comment & return & ¬
   "\\" & level & "{" & title & "}" & return & ¬
   "\\label{" & labelprefix & label & "}" & return & ¬
   comment & return
 end if
 
 tell application "TeXShop" to set the selection of the front document to new_title
end tell
This macro creates a section just like the initial macro version, but this time spaces are automatically replaced in the label. That is, simply select your section title, activate the macro, and you get a nicley formatted title with a TeXShop compatible label. E.g. Mark
Hello World, this is great
and the macro will convert this to
% ==============================================================================
\section{Hello World, this is great}
\label{sec:Hello_World__this_is_great}
% ==============================================================================
You can easily adjust the macro in order to create subsection, subsubsections or chapters as well. I have different kind of comments for different section levels, all you have to change are the properties in the first line:

...
property level : "section"
property cmtchar : "-"
property cmtlength : 78
property labelprefix : "sec:"
...
Change level to "subsection" or whatever, and set the cmtchar to "*", "." or whatever you like. Changing a section level has already been subject of another blog post: Increase/Decrease Section Level with TeXShop Macros.

Sunday, September 20, 2009

Acronyms and LaTeX

Computer geeks like acronyms, especially three-letter acronyms (TLAs). To give you an impression: I'm working in the area of MDD. Actually, OMG calls it MDA, Stuart Kent MDE, and others MDSD. In short, models, such as UML or EMF models, are transformed into other models or code by M2M- or M2T-transformations, such as QVT or ATL. Writing a thesis in that area is really hard, since you have to keep an eye on all that TLAs. So I've looked for a LaTeX package doing the job for me, and what I found is a package called acronym by Tobias Oetiker. I really like the simplicity of this package, this is why I decided to use that instead of other alternative solutions.

Install acronym

Surprisingly, it was already installed with my tex installation (gwTeX), but it requires a packages called suffix, which was not. The later is contained in a bundle called bigfoot. Here are the CTAN locations of acronym and bigfoot: In order to install a package from the files available at CTAN, you usually have to
  • download the zip or all the files from CTAN
  • unzip them (or put them into a folder) and put the folder somewhere tex can find it, e.g. into $HOMETEXMF (i.e. ~/library/texmf/tex)
  • run the installer via latex *.ins, in that case latex bigfoot.tex
Now you are ready to use acronym. It is quite simple: simply include the package via
\usepackage{acronym}
Instead of simply writing the acronym in your text, you now have to write \ac{..} (or, in case of a plural, \acp{..}). You have to add a new environment with a list of all the acronyms and their long form with

\begin{acronym}
\arcro{..}{...}
\end{acronym}
The first time an acronym is used, \ac prints the long form with the acronym in brakets. There are also some other commands available, see the acronym documentation for details.

Add list of acronyms to table of contents

Unfortunately, there is no command available for adding an entry to the table of contents. I have written my own command for that, which creates an entry similar to the list of figures. You have to add the following code somewhere in your preamble:

\@ifundefined{listofacronymsname}{\newcommand{\listofacronymsname}{Acronyms}}{}
\@ifundefined{chapter}{%
\newcommand{\listofacronyms}{%
\section*{\listofacronymsname}%
\addcontentsline{toc}{section}{\listofacronymsname}%
\label{sec:acronyms}%
\markboth{\listofacronymsname}{\listofacronymsname}%
}}{%
\newcommand{\listofacronyms}{%
\chapter*{\listofacronymsname}%
\addcontentsline{toc}{chapter}{\listofacronymsname}%
\label{sec:acronyms}%
\markboth{\listofacronymsname}{\listofacronymsname}%
}}
It defines two commands:
\listofacronymsname
defines the name of the heading used for the list of acronyms. It is "Acronyms" by default, but you can change that with \renewcommand, as demonstrated below.
\listofacronyms
creates a heading and a section or chapter definition (depending on the document class), which is also added to the table of contents. A label "sec:acronyms" is added as well.
(Update 2012-05-21: \markboth adjusts the header accordingly, see mrunix thread)

Put it all together

Let's put it all together. Firstly, we use the package and define the \listofacronyms command:

\usepackage[printonlyused,smaller]{acronym}     % acronyms ac
\@ifundefined{listofacronymsname}{\newcommand{\listofacronymsname}{Acronyms}}{}
...
I have added some parameters to only list the used acronyms and use a slightly smaller font. Secondly, we create a new file "acronyms.text" with a list of the acronyms, which makes it easier to maintain. This is how my file looks like:

\renewcommand{\listofacronymsname}{Abkürzungsverzeichnis} % german title
\listofacronyms

% \acro{acronym}[shortname]{fullname}
% inside fullname: \acroextra{} -- not in text, only in description list
\begin{acronym}
\acro{EMF}{Eclipse Modeling Framework \cite{EMF}}
\acro{GEF}{Graphical Editing Framework \cite{GEF}}
\acro{MDD}{Model Driven Development}
\acro{MDA}{Model Driven Architecture}
\acro{UML}{Unified Modeling Language}
...
\end{acronym}
The acronyms are not sorted automatically, I use SubEthaEdit for sorting the acronyms from time to time, but I guess there are several editors which can do that. This file has to be included in your main latex source document, e.g.,

\begin{appendix}
\input{acronyms}
\end{appendix}
Last but not least, we have to use the acronym commands in the text, just like that:

I'm working in the area of \ac{MDD}. Actually, \ac{OMG} calls it \ac{MDA}, Stuart Kent \ac{MDE}. In short, models, such as \ac{UML} or \ac{EMF} models, ...
You do not have to look for the first usage of an acronym anymore, acronym is doing that for you. If you forget to define an acronym, you will see that in the generated output as acronym creates a bold placeholder in that case. If you do not want to printed the list of acronyms, you can use acronym just as described before, you only have to add a package option nolist (i.e. \usepackage[nolist]{acronym}). This is especially useful in combination with the option footnote, as in that case the description of the acronym is printed as a footnote and not in the text (and one can find the definitions by scanning the footnotes, which is ok for shorter texts). Thank you very much, Tobias Oetiker, for writing that package!

Thursday, July 16, 2009

Increase/Decrease Section Level with TeXShop Macros

TeXShop is a really nice editor, especially since new commands can be added using macros. These macros can contain AppleScript, which makes them very flexible and powerful. I like formating my headings in order to easily see sections, subsections etc. For that reason, I have added some macros creating sections etc. like this: Macro "section":

% ==============================================================================
\section{#SEL##INS#}
\label{sec:#SEL#}
% ==============================================================================
My latex code then looks like that:

% ******************************************************************************
\chapter{Chapter}
\label{chapter:Chapter}
% ******************************************************************************

% ==============================================================================
\section{Section}
\label{sec:Section}
% ==============================================================================

% ------------------------------------------------------------------------------
\subsection{SubSection}
\label{sec:SubSection}
% ------------------------------------------------------------------------------

% ..............................................................................
\subsubsection{SubSubSection}
\label{sec:SubSubSection}
% ..............................................................................

\paragraph{Paragraph}
This works pretty well. But it becomes very painful to change a section to a subsection, because I do not only want to change "section" to "subsection", but the comment lines as well. So I added two macros including AppleScript in order to decrease or increase the level of a section. I assume other people might find these macros useful, so I publish them here. They are written very quick and dirty, so you may have to adapt them to suit your preferences: Macro: "Decrease Section Level":

--Applescript direct

-- Decrease Section Level
--Select Section Block including Comments to decrease section level, i.e. section become subsection, chapter becomes section and so on

-- (C) 2009 Jens von Pilgrim

--THE SCRIPT:

property texapp : "TeXShop"
tell application texapp
 
 if texapp = "TeXShop" then
  tell application "TeXShop" to set section to the content of the selection of the front document
 else if texapp = "iTeXMac" then
  --tell application "iTeXMac" to set section to (the selection of the text of the front document)
 end if
 
 set new_section to ""
 repeat with ii from 1 to the count of the paragraphs of section
  
  set this_line to paragraph ii of section
  set new_line to this_line 
  set add to "true"

  -- replace commands
  if this_line contains "\\chapter" then
   set new_line to do shell script ¬
    "echo " & the quoted form of this_line & ¬
    " | sed 's/\\\\chapter/\\\\section/'"
  end if
  if this_line contains "\\section" then
   set new_line to do shell script ¬
    "echo " & the quoted form of this_line & ¬
    " | sed 's/\\\\section/\\\\subsection/'"
  end if
  if this_line contains "\\subsection" then
   set new_line to do shell script ¬
    "echo " & the quoted form of this_line & ¬
    " | sed 's/\\\\subsection/\\\\subsubsection/'"
  end if
  if this_line contains "\\subsubsection" then
   set new_line to do shell script ¬
    "echo " & the quoted form of this_line & ¬
    " | sed 's/\\\\subsubsection/\\\\paragraph/'"
  end if

  -- replace the comments
  if this_line contains "% ******************************************************************************" then
   set new_line to do shell script ¬
    "echo " & the quoted form of this_line & ¬
    " | sed 's/\\*/=/g'"
  end if
  if this_line contains "% ==============================================================================" then
   set new_line to do shell script ¬
    "echo " & the quoted form of this_line & ¬
    " | sed 's/=/-/g'"
  end if
  if this_line contains "% ------------------------------------------------------------------------------" then
   set new_line to do shell script ¬
    "echo " & the quoted form of this_line & ¬
    " | sed 's/-/\\./g'"
  end if
  if this_line contains "% .............................................................................." then
   set add to "false"
  end if

  if add="true" then
   if new_section = "" then
    set new_section to new_line
   else
    set new_section to new_section & return & new_line
   end if
  end if  
  
 end repeat
 
 if texapp = "TeXShop" then
  tell application "TeXShop" to set the selection of the front document to new_section
 else if texapp = "iTeXMac" then
  --tell application "iTeXMac" to insert new_section in the text of the front document
 end if
end tell
Macro: "Increase Section Level":

--Applescript direct

-- Increase Section Level
--Select Section Block including Comments to decrease section level, i.e. section become subsection, chapter becomes section and so on

-- (C) 2009 Jens von Pilgrim
--THE SCRIPT:

property texapp : "TeXShop"
tell application texapp
 
 if texapp = "TeXShop" then
  tell application "TeXShop" to set section to the content of the selection of the front document
 else if texapp = "iTeXMac" then
  --tell application "iTeXMac" to set section to (the selection of the text of the front document)
 end if
 
 set new_section to ""
 repeat with ii from 1 to the count of the paragraphs of section
  
  set this_line to paragraph ii of section
  set new_line to this_line 
  set add to "true"

  -- replace commands
  if this_line contains "\\section" then
   set new_line to do shell script ¬
    "echo " & the quoted form of this_line & ¬
    " | sed 's/\\\\section/\\\\chapter/'"
  end if
  if this_line contains "\\subsection" then
   set new_line to do shell script ¬
    "echo " & the quoted form of this_line & ¬
    " | sed 's/\\\\subsection/\\\\section/'"
  end if
  if this_line contains "\\subsubsection" then
   set new_line to do shell script ¬
    "echo " & the quoted form of this_line & ¬
    " | sed 's/\\\\subsubsection/\\\\subsection/'"
  end if
  if this_line contains "\\paragraph" then
   set new_line to do shell script ¬
    "echo " & the quoted form of this_line & ¬
    " | sed 's/\\\\paragraph/\\\\subsubsection/'"
   set new_line to "% .............................................................................." & return & new_line & return & "% .............................................................................."
  end if

  -- replace the comments
  if this_line contains "% ==============================================================================" then
   set new_line to do shell script ¬
    "echo " & the quoted form of this_line & ¬
    " | sed 's/=/\\*/g'"
  end if
  if this_line contains "% ------------------------------------------------------------------------------" then
   set new_line to do shell script ¬
    "echo " & the quoted form of this_line & ¬
    " | sed 's/-/=/g'"
  end if
  if this_line contains "% .............................................................................." then
   set new_line to do shell script ¬
    "echo " & the quoted form of this_line & ¬
    " | sed 's/\\./-/g'"

  end if

  if add="true" then
   if new_section = "" then
    set new_section to new_line
   else
    set new_section to new_section & return & new_line
   end if
  end if  
  
 end repeat
 
 if texapp = "TeXShop" then
  tell application "TeXShop" to set the selection of the front document to new_section
 else if texapp = "iTeXMac" then
  --tell application "iTeXMac" to insert new_section in the text of the front document
 end if
 
end tell
These two macros increase or decrease the level of a section. You have to simply select a section (or several sections), and the levels of all chapters, sections, and paragraphs are increased or decreased respectively. Besides the commands, the comments are reformatted as well. When increasing the levels, the following modifications are made:
  1. section -> chapter
  2. subsection -> section
  3. subsubsection -> subsection
  4. paragraph -> subsubsection
When decreasing the levels, the following modifications are made:
  1. chapter -> section
  2. section -> subsection
  3. subsection -> subsubsection
  4. subsubsection -> paragraph
Note that chapters are not increased any further, and paragraphs are not decreased.

Wednesday, July 15, 2009

How to write very long documents with LaTeX

I eventually started writing my thesis--with LaTeX. Since it will become a rather long document (approx. 200 pages) I decided to split the document into its chapters (and maybe into more parts). Splitting a document is very easy with latex and it typically looks like that:

\documentclass{someClass}
... some definitions, use packages etc ...
\begin{document}
...
\maketitle
...
\input{abstract}
\input{introduction}
...
\input{relatedwork}
\input{conclusion}
...
\end{document}
This works pretty well, and I always use this pattern for writing smaller papers. Unfortunately I found two severe problems:
  1. The latex compiler is unaware of folders.
  2. I cannot compile the parts separately, which leads to new problems

Chapterfolder

The first problem is further described and solved by the latex package "chapterfolder". Instead of simply including a chapter, it is included and the current folder is changed accordingly. The main file will now look like this:

...
\begin{document}
...
\maketitle
...
\cfchapter{Introduction}{chapters/introduction}{introduction.tex}
...
\cfchapter{Conclusion}{chapters/conclusion}{conclusion.tex}
In my case I can now use chapter-relative figure folders, i.e. my folder structure looks like that:

/Main
- main.tex
+ chapters
 + introduction
     - introduction.tex
     + fig
         - figOfChapter1.png
+ conclusion
     - conclusion.tex
     + fig
         - figOfChapter2.png
Without "chapterfolder", I had to include a figure in chapter 1 (Introduction) like this:
\includegraphics{chapters/introduction/fig/figOfChapter1}
However, I want to be able to simply include figures by specifying a relative path to the chapter document, that is
\includegraphics{fig/figOfChapter1}
In order to achieve, this, we have to rewrite the includegraphics command. We can do that in the preamble, next to the usepackage statement:
\usepackage{chapterfolder}
% and we re-write includegraphics
\let\includegraphicsWithoutCF\includegraphics
\renewcommand{\includegraphics}[2][]{\includegraphicsWithoutCF[#1]{\cfcurrentfolder#2}}
This makes life much easier, especially if figures are moved from one chapter to another (I have only to move the file of the figure and can simply copy the code). And we are also able of compiling documents separately, as explained further on!

Compile Separately and Embedded

Although I'm using a wonderful LaTeX editor (Texshop) and my computer is pretty fast, working with a split document has some tradeoffs:
  1. The "goto error" function in my editor is not working with included documents, which makes bug fixing really annoying.
  2. Compiling a (currently) 100 page long document with lots of images takes quite some time
For that reason, I tried to figure out how to split my document and use a main file including all parts, while at the same time the parts could be compiled standalone. Here is my solution: In the main file, I define a command for letting the included files know that they are embedded:

\newcommand{\isEmbedded}{true}
In my parts (chapters), I can now test whether this command is defined or not, and include a preamble if required:

\ifx\isEmbedded\undefined
..
\documentclass{../../styles/myStyle}
..
other settings
...
\begin{document}
\maketitle
...
% -------+---------+---------+---------+---------+---------+---------+---------+
\else
\fi
% ******************************************************************************

Here comes the text of the chapter or part.

% ******************************************************************************
\ifx\isEmbedded\undefined
\bibliography{myBib}
...
\end{document}
\else
\fi
I can now compile every chapter separately, and finding a bug is very simple thanks to Texshops "Goto Error" function -- which is now working. Without any modifications, I can also compile the whole text, i.e. my main.tex file.

Tuesday, November 6, 2007

Merge PDF documents with LaTeX

Sometimes, a single book comes in multiple PDF documents, one document for a chapter. I often want to merge these PDF document into one single document. There are several possibilites, e.g. using Adobe Acrobat. A less expensive and yet easy solution is to use LaTeX for that purpose. So I have created a simple LaTeX template in which I only have to add the names of the documents to be merged., that's it. Besides, several options are available such as scaling the documents on the fly. The work is done by the LaTex package "pdfpages", see pdfpages at www.ctan.org. The documents are included with \includepdf, the two lines above this command are used here for creating a table of content in the PDF.

%!TEX encoding = UTF-8 Unicode
% -------+---------+---------+---------+---------+---------+---------+---------+
\documentclass{book}
% -------+---------+---------+---------+---------+---------+---------+---------+
% Used Packages
% -------+---------+---------+---------+---------+---------+---------+---------+
\usepackage[pdftex,dvips]{graphicx}
\usepackage[english]{babel}
\usepackage[
 pdfhighlight=/O, colorlinks, linkcolor=black, urlcolor=black, citecolor=black,
 breaklinks, bookmarksopen,bookmarksopenlevel=1,linktocpage
] {hyperref}
\usepackage{fancyhdr}
\usepackage{pdfpages} % That does the trick!
% -------+---------+---------+---------+---------+---------+---------+---------+
% Header
% -------+---------+---------+---------+---------+---------+---------+---------+
\pagestyle{headings}
\pagestyle{fancy}
\fancyhead{}
\fancyfoot{}
%\fancyfoot[LE,RO]{\raisebox{-25mm}{\large\textsf{\thepage}}}
%\fancyfoot[RE,LO]{\raisebox{-25mm}{Merged Document}}
%\fancyfoot[CE,CO]{\raisebox{-25mm}{}}
\renewcommand{\headrulewidth}{0mm}
\renewcommand{\footrulewidth}{0mm}
% -------+---------+---------+---------+---------+---------+---------+---------+
% Settings for including the PDF documents,
% see: 
% http://www.ctan.org/tex-archive/macros/latex/contrib/pdfpages/pdfpages.pdf
% -------+---------+---------+---------+---------+---------+---------+---------+
\includepdfset{pages=-,nup=1x1, pagecommand={\mbox{}}}
% -------+---------+---------+---------+---------+---------+---------+---------+
% The Documents
% -------+---------+---------+---------+---------+---------+---------+---------+
\begin{document}

\phantomsection 
\addcontentsline{toc}{chapter}{Chapter 1}
\includepdf{file1.pdf}

\phantomsection 
\addcontentsline{toc}{chapter}{Chapter 2}
\includepdf{file2.pdf}

% ...

% -------+---------+---------+---------+---------+---------+---------+---------+
\end{document}