[Arjen Markus] (26 october 2009) Having experimented a bit with the [pdf4tcl] package I found it a very useful package for generating PDF files, but there were too many details to take care of: the commands it offers are somewhat low-level. Luckily it is easy to wrap them into commands that hide the details. While this is a very first, incomplete version of what I have in mind, I thought it might be useful enough to put it on the Wiki. The text I use in the example is simply nonsense, but it suffices for my testing purposes. Note: I have used Snit to create the wrapper interface, as pdf4tcl itself uses Snit too. As it is my first serious use of Snit, I can probably improve on it. ====== package require snit package require pdf4tcl # document -- # Snit type defining a document with high-level methods # ::snit::type document { variable pdf variable yCoord variable lineHeight constructor {args} { #set pdf [::pdf4tcl::new %AUTO% {*}$args] set pdf [::pdf4tcl::new %AUTO%] $pdf configure -margin {5m 5m} set lineHeight [expr {1.3*12}] } method chapter {title} { $pdf startPage $pdf setFont 24 Helvetica-Bold set yCoord [$pdf getFontMetric ascend] $pdf setTextPosition 0 $yCoord $pdf text $title $pdf setFont 12 Times-Roman set yCoord 36 } method section {title} { $pdf setFont 18 Times-Bold set lineHeight [expr {1.3*18}] $self paragraph $title $pdf setFont 12 Times-Roman set lineHeight [expr {1.3*12}] } method subsection {title} { $pdf setFont 14 Times-Italic set lineHeight [expr {1.3*14}] $self paragraph $title $pdf setFont 12 Times-Roman set lineHeight [expr {1.3*12}] } method paragraph {text {margin 0}} { set text [string map {\n " "} $text] foreach {pageWidth pageHeight} [$pdf getDrawableArea] {break} while { $text != "" } { set text [$pdf drawTextBox $margin $yCoord [expr {$pageWidth-$margin}] $lineHeight $text -align justify] set yCoord [expr {$yCoord + $lineHeight}] if { $yCoord > $pageHeight } { $pdf startPage set yCoord $lineHeight } } $pdf newLine } method newLine {} { set yCoord [expr {$yCoord + $lineHeight}] } method bullet {text} { set xcentre [expr {0.5 * $lineHeight}] set ycentre [expr {$yCoord + 0.3 * $lineHeight}] $pdf circle $xcentre $ycentre 2p -filled 1 $self paragraph $text $lineHeight } method bullet2 {text} { set xcentre [expr {1.5 * $lineHeight}] set ycentre [expr {$yCoord + 0.3 * $lineHeight}] $pdf circle $xcentre $ycentre 1.2p -filled 1 $self paragraph $text [expr {2.0*$lineHeight}] } method code {text} { $pdf setFont 10 Courier set lineHeight [expr {1.3 * 10}] set charWidth [$pdf getCharWidth " "] foreach {pageWidth pageHeight} [$pdf getDrawableArea] {break} foreach line [split $text \n] { set margin [expr {$charWidth * ([string length [regexp -inline {^ *} $line]] - 2)}] $pdf drawTextBox $margin $yCoord [expr {$pageWidth-$margin}] $lineHeight $line set yCoord [expr {$yCoord + $lineHeight}] if { $yCoord > $pageHeight } { $pdf startPage set yCoord $lineHeight } } $pdf newLine $pdf setFont 12 Times-Roman set lineHeight [expr {1.3 * 12}] } method getpdf {} { return $pdf } method write {filename} { $pdf write -file $filename $pdf destroy } } document doc doc chapter "Chapter 1" doc paragraph "Some longish text that clearly wraps around the right margin of the page, so that we can demonstrate the aligning behaviour of this command. And of course how you put in a paragraph of text into the document, using a simple, high-level method." doc section "Demonstration of a section" doc subsection "Demonstration of a subsection" doc paragraph "Does it do pages?" for { set i 0 } { $i < 50 } { incr i } { doc paragraph "Line $i" } doc chapter "Chapter 2" doc paragraph "Again some text - mostly for fun" doc paragraph "What about two paragraphs?" doc bullet "Bullet 1, but let's demonstrate the wrapping for this type of text entity too. After all we do want it to be useful in a fairly general context" doc newLine doc bullet "Bullet 2" doc bullet "Bullet 3" doc bullet2 "Second level bullet - no more levels" doc code { What about writing some text in the style of "code"? proc putTitle {string} { global currentY book setFont 24 Times-BoldItalic book text [string range $string 3 end-3] book setFont 12 Times-Roman set currentY [expr {$currentY + 24}] } } ;# End of "doc code" doc write "mydocument.pdf" ====== <>Category Package|Category Printing