Composing and typesetting a funding proposal using LyX (SSHRC/ NSERC /CIHR)

This is one of the geekier posts I’ve written, in the sense that the number of people for whom this might be useful is… small and they are not likely to search for it.

In Canada, submitting an application to the government “Tri-Councils” for  funding of  research costs  involves one of a couple of horrid/laborious (soul-crushing) interfaces for entering one’s C.V. information. However, I have nothing useful to say about that task.

On the other hand, the core of the rest of the proposal (for several types of funding) consists of the following:

  • Some parts which are simply small form entry, online
  • Some parts which consist of unformatted text pasted into a textbox, online. The text size is limited in terms of characters,
  • Some parts which are uploaded as PDF files; their length is limited in terms of number of pages.

For instance, for the 2015 SSHRC Insight Grant there are two of the big text-entry boxes and seven separate PDF sections to upload.  One of those is a list of references. I would like to use a citation manager to make citations across the various PDF sections, and to have the reference list coordinated across them. I would like to have a count of how many characters are in drafts of the character-limited sections. I would like to have appropriate headers and footers which indicate the current page and total number of pages within each PDF section. I would like to prepare everything in one file when I’m writing or sharing drafts for comments.

I imagine I could do most of this in LibreOffice or another office suite pretty straightforwardly, but I want to do it in LyX because that has a nice interface to my BibTeX databases, and because of all the other advantages of LaTeX; I think the output from LaTeX still looks vastly nicer than what everyone not using it seems to produce.

So, I made a short Python script which

  • exports my LyX file to LaTeX;
  • counts the characters in each named text box, and display this in red above the box;
  • exports the text contents of each textbox into a separate, named, paste-ready (ie most newlines removed, etc) file;
  • compiles the LaTeX and BibTeX source into one big PDF file; and
  • extracts the appropriate PDF page ranges into named PDF files ready for upload.

Here it is (it makes command line calls for a POSIX system, of course):

#!/usr/bin/python
"""
Compose your funding application in LyX; use this to create the web-ready components.

NSERC, CIHR, SSHRC funding agencies in Canada have funding applications on the WWW that require some text entry (text boxes, with limits by number of characters) and some PDF inclusions (with limits by number of pages). It's nice to draft the whole thing in one document, making use of bibliographic citation and reference automation, etc, so this is for doing that.

Put "\usepackage{color}" in the preamble of your LyX document.
Put, for example,
"begin{countbox}{summary}{3800 characters}" inside an ERT box (ie source code insert)
to note the start of a character-count section, and "end{countbox}" at its end.

Then run this python file on your lyx doc. It will count the characters of each text box region and display them in the compiled pdf.

It will export the text of your text boxes in paste-friendly (removing carriage returns) format.

It will separate out the various PDF submissions which must be separated (some customization needed for this last part).

"""
import sys
infile=sys.argv[1] # '/home/meuser/funding/SSHRC-2015/SSHRCapp.lyx
import os
SP='./tmp/' # Scratch path
pp,ff=os.path.split(infile) # pathname and filename
pp+='/'
os.system("lyx --export-to pdflatex "+SP+ff+".tex "+pp+ff+'.lyx')

# Now parse .tex file; find "boxes" with length limits:

tex=open(SP+ff+'.tex').read()
import re
boxes=re.findall('begin{countbox}{(.*?)}{(.*?)}(.*?)end{countbox}',tex, re.DOTALL)
for onebox in boxes:
 toreplace='begin{countbox}{'+onebox[0]+'}{'+onebox[1]+'}'+onebox[2]+'end{countbox}'
 thetext=onebox[2]
 LL=len(thetext.replace('\n',' '))
 replacement=' {\\LARGE\\color{red} [%d characters/%s]}\n\n'%(LL,onebox[1])+thetext+'\n{\\LARGE\\color{red} END:BOX} \n'
 tex=tex.replace(toreplace,replacement)
 # Also save the text, with newlines removed!
 detexed=thetext.replace('\n\n','|||').replace('\n',' ').replace(' ',' ').replace('|||','\n')
 with open('tmp-'+onebox[0]+'-box.txt','wt') as fout:
 fout.write(detexed)

with open(SP+ff+".tex",'wt') as fout:
 fout.write(tex)

# Now compile and display the PDF:
syscmd='latexmk -pdf -pv -aux-directory='+SP+' -output-directory='+SP+' '+SP+ff+' && cp -a '+SP+ff+'.pdf '+pp
print(syscmd)
os.system(syscmd)

# And now explode out the PDF files. This requires hard-coding the page ranges and section names, below (just once, before submission)
explodePages=[
 [4,9,'details',], # Detailed description
 [11,11,'knowledge',], # KB
 [13,16,'team'], # Team
 [18,19,'budget'],
 [23,26,'contributions'],
 [27,31,'references'],
 ]
from cpblUtilities import fileOlderThan
for sss,ttt,nn in explodePages:
 if fileOlderThan('tmp-pp-%s.pdf'%nn,pp+ff+'.pdf'):
 syscmd=' pdftk '+pp+ff+'.pdf cat %d-%d output tmp-pp-%s.pdf '%(sss,ttt,nn) 
 print(syscmd)
 os.system(syscmd)
 

This entry was posted in Academia, GNU/linux, LaTeX, LyX. Bookmark the permalink.

Leave a comment