Saturday, February 11, 2012

Strange fonts and spacing in a ".doc" file

My wife, the lovely Carol, is a writer. Unsurprisingly, she uses word-processing software, NeoOffice in particular. Her grad school profs use Microsoft Word, so what she sends them are ".doc" files.

One of the annoying things about so-called WYSIWYG word processors is that you can't quite tell what's going on. The image at right, for example, shows somewhat uneven spacing between lines. The gap between the first two lines is a little wider than the gap between the second and third. And the 2nd line from the bottom is a little farther away from its predecessor.

Where do these things come from? Well, if you jam a half-dozen ".doc" files together, you might have a diversity of font faces and sizes. Or if you copy/paste some text from one document (which started off with a larger font size for example) you might find font sizes varying even within a paragraph.

Now a close look at the 2nd-to-last line reveals that the closing quotation mark looks a little large. Indeed, if you position the cursor right there and watch the appropriate toolbar, you might see the font size window change from '10' to '12' and back. This explains why that line is a little lower than you'd otherwise expect. But what about the 2nd line? The same careful trick with the cursor would show that one of the '.'s had a larger font size.

So in a 112-page document, would you want to look carefully at the line spacings and watch the font-size on every single character to see where the font size changed? Or grab the entire document and change the font size to 10pt? That last trick might actually work, but what if you have some characters in a different font—"Albany AMT" for example instead of "Verdana"?

If you know the entire document shall be of one font, one size, one style (etc) then that would work, but often there are words or sentences in italics, or a section in a different font. So the brute-force method feels just a little risky.

So what's a techno-weenie to do with this? Since this particular techno-weenie wrote this article about manipulating ODF files with Python, the natural thing is to write a Python script. I'll spare you the gruesome details but basically I did this:

  1. Use openoffice/Neooffice to convert a ".doc" file to ".odt"
  2. Use unzip to unpack the ".odt" file, and examine "content.xml" using emacs (or firefos)
  3. Write a Python script to examine and modify properties
  4. Play with it a bit, and save the modified version...
  5. Use openoffice/Neooffice to convert the ".odt" file back to ".doc"
So items #1 and #5 are just a matter of "Save as"; for #2 I said:
collin@p3:/mnt/home/collin/kstyle/tmp> unzip ../CreativeProjectFeb10.odt 
Archive:  ../CreativeProjectFeb10.odt
 extracting: mimetype                
   creating: Configurations2/statusbar/
  inflating: Configurations2/accelerator/current.xml  
   creating: Configurations2/floater/
   creating: Configurations2/popupmenu/
   creating: Configurations2/progressbar/
   creating: Configurations2/menubar/
   creating: Configurations2/toolbar/
   creating: Configurations2/images/Bitmaps/
  inflating: layout-cache            
  inflating: content.xml             
  inflating: styles.xml              
 extracting: meta.xml                
  inflating: Thumbnails/thumbnail.png  
  inflating: Thumbnails/thumbnail.pdf  
  inflating: settings.xml            
  inflating: META-INF/manifest.xml   
collin@p3:/mnt/home/collin/kstyle/tmp> 
Then I pointed firefox at /mnt/home/collin/kstyle/tmp/content.xml and observed that some text styles specified different fonts, different sizes, etc.
collin@p3:~/kstyle> ./kstyles.py CreativeProjectFeb10.odt junk.odt -l | grep -v '<'
T1: 701 spans
T2: 77 spans
T3: 2 spans
T4: 10 spans
T5: 2 spans
T6: 4 spans
T7: 18 spans
T8: 8 spans
T9: 13 spans
T10: 1 spans
T11: 221 spans
T12: 1 spans
T13: 112 spans
T14: 2 spans
T15: 6 spans
T16: 1 spans
collin@p3:~/kstyle> 
The script gives the characteristics of the styles, which I've filtered out above. Anyway, here's a slightly less uncensored version, looking at style T15; I've folded the output lines so you can see 'em all:
collin@p3:~/kstyle> ./kstyles.py CreativeProjectFeb10.odt junk.odt -l -dT15
T1: 701 spans
…
T15: 6 spans
        <style:style style:family="text" style:name="T15"><style:text-properties 
fo:font-size="12pt" fo:font-style="italic" style:font-name-asian="Albany AMT" 
style:font-name-complex="Albany AMT" style:font-size-asian="12pt" 
style:font-style-asian="italic" style:font-style-complex="italic"/></style:style>
T16: 1 spans
…
=== Text style T15:
. 
. 
. 
. 
. 
.”
collin@p3:~/kstyle> 
So the font size is too big here -- also it's the wrong font! And did you notice that the big font was just a '.' in several cases? How could you ever find those?

After looking at a bunch of them, I eventually decided I could collapse 3 and 5 to 2, and most of the rest to 1. I ended up with this:

collin@p3:~/kstyle> ./kstyles.py CreativeProjectFeb10.odt d.odt T3=T2  T5=T2  T6=T1 \
T7=T1 T8=T1 T9=T1 T10=T1 T11=T1 T12=T1 T13=T1  T14=T1 T15=T2
Changing style "T3" to "T2".
Changing style "T5" to "T2".
Changing style "T6" to "T1".
Changing style "T7" to "T1".
Changing style "T8" to "T1".
Changing style "T9" to "T1".
Changing style "T10" to "T1".
Changing style "T11" to "T1".
Changing style "T12" to "T1".
Changing style "T13" to "T1".
Changing style "T14" to "T1".
Changing style "T15" to "T2".
collin@p3:~/kstyle> 
The output file is called "d.odt" (due to typing laziness), and it looked fine. Here's the script:
    1   #!/usr/bin/python -utt
    2   # vim:et:sw=4
    3   '''Unzip an ODF document and list or kill/substitute text styles.
    4
    5   Usage: kstyles INPUT OUTPUT [-l] [-dsty1]... [sty1=sty2]...
    6       -l
    7           list styles
    8
    9       -dsty1
   10           Show text spans having property sty1
   11
   12       sty1=sty2
   13           Text elements which are sty1 are assigned sty2
   14
   15   $Id: kstyles.py,v 0.4 2012/02/12 01:25:52 collin Exp collin $
   16   '''
   17
   18   import codecs
   19   import os
   20   import sys
   21   import xml.dom.minidom
   22   import zipfile
   23
   24   CONTENT = 'content.xml'
   25   STYLE = 'style:style'
   26   SFAMILY = 'style:family'
   27   SNAME = 'style:name'
   28   TSTYLENAME = 'text:style-name'
   29   TSPAN = 'text:span'
   30
   31   def main(args):
   32       '''Unpack ODF/XML (zipfile).  Discover text styles.
   33       Find # of text elements which have each style; if "-l", display.
   34       If "-dXX", display text:spans with style XX
   35       For each "sty1=sty2" provided:
   36           change any text elements of sty1 to sty2'''
   37       try:
   38           infile_name = args[0]
   39           outfile_name = args[1]
   40           ops = args[2:]
   41       except:
   42           usage()
   43       if not os.path.exists(infile_name):
   44           print "Couldn't find input file %s" % INFILE
   45           usage()
   46       INFILE = zipfile.ZipFile(infile_name, 'r')
   47       # Sanity-check input file before doing anything else.
   48       if CONTENT not in INFILE.namelist():
   49           print "Couldn't find %s in %s's zip archive" % (CONTENT, infile_name)
   50           print 'Is it an ODF file?'
   51           sys.exit(1)
   52       # Read and parse content.
   53       cdata = INFILE.read(CONTENT)
   54       cdom = xml.dom.minidom.parseString(cdata)
The above checks parameters, unpacks the ".odt" file, and ensures that CONTENT (viz., "content.xml"; see line 24) is there. Then it creates a document object model (DOM) from what's in the content.
   55       # Find text styles
   56       cstyles = cdom.getElementsByTagName(STYLE)
   57       text_styles = [X for X in cstyles
   58                           if X.getAttribute(SFAMILY) == 'text']
   59       text_style_names = [X.getAttribute(SNAME) for X in text_styles]
   60       # print text_styles
   61       style_counts = dict()
   62       for astyle in text_style_names:
   63           style_counts[astyle] = 0
   64       for aspan in [X for X in cdom.getElementsByTagName(TSPAN)
   65                       if X.hasAttribute(TSTYLENAME)]:
   66           style_counts[aspan.getAttribute(TSTYLENAME)] += 1
The above looks for all the text-styles, and counts how many "text:span" items refer to each text-style.
   67
   68       if '-l' in ops:
   69           for idx in range(len(text_styles)):
   70               astyle = text_style_names[idx]
   71               print '%s: %d spans' % (astyle, style_counts[astyle])
   72               if style_counts[astyle]:
   73                   print '\t%s' % text_styles[idx].toxml()
   74           for astyle in [X for X in style_counts if X not in text_style_names]:
   75               print '??? %s: %d spans' % (astyle, style_counts[astyle])
   76           while '-l' in ops:
   77               ops.remove('-l')
...and this part prints the information, if you want it
   78
   79       # Before the following fun stuff, make stdout be utf8
   80       utf8_enc = codecs.getencoder('utf8')
I need line 80 to avoid encoding errors. The next part handles each operation (or "command") -- "-dT15" for example.
   81
   82       for op in ops:
   83           if op.startswith('-d'):
   84               astyle = op[2:]
   85               if astyle not in style_counts:
   86                   print "*** Couldn't find style %s" % astyle
   87                   continue
   88               print "=== Text style %s:" % astyle
   89               for aspan in [X for X in cdom.getElementsByTagName(TSPAN)
   90                               if X.getAttribute(TSTYLENAME) == astyle]:
   91                   print utf8_enc(aspan.firstChild.data)[0]
   92               continue
So that was the "-d" part -- dump out the text spans referring to a particular style.
   93           styles = op.split('=')
   94           if len(styles) > 2:
   95               print >> sys.stderr, "Can't parse: '%s'" % op
   96               usage()
   97           if len(styles) < 2:
   98               print >> sys.stderr, 'Not yet implemented: %s' % op
   99               continue
  100           print 'Changing style "%s" to "%s".' % (styles[0], styles[1])
  101           for aspan in [X for X in cdom.getElementsByTagName(TSPAN)
  102                           if X.getAttribute(TSTYLENAME) == styles[0]]:
  103               aspan.setAttribute(TSTYLENAME, styles[1])
Line 93 interprets "T15=T1" and assigns styles[0]="T15", styles[1]="T1". Then lines 101-103 find all the text-spans matching "T15" and does the setAttribute to change it to "T1". The last part puts the content back into a new ODF file:
  104
  105       if os.path.exists(outfile_name):
  106           os.unlink(outfile_name)
  107       OUTFILE = zipfile.ZipFile(outfile_name, 'w')
  108       for oldinfo in INFILE.infolist():
  109           fname = oldinfo.filename
  110           fsize = oldinfo.file_size
  111           #print 'archive member "%s", %d bytes' % (fname, fsize)
  112           if fsize > 0:
  113               if fname == CONTENT:
  114                   OUTFILE.writestr(fname, utf8_enc(cdom.toxml())[0])
  115               else:
  116                   OUTFILE.writestr(fname, INFILE.read(fname))
  117           else:
  118               OUTFILE.writestr(fname, '')
  119       OUTFILE.close()
  120
  121
  122   def usage():
  123       print >> sys.stderr, __doc__
  124       sys.exit(1)
  125
  126   if __name__ == '__main__':
  127       main(sys.argv[1:])

Update: May 2014

I ran into this issue again with a collection of short stories. A single document (a short story, to which a half-dozen other stories were appended via snarf'n'barf with the mouse) had something like 35 or 36 text styles, which were largely unnecessary. I had to update the above script (which by now I've renamed kstyles.py, but I don't remember what "k" meant) to account for a few things
  • Sometimes line 91 didn't work:
       91                   print utf8_enc(aspan.firstChild.data)[0]
    because firstChild wasn't Plain Old Text; it was this:<text:s/>
  • Sometimes a text style couldn't be found in content.xml; I had to look in styles.xml (no, really); who would have known?
  • While I was in there, I added some sanity checks and updated the documentation
You can see the resulting script at http://cpwriter.net/kstyles.py-v0.6 Wait, did I say documentation?
 
 
kstyles
index
/mnt/home/collin/projects/kstyle/kstyles.py

Unzip an ODF document and list or kill/substitute text styles.
 
Usage: kstyles INPUT OUTPUT [-l] [-dsty1]... [sty1=sty2]...
    INPUT
        name of file to read
 
    OUTPUT
        name of file to write new (modified) file
 
    -l
        list styles
 
    -dsty1
        Show text spans having property sty1
 
    sty1=sty2
        Text elements which are sty1 are assigned sty2
 
$Id: kstyles.py,v 0.6 2014/05/10 22:19:13 collin Exp collin $

 
Modules
       
codecs
os
sys
xml
zipfile

 
Functions
       
main(args)
Unpack ODF/XML (zipfile).  Discover text styles.
Find # of text elements which have each style; if "-l", display.
If "-dXX", display text:spans with style XX
For each "sty1=sty2" provided:
    change any text elements of sty1 to sty2
usage()

 
Data
        CONTENT = 'content.xml'
SFAMILY = 'style:family'
SNAME = 'style:name'
STYLE = 'style:style'
STYLES = 'styles.xml'
TSPAN = 'text:span'
TSTYLENAME = 'text:style-name'

Saturday, January 28, 2012

Yeah right Newt

Newt, you say that a 30% income tax rate on the highest earning Americans would destroy jobs. I have three questions for you.
  1. We now know that Mitt paid about 14% on his 2010 income of $21.7 million. If Mitt had instead paid 30% (i.e., about $6½ million), how many jobs would would have been lost? Put differently, how many additional jobs did Mitt create because he paid about $3 million in income tax rather than $6½ million?
  2. If a 30% income tax on the rich is a job-killing figure, then how in the world did our economy grow at all from World War II through the 1970s, when tax rates on high-income Americans were much higher?
  3. Why do you and other Republicans keep repeating this same damnable lie? Do you think, "It worked for Hitler, so it'll work for us"?
You lying scoundrel! You whitewashed tomb! You reprobate! I'm embarrassed to be a Republican.

"What do you want me to do for you?" (Mark 10:51)

Or, How should we pray?

Before going into the Big Game, should an athlete pray for victory? Or should s/he pray for grace and faith whatever the outcome? Should parents pray that their investments will do well, so they can afford to send their kids to college? Or should they pray for wisdom and creativity regardless of the financial outcome?

The PC (pietistically correct) answer is to pray only for acceptance of God's will however things turn out, but that's not the biblical answer: both by example (Paul in 2 Cor. 12:7-9, David in 2 Samuel 15:31, and countless others) and by command (Philippians 4:6) the Bible tells us to pray specifically for what we want. There are of course conditions (not selfishly James 4:3; according to his will 1 John 5:14; abide in Christ and his words in us John 15:7; etc.) but God wants us to be honest with him. Yes, he already knows what we need (Matthew 6:8), yet we're told to ask. And here's the best part: sometimes he gives far more than we ask—or even could imagine asking as Paul tells us in Ephesians 3. I have a couple of examples. First, you may recall that Jesus was crucified together with two criminals.

One of the criminals who hung there hurled insults at him: “Aren’t you the Messiah? Save yourself and us!”

But the other criminal rebuked him. “Don’t you fear God,” he said, “since you are under the same sentence? We are punished justly, for we are getting what our deeds deserve. But this man has done nothing wrong.”

Then he said, “Jesus, remember me when you come into your kingdom.[a]”

Jesus answered him, “Truly I tell you, today you will be with me in paradise.”

Luke 23:39-43
I think this a remarkable passage. The “other criminal” asked only that Jesus remember him. But Jesus replies, “Today you will be with me in paradise.”

Imagine this: here's a guy who once was a little boy, playing in the fields or on the streets. Somehow his life turned to robbery (Matthew 27:38, Mark 15:27) and eventually to ignonimous execution. At the last, he realizes that his life is over; he begs for a little pity from Jesus, the Righteous One.

Imagine what light must have come into this man's final hours on earth when he heard that unbelievable good news from Jesus: today he would be in Paradise with Jesus himself!

Why didn't he say, "Lord, let me be with you in your kingdom" in the first place? (For this question I'm indebted to Mailis Janatuinen and her excellent Glad Tidings Bible Studies.) I think it's because he asked only what he could imagine. Thanks be to God, he can do far far beyond anything we can ask or even imagine.

The second example, which I must have heard some decades ago, concerns a young girl who had severe problems with her feet due to some disease. Her father didn't have much money for the very expensive orthopedic shoes she would need. I think he bought a lottery ticket or bet on some horse race or something like this. He prayed fervently that God would bless his gamble.

Or maybe he was a salesman and he prayed that God would enable him to sell more of his product, or maybe he asked his boss for a raise. I don't remember exactly what it was, but he prayed with great energy and sincerity.

Well, his horse lost, his lottery ticket didn't pay off, he didn't exceed his quota... and with a heavy heart he took his daughter to the doctor. He had no idea how to pay for the very expensive orthopedic shoes, and he didn't understand why his prayers weren't answered.

Then came the astonishing news: his little girl's feet were inexplicably healed; no orthopedic shoes would be necessary. As far as the doctor could tell, this girl would be just fine with regular shoes.

This father had prayed that his bet/ticket/efforts would succeed, but they didn't. Instead he got something so much better. Why didn't he pray for his little girl's feet to be healed?

Like the criminal in Luke 23, he could only pray what he could imagine. Also like the criminal in Luke 23, the father received far more than he could ask or imagine.

God sometimes does that, and we get glimpses of his goodness, the abundance riches of his grace in kindness toward us.

The question always arises, "Why didn't God do that for me?"—or for any number of other people who prayed and saw nothing happen? I'll tell you: I don't know. Nobody else knows, either. And here's something else: it's not necessarily your fault, and you are not alone.

They were stoned, they were sawn in two, [were tempted,] were slain with the sword. They wandered about in sheepskins and goatskins, being destitute, afflicted, tormented— of whom the world was not worthy. They wandered in deserts and mountains, in dens and caves of the earth.
Hebrews 11:37-38 (NJKV)
But he does answer sometimes, and gives such astonishing and extravagant gifts that we are amazed, and wonder, and worship.

CDs of Shakespeare for (almost) free!

The lovely Carol wants to listen to a few Shakespeare plays for her MFA program, and asked me how to get CDs of them. Yeah, I can hear you now. "CDs? That's so 20th century!"

Two words for you: car stereo. "Ruby," our 2004 Subaru, has a CD player but no mp3 player and no aux input jack. The other thing about the car stereo is that, unlike an iPod, you can't leave it on a bench somewhere. If you're in the car, the car stereo's there.

All-righty then. A search on "twelfth night audio" (no quotes) led me to LibriVox site and the download page for King Lear, which you see at right. As you can see, the play runs about 3½ hours, and there are five mp3 files, one per act.

So far so good, but there are two issues we want to deal with. First, a music CD holds what, 65 or 70 minutes, right? Notice the duration of the various parts of the play:

  • Act 1 – 00:53:42
  • Act 2 – 00:38:56
  • Act 3 – 00:38:38
  • Act 4 – 00:42:54
  • Act 5 – 00:28:52
How do we put these on CDs? Act I goes on one CD. Great, fantastic. Act 2 goes on another -- but that leaves 20 minutes, maybe 30 minutes unused at the end of that CD. But not 38:38 -- not enough time for Act 3! Will Act 4 and Act 5 fit together on a single CD? Maybe.

So that's the first issue. The second issue is, if the CD's in the car stereo and somebody wants to change the CD, then how can you recover your place? If one track is 28 or 42 or 53 minutes long, it's rather a pain. So we want to have track divisions at maybe 10-minute intervals.

So here's what we're gonna do. First, change each mp3 file into a "wav" file. For this, we'll use "lame" (meaning "lame ain't no mp3 encoder"). Then we'll use the compact "snd" together with "sox" to split the "wav" files into 10-minute pieces. The plan then would be to put these onto CDs as follows:

  1. Act 1 + 12 minutes of act 2
  2. about 27 minutes of act2 + act 3
  3. acts 4 and 5
Well, we'll see how that works out. So after downloading all the mp3s, we convert them to wavs by typing:
lame --decode Downloads/king_lear_1_shakespeare.mp3 /tmp/k1.wav
and so on for the other 4 files.

Next, we want to divide each of these into (about) ten-minute segments. Where exactly do we divide them, and how? To answer the "where" we'll use snd. You may want to use something else, but "snd" works for me. In the image at left, you can see what looks like a pretty quiet spot about 612 seconds in. The x-axis shows just 611.0 and 613.0 and a bunch of tick-marks; you have to interpolate... well, or you can position the cursor and click, and you'll get a little number near the lower-left corner; you can see it if you enlarge the image -- "612.5030" -- let's just call it 612.5. We'll look for quiet spots around 1200 seconds in, 1800 seconds in, etc., and break the ".wav" file at those points.

But one thing at a time. Given the first break-point, at 612.5 seconds, I type:
sox /tmp/k1.wav -c 2 Desktop/k1.1.wav trim 0 =10:12.5
which is explained as

  • sox
    the program name.
  • /tmp/k1.wav
    the input file
  • -c 2
    Make the output have two channels (stereo) as CDs have
  • Desktop/k1.1.wav
    the output file
  • trim 0 =10:12.5
    Trim 0 off the front, and everything past 10:12.5 (612.5 seconds) from the start.
The next breakpoint looks to be about 1206.2 seconds, which is 20:06.2 so I'll type
sox /tmp/k1.wav -c 2 Desktop/k1.2.wav trim 10:12.5 =20:06.2
and so on for the rest of the 53-minute act. Here are the files for Act I:
collin@p3:/mnt/home/collin> ls -o /tmp/k1.wav; ls -o Desktop/k1.*.wav
-rw-r--r-- 1 collin 284258442 2012-01-23 20:30 /tmp/k1.wav
-rw-r--r-- 1 collin 108045044 2012-01-23 20:48 Desktop/k1.1.wav
-rw-r--r-- 1 collin 104728724 2012-01-27 21:08 Desktop/k1.2.wav
-rw-r--r-- 1 collin 107039564 2012-01-27 21:18 Desktop/k1.3.wav
-rw-r--r-- 1 collin 103723244 2012-01-27 21:19 Desktop/k1.4.wav
-rw-r--r-- 1 collin  85906844 2012-01-27 21:20 Desktop/k1.5.wav
-rw-r--r-- 1 collin  59073640 2012-01-27 21:20 Desktop/k1.6.wav
You may wonder why it is that the six files come to about 56 Mbytes whereas the original /tmp/k1.wav was closer to 28 Mbytes; it's because the output files are stereo, which I think we need for recording on CDs.

I do the same with the rest of King Lear's ".wav" files, aiming for 66 minutes (my guess for how much will fit on a blank CD) on each. The last CD has over 70 minutes, but it still just might fit -- I'm finding out now.

For actually burning the CDs, well, my CD-writer is broken, so I'm using a mac mini, which belongs to the lovely Carol. It's pretty easy to do on a Mac using iTunes (we are running OS X 10.6). Here are the steps:

  1. File → Add to Library
    then select the files (in this case k1.1.wav up to k5.3.wav
  2. Select 65-70(?) minutes' worth of tracks, then File → New playlist from selection
    Then name each playlist
  3. right-click on a playlist and "burn CD from playlist"
And Bob's yer uncle. To summarize, we
  • get free MP3 files from librivox (or wherever);
  • convert to 44.1khz stereo WAV files using lame
  • Separate into tracks (if needed) using snd and sox
  • import into iTunes
  • create iTunes playlists
  • burn CD image using iTunes

Wednesday, January 18, 2012

Re-reading the Psalms

One of our pastors recommended Peterson's book Answering God. Early on, Peterson says we have three languages; really they're overlapping subsets but I agree they're broad categories of speech:
  • The simple expression of a need—not very articulate but often effective. A baby's cry is an example of this language.
  • Another language is what conveys information and ideas.
  • Persuasive, motivational speech is the third.
According to Peterson, the Psalms are examples of the first language, or category of speech. Now of course they aren't just the first category, but a lot of what they are is that:
Give ear unto my words, O Lord.
Consider my meditation.
Hearken unto the voice of my cry,
My king and my God,
For unto thee will I pray.
My voice shalt thou hear in the morning.
O Lord, in the morning
Will I direct my prayer unto thee
And will look up.
I don't remember which psalm that was (probably 3 or 5; too lazy to look it up) but it was set to music some years ago and I remembered the words from that. One could argue that the psalmist is conveying information here (My Plans for Tomorrow Morning) and maybe trying to persuade or influence God (Give ear, consider, hearken). But I think Peterson is on to something in saying the psalms are mostly the cry of a dependent, contingent creature, directed toward the Creator.

It's struck me lately that we are a lot less capable and secure in ourselves than we often think we are. It's not just in Tunisia or Egypt or China where the government might decide to persecute someone arbitrarily—who was that guy that the feds accused (incorrectly) of spreading anthrax?

And I believe it was here in the US that the government released radioactive dust into the air to see how many people it would sicken or kill.

Besides governments and organized crime, there's disease and accident. Men my age, and younger, have dropped dead from heart attacks—sometimes with no prior warning.

We know how a lot of diseases happen; what we don't know is why we don't have just about everybody sick or dying just about all the time. The same could be said for motor vehicle (or airplane) accidents.

It would not surprise me if one day I learn that there really are angels preventing death and disease, that "upholding all things by his powerful word" and "in him all things consist" are more literal than we usually think.

But one thing is certain: every moment of every day is a gift. By reminding me of my contingent existence, my dependence upon a merciful Lord, they help me appreciate that gift.

Saturday, December 17, 2011

Collin reads actual literature

The lovely Carol is pursuing a Master of Fine Arts degree in—no, not computer programming or mathematics (the latter especially being a very Fine Art)—Creative Writing. Consequently, new books appear on our shelves and in our travel bags. One of these books, a short story collection by Andre Dubus, caught my attention (actually, the lovely Carol may have asked my opinion about one of the stories) and WOW! I read every one of them.

Todd Field wrote the preface to this collection, named after his 2001 film In the Bedroom, which was based upon Dubus’s story Killings. Field’s title does not mean what you think; according to this wikipedia article, the rear compartment of a lobster trap is called the "bedroom," and if two males and one female are together in it, one male will kill the other. Killings, the first story in the collection, is superbly crafted, the story of a moral failure following a tragedy I hope never to experience; if it happens, I pray I have the strength to do what Jesus would have me do.

Yet the story drew me in, and convinced me of how a man might murder his son's killer and feel the inevitability of his own crime, and paradoxically also remorse.

Dubus’s writing is accessible; if literature must be abstruse, opaque, ponderous, difficult, painful reading, then this isn't it. But these stories are filled with deep insights expressed in beautiful language. Here's Dubus in Rose:

Rose and Jim... could not see a single act of renunciation or affirmation of a belief, a way of life. No. They had neither a religion nor a philosophy; like most people I know, their philosophies were simply their accumulated reactions to their daily circumstances, their lives as they lived them from one hour to the next. They were not driven, guided, by either passionate belief or strong resolve. And for that I pity them both, as I pity the others who move through life like scraps of paper in the wind.
Rose, from In the Bedroom, Andre Dubus
(Vintage Contemporaries, 2002), p. 65
Rose is also a tragedy. I do not like tragedies, but the insight Dubus brings to the tale makes it a gem—no, an X-ray, exposing the human condition with its faults: living without thought, without courage, without taking responsibility for our careless words and actions. There is an awakening and a repentance and a victory, and perhaps it isn't really a tragedy after all.

So what do I find so captivating? Besides the beauty of the language—the expertise he brings to the craft—is the deep thought behind the insight evident in these stories. Field writes in the preface that Dubus desired from a young age “to understand how my two sisters had to live in the world compared with the way I had to live as a boy.” (op. cit., page x)

The other thing is that I have come late in life to an understanding that just as "A gallon of good California red in the kitchen closet will do more for your cooking than all the books in the world" (The Supper of the Lamb, p.33) so this book of short stories will do more for a person's soul than all the math and computer science books in the world.

And there is the pleasure, particularly in the last story of the collection, titled All the Time in the World:

"I want a home with love in it, with a woman and children."

"My God," she said, and smiled, nearly laughing, her hands moving up from the table. "I don't think I've ever heard those words from the mouth of a man."

"I love the way you talk with your hands." (146)

and near the end of that story:
And this time love was taking her into pain, yes, quarrels and loneliness and burning rage; but this time there was no time, and love was taking her as far as she would go, as long as she would live, taking her strongly and bravely with this Ted Briggs holding his pretty cane; this man who was frightened by what had happened to him but was not frightened by the madness she knew he was feeling now. (148)
Why that story in particular? I guess I'm a sucker for a feel-good story, and as the father of daughters it pleases me to read about a young woman discovering the truth about herself (on p. 142 I read that "[s]he wanted love, but she did not want her search for it to begin in someone’s bed.") and then taking a step toward the life she actually does want.

Saturday, December 03, 2011

Keller talks on marriage at Google

It's at http://www.youtube.com/watch?v=C9THu0PZwwk

Here are my unsanitized incomplete distracted inaccurate [etc] notes.

Preface: Presenting Christian views of marriage. Some of you think, "That's partisan." Well, whatever your view, it's partisan; it's religious or quasi-religious; it's not scientific.

Essence of marriage

You've heard it said, "I love you, why do I need a piece of paper to tell me I love you?" "Marriage is just a piece of paper" but what does the piece of paper do? What does the covenant relationship do?
  1. Adds security. There are two types of relationships:
    • consumer-type relationship. You buy stuff at the store, that's great, but if you find another store that provides same stuff at better prices, you'll go there, because your needs are much more important than your relationship with the grocer or whoever.
    • covenant relationship. If your kid cries and is selfish and bratty, you have responsibility; you can't just dump him somewhere with "you're not meeting my needs."
    If you're "dating" and not married, you don't have a covenant, you're in a consumer-type relationship where the other person could just leave at any time. So you have to continuously sell yourself; you can't just be yourself; the covenant creates the security within which you can be vulnerable and honest.
  2. Adds stability. 2/3 of "unhappy" marriages, if they stick it out, are happy 5 years later. What keeps you in there, through hard times, to something really great? Think Ulysses past the island of the sirens, tied to the mast.

    Auden, "Any marriage, happy or unhappy, is infinitely more interesting than any romance, however passionate" because it's the product of time and will, not just of fleeting emotion.

  3. It adds freedom. Kierkegaard: if you don't know the discipline of making a promise and sticking to it, you're not free; you're slave to your impulses, the moment, the circumstances, your feelings. Hannah Arin: without promises, no identity. Smedes, "when you make a promise you are most free."

"He loves me but doesn't want to marry me." Keller: "He probably means, ‘I don't love you enough to marry you, to lose my independence, to bind myself to you in a covenant relationship.’"

Mission of marriage

What's your marriage for? What do you hope to accomplish with it? To many people, it's passion and romance, maybe to combine your fortunes together to form a more comfortable life.

The Christian purpose is for deep character change through deep friendship. People want a compatible soul-mate... who will accept me the way I am and whom I can accept and appreciate just the way they are; someone who won't try to change me. If you want that, that's why you're not married yet. You want someone low-maintenance who won't change and won't try to change you. But no such person exists, and you're not that way either. You pose like someone who is, but you're not; you've got flaws. What might some flaws be?

  • fearful person with tendency to anxiety
  • proud person who tends to be selfish
  • inflexible person who tends to be demanding
  • undisciplined person who tends to be unreliable
  • perfectionistic person who tends to be too critical of others
  • impatient, irratible person who tends to hold grudges
  • a cowardly person who tends to twist the truth to look good
Everyone comes into marriage with these kinds of things. Your parents told you, your siblings told you, but you didn't really believe them. But you get married, and those issues that caused small problems now cause big problems. Marriage doesn't create flaws, it reveals them.

Hauerwas says, we assume there's someone out there who's just right for us, but this overlooks the fact that we always marry the wrong person.

Marriage is a huge thing and it changes us. So we change. Hence even if you could find someone compatible to marry, after you've been married awhile, they won't be any more! So what are the Christian responses to this?

  • First, not to be surprised, because the Christian view is we're all selfish. Think Kim Kardashian. Embrace the conflict.
  • Don't look for a finished statue, look for a great block of marble. You want to be in love with the person as they are, but you want to love the person they're becoming. Don't overdo what they look like, as that'll change. Don't focus too much on their character as it is today, but who they could become!
  • Look for someone who could be your best friend. Remember that great friendship doesn't come out of great sexual chemistry; it's other way around. The praise of the praiseworthy is its own reward.

    The feeling I got the first time I kissed her was shallow; it was all ego. It wasn't about her; I had no idea who she was. It was about me, the thrill that she liked me. Now it's like a deep river that makes no noise, vs a babbling brook one inch deep.

The secret of marriage

To be able to love your spouse for periods when you're getting very little back. They might be discouraged, sick, absorbed in their problems. Very important to keep on giving love. That takes a source of love from outside.

Seen this happen a lot of times: give to child, don't get much back, but you give and you sacrifice [etc] anyway for 18 years. These actions engender deep feelings of love. But your spouse -- if you don't love me the way I want, I won't love you the way you want, and at the end of 18 years, you love your kid, you don't love your spouse, and the marriage falls apart.

And it's your fault because what you did with your kid you didn't do with your spouse. "Love philanthropy." Financial philanthropy possible when you got a lotta money. Love philanthropy possible if you got a lotta love from God.

Christ loved us not because we were lovely but in order to make us lovely.

Q&A

  • On finding a spouse, not just physical; what criteria? 4 or 5?

    First, someone who really understands you, maybe better than you know yourself. Who isn't surprised by your reactions. Second, someone you can already solve problems with -- had a serious conflict, solved it in a way satisfactory to both people.

    btw if your faith is important to you, then for somebody to "get" you they have to share your faith.

  • I think we have a great marriage, my husband would say I have a lot of flaws and am not making real good progress. How can I change? I think I'm trying but it's harder than I thought.

    If you agree on what needs to be changed, then 2/3 of your problem's over; you just need a coach. You might want to get a 3rd party involved. You need add'l fellowship.

  • Love analogy of truck exposing stress fractures in a bridge; kids are like a 2nd truck. Your perspective on that?

    You spend more time together but you're not talking with each other as much as talking through the kids. Probably not so much disagreements about children, but time. You might travel less, work fewer hours, to get time with family -- but time with my wife very specific.

    Mothers get a lot of their "skin hunger" addressed with kids and don't have as much desire for physical intimacy as husbands have. Husbands' desire is less complex.

  • Criteria... sounds like it could take a long time to be sure about that.

    If you go to a film, have dinner, that's maybe an hour of conversation; doesn't have to take a whole lotta time.
    At other end, you describe the case of both spouses withdrawing, and it's been going on 18-20 years, what do you do?

    Too general a case. There are grounds for divorce so I don't know that you absolutely can work it out. Intervention.

  • About attraction -- ego rush vs real love?

    Ego rush is inevitably there. If the main thing that attracts you is physical (women disproportionately look at height and economics; men likewise disproportionatelylook at body and face)... you need something more.

  • Role of dating? Dating vs engagement etc?

    Nothing in Bible about dating. Lots about marriage in the Bible. All I can tell you is, get a picture of marriage and let that affect dating. As you get older, probably you shouldn't be dating if in your view there's no way you could get married to that person.

  • Advice for an engaged couple? Not premarital counseling.

    The book is basically about that. So don't get discouraged in the short term. The basic cancer is self-centeredness. It's not "I've got into conflict w/spouse; marriage has brought me into conflict with my self-centeredness." Mission of marriage: become best friends and figure out how that happens. Look at sex as a covenant renewal ceremony, or covenant cement.

    Sex outside marriage is no preparation for sex within marriage. They're completely different.

  • What you've said about marriage, most of that would apply to gay marriage. What role in society?

    Christian view of marriage is that it's between a man and a woman, because primary mission connected with bringing together people of diametrically opposed genders. We clash and mesh. It's intrinsic to the Christian idea of marriage. My wife teaches me things that I could not learn from another man.