Main index Other Papers index About author

Valid HTML 4.01 Transitional

Glasses placemat: how to avoid confusion at a port tasting

Julian D. A. Wiseman

Contents: Publication history; example output (and in PDF); How to control the PostScript program; Other easy parameters; Non-easy parameters; Code within parameters; Errors: causation and avoidance; How to comment; Who to invite?; Recent changes.

Publication history: only at www.jdawiseman.com. Usual disclaimer and copyright terms apply. Also see the main feature, the PostScript program itself.


This is the ‘documentation’, such as it is, for the latest version, dated May 2013, which prior precedent suggests will not be the last. The code is mostly debugged, but errors surely remain. It is provided as-is, without liability—it is free.

Also see the complete list of previous placemats, some with comments; the advice about choosing of the page size; the obscure parameters; how to use code in parameters; /TimesNewRomanPS-BoldMT’s accented characters and their PostScript glyphs, which includes diacritics as well as accents. Further, PostScript programmers are invited to peruse the infrequently updated list of re-usable routines.

Introduction

So you and your lucky guests are to enjoy a port tasting. Of course, there will be many glasses, each person having one for each port. But it is important to avoid the what-is-in-this-glass confusion: each person will need a wine tasting placemat, clearly labelling each glass’s spot.

The author has devised a PostScript program to create such pages, and all the other paperwork required to manage such tastings, large or small. Glasses pages are set as in the PDF example, the first two pages of which (to hold the glasses, and on which to write tasting notes) are also rendered immediately below.

Example of an 8-glass port tasting placemat Example of tasting-notes sheet

 Making Your First Placemat: Advice for Beginners

Don’t try to make your first placemats with little time to spare. Start a week in advance, to allow time for learning and improvements, and to avoid the other things that need doing just before a tasting. Yes, it can be done in a few minutes—but not your first placemats.

A code editor, a good text editor, is a boon, and it should be one that understands PostScript. On a Mac Alpha X is excellent and free, and Aquamacs Emacs is suitable for Emacs experts. On a PC NotePad++ is good. The basic text editor that came pre-installed on your computer will make life harder than it needs to be. A code editor that understands PostScript will prevent many errors and save much labour.

Bookmark this manual, and download to your machine a copy of the PostScript code (update this copy every time: new versions fix bugs; add features; improve default settings). Store it in a directory named something like “placemats”. Make a copy of the original PostScript. Give it a name which will make sense in aeons to come: perhaps YYYYMMDD.ps, or YYYYMMDD_TastingName.ps. The ¶ of examples can give a sense of the author’s file naming.

You have saved a .ps file. This file is to be opened in two different ways: with the code editor; and with a program to convert it from .ps to .pdf. Let’s master the latter. On a Mac right-click the file, and ‘Open With’ Preview. It should convert to a PDF. On a PC, in your preferred web browser, open PS2PDF.com; ‘Browse…’ to the PostScript file; and ‘Convert’ it. You can now convert the PostScript to PDF.

Open the file with the code editor, perhaps by right-clicking and choosing from the ‘Open With’ applications (Alpha, Notepad++, whatever). For a sense of which of the many features might be wanted look at the ¶ of example placemats, or the complete list of old placemats, some of which have helpful comments and advice. Then use the text editor to edit the copy of the PostScript, changing to values appropriate for your tasting the:

Convert to PDF, to test that all is well.

If decanter labels are wanted, set DecanterLabelsNumCopies to 1. Also alter, as necessary, PlaceNamesNumCopies, PrePourNumCopies, DecantingNotesNumCopies, CorkDisplay, VoteRecorders, or StickyLabelsNumCopies and StickyLabelsTypes.

By default, glasses are spread sensibly over one or several sheets. But if necessary change GlassesOnSheets to something like [  [ 0 1 2 3 ]   [ 4 5 6 7 ]   [ 8 9 10 11 ]  ]. (Obviously, this precise example assumes exactly twelve glasses on three pages each of four glasses.)

Now test some of the more exuberant glass-decoration features described in this manual. Play and experiment. Convert to PDF after each significant change, and admire the results. Choose a small subset of the decorative features to go in the final placemats. Too many flamboyant features looks cluttered and horrible, so be parsimonious. Perhaps change the the fonts—a list of valid PostScript font names being most easily made by distilling fonts_illustrated.ps. Convert to PDF.

If the tasting is being arranged via ThePortForum or another wine bulletin board, upload the PDF to the web, and post in an appropriate thread a link labelled something like “First draft of the placemats”. Allow some time for comments and corrections and changes. Update if appropriate (and post “Updated draft of the placemats”).

Perhaps send to the author a copy of the PS and PDF for comment. Time and convenience permitting, help might be forthcoming. Please send the URLs of the uploaded .ps and .pdf files, rather than filling email with large enclosures. Allow some days for a response.

The day before the tasting print the mats using a toner printer.

Neatly fold the place-names pages, and construct the decanter labels. Cut a neat rectangle around each; paste to the back of a business card (typically one from a former employer—keep them when changing jobs); allow the glue to dry; punch holes top-left and top-right; hang on the decanter, perhaps using a 30″ metal bead chain (filling an unlabelled decanter risks needless confusion, so hang before filling).

Enjoy the tasting.

 As further examples, the following link to placemats from actual tastings, or draft placemats for future tastings. Most of these were made with earlier versions of the software; some required expert use of the program’s features. 22 Mar 2013, Taylor vertical17 Jan 2013, Dow Magnumonicon13 Dec 2012, sticky labels at the Bell13 Nov 2012, a smattering of Graham23 Oct 2012, a few 1963s15 Oct 2012, unusuals18 Sept 2012, Sandeman Vau4 Sept 2012, blind25 July 2012, Olympic years at the Portuguese Embassy15 May 2012, small horizontal of 1970s24 Apr 2012, Delaforce29 Mar 2012, the birthday boys2 Mar 2012, horizontal of 198029 Feb 2012, a blind leap8 Nov 2011, ‘Port with Star Quality’11 Oct 2011, semi-blind 4×419 Sept 2011, ragbag of good port8 Aug 2011, mostly blind, port from the ’90s, and the annexe in Paris13 May 2011, Sandeman4 Apr 2011, Fonseca versus Guimaraens29 Dec 2010, blind 1→1210 Dec 2010, Köln, 1955 horizontal17 Apr 2010, Warre in Sussex1 Feb 2010, bring a bottle2 Oct 2009, Warre26 June 2009, decent drinking;  and, recent, from the code’s default parameters. Also see complete list of placemats.

For some of the ≥2012 placemats, the parameters used in the construction are quoted in a thread on ThePortForum, Parameters for the placemat software. Users wishing to replicate a feature might wish to peruse the examples therein.

 How to control the PostScript program

PostScript programs are in the form of a text file, which can be interpreted by Adobe Distiller, by Preview on the Mac OS X, by GNU Ghostscript, or by any PostScript printer (though sending raw PostScript to a printer might require some technical knowledge). Several websites offer free PS→PDF conversion; the author has successfully used PS2PDF.com (fonts that can be used if distilling at PS2PDF.com). The text file can be edited in any text editor, though it is easier to use a text editor that has been configured to edit PostScript files—see comment in box.

After some opening comments (after a “%” character the remainder of a line is a comment), the program defines some arrays, starting with Titles, Belowtitles, and Circlearrays. Each of these arrays has the same length, typically equal to the number of glass-settings on the page (five in the example above), and the program copes with any sensible number of glasses.

In the example provided, Titles is defined thus:

/Titles [
	(G63)
	(G70)
	(G77)
	(G85)
	(G85)
] def

Observe that the array is delimited with square parentheses [], and that each of the strings is delimited with round parentheses (). White space outside strings is ignored. The page looks best if each of these titles is short, ideally ≤4 characters.

(Throughout this manual PostScript is shown in monospace with a pale grey background. Further, the preferred code editor of the author, Alpha X, helpfully colours the different types of element. That colouring is echoed here: /names; operators; array and code parentheses [ ] { }; and % comments.)

Belowtitles is an array of the same length, though, in the example, most of the strings are empty:

/Belowtitles [
	()
	()
	()
	(Single)
	(Magnum)
] def

If an auction house is hosting the tasting, Belowtitles might contain lot numbers: (123), or even [(123) /arrowright (129)] = “123→129” (see below).

And Circlearrays, which is an array of arrays, thus:

/Circlearrays [
	[ (1963) (Graham) ]
	[ (1970) (Graham) ]
	[ (1977) (Graham) ]
	[ (1985) (Graham) (Single) ]
	[ (1985) (Graham) (Magnum) ]
] def

Each of the sub-arrays of Circlearrays contains strings. The program calculates how many copies of these sub-arrays can be spaced around the circle, and then does so with equal spacing between the elements of the sub-arrays.

Each place settings is named (e.g., the author’s “JDAW” initials are on the page shown above), and these names are listed in yet another array, not necessarily of the same length as the previous three:

/Names [
	(JDAW)
	[(G) /uacute /edieresis (st ) /Ocircumflex /ntilde /egrave]
	(Guest Two)
	()
] def

Including a blank name, (), is very strongly recommended: last-minute changes to the guest list do happen.

Accents and modifiers: Á /Aacute; á /aacute;  /Acircumflex; â /acircumflex; À /Agrave; à /agrave; Å /Aring; å /aring; à/Atilde; ã /atilde; Ä /Adieresis; ä /adieresis; Ç /Ccedilla; ç /ccedilla; É /Eacute; é /eacute; Ê /Ecircumflex; ê /ecircumflex; etc…. (See /TimesNewRomanPS-BoldMT: accented characters and their PostScript glyphs.)

Ligatures and punctuation: ß /germandbls; fi /fi; fl /fl; æ /ae; Æ /AE; œ /oe; Œ /OE; … /ellipsis; – /endash; — /emdash; ‘ /quoteleft; ’ /quoteright; “ /quotedblleft; ” /quotedblright; ‹ /guilsinglleft; › /guilsinglright; ‚ /quotesinglbase; „ /quotedblbase.

Currencies, fractions and arithmetic: £ /sterling; € /Euro; ¥ /yen (also used for the Renminbi); ₩ /won; ₪ /sheqel; ¢ /cent; ½ /onehalf; ¼ /onequarter; ¾ /threequarters; ⅛ /oneeighth; ⅜ /threeeighths; ⅝ /fiveeighths; ⅞ /seveneighths; ⅓ /onethird; ⅔ /twothirds; ≈ /approxequal; ≥ /greaterequal; ≤ /lessequal; ≠ /notequal; × /multiply; ÷ /divide.

Greeks: α /alpha; β /beta; γ /gamma; δ /delta; ε /epsilon; ζ /zeta; η /eta; θ /theta; ι /iota; κ /kappa; λ /lambda; μ /mu; ν /nu; ξ /xi; ο /omicron; π /pi; ρ /rho; σ /sigma; τ /tau; υ /upsilon; φ /phi; χ /chi; ψ /psi; ω /omega.

Other: • /bullet; · /periodcentered; ◊ /lozenge; † /dagger; ‡ /daggerdbl; § /section; ® /registered; ™ /trademark; ♠ /spade; ♥ /heart; ♦ /diamond; ♣ /club; → /arrowright; ← /arrowleft; ↑ /arrowup; ↓ /arrowdown; ↔ /arrowboth.

Any string parameter may be replaced by an array (to make a ‘compound string’) of strings and glyphs, each glyph beginning with a forward slash (“/”). As an example, the second item of the default value of Names makes the silly but didactic “Gúëst Ôñè”. Examples of glyphs include accented characters such as /atilde, and the likes of /daggerdbl, as well as ligatures such as that in [(Quinta do Bom) /fi (m)]. Most of the characters one might need are in the box on the right, or in /TimesNewRomanPS-BoldMT: accented characters and their PostScript glyphs. Others are listed in appendix E.5 of the PostScript Language Reference Manual, third edition; a still fuller list is at www.jdawiseman.com/​papers/​trivia/​character-entities.html. (But most fonts do not contain all the glyphs listed, so check the output carefully.) Any string parameter may be replaced with an array of any of: strings; glyphs; other like arrays; and indeed pieces of PostScript code such as “{-0.06 Kern}”.

Titles, Abovetitles, Belowtitles, Overtitles, Circlearrays

 Abovetitles and Overtitles

As well as Belowtitles, there are similar arrays Abovetitles and Overtitles. The diagram on the right shows the usage of these arrays. It is best if items of Titles are short, ideally ≤ 4 characters, so that they can be shown very large. Separately, observe that the Titles and Overtitles have been ‘filled’ with text: see FillTexts below.

This profusion of places to put information should be used sparsely, and consistently. For example, in a vertical, the Titles might contain two-digit years and the Overtitles the name of the shipper/quinta/château. Most Abovetitles would be blank, only a few specifying a non-standard bottle size (“Double Magnum”). Most Belowtitles would be blank, only a few specifying the likes of “Cask Sample”.

 Other Page Types

Much of this data is used to drive many other types of pages, including Tasting-note pages, Vote Recorder and Decanting Notes. But these lack the space to hold all the data that can fit in a glass-sized circle. Each has room for two sets of text analogous to the four title-type arrays, and one analogous to the Circlearrays. These are stored in arrays as follows.

On Glasses, Pre-Pour, Sticky Labels →

Page type ↓

TitlesAbovetitles
Belowtitles
Overtitles
Circlearrays
Tasting NotesTitlesTastingNotesSubtitlesTastingNotesCirclearraysTastingNotes
Vote RecorderTitlesVoteRecorderSubtitlesVoteRecorderCirclearraysVoteRecorder
Decanting NotesTitlesDecantingNotesSubtitlesDecantingNotesCirclearraysDecantingNotes
Cork DisplayTitlesCorkDisplaySubtitlesCorkDisplayCirclearraysCorkDisplay
/Circlearrays [
	[ (1927) (Niepoort) ]
	[ (1931) (Niepoort) ]
	[ (1945) (Niepoort) ]
	[ (1955) (Niepoort) ]
	[ (1963) (Niepoort) ]
] def
/TitlesTastingNotes [ Circlearrays {0 get} forall ] def
/Titles [ TitlesTastingNotes {2 2 getinterval} forall ] def

These arrays may be set to already defined arrays, such as the default “/SubtitlesTastingNotes Belowtitles def”. Or they may be set to custom values, differing from one page type to the next. But all these arrays must be the same length.

Indeed, it is quite usual to generate variations automatically. For a vertical tasting, elegance is enhanced by having two-digit years in the Titles, but four-digit years on the tasting-note sheets. The example on the right repays study.

 Other parameters

 Fonts

◊ The fonts in which the various text pieces are rendered are contained in the parameters NamesFont, CircletextFont, TitlesFont, AbovetitlesFont, BelowtitlesFont, OvertitlesFont, FillTextFont, SubtitlesFont (on non-glasses sheets), HeaderFont, FooterFont, and even the rarely-used BackgroundTextsGlassesFont.

But PostScript uses font names that are not always obvious. Help is at hand: distilling fonts_illustrated.ps produces a PDF with a list of the available fonts, their PostScript names, and formatted example text. If distilling on a different machine or with a different program, a different set of fonts might be available: re-test by re-distilling fonts_illustrated.ps.

The program was designed for left-to-right script, and the alphabets successfully used have been Roman (mostly), Greek (occasionally), and Cyrillic (rarely). Users with knowledge of PostScript who are able to assist with testing in other scripts—including right-to-left—are invited to contact the the author, perhaps after reading this request for assistance rendering “泉十段”.

 PaperType and Orientation

◊ Two parameters control the page size and the page orientation:

/PaperType /A4 def  % /A4 /A3 /B4 /USL /USLegal /USL2 [SmallerPts LargerPts]
/Orientation /Portrait def  % /Landscape /Portrait

Units

In PostScript sizes, distances, lengths, widths, etc, are always denominated in points, where 72 pt = 1″ = 1 inch = 25.4 mm, and hence 1 pt = 172″ = 0.01388″ = 127360 mm = 0.35277 mm, and 1 mm = 360127 pt ≈ 2.83 pt.

A useful ready reckoner is 6 mm ≈ 17 pt, this being inexact by only one part in 2159, as 6 mm = 171127 pt.

If using lots of measurements in millimetres, near the start of the file insert the line “/mm {360 mul 127 div} def”, which will automatically convert the likes of “6 mm” into Adobe points.

Angles are always in degrees = ° and never in radians, so a quarter turn is 90°. PostScript’s arithmetic is only single precision, so angles should not be bigger than ± a few thousand degrees.

In the first line allowed values include /A4 (≈ 210mm×297mm, 8.28″×11.70″), /USL (8½″×11″), /A3 (≈ 297mm×420mm, 11.70″×16.55″), /USLegal (8½″×14″), /USL2 (11″×17″), or a custom page size expressed in points (see box on right) as an array of length two: [d1 d2] with 0 < d1 ≤ d2. For convenience of copy-pasting, some of the allowed values appear in the comment at the end of the line—after the “%”. Also allowed are sizes from /A9 (don’t ask why but do shrink the margins) to /A0, and from /B9 to /B0. In the second line allowed values are /Landscape and /Portrait.

Also see the separate manual page Glasses placemat: choosing a paper size.

Around the edge of the page is an invisible margin, the circles lying inside the area at least the margin away from the edge of the page. The margin equals the parameters MarginL (left), MarginR (right), MarginT (top), and MarginB (bottom), each defaulting to 30 points ≈ 0.42″ ≈ 10.6 mm.

 Decorating the Titles

 Colour Schemes

By default, the Titles are black if the relevant item of Overtitles is empty, and grey otherwise. By default the Abovetitles and Belowtitles are always black; and Overtitles is black if the relevant item of Titles isn’t. These colour schemes are controlled by the parameters ColourSchemeTitles, ColourSchemeAbovetitles, ColourSchemeBelowtitles, ColourSchemeOvertitles, each of which can be set to (code evaluating to) /Black or /MidGrey. There is also the analogous parameter ColourSchemePlaceNames, used to control the colour of Place Names.

Example of CrossHatchingTitles

 CrossHatching

◊ The example on the right is filled with a check pattern. This check is activated by the boolean CrossHatchingTitles. The polar gridlines originate from a point with x coordinate CrossHatchingCentreX which can take values of /Name, /Left, /Center, /Right, or a number being points from the left edge of the page; and y coordinate CrossHatchingCentreY with possible values /Name, /Bottom, /Middle, /Top, or points from the bottom of the page. Lines are formatted and stroked by the code in CrossHatchingTitlesStrokeCode (the code must include the stroke, this requirement permitting the likes of “gsavestroke grestorestroke”). The number of straight lines is CrossHatchingNumRadialLines, defaulting to 180 so 2° apart. The radial gaps start at CrossHatchingRadialGapStart (this is the diameter of the inner-most circle), the gaps between the radii tending to CrossHatchingRadialGapAtInfinity with decay CrossHatchingRadialGapDecay. The author believes that CrossHatching… looks quite stylish when every item of Overtitles is empty, and hence the text in black and the lines defaulting to white.

There are analogous booleans CrossHatchingAbovetitles, CrossHatchingBelowtitles, and CrossHatchingOvertitles; and strokeing code CrossHatchingAbovetitlesStrokeCode, CrossHatchingBelowtitlesStrokeCode, and CrossHatchingOvertitlesStrokeCode. CrossHatchingBackground (with CrossHatchingBackgroundStrokeCode) controls whether (and how) the cross hatching appears in the background, filling the inside of the circle behind the various titles, and CrossHatchingBackgroundSuppressForDecanterLabels controls whether this is suppressed for decanter labels.

Example of outlined titles

 Stars and flowers

◊ In the very cluttered diagram on the left, showing QvA08, the Titles and Belowtitles contain small random stars and flowers. This feature is activated by setting to true the boolean parameter ShapesInTitles, which has obvious variations ShapesInAbovetitles, ShapesInBelowtitles, ShapesInOvertitles. The array ShapesToUse, defaulting to [/Flower /Star], controls which shapes are used.

The shape is filled with the code ShapesTitlesFill (or ShapesAbovetitlesFill, +ShapesBelowtitlesFill, ShapesOvertitlesFill), which, if the shapes are filled, should end with a fill. The shape is then stroked with ShapesTitlesStroke (or ShapesAbovetitlesStroke, ShapesBelowtitlesStroke, ShapesOvertitlesStroke) which should end with a stroke.

For the stars, the numbers of points and the step between points are chosen randomly from within ShapesStarsPointsAndStepsArray, the default [[5 2] [6 2] [7 2] [7 3] [8 3]] being small 5/2 star small 6/2 star small 7/2 star small 7/3 star small 8/3 star. A possible alternative value for ShapesStarsPointsAndStepsArray is [[3 1.318] [4 1.792] [5 2.278] [6 2.77]], being pointier and less polygonal: small sharp 3-pointed star small sharp 4-pointed star small sharp 5-pointed star small sharp 6-pointed star. (Mathematicians might be interested in an open question about such stars.) For the flowers the number of petals is chosen randomly from ShapesFlowersNumPetalsMin to ShapesFlowersNumPetalsMax, and, as a proportion of 360° divided by the number of petals, the angular width of each is chosen randomly from the range ShapesFlowersAngularWidthMin to ShapesFlowersAngularWidthMax.

The radius of each shapes’s enclosing circle is random in the range ShapesEnclosingCircleRadiusMin to ShapesEnclosingCircleRadiusMax. An approximation to the typical separation between the shapes is ShapesAverageSeparation; a parameter controlling how far stars are moved from a regular grid is ShapesAverageMaxTweakPlusMinus.

 OutlineTitles

◊ The Titles can be outlined by setting /OutlineTitles true def, as in the (still very cluttered) example with flowers and stars. The innermost white and black outlines have width OutlineTitlesInnerWidthWhite and OutlineTitlesInnerWidthBlack, and these widths grow in successive outlines by factors of OutlineTitlesMultiplierWhite (defaulting to (1+√5)/2 = the golden ratio) and OutlineTitlesMultiplierBlack (defaulting to unity). Subject to there being not more than OutlineTitlesMaxNum black ripples, the number of black ripples is chosen such that the total width of the ripples is at least OutlineTitlesTargetTotalDistanceProportionRadius radii. This parameter can be relevant if a title is something like “L”, as the top-right of the circle can then be more than 1 radius from the title.

If OutlineTitlesAlsoAbovetitles is true then Abovetitles are also outlined; if false then Abovetitles sit plainly atop the lines (and likewise OutlineTitlesAlsoBelowtitles and OutlineTitlesAlsoOvertitles). Generally it helps if the decanter labels fit onto a rectangular business card, so the default value of OutlineTitlesSuppressForDecanterLabels suppresses the outlines on the decanter labels. OutlineTitles does not impose as high a burden on a printer as does FillTexts, but can still be difficult for some. Again, test your printer.

Example of inlined titles

 InlineTitles

◊ A more architectural form of decoration is activated by the booleans InlineTitles, InlineAbovetitles, InlineBelowtitles and InlineOvertitles. These are in some sense a reversal of OutlineTitles—the lines being on the inside. In the Titles the lines have widths of InlineTitlesBlackWidth and InlineTitlesWhiteWidth; with obvious variations InlineAbovetitlesBlackWidth, InlineTitlesBlackWidth, InlineAbovetitlesWhiteWidth, InlineBelowtitlesBlackWidth, InlineBelowtitlesWhiteWidth, InlineOvertitlesBlackWidth and InlineOvertitlesWhiteWidth. All default to 1. If the colour scheme is /MidGrey then “black” means the darker of the two shades, and “white” the lighter.

It would be difficult for the code to compute correctly how many contours are needed. So instead the code makes an estimate, which will typically be a great overestimate, and then caps that estimate at InlineTitlesMaxNumberContours/InlineAboveBelowOverMaxNumberContours. Setting these carefully reduces file size and complexity, which can help some printers.

InlineTitles (and variations) do not mix well with other decoration: the text can be illegibly cluttered. Self-restraint is beautiful.

 Rotation

The example on the right is also at a jaunty angle (well, an angle that the author imagines might be jaunty). This is controlled by RotationTitlesAboveBelowOverCirclearray, which rotates the whole glass circle by that number of °, and is here set to 15.

Example of titles filled with text

 FillTexts

◊ The booleans FillTitles, FillAbovetitles, FillBelowtitles and FillOvertitles control whether their respective elements are filled with multiple copies of some text, outlined. The filling texts are in the array FillTexts, which is of the same length as Titles, and each is outlined FillTextNumOutlines times. Depending on the values of ColourSchemeTitles etc, the colours are either black and white, or 40% grey and white. Each rendering of an item of FillTexts is suffixed with FillTextNumSpaces spaces.

The additional parameter FillTextAngle may be deffed to a number (30 being a good choice), this being the ° from horizontal at which the FillTexts are shown. Alternatively, FillTextAngle may be one of /LowerLeft, /LowerCenter, /LowerRight, /MiddleLeft, /MiddleCenter, /MiddleRight, /UpperLeft, /UpperCenter or /UpperRight such that the text will be 90° to a line drawn from the centre of the circle to that corner or edge or centre of the page. Or FillTextAngle may be /Name, making the angle perpendicular to a line drawn to the positioning of the Names.

The FillTexts are set in the font FillTextFont, at a size of at least FillTextMinFontSizeAbsolute, and of a size of at least FillTextMinFontSizeProportionLargestTitleAboveBelowOver × the largest their font sizes.

In the example on the right the relevant item of Titles is (S); of Overtitles is (Sandeman); of Circlearrays is [(Sandeman) (1985)]; of FillTexts is (1985), with FillTextNumSpaces being 2 and FillTextAngle being 30, and all the typefaces being /HelveticaNeue-CondensedBold. The default value of FillTextAngle is complicated, but natural. If GlassesOnSheets specifes a two-page layout, then to /LowerRight on the first sheet, and /LowerLeft on the second. If not a two-page layout, then if NamesAtTop is true to /LowerCenter, otherwise to /Name.

The formatting of the PlaceNames… generally matches that of the Titles, except that the filling text is FillTextPlacename, and the angle is FillTextAnglePlacename.

Use of FillTexts makes distillation slow, and produces files that can be too complicated for some printers. The balance between these two can be influenced by the boolean FillTextPrintQuickerDistillSlower. For example, in a draft placemat with FillTitles and PlaceNames, changing FillTextPrintQuickerDistillSlower from false to true decreased the file size from 1013k to 871k, but increased the distill time from 64 seconds to 40 minutes. If distilling the PostScript via the web (e.g. via PS2PDF.com), the latter would definitely have timed out the browser. And it might be that, on some printers, the print-slowly option (false) won’t print at all, whereas the print-quickly option (true) will. But some printers can’t cope with either: the author’s Canon Pixma MP240 fails to print the FillTexts at all, the interior of the Titles rendering as plain white. (Printing this FillText test page to an MP240 results in output of which this scan is an extract.) So test your printer; do not assume that anything will work first time; and do not assume that all larger more expensive printers cope better.

It also appears that Adobe does not always distill or render perfectly these FillTexts. This problem can be fixed by opening the PostScript file with Preview on the Mac OS X, and then printing from Preview or saving the PDF file Preview makes and subsequently printing from Acrobat (technical demonstration of error).

But there is also a problem with Preview on the Mac OS X, which crashes if the paths are too complicated. The relevant constraint is on the complexity of the path of the item of FillTexts, plus the complexity of the path of the text that is filled (the item of Titles or of Names, as appropriate). As Names are typically longer than Titles, the problem can typically be remedied by setting PlaceNamesNumCopies to 0.

 Page-level settings

Example of use of Rays

 Rays

To connect circles with pseudo-electrical field lines, as in the example on the right, set Rays to true. Then from each glass setting there emanates RaysLinesPerGlass lines, the first being offset from vertical by RaysAngleOffset°. It is strongly recommended that RaysLinesPerGlass be an integer multiple of 4. Rays can be straight lines, or, as in the example, curves, this being controlled by the boolean RaysUseCurves. The lines or curves can be truncated at the margin, or at the edge of the paper: RaysLinesToPaperEdge. If this is true, it is even more important to ensure that printing is done at 100% with no scaling. Lines shorter than RaysCollidingCircleMinLength that collide with a circle (rather than meeting one of its rays) are suppressed. The formatting of the stroke can be controlled within RaysStrokeCode.

The electrical-ness is very pseudo. With real electro-magnetic lines, each circle would have to be of a positive or negative charge. So if A connected to B, and B to C, then A could not connect to C. But these lines can, layout dependent, connect almost any combination of pairs of circles. If a physical interpretation is wanted—this being strongly dis-recommended—it would have to be chromatic. It is best to deem the whole thing ‘decorative’. (Comment from a real physicist would be welcome.)

Imperfections in the algorithm can cause crossovers or missed intersections, either of which can be aesthetically detrimental. Typically the problem can be fixed by tweaking RaysLinesPerGlass and RaysAngleOffset: for several PermittedPackingStyles vertical and horizontal lines seem to cause particular problems. There is a further ‘feature’ in the interaction of rays and SideBySideGlassesTastingNotes. For right handers, the rays rather dramatically spill over into the tasting-note section. For left handers, less dramatically, they don’t.

Example of watercounts

 H2O

◊ Particularly at a tasting of a sweet fortified wine, drinking water is important. If WaterCounts is true, then there is a set of little glass icons (see lower-right of figure on left) with which to record water consumption: check one for each glass of water downed. Even better, use a diagonal slash (I drank half a glass of water) for a half glass of water, and a cross (I drank a whole glass of water) for a whole.

The number of these boxes is usually at least WaterCountTarget, each of size WaterCountSize and separated by gaps of width WaterCountGap. These should appear on the lower-right of the page for right-handed drinkers, and lower-left for left-handers. Tasters’ handedness is set by LeftHanders, an array of the text of the name of known left-handers, whether or not at this tasting. If a name within Names is duplicated, and both are to be left-handed, that name must appear twice within LeftHanders.

If there are multiple pages of glasses (see GlassesOnSheets below), then on which of these pages should they appear? For simplicity, WaterCountsOverrideShowEverySheet overrides the complexity in the next few sentences, putting watercounts on every sheet. But if WaterCountsOverrideShowEverySheet is false, the presence or absence is controlled, for the right handers, by the array of booleans WaterCountShowRight; and for the lefties by WaterCountShowLeft. Nota Bene: WaterCountShowRight and WaterCountShowLeft must be the same length as GlassesOnSheets. The default values of WaterCountShowRight and WaterCountShowLeft refer to PageOrderingNonDecanterLabelGlasses, which is implicitly assumed to specify sessions. Naturally enough, WaterCountShowRight defaults to true for the last page in each ‘session’, and WaterCountShowLeft for the first.

There is some partial control over the arrangement of boxes, via the array WaterCountMaxRowLengths. If this is empty, it is ignored. If not empty, it should contain integers ≥ 0, being the maximum length of each row. If there are more rows than items in the array, the last item is deemed to apply to all the extra rows. However, no boxes are painted above a blank row, so if there is a 0 in WaterCountMaxRowLengths, all subsequent elements would be ignored.

It is possible to define a header to title a tasting. Headers have texts HeaderLeftText, HeaderCenterText, and HeaderRightText, which are rendered left-aligned to the page, centered and right-aligned. These are shown in font HeaderFont, at size HeaderFontSize, with the baseline of the characters a distance HeaderBaselineFromPageTop from the top of the page (which should be inside the top margin). Likewise FooterLeftText, FooterCenterText, and FooterRightText are shown in FooterFont at size FooterFontSize, with the top of the footer a distance FooterTopFromPageBottom from page bottom (which should be inside the bottom margin). Using all of six of these text positions would be very cluttered. Also, to have different headers on glass sheets and tasting-note sheets set the text parameters to suitable code: {TypeOfPagesBeingRendered /TastingNotes eq {(Tasting-note header)} {(Glass-sheet header)} ifelse}.

Usually elegance is enhanced by having left and right headers of approximately equal length.

Very rarely one might want the centre heading non-centred (e.g.). This can be controlled with HeaderFooterCenterX, which is x position of the centre of the HeaderCenterText and of the FooterCenterText.

Links or other text can also appear in the header or footers of ‘back-of-house pages’, contained in parameters such as FooterCenterText-Backstage, the default value of which is computed from ExternalLinks. There are like parameters FooterLeftText-Backstage, FooterRightText-Backstage, HeaderCenterText-Backstage, HeaderLeftText-Backstage, HeaderRightText-Backstage, which substitute for the non--Backstage parameters on the pre-pour pages, decanting-note and vote-recorder pages.

 Layout

There are several types of layout for the glasses, and which may be used is controlled by the array PermittedPackingStyles, which should contain the permitted styles in order of preference. The code chooses the style from those in PermittedPackingStyles, and chooses the parameters for that style, to maximise the permitted circle radius (whilst ignoring MaxRadius), draws being resolved by order. Below are some examples of the packing styles.

/PseudoHexagonal: circles in each row and column lie midway between those in neighbouring rows and columns. This also has the variant /PseudoHexagonalMirror, which mirrors the placement but not the ordering of the circles.

5 glasses, /PseudoHexagonal on /A4 /Portrait
/PseudoHexagonal
on /A4, /Portrait
8 glasses, /PseudoHexagonal on /A4 /Portrait
/PseudoHexagonal
on /A4, /Portrait
13 glasses, /PseudoHexagonal on /A3 /Landscape
/PseudoHexagonal on /A3, /Landscape
16 glasses, /PseudoHexagonal on /A3 /Landscape
/PseudoHexagonal on /A3, /Landscape
5 glasses, /PseudoHexagonal on /USL=8½″×11″ /Portrait
/PseudoHexagonal
on /USL, /Portrait
9 glasses, /PseudoHexagonal on /USLegal=8½″×14″ /Landscape
/PseudoHexagonal on
/USLegal, /Landscape

/SquareGrid: circles lie in a square grid, in which the distance to vertical neighbours equals that to horizontal neighbours.

5 glasses, /SquareGrid on /A4 /Portrait
/SquareGrid on
/A4, /Portrait
15 glasses, /SquareGrid on /A3 /Landscape
/SquareGrid on /A3, /Landscape

/RectangularDislocation or /RectangularDislocationV: circles lie in a rectangular grid, filling the x and y space, so vertical neighbours not necessarily being the same distance away as horizontal neighbours. There can also be a horizontal “dislocation”, above and below which there is regular grid, but the meeting of which is offset by half a circle. For /RectangularDislocation, the upper block has one column fewer than the lower block. For /RectangularDislocationV this is reversed, the lower block being narrower.

4 glasses, /RectangularDislocation on /A4 /Portrait
/RectangularDislocation
on /A4, /Portrait
5 glasses, /RectangularDislocation on /A4 /Portrait
/RectangularDislocation
on /A4, /Portrait
6 glasses, /RectangularDislocation on /A4 /Portrait
/RectangularDislocation
on /A4, /Portrait
10 glasses, /RectangularDislocation on /A3 /Landscape
/RectangularDislocation on /A3, /Landscape
11 glasses, /RectangularDislocation on /A3 /Landscape
/RectangularDislocation on /A3, /Landscape
5 glasses, /RectangularDislocation on /USL=8½″×11″ /Portrait
/RectangularDislocation
on /USL, /Portrait

/Gaia or /GaiaElegant: inspired by a simpler design seen by the author in Vila Nova de Gaia, and leaving room for a substantial corporate message in the centre of the page—particularly useful to those skilled in Adobe Illustrator.) /Gaia looks less handsome in portrait pages: the default /GaiaElegant applies only when the gap between the vertical columns of circles is at least 1½ circles across, and adjacent glasses are equally spaced. If /GaiaElegant, and there isn’t an elegant /Gaia, treated as /PseudoHexagonal.

6 glasses, /Gaia on /A4 /Landscape
/Gaia on /A4, /Landscape
6 glasses, /Gaia on /USL=8½″×11″ /Landscape
/Gaia on /USL, /Landscape

/Irregular, /IrregularMirror, /IrregularPortrait, /IrregularLandscape, /IrregularMirrorPortrait or /IrregularMirrorLandscape: each of these is a special pattern for exactly five glasses. The …Mirror variants are a mirror image of the non-Mirror variants; the …Landscape variants are ignored unless Orientation is /Landscape; and likewise the …Portrait variants are ignored unless Orientation is /Portrait.

5 glasses, /Irregular on /A4 /Landscape
/Irregular on
/A4, /Landscape
5 glasses, /IrregularMirror on /A4 /Landscape
/IrregularMirror
on /A4, /Landscape

/RectangularAlternateNudge, /RectangularAlternateNudgeMirror, /RectangularAlternateNudgeIf2pt, or /RectangularAlternateNudgeIf2ptMirror: these can be thought of as a compromise between /SquareGrid and /PseudoHexagonal. /PseudoHexagonal is like /SquareGrid, except that alternate rows (or columns) are moved over by half the horizontal (vertical) gap between circles. /RectangularAlternateNudge and relatives do the same, except that the movement is a mere nudge, by less than half the gap. This is less symmetrical, so the …If2pt variants ignore this possibility unless the gain in radius, relative to the best of the possibilities earlier in the array, is ≥ 2pt (so the distance between glasses is improved by ≥ 4pt = 118″ ≈ 1.4mm). The …Mirror variants switch which rows or columns are nudged. Finally, not all numbers of glasses have a solution; /RectangularAlternateNudge… is ignored for those without.

6 glasses, /RectangularAlternateNudge on /USL /Landscape
/RectangularAlternateNudge
on /USL, /Landscape
2 glasses, /RectangularAlternateNudge on /A4 /Landscape
/RectangularAlternateNudge
on /A4, /Landscape

There are also three simple designs, /TopRow, /MiddleRow, /BottomRow, each having everything in one row, with obvious vertical position. In most cases these are too cramped.

The default value of PermittedPackingStyles tests each of /RectangularDislocation, /PseudoHexagonal, /SquareGrid, /RectangularAlternateNudgeIf2pt, /IrregularLandscape, and, redundantly, /GaiaElegant. It then chooses whichever gives the largest radius. Obviously if an elegant /Gaia is wanted one should delete all but /GaiaElegant.

Further control of the layout is possible with RowsMinNum and RowsMaxNum, as the number of rows of glasses is restricted to lie between these two. (It is assumed that 1 ≤ RowsMinNum ≤ RowsMaxNum and RowsMinNum ≤ the number of glasses. If not so, the limits are adjusted sensibly.) Where context requires, RowsMinNum and RowsMaxNum are ignored.

[ [0 2] [2 2] [4 2] [6 2] [0 1] [3 1] [6 1] [0 0] [3 0] [6 0] ]

Additionally, PermittedPackingStyles may contain an array. Such an array must contain only sub-arrays, typically of the form [x y], with y increasing up the page. The code then chooses the radius and separately scales the x and y directions such that things fit as snugly as possible, obviously subject to the other upper bounds on the radius.

There is a more complicated variant, in which some of the sub-arrays are of the form [x y xy]. The first two elements are used, as before, and fix the radius and the canvas. The circle at (x,y) is then moved in a straight line towards (x′,y′). A circle stops moving if it collides with another circle (a tangential touch not being a collision); if it collides with the edge of the page; or it arrives at (x′,y′).

As an example of unmoved and moved circles (inspired by a GC + SW + QH triple vertical in November 2011), the diagram on the right has two frames, the difference being the grey bolded numbers in [ [0 2] [2 2 3 2] [4 2 3 2] [6 2]   [0 1] [3 1] [6 1]   [0 0] [3 0] [6 0] ]. For the author’s taste, it is indeed better with the two A1 circles nearer each other, rather than equally spaced between A0 and A2.

As a convenience, there is the parameter PackingDirectionVertical which can be set to /TopToBottom or /BottomToTop; and PackingDirectionHorizontal with possible values /LeftToRight or /RightToLeft; and the boolean PackingNestingColumnMajor which determines the nesting order. But, in the obvious way, these cannot work with all possible layouts. The same effect can be made, less easily, with GlassesOnSheets.

For large pre-poured tastings on /A3 or /USL2, generally one pre-pours the youngest first. If these are in the front row, it is more fiddly to lower subsequent older vintages into place. This problem can be elegantly dodged by setting PackingNestingColumnMajor to true. Alternatively change PackingDirectionVertical from its default value to /BottomToTop.

When there are few glasses on a page, the radius of the circles could become very large. Hence the radius of the circles is bounded above by MaxRadius. Further, if there are multiple pages of glass sheets, it can look neater if all the pages, or all the pages in the same session, have the same radius. This is controlled by ShrinkRadii, which can be /NotAtAll, so each page’s radius is determined independently; /ToSmallest, so all pages have the same radius; or /ToSmallestSamePageOrdering, so the radius of each page in the same session, presumed to be equivalent to having the same value of PageOrderingNonDecanterLabelGlasses, is shrunk to the smallest of that session’s radii. Alternatively, ShrinkRadii may be an array of the same length as GlassesOnSheets, pages being grouped if their array values are equal (so the default value of ShrinkRadii, “/ToSmallestSamePageOrdering”, is equivalent to “{PageOrderingNonDecanterLabelGlasses}”).

The names appear at the top if NamesAtTop is true, and at the bottom if it is false. The names are rendered in the font NamesFont, at a size equal to the size of the largest of the Circlearrays, subject to a minimum of NamesFontSizeMin and a maximum of NamesFontSizeMax.

If Rotate180AlternateNames is true then, for every other person, the glass and tasting-note pages are rotated 180°. At set-up time this slightly simplifies separation of pages by owner.

The making of decanter labels is controlled by the integer DecanterLabelsNumCopies. If this is ≥1, then the sizes of the Titles etc are reduced so that they fit within a business card of size DecanterLabelMaxSmallerDimension × DecanterLabelMaxLargerDimension, as described in the section Type sizes. The decanter label pages include instructions along the lines of “Cut; paste to the back of a business card; allow to dry; punch holes; hang on decanter; fill decanter; wait; drink.” Two sets of decanter labels can be pasted to both sides of the business cards, sometimes affording those sitting ‘behind’ the labels a clue as to contents.

Side-by-side, right-Handed
Side-by-side, left-Handed

 Side-by-side Glasses and TastingNotes

◊ If having a mini tasting of only three wines, one might wish to print everything on one sheet. For right handers the three glasses would be on the left of the tasting-notes; for lefties, glasses to the right—as in the images on the right. This small-tasting layout is enabled by setting the boolean constant SideBySideGlassesTastingNotes to true. Between the two sides of the paper is a gutter, an internal margin, of size SideBySideGlassesTastingNotesWidthGutter; the proportion of the page occupied by the glasses (from the edge of the paper to the middle of the gutter) being SideBySideGlassesTastingNotesProportionPageGlasses. The people are right-handed unless present in the array LeftHanders.

When SideBySideGlassesTastingNotes is true several of the tasting-note parameters are ignored, action being determined by the glasses equivalent. Ignored parameters include TastingNotesPaperType and TastingNotesOrientation; PageOrderingTastingNotePages; and MirrorPagesTastingNotePages.

 Tasting-note pages

◊ By default there are also tasting-note pages (controlled by GlassesOnTastingNotePages), these pages being of size TastingNotesPaperType and orientation TastingNotesOrientation. The tasting-note pages are lightly divided into columns, the number of columns and the column headings being determined by the array TastingNotesColumnHeadings, by default this being [ (Times) (Eye) (Nose) (Mouth) (Score) ] (the “Times” column being intended to hold the times of decanting and sampling). These column headings are rendered in the font NamesFont at size TastingNotesColumnHeadingsFontSize. The columns have widths proportionate to TastingNotesColumnRelativeWidths, an array of the same length as TastingNotesColumnHeadings. TastingNotesColumnStrokeCode formats and strokes the lines that separate the columns. Technical aside: whilst these tasting-note pages are being rendered the program sets TypeOfPagesBeingRendered to /TastingNotes. Many parameters may be set to code that checks this flag.

The elements of TitlesTastingNotes are shown at a size not exceeding TastingNotesTitlesFontSizeMax, and the elements of SubtitlesTastingNotes are shown at TastingNotesSubtitleFontSizeProportionTitles times the size of the TitlesTastingNotes. The vertical separation between the CirclearraysTastingNotes and TitlesTastingNotes, and between the TitlesTastingNotes and SubtitlesTastingNotes, is TastingNotesLineGap.

TastingNotesCirclesBehind

There is also the decorative boolean TastingNotesCirclesBehind, which repeats the elements from the glasses pages, faded by a factor of either TastingNotesCirclesBehindFadingFactorIfAnyGrey or TastingNotesCirclesBehindFadingFactorIfAllBlack, according to whether ColourSchemeTitles is ever /MidGrey. The circles are in a straight line, the x position at the top being TastingNotesCirclesBehindTopX (0 ⇒ left, 1 ⇒ right), and at the bottom is TastingNotesCirclesBehindBottomX. The complication of the default values causes, over multiple TN pages, some variation to the visual effect. The boolean TastingNotesCirclesBehindFitAndCentreInRow controls whether the circles fit between the horizontal lines made by the Circlearrays (true), or whether they are as large as possible (false). There has been discussion of printing A6 booklets to hold the tasting-note pages, one wine per page. To aid this it is possible to replace the names with page numbers via TastingNotesReplaceNameWithPageNum, the page-number string being defined in TastingNotesPageNumCompoundString, and being shown in a font size reduced by a factor of TastingNotesPageNumFontSizeFactor.

Example of a place-name sheet

 Place Names

◊ At a large formal tasting it is appropriate to label each person’s place-setting, so everybody knows who everybody else is, even late in the tasting. Pages to facilitate this are produced using the PlaceNamesNumCopies parameter, being an integer containing the number of such pages for each person. The pages are formatted to match the Titles: example on right. Generally PlaceNamesNumCopies is deffed to 0 or 1, though might be larger for tastings over multiple sessions.

Pages require three folds. First, fold in half; then fold and press hard along the faint dashed lines (so preventing the corners curling). The side with the small-writing header and footer should face the named person; the side without should face away. Whilst these are being rendered TypeOfPagesBeingRendered is /PlaceName, and the variable PlaceNameSheetNum is the number of the place-name page. So 0 ≤ PlaceNameSheetNum < PlaceNamesNumCopies.

These place-name pages are set on pages of size PlaceNamesPaperType (defaulting to TastingNotesPaperType), and orientation PlaceNamesOrientation (default /Landscape). The lines marking the anti-curling folds are a distance PlaceNamesFirstAndThirdFoldsFromEdge away from the top and bottom edges (defaulting to 36 = ½″ = 12.7mm). The Names are set in font PlaceNamesFont (defaulting to TitlesFont), at the largest size that fits subject to an upper bound of PlaceNamesMaxFontSizeAbsolute (defaulting to 192). The colour scheme used is ColourSchemePlaceNames, this functioning in the same manner as ColourSchemeTitles. Because these names are usually larger than the Titles, various details such as line-widths are set larger by a factor of PlaceNamesDetailsScalingFactor; but this parameter is used partly in the code, and partly in the default values of other parameters.

Caution: if used with FillTitles distillation is excruciatingly slow. Distillation over the web will almost certainly time out: use local conversion.

Example of a pre-pour sheet

 Pre-Pour Sheets

◊ Tastings arranged on ThePortForum are for a maximum of fourteen people, in order to give a 5cl portion to each person (75cl bottle, less the angels’ share and less a little loss during decanting leaves only an edge more than 14×5cl = 70cl). At a tasting attended by eight people, decanters can circulate and people help themselves. But when there are fourteen people and so only 5cl each, portions need to be pre-poured. This could be a source of confusion: “What did you pour into these fourteen glasses?”, “Err, I think…”. Instead glasses are arranged on and closely vincinal to a page that labels them. Then the pourer knows what to pour; and those moving the glasses to the table know what has been poured.

The number of copies of these pre-pour sheets is PrePourNumCopies, by default 0. If pre-pour sheets are wanted this should be set to a higher value: usually /PrePourNumCopies 1 def is sufficient, and 2 would allow for an awkward working space.

The ordering of the loops is controlled by PrePourCollate: if true then PrePourNumCopies is outside SheetNum and WithinPage/WithinTitles; if false then PrePourNumCopies is inside. In a typical vertical tastings, the oldest wines come first in the list, so as to be top-left of the sheet. But decanting is in the reverse order, youngest to oldest, so it is convenient to reverse the order of the pre-pour sheets. This is controlled by PrePourReverseOrder, which defaults to true. There are also obvious parameters PrePourPaperType and PrePourOrientation.

If RotationTitlesAboveBelowOverCirclearray ≠ 0, then small arrows appear on the pre-pour sheets indicating the correct orientation.

Example of a tasting in which over-lapping pages caused problems with the pre-pour sheets

This was constructed from two sheets of A3 card, both of which included the ’63 and ’83. The right sheet was guillotined (shown green), overlapped on the left, and fixed with double-sided sticky tape. The double-presence of the ’63 and ’83 caused them to have two pre-pour sheets, a problem later fixed by PrePourRemoveDuplicatesByWithinTitles. Also observe use of HeaderFooterCenterX.

For some layouts, it may be desirable for a specific bottle to appear on more than one glasses sheet (e.g. when using overlapping sheets). The consequent duplication of pre-pour sheets is removed by PrePourRemoveDuplicatesByWithinTitles being true, its default value. The guillotine-and-overlap trick also messes with the order of the pre-pour sheets, sometimes fixable with PrePourSortByWithinTitles.

To make pre-pour sheets for wines not appearing on a glasses sheet, see NonDecanterLabelGlassesNumCopies.

 Points: The Vote Recorder

◊ At the end of a tasting there is typically a vote for the Wine Of The Night (WOTN), and for large tastings there might also be a vote after each flight or page. The vote is not usually secret, people being asked to declare 1st, 2nd, and 3rd places (scoring 3, 2, 1). To assist the ‘returning officer’ there is paper on which votes can be recorded. For WOTN it is the points that should be recorded, rather than the ranks, as doing so simplifies the addition of the totals. (There is also benefit in there being agreement as to what is recorded: if you record, but I retain the vote-recorder sheet and enter it into a description of the tasting, it is useful that “3” be unambiguously first place three points.)

Indeed, at ThePortForum.com tastings, the rules are slightly more liberal. Each voter has 6 points to assign, which may be assigned in any simple fractions, subject to no one wine receiving more than 3. So permitted scoring patterns include the likes of 3:2:1, and 3:3, and 2:2:2, and 3:1½:1½, and 2:1½:1:½:½:½, and others.

Vote recorder sheets can also be used to hold, in a blind tasting, guesstimates of which is what.

These sheets are enabled by setting VoteRecorders to true. There are then conceptually two levels of loops. Pages are specified, except the question in the top text. Then each of these pages can be re-used with multiple top texts.

The vote-recorder sheet contains the wines within GlassesClusteredOnVoteRecorders, which is a triple-depth array, so one deeper than GlassesOnTastingNotePages. The outermost array is one per vote-recorder page: voting on separate days, with different people or wines, or different total-column-row flags, should be recorded on separate sheets. Within this are ‘clusters’, intended to align with tasting-note pages. Within this are integers pointing to wines. The default value is empty if GlassesOnTastingNotePages is empty, otherwise [GlassesOnTastingNotePages], so the cluster divisions (some 25% grey backgrounding) on the vote recorder are page divisions between the tasting-note pages.

Example of VoteRecorderCrossedBox.

Of the same length as GlassesClusteredOnVoteRecorders is VoteRecorderTopTexts, a double-depth array. The inner arrays hold the one/multiple top-texts to be used with each item of GlassesClusteredOnVoteRecorders. There are also arrays of booleans VoteRecorderShowTotalRow and VoteRecorderShowTotalCol, which specify whether there is to be a total column or row. Generally a total column is always wanted; typically a total row is wanted only for blind-tasting “What is it?” top-texts. The (Total) strings are in VoteRecorderTotalColTitle and VoteRecorderTotalRowTitle: there might be changes for Kernning or different languages. For blind-tasting “What is it?” voting, typically the person who brought a bottle should not guess. Rectangles can be crossed out by setting VoteRecorderCrossedBox to code evaluating to a boolean, that code typically referring to WithinTitles and NameNum.

Also ∃ obvious parameters VoteRecorderPaperType and VoteRecorderOrientation; and VoteRecorderTitlesFontSizeMax and VoteRecorderSubtitleFontSizeProportionTitles.

 Decanting Notes

◊ Those decanting should record the time each bottle is decanted, as well as the condition of the cork and perhaps the qualities of the sediment. Pages to do same are controlled by GlassesClusteredOnDecantingNotes, which has the same structure as GlassesClusteredOnVoteRecorders. There are DecantingNotesNumCopies copies of each page specified by GlassesClusteredOnDecantingNotes. Each page is headed DecantingNotesTopText, the columns being headed DecantingNotesColumnHeadingTimes and DecantingNotesColumnHeadingNotes. Other parameters specify page size and orientation, name the page, the columns, and DecantingNotesSubtitleFontSizeProportionTitles is analogous to VoteRecorderSubtitleFontSizeProportionTitles.

Also ∃ obvious parameters DecantingNotesPaperType and DecantingNotesOrientation, and DecantingNotesTitlesFontSizeMax and DecantingNotesSubtitleFontSizeProportionTitles.

Example of a cork-display page.

 Cork Display

Bottles having been decanted, corks should be put on display, for which pages are activated by /CorkDisplay true def. There are CorkDisplayNumCopies of each, and also CorkDisplaySpaceForNumExtras blanks for extra bottles that might appear. Each rectangle is at least CorkDisplayMinWidth wide, and at least CorkDisplayMinHeight high; and the corks shown are in GlassesClusteredOnCorkDisplay, a triple-depth array resembling GlassesClusteredOnVoteRecorders. Pages are titled with CorkDisplayTopText, defaulting to “The Corks”. The paper type is CorkDisplayPaperType; the orientation being chosen automatically.

 Sticky labels

What is the purpose of the sticky labels that isn’t handled by the decanter labels?

So go back in time, to the start of decanting. Some bottles will be clearly labelled. Others might have little more than a capsule, so after opening, could be entirely unlabelled. To prevent confusion there should be, printed onto sheets of sticky labels, bottle labels, to avoid the potential confusion. Alternatively, in an informal tasting, with many more wines than glasses, it can be useful to stick to the foot of the glass (please, never the bowl, always the foot) a very small sticky label identifying the current contents. Specifying these largely requires describing the sheet of labels

Sticky labels appear if StickyLabelsNumCopies exceeds zero, and multiple copies are permitted. If the labels are for bottles, there is one per wine. If for glasses, there is one per wine per element of Names. StickyLabelsByNameWhichReplaceCirclearrays controls which; if there is one label per wine per person, then the element of Circlearrays is replaced with the element of Names.

To allow both bottle and glass labels, the sticky labels can be of multiple types, as contained in the array StickyLabelsTypes. This does very little: the sticky label code is run with StickyLabelsTypeThis set to each element of this in turn. The other parameters might choose to access the current value of StickyLabelsTypeThis. With StickyLabelsTypeThis equalling 0 the default parameters fit Ryman product 0220013460 (containing 25 sheets, or equivalently to the 100-sheet pack 0220023460), having on each A4 sheet eight labels, each 99mm×68mm. With StickyLabelsTypeThis equalling 1 the default parameters fit Avery J8651, each sheet of which has 65 labels, each 38.1mm×21.2mm. Regular users of this software should inform the author if other sheets of labels should be included in the defaults.

If not using a default, the user must change the specification of the label layout. For all the following it is assumed that the page is portrait.

Then StickyLabelsOrientation is the desired orientation of the labels. That is not necessarily the same as the orientation of the page: if, with the page held portrait, labels are wider than they are high, it will be the opposite. Allowed values are /Landscape and /Portrait. If StickyLabelsOrientationAutomatic then StickyLabelsOrientation is ignored, the orientation being chosen automatically, the code choosing /Landscape unless switching to /Portrait would increase the linear size of the text by ≥√√2.

If one has a part-used sheet of labels, it can help to specify the where on the first page of sticky labels to start, as if StickyLabelsFirstPageStartPosition had already been done.

To make sticky labels for wines not appearing on a glasses sheet, see NonDecanterLabelGlassesNumCopies.

There are also settings StickyLabelsReverseOrder, StickyLabelsRemoveDuplicatesByWithinTitles, and StickyLabelsSortByWithinTitles, which are analogous to the similarly-named PrePour… settings.

 Non-easy parameters

Stylised glasses sheet, 1 of 2 Stylised glasses sheet, 2 of 2

 GlassesOnSheets and GlassesOnTastingNotePages

◊ Imagine that ten wines are to be tasted—too many for one sheet of /A4 or /USL. So instead the glasses could be split over two sheets, as shown on the right.

This is done using the parameter GlassesOnSheets, which is an array of arrays, each of the inner arrays listing the elements of Titles etc to be on that page. This two-sheet example happens with GlassesOnSheets set to [   [ 0 1 2 3 4 ]   [ 5 6 7 8 9 ]   ], which is the default with Titles of length ten. Observe that numbering starts at 0: the first wine (described by the first element of each of Titles, Subitles, Circlearrays, and FillTexts) is number 0; the tenth glass is therefore number 9.

In the picture the WaterCounts are on the right side of the second page—as the author is right-handed. Participants are right-handed unless in LeftHanders, an array of the names of known left-handers. Which pages have water counts is controlled by WaterCountShowRight and WaterCountShowLeft. These parameters are described in the section on WaterCounts.

GlassesOnSheets has a more general purpose. As a putative tasting is being arranged, there are candidate bottles, some of which will appear in the final version. Create entries in Titles, Subitles, Circlearrays, and FillTexts for all these wines. Then, when decisions have been taken, use GlassesOnSheets to select from them, and to determine which wines appear in which order on which sheets.

The default value of /GlassesOnSheets is complicated. Let n = the length of Titles. Then if n ≤ 6, GlassesOnSheets is [ [0 1 2 … n–1] ], so putting all the glasses on a single page. Otherwise there are ⌈n ÷ 6⌉ pages, the glasses being distributed as evenly as possible, so each page holding ≤ 6. This default has been optimised for A4 or 8½″×11″ page sizes; if your PaperType is neither /A4 nor /USL, then this default will very likely need changing.

The parameter GlassesOnTastingNotePages works the same way, controlling the tasting-note pages. By default it is set to GlassesOnSheets, which is sensible with a PaperType of /A4 or /USL. Having more than six-ish wines per /A4 or /USL page of tasting notes can leave too little space for writing, so, if the glasses are on /A3 or /USL2, the default value of GlassesOnTastingNotePages will most likely also need changing.

 Type sizes

The type sizes of Titles and Abovetitles, Belowtitles and Overtitles are controlled by a multi-stage process.

  1. First, the Titles are fitted, and various one-at-a-time constraints applied. These include:

    For these purposes, “the circle” is the inside of the Circlearrays, adjusted by ExclusionAnnulusProportionInnerRadiusTitlesAboveBelow (for the Titles, Abovetitles and Belowtitles) or by ExclusionAnnulusProportionInnerRadiusOvertitles (for just the Overtitles). These might behave weirdly if negative or ≥1, and default to zero which uses all available space.

  2. Second, the font sizes of the Titles are considered together. It would look messy if there were many type sizes, only slightly different. If FontSizesTitlesNotSmallerIfTitlesNotLonger true, then sizes are so constrained. I.e., the font size of “Df” must be ≤ the font size of “W” which must = that of “I”. Then a constraint is applied to their ratio: for two titles, either they have the same font size, or the larger÷smaller ratio of their font sizes ≥ FontSizesRatioTitlesMin, which defaults to 2.

    Except that one might not wish to apply this constraint over pages in different sessions: it would hardly matter whether yesterday’s sheets did or did not precisely match today’s. So there is an array FontSizesSetsGlassesPages of the same length as GlassesOnSheets, and pages with matching values in this array are considered together.

  3. Third, Abovetitles, Belowtitles and Overtitles are fitted around the Titles. Then, if needed, these are lowered to the size of the matching element of Titles, times AbovetitleMaxFontSizeProportionTitles, BelowtitleMaxFontSizeProportionTitles or OvertitleMaxFontSizeProportionTitles.

  4. Fourth, as with the Titles, fewer matching font sizes would look better. If FontSizesAboveBelowOverNotSmallerIfTitlesNotLonger, then, in turn and separately for each of Abovetitles, Belowtitles and Overtitles, lengths are constrained according to the lengths of the elements of Titles. Then the ratio of FontSizesRatioAboveBelowOverMin is used, and over the same FontSizesSetsGlassesPages sets of pages.

    But should Abovetitles be considered with Overtitles? If their fonts are very different, perhaps not. So there is an array of length three, FontSizesSetsAboveBelowOver, the elements of which refer to ‘Above’, ‘Below’ and ‘Over’, in that order. If the elements of FontSizesSetsAboveBelowOver match, the arrays are considered jointly. Typically, arrays in the same or similar fonts should be considered together; those in very different fonts should not.

How big is the circle text? In points, not bigger than CircletextMaxFontSizeAbsolute; and as a proportion of the circles’ radius not bigger than CircletextMaxFontSizeProportionRadius. If, in a font size equal to the lesser of these two, a particular item in Circlearrays is too long to fit at least CircletextsMinCopies times, then the font size is reduced such that it does. If CircletextsSameFontSizeIfRadiiShrunkToBeSame, then across all pages compelled to have the same radius (see ShrinkRadii), the Circlearrays are compelled to have the same size. If not, the font size of Circlearrays can vary within and between pages. (Technical note: CircletextsSameFontSizeIfRadiiShrunkToBeSame should have the same boolean value over any such set of pages. Typically this is most easily achieved by having it depend on PageOrderingNonDecanterLabelGlasses SheetNum get or on ShrinkRadii SheetNum get, rather than directly on SheetNum.) If Rays is activated, then CircletextsTryToResonateWithRays can improve the look of a very short item of Circlearrays, such as [ /dagger ] = “†”. The number of copies is also bounded above by CircletextsMaxCopies; when this is invoked the the number of copies that would otherwise appear is on the top of the stack, so CircletextsMaxCopies could be code referring to it, such code advisedly starting with a “dup”. Relatedly, the minimum separation between the items of the sub-arrays of Circlearrays, measured in space-widths, is CircletextsMinNumSpacesBetween.

 BackgroundTextsGlasses

BackgroundTextsGlasses: some 1982s BackgroundTextsGlasses: some 1983s    BackgroundTextsGlasses: more 1982s BackgroundTextsGlasses: more 1983s

In some multi-page tastings, for each page all the wines have something in common. A typical example is a multi-horizontal, in which wines from several houses are tasted from two or few vintages. As everything on a page has a common feature, perhaps this common feature should be marked, faintly, as in the two-session four-page example on the right.

This is activated by setting BackgroundTextsGlasses to true. Then BackgroundTextsGlassesTexts is an array of the same length as GlassesOnSheets, containing the strings to be shown. The strings should be short: one or two characters is recommended, and are shown in font BackgroundTextsGlassesFont.

The text is shown in the centre of the page, the separate x and y sizes each as large as possible, subject to the following.

The bounding path of the text is constructed and then BackgroundTextsGlassesPaintCode is executed. The default clips then strokes, but the example above shows a plain fill.

The boolean parameter BackgroundTextsTastingNotes also shows these on the tasting-note pages. For each such page, if every glass on the page appears on a glasses page with the same BackgroundTextsGlassesTexts, then that item is shown on the page. For pre-pour pages, which are naturally associated with a glasses page, the boolean BackgroundTextsPrePour causes the BackgroundTextsGlassesTexts to appear.

 Separating flights within a page

[   [ [/Left 0 3 -0.5] [0 3] [/Top 3 0 +0.5] ]   [ [/Left 5 +1.0] [/Clockwise 5] [/Bottom 5 +1.0] ]   [ [/Bottom 3] /Curve [3 6] /Curve [3 1] /Curve [/Top 3] ]   [ [/Top 4] [1 4] [/Widdershins 4] [/Bottom 4] ]   [ /Closed [/Right] [/Bottom] [/Clockwise 7] [/Widdershins 4] [/Clockwise 2] ]   ]
[ /Closed [0 3] [3 1] /Curve [1 4] [4 2] [4 7] /Curve  [4 6] [/Widdershins 6] [6 3] /Curve [3 5] ]

◊ It is often natural to split a tasting into ‘flights’ of a few wines. This can structure a balance between quietly contemplating the differences between wines, and subsequent sociable discussion. The parameters FlightSeparations and FlightSeparationLines allow the page to be divided into zones. However FlightSeparationLines is fiddly, and if one wine is added or taken away, will need to be completely reworked. Hence it is recommended that division into flights be saved until late in the planning.

FlightSeparations is a boolean: true to activate the line-drawing code, false de-activated. The real work is done by FlightSeparationLines, being an array nested four deep. FlightSeparationLines is of the same length as GlassesOnSheets. Each item of FlightSeparationLines is an array, each of which holds line descriptions, as many as there are lines on that page. Each line description is an array, pieces of which can be as follows.

Examples can be found at www.jdawiseman.com/papers/placemat/flightseparations.pdf, the header showing that page’s item of FlightSeparationLines (i.e., FlightSeparationLines is an array one deeper than the header). If using FlightSeparations it is strongly recommended that these PDF examples be examined and appropriate parts used as a starting draft. The first two pages of this file are shown on the right, the first having many example lines, to the gain of instruction and the loss of aesthetics.

The path can be stroked, clipped or filled by the code FlightSeparationPaintCode, which has a default stroke that is complicated but elegant. Use of fill is discouraged, as it impedes comparison of colours of the wines. If FlightSeparationPaintSeparately then FlightSeparationPaintCode is invoked after each line, the variable FlightSeparationLineNum being set to the appropriate integer ≥ 0. If not FlightSeparationPaintSeparately, then all the lines on the current page are drawn, after which is the single call of FlightSeparationPaintCode. The former is better if the format is not constant; the latter preferred if overlapping or crossing lines are to be double-stroked.

Some control over the radius of the arcs is sometimes possible. If any circles touch, the radius of the arcs equals that of the circles. If no circles touch (probably because of MaxRadius or ShrinkRadii) then FlightSeparationArcRadiusControl controls the radius. FlightSeparationArcRadiusControl should be both ≥0 and ≤1; the default being the maximum. If it is 0, the radius of the arcs is that of the circles. If 1, the radius is the half the distance between the closest circles. If between, between.

 Page order

◊ The order of the pages is controlled by eight arrays of integers.

Array nameLengthDefault
entries
Default explained
PageOrderingNonDecanterLabelGlassessame as GlassesOnSheets0 Sorted into order by the algorithm: for simplicity of table setting starting with interleaved glasses sheets and tasting-note sheets; then the vote-recording page(s) to be placed with the returning officer’s tasting-note sheets; then decanting-notes, cork display and pre-pour pages.
PageOrderingTastingNotePagessame as GlassesOnTastingNotePages0
PageOrderingVoteRecordersame as GlassesClusteredOnVoteRecorders0
PageOrderingDecantingNotessame as GlassesClusteredOnDecantingNotes0
PageOrderingCorkDisplaysame as GlassesClusteredOnCorkDisplay0
PageOrderingPrePourPagessame as GlassesOnSheets0
PageOrderingPlaceNamesPlaceNamesNumCopies100Separated from 0s to facilitate pre-tasting folding.
PageOrderingDecanterLabelssame as GlassesOnSheets200Separated from above to facilitate pre-tasting gluing.
PageOrderingStickyLabelssame as GlassesOnSheets300Separated from above so there is a single switch of printer paper to the labels.

Draws are resolved in a manner that separates pages on different paper types, perhaps simplifing printer loading, as described by the following algorithm (in which “matching” means matching the page ordering and the paper type).

For a tasting over multiple sessions it can be helpful to have a page order more complicated than the default. For example, imagine a tasting split over afternoon and evening sessions, each session having three glasses pages and two tasting-note pages per person (example of such a tasting, inspiring but pre-dating these page-order controls). Managing such a tasting will be enough work and spare on the day: simplifying the task of table setting, thus reducing the likelihood of error, is worthwhile. One might set:

/PageOrderingNonDecanterLabelGlasses [ 10 10 10  20 20 20 ] def
/PageOrderingTastingNotePages [ 10 10  20 20 ] def
/PageOrderingVoteRecorder  [ 10 ] def
/PageOrderingDecantingNotes  [ 10 20 ] def
/PageOrderingCorkDisplay  [ 10 20 ] def
/PageOrderingPrePourPages [ 10 10 10  20 20 20 ] def
/PageOrderingPlaceNames [ 1 2 ] def
/PageOrderingDecanterLabels [ 0 0 0  0 0 0 ] def
/PageOrderingStickyLabels [ 65535 65535 65535  65535 65535 65535 ] def

First out of the printer are the decanter labels, which can be cut and pasted to business cards in advance (integer: 0). Next are place-name pages for the two sessions, collated, to be folded before the day (1 and 2). Next are the glasses and tasting-note pages for the afternoon, with each person’s five pages together (10), followed by the vote recorder for the day (10), and the decanting-notes and pre-pour sheets for that session (10). Then the glasses and tasting-note pages for the evening, with each person’s five pages together (20) followed by decanting-notes, cork-display and pre-pour sheets (20). Finally the bottle labels at the end (65535) for ease of paper-changing in the printer.

The values in PageOrderingNonDecanterLabelGlasses are used by ShrinkRadii as they are presumed to define sessions. The values in PageOrderingNonDecanterLabelGlasses are also used to determine the default values of WaterCountShowRight and WaterCountShowLeft.

 Page mirroring

◊ Generally one should print using toner not ink, as a single drop of wine or water causes ink to smudge. Alternatively, one could print the glasses mats onto acetate, and use the non-printed side. This requires mirroring the page, this being controlled by the eight arrays MirrorPagesNonDecanterLabelGlasses, MirrorPagesTastingNotePages, MirrorPagesVoteRecorder, MirrorPagesDecantingNotes, MirrorPagesCorkDisplay, MirrorPagesPrePour, MirrorPagesPlaceNames, MirrorPagesDecanterLabels, and MirrorPagesStickyLabels. These are of the same length as the arrays PageOrdering…, though contain booleans. By default all values are false.

Use of page mirroring should be accompanied by use of PageOrdering…, to ensure that the acetates are consecutive.

 Numbers of copies

For most types of sheet, there is a parameter controlling how many copies appear. Already described are DecanterLabelsNumCopies, StickyLabelsNumCopies, PlaceNamesNumCopies, PrePourNumCopies, DecantingNotesNumCopies. Analogously, there are parameters NonDecanterLabelGlassesNumCopies and TastingNotePagesNumCopies, both defaulting to 1. For the vote-recorder sheets the parameter is a boolean, VoteRecorders.

NonDecanterLabelGlassesNumCopies has a role that is not obvious. For both the pre-pour sheets and the sticky labels what appears there is a scaled version of that on the glasses sheets. So if a wine does not appear on the glasses sheets, it cannot appear on the pre-pours or sticky labels. But what if this is wanted? What if the pre-pour sheets should be known wines such as D63 F63 G63 T63, but the glasses sheets should be a blinded version of this such as α63 β63 γ63 δ63 (example of such a tasting)? Then construct additional glasses sheets to hold the material for the extra pre-pour or sticky-label sheets, but suppress their output with something like /NonDecanterLabelGlassesNumCopies {SheetNum 4 ge {0} {1} ifelse} def. That done, the values of GlassesOnTastingNotePages and GlassesClusteredOnDecantingNotes might also need work.

 Suppressing pages

You have made the placemats for somebody else’s large tasting. But that somebody else wants to change a font; or doesn’t know what is a pre-pour sheet nor whether they are wanted. One could make several new versions, each of several megabytes and several hundred pages, and email those. But only a few pages are relevant. One could kill the other pages by specifying 0 copies or setting their presence to false, and by reducing the number of wines and people. What a faff, and because of the interactions between font sizes, doing so might change the shown pages. Instead suppress temporarily-unwanted page types with the array TestingSuppressPageTypes, which can contain any of /Glasses /TastingNotes /PlaceName /PrePour /StickyLabels /VoteRecorder /DecantingNotes /CorkDisplay /DistillerLog. Also set TestingMaxNumPagesToShow to a small integer, which will suppress all subsequent pages.

 Placemat ©

Who owns the © of the output, of the placemats? The parameter CopyrightStatementPlacemats holds this, defaulting to “Copyright 2013 Julian D. A. Wiseman of www.jdawiseman.com”. Obviously, adjust to your needs, copying the form. By default others may use the output, as given in the human-readable text LicensingAgreementTextPlacemats, defaulting to “This work is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported Licence.” There is the related parameter LicensingAgreementLinkPlacemats, defaulting to (http://creativecommons.org/licenses/by-nc-sa/3.0/deed.en_GB). Obviously LicensingAgreementTextPlacemats and LicensingAgreementLinkPlacemats should be consistent. It is hoped to embed these permissions, and perhaps additional parameters, in a machine-readable manner. Please could those with expertise in the use of pdfmark read the request for help, and then help.

 Code within parameters

It is possible to vary the parameters by sheet or by glass, as described at www.jdawiseman.com/papers/placemat/placemat-code.html. The same page also describes how to add code inside compound strings, and gives examples of why this might be done.

Page typeTypeOfPagesBeingRendered
(ThisPageDecanterLabels)
URL ending of first
page of this type
Glasses/Glasses
false
…#Glasses_0
Tasting notes/TastingNotes…#TastingNotes_0
Vote recorders/VoteRecorder…#VoteRecorder_0
Decanting notes/DecantingNotes…#DecantingNotes_0
Cork display/CorkDisplay…#CorkDisplay_0
Pre-pour pages/PrePour…#PrePour_0
Place names/PlaceName…#PlaceName_0
Decanter labels/Glasses
true
…#DecanterLabels_0
Sticky labels/StickyLabels…#StickyLabels_0

 Linking to specific pages within the PDF

So that it is possible to link to specific pages within the PDF, the PDF includes some ‘nameddest’s. However, the use of these is imperfectly reliable (see help received). It seems to work when opening a PDF within the browser, but if the PDF is read by a separate application, it seems not to work.

To link to the first of the pages of glasses the URL should end …#Glasses_0. For second page, …#Glasses_1; etc. Links for other types of pages are shown in the table on the right. The log file also contains a list of the “URL # tags” added to the PDF.

 Errors: causation and avoidance

This is a PostScript program, and its various parameters are entered directly in PostScript. The program does little error checking. If parameters are malformed (e.g., non-matching parentheses), or if the parameters have nonsense values, then the output might be inelegant, incomplete, or non-existent.

If it just won’t work, then start again with the code as published at www.jdawiseman.com. Does that distill correctly? Then change the Titles etc, and set the Circlearrays to be something simple of the same length. Does that distill correctly? Then add any required complexity to the Circlearrays, and re-test, before setting the other parameters one at a time. If you believe yourself to be coping competently, and it still won’t work, contact the author, enclosing in the email a link to the PostScript file and the log file produced by the distiller, and saying which program you use for the ps→pdf conversion.

The program outputs to a log file. This can contain various ‘Error’s, ‘Warning’s, and ‘Advice’s, as well as values of variables and other diagnostics. Perusal of this data might help. If OutputLogToPage is still at its default value of true, this log file also appears at the end of the output. There is the analogous parameter OutputLogToLog, and LogThisExtra, a user-chosen string which is output to the log.

 Comment

Avatar of jdaw1
Avatar of jdaw1

The author welcomes comment on this program, which may be by email or in the appropriate thread on The Port Forum, there also being a thread showing the used parameters from actual tastings. The author’s most-often used avatars are to the sides of this paragraph, and there is also an svg gravatar, each of these being a stylised placemat.

 Who to invite?

Permission is given to make non-commercial use of this program as you see fit, and to distribute its output. But not to distribute the code: refer interested parties to the latest version via this page (www.jdawiseman.com/papers/​placemat/​placemat.html). Those with improvements to the code are invited to send them to the author.

It hardly needs saying that the finest way to thank me for this excellent product would be an invitation to your tasting! I’m particularly fond of port and Madeira, and to a lesser extent of whisky and beer, but am willing to have my horizons broadened. Let me check my diary… yes, that evening is good—thank you very much indeed.

Julian D. A. Wiseman


 Recent changes

April 2013

March 2013

February 2013

January 2013

December 2012

November 2012


Main index Top About author