Hiển thị các bài đăng có nhãn text-processing. Hiển thị tất cả bài đăng
Hiển thị các bài đăng có nhãn text-processing. Hiển thị tất cả bài đăng

Thứ Sáu, 4 tháng 11, 2016

[xtopdf] Batch convert text files to PDF (with xtopdf and fileinput)

By Vasudev Ram


file1.txt + file2.txt + file3.txt => file123.pdf

I created this new xtopdf app recently. (For those unfamiliar with it, xtopdf (source here) is my open source Python project for PDF generation from other formats and sources. Here is a good high-level overview of xtopdf, describing what it is and can do, its supported input formats, platforms (Windows, Linux, Mac OS X, Unix) and environments (CLI, GUI, Web), etc. The core of the xtopdf project is a library, and what I call xtopdf apps, are applications built using that library.)

This particular app lets you batch-convert multiple text files at a time, to a PDF file. The content of each text file starts on a new page in the PDF file. The program uses xtopdf (which uses ReportLab) and the fileinput module from Python's standard library. The program could be written without using the fileinput module too, and I've done a variant of it that way earlier, but I used fileinput this time for convenience, and to show a use of it.

(BTW, fileinput is a pretty useful module in its own right, for this sort of work - applying the same process (any process, not just PDF generation) to a bunch of input files. fileinput can also read from standard input if no input filenames are specified, but I don't use that feature here. Also, I used 4 functions from the fileinput module, on 4 consecutive lines, in this short program :) - not just for the sake of it, though; it made sense to do so.)

Here is the code, in file BatchTextToPDF.py:
from __future__ import print_function

# BatchTextToPDF.py
# Convert a batch of text files to a single PDF.
# Each text file's content starts on a new page in the PDF file.
# Requires:
# - xtopdf: https://bitbucket.org/vasudevram/xtopdf
# - ReportLab: https://www.reportlab.com/ftp/reportlab-1.21.1.tar.gz
# Author: Vasudev Ram
# Copyright 2016 Vasudev Ram
# Product store: https://gumroad.com/vasudevram
# Web site: https://vasudevram.github.io
# Blog: http://jugad2.blogspot.com

import sys
import fileinput
from PDFWriter import PDFWriter

def usage(prog_name):
sys.stderr.write("Usage: {} outfile.pdf infile1.txt ...".format(prog_name))

def main():

if len(sys.argv) < 3:
usage(sys.argv[0])
sys.exit(0)

try:
pw = PDFWriter(sys.argv[1])
pw.setFont('Courier', 12)
pw.setFooter('xtopdf: https://google.com/search?q=xtopdf')

for line in fileinput.input(sys.argv[2:]):
if fileinput.filelineno() == 1:
pw.setHeader(fileinput.filename())
if fileinput.lineno() != 1:
pw.savePage()
pw.writeLine(line.strip('\n'))

pw.savePage()
pw.close()
except Exception as e:
print("Caught Exception: type: {}, message: {}".format(\
e.__class__, str(e)))

if __name__ == '__main__':
main()
Here is a sample run of the program. I created 3 text files, text1.txt through text3.txt, with the respective number of lines in them. Then ran the command:
python BTTP123.pdf text1.txt text2.txt text3.txt
This created the PDF file BTTP123.pdf. Cropped screenshots of the 1st and 3rd (last) page of the PDF are below:

1st page:


3rd page:


In this example I've closed the PDFWriter instance manually, using pw.close(), but PDFWriter can also be used with the Python with statement, since I had added context manager support to PDFWriter earlier. I use the with statement in some of my xtopdf app examples, and not in others, to show that both possibilities exist.

Here is a Guide to installing and using xtopdf, including creating simple PDF e-books with it.

- Enjoy.

- Vasudev Ram - Online Python training and consulting

Get updates on my software products / ebooks / courses.

Jump to posts: Python   DLang   xtopdf

Subscribe to my blog by email

My ActiveState recipes

FlyWheel - Managed WordPress Hosting



Thứ Năm, 19 tháng 5, 2016

i18nify any word with this Python utility

By Vasudev Ram

I18Nify

While I was browsing some web pages, reading a word triggered a chain of thoughts. The word had to do with internationalization (often shortened to i18n by developers, because there are 18 letters between the first i and the last n). That's how I thought of writing this small program that "i18nifies" a given word - not in the original sense, but in the way shown below - making a numeronym out of the word.

Here is i18nify.py:
from __future__ import print_function
'''
Utility to "i18nify" any word given as argument.

You Heard It Here First (TM):
"i18nify" signifies making a numeronym of the given word, in the
same manner that "i18n" is a numeronym for "internationalization"
- because there are 18 letters between the starting "i" and the
ending "n". Another example is "l10n" for "localization".
Also see a16z.

Author: Vasudev Ram
Copyright 2016 Vasudev Ram - https://vasudevram.github.io
'''

def i18nify(word):
# If word is too short, don't bother, return as is.
if len(word) < 4:
return word
# Return (the first letter) plus (the string form of the
# number of intervening letters) plus (the last letter).
return word[0] + str(len(word) - 2) + word[-1]

def get_words():
for words in [ \
['a', 'bc', 'def', 'ghij', 'klmno', 'pqrstu', 'vwxyz'], \
['the', 'quick', 'brown', 'fox', 'jumped', 'over', 'the', \
'lazy', 'dog'], \
['all', 'that', 'glitters', 'is', 'not', 'gold'], \
['often', 'have', 'you', 'heard', 'that', 'told'], \
['jack', 'and', 'jill', 'went', 'up', 'the', 'hill', \
'to', 'fetch', 'a', 'pail', 'of', 'water'],
]:
yield words

def test_i18nify(words):
print("\n")
print(' '.join(words))
print(' '.join([i18nify(word) for word in words]))

def main():
for words in get_words():
test_i18nify(words)
print

if __name__ == "__main__":
main()
Running it with:
$ python i18nify.py
gives this output:
a bc def ghij klmno pqrstu vwxyz
a bc def g2j k3o p4u v3z

the quick brown fox jumped over the lazy dog
the q3k b3n fox j4d o2r the l2y dog

all that glitters is not gold
all t2t g6s is not g2d

often have you heard that told
o3n h2e you h3d t2t t2d

jack and jill went up the hill to fetch a pail of water
j2k and j2l w2t up the h2l to f3h a p2l of w3r

Notes:

- The use of yield makes function get_words a generator function. It is not strictly needed, but I left it in there. I could have used "return words" instead of "yield words".

- Speaking of generators, also see this post: Python generators are pluggable.

- The article on numeronyms (link near top of post) reminded me of run-length encoding

Anyway, e3y :)

- Vasudev Ram - Online Python training and consulting

Signup to hear about my new courses and products.

My Python posts     Subscribe to my blog by email

My ActiveState recipes