Building Skia library on Linux with Waf

I wanted to try Skia, the 2D graphic library from Google. The problem is: there's still no mature build script for linux and the samples are not compiled at all. So I patched some sources and wrote a simple build script for Waf, which in the end will build the skia library (as shared object) and the demo executable.

What is Waf? It is a python based framework that allows you to write "configure" like scripts, without the hassle of learning autotools and m4. I will show you the basics and what it takes to write from scratch a project build script. I assume you will be using Ubuntu 9.04.

So, first off: check out the skia sources, using the following command:

svn checkout http://skia.googlecode.com/svn/trunk/ skia-read-only -r 501

The revision 501 (on which I generated my patch file) will be downloaded.

Next, download this patch: skia.patch.gz and save somewhere on your system. It contains the modifications (hacks, actually) I did to have the demo compiled. After that, enter the directory skia-read-only and issue the command

zcat /path/to/skia.patch.gz | patch -p1

The patches will be applied and the waf build script, wscript, will be added. Open it and take a look. It starts like this:

  1. #! /usr/bin/env python
  2. # -*- coding: utf-8 -*-
  3.  
  4. ports = """
  5.  src/ports/SkDebug_stdio.cpp                                                                                                                    
  6.  src/ports/SkGlobals_global.cpp                                                                                                                      
  7.  src/ports/SkOSFile_stdio.cpp                                                                                                                      
  8.  src/ports/SkThread_pthread.cpp                                                                                                                    
  9.  src/ports/SkTime_Unix.cpp
  10.  src/ports/SkFontHost_linux.cpp
  11.  src/ports/SkFontHost_gamma_none.cpp
  12.  src/ports/SkFontHost_FreeType.cpp
  13.  src/ports/SkFontHost_FreeType_Subpixel.cpp
  14.  src/ports/SkFontHost_tables.cpp
  15.  src/ports/SkXMLParser_empty.cpp
  16. """.split()
  17.  
  18. opts = """
  19.  src/opts/SkBlitRow_opts_none.cpp                                                                                                                
  20.  src/opts/SkBitmapProcState_opts_none.cpp                                                                                                        
  21.  src/opts/SkUtils_opts_none.cpp                                                                                                                  
  22. """.split()
  23.  
  24. xml = """
  25.  src/xml/SkDOM.cpp
  26.  src/xml/SkXMLParser.cpp
  27.  src/xml/SkXMLWriter.cpp
  28. """.split()
  29.  
  30. defines = """
  31.  GL_GLEXT_PROTOTYPES
  32.  SK_SUPPORT_LCDTEXT
  33.  SK_CAN_USE_FLOAT
  34.  SK_SCALAR_IS_FLOAT
  35.  SK_DEBUG
  36.  SK_SUPPORT_UNIT
  37.  SK_BUILD_FOR_UNIX
  38. """.split()
  39.  
  40. includes = """
  41.  src/core
  42.  include/config
  43.  include/core
  44.  include/effects
  45.  include/images
  46.  include/utils
  47.  include/views
  48.  include/xml
  49.  include/animator
  50. """.split()

Well, I just defined few lists. The first three: ports, opts and xml are the files I would like to be compiled in addition to all the other files sitting in few other subdirectories. With waf several approachs are possible: you can list all of your files to compile, or you can specify just the directories and let waf pick all the sources, or you can mix and match (as I did). Or you can put a wscript in each sub dir and create a hierarchy of wscript files, each one taking care of one piece of the build. This is what I like of waf: it does not enforce you doing only in a certain way - supposedly for your own sake - but let you decide. You may make a mess but we are adults and we don't like the maven approach. But I digress... So, take a look at the second part of the script:

  1. def configure(conf):
  2.  
  3.    # check gnu compiler
  4.    conf.check_tool('g++')
  5.  
  6.    # check freetype library
  7.    conf.check_cfg(package='freetype2', atleast_version='6.3', uselib_store='freetype', args='--cflags --libs', mandatory=1)
  8.  
  9.    # check the sdl library
  10.    conf.check_cfg(package='sdl', atleast_version='1.2', uselib_store='sdl', args='--cflags --libs', mandatory=1)
  11.  
  12.    # check the opengl library
  13.    conf.check_cfg(package='gl', atleast_version='7.6', uselib_store='gl', args='--cflags --libs', mandatory=1)
  14.  
  15.    # check the png library
  16.    conf.check_cfg(package='libpng', atleast_version='1.2.37', uselib_store='png', args='--cflags --libs', mandatory=1)
  17.  
  18.    # check libgif
  19.    conf.check(lib='gif',  uselib_store='gif', mandatory=True)
  20.  
  21.    # check libgif
  22.    conf.check(lib='jpeg', uselib_store='jpeg', mandatory=True)
  23.  
  24.    # compilation flags
  25.    conf.env.CXXFLAGS = ['-g', '-w', '-msse2' ]

In waf if you want to check for libraries, tools, headers and so, you define a function called configure. It takes one parameter, which is a sort of context constructed by waf, exposing some functions. You call them to have waf doing the checks for you. For example, at line 4, I check if the c++ compiler is installed. At line 7, I check for the freetype library writing

conf.check_cfg(package='freetype2',
               atleast_version='6.3',
               args='--cflags --libs',
               uselib_store='freetype',
               mandatory=1)


The check_cfg checks the libraries using the pkg-config tool, so basically it instructs waf to look into the PKG_CONFIG_PATH list of directories, searching in this case for freetype2.pc. Waf will check the version of the library to see if it equal or greater than 6.3. It stores the values for --cflags and --libs in the waf cache under the key 'freetype' (the key will allow you to reference the library somewhere else in the script) and, finally, waf will abort if the library is not found, because I've marked it as mandatory.

In the same way I check for other libraries at the lines 10, 13, 16. At line 19 and 22 I don't use the check_cfg but simply check because the libraries gif and jpeg are not shipped with a pkg-config file. Finally, at line 25 I just set up the compilation flags for both the skia and the executable. There are other ways to do so, and you can check the waf manual and its samples if you're curious.

For the build phase we have to define the function build. As for the configure fuction, the parameter passed by waf is the context. Now, in this function you should declare how your targets should be built. To do so you have to create a task generator. The task generator is able to generate the task (d'oh!) that will be performed by waf. In creating the task generator, you can specify everything about your target. Let's take a look

  1. def build(bld):
  2.  
  3.    # ========================================
  4.    #       Build skia library
  5.    # ========================================
  6.    obj = bld(
  7.       features = 'cxx cshlib',
  8.       target = 'skia',
  9.       defines = defines,
  10.       includes = includes,
  11.       export_incdirs = includes,
  12.       uselib = 'freetype gif jpeg gl'  )
  13.  
  14.    # add the files to the list of sources to compile
  15.    obj.find_sources_in_dirs('src/core src/effects src/utils src/images src/views src/animator src/gl')
  16.  
  17.    # skip the files we don't have to compile
  18.    obj.source.remove('src/core/SkDrawing.cpp')
  19.    obj.source.remove('src/images/SkImageDecoder_libpvjpeg.cpp')
  20.    obj.source.remove('src/images/SkImageDecoder_fpdfemb.cpp')
  21.    obj.source.remove('src/animator/SkAnimatorScript2.cpp')
  22.  
  23.    # add the other sources for the linux port
  24.    obj.source.extend(ports)                                                                                                                      
  25.    
  26.    # add the other optional sources
  27.    obj.source.extend(opts)                                                                                                                      
  28.  
  29.    # add the xml stuff
  30.    obj.source.extend(xml)

At line 6 I create the task generator using the shortcut offered by the context (in this case named bld). At line 7 I set the task generator to generate the target as shared library (cshlib) using c++ compiler to build it (cxx). At line 8 I want the library to be called "skia". At line 9 I specify the defines to use, in this case I use the list "defines" declared previously. At line 10 I set up the list of include dirs and at line 11 I instruct waf to export the same includes list. At line 12 I simply list the prerequisite libraries needed by skia. In listing the prerequisite I just use the keys chosen in the configure phase. The task generator is still not completed. At line 15 I set the generator to look into a set of directories for the sources. At line 18-21 I removed certain files from the set of sources. Finally, at line 24, 27, 30 I add other sources file to the list. Well, that's all. The generator will create a task able to compile the library.

For the demo executable, also within the build fuction, I create another task generator:

  1. # ========================================
  2.    #       Build the demo application
  3.    # ========================================
  4.    exe = bld(
  5.       features = 'cxx cprogram',
  6.       uselib = 'freetype sdl gl gif jpeg png',
  7.       uselib_local = 'skia',
  8.       defines = defines,
  9.       target = 'demo')
  10.  
  11.    exe.find_sources_in_dirs( 'samplecode')  
  12.    exe.source.append('src/utils/SDL/SkOSWindow_SDL.cpp')
  13.    exe.source.append('xcode/sampleapp_sdl/skia_sdl_main.cpp')
  14.  
  15.    # remove the samples that don't work
  16.    exe.source.remove('samplecode/SampleText.cpp')    
  17.    exe.source.remove('samplecode/SampleTypeface.cpp')  
  18.    exe.source.remove('samplecode/SampleFontScalerTest.cpp')  
  19.    exe.source.remove('samplecode/SampleGM.cpp')
  20.    exe.source.remove('samplecode/SampleTests.cpp')
  21.    exe.source.remove('samplecode/SamplePolyToPoly.cpp')
  22.    exe.source.remove('samplecode/SampleDecode.cpp')
  23.    exe.source.remove('samplecode/SampleEncode.cpp')
  24.    exe.source.remove('samplecode/SampleWarp.cpp')

It works more or less like the first generator. At line 7 I use the uselib_local instead of uselib because skia is generated by the same script and not found on the system as external dependency. Again, I add all the sources found in the samplecode directory and then I adjust the list cherry-picking and removing few more files.

Time to run the script

To run the script you need the waf engine, which is a singular file named waf you have to store in your project directory. So, let's grab waf here

http://waf.googlecode.com/files/waf-1.5.11.tar.bz2

Explode the tar somewhere and fire the ./configure script. If all goes well the waf script is generated. So, copy it into the skia-read-only directory.

Now we are ready to configure and compile skia! Enter the skia-read-only dir and issue the command

./waf configure

The project will be configured. Probably you will get some warnings due to the missing requirements. Here's the command to install them in one shot:

sudo apt-get install libgl1-mesa-dev libfreetype6-dev libsdl1.2-dev libpng12-dev libgif-dev libjpeg62-dev ttf-mscorefonts-installer

Now, again ./waf configure and this time you should get something like that:

waf configure

Time to compile skia library and the demo application. You just issue the following command

./waf

If you want, you can specify the number of parallel jobs to spawn. And you can enable the progress bar too:

./waf -j3 -p

You will see the compilation process rolling out.

waf compile

If all goes well you will find in skia-read-only/build/default the libskia.so shared library and the demo executable.

To run the demo application, first set

export LD_LIBRARY_PATH=/path/to/skia-read-only/build/default

Then run the demo. Once it started you can switch from a view to the other using the right-arrow. Hereafter some samples

demo0
demo1
demo2
demo3
demo4
demo5

Some demos don't work perfectly, like the ones that should show a picture. The pictures are not there and the paths are hardcoded. But you can hack your way around and do some experiments. Enjoy!

Cover letter with style - part six

This is the sixth part of the tutorial Cover letter with style. You can find the fifth part here.

In this part I will show you how to add a barcode in the destination address. It's a kind of nerdy, but it will serve to illustrate how to do graphics stuff easily with XeLaTex. For the purpose, you have to install pstricks and let Xe(La)Tex know about it.

Installing pstricks is very easy on ubuntu: just open a terminal and issue the command:

sudo apt-get install texlive-pstricks

Then, we need to inform Xe(La)Tex where to find the pstricks configuration file for the xdvipdfmx driver (this is the driver XeLaTex uses to output your pdf). To do so, first create a couple of directories

mkdir -p /usr/share/texmf-texlive/tex/xetex/xetex-pstricks/
mkdir -p /usr/share/texmf-texlive/tex/xelatex/xetex-pstricks/

Then you need to copy this pstricks.con file in those directories. You need also to copy this xdvipdfmx.con file in

/usr/share/texmf-texlive/tex/generic/pstricks

To finish, run

sudo texhash

All this, to have graphics in your pdf's in just one go, through XeLaTex. For those who are not fully aware of the problem, I just saved you from this mess:

mess

Consider also that the above instructions are done once for all. After this setup, we are ready to use pstricks packages.

So, for drawing a barcode we can use pst-barcode. It is pretty easy to use and its documentation says it all.

This time, instead of changing the template file (standard.lco, remember?) I will change the letter itself, because the destination address is in there. So here it is the letter with the barcode added

  1. \documentclass[standard]{scrlttr2}
  2.  
  3. \usepackage{pst-barcode}
  4.  
  5. \begin{document}
  6.  
  7. \begin{letter}{%
  8.        Damage Inc. --- HR Dept.\\%
  9.        Paulus Potterstraat 134\\%
  10.        1753KJ Amsterdam\\%
  11.        \psbarcode{1234567}{}{royalmail}
  12. }
  13. \setkomavar{subject}{Cover Letter}
  14. \opening{Dear Recruiter,}
  15.  
  16. My name is Iulius Caesar bla bla bla...
  17.  
  18. \closing{Regards}
  19.  
  20.  
  21. \end{letter}
  22. \end{document}

At line 3 I import the package and at line 11 I specify a royalmail barcode, coding the number 1234567 (just an example). If you typeset the document, you will obtain this

bar1

Cool, isnt' it? Further, we can adjust the barcode position, specifing the optional parameters, transx and transy

\psbarcode[transy=-0.2cm,transx=0.1cm]{1234567}{}{royalmail}

The result now is

bar2

The entire cover letter, finally, appears like that

step7

Well, it was a long journey but now we got a stylish cover letter to show off. I hope you like it.

I am still not done! I have to show one thing more: an alternative template you can use to completely change the look and feel of your cover letter. Keeping the template separated from the content permits us to easily swap style as changing one line only.

First of all, I will provide you a new template.

  1. \ProvidesFile{alternate.lco}[%
  2.   2002/07/09 v0.9a LaTeX2e unsupported letter-class-option]
  3.  
  4. \usepackage{fontspec}
  5. \usepackage{xltxtra}
  6. \usepackage{marvosym}
  7. \usepackage{graphicx}
  8. \usepackage[dvipdfm]{geometry}
  9.  
  10. % ==============================================
  11. %  PERSONAL DATA
  12. % ==============================================
  13. \setkomavar{fromname}{Iulius Caesar}
  14. \setkomavar{fromaddress}{Van Eeghenlaan 69\\1691QT Amsterdam\\Nederland}
  15. \setkomavar{fromphone}{+31 (0)22 7394203}
  16. \setkomavar{fromemail}{iulius@gmail.com}
  17. \setkomavar{fromfax}{+31 (0)71 5144543}
  18. \setkomavar{fromurl}{http://stefano.italians.nl}
  19. \setkomavar{frombank}{Postbank 9307157}
  20. \setkomavar{place}{Amsterdam}
  21. \setkomavar{signature}{Iulius Caesar}
  22. \setkomavar{fromlogo}{\includegraphics[width=3cm]{sample_logo.eps}}
  23.  
  24. % DIN standard
  25. %\LoadLetterOption{DINmtext}
  26.  
  27.  
  28. % ==============================================
  29. %  FORMATTING STUFF
  30. % ==============================================
  31.  
  32. % === font settings
  33. \defaultfontfeatures{Mapping=tex-text}
  34. \setmainfont {Adobe Garamond Pro}
  35. \setsansfont {Gill Sans Std}
  36.  
  37.  
  38. % shift the page body on the left to make room for
  39. % our data and logo
  40. \setlength{\oddsidemargin}{\useplength{toaddrhpos}}%
  41. \addtolength{\oddsidemargin}{-1in}%
  42. % Take care that the shift stays intact even after recalculating the page
  43. % layout (see Kohm & Morawski 2005, section C.7)
  44. \l@addto@macro{\@typearea@end}{%
  45.   \setlength{\oddsidemargin}{\useplength{toaddrhpos}}%
  46.   \addtolength{\oddsidemargin}{-1in}%
  47. }
  48.  
  49.  
  50. % setup some lenghts
  51. \@setplength{firstheadvpos}{0pt}%
  52. \@setplength{firstheadwidth}{\paperwidth}%
  53. \@setplength{firstfootvpos}{\paperheight}%
  54. \@addtoplength[-]{firstfootvpos}{\useplength{toaddrvpos}}%
  55. \@addtoplength{refvpos}{-1.5\baselineskip}%
  56. \@newplength{infocolwidth}%
  57. % Kohm & Morawski 2005, C.7. Modifikationen (Modifications)
  58. \ifdim \textwidth<0.666\paperwidth
  59.   \@setplength{infocolwidth}{.22222\paperwidth}%
  60. \else
  61.   \@setplength{infocolwidth}{0.1667\paperwidth}%
  62. \fi
  63.  
  64. % define new variable company
  65. \newkomavar{company}%
  66. \setkomavar{company}{Initech}
  67.  
  68.  
  69. % fancy header for the first page
  70. \firsthead{%
  71.   \fontsize{8}{9}\sffamily
  72.   \hspace*{\fill}%
  73.   \begin{picture}(0,0)%
  74.     \put(0,0){\parbox[t]{\useplength{infocolwidth}}{%
  75.         \vspace{\useplength{toaddrvpos}}%
  76.         \usekomavar{fromlogo}%
  77.       }%
  78.     }%
  79.     \put(0,0){\parbox[t]{\useplength{infocolwidth}}{%
  80.         \raggedright
  81.         \vspace{\useplength{refvpos}}%
  82.         \vspace{\useplength{refaftervskip}}%
  83.         \usekomavar{place}\usekomavar{placeseparator}\\
  84.         \usekomavar{date}\\[10\baselineskip]
  85.         \usekomavar{fromname}
  86.         \ifkomavarempty{company}{}{%
  87.           \\
  88.           \usekomavar{company}%
  89.         }\\[\baselineskip]
  90.         \usekomavar{fromaddress}\\
  91.         \usekomavar*{fromphone}\usekomavar{fromphone}\\
  92.         \usekomavar*{fromfax}\usekomavar{fromfax}%
  93.         \\[\baselineskip]
  94.         \usekomavar{fromemail}\\
  95.         \usekomavar{fromurl}
  96.       }%
  97.     }%
  98.   \end{picture}%
  99.   \hspace*{\useplength{infocolwidth}}%
  100. }%
  101.  
  102. % avoid the display of the date in the default position
  103. \l@addto@macro\@firstheadfootfield{\setkomavar{date}{}}
  104.  
  105. \endinput

I won't explain the details. Moreover, this template was not created by me: I just copied (and somewhat simplified) the template shown in this document [Replacing LATEX2# standard classes with KOMA-Script by Yuri Robbers, Markus Kohm and Rasmus Pank Roulund].

Save the above template in alternate.lco file. Also, check the line 22, where the name of your logo should be specified. Now take your cover letter and in the first line specifiy you want to use this alternative template, like this

  1. \documentclass[alternate]{scrlttr2}
  2.  
  3. \usepackage{pst-barcode}
  4.  
  5. \begin{document}
  6.  
  7. \begin{letter}{%
  8.        Damage Inc. --- HR Dept.\\%
  9.        Paulus Potterstraat 134\\%
  10.        1753KJ Amsterdam
  11.        \psbarcode{1234567}{}{royalmail}
  12. }
  13. \setkomavar{subject}{Cover Letter}
  14. \opening{Dear Recruiter,}
  15.  
  16. My name is Iulius Caesar bla bla bla...
  17.  
  18. \closing{Regards}
  19.  
  20.  
  21. \end{letter}
  22. \end{document}

That's all. I just changed the first line, instructing KOMA-Script to load the alternate file (no need to specify the .lco extension). If you typeset the document, your cover letter now will look like this

alternate

Mind that the logo was not the one I used in the previous part. I edited it to have the outlines in stronger colors (it has to be in the foreground, this time)

So, I hope you enjoyed the tutorial. And I hope you can sport those cover letters in the next job application; maybe they will give you more points, who knows....

See you in seven years

Cover letter with style - part five

This is the fifth part of the tutorial Cover letter with style. You can find the fourth part here.

In this part I will show you how to add your logo as a watermark to your cover letter1

Ok, ready to go. Well...almost: you need a logo. For this time, I will provide one (Save link as...) so you can proceed with the tutorial. It is a simple vectorial image, edited with Inkscape. If you don't have Inkscape installed, you already know what to do:

sudo apt-get install inkscape

Actually, if you are able to, I suggest to compile and install Inkscape from the svn sources, but it is not mandatory.

Another thing you need is to install a couple of fonts in a way the logo will look like as I designed. The fonts are: Diavlo and Fontin. Designed by Jos Buivenga, they are free to use. I already explained how to install new fonts in linux, so I won't bother you further.

Once the fonts and Inkscape are installed, grab the svg sample logo I made for you. Launch Inkscape, open the file and customize a little bit. For example, you could select the name

edit

replace it and then adjust the its displacement with ALT+(arrows up/down/left/right) which are the keys to adjust the font tracking and kerning in Inkscape. There's a plenty of Inkscape tutorials out there, so I am confident you will come up with a decent logo for yourself.

For the moment, I suggest you to do just little changes and save the file as Encapsulated Postscript (.eps). Before saving, Inkscape shows you this dialog:

dialog

There's only one option you should change: enable the "Convert texts to paths". What it does is converting... well, text into vectorial outlines (so font informations are then discarded) If you don't check that option, acrobat reader will consider text as text in your final pdf document. In brief, it will make the text selectable, like this

selectable

And, in general, you don't want that happening for a background image, don't you?

Anyway, now you should have your beautiful logo, says sample_logo_transparent.eps. A little digression: for the name of my logo I used the word transparent, but the eps's don't really support transparency. If you go back to Inkscape and look carefully at the fill properties:

fill

you will notice that the opacity is 100% and the color of the outlines is just a light gray, giving the impression, in the final document, of transparency. At first one could think to use indeed opacity parameter and save the logo as pdf (which supports transparency) but the final result is awful.

bad

The above picture is not a screenshot gone bad, it is the actual result if you try to import the image as pdf (supporting transparency) instead of an encapsulated postscript (which doesn't support transparency, so you are forced to fake using light colors). If someone obtains better results in importing images as pdf's, let me know, please. End of digression.

Ok, time is come to add our picture as the page background. For the purpose I will use a tiny package called eso-pic.

  1. \ProvidesFile{standard.lco}[%
  2.   2002/07/09 v0.9a LaTeX2e unsupported letter-class-option]
  3.  
  4. \usepackage{fontspec}
  5. \usepackage{marvosym}
  6. \usepackage{eso-pic}
  7.  
  8. % ==============================================
  9. %  PERSONAL DATA
  10. % ==============================================
  11. \setkomavar{fromname}{Iulius Caesar}
  12. \setkomavar{fromaddress}{Van Eeghenlaan 69\\1691QT Amsterdam\\Nederland}
  13. \setkomavar{fromphone}{+31 (0)22 7394203}
  14. \setkomavar{fromemail}{iulius@gmail.com}
  15. \setkomavar{fromfax}{+31 (0)71 5144543}
  16. \setkomavar{fromurl}{http://stefano.italians.nl}
  17. \setkomavar{frombank}{Postbank 9307157}
  18. \setkomavar{place}{Amsterdam}
  19. \setkomavar{signature}{Iulius Caesar}
  20.  
  21. % ==============================================
  22. %  FORMATTING STUFF
  23. % ==============================================
  24.  
  25. % === font settings
  26. \defaultfontfeatures{Mapping=tex-text}
  27. \setmainfont {Adobe Garamond Pro}
  28. \setsansfont {Gill Sans Std}
  29.  
  30. %set the font size and leading
  31. \renewcommand{\normalsize}{\fontsize{12.5}{17}\selectfont}
  32.  
  33. % === header settings
  34. \firsthead{
  35.    \centering
  36.          {\addfontfeature{LetterSpace=20.0}\fontsize{36}{36}\selectfont\scshape \usekomavar{fromname}}\\[5mm]
  37.          \fontsize{21}{21}\selectfont\scshape Programmer and Architect at Initech
  38. }
  39.  
  40. % === footer settings
  41. \firstfoot{
  42.   \centering
  43.   \addfontfeature{LetterSpace=20.0}\scshape
  44.   {
  45.       \renewcommand{\\}{\ {\large\textperiodcentered}\ }
  46.       \usekomavar{fromaddress}
  47.   }\\
  48.   {\Large\Letter} \usekomavar{fromemail} \ {\Large\Telefon} \usekomavar{fromphone}
  49.  
  50. % === watermark settings
  51. \newcommand\BackgroundPicture{
  52.    \put(0,0){
  53.      \parbox[b][\paperheight]{\paperwidth}{
  54.        \vfill
  55.        \centering
  56.        \includegraphics[width=0.8\paperwidth,height=0.8\paperheight,%
  57.                         keepaspectratio]{sample_logo_transparent.eps}%
  58.        \vfill
  59.      }}}
  60.  
  61. % the picture is centered on the page background
  62. \AddToShipoutPicture{\BackgroundPicture}
  63.  
  64.  
  65. \endinput

At line 6 I imported the package and at line 62 I added the background picture, which is defined in lines 51-59. The command \BackgroundPicture will put a box big as the entire page. Inside the box, the image, centered orizontally (with \centering) and vertically (with a pair of enclosing \vfill)

Finally! Let's run xelatex and see the result:

step 6

Our mighty page came to life. Hope you like it. Happy experimenting.

Click here for the last part of the tutorial.

  1. Note that in this part of the tutorial there is nothing specific to XeLaTex, so ideally you can use these instructions to add a watermark also to plain Latex documents. []

Cover letter with style - part four

This is the fourth part of the tutorial Cover letter with style. You can find the third part here.

After the header, I will take care of the footer. To change the default I will use the \firstfoot command. Basically it works like \firsthead, so I have nothing special to add. I will update the template with:

  1. \ProvidesFile{standard.lco}[%
  2.   2002/07/09 v0.9a LaTeX2e unsupported letter-class-option]
  3.  
  4. \usepackage{fontspec}
  5.  
  6. % ==============================================
  7. %  PERSONAL DATA
  8. % ==============================================
  9. \setkomavar{fromname}{Iulius Caesar}
  10. \setkomavar{fromaddress}{Van Eeghenlaan 69\\1691QT Amsterdam\\Nederland}
  11. \setkomavar{fromphone}{+31 (0)22 7394203}
  12. \setkomavar{fromemail}{iulius@gmail.com}
  13. \setkomavar{fromfax}{+31 (0)71 5144543}
  14. \setkomavar{fromurl}{http://stefano.italians.nl}
  15. \setkomavar{frombank}{Postbank 9307157}
  16. \setkomavar{place}{Amsterdam}
  17. \setkomavar{signature}{Iulius Caesar}
  18.  
  19. % ==============================================
  20. %  FORMATTING STUFF
  21. % ==============================================
  22.  
  23. % === font settings
  24. \defaultfontfeatures{Mapping=tex-text}
  25. \setmainfont {Adobe Garamond Pro}
  26. \setsansfont {Gill Sans Std}
  27.  
  28. %set the font size and leading
  29. \renewcommand{\normalsize}{\fontsize{12.5}{17}\selectfont}
  30.  
  31. % === header settings
  32. \firsthead{
  33.    \centering
  34.          {\addfontfeature{LetterSpace=20.0}\fontsize{36}{36}\selectfont\scshape \usekomavar{fromname}}\\[5mm]
  35.          \fontsize{21}{21}\selectfont\scshape Programmer and Architect at Initech
  36. }
  37.  
  38. % === footer settings
  39. \firstfoot{
  40.   \centering
  41.     \usekomavar{fromaddress} \\
  42.     \usekomavar{fromemail} \usekomavar{fromphone}
  43. }
  44.  
  45. \endinput

At line 39 I've declared my new footer. I wanted the material in the footer to be centered (line 40) and I've read the content of the variable fromaddress and used it as the first line, then the break line (\\) and then the email and phone (also read from the corresponding variables). The result is the following:

footer one

There's a problem with the way I declared the fromaddress: to have KOMA-Script rendering my address on three lines, I used the break line command (\\) but now I would like a one-liner address in the footer. I could declare yet another variable, this time avoiding to put the line breaks, but it will be an ugly duplication. Instead, I will use \renewcommand{}{}. As first parameter it takes the command to be redefined and as second parameter you declare the new material to use instead. Well, let's proceed:

  1. \ProvidesFile{standard.lco}[%
  2.   2002/07/09 v0.9a LaTeX2e unsupported letter-class-option]
  3.  
  4. \usepackage{fontspec}
  5.  
  6. % ==============================================
  7. %  PERSONAL DATA
  8. % ==============================================
  9. \setkomavar{fromname}{Iulius Caesar}
  10. \setkomavar{fromaddress}{Van Eeghenlaan 69\\1691QT Amsterdam\\Nederland}
  11. \setkomavar{fromphone}{+31 (0)22 7394203}
  12. \setkomavar{fromemail}{iulius@gmail.com}
  13. \setkomavar{fromfax}{+31 (0)71 5144543}
  14. \setkomavar{fromurl}{http://stefano.italians.nl}
  15. \setkomavar{frombank}{Postbank 9307157}
  16. \setkomavar{place}{Amsterdam}
  17. \setkomavar{signature}{Iulius Caesar}
  18.  
  19. % ==============================================
  20. %  FORMATTING STUFF
  21. % ==============================================
  22.  
  23. % === font settings
  24. \defaultfontfeatures{Mapping=tex-text}
  25. \setmainfont {Adobe Garamond Pro}
  26. \setsansfont {Gill Sans Std}
  27.  
  28. %set the font size and leading
  29. \renewcommand{\normalsize}{\fontsize{12.5}{17}\selectfont}
  30.  
  31. % === header settings
  32. \firsthead{
  33.    \centering
  34.          {\addfontfeature{LetterSpace=20.0}\fontsize{36}{36}\selectfont\scshape \usekomavar{fromname}}\\[5mm]
  35.          \fontsize{21}{21}\selectfont\scshape Programmer and Architect at Initech
  36. }
  37.  
  38. % === footer settings
  39. \firstfoot{
  40.   \centering
  41.     {
  42.       \renewcommand{\\}{\textperiodcentered}
  43.       \usekomavar{fromaddress}
  44.     }\\
  45.     \usekomavar{fromemail} \usekomavar{fromphone}
  46. }
  47.  
  48. \endinput

First of all, I enclose the first line in curly braces (line 41 and 44). In this way the effect of \renewcommand will remain local and will not affect the entire document. At line 42 I redefine the meaning of the \\ command, specifying it has to be replaced by a dot. That's all. Let's look at the result

footer two

So, only for the first line in the footer, the line breaks in my address were replaced by a dot. Now just enlarge the dots and add some space before and after them:

  1. \ProvidesFile{standard.lco}[%
  2.   2002/07/09 v0.9a LaTeX2e unsupported letter-class-option]
  3.  
  4. \usepackage{fontspec}
  5.  
  6. % ==============================================
  7. %  PERSONAL DATA
  8. % ==============================================
  9. \setkomavar{fromname}{Iulius Caesar}
  10. \setkomavar{fromaddress}{Van Eeghenlaan 69\\1691QT Amsterdam\\Nederland}
  11. \setkomavar{fromphone}{+31 (0)22 7394203}
  12. \setkomavar{fromemail}{iulius@gmail.com}
  13. \setkomavar{fromfax}{+31 (0)71 5144543}
  14. \setkomavar{fromurl}{http://stefano.italians.nl}
  15. \setkomavar{frombank}{Postbank 9307157}
  16. \setkomavar{place}{Amsterdam}
  17. \setkomavar{signature}{Iulius Caesar}
  18.  
  19. % ==============================================
  20. %  FORMATTING STUFF
  21. % ==============================================
  22.  
  23. % === font settings
  24. \defaultfontfeatures{Mapping=tex-text}
  25. \setmainfont {Adobe Garamond Pro}
  26. \setsansfont {Gill Sans Std}
  27.  
  28. %set the font size and leading
  29. \renewcommand{\normalsize}{\fontsize{12.5}{17}\selectfont}
  30.  
  31. % === header settings
  32. \firsthead{
  33.    \centering
  34.          {\addfontfeature{LetterSpace=20.0}\fontsize{36}{36}\selectfont\scshape \usekomavar{fromname}}\\[5mm]
  35.          \fontsize{21}{21}\selectfont\scshape Programmer and Architect at Initech
  36. }
  37.  
  38. % === footer settings
  39. \firstfoot{
  40.   \centering
  41.     {
  42.       \renewcommand{\\}{\ {\large\textperiodcentered}\ }
  43.       \usekomavar{fromaddress}
  44.     }\\
  45.     \usekomavar{fromemail} \usekomavar{fromphone}
  46. }
  47.  
  48. \endinput

Look carefully at line 42. First of all, I used the escaped space (a backslash followed by a white space) to instruct TeX to put literally two spaces around the dot. Without escaping the spaces, TeX will happily swallow them. Secondly, I applied the \large modifier to the dot character and I enclosed in curly braces (otherwise the trailing space would be enlarged too). The result will be the following

footer three

Nice, we have our address on one line now. It's time to take care of the second line. For the email and the phone contacts, I will use a couple of symbols from the marvosym package. The template so becomes:

  1. \ProvidesFile{standard.lco}[%
  2.   2002/07/09 v0.9a LaTeX2e unsupported letter-class-option]
  3.  
  4. \usepackage{fontspec}
  5. \usepackage{marvosym}
  6.  
  7. % ==============================================
  8. %  PERSONAL DATA
  9. % ==============================================
  10. \setkomavar{fromname}{Iulius Caesar}
  11. \setkomavar{fromaddress}{Van Eeghenlaan 69\\1691QT Amsterdam\\Nederland}
  12. \setkomavar{fromphone}{+31 (0)22 7394203}
  13. \setkomavar{fromemail}{iulius@gmail.com}
  14. \setkomavar{fromfax}{+31 (0)71 5144543}
  15. \setkomavar{fromurl}{http://stefano.italians.nl}
  16. \setkomavar{frombank}{Postbank 9307157}
  17. \setkomavar{place}{Amsterdam}
  18. \setkomavar{signature}{Iulius Caesar}
  19.  
  20. % ==============================================
  21. %  FORMATTING STUFF
  22. % ==============================================
  23.  
  24. % === font settings
  25. \defaultfontfeatures{Mapping=tex-text}
  26. \setmainfont {Adobe Garamond Pro}
  27. \setsansfont {Gill Sans Std}
  28.  
  29. %set the font size and leading
  30. \renewcommand{\normalsize}{\fontsize{12.5}{17}\selectfont}
  31.  
  32. % === header settings
  33. \firsthead{
  34.    \centering
  35.          {\addfontfeature{LetterSpace=20.0}\fontsize{36}{36}\selectfont\scshape \usekomavar{fromname}}\\[5mm]
  36.          \fontsize{21}{21}\selectfont\scshape Programmer and Architect at Initech
  37. }
  38.  
  39. % === footer settings
  40. \firstfoot{
  41.   \centering
  42.     {
  43.       \renewcommand{\\}{\ {\large\textperiodcentered}\ }
  44.       \usekomavar{fromaddress}
  45.     }\\
  46.     {\Large\Letter} \usekomavar{fromemail} \ {\Large\Telefon} \usekomavar{fromphone}
  47. }
  48.  
  49. \endinput

At line 5 I included the marvosym package; the rest is happening at line 46. Nothing special: I used the enlarged version of the symbols \Letter and \Telefon. I also used an escaped space to keep the email address separated from the telephone number.

footer four

Now, the final touch: I will letterspace the entire footer and use the small caps. So, here it is:

  1. \ProvidesFile{standard.lco}[%
  2.   2002/07/09 v0.9a LaTeX2e unsupported letter-class-option]
  3.  
  4. \usepackage{fontspec}
  5. \usepackage{marvosym}
  6.  
  7. % ==============================================
  8. %  PERSONAL DATA
  9. % ==============================================
  10. \setkomavar{fromname}{Iulius Caesar}
  11. \setkomavar{fromaddress}{Van Eeghenlaan 69\\1691QT Amsterdam\\Nederland}
  12. \setkomavar{fromphone}{+31 (0)22 7394203}
  13. \setkomavar{fromemail}{iulius@gmail.com}
  14. \setkomavar{fromfax}{+31 (0)71 5144543}
  15. \setkomavar{fromurl}{http://stefano.italians.nl}
  16. \setkomavar{frombank}{Postbank 9307157}
  17. \setkomavar{place}{Amsterdam}
  18. \setkomavar{signature}{Iulius Caesar}
  19.  
  20. % ==============================================
  21. %  FORMATTING STUFF
  22. % ==============================================
  23.  
  24. % === font settings
  25. \defaultfontfeatures{Mapping=tex-text}
  26. \setmainfont {Adobe Garamond Pro}
  27. \setsansfont {Gill Sans Std}
  28.  
  29. %set the font size and leading
  30. \renewcommand{\normalsize}{\fontsize{12.5}{17}\selectfont}
  31.  
  32. % === header settings
  33. \firsthead{
  34.    \centering
  35.          {\addfontfeature{LetterSpace=20.0}\fontsize{36}{36}\selectfont\scshape \usekomavar{fromname}}\\[5mm]
  36.          \fontsize{21}{21}\selectfont\scshape Programmer and Architect at Initech
  37. }
  38.  
  39. % === footer settings
  40. \firstfoot{
  41.   \centering
  42.   \addfontfeature{LetterSpace=20.0}\scshape
  43.   {
  44.       \renewcommand{\\}{\ {\large\textperiodcentered}\ }
  45.       \usekomavar{fromaddress}
  46.   }\\
  47.   {\Large\Letter} \usekomavar{fromemail} \ {\Large\Telefon} \usekomavar{fromphone}
  48.  
  49. \endinput

Basically I just added the line 42. The result?

footer six

Quite a long journey for a fucking footer, but we're done and I hope you will like the final result so far. Please mind that the above screenshot was made smaller in respect of the others. To see the footer in respect of the entire page, here it is the last picture

step five

I think it is already quite a good letter, but in the next part we will watermark our logo.

Cover letter with style - part three

This is the third part of the tutorial Cover letter with style. You can find the second part here.

It's time to setup a custom header for our cover letter. I usually put my name and my current job title in the header, accordingly to my big ego. In KOMA-Script, there are several ways to define your own header; each one offers an increasing degree of freedom but also an increasing complication in use. Luckily enough, for our purposes, we can use the easiest.

So, the simplest way to change your header is by the \firsthead command. That will set the custom header just for the first page of the document. But we're talking about a cover letter: don't even think to make it longer than a page. Enough said, I will modify the template now

  1. \ProvidesFile{standard.lco}[%
  2.   2002/07/09 v0.9a LaTeX2e unsupported letter-class-option]
  3.  
  4. \usepackage{fontspec}
  5.  
  6. % ==============================================
  7. %  PERSONAL DATA
  8. % ==============================================
  9. \setkomavar{fromname}{Iulius Caesar}
  10. \setkomavar{fromaddress}{Van Eeghenlaan 69\\1691QT Amsterdam\\Nederland}
  11. \setkomavar{fromphone}{+31 (0)22 7394203}
  12. \setkomavar{fromemail}{iulius@gmail.com}
  13. \setkomavar{fromfax}{+31 (0)71 5144543}
  14. \setkomavar{fromurl}{http://stefano.italians.nl}
  15. \setkomavar{frombank}{Postbank 9307157}
  16. \setkomavar{place}{Amsterdam}
  17. \setkomavar{signature}{Iulius Caesar}
  18.  
  19. % ==============================================
  20. %  FORMATTING STUFF
  21. % ==============================================
  22.  
  23. % === font settings
  24. \defaultfontfeatures{Mapping=tex-text}
  25. \setmainfont {Adobe Garamond Pro}
  26. \setsansfont {Gill Sans Std}
  27.  
  28. %set the font size and leading
  29. \renewcommand{\normalsize}{\fontsize{12.5}{17}\selectfont}
  30.  
  31. \firsthead{
  32.    \centering
  33.          \usekomavar{fromname}\\
  34.          Programmer and Architect at Initech
  35. }
  36.  
  37. \endinput

So, I have specified the following: the header shall be centered and will be comprised of two lines (the \\ is the latex command to break the line). The first line will be our name. I didn't write it directly because it is already set at line 9. Instead, I used \usekomavar to lookup the fromname variable. Here I am adhering to the D-FRY principle: don't fucking repeat yourself. The second line is the job title. You can choose to define a variable as well, if you plan to use the job title more than once in your letter.

Now, render the letter again, to see the result

header one

Well, it sucks. I will increase the font size, and use the small caps version.

  1. \ProvidesFile{standard.lco}[%
  2.   2002/07/09 v0.9a LaTeX2e unsupported letter-class-option]
  3.  
  4. \usepackage{fontspec}
  5.  
  6. % ==============================================
  7. %  PERSONAL DATA
  8. % ==============================================
  9. \setkomavar{fromname}{Iulius Caesar}
  10. \setkomavar{fromaddress}{Van Eeghenlaan 69\\1691QT Amsterdam\\Nederland}
  11. \setkomavar{fromphone}{+31 (0)22 7394203}
  12. \setkomavar{fromemail}{iulius@gmail.com}
  13. \setkomavar{fromfax}{+31 (0)71 5144543}
  14. \setkomavar{fromurl}{http://stefano.italians.nl}
  15. \setkomavar{frombank}{Postbank 9307157}
  16. \setkomavar{place}{Amsterdam}
  17. \setkomavar{signature}{Iulius Caesar}
  18.  
  19. % ==============================================
  20. %  FORMATTING STUFF
  21. % ==============================================
  22.  
  23. % === font settings
  24. \defaultfontfeatures{Mapping=tex-text}
  25. \setmainfont {Adobe Garamond Pro}
  26. \setsansfont {Gill Sans Std}
  27.  
  28. %set the font size and leading
  29. \renewcommand{\normalsize}{\fontsize{12.5}{17}\selectfont}
  30.  
  31. \firsthead{
  32.    \centering
  33.          \fontsize{36}{36}\selectfont\scshape \usekomavar{fromname}\\
  34.          \fontsize{21}{21}\selectfont\scshape Programmer and Architect at Initech
  35. }
  36.  
  37. \endinput

Now the header looks like this

header two

Much better. But I'm still not quite happy. So, I will increase the letter spacing, just for the first line. I will change the so called "feature" LetterSpace.

  1. \ProvidesFile{standard.lco}[%
  2.   2002/07/09 v0.9a LaTeX2e unsupported letter-class-option]
  3.  
  4. \usepackage{fontspec}
  5.  
  6. % ==============================================
  7. %  PERSONAL DATA
  8. % ==============================================
  9. \setkomavar{fromname}{Iulius Caesar}
  10. \setkomavar{fromaddress}{Van Eeghenlaan 69\\1691QT Amsterdam\\Nederland}
  11. \setkomavar{fromphone}{+31 (0)22 7394203}
  12. \setkomavar{fromemail}{iulius@gmail.com}
  13. \setkomavar{fromfax}{+31 (0)71 5144543}
  14. \setkomavar{fromurl}{http://stefano.italians.nl}
  15. \setkomavar{frombank}{Postbank 9307157}
  16. \setkomavar{place}{Amsterdam}
  17. \setkomavar{signature}{Iulius Caesar}
  18.  
  19. % ==============================================
  20. %  FORMATTING STUFF
  21. % ==============================================
  22.  
  23. % === font settings
  24. \defaultfontfeatures{Mapping=tex-text}
  25. \setmainfont {Adobe Garamond Pro}
  26. \setsansfont {Gill Sans Std}
  27.  
  28. %set the font size and leading
  29. \renewcommand{\normalsize}{\fontsize{12.5}{17}\selectfont}
  30.  
  31. \firsthead{
  32.    \centering
  33.          {\addfontfeature{LetterSpace=20.0}\fontsize{36}{36}\selectfont\scshape \usekomavar{fromname}}\\[5mm]
  34.          \fontsize{21}{21}\selectfont\scshape Programmer and Architect at Initech
  35. }
  36.  
  37. \endinput

I used the command \addfontfeature to set the LetterSpace feature equal to 20. To find the right factor, I just did some experiments. Mind the use of a pair of {} to enclose the entire first line. In this way the change of letter spacing is local to the first line and don't apply to the second line. I also set up half centimeter of space between the lines, with the command \\[put your vertical distance here]

So, render again the letter and see the result:

header three

Well, now take a look at the entire page so far

step 4 completed

Perfect. In the next part I will show how to setup up the footer and then we will be ready for the watermarks, logo and barcode...

Cover letter with style - part two

This is the second part of the tutorial Cover letter with style. You can find the first part here.

In this second part, we will change the default fonts using fontspec. Forget importing Postscript fonts, classifying them under the NFSS1 and other crazy stuff: fontspec is able to load opentype fonts and select them very easily. You have just to install the fonts on your system. For example, I bought Garamond e Gill Sans fonts from Adobe and I'm using Ubuntu, so I copied the *.otf files somewhere under the

/usr/share/fonts

and then I updated the font cache with this command

sudo fc-cache -fv

Last thing you will need is to take note of the exact name of the font family, to be able to select it. For that, after having installed the lcdf-typetools ubuntu package, you can do something like

otfinfo -i /usr/share/fonts/AGaramondPro-Regular.otf | grep Family

Ok, after those few steps I have installed the fonts and discovered their family name, say, "Adobe Garamond Pro" and "Gill Sans Std". Now just change the template (remember, standard.lco) as this:

  1. \ProvidesFile{standard.lco}[%
  2.   2002/07/09 v0.9a LaTeX2e unsupported letter-class-option]
  3.  
  4. \usepackage{fontspec}
  5.  
  6. % ==============================================
  7. %  PERSONAL DATA
  8. % ==============================================
  9. \setkomavar{fromname}{Iulius Caesar}
  10. \setkomavar{fromaddress}{Van Eeghenlaan 69\\1691QT Amsterdam\\Nederland}
  11. \setkomavar{fromphone}{+31 (0)22 7394203}
  12. \setkomavar{fromemail}{iulius@gmail.com}
  13. \setkomavar{fromfax}{+31 (0)71 5144543}
  14. \setkomavar{fromurl}{http://stefano.italians.nl}
  15. \setkomavar{frombank}{Postbank 9307157}
  16. \setkomavar{place}{Amsterdam}
  17. \setkomavar{signature}{Iulius Caesar}
  18.  
  19. % ==============================================
  20. %  FORMATTING STUFF
  21. % ==============================================
  22.  
  23. % === font settings
  24. \defaultfontfeatures{Mapping=tex-text}
  25. \setmainfont {Adobe Garamond Pro}
  26. \setsansfont {Gill Sans Std}
  27.  
  28.  
  29. \endinput

At line 4 I just imported the fontspec package. At line 24 I am instructing fontspec to add the ligatures TeX needs.2 At line 25 I set the main font and at line 26 I set the font to be used in case a sans serif one if needed.

Another important thing to set up, usually, is the font size and the lead. To do so, just add one more line:

  1. \ProvidesFile{standard.lco}[%
  2.   2002/07/09 v0.9a LaTeX2e unsupported letter-class-option]
  3.  
  4. \usepackage{fontspec}
  5.  
  6. % ==============================================
  7. %  PERSONAL DATA
  8. % ==============================================
  9. \setkomavar{fromname}{Iulius Caesar}
  10. \setkomavar{fromaddress}{Van Eeghenlaan 69\\1691QT Amsterdam\\Nederland}
  11. \setkomavar{fromphone}{+31 (0)22 7394203}
  12. \setkomavar{fromemail}{iulius@gmail.com}
  13. \setkomavar{fromfax}{+31 (0)71 5144543}
  14. \setkomavar{fromurl}{http://stefano.italians.nl}
  15. \setkomavar{frombank}{Postbank 9307157}
  16. \setkomavar{place}{Amsterdam}
  17. \setkomavar{signature}{Iulius Caesar}
  18.  
  19. % ==============================================
  20. %  FORMATTING STUFF
  21. % ==============================================
  22.  
  23. % === font settings
  24. \defaultfontfeatures{Mapping=tex-text}
  25. \setmainfont {Adobe Garamond Pro}
  26. \setsansfont {Gill Sans Std}
  27.  
  28. %set the font size and leading
  29. \renewcommand{\normalsize}{\fontsize{12.5}{17}\selectfont}
  30.  
  31. \endinput

I just added the line 29, plain old Latex directive, to redefine the \normalsize macro3. In this way I can specify the height of the font and the space in point between the lines. The values one should use really depend on so many factors... but this is not a course on basic typography.

Ok, time to generate our cover letter again. To appreciate the differences, I first show the old version:

default font

And now with the professional fonts

professional font

Can you see the difference? I hope so. Note also the sender address: it has to be rendered in a smaller size, so KOMA-Script used the sans serif font because more legible; that's why we also specified a suitable family for sans serif font in our template.

For more information, examples and so on, I urge you to read the fontspec documentation, to get ready for the third part of the tutorial.

That's all folks. Now you can proceed to the third part.

  1. New Font Selection Scheme []
  2. Commercial fonts usually lacks ligatures like "--" (n-dash) and "---" (m-dash) but with this line TeX will still find them []
  3. There are other methods []

Cover letter with style - part one

Time flies and almost one year went by without me writing the 5th part of Your Curriculum in LaTeX series. You know what? I grew tired of the tutorial: you can figure out the rest1

Instead, I decided to start a new tutorial, this time illustrating a way to obtain a stylish cover letter with XeTeX (and XeLaTeX), which enables the easy use of OpenType fonts (through the fontspec package) and support for Unicode text (no need of escape extended characters anymore). Also, as in the other tutorial, KOMA-Script will be used.

The cover letter is the first thing they will read; possibly its form is as much important as its content. Even if you don't agree, a fancy letter doesn't do any harm, doesn't it? For example, what about a letter like this2

Sample letter one

Strong header, contact data in footer, logo as watermark. Even a barcode to pimp the destination address! Ok, the barcode is a little bit too nerdy, but it will give me the chance to show how easy is to use PSTricks from inside XeLaTex.

In this tutorial I will also show how to separate the content of your letters from the style, so you can swap the latter really easily, to obtain something completely different, like this for example:

Sample letter two

Ok, let's start. I assume you dutifully installed XeTeX, XeLaTeX, KOMA-Script and you are ready to follow me. Ready?

Create a .tex file and past the skeleton of the cover letter into it:

  1. \documentclass{scrlttr2}
  2.  
  3. \begin{document}
  4.  
  5. \begin{letter}{%
  6.        Damage Inc. --- HR Dept.\\%
  7.        Paulus Potterstraat 134\\%
  8.        1753KJ Amsterdam
  9. }
  10. \setkomavar{subject}{Cover Letter}
  11. \opening{Dear Recruiter,}
  12.  
  13. My name is Iulius Caesar bla bla bla...
  14.  
  15. \closing{Regards}
  16.  
  17.  
  18. \end{letter}
  19. \end{document}

At line 1 you are instructing XeLaTeX to load the letter class from KOMA-Script, which will format a nice letter for you. At lines 6,7,8 the destination address is specified. At line 13 the body of the letter. The other parts should be trivial to understand. Basically this is a template for any kind of letter you will write. Nothing difficult indeed. If you process this with XeLaTeX you will get:

barebone letter

Effortlessly we obtained a nice formatted letter. KOMA-Script even added three little dashes on the left border: they are guides to fold the letter with precision. The only thing is missing is the sender address. I could have added the KOMA instructions to set the sender address directly into the tex file, but there's a better method.

The letter document class defined by KOMA-Script support the loading of a setting/style file. In this file, with extension .lco, you can store things like your data (used to compose the sender address) or whatever latex instruction, to change the style for example. In this way the .tex will contain just the letter text and nothing else. This is handy for two reason: 1) you don't have to type your data for each letter you write; 2) you may have more .lco files that you can use to change altogether the look & feel.

So, create a file and call it standard.lco. Stick your data in it, like this:

  1. \ProvidesFile{standard.lco}[%
  2.   2002/07/09 v0.9a LaTeX2e unsupported letter-class-option]
  3.  
  4. % ==============================================
  5. %  PERSONAL DATA
  6. % ==============================================
  7. \setkomavar{fromname}{Iulius Caesar}
  8. \setkomavar{fromaddress}{Van Eeghenlaan 69\\1691QT Amsterdam\\Nederland}
  9. \setkomavar{fromphone}{+31 (0)22 7394203}
  10. \setkomavar{fromemail}{iulius@gmail.com}
  11. \setkomavar{fromfax}{+31 (0)71 5144543}
  12. \setkomavar{fromurl}{http://stefano.italians.nl}
  13. \setkomavar{frombank}{Postbank 9307157}
  14. \setkomavar{place}{Amsterdam}
  15. \setkomavar{signature}{Iulius Caesar}
  16.  
  17. \endinput

Change accordingly your .tex file (containing the text of the letter) to instruct KOMA-Script to load the standard.lco file:

  1. \documentclass[standard]{scrlttr2}
  2.  
  3. \begin{document}
  4.  
  5. \begin{letter}{%
  6.        Damage Inc. --- HR Dept.\\%
  7.        Paulus Potterstraat 134\\%
  8.        1753KJ Amsterdam
  9. }
  10. \setkomavar{subject}{Cover Letter}
  11. \opening{Dear Recruiter,}
  12.  
  13. My name is Iulius Caesar bla bla bla...
  14.  
  15. \closing{Regards}
  16.  
  17.  
  18. \end{letter}
  19. \end{document}

I've changed just the first line. Urge yourself to run XeLaTeX to see the results:

barebone letter with sender address

The sender address now appears where it is supposed to be. You will notice that KOMA-Script will also add the one-liner version, meant to pop up from the transparent window of the envelope - if any - together with the destination address.

Well, that's all for the first part. There's still lot to explain so please proceed to the second part.

  1. Oh, gentlemen, do you know, perhaps I consider myself an intelligent man, only because all my life I have been able neither to begin nor to finish anything [Dostoevskij - Notes From The Underground] []
  2. The content is completely fictitious and doesn't necessarily reflect my views []

Your curriculum in LaTeX - part four

This is the fourth part of the tutorial. You can find here the third part.

In the first part we took care of the title of the resume; in the second part we organized the sections, using an appropriate style; finally, in the third part, we formatted the footer, as a container for our contact data. Now it's time to tackle the Experiences entries, the place where to display infos about our past and current employments. The entries will look like the following

job entry

For more clarity, the following picture shows the used grid

grid

It is basically a table, with two columns. The first one is 2cm wide and the second spans for the remaining space of the table. The total width of the table is slightly less than the width of the page body width (i.e. the page width minus the margins width.)
To achieve this, we will use the tabularx environment, which is able calculate automatically the column size depending on the total width of the table. The general form of the environment is the following:

\begin{tabularx}{width}{preamble}
[... table data ...]
\end{tabularx}

The width parameter is the total length of the table, whereas the preamble is used for the column specifications. For each column in the table we can use a symbol in the preamble to specify which kind of column we want. For example, to indicate that a column should have the width automatically calculated, we have to use the “X” symbol in the preamble. So, the code

\begin{tabularx}{5cm}{XX}
[... table data ...]
\end{tabularx}

will define a table 5cm wide featuring two columns, both with an automatic width (in this case each column will be 2.5cm wide.) Among the preamble options, we can use the “p” symbol, followed by a width specification, to force a column to that width. So we could write something like that

\begin{tabularx}{5cm}{p{2cm}X}
[... table data ...]
\end{tabularx}

In this case the table will be 5cm wide, with the first column spanning for 2cm and the second column automatically adjusted. There's a lot of options one could specify in the preamble, so I suggest to read the tabularx document to become aware of all the possibilities.
The data enclosed in the environment will be formatted as a table. To specify rows and columns the symbols & and \\ has to be used. For example the following

\begin{tabularx}{5cm}{p{2cm}X}
Name & Stefano \\
Surname & Kindoblue \\
City & Amsterdam
\end{tabularx}

will generate this table:

sample table

Back to our requirements: we need to define a table wide, say, 97% of the page body width. To calculate that length we can use the latex command \linewidth, which represents the length of a line of text in the document (nota a \textwidth) I think we are pretty much done. The following code will create the desired table

\begin{tabularx}{0.97\linewidth}{p{2cm}X}
[... table data ...]
\end{tabularx}

Finally we can write our first entry in the Experiences section.

  1. \documentclass[a4paper, oneside, final]{scrartcl}
  2.  
  3. \usepackage{soul}
  4. \usepackage{scrpage2}
  5. \usepackage{titlesec}
  6. \usepackage{marvosym}
  7. \usepackage{tabularx}
  8.  
  9. \titleformat{\section}{\large\scshape\raggedright}{}{0em}{}[\titlerule]
  10.  
  11. \pagestyle{scrheadings}
  12.  
  13. \renewcommand{\headfont}{\normalfont\rmfamily\scshape}
  14.  
  15. % add the symbols for email and phone contact data
  16. \cofoot{\so{Liefdestraat, 7 - 1234LI, Amsterdam, Nederland}\\
  17. \so{ {\Large\Letter} jeff@gmail.com \ {\Large\Telefon} +31 (0)6 12345678}}
  18.  
  19. \begin{document}
  20. \begin{center}
  21.  
  22. \textsc{\Huge{\so{Iulius Caesar}}}
  23.  
  24. \section{Experiences}
  25.  
  26. \begin{tabularx}{0.97\linewidth}{p{2cm}X}
  27. Period     & August 2004 --- September 2006\\
  28. Employer   & Layer BV \hfill Amsterdam, The Netherlands\\
  29. Job Title  & J2EE Analyst programmer\\
  30. Languages  & J2EE\\
  31.            & Non eram nescius, Brute, cum, quae summis ingeniis exquisitaque doctrina philosophi Graeco sermone tractavissent, ea Latinis litteris mandaremus, fore ut hic noster labor in varias reprehensiones incurreret.
  32. \end{tabularx}
  33.  
  34. \section{Skills}
  35. \section{Education}
  36. \section{Publications}
  37. \section{Personal Info}
  38. \section{Languages}
  39. \section{Interests}
  40.  
  41. \end{center}
  42. \end{document}

Note the use of \hfill command, to push the “Amsterdam, The Netherlands” apart from the company name. The result will be this:
table version 1
Nice. Now we need to format the first column, which should be ragged left and in small caps. To do so, we need to modify the preamble. Remember the symbols used to specify the column type? If we prefix those symbols with something like that

>{decl}

Then the decl will be put directly in front of the entry of the column. The decl can be a sequence of Latex commands, that will act on the column matter. We can write something like that:

\begin{tabularx}{0.97\linewidth}{>{\raggedleft\scshape}p{2cm}X}
[... table data ...]
\end{tabularx}

What we just did is to declare the text ragged left and small caps enabled for the first column. Let's go back to our curriculum and modify accordingly. I will also make bold some parts:

  1. \documentclass[a4paper, oneside, final]{scrartcl}
  2.  
  3. \usepackage{soul}
  4. \usepackage{scrpage2}
  5. \usepackage{titlesec}
  6. \usepackage{marvosym}
  7. \usepackage{tabularx}
  8.  
  9. \titleformat{\section}{\large\scshape\raggedright}{}{0em}{}[\titlerule]
  10.  
  11. \pagestyle{scrheadings}
  12.  
  13. \renewcommand{\headfont}{\normalfont\rmfamily\scshape}
  14.  
  15. % add the symbols for email and phone contact data
  16. \cofoot{\so{Liefdestraat, 7 - 1234LI, Amsterdam, Nederland}\\
  17. \so{ {\Large\Letter} jeff@gmail.com \ {\Large\Telefon} +31 (0)6 12345678}}
  18.  
  19. \begin{document}
  20. \begin{center}
  21.  
  22. \textsc{\Huge{\so{Iulius Caesar}}}
  23.  
  24. \section{Experiences}
  25.  
  26. \begin{tabularx}{0.97\linewidth}{>{\raggedleft\scshape}p{2cm}X}
  27. Period     & \textbf{August 2004 --- September 2006}\\
  28. Employer   & \textbf{Layer BV \hfill Amsterdam, The Netherlands}\\
  29. Job Title  & \textbf{J2EE Analyst programmer}\\
  30. Languages  & J2EE\\
  31.            & Non eram nescius, Brute, cum, quae summis ingeniis exquisitaque doctrina philosophi Graeco sermone tractavissent, ea Latinis litteris mandaremus, fore ut hic noster labor in varias reprehensiones incurreret.
  32. \end{tabularx}
  33.  
  34. \section{Skills}
  35. \section{Education}
  36. \section{Publications}
  37. \section{Personal Info}
  38. \section{Languages}
  39. \section{Interests}
  40.  
  41. \end{center}
  42. \end{document}

The result is the following:
table version 2
To highlight the salient data of the employment entry in respect of the job description, we can use a gray background for the first four rows of the table. The colortbl package provides several commands to colorize backgrounds in tables. For example, the command

\rowcolor[gray]{.90}

set the background color to 90% gray for a given row. We can define a custom command to be used as a shortcut, in this way

\newcommand{\gray}{\rowcolor[gray]{.90}}

Now in our resume, for the first four rows of the table we can use the command \gray. But don't forget to include the colortbl package!

  1. \documentclass[a4paper, oneside, final]{scrartcl}
  2.  
  3. \usepackage{soul}
  4. \usepackage{scrpage2}
  5. \usepackage{titlesec}
  6. \usepackage{marvosym}
  7. \usepackage{tabularx,colortbl}
  8.  
  9. \titleformat{\section}{\large\scshape\raggedright}{}{0em}{}[\titlerule]
  10.  
  11. \pagestyle{scrheadings}
  12.  
  13. \renewcommand{\headfont}{\normalfont\rmfamily\scshape}
  14.  
  15. % add the symbols for email and phone contact data
  16. \cofoot{\so{Liefdestraat, 7 - 1234LI, Amsterdam, Nederland}\\
  17. \so{ {\Large\Letter} jeff@gmail.com \ {\Large\Telefon} +31 (0)6 12345678}}
  18.  
  19. \begin{document}
  20. \begin{center}
  21.  
  22. \textsc{\Huge{\so{Iulius Caesar}}}
  23.  
  24. \section{Experiences}
  25. \newcommand{\gray}{\rowcolor[gray]{.90}}
  26. \begin{tabularx}{0.97\linewidth}{>{\raggedleft\scshape}p{2cm}X}
  27. \gray Period    & \textbf{August 2004 --- September 2006}\\
  28. \gray Employer  & \textbf{Layer BV} \hfill Amsterdam, The Netherlands\\
  29. \gray Job Title & \textbf{J2EE Analyst programmer}\\
  30. \gray Languages & J2EE\\
  31.        & Non eram nescius, Brute, cum, quae summis ingeniis exquisitaque doctrina philosophi Graeco sermone tractavissent, ea Latinis litteris mandaremus, fore ut hic noster labor in varias reprehensiones incurreret.
  32. \end{tabularx}
  33.  
  34. \section{Skills}
  35. \section{Education}
  36. \section{Publications}
  37. \section{Personal Info}
  38. \section{Languages}
  39. \section{Interests}
  40.  
  41. \end{center}
  42. \end{document}

Finally we obtain something like this:
table version 3
Sweet, isn't it? We are able to define a table for our job entries, with style (at least, in my humble opinion). Only problem is there's a lot of boilerplate code to repeat for each job entry we would like to add to our document. So in the next part of the tutorial I will show how to define a custom environment that will format once for all of our job entries, regardless their number. Along the road there will be room also for some refinements.

See you in 7 seven years, then.

Your curriculum in LaTeX - part three

This is the third part of the tutorial. You can find here the second part.

In the first part of the tutorial we took care of the title of the resume; in the second part we organized the sections, using an appropriate style. Now it's time to properly format the pages and add a decent footer. To do so, I installed and used KOMA-Script. It is a powerful bundle of LaTeX classes and packages and, as stated in its guide: its primary purpose is to provide more-flexible alternatives to the standard classes. It includes the scrpage2 package to customise the document page header and footer, improved and enhanced successor of scrpage.

So, let's change the \documentclass to use KOMA. Also, include the package scrpage2:

  1. \documentclass[a4paper, oneside, final]{scrartcl}
  2.  
  3. \usepackage{soul}
  4. \usepackage{scrpage2}
  5. \usepackage{titlesec}
  6.  
  7. \titleformat{\section}{\large\scshape\raggedright}{}{0em}{}[\titlerule]
  8.  
  9. \begin{document}
  10. \begin{center}
  11.  
  12. \textsc{\Huge{\so{Iulius Caesar}}}
  13.  
  14. \section{Experiences}
  15. \section{Skills}
  16. \section{Education}
  17. \section{Publications}
  18. \section{Personal Info}
  19. \section{Languages}
  20. \section{Interests}
  21.  
  22. \end{center}
  23. \end{document}

As you can see from the result page, the are some adjustments regarding the margins.

The page with KOMA class

Still, no big differences. So, we proceed to set the footer to replace the page numbers in the bottom of the page with something more appropriate for a resume: the contact data. To do so, we will use the commands \pagestyle{scrheadings} and \cofoot. In this way:

  1. \documentclass[a4paper, oneside, final]{scrartcl}
  2.  
  3. \usepackage{soul}
  4. \usepackage{scrpage2}
  5. \usepackage{titlesec}
  6.  
  7. \titleformat{\section}{\large\scshape\raggedright}{}{0em}{}[\titlerule]
  8.  
  9. % enable customized headers and footers
  10. \pagestyle{scrheadings}
  11.  
  12. % define footer
  13. \cofoot{Liefdestraat, 7 - 1234LI, Amsterdam, Nederland\\
  14. jeff@gmail.com \  +31 (0)6 12345678}
  15.  
  16. \begin{document}
  17. \begin{center}
  18.  
  19. \textsc{\Huge{\so{Iulius Caesar}}}
  20.  
  21. \section{Experiences}
  22. \section{Skills}
  23. \section{Education}
  24. \section{Publications}
  25. \section{Personal Info}
  26. \section{Languages}
  27. \section{Interests}
  28.  
  29. \end{center}
  30. \end{document}

Take a look at the result page:

The page with the customized footer

Let's focus on the footer, because the default appearance is not enough.

The zoomed footer

The first thing to do is to change the font shape of the footer, redefining the command \headfont, so the latex code becomes:

  1. \documentclass[a4paper, oneside, final]{scrartcl}
  2.  
  3. \usepackage{soul}
  4. \usepackage{scrpage2}
  5. \usepackage{titlesec}
  6.  
  7. \titleformat{\section}{\large\scshape\raggedright}{}{0em}{}[\titlerule]
  8.  
  9. \pagestyle{scrheadings}
  10.  
  11. % specify the font family for headers and footers
  12. \renewcommand{\headfont}{\normalfont\rmfamily\scshape}
  13.  
  14. \cofoot{Liefdestraat, 7 - 1234LI, Amsterdam, Nederland\\
  15. jeff@gmail.com \  +31 (0)6 12345678}
  16.  
  17. \begin{document}
  18. \begin{center}
  19.  
  20. \textsc{\Huge{\so{Iulius Caesar}}}
  21.  
  22. \section{Experiences}
  23. \section{Skills}
  24. \section{Education}
  25. \section{Publications}
  26. \section{Personal Info}
  27. \section{Languages}
  28. \section{Interests}
  29.  
  30. \end{center}
  31. \end{document}

The footer now looks like the following:

The footer with changed font shape

As we did with other important pieces of this document, we can use the command \so from the Soul package, in this way:

  1. \documentclass[a4paper, oneside, final]{scrartcl}
  2.  
  3. \usepackage{soul}
  4. \usepackage{scrpage2}
  5. \usepackage{titlesec}
  6.  
  7. \titleformat{\section}{\large\scshape\raggedright}{}{0em}{}[\titlerule]
  8.  
  9. \pagestyle{scrheadings}
  10.  
  11. \renewcommand{\headfont}{\normalfont\rmfamily\scshape}
  12.  
  13. % the so command to expand the text
  14. \cofoot{\so{Liefdestraat, 7 - 1234LI, Amsterdam, Nederland}\\
  15. \so{jeff@gmail.com \  +31 (0)6 12345678}}
  16.  
  17. \begin{document}
  18. \begin{center}
  19.  
  20. \textsc{\Huge{\so{Iulius Caesar}}}
  21.  
  22. \section{Experiences}
  23. \section{Skills}
  24. \section{Education}
  25. \section{Publications}
  26. \section{Personal Info}
  27. \section{Languages}
  28. \section{Interests}
  29.  
  30. \end{center}
  31. \end{document}

The result is now much better:

The footer with more spaces

And now, the final touch! Go, grab and install the Marvosym package. It contains fonts with a lot of symbols1. The idea is to specify the symbols for email and phone contact data, to provide visual hints.
To do so, we will use the command \Letter and \Telefon. Also, to increase the size of the symbols, we will use the \Large modifier, all enclosed in curly brakets (to limit the scope of the command, otherwise also the text will be enlarged.)
So, the latex code becomes:

  1. \documentclass[a4paper, oneside, final]{scrartcl}
  2.  
  3. \usepackage{soul}
  4. \usepackage{scrpage2}
  5. \usepackage{titlesec}
  6. \usepackage{marvosym}
  7.  
  8. \titleformat{\section}{\large\scshape\raggedright}{}{0em}{}[\titlerule]
  9.  
  10. \pagestyle{scrheadings}
  11.  
  12. \renewcommand{\headfont}{\normalfont\rmfamily\scshape}
  13.  
  14. % add the symbols for email and phone contact data
  15. \cofoot{\so{Liefdestraat, 7 - 1234LI, Amsterdam, Nederland}\\
  16. \so{ {\Large\Letter} jeff@gmail.com \ {\Large\Telefon} +31 (0)6 12345678}}
  17.  
  18. \begin{document}
  19. \begin{center}
  20.  
  21. \textsc{\Huge{\so{Iulius Caesar}}}
  22.  
  23. \section{Experiences}
  24. \section{Skills}
  25. \section{Education}
  26. \section{Publications}
  27. \section{Personal Info}
  28. \section{Languages}
  29. \section{Interests}
  30.  
  31. \end{center}
  32. \end{document}

The result is the following:

The footer with the symbols

To recap, in this part of the tutorial we adjusted the page format using KOMA-Script, then we added and customized the footer. The following picture shows the steps we took in the customization:

The footer comparison

That's all folks. See you in seven years for the fourth part.

  1. Take a look at the Marvosym documentation to discover which symbols are available and how to specify them in your document []

Your curriculum in LaTeX - part two

This is the second part of the tutorial. You can find here the first part.

Now it's time to add the section headers. We will use the command \section, in this way:

  1. \documentclass{article}
  2.  
  3. \includepackage{soul}
  4.  
  5. \begin{document}
  6.  
  7. \begin{center}
  8.  
  9. \textsc{\so{\Huge{Iulius Caesar}}}
  10.  
  11. % hereafter we specify the section
  12. % of our resume
  13. \section{Experiences}
  14. \section{Skills}
  15. \section{Education}
  16. \section{Publications}
  17. \section{Personal Info}
  18. \section{Languages}
  19. \section{Interests}
  20.  
  21. \end{center}
  22.  
  23. \end{document}

The result is like this:

The section headers can be improved with a little bit of personality. So, instead of living with the standard format for the section header, we will customize it. The package titlesec is offering several macro to cope with personalization of titles and headers. Install it and load in the preamble, so we can use the \titleformat command

\titleformat{command}[shape]{format}{label}{sep}{before}[after]

It takes 7 parameters. The ones in curly braces are mandatory; the others, optional.

  • The first parameter, command, is used to specify which sectioning command has to be redefined. In our case, we want to change the format of the sections, so we will use the value \section
  • The second parameter is to specify the shape of the sectioning command. For the possible values, see the titlesec manual. In our case, we are happy with the default shape.
  • The third parameter is the most important. Here we can specify the format for the entire title.
  • The fourth parameter is the label. It is some text that appears in the title. In the previous image, the labels for the section are the running numbers.
  • The fifth parameter is the separator between the label and the title.
  • The last two parameters can contains LaTeX code that will appears before and after the title material.

So, to begin with, let's eliminate the numbers in front of the section titles, by using the following declaration

\titleformat{\section}{}{}{0em}{}

As first parameter, we specify the sectioning command whose format has to be redefined; in our case: \section. The shape parameter is not passed, because we are happy with the default value and it is not mandatory. The third parameter, the format, we leave empty for the moment. Now the forth parameter, the label. We said we want to get rid of the numbers, so we leave the parameter out. Regarding the fifth parameter, we have to specify a length for the separation between label (null) and the title. The sixth parameter also will be left empty. The seventh parameter is not specified because is not mandatory.

So our code will look like the following:

  1. \documentclass{article}
  2.  
  3. \usepackage{soul}
  4. \usepackage{titlesec}
  5.  
  6. % this is a global declaration that
  7. % will change the appearance of
  8. % the section command
  9. \titleformat{\section}{}{}{0em}{}
  10.  
  11. \begin{document}
  12. \begin{center}
  13.  
  14. \textsc{\Huge{\so{Iulius Caesar}}}
  15.  
  16. \section{Experiences}
  17. \section{Skills}
  18. \section{Education}
  19. \section{Publications}
  20. \section{Personal Info}
  21. \section{Languages}
  22. \section{Interests}
  23.  
  24. \end{center}
  25. \end{document}

The section titles now become like this:

Now it's time to play with the format parameter. To begin with, I would say to increase the font size and use the small caps. After all, those strings are the labels of the sections, so we have to add some emphasis. It's easy to do, just use the commands \large\scshape in the format. So our declaration will be

\titleformat{\section}{\large\scshape}{}{0em}{}

The result is the following:

You may notice something strange: the title "Personal Info" is typeset as justified. Whatever is the reason, we can specify our titles has to be ragged on the right. So we can change the format to:

\titleformat{\section}{\large\scshape\raggedright}{}{0em}{}

Let's take a look now:

As final touch, we can add a separator line. To do so we should add the command \titlerule after each title. If you remember, the last two parameters of the \titleformat are meant to specify materials that goes before and after, respectively, the titles. The definition now becomes:

\titleformat{\section}{\large\scshape\raggedright}{}{0em}{}[\titlerule]

We just specified the last parameter, in a way that a title rule will be appended (after) the titles. The parameter is not mandatory, so when it appears, has to be wrapped in square braces and not in curly ones. The result is the following:

I think we are pretty much done with the section titles. Hereafter I show how their look changed along the tutorial:

For the third part, see you in seven years.

Next Page »