Using Leo to process Latex to Pdf

137 views
Skip to first unread message

mdb

unread,
Sep 23, 2011, 3:59:59 PM9/23/11
to leo-editor
There have been a handful of questions in this group about using Latex
& Leo
and I'd like to encourage more user development in this area.

So below I offer my script for creating a pdf from a latex file to
help new users get started.

I link the script to both a button and a shortcut key and I include a
step to open the result (a pdf file). Suggestions are welcome.

Some program notes:

In the settings section I name the pdf creation program. I use
'pdflatex' (that I think is part of MikTex) to process the tex file.
Other programs could be used, just need to change
runstring = "%s -output-directory=%s %s " % (create_pdf,
odir, fn)

The main trick or value in my script is to find the filename.tex so I
know filename.pdf to open.
The script assumes I am working on a node in the Latex file tree and
the script backtracks to find the node that starts @file, @auto or
@nosent.

A more elegant version would make use of the file path in the @file
headline. I had to set a work directory (wdir) in the Settings section
because of problems with spaces in the path (on a Windows system). I
also use an 'out' subdirectory to hold the tex log and the pdf, but
these files could be in the same work directory as the tex file (just
leave odir empty).

And the latex file is written using c.save() because I could not make
a node specific way work.

I am working (slowly) on a more sophisticated version that would
-- determine if the node held a rst file and first turn this into
Latex
-- open the log file or read it into a node if there is a compiling
error
-- remove the os.chdir(wdir) step and solve the problem with path
spaces in the @file headline
-- find the rst or tex file node (assuming only one) from any current
position

It might be useful to have some settings in the file node that let the
script automatically
basic latex packages, items and definitions for a particular type of
document (Title page, TOC, set date, use the beamer package to create
slides, etc)

And it would be really cool to be able to render TEX to PDF in real
time like viewrendered handles HTML and ReST. That might be asking
too much

================================
Headline:
@button MakePDF @key=Alt-m

Body:
import os

## Settings

## Work directory (wdir) is where the latex file is assumed to be
saved
## Changing to wdir solves problems created by spaces in a Windows
OS path
## and lets the pdf->latex program use only filename.tex (no
path) as an argument
## Output directory (odir) should be a sub-directory of work
directory
## and will hold the pdf file and tex log

wdir= r'C:\Users\fn lname\Desktop\Latex\doc1'
odir= 'out'

create_pdf= 'pdflatex'
validnodes= ('@file', '@auto', '@nosent' )

ready= False
open_pdf= True


## Set base directory
os.chdir(wdir)

## if odir does not exist, make it
try:
os.mkdir(odir)
except:
pass

## Find the current position and move backward on tree to find the
headline
## that names the tex file (in the node headline)
p1 = c.currentPosition()
h1= p1.h
hx=None
hx= h1.split(' ')[0]
while not (hx in validnodes) and not (p1.level()==0):
p1= p1.parent()
h1= p1.h
hx= h1.split(' ')[0]

##Prepare to process file, need path and filename
if (hx in validnodes):
h1=p1.h
h2= h1[len(hx):].strip()
fn2= os.path.split(h2)
fdir= fn2[0]
fn= fn2[-1]
fn1= os.path.splitext(fn)
## Set .tex latex file with path
fn2=os.path.join(wdir,fn)
## Set .pdf output file with path
fpdf= os.path.join(wdir,odir,fn1[0])+'.pdf'
c.save() #used c.save() to re-rewrite node to file,
c.writeFileFromNode() did not work
ready=True
else:
ready=False
g.es('*** Could not process node wiith latex file link')

## Create pdf from tex file
if ready:
os.chdir(wdir)
if odir:
runstring = "%s -output-directory=%s %s " % (create_pdf,
odir, fn)
else:
runstring = "%s %s" % (prog, fn)
g.es('MakePDF using: \n %s' % runstring)
os.system(runstring)

if ready and open_pdf:
# note: pdf opened using the full path + filename.
g.es('Opening PDF: %s' % fpdf)
os.startfile(fpdf)

g.es('*** Done ***')

Edward K. Ream

unread,
Oct 3, 2011, 5:35:00 PM10/3/11
to leo-e...@googlegroups.com
On Fri, Sep 23, 2011 at 2:59 PM, mdb <mdbo...@gmail.com> wrote:
> There have been a handful of questions in this group about using Latex
> & Leo...So below I offer my script for creating a pdf from a latex file to

> help new users get started.

Thanks for this. I've downloaded MikTeX and will play with your script asap.

> I link the script to both a button and a shortcut key and I include a
> step to open the result (a pdf file).   Suggestions are welcome.

Can you put it in scripts.leo? If not, I'll do it for you.

Edward

Edward K. Ream

unread,
Oct 4, 2011, 11:41:33 PM10/4/11
to leo-e...@googlegroups.com
On Fri, Sep 23, 2011 at 2:59 PM, mdb <mdbo...@gmail.com> wrote:
> There have been a handful of questions in this group about using Latex
> & Leo and I'd like to encourage more user development in this area.
>
> So below I offer my script for creating a pdf from a latex file to
> help new users get started.

You did indeed encourage development. Rev 4536 contains a complete
rewrite of the script :-) It's in scripts.leo. A clone of the script
appears at the top level, along with an @@auto node that I used for
testing.

To test, change @@auto to @auto and save, changing the @path node as needed.

The Post Script contains the new docstring, but here are a few notes:

1. The "trick" of finding @<file> nodes, is actually quite easy with
p.isAnyAtFileNode() and p.anyAtFileNodeName().

2. Perhaps I did not emphasize this enough in the docstring: the code
does *not* "compute" the file's contents. Instead, it simply computes
the full path to the input file and the output directory, and passes
these on the pdflatex. However, the script does do a c.save before
calling pdflatex so all external files are up to date.

3. The new script is much more careful about computing file names. It
takes into account @path directives, and resolves relative paths by
making them relative to the directory containing the .leo file.

4. There are two modes of operation, determined by whether a static
file name is given. If not, the script searches for the nearest
ancestor node of the selected node (c.p.self_and_parents()).

**Important** The idea is that you will alter the dictionary returned
by get_options to meet your needs. This is easy in practice. If we
were to turn this script into an official Leo command, we would need
lots of settings to accomplish the same thing. That wouldn't be bad,
but the present way is good for experimentation.

That's about all. In some ways, the code is quite straightforward: it
just invokes pdflatex. The complications arise from the usual gory
details concerning file names and paths.

I shall be happy to make any changes that you might like.

Edward

P.S. Here is the docstring for the script:

'''A script for creating a pdf from a latex file.

There are two modes of operation, static and dynamic, determined by the contents
of **d**, the **option dictionary**, returned by get_options.

**Important**: change get_options as described below to meet your needs.

If d.get('in_fn') exists, the script operates in static mode. Otherwise, the
script operates in dynamic mode.

Static mode
===========

d.get('in_fn') must be the full path to the input file.

If d.get('out_dir') exists, it must be the full path to the output directory.
The out_dir setting is optional. If omitted, output goes to the directory
containing the input file.

Dynamic mode
============

Rather than use d.get('in_fn'), the script finds the nearest @<file> node in
c.p.self_and_parents(). This node, *whatever it is*, is assumed to contain LaTeX
text.

**Important**: if in_fn is a relative path, it is converted to an absolute path
by taking account of any ancestor @path directive. If the resulting path is
still relative, it is taken to be a path relative to the directory containing
the .leo file. Here is the actual code::

c_dir = g.os_path_dirname(c.fileName())
fn = g.os_path_join(c_dir,c.getNodePath(p),fn)

If d.get('out_dir') exists, it may be either an absolute or relative path. If it
is a relative path, it is taken to be a path relative to the path given by the
@<file> node. That is::

out_dir = g.os_path_join(g.os_path_dirname(fn),out_dir)

Other settings
==============

- exe: The full path to the pdf creation program.
'pdflatex' is part of MikTex.

- open_out: True: open the output file automatically after it is created.

- trace: True: output log messages using g.es_print.

The exe setting is a global variable. The open_out and trace settings
are arguments to the makePDF function.

To do
=====

- Add an argument to the command that would have pdflatex run without
user input.

- determine if the node held a rst file and first turn this into Latex.

- open the log file or read it into a node if there is a compiling error.

- It might be useful to have some settings in the file node that let the script


automatically basic latex packages, items and definitions for a particular
type of document (Title page, TOC, set date, use the beamer package to create

slides, etc.)

- It would be really cool to be able to render TEX to PDF in real time like


viewrendered handles HTML and ReST.

Acknowledgements
================

The original script by M.D.Boldin. Rewritten by EKR.
'''

EKR

Edward K. Ream

unread,
Oct 4, 2011, 11:55:39 PM10/4/11
to leo-editor
On Oct 4, 10:41 pm, "Edward K. Ream" <edream...@gmail.com> wrote:

> You did indeed encourage development.  Rev 4536 contains a complete
> rewrite of the script :-)

Oh. I forgot to mention that you must run Leo from a console when
using this script, at least until the script can drive pdflatex in
some kind of unattended mode. As it is now, pdflatex is likely to
hang, waiting for console input. The typical (only?) response is to
hit carriage returns until pdflatex finishes. It's pretty wonky, but
I have no control over that :-)

I'm pretty sure that you had to run the original script from a console
as well...

Edward

mdb

unread,
Oct 16, 2011, 4:28:22 PM10/16/11
to leo-editor
Finally got a chance to try Ed's version of MakePDF
Works well with one small issue

This part of the code (in node: compute_file_names)

if g.os_path_exists(fn) and g.os_path_exists(out_dir):
return fn,out_dir
else:
log('not found: %s' % fn)
return None,None

Flags a problem and based on the log I assumed I had a problem with
the spaces in the path for my tex file

lnstead the problem was the 2nd part of the if : and
g.os_path_exists(out_dir)

out-dir was not pre-created. So changed it to

if not g.os_path_exists(out_dir):
log('Creating OUT dir %s' % out_dir)
g.os.mkdir(out_dir)

if g.os_path_exists(fn) and g.os_path_exists(out_dir):
log('Running')
log(fn)
return fn, out_dir
else:
log('Problem ***')
if not g.os_path_exists(fn):
log('TEX file not found: %s' % fn)
if not g.os_path_exists(out_dir):
log('OUT dir not found: %s' % out_dir)
return None,None

Only changed in my local copy (ie not pushed to launchpad)

Also MakePDF was not in the main branch version of scripts.leo
(revision 4597). Found it in an earlier branch version

Finally, it is not hard to run ascript that converts a @rst node to
tex and then process the tex file
but it seems p.isAnyAtFileNode() does not recognize nodes starting
with @rst. I guess that makes sense, so I will work on creating a
step that translate a @rst node with ReStruct markup to a @file x.tex
node

Edward K. Ream

unread,
Oct 28, 2011, 7:41:04 AM10/28/11
to leo-e...@googlegroups.com
On Sun, Oct 16, 2011 at 3:28 PM, mdb <mdbo...@gmail.com> wrote:
> Finally got a chance to try Ed's version of MakePDF

Thanks for these comments.

> out-dir was not pre-created.

I would suggest honoring the following setting::

@bool create_nonexistent_directories = False

You can do so by calling::

g.makeAllNonExistentDirectories

The arguments are (theDir,c=None,force=False,verbose=True)

g.makeAllNonExistentDirectories will return None if the
create_nonexistent_directories settings is False, or if there was any
other problem creating the directories.

> MakePDF was not in the main branch version of scripts.leo
> (revision 4597).

@@button MakePDF is in scripts.leo, the node::

@thin leoScripts.txt-->Important-->@@button MakePDF

> it seems p.isAnyAtFileNode()  does not recognize nodes starting with @rst.  I guess that makes sense, so I will work on creating a step that translate a @rst node with ReStruct markup  to a @file x.tex node

Possible, or just test p.h.startswith('@rst') in addition to the test
p.isAnyAtFileNode()

Feel free to commit any of your changes to the trunk in scripts.leo.

Edward

yadhu

unread,
Dec 20, 2011, 11:49:31 PM12/20/11
to leo-e...@googlegroups.com
sir i want to convert the imported input file into .dat file how can i done it using geo office?

HansBKK

unread,
Dec 21, 2011, 10:44:01 PM12/21/11
to leo-e...@googlegroups.com
Mr Nath,

I highly recommend you start with this very important howto, written by a very wise man. You will find it very helpful, if not for this one problem then for your success in future learning.

I hope this helps,

Hans

PS to all - I realize l'm teaching that which I most need to learn 8-)

HansBKK

unread,
Dec 21, 2011, 10:47:06 PM12/21/11
to leo-e...@googlegroups.com
Sorry somehow the link got mangled, pretty content-free post without it 8-)

http://catb.org/~esr/faqs/smart-questions.html

Arjan

unread,
Jan 20, 2017, 12:10:38 PM1/20/17
to leo-editor
I'm looking to compile raw latex to pdf from Leo. I wanted to take a look at the mentioned MakePDF script, but I can't find it in the current version of Leo. Has it been removed, or superceded by something else? Any recommendations?

I just have an "@clean myfile.tex" node (with @all), so I think I only need to run `xelatex myfile.tex`, `bibtex myfile`, then `xelatex myfile.tex` again (this is what I do from command line).

Arjan

Edward K. Ream

unread,
Jan 20, 2017, 12:53:28 PM1/20/17
to leo-editor
On Fri, Jan 20, 2017 at 11:10 AM, Arjan <arjan...@gmail.com> wrote:
I'm looking to compile raw latex to pdf from Leo. I wanted to take a look at the mentioned MakePDF script, but I can't find it in the current version of Leo.

​It's in scripts.leo.  Just search for makePDF.

I don't have the slightest memory of this script.  It might have written it...

Edward

Arjan

unread,
Jan 20, 2017, 1:08:58 PM1/20/17
to leo-editor
Oh found it, it looks like Github search doesn't look in .txt files. I searched GitHub and looked manually in the scripts.leo file, but the string "makePDF" is only found in leoScripts.txt.
Reply all
Reply to author
Forward
0 new messages