Showing posts with label latex. Show all posts
Showing posts with label latex. Show all posts

Friday, 4 November 2011

Making single eps file from latex figure

Journals, being the cash-strapped money-printing machines that they are, like to have submissions written in LaTeX, but only in the simplest LaTeX possible.

I like to use LaTeX as much as possible when annotating figures produced by other programs, as then the fonts in my document match those in my figures. This makes it sensible to compose figures within the LateX figure environment. A simple example which collects some sub-figures then labels them would be:

\begin{figure}
\begin{picture}(86,175)(0,0)
  \put(0,140){\includegraphics[width=86mm]{figures-a}}%
  \put(80,144){a}
  \put(0,75){\includegraphics[width=86mm]{figures-b}}%
  \put(80,78){b}
  \put(0,108){\includegraphics[width=86mm]{figures-c}}%
  \put(80,111){c}
\end{picture}
\caption{A multi-figure figure}
\label{f-FigureLabel}
\end{figure}

For final submission, journals like to have single eps files for each figure, so we need a way to make a single eps file from this. The trick is to use the preview and standalone environments. Create a file for the figure (e.g. fig-01.tex) with contents:

\documentclass{standalone}
\usepackage[dvips]{graphicx}
\usepackage[T1]{fontenc}
\usepackage[active,tightpage]{preview}

\begin{document}%
\begin{preview}%
%
\resizebox{86mm}{!}{%
% put \picture{} here
}%
%
\end{preview}%
\end{document}

do not include the \caption or \label, just the code for the figure itself.

Now run:

latex fig-01.tex --output-format=dvi
dvips -E -I 3c -o fig-01.eps fig-01.dvi

to produce a single eps file with cropped boundaries. This can then be included in the main document's figure directly.

Friday, 3 June 2011

Saving me from myself

The great thing about using Perl to schedule the generation of your LaTeX documents, is that you can also use the Perl to catch a bunch of little mistakes that make life unpleasant in non-obvious ways. One of my favourites is to put the \label before the \caption in the figure environment, because, of course, in any sane world you could do that, but not in LaTeX. Thus, Perl to the rescue:

method check_figure_labels {
    my $file = $self->src;
    my ($in_figure, $seen_caption) = 0;
    foreach my $line (read_file($file)) {
      $line =~ s/%.*$//; # strip comments
      given ($line) {
        when (/\\end{document}/) {
          last;
        }
        when (/\\begin{figure}/) {
          $in_figure = 1;
        }
        when (/\\end{figure}/) {
          $seen_caption = 0;
          $in_figure = 0;
        }
        next unless $in_figure;
        when (/\\caption/) {
          $seen_caption = 1;
        }
        when (/\\label{(.*?)}/) {
          die "Label for LATEX figure $1 comes before the \\caption you will hate yourself later\n"
            unless $seen_caption;
        }
      }
    }
}

Also, sometimes I cannot spell the names of famous (and awesome) physicists:

method check_rayleigh {
    my $file = $self->src;
    my $latex = read_file($file);
    if ($latex =~ /raleigh/i) {
       die "YOU ARE A MORON! RAYLEIGH HAS A Y IN IT!";
    }
    return;
}

Sunday, 29 May 2011

In which Alex learns Moose

Today I have decided to learn Moose.  I shall do this by converting my spider-web latex generation master script, now existing in four different incarnations, into an application class.  It will be easy! Or will it?  I liveblog myself, thus:

15:00 Finally decide to be productive (it is Sunday).
15:01 Decide to re-write generate.pl
15:02 type 'perl -MCPAN -e shell' 'install MooseX::Getopt'
15:12 While waiting for Moose to install, decide to liveblog myself.  The install is taking a whole long while...
15:16 Meanwhile, I have written this, which I hope will work:

package MyApp::Generate;
use Moose;
with 'MooseX::Getopt';

has small => (is => 'rw', isa => 'Int', default => 0);

1;

15:23 Still waiting for Moose to build and test and install. I'd like to at least run perl -c on my snippet to see if I'm a fool or not, but as yet, I'm ignorant even of my foolishness.

15:29 Oh, there we are, installed. Time to try the very basic:

use 5.12.0;
use lib "$ENV{HOME}/alexwork/perl/";
use MyApp::Generate;

my $app = MyApp::Generate->new_from_opts();

15:33 Well, that works at least. Now, to make things work. (This might take a while).
15:38 So, I want a list of somethings, but not have it be commandline-able, this can be done using an attribute with a leading underscore:

has '_lib' => (accessor => 'lib', isa => 'ArrayRef[Str]', default => ['lib']);

15:47 Well, that didn't work, an enormous error (can I stop these enormous traces?) tells me I can't have a reference as a default, but I can have a sub to wrap it, so I do that.
16:12 Importing the crufty methods and changing the million script-local my variables into attributes of the class. How do I get a the entries of a HashRef attribute?
16:15 By which I mean, get in a tidy manner. For now I'll just grab it and use it.
16:28 still bashing in methods. Wondering what the output of an 'ArrayRef' attribute will be, a list or a reference. Not immediately clear.
16:35 well, it runs, but I want to have my options just as '--nopdf'. Maybe I can't do this, that would be sad.
16:39 Ah, I need to make the attributes be 'Bool' then MooseX::Getopt figures it out fine. Not all sad, happy even.
16:41 Now having trouble with a builder method. It's getting called, I'm going to find out what with.
16:45 As expected, I'm now in a confused state where I'm not quite sure why this method is being called.
16:46 so it looks like it's being called as part of the ->new_with_options during object construction, so maybe the builder is called when a default value is created...
16:48 Yes, this is so. I've added a guard for the default case.
16:50 I've constructed my object, now I fail to access an ArrayRef attribute correctly. What should it be?
16:51 It is indeed an array reference.
16:53 Now it seems I don't understand what a builder is for. Perhaps I really just need to write my own set_foo which then sets other things (I have an option which sets lots of things).
17:03 Well, I didn't. A builder is a different way to set a default, but to be able to override this in subclasses. I really want a trigger which will then go and set the other attributes.
17:06 Hmm, I can't suggest a trigger to be a method. For now this isn't a problem.

has src => (is => 'rw', isa => 'Str', default => '', trigger => \&_src_set);
sub _src_set {
    my $self = shift;
    my $val = shift;
    return unless defined($val);
    $val =~ s/\.tex$//;
    $self->out($val);
}

17:14 This now works for the first script, let's see if I can impose the class on the other generation routines without too much crying...
17:25 Different journals have their quirks, so it's time for a subclass instead of a slightly different but otherwise the same script.
17:35 Well, that was nice and easy.

Moral of the story: That was really very easy.

Next is to use more than just Moose. I think I like MooseX::Method::Signatures; One trouble, with picking all this up, it's that it's not clear what's worth picking up.

Wednesday, 4 May 2011

Putting comments next to paragraphs in latex and emacs (fix fill-paragraph)

Again, this is just to save this for the edification of my future self.  For the rest of you, do avoid using 30 year old technology if you value achieving anything on a Wednesday.

So, I like to put little comments by my paragraphs in papers I'm writing:

% this is rubbish
blah blah blah


% this is just plain wrong
blah blah blah


% I have checked this and it is ok
dobedobedo bedadadada

Which is very useful, because this is the way to annotate the latex source so that I can understand why I've written what I did.  Now, the annoying thing is that I also like to bounce on M-q when I can't think of anything else to say, so my lovely paragraphs get turned into comments by the default emacs fill-paragraph command:

% I have checked this and it is ok debedobedo
% bedadadada

At which point the text disappears from my output, and I get cranky.

The solution is, of course, very simple but impossible to actually find (get it together google, you are now officially beyond being useless):

Get filladapt.el

Put it into site_lisp

And put this into ~/.emacs:

(require 'filladapt)
(add-hook 'text-mode-hook 'turn-on-filladapt-mode)

Also useful, discovered in an aside, is to associate files not with 'runemacs.exe', but with 'emacsclientw.exe' but then you have to set the environment variable to 'ALTERNATE_EDITOR' to 'path\to\runemacs.exe' OR IT WILL LAUGH AT YOU.

Tuesday, 5 October 2010

LaTeX and windows

Oh yes we hate it we do. LaTeX + Windows = Pain. Well, actually, writing large documents anywhere = pain. Here, though, a trick to make some of the pain go away! (Posted for my future reference.)

First: Perl! Emacs! (If not, this will be senseless...)

Use a perl script to generate your pdf. Easier than a makefile, better than a punch in the face.

When running pdflatex, use the '-synctex=-1' option.

Then, at the end of the generate script, use SumatraPDF to view the file:

exec($pdfview,
'-reuse-instance',
'-inverse-search',
'"c:\\Program Files (x86)\\Emacs\\emacs-23.1\\bin\\emacsclientw.exe +%l %f"',
"$out.pdf"
);

This is fantastic, as it will reopen the pdf where you last looked at it (which is what you probably want) and you get to clicky on bits of the file and get them come up in emacs (which is also what you want to do).

Oh yes.

Wednesday, 18 August 2010

LaTeX doom

Having passed through the part of my PhD where I put everything into a powerpoint and yammer about it to intensely interested audiences, I find myself instead in the part where I have to put things into papers. This means wrestling with LaTeX and spending the bulk of my time fiddling figures into the right format, dimensions, resolution, font and, possibly, the right data. I officially hate type-setting because it's entirely distracting busywork but it's busywork you've just got to do.

Still, some people have hit their heads on this wall before, so I'm extending my sincere thanks to the following things, made by real people, that have made my life a little less stressful recently. Maybe they will help you too...

For making it possible to make mistakes and magically recover without a thousand files marked '-old', '-old-old', '-broken' and '-fixed'. If you don't use version control, you're already lost.

Because no one gets the spacing with units right, and typing $^\circ$ is just too much.

Because I can't remember the magic words.

Because who needs EndNote anyway.

Because clicky and my headache is solved.