diff --git a/Makefile b/Makefile index e9e8250..cf8382e 100644 --- a/Makefile +++ b/Makefile @@ -1,5 +1,6 @@ -START = noxxxnote nodraft noblue +START = noxxxnote nodraft blue END = missing +PYTEX = $(shell pwd)/pytex/ CLASS = $(PYTEX)/cls/sig-alternate.cls all: paper ABSTRACT diff --git a/pytex/.gitignore b/pytex/.gitignore new file mode 100644 index 0000000..5acb80a --- /dev/null +++ b/pytex/.gitignore @@ -0,0 +1,4 @@ +/.pydevproject +/.project +*.pyc +*.swp diff --git a/pytex/README b/pytex/README new file mode 100644 index 0000000..086150a --- /dev/null +++ b/pytex/README @@ -0,0 +1,19 @@ +To use, create a PYTEX environment variable and point it at the directory +where you install these files. + +This contains a combined Python-Latex build system useful for generating +scientific documents. + +bin/ contains useful Python tools for generating and building Latex +documents. + +cls/ contains useful class files for NSF proposals, letters, etc. Most of +these are based on the Memoir Latex package. + +make/ contains a Make system designed to be used with these Python tools. + +skel/ contains a set of example directories using each of the class files in +cls/. + +docs/ contains the Memoir Latex package and a reminder about how to write NSF +broader impact sections. diff --git a/pytex/bin/.gitignore b/pytex/bin/.gitignore new file mode 100644 index 0000000..9a0cd45 --- /dev/null +++ b/pytex/bin/.gitignore @@ -0,0 +1,2 @@ +/flatex +*.pyc diff --git a/pytex/bin/blank b/pytex/bin/blank new file mode 100755 index 0000000..a9eb773 --- /dev/null +++ b/pytex/bin/blank @@ -0,0 +1,7 @@ +#!/usr/bin/env python + +import sys,subprocess +subprocess.check_output("convert -size %dx%d -density 300 -format pdf xc:white -bordercolor black -border 1x1 %s" % \ + ((int(float(sys.argv[2]) * 300.) - 1), + (int(float(sys.argv[3]) * 300.) - 1), + sys.argv[1]), shell=True) diff --git a/pytex/bin/clean b/pytex/bin/clean new file mode 100755 index 0000000..f306cc3 --- /dev/null +++ b/pytex/bin/clean @@ -0,0 +1,27 @@ +#!/usr/bin/env python + +import lib, sys +from optparse import OptionParser +import re + +parser = OptionParser() +(options, args) = parser.parse_args() + +if len(args) < 2: + sys.exit(1) + +if args[0] == "-": + dirty_string = sys.stdin.read() +else: + dirty_string = open(args[0], "r").read() + +match = re.search(r"""(?ms)\s*(?P.*?)\s*""", dirty_string) +if match != None: + dirty_string = match.group('excerpt') + +if args[1] == "-": + outfile = sys.stdout +else: + outfile = open(args[1], "w") + +outfile.write(lib.clean(dirty_string).encode('utf8')) diff --git a/pytex/bin/flatex.c b/pytex/bin/flatex.c new file mode 100644 index 0000000..aacfbf7 --- /dev/null +++ b/pytex/bin/flatex.c @@ -0,0 +1,601 @@ +/*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* + * flatex.c - + * Flatten a latex file into a single file, by explicitly including + * the files inclued by \include and \input commands. Also, if bibtex is + * beeing used, then includes the .bbl file into the resulting file. Thus, + * creating a stand alone latex file that can be emailed to someone else. + * + * Compile : gcc -o flatex flatex.c + * Tested on : Linux + gcc + * By : Sariel Har-Peled + * Email : sariel@math.tau.ac.il + * WEB Page : http://www.math.tau.ac.il/~sariel/flatex.html + * Status : You can do whatever you like with this program. please + * email me bugs & suggestions. + * + * To do : Add support to the includeonly command. + *----------------------------------------------------------------------- + * FLATEX 1.21, 1994, 1996, by Sariel Har-Peled. + * + * flatex - create a single latex file with no include/inputs + * + * flatex [-v] [-x FileName] [files] + * -v Verbose, display file structure. + * -x Unflatex: extract files from archive + * -q Quiet mode. Cleaner output but -x can not be used. + * -b Do not insert bibiliography file(.bbl) + * + * Flatex page: http://www.math.tau.ac.il/~sariel/flatex.html + *----------------------------------------------------------------------- + * History: + * 26/8/96, 1.21 + * Fixed bug with includegraphics command. +\*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/ + +#include +#include +#include +#include +#include + + +/*====================================================================== + * Static constants. +\*======================================================================*/ +#define LINE_SIZE 1000 +#define FALSE 0 +#define TRUE 1 +#define USE_ARGUMENT( X ) ((void)X) + + +/*====================================================================== + * Types +\*======================================================================*/ +typedef struct { + char verbose; + char fBibInsert, fQuiet; + int cSpecialInputLevel; + char szFullName[ LINE_SIZE ]; +} structFlags; + + +/*====================================================================== + * Static prototypes. +\*======================================================================*/ +static void flatIt( FILE * flOut, + char * szInName, + int level, + structFlags * pFlags ); +static void replaceExt( char * str, char * ext ); + + +/*====================================================================== + * Start of Code +\*======================================================================*/ + + +static void spacesByLevel( int level ) +{ + while ( level > 0 ) { + printf( " " ); + level--; + } +} + + +static void printHelp( void ) +{ + printf( "flatex - create a single latex file with no include/inputs\n" ); + printf( "\n\tflatex [-v] [-x FileName] [files]\n" ); + printf( "\t\t-v\tVerbose, display file structure.\n" ); + printf( "\t\t-x\tUnflatex: extract files from archive\n" ); + printf( "\t\t-q\tQuiet mode. Cleaner output but -x can not be used.\n" ); + printf( "\t\t-b\tDo not insert bibiliography file(.bbl)\n" ); + printf( "\nFlatex page: http://www.math.tau.ac.il/~sariel/flatex.html\n" ); + printf( "\n" ); +} + + +static void * myMalloc( unsigned int size ) +{ + void * ptr; + + ptr = malloc( size ); + if ( ptr == NULL ) { + fprintf( stderr, "Not enough memory" ); + exit( -1 ); + } + + return ptr; +} + + +static void handleIncludeCommand( char * line, + char * lpszInclude, + FILE * flOut, + int level, + structFlags * pFlags ) +{ + char * lpszBrace, * lpszName, * lpszEndBrace; + char ch, fInput = 0; + + lpszBrace = NULL; + + if ( strncmp( lpszInclude, "\\input", 6 ) == 0 ) { + lpszBrace = lpszInclude + 6; + fInput = 1; + } else + if ( strncmp( lpszInclude, "\\include", 8 ) == 0 ) { + lpszBrace = lpszInclude + 8; + } + + ch = *lpszInclude; + *lpszInclude = 0; + fputs( line, flOut ); + *lpszInclude = ch; + + lpszEndBrace = strchr( lpszBrace, '}' ); + if ( *lpszBrace != '{' || lpszEndBrace == NULL ) { + fprintf( stderr, "ERROR: Expected brace not found.\n\n\tline:%s\n", + line ); + exit( -1 ); + } + + *lpszEndBrace = 0; + lpszName = (char *)myMalloc( LINE_SIZE ); + strcpy( lpszName, lpszBrace + 1 ); + if ( ! fInput ) + replaceExt( lpszName, ".tex" ); + + flatIt( flOut, lpszName, level + 1, pFlags ); + + lpszEndBrace++; + while ( *lpszEndBrace ) { + *line++ = *lpszEndBrace++; + } + *line = 0; + + free( lpszName ); +} + + +static char isBefore( char * lpszA, char * lpszB ) +{ + if ( lpszB == NULL ) + return TRUE; + if ( lpszA == NULL ) + return FALSE; + + if ( (int)( lpszA -lpszB ) < 0 ) { + return TRUE; + } + return FALSE; +} + + +static FILE * fopenTex( char * file, + char * mode ) +{ + FILE * fl; + + fl = fopen( file, mode ); + if ( fl != NULL ) + return fl; + + replaceExt( file, ".tex" ); + fl = fopen( file, mode ); + + return fl; +} + + +static char isTexFileExists( char * file ) +{ + FILE * fl; + + fl = fopenTex( file, "rt" ); + if ( fl != NULL ) { + fclose( fl ); + return 1; + } + + return 0; +} + + +static void addTexExt( char * file ) +{ + FILE * fl; + + fl = fopenTex( file, "rt"); + if ( fl != NULL ) + fclose( fl ); +} + + +static char is_str_prefix( char * str, char * prefix ) +{ + int len; + + if ( str == NULL || prefix == NULL ) + return 0; + + len = strlen( prefix ); + + return (strncmp( str, prefix, len ) == 0); +} + + +static void flatIt( FILE * flOut, + char * pSzInName, + int level, + structFlags * pFlags ) +{ + FILE * flIn; + char * str, * lpszInput, * lpszInclude, * line, * lpszRem, *inc; + char * lpszLine, * lpszRemark, * lpszBib, * lpszBibStyle; + char * lpszNewCommand, * lpszName; + char cont; + char repFlag; + char szInName[ 100 ]; + char fInclude; + + strcpy( szInName, pSzInName ); + + addTexExt( szInName ); + if ( ! pFlags->fQuiet ) + fprintf( flOut, "%%%cflatex input: [%s]\n", + pFlags->cSpecialInputLevel > 0? '*' : ' ', + szInName ); + if ( pFlags->verbose ) { + printf( "\t" ); + spacesByLevel( level ); + printf( "%s\n", szInName ); + } + + line = (char *)myMalloc( LINE_SIZE ); + lpszLine = (char *)myMalloc( LINE_SIZE ); + lpszRemark = (char *)myMalloc( LINE_SIZE ); + + flIn = fopenTex( szInName, "rt" ); + if ( flIn == NULL ) { + fprintf( stderr, "Unable to open file: %s\n", szInName ); + exit( -1 ); + } + + *lpszRemark = 0; + while ( ! feof( flIn ) ) { + str = fgets( line, LINE_SIZE, flIn ); + if ( str == NULL ) + break; + + fInclude = FALSE; + + strcpy( lpszLine, line ); + + lpszRem = strchr( line, '%' ); + if ( lpszRem != NULL ) { + strcpy( lpszRemark, lpszRem ); + *lpszRem = 0; + } + + do { + cont = 0; + lpszInput = strstr( line, "\\input" ); + + lpszBib = strstr( line, "\\bibliography" ); + lpszBibStyle = strstr( line, "\\bibliographystyle" ); + + if ( pFlags->fBibInsert && + ( lpszBib != NULL || lpszBibStyle != NULL ) ) { + lpszName = (char *)myMalloc( LINE_SIZE ); + + strcpy( lpszName, lpszLine ); + strcpy( lpszLine, pFlags->fQuiet? "%" : "%FLATEX-REM:" ); + strcat( lpszLine, lpszName ); + + if ( lpszBibStyle != NULL ) { + strcpy( lpszName, pFlags->szFullName ); + replaceExt( lpszName, ".bbl" ); + + pFlags->cSpecialInputLevel++; + flatIt( flOut, lpszName, level + 1, pFlags ); + pFlags->cSpecialInputLevel--; + + if ( pFlags->verbose ) { + printf( "\t" ); + spacesByLevel( level + 1 ); + printf( "(Bibiliography)\n" ); + } + } + break; + } + + inc = line; + do { + repFlag = 0; + lpszInclude = strstr( inc, "\\include" ); + + if ( is_str_prefix( lpszInclude, "\\includeversion" ) + || is_str_prefix( lpszInclude, + "\\includegraphics" ) ) { + repFlag = 1; + inc = lpszInclude + 1; + continue; + } + + if ( is_str_prefix( lpszInclude, "\\includeonly" ) ) { + fprintf( stderr, "WARNING: \"\\includeonly\" command " + "ignored\n" ); + inc = lpszInclude + 1; + repFlag = 1; + continue; + } + if ( lpszInclude != NULL && isalpha( lpszInclude[ 8 ] ) ) { + fprintf( stderr, + "\nWarning: include-like(?) command ignored" + " at line:\n\t%s", lpszLine ); + inc = lpszInclude + 1; + repFlag = 1; + continue; + } + } while ( repFlag ); + + if ( isBefore( lpszInput, lpszInclude ) ) + lpszInclude = lpszInput; + + if ( lpszInclude != NULL ) { + lpszNewCommand = strstr( line, "\\newcommand" ); + if ( lpszNewCommand == NULL ) { + handleIncludeCommand( line, lpszInclude, flOut, level, + pFlags ); + cont = 1; + fInclude = TRUE; + } + } + } while ( cont ); + if ( fInclude ) { + strcat( line, lpszRemark ); + fputs( line, flOut ); + } else + fputs( lpszLine, flOut ); + } + + fclose( flIn ); + fputs( "\n", flOut ); + + if ( ! pFlags->fQuiet ) + fprintf( flOut, "%% flatex input end: [%s]\n", szInName ); + + free( line ); + free( lpszLine ); + free( lpszRemark ); +} + + +static void replaceExt( char * str, char * ext ) +{ + int len, ind; + + len = strlen( str ); + ind = len - 1; + while ( ind >= 0 && str[ ind ] != '.' && str[ ind ] != '\\' && + str[ ind ] != '/' ) + ind--; + + if ( ind >= 0 && str[ ind ] == '.' ) { + str[ ind ] = 0; + } + + strcat( str, ext ); +} + +static char strCmpPrefixAndCopy( char * line, + char * str, + char * outName ) +{ + char * pos, * pPreLine; + + pPreLine = line; + + pos = strstr( line, str ); + if ( pos == NULL ) + return 0; + + line = pos + strlen( str ); + strcpy( outName, line ); + pos = strchr( outName, ']' ); + + if ( pos == NULL ) { + fprintf( stderr, "Error encountered in line: [%s]", pPreLine ); + exit( -1 ); + } + *pos = 0; + + return 1; +} + + +static void writeFile( FILE * flIn, + char * pOutName, + int level ) +{ + FILE * flOut; + char * lpszLine; + char line[ LINE_SIZE ], outName[ LINE_SIZE ]; + char flag; + + outName[ 0 ] = 0; + + if ( pOutName == NULL ) { + flOut = NULL; + printf( "Scanning for flatex archive start...\n" ); + } else { + flOut = fopen( pOutName, "wt" ); + if ( flOut == NULL ) { + fprintf( stderr, "Unable to open file: %s", pOutName ); + exit( -1 ); + } + spacesByLevel( level ); + printf( "[%s]\n", pOutName ); + } + + do { + lpszLine = fgets( line, LINE_SIZE, flIn ); + if ( lpszLine == NULL ) + break; + + flag = strCmpPrefixAndCopy( line, "% flatex input end: [", outName ); + if ( flag ) { + if ( flOut == NULL ) { + fprintf( stderr, "Something is wrong!!!!\n" ); + exit( -1 ); + } + //spacesByLevel( level ); + // printf( "/\n" ); + //printf( "Writing [%s] done\n", outName ); + break; + } + + flag = strCmpPrefixAndCopy( line, "% flatex input: [", outName ); + if ( flag ) { + writeFile( flIn, outName, level + 1 ); + if ( flOut != NULL ) + fprintf( flOut, "\\input{%s}\n", outName ); + } else { + flag = strCmpPrefixAndCopy( line, "%*flatex input: [", outName ); + if ( flag ) { + writeFile( flIn, outName, level + 1 ); + } else { + if ( flOut != NULL ) { + if ( strncmp( line, "%FLATEX-REM:", 12 ) == 0 ) + fputs( line + 12, flOut ); + else + fputs( line, flOut ); + } + } + } + } while ( ! feof( flIn ) ); + + if ( flOut != NULL ) + fclose( flOut ); +} + + +static void flatOutFile( char * fileName, + structFlags * pFlags ) +{ + FILE * flIn; + + USE_ARGUMENT( pFlags ); + + flIn = fopen( fileName, "rt" ); + if ( flIn == NULL ) { + fprintf( stderr, "Unable to open file: %s", fileName ); + exit( -1 ); + } + + writeFile( flIn, NULL, 0 ); + + fclose( flIn ); +} + + +static void flatFile( char * fileName, + structFlags * pFlags ) +{ + char * szInName, * szOutName; + int inLen; + FILE * flOut; + + szInName = (char *)myMalloc( LINE_SIZE ); + szOutName = (char *)myMalloc( LINE_SIZE ); + + strcpy( szInName, fileName ); + if ( ! isTexFileExists( szInName ) ) { + fprintf( stderr, "--Unable to open file: [%s]\n", fileName ); + exit( -1 ); + } + + inLen = strlen( szInName ); + if ( inLen < 4 || ( szInName[ inLen ] != '.' && + strcmp( szInName + inLen - 4, ".tex" ) != 0 ) ) { + strcat( szInName, ".tex" ); + } + + printf( "input file: [%s]\n", szInName ); + + strcpy( pFlags->szFullName, szInName ); + + strcpy( szOutName, szInName ); + replaceExt( szOutName, ".flt" ); + + flOut = fopen( szOutName, "wt" ); + if ( flOut == NULL ) { + fprintf( stderr, "Unable to open file: %s", szOutName ); + exit( -1 ); + } + + flatIt( flOut, szInName, 0, pFlags ); + + fclose( flOut ); + + printf( "\n\tFile: \"%s\" generated\n", szOutName ); +} + + +static char isFlag( char * str, char ch ) +{ + if ( str[ 0 ] == '-' && + ( str[ 1 ] == ch || str[ 1 ] == toupper( ch ) ) + && ( str[ 2 ] == 0 ) ) + return TRUE; + + return FALSE; +} + + +int main( int argc, char * argv[] ) +{ + int ind; + structFlags sFlags; + + printf( "FLATEX 1.21, 1994, 1996, by Sariel Har-Peled.\n\n" ); + if ( argc == 1 ) + printHelp(); + + sFlags.verbose = FALSE; + sFlags.fBibInsert = TRUE; + sFlags.cSpecialInputLevel = 0; + *sFlags.szFullName = 0; + sFlags.fQuiet = FALSE; + + for ( ind = 1; ind < argc; ind++ ) { + if ( isFlag( argv[ ind ], 'v' ) ) { + sFlags.verbose = TRUE; + continue; + } + if ( isFlag( argv[ ind ], 'b' ) ) { + sFlags.fBibInsert = FALSE; + continue; + } + if ( isFlag( argv[ ind ], 'q' ) ) { + sFlags.fQuiet = TRUE; + continue; + } + if ( isFlag( argv[ ind ], 'x' ) ) { + flatOutFile( argv[ ind + 1 ], &sFlags ); + ind++; + continue; + } + + flatFile( argv[ ind ], &sFlags ); + } + return 0; +} + +/*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* + * + * flatex.c - End of File +\*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/ + diff --git a/pytex/bin/lib.py b/pytex/bin/lib.py new file mode 100644 index 0000000..8604b86 --- /dev/null +++ b/pytex/bin/lib.py @@ -0,0 +1,77 @@ +import re + +def clean(inlines): + + removecomments = re.compile(r"^(%.*)$", re.M) + inlines = removecomments.sub("", inlines) + fixpercents = re.compile(r"\\%", re.M) + inlines = fixpercents.sub("%", inlines) + removetex = re.compile(r"~?\\(((sub)*)section(\*?)|cite|chapter|thispagestyle)\*+\{([^\}]+)\}", re.M) + inlines = removetex.sub("", inlines) + removetex2 = re.compile(r"\\(clearpage)", re.M) + inlines = removetex2.sub("", inlines) + keeptex = re.compile(r"\\(textit|textbf|texttt|textsc|sloppypar)\{([^\}]+)\}", re.M) + while True: + beforelines = inlines + inlines = keeptex.sub(r"\2", inlines) + if inlines == beforelines: + break + keeptex2 = re.compile(r"\{\\scshape\s+([^\}]+)\}", re.S | re.M) + inlines = keeptex2.sub(r"\1", inlines) + quotes = re.compile(r"(``|'')", re.M) + inlines = quotes.sub(r'"', inlines) + phonelab_macro = re.compile(r"\\PhoneLab{}", re.M) + inlines = phonelab_macro.sub("PhoneLab", inlines) + sciwinet_macro = re.compile(r"\\SciWiNet{}", re.M) + inlines = sciwinet_macro.sub("SciWiNet", inlines) + composite_macro = re.compile(r"\\ComPoSiTe{}", re.M) + inlines = composite_macro.sub("ComPoSiTe", inlines) + agiledroid_macro = re.compile(r"\\AG{}", re.M) + inlines = agiledroid_macro.sub("AgileDroid", inlines) + wifi_macro = re.compile(r"\\wifi{}", re.M) + inlines = wifi_macro.sub("Wifi", inlines) + keep_together = re.compile(r"~", re.M) + inlines = keep_together.sub(" ", inlines) + en_dashes = re.compile(r"([^-])--([^-])", re.M) + inlines = en_dashes.sub(u"\\1\u2013\\2", inlines) + em_dashes = re.compile(r"([^-])---([^-])", re.M) + inlines = em_dashes.sub(u"\\1\u2014\\2", inlines) + enum = re.compile(r"\\begin\{enumerate\}(.*?)\\end\{enumerate\}", re.S | re.M) + + class Counter: + def __init__(self): + self.count = 0 + def reset(self): + self.count = 0 + def increment(self, matchObject): + self.count += 1 + return str(self.count) + "." + + def match(m): + c = Counter() + item = re.compile(r"\\item") + text = item.sub(c.increment, m.group(1)) + c.reset() + return text + inlines = enum.sub(match, inlines) + + removeitem = re.compile(r"~?\\item", re.M) + inlines = removeitem.sub("", inlines) + removeflushenumbf = re.compile(r"\\begin\{flushenumbf\}\s+(.*?)\s+\\end\{flushenumbf\}", re.S | re.M) + inlines = removeflushenumbf.sub(r"\1", inlines) + removebeginabstract = re.compile(r"\\begin\{abstract\}\s+(.*?)\s+\\end\{abstract\}", re.S | re.M) + inlines = removebeginabstract.sub(r"\1", inlines) + + lines = re.split(r'\s{2,}', inlines) + + while re.match(lines[0], r"^\s*$"): + lines = lines[1:] + if len(lines) == 0: + return "" + while re.match(lines[-1], r"^\s*$"): + lines = lines[:-1] + if len(lines) == 0: + return "" + + output = '\n\n'.join([re.sub(r'\n', ' ', line) for line in lines]) + return output diff --git a/pytex/bin/number b/pytex/bin/number new file mode 100755 index 0000000..ce99bfe --- /dev/null +++ b/pytex/bin/number @@ -0,0 +1,65 @@ +#!/usr/bin/env python + +from optparse import OptionParser +import sys, subprocess, time, re, shlex, tempfile, os + +parser = OptionParser() +parser.add_option("-s", "--skip", dest="skip", type=int, default=0, help="number of initial pages to skip (default 0)") +parser.add_option("-a", "--avoid", dest="avoid", type=str, default="", help="pages to avoid, comma separated (default \"\")") +(options, args) = parser.parse_args() + +avoid = options.avoid.split(",") +avoid = [int(a) for a in avoid] + +infile = args[0] +outfile = args[1] +ininfo = subprocess.Popen("pdfinfo \"%s\"" % (infile), shell=True, stdout=subprocess.PIPE).communicate()[0] +origpages = int(re.search(r'Pages:\s+(\d+)', ininfo).group(1)) +numpages = origpages - options.skip + +latexstart = r'''\documentclass[11pt]{memoir} +\usepackage{times} +\maxdeadcycles=1000 +\setstocksize{11in}{8.5in} +\settrimmedsize{11in}{8.5in}{*} +\settrims{0pt}{0pt} +\setlrmarginsandblock{1in}{1in}{*} +\setulmarginsandblock{1in}{1in}{*} +\setheadfoot{0.1pt}{36pt} +\setmarginnotes{0.5cm}{1.5cm}{0.1cm} +\checkandfixthelayout +\copypagestyle{number}{headings} +\makeoddhead{number}{}{}{} +\makeevenhead{number}{}{}{} +\makeoddfoot{number}{}{\thepage}{} +\makeevenfoot{number}{}{\thepage}{} +\begin{document} +\pagestyle{number}''' + +latexend = r'''\end{document}''' + +startdir = os.getcwd() +tempdir = tempfile.mkdtemp() +subprocess.call("cp \"%s\" \"%s\"/A.pdf" % (infile, tempdir), shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) +os.chdir(tempdir) +latexfile = open('B.tex', 'w') +print >>latexfile, latexstart +for a in range(numpages): + print >>latexfile, r'''\mbox{} +\newpage''' +print >>latexfile, latexend +latexfile.close() +subprocess.Popen("pdflatex --interaction=nonstopmode B.tex", shell=True, stdout=subprocess.PIPE).communicate()[0] +subprocess.Popen(r"pdftk A.pdf burst output A%03d.pdf", shell=True, stdout=subprocess.PIPE).communicate()[0] +subprocess.Popen(r"pdftk B.pdf burst output B%03d.pdf", shell=True, stdout=subprocess.PIPE).communicate()[0] +Boffset = options.skip +for Aindex in range(origpages): + Aindex += 1 + if (Aindex <= Boffset) or ((Aindex - Boffset) in avoid): + subprocess.Popen(r"cp A%03d.pdf C%03d.pdf" % (Aindex, Aindex), shell=True, stdout=subprocess.PIPE).communicate()[0] + else: + subprocess.Popen(r"pdftk A%03d.pdf background B%03d.pdf output C%03d.pdf" % (Aindex, Aindex - Boffset, Aindex), shell=True, stdout=subprocess.PIPE).communicate()[0] +subprocess.Popen(r"pdftk %s output D.pdf" % (' '.join(["C%03d.pdf" % (i + 1) for i in range(origpages)])), shell=True, stdout=subprocess.PIPE).communicate()[0] +subprocess.call("cp D.pdf \"%s\"/\"%s\"" % (startdir, outfile), shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) + +os.chdir(startdir) diff --git a/pytex/bin/rotateandstitch b/pytex/bin/rotateandstitch new file mode 100755 index 0000000..3c86a74 --- /dev/null +++ b/pytex/bin/rotateandstitch @@ -0,0 +1,33 @@ +#!/usr/bin/env python + +from optparse import OptionParser +import sys, subprocess, time, re, shlex + +parser = OptionParser() +(options, args) = parser.parse_args() + +pagesize = re.compile(r'Page size:\s+(\d+)\s+x\s+(\d+)') +files = [] +outpdf = args.pop(0) +for arg in args: + output = subprocess.Popen("pdfinfo \"%s\"" % (arg), shell=True, stdout=subprocess.PIPE).communicate()[0] + pagematch = pagesize.search(output) + if pagematch == None: + continue + if pagematch.group(1) < pagematch.group(2): + files.append(arg) + continue + infile = arg + outfile = re.sub(r'.pdf', '.rotate.pdf', infile) + output = subprocess.Popen("pdftk \"%s\" cat 1-endW output \"%s\"" % (infile, outfile), shell=True, stdout=subprocess.PIPE).communicate()[0] + files.append(outfile) + +def order(pdf): + nummatch = re.search(r'(\d+)', pdf) + if nummatch == None: + return 0 + else: + return int(nummatch.group(1)) + +files = sorted(files, key=order) +output = subprocess.Popen("pdftk %s cat output \"%s\"" % (' '.join(['"%s"' % (file) for file in files]), outpdf), shell=True, stdout=subprocess.PIPE).communicate()[0] diff --git a/pytex/bin/texincludes b/pytex/bin/texincludes new file mode 100755 index 0000000..7206fcd --- /dev/null +++ b/pytex/bin/texincludes @@ -0,0 +1,105 @@ +#!/usr/bin/env python + +import sys,re,glob,StringIO,os,tempfile,filecmp,shutil +from optparse import OptionParser + +parser = OptionParser() +(options, args) = parser.parse_args() + +if len(args) < 1: + sys.exit(1) + +files = glob.glob("*.tex") + +if len(files) == 0: + sys.exit(0) + +outfile = tempfile.NamedTemporaryFile(delete=False) + +docfile = re.compile(r"""(?m)^(?!\s*%).*\\begin\{document\}""") +inputs = re.compile(r"""(?m)^(?!\s*%).*\\input{(.*)}""") +bibs = re.compile(r"""(?m)^(?!\s*%).*\\bibliography\{(.*)\}""") +citations = re.compile(r"""^(?m)^(?!\s*%).*\\(?:no)?cite""") +graphics = re.compile(r"""(?m)^(?!\s*%).*\\includegraphics(\[.*?\])?\{(.*?)\}""") +withpdf = re.compile(r"^.*\.pdf$") +nobibtex = re.compile(r"""(?m)^% !NOBIBTEX!""") + +nobibtexs = {} + +output = StringIO.StringIO() +allnames = [] + +for f in files: + lines = open(f, "r").read() + if not docfile.search(lines): + continue + input_files = [] + bib_files = [] + graphic_files = [] + toprocess = [f] + + docitations = False + dontbibtex = False + fbasename = os.path.splitext(f)[0] + + while len(toprocess) > 0: + try: + lines = open(toprocess[0], "r").read() + if nobibtex.search(lines): + nobibtexs[toprocess[0]] = True + else: + nobibtexs[toprocess[0]] = False + if len(citations.findall(lines)) > 0: + docitations = True + toprocess += inputs.findall(lines) + b = bibs.finditer(lines) + for m in b: + allbibs = m.group(1).split(",") + for bib in allbibs: + bib_files.append(bib + ".bib") + g = graphics.finditer(lines) + for m in g: + if withpdf.match(m.group(2)): + graphic_files.append(m.group(2)) + else: + path, ext = os.splitext(m.group(2)) + if ext == '': + graphic_files.append(path + ".pdf") + else: + graphic_files.append(m.group(2)) + except: + True + input_files.append(toprocess.pop(0)) + + all_files = input_files + all_files.extend(graphic_files) + all_files.extend(bib_files) + for file in args[1:]: + all_files.append(file) + allnames.append(fbasename) + + print >>output, "%s : LOG := %s.log" % (fbasename, fbasename) + print >>output, "%s : PDF := %s.pdf" % (fbasename, fbasename) + print >>output, "%s : $(START) %s.pdf $(END)" % (fbasename, fbasename) + print >>output, "%s.ps : %s.pdf" % (fbasename, fbasename) + print >>output, "%s.pdf %s.blg : .deps %s" % (fbasename, fbasename, " ".join(all_files)) + if docitations and not nobibtexs[f]: + print >>output, "\tpdflatex -shell-escape %s" % (f) + print >>output, "\tbibtex %s" % (fbasename) + print >>output, "\tpdflatex -shell-escape %s" % (f) + print >>output, "\tpdflatex -shell-escape %s" % (f) + else: + print >>output, "\tpdflatex -shell-escape %s" % (f) + print >>output, "\tpdflatex -shell-escape %s" % (f) + tex_files = [all_file for all_file in all_files if all_file.endswith(".tex")] + print >>output, "spell-%s : %s" % (fbasename, " ".join(tex_files),) + print >>output, "\tispell %s" % (" ".join(tex_files),) + +print >>outfile, output.getvalue(), +print >>outfile, "PDFS = %s" % (" ".join([n + ".pdf" for n in allnames])) +outfile.close() + +if not os.path.exists(args[0]) or not filecmp.cmp(outfile.name, args[0], shallow=False): + shutil.move(outfile.name, args[0]) +else: + os.unlink(outfile.name) diff --git a/pytex/bin/wc b/pytex/bin/wc new file mode 100755 index 0000000..9628524 --- /dev/null +++ b/pytex/bin/wc @@ -0,0 +1,55 @@ +#!/usr/bin/env python + +import lib +import sys, re, os +from optparse import OptionParser + +parser = OptionParser() +parser.add_option("-o", "--overonly", dest="overonly", action="store_true", default=False, help="only display sections over the word count (default False)") +(options, args) = parser.parse_args() + +if len(args) < 2: + sys.exit(1) + +if args[0] == "-": + inlines = sys.stdin.read() +else: + try: + inlines = open(args[0], "r").read() + except: + sys.exit(1) + +if args[1] == "-": + outfile = sys.stdout +else: + try: + outfile = open(args[1], "w") + except: + sys.exit(1) + +clean = re.compile(r'(.*?)', re.S) +index = 1 +for f in clean.finditer(inlines): + description = f.group(1) + max = int(f.group(2)) + count = len(lib.clean(f.group(3)).split()) + if not options.overonly or count > max: + if count > max: + char = "*" + else: + char = " " + print "%c %2d. M:%3d C:%3d %s" % (char, index, max, count, description) + index += 1 +clean = re.compile(r'(.*?)', re.S) +index = 1 +for f in clean.finditer(inlines): + description = f.group(1) + max = int(f.group(2)) + count = len(lib.clean(f.group(3)).strip()) + if not options.overonly or count > max: + if count > max: + char = "*" + else: + char = " " + print "%c %2d. M:%3d C:%3d %s" % (char, index, max, count, description) + index += 1 diff --git a/pytex/make/Makerules b/pytex/make/Makerules new file mode 100644 index 0000000..d096da8 --- /dev/null +++ b/pytex/make/Makerules @@ -0,0 +1,109 @@ +SHELL := /bin/bash +export TEXINPUTS :=.:$(PYTEX)/cls: + +# 16 Nov 2010 : GWA : Watch all .tex files below this directory to determine +# when to rebuild the dependencies. + +TEXFILES = $(shell find . -name "*.tex") + +# 16 Nov 2010 : GWA : Kind of a nasty hack, but we use a special Python +# script to regenerate make rules which are then loaded by the +# include below. This was the least nasty way of getting +# complex Latex dependencies to rebuild properly, while also +# enabling/disabling Bibtex as needed. + +.deps: $(TEXFILES) + @$(PYTEX)/bin/texincludes .deps $(CLASS) +include .deps + +%.ps : %.pdf + acroread -toPostScript $< + +allclean: rulesclean + @/bin/rm -f .deps + +rulesclean: + @/bin/rm -f *.dvi *.aux *.ps *~ *.log *.lot *.lof *.toc *.blg *.bbl url.sty *.out *.bak $(PDFS) + +# 16 Nov 2010 : GWA : Special dummy targets below. + +xxxnote: + @echo "\\newcommand{\\XXXnote}[1]{\\textcolor{red}{\\bfseries XXX: #1}}" > .xxxnote-new + @if [ -n "`diff -N 2>/dev/null .xxxnote .xxxnote-new`" ]; then\ + mv .xxxnote-new .xxxnote; \ + else\ + rm -f .xxxnote-new; \ + fi + +noxxxnote: + @echo "\\newcommand{\\XXXnote}[1]{}" > .xxxnote-new + @if [ -n "`diff -N 2>/dev/null .xxxnote .xxxnote-new`" ]; then\ + mv .xxxnote-new .xxxnote; \ + else\ + rm -f .xxxnote-new; \ + fi + +draft: + @echo "\\def\\isdraft{1}" > .draft-new + @if [ -n "`diff -N 2>/dev/null .draft .draft-new`" ]; then\ + mv .draft-new .draft; \ + else\ + rm -f .draft-new; \ + fi + +nodraft: + @echo "" > .draft-new + @if [ -n "`diff -N 2>/dev/null .draft .draft-new`" ]; then\ + mv .draft-new .draft; \ + else\ + rm -f .draft-new; \ + fi + +blue: + @echo "\\def\\isblue{1}" > .blue-new + @if [ -n "`diff -N 2>/dev/null .blue .blue-new`" ]; then\ + mv .blue-new .blue; \ + else\ + rm -f .blue-new; \ + fi + +noblue: + @echo "" > .blue-new + @if [ -n "`diff -N 2>/dev/null .blue .blue-new`" ]; then\ + mv .blue-new .blue; \ + else\ + rm -f .blue-new; \ + fi + +.embed.pdf: $(PDF) + gs -dSAFER -dNOPLATFONTS -dNOPAUSE -dBATCH -sDEVICE=pdfwrite -sPAPERSIZE=letter -dCompatibilityLevel=1.4 -dPDFSETTINGS=/printer -dCompatibilityLevel=1.4 -dMaxSubsetPct=100 -dSubsetFonts=true -dEmbedAllFonts=true -sOutputFile=.embed.pdf -f $(PDF) + @cp .embed.pdf $(PDF) + +embed: .embed.pdf + +MISSINGREFERENCES = $(strip $(shell grep Ref $(LOG) | awk '{print substr($$4, 2, length($$4) - 2)}')) +MISSINGCITATIONS = $(strip $(shell grep Cit $(LOG) | awk '{print substr($$4, 2, length($$4) - 2)}')) +missing: + @if [ "$(MISSINGREFERENCES)" != "" ]; then\ + echo "-------------------------------------------------------------";\ + echo "Missing references:";\ + echo "-------------------------------------------------------------";\ + echo $(MISSINGREFERENCES);\ + fi + @if [ "$(MISSINGCITATIONS)" != "" ]; then\ + echo "-------------------------------------------------------------";\ + echo "Missing citations:";\ + echo "-------------------------------------------------------------";\ + echo $(MISSINGCITATIONS);\ + fi + +missing-fail: missing + @if [ "$(MISSINGREFERENCES)" != "" ]; then false; fi + @if [ "$(MISSINGCITATIONS)" != "" ]; then false; fi + +pages: $(PDF) + @pdfinfo $(PDF) 2>/dev/null | grep "Pages" | awk '{print "$(PDF)", $$2;}' + +# 16 Nov 2010 : GWA : Phony targets. + +.PHONY : pages rulesclean missing-fail missing xxxnote noxxxnote draft nodraft blue noblue clean allclean all figures wc