Erik van Blokland 3646055ea2 initial import
git-svn-id: http://svn.robofab.com/trunk@1 b5fa9d6c-a76f-4ffd-b3cb-f825fc41095c
2008-01-07 17:40:34 +00:00

434 lines
45 KiB
HTML
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8" /><title>
RoboThon 2006: Scripting for production
</title>
<link href="../default.css" type="text/css" rel="stylesheet" />
<link href="../code/robothon06/py2html.css" type="text/css" rel="stylesheet" />
</head><body>
<script type="text/javascript" src="http://www.google-analytics.com/urchin.js"></script>
<script type="text/javascript">
_uacct = "UA-2044310-2";
urchinTracker();
</script>
<div id="modellogo">
<img src="../img/drawmodel_header.jpg" width="595" height="112" />
</div>
<div class="leftcontent">
<h1 class="crb-seealso">
RoboFab
</h1>
<p class="menu">
<a href="../index.html">
Home
</a>
<br />
<a href="../download/index.html">
Download v1.1.1
</a>
<br />
<a href="../intro.html">
Intro
</a>
<br />
<a href="../install.html">
Install Notes
</a>
<br />
<a href="../history.html">
History
</a>
<br />
<a href="../executive.html">
Summary
</a>
</p>
<p class="menu">
<a href="../howto/index.html">
How to's
</a>
<br />
<a href="index.html">
Step by step
</a>
<br />
<a href="../tools/dialogs.html">
Fab Dialogs
</a>
<br />
<a href="../objects/index.html">
Object reference
</a>
<br />
<a href="../objects/model.html">
Object map
</a>
<br />
<a href="../tools/index.html">
Tools
</a>
<br />
<a href="../ufo/index.html">
UFO Overview
</a>
<br />
<a href="../ufo/specification.html">
UFO Spec
</a>
<br />
<a href="../limitations.html">
Fab Limitations
</a>
<a href="../links/index.html">
Links
</a>
<br />
<a href="../credits.html">
Credits
</a>
</p>
<h1 class="crb-seealso">
Support RoboFab
</h1>
<form action="https://www.paypal.com/cgi-bin/webscr" method="post">
<input type="hidden" name="cmd" value="_s-xclick">
<input type="image" src="https://www.paypal.com/en_US/i/btn/x-click-but21.gif" border="0" name="submit" alt="Make payments with PayPal - it's fast, free and secure!">
<img alt="" border="0" src="https://www.paypal.com/en_US/i/scr/pixel.gif" width="1" height="1">
<input type="hidden" name="encrypted" value="-----BEGIN PKCS7-----MIIHRwYJKoZIhvcNAQcEoIIHODCCBzQCAQExggEwMIIBLAIBADCBlDCBjjELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAkNBMRYwFAYDVQQHEw1Nb3VudGFpbiBWaWV3MRQwEgYDVQQKEwtQYXlQYWwgSW5jLjETMBEGA1UECxQKbGl2ZV9jZXJ0czERMA8GA1UEAxQIbGl2ZV9hcGkxHDAaBgkqhkiG9w0BCQEWDXJlQHBheXBhbC5jb20CAQAwDQYJKoZIhvcNAQEBBQAEgYCwSKfv3n+m7gMAQttRdiUdaGxSHt2oKSNvYzSFsBPjNsxmwva6gPCPUFV5sfJY1QJQuzQk8iXLqxb/mKmdoWc8Z2Eq7+rUtgo0149vBg35woLGv8zoMkgbghCcHJjdclAl/KOSqhjCOblpCsXpJwy9fs1wuxSOrbDwO5C26bXOkzELMAkGBSsOAwIaBQAwgcQGCSqGSIb3DQEHATAUBggqhkiG9w0DBwQItAyVpzgCAg2AgaA4Sx/oMTU9S7iN3M25nZ1ebqx2vt1UMGcUGtDmk13jLL1IO4lXmG1Lb/lTKJSg1d2Aj/OQJrOpL7T2yEGFkqK0yojO8+CUXHOihCJ+ovr2r7VkBi2C425JSRjRh5wPc4LN2UxCn2FhMrZwc6Mnq9Emuh2Mf35oEQ2ZfKZs37yDlB6RL4hTfmUEMibLwrQPwD+NmpihgZ6LrWvPrIDLeWFdoIIDhzCCA4MwggLsoAMCAQICAQAwDQYJKoZIhvcNAQEFBQAwgY4xCzAJBgNVBAYTAlVTMQswCQYDVQQIEwJDQTEWMBQGA1UEBxMNTW91bnRhaW4gVmlldzEUMBIGA1UEChMLUGF5UGFsIEluYy4xEzARBgNVBAsUCmxpdmVfY2VydHMxETAPBgNVBAMUCGxpdmVfYXBpMRwwGgYJKoZIhvcNAQkBFg1yZUBwYXlwYWwuY29tMB4XDTA0MDIxMzEwMTMxNVoXDTM1MDIxMzEwMTMxNVowgY4xCzAJBgNVBAYTAlVTMQswCQYDVQQIEwJDQTEWMBQGA1UEBxMNTW91bnRhaW4gVmlldzEUMBIGA1UEChMLUGF5UGFsIEluYy4xEzARBgNVBAsUCmxpdmVfY2VydHMxETAPBgNVBAMUCGxpdmVfYXBpMRwwGgYJKoZIhvcNAQkBFg1yZUBwYXlwYWwuY29tMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDBR07d/ETMS1ycjtkpkvjXZe9k+6CieLuLsPumsJ7QC1odNz3sJiCbs2wC0nLE0uLGaEtXynIgRqIddYCHx88pb5HTXv4SZeuv0Rqq4+axW9PLAAATU8w04qqjaSXgbGLP3NmohqM6bV9kZZwZLR/klDaQGo1u9uDb9lr4Yn+rBQIDAQABo4HuMIHrMB0GA1UdDgQWBBSWn3y7xm8XvVk/UtcKG+wQ1mSUazCBuwYDVR0jBIGzMIGwgBSWn3y7xm8XvVk/UtcKG+wQ1mSUa6GBlKSBkTCBjjELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAkNBMRYwFAYDVQQHEw1Nb3VudGFpbiBWaWV3MRQwEgYDVQQKEwtQYXlQYWwgSW5jLjETMBEGA1UECxQKbGl2ZV9jZXJ0czERMA8GA1UEAxQIbGl2ZV9hcGkxHDAaBgkqhkiG9w0BCQEWDXJlQHBheXBhbC5jb22CAQAwDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQUFAAOBgQCBXzpWmoBa5e9fo6ujionW1hUhPkOBakTr3YCDjbYfvJEiv/2P+IobhOGJr85+XHhN0v4gUkEDI8r2/rNk1m0GA8HKddvTjyGw/XqXa+LSTlDYkqI8OwR8GEYj4efEtcRpRYBxV8KxAW93YDWzFGvruKnnLbDAF6VR5w/cCMn5hzGCAZowggGWAgEBMIGUMIGOMQswCQYDVQQGEwJVUzELMAkGA1UECBMCQ0ExFjAUBgNVBAcTDU1vdW50YWluIFZpZXcxFDASBgNVBAoTC1BheVBhbCBJbmMuMRMwEQYDVQQLFApsaXZlX2NlcnRzMREwDwYDVQQDFAhsaXZlX2FwaTEcMBoGCSqGSIb3DQEJARYNcmVAcGF5cGFsLmNvbQIBADAJBgUrDgMCGgUAoF0wGAYJKoZIhvcNAQkDMQsGCSqGSIb3DQEHATAcBgkqhkiG9w0BCQUxDxcNMDYwNTA1MDk0MDI3WjAjBgkqhkiG9w0BCQQxFgQUuGyd1NYqa4RVlKQ48vrRVsRjTXYwDQYJKoZIhvcNAQEBBQAEgYC6ZiJbUzbugBCir8QnRYRas0tJrdMXcUXQnO3HlO5Zj7+F9cGT2NI73VgB5Vhpu+OaMjBcmc8f0LSP6/ns48YZiIki3+nilxKt/sEq3R0B9XeoB21nHxLmlWkFGMGKxPexWEkjJq0v3UNhS6mYDAIdLkrLE6RHRYAVvKET8hkzDw==-----END PKCS7-----
">
</form>
<h2 class="crb-seealso">
Up
</h2>
<p class="menu">
<p class="bonbon_uplink"><a href="index.html">Back to Step by step</a></p>
</p>
<h2 class="crb-seealso">
See also
</h2>
<p class="menu">
<a href="../howto/scripting.html">Scripting</a><br /><a href="basic.html">Basic Python</a><br /><a href="dialogkit.html">Dialog Kit</a><br /><a href="examples/index.html">RoboThon 2006</a><br /><a href="index.html">Step by step</a><br /><a href="robofab_session4.html">NoneLab</a><br />
</p>
</div>
<div class="footer">
<a href="../feedback.html">
Feedback
</a>
<br />
<a href="../map.html">
Sitemap
</a>
<br />
Please also refer to the
<a href="../download/license.html">
Legal
</a>
<br />
Copyright 2003-2006 RoboFab
<br />
version 1.1.1
</div>
<div class="google">
<h2>RoboFab Mailinglist</h2>
<p>
Join the RoboFab users community at Google groups.
</p>
<img src="http://groups.google.com/groups/img/3nb/groups_bar.gif" alt="Google Groups" height="26" width="132" />
<p>
<form action="http://groups.google.com/group/robofab/boxsubscribe">
Email: <input type="text" name="../email" />
<input type="submit" name="../sub" value="Subscribe" />
</form>
</p>
<p>
<a href="http://groups.google.com/group/robofab">Visit this group</a>
</p>
<h2>RoboFab Sponsors</h2>
<script type="text/javascript">
google_ad_client = "pub-3703953449723704";
google_ad_width = 120;
google_ad_height = 600;
google_ad_format = "120x600_as";
google_ad_type = "text_image";
google_ad_channel ="";
google_color_border = "336699";
google_color_bg = "FFFFFF";
google_color_link = "0000FF";
google_color_url = "008000";
google_color_text = "000000";
</script>
<script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"></script>
</div>
<div class="content">
<h1>
Scripting for production
</h1>
<img src="http://letterror.com/code/robofab/img/ondrawmodel_07.gif" />
<h2>Production</h2>
<p>
In the production phase of a font it all comes together: moving stuff around, naming, interpolations, quality control, generating, database work, it pays to invest some time (or money) in some really good scripts. Each foundry and designer has their own preferred ways of doing things. It's impossible to describe one production process and please everyone. So instead we're going to look at some of the things you probably have to do anyway. You will have to match and adapt for your own methods.
</p>
<p>
Production scripts can save a lot of time. But be careful: it is costly to make mistakes with your production sources. Make sure to <strong>test</strong> production scripts first on duplicate data, preferably in a different folder. Doing something "quickly" to a massive kerning table only to discover it was your only copy, and the action was wrong — will not save you any time. Like carpentry: measure twice, cut once.
</p>
<h2>Batch processing</h2>
<p>
Here are some examples of applying changes to several fonts at once using <strong>AllFonts()</strong>. Keep in mind that this applies to all fonts you have open in FontLab. So make sure to close any fonts that you don't want treated this way before running the script.
</p>
<div class="pythonsource"><pre># robothon06<br># set font info in all fonts<br> <br><span class="py_res">from</span> <span class="py_key">robofab</span>.<span class="py_key">world</span> <span class="py_res">import</span> <span class="py_key">AllFonts</span><br><span class="py_res">for</span> <span class="py_key">font</span> <span class="py_res">in</span> <span class="py_key">AllFonts</span>():<br>&nbsp; &nbsp; <span class="py_key">font</span>.<span class="py_key">info</span>.<span class="py_key">familyName</span> = <span class="py_str">"MyFamily"</span><br>&nbsp; &nbsp; <span class="py_key">font</span>.<span class="py_key">info</span>.<span class="py_key">ascender</span> = <span class="py_num">700</span><br>&nbsp; &nbsp; <span class="py_key">font</span>.<span class="py_key">info</span>.<span class="py_key">descender</span> = -<span class="py_num">300</span><br>&nbsp; &nbsp; <span class="py_key">font</span>.<span class="py_key">update</span>()<br> <br></pre></div><div class="pythonsourcetitle"><a href="examples/allFontsFontInfo.py" target="new">download examples/allFontsFontInfo.py</a></div>
<p>
Obviously you can extend these to do lots more.
</p>
<div class="pythonsource"><pre># robothon 2006<br># get info attributes for all fonts<br># and dump them to a text file<br> <br><span class="py_res">from</span> <span class="py_key">robofab</span>.<span class="py_key">world</span> <span class="py_res">import</span> <span class="py_key">AllFonts</span><br><span class="py_res">from</span> <span class="py_key">robofab</span>.<span class="py_key">interface</span>.<span class="py_key">all</span>.<span class="py_key">dialogs</span> <span class="py_res">import</span> <span class="py_key">PutFile</span><br> <br><span class="py_key">text</span> = []<br> <br><span class="py_res">for</span> <span class="py_key">font</span> <span class="py_res">in</span> <span class="py_key">AllFonts</span>():<br>&nbsp; &nbsp; <span class="py_key">text</span>.<span class="py_key">append</span>(<span class="py_key">str</span>(<span class="py_key">font</span>.<span class="py_key">path</span>))<br>&nbsp; &nbsp; <span class="py_key">text</span>.<span class="py_key">append</span>(<span class="py_key">str</span>(<span class="py_key">font</span>.<span class="py_key">info</span>.<span class="py_key">familyName</span>))<br>&nbsp; &nbsp; <span class="py_key">text</span>.<span class="py_key">append</span>(<span class="py_key">str</span>(<span class="py_key">font</span>.<span class="py_key">info</span>.<span class="py_key">styleName</span>))<br>&nbsp; &nbsp; <span class="py_key">text</span>.<span class="py_key">append</span>(<span class="py_key">str</span>(<span class="py_key">font</span>.<span class="py_key">info</span>.<span class="py_key">fullName</span>))<br>&nbsp; &nbsp; <span class="py_key">text</span>.<span class="py_key">append</span>(<span class="py_key">str</span>(<span class="py_key">font</span>.<span class="py_key">info</span>.<span class="py_key">unitsPerEm</span>))<br>&nbsp; &nbsp; <span class="py_key">text</span>.<span class="py_key">append</span>(<span class="py_key">str</span>(<span class="py_key">font</span>.<span class="py_key">info</span>.<span class="py_key">ascender</span>))<br>&nbsp; &nbsp; <span class="py_key">text</span>.<span class="py_key">append</span>(<span class="py_key">str</span>(<span class="py_key">font</span>.<span class="py_key">info</span>.<span class="py_key">descender</span>))<br>&nbsp; &nbsp; <span class="py_key">text</span>.<span class="py_key">append</span>(<span class="py_str">''</span>)<br> <br><span class="py_key">text</span> = <span class="py_str">'\n'</span>.<span class="py_key">join</span>(<span class="py_key">text</span>)<br><span class="py_key">path</span> = <span class="py_key">PutFile</span>(<span class="py_str">'Save file as:'</span>)<br><span class="py_res">if</span> <span class="py_key">path</span>:<br>&nbsp; &nbsp; <span class="py_key">file</span> = <span class="py_key">open</span>(<span class="py_key">path</span>, <span class="py_str">'w'</span>)<br>&nbsp; &nbsp; <span class="py_key">file</span>.<span class="py_key">write</span>(<span class="py_key">text</span>)<br>&nbsp; &nbsp; <span class="py_key">file</span>.<span class="py_key">close</span>()<span class="py_com"></span></pre></div><div class="pythonsourcetitle"><a href="examples/makeFontInfoReport.py" target="new">download examples/makeFontInfoReport.py</a></div>
<p>
This is a more complex script. It iterates through all open fonts, collects some data in each and finally asks for a place to save all the data in a text file.
</p>
<div class="pythonsource"><pre># robothon 2006<br># batch save as<br> <br><span class="py_res">import</span> <span class="py_key">os</span><br><span class="py_res">from</span> <span class="py_key">robofab</span>.<span class="py_key">world</span> <span class="py_res">import</span> <span class="py_key">AllFonts</span><br><span class="py_res">from</span> <span class="py_key">robofab</span>.<span class="py_key">interface</span>.<span class="py_key">all</span>.<span class="py_key">dialogs</span> <span class="py_res">import</span> <span class="py_key">GetFolder</span><br> <br><span class="py_key">path</span> = <span class="py_key">GetFolder</span>()<br><span class="py_res">if</span> <span class="py_key">path</span>:<br>&nbsp; &nbsp; <span class="py_res">for</span> <span class="py_key">font</span> <span class="py_res">in</span> <span class="py_key">AllFonts</span>():<br>&nbsp; &nbsp; &nbsp; &nbsp; <span class="py_key">fileName</span> = <span class="py_key">os</span>.<span class="py_key">path</span>.<span class="py_key">basename</span>(<span class="py_key">font</span>.<span class="py_key">path</span>)<br>&nbsp; &nbsp; &nbsp; &nbsp; <span class="py_key">newPath</span> = <span class="py_key">os</span>.<span class="py_key">path</span>.<span class="py_key">join</span>(<span class="py_key">path</span>, <span class="py_key">fileName</span>)<br>&nbsp; &nbsp; &nbsp; &nbsp; <span class="py_key">font</span>.<span class="py_key">save</span>(<span class="py_key">newPath</span>)<br> <br></pre></div><div class="pythonsourcetitle"><a href="examples/batchSaveAs.py" target="new">download examples/batchSaveAs.py</a></div>
<p>
This asks for a folder, then proceeds to save all open fonts in this folder.
</p>
<div class="pythonsource"><pre># robothon 2006<br># batch interpolate<br> <br><span class="py_res">import</span> <span class="py_key">os</span><br><span class="py_res">from</span> <span class="py_key">robofab</span>.<span class="py_key">world</span> <span class="py_res">import</span> <span class="py_key">SelectFont</span>, <span class="py_key">NewFont</span><br> <br># ask for two masters to interpolate:<br><span class="py_key">font1</span> = <span class="py_key">SelectFont</span>(<span class="py_str">"Select font 1"</span>)<br><span class="py_key">font2</span> = <span class="py_key">SelectFont</span>(<span class="py_str">"Select font 2"</span>)<br># these are the interpolation factors:<br><span class="py_key">values</span> = [<span class="py_num">.3</span>, <span class="py_num">.6</span>]<br> <br><span class="py_res">for</span> <span class="py_key">value</span> <span class="py_res">in</span> <span class="py_key">values</span>:<br>&nbsp; &nbsp; # make a new font<br>&nbsp; &nbsp; <span class="py_key">destination</span> = <span class="py_key">NewFont</span>()<br>&nbsp; &nbsp; # do the interpolation<br>&nbsp; &nbsp; <span class="py_key">destination</span>.<span class="py_key">interpolate</span>(<span class="py_key">value</span>, <span class="py_key">font1</span>, <span class="py_key">font2</span>, <span class="py_key">doProgress</span>=<span class="py_key">True</span>)<br>&nbsp; &nbsp; <span class="py_key">destination</span>.<span class="py_key">update</span>()<br>&nbsp; &nbsp; # make a new path + filename for the new font to be saved at:<br>&nbsp; &nbsp; <span class="py_key">dir</span> = <span class="py_key">os</span>.<span class="py_key">path</span>.<span class="py_key">dirname</span>(<span class="py_key">font1</span>.<span class="py_key">path</span>)<br>&nbsp; &nbsp; <span class="py_key">fileName</span> = <span class="py_str">"Demo_%d.vfb"</span> % (<span class="py_num">1000</span> * <span class="py_key">value</span>)<br>&nbsp; &nbsp; # save at this path and close the font <br>&nbsp; &nbsp; <span class="py_key">destination</span>.<span class="py_key">save</span>(<span class="py_key">os</span>.<span class="py_key">path</span>.<span class="py_key">join</span>(<span class="py_key">dir</span>, <span class="py_key">fileName</span>))<br>&nbsp; &nbsp; <span class="py_key">destination</span>.<span class="py_key">close</span>()<br> <br><br></pre></div><div class="pythonsourcetitle"><a href="examples/batchInterpolate.py" target="new">download examples/batchInterpolate.py</a></div>
<p>
Here you can pick two fonts from the open fonts. The script will create a new, third font, and make interpolations with the interpolation factors in the <strong>values = [.3, .6]</strong> list. The interpolated font is then saved in the same folder as the first master.
</p>
<p>
This touches on a slippery problem which can cause a lot of confusion. Robofab can only tell FontLab fonts apart from their path attribute, the place where each font is saved. A newly created font has not been saved yet, so it has no path. The effect is that when you have more than one new, unsaved font open, Robofab can't tell them apart (for a couple of reasons) and will continue to work with the first one. It will look like nothing is happening when you run a script. The way around this is to make sure you save each font you created with a script before creating another one. This is safer anyway.
</p>
<p>Here are some useful bits for batch processing fonts which are not open, but in a file. This script is a way to make python collect all files of a particular kind in a folder or folders within that folder. You can use the walker function outside of this script too, it's a useful thing to know.
</p>
<div class="pythonsource"><pre># robothon06<br># ask for a folder<br># find (nested) fontlab files in the folder<br># open the fonts<br># Demonstrates: recursive function,, dialog, os module<br> <br><span class="py_res">import</span> <span class="py_key">os</span>.<span class="py_key">path</span><br><span class="py_res">from</span> <span class="py_key">robofab</span>.<span class="py_key">interface</span>.<span class="py_key">all</span>.<span class="py_key">dialogs</span> <span class="py_res">import</span> <span class="py_key">GetFolder</span><br><span class="py_res">from</span> <span class="py_key">robofab</span>.<span class="py_key">world</span> <span class="py_res">import</span> <span class="py_key">OpenFont</span><br> <br># this function looks for fontlab files in a folder <br><span class="py_res">def</span> <span class="py_def">walk</span>(<span class="py_key">someFolder</span>, <span class="py_key">extension</span>):<br>&nbsp; &nbsp; <span class="py_key">extension</span> = <span class="py_key">extension</span>.<span class="py_key">lower</span>()<br>&nbsp; &nbsp; <span class="py_key">files</span> = []<br>&nbsp; &nbsp; # the os module has tools to deal with<br>&nbsp; &nbsp; # the operating system. This returns a list of names<br>&nbsp; &nbsp; # of stuff in the folder you feed it:<br>&nbsp; &nbsp; <span class="py_key">names</span> = <span class="py_key">os</span>.<span class="py_key">listdir</span>(<span class="py_key">someFolder</span>)<br>&nbsp; &nbsp; <span class="py_res">for</span> <span class="py_key">n</span> <span class="py_res">in</span> <span class="py_key">names</span>:<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="py_key">p</span> = <span class="py_key">os</span>.<span class="py_key">path</span>.<span class="py_key">join</span>(<span class="py_key">someFolder</span>, <span class="py_key">n</span>)<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; # if this new thing is a folder itself,<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; # call this function again, but now with the<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; # new path to check that as well. This is<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; # called recursion.<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="py_res">if</span> <span class="py_key">os</span>.<span class="py_key">path</span>.<span class="py_key">isdir</span>(<span class="py_key">p</span>):<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; # add the results of the other folder<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; # to the list<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="py_key">files</span> += <span class="py_key">walk</span>(<span class="py_key">p</span>, <span class="py_key">extension</span>)<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="py_res">continue</span><br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; # is it a file with the extension we want?<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; # add it then!<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="py_res">if</span> <span class="py_key">n</span>.<span class="py_key">lower</span>().<span class="py_key">find</span>(<span class="py_key">extension</span>) &lt;&gt; -<span class="py_num">1</span>:<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="py_key">files</span>.<span class="py_key">append</span>(<span class="py_key">p</span>)<br>&nbsp; &nbsp; <span class="py_res">return</span> <span class="py_key">files</span><br> <br><br><span class="py_key">yourFolder</span> = <span class="py_key">GetFolder</span>(<span class="py_str">"Search a folder:"</span>)<br><span class="py_res">if</span> <span class="py_key">yourFolder</span> <span class="py_res">is</span> <span class="py_res">not</span> <span class="py_key">None</span>:<br>&nbsp; &nbsp; <span class="py_key">fontPaths</span> = <span class="py_key">walk</span>(<span class="py_key">yourFolder</span>, <span class="py_str">".vfb"</span>)<br>&nbsp; &nbsp; <span class="py_res">for</span> <span class="py_key">path</span> <span class="py_res">in</span> <span class="py_key">fontPaths</span>:<br>&nbsp; &nbsp; &nbsp; &nbsp; <span class="py_key">OpenFont</span>(<span class="py_key">path</span>)<span class="py_com"></span><br>&nbsp; &nbsp; &nbsp; &nbsp; <br></pre></div><div class="pythonsourcetitle"><a href="examples/fileWalker.py" target="new">download examples/fileWalker.py</a></div>
<div class="pythonoutput"><pre>[<span class="py_str">'/Applications/FontLab/Samples/FREESANS.VFB'</span>,<br><span class="py_str">'/Applications/FontLab/Samples/FREESERF.VFB'</span>]</pre></div>
<h2>Moving stuff around</h2>
<p>
The moving, merging and splitting of fonts. The first example moves selected glyphs in the same font and renames them. Note that if you remove the line <strong>f.removeGlyph(g.name)</strong> the same script effectively <strong>copies</strong> the glyphs. Also new in this script: it iterates through the whole font and checks for each glyph if the <strong>g.selected</strong> attribute is 1 or 0. If it is 0, the glyph is not selected in the font window. If it is 1, is <strong>is</strong> selected. It then proceeds to create a new glyph name, and calls <strong>f.insertGlyph()</strong> method which takes a glyph as parameter. The optional parameter <strong>as</strong> is to be able to insert the glyph under a different name. If you don't pass a parameter for <strong>as</strong>, the font will insert the glyph under its own name. The glyph can come from the same font, or a different font, or be an orphan glyph.
</p>
<div class="pythonsource"><pre># rename the selected glyphs<br># in the current font to &lt;glyphname&gt;.sc<br> <br><span class="py_res">from</span> <span class="py_key">robofab</span>.<span class="py_key">world</span> <span class="py_res">import</span> <span class="py_key">CurrentFont</span><br><span class="py_key">f</span> = <span class="py_key">CurrentFont</span>()<br> <br><span class="py_res">for</span> <span class="py_key">g</span> <span class="py_res">in</span> <span class="py_key">f</span>:<br>&nbsp; &nbsp; <span class="py_res">if</span> <span class="py_key">g</span>.<span class="py_key">selected</span> == <span class="py_num">0</span>:<br>&nbsp; &nbsp; &nbsp; &nbsp; <span class="py_res">continue</span><br>&nbsp; &nbsp; <span class="py_key">newName</span> = <span class="py_key">g</span>.<span class="py_key">name</span>+<span class="py_str">".sc"</span><br>&nbsp; &nbsp; <span class="py_res">print</span> <span class="py_str">"moving"</span>, <span class="py_key">g</span>.<span class="py_key">name</span>, <span class="py_str">"to"</span>, <span class="py_key">newName</span><br>&nbsp; &nbsp; <span class="py_key">f</span>.<span class="py_key">insertGlyph</span>(<span class="py_key">g</span>, <span class="py_key">as</span>=<span class="py_key">newName</span>)<br>&nbsp; &nbsp; <span class="py_key">f</span>.<span class="py_key">removeGlyph</span>(<span class="py_key">g</span>.<span class="py_key">name</span>)<br>&nbsp; &nbsp; <span class="py_key">f</span>.<span class="py_key">update</span>()</pre></div>
<div class="pythonoutput"><pre><span class="py_key">moving</span> <span class="py_key">A</span> <span class="py_key">to</span> <span class="py_key">A</span>.<span class="py_key">sc</span><br><span class="py_key">moving</span> <span class="py_key">C</span> <span class="py_key">to</span> <span class="py_key">C</span>.<span class="py_key">sc</span><br><span class="py_key">moving</span> <span class="py_key">B</span> <span class="py_key">to</span> <span class="py_key">B</span>.<span class="py_key">sc</span></pre></div>
<h2>Generating font binaries</h2>
<p>
</p>
<div class="pythonsource"><pre># robothon 2006<br># batch generate<br> <br><span class="py_res">from</span> <span class="py_key">robofab</span>.<span class="py_key">world</span> <span class="py_res">import</span> <span class="py_key">AllFonts</span><br> <br><span class="py_res">for</span> <span class="py_key">font</span> <span class="py_res">in</span> <span class="py_key">AllFonts</span>():<br>&nbsp; &nbsp; <span class="py_key">font</span>.<span class="py_key">generate</span>(<span class="py_str">'otfcff'</span>)<br></pre></div><div class="pythonsourcetitle"><a href="examples/batchGenerate.py" target="new">download examples/batchGenerate.py</a></div>
<p>
This will generate CFF flavored OpenType fonts for all open files.
</p>
<div class="pythonsource"><pre># robothon 2006<br># a more robust batch generator that only has one font open at the time.<br> <br><span class="py_res">from</span> <span class="py_key">robofab</span>.<span class="py_key">interface</span>.<span class="py_key">all</span>.<span class="py_key">dialogs</span> <span class="py_res">import</span> <span class="py_key">GetFolder</span><br><span class="py_res">from</span> <span class="py_key">robofab</span>.<span class="py_key">world</span> <span class="py_res">import</span> <span class="py_key">RFont</span>, <span class="py_key">OpenFont</span><br><span class="py_res">import</span> <span class="py_key">os</span><br> <br><span class="py_res">def</span> <span class="py_def">collectSources</span>(<span class="py_key">root</span>):<br>&nbsp; &nbsp; <span class="py_key">files</span> = []<br>&nbsp; &nbsp; <span class="py_key">ext</span> = [<span class="py_str">'.vfb'</span>]<br>&nbsp; &nbsp; <span class="py_key">names</span> = <span class="py_key">os</span>.<span class="py_key">listdir</span>(<span class="py_key">root</span>)<br>&nbsp; &nbsp; <span class="py_res">for</span> <span class="py_key">n</span> <span class="py_res">in</span> <span class="py_key">names</span>:<br>&nbsp; &nbsp; &nbsp; &nbsp; <span class="py_res">if</span> <span class="py_key">os</span>.<span class="py_key">path</span>.<span class="py_key">splitext</span>(<span class="py_key">n</span>)[<span class="py_num">1</span>] <span class="py_res">in</span> <span class="py_key">ext</span>:<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="py_key">files</span>.<span class="py_key">append</span>(<span class="py_key">os</span>.<span class="py_key">path</span>.<span class="py_key">join</span>(<span class="py_key">root</span>, <span class="py_key">n</span>))<br>&nbsp; &nbsp; <span class="py_res">return</span> <span class="py_key">files</span><br> <br># A little function for making folders. we'll need it later.<br><span class="py_res">def</span> <span class="py_def">makeFolder</span>(<span class="py_key">path</span>):<br>&nbsp; &nbsp; #if the path doesn't exist, make it!<br>&nbsp; &nbsp; <span class="py_res">if</span> <span class="py_res">not</span> <span class="py_key">os</span>.<span class="py_key">path</span>.<span class="py_key">exists</span>(<span class="py_key">path</span>):<br>&nbsp; &nbsp; &nbsp; &nbsp; <span class="py_key">os</span>.<span class="py_key">makedirs</span>(<span class="py_key">path</span>)<br> <br><span class="py_res">def</span> <span class="py_def">makeDestination</span>(<span class="py_key">root</span>):<br>&nbsp; &nbsp; <span class="py_key">macPath</span> = <span class="py_key">os</span>.<span class="py_key">path</span>.<span class="py_key">join</span>(<span class="py_key">root</span>, <span class="py_str">'FabFonts'</span>, <span class="py_str">'ForMac'</span>)<br>&nbsp; &nbsp; <span class="py_key">makeFolder</span>(<span class="py_key">macPath</span>)<br>&nbsp; &nbsp; <span class="py_res">return</span> <span class="py_key">macPath</span><br> <br><span class="py_res">def</span> <span class="py_def">generateOne</span>(<span class="py_key">f</span>, <span class="py_key">dstDir</span>):<br>&nbsp; &nbsp; <span class="py_res">print</span> <span class="py_str">"generating %s"</span>%<span class="py_key">f</span>.<span class="py_key">info</span>.<span class="py_key">fullName</span><br>&nbsp; &nbsp; <span class="py_key">f</span>.<span class="py_key">generate</span>(<span class="py_str">'otfcff'</span>,&nbsp; <span class="py_key">dstDir</span>)<br>&nbsp; &nbsp; <br> <br><span class="py_key">f</span> = <span class="py_key">GetFolder</span>()<br> <br><span class="py_res">if</span> <span class="py_key">f</span> <span class="py_res">is</span> <span class="py_res">not</span> <span class="py_key">None</span>:<br>&nbsp; &nbsp; <span class="py_key">paths</span> = <span class="py_key">collectSources</span>(<span class="py_key">f</span>)<br>&nbsp; &nbsp; <span class="py_key">dstDir</span> = <span class="py_key">makeDestination</span>(<span class="py_key">f</span>)<br> <br>&nbsp; &nbsp; <span class="py_res">for</span> <span class="py_key">f</span> <span class="py_res">in</span> <span class="py_key">paths</span>:<br>&nbsp; &nbsp; &nbsp; &nbsp; <span class="py_key">font</span> = <span class="py_key">None</span><br>&nbsp; &nbsp; &nbsp; &nbsp; <span class="py_res">print</span> <span class="py_key">f</span><br>&nbsp; &nbsp; &nbsp; &nbsp; <span class="py_res">try</span>:<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="py_key">font</span> = <span class="py_key">OpenFont</span>(<span class="py_key">f</span>)<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="py_key">generateOne</span>(<span class="py_key">font</span>, <span class="py_key">dstDir</span>)<br> <br>&nbsp; &nbsp; &nbsp; &nbsp; <span class="py_res">finally</span>:<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="py_res">if</span> <span class="py_key">font</span> <span class="py_res">is</span> <span class="py_res">not</span> <span class="py_key">None</span>:<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="py_key">font</span>.<span class="py_key">close</span>(<span class="py_key">False</span>)<br> <br><br>&nbsp; &nbsp; <span class="py_res">print</span> <span class="py_str">'done'</span><br> <br><br></pre></div><div class="pythonsourcetitle"><a href="examples/robustBatchGenerate.py" target="new">download examples/robustBatchGenerate.py</a></div>
<p>
The script above generates fonts too, but is a bit more robust. FontLab sometimes crashes when it has to generate a long list of fonts and they're all open at the same time. This script asks you for a folder of .vfb sources (which in itself can be a useful ingredient for your own scripts). Then it will open them one by one and generate the fonts in the flavor indicated in the line <strong>f.generate('mactype1', dstDir)</strong>. A list of types and their names can be found in the robofab documentation how-to page on <a href="http://letterror.com/code/robofab/howto/generatefonts.html" class="reference" target="docs">generating fonts.</a> This script also creates a new folder to store the generated fonts in, sorted by type.
</p>
<h2>Merging</h2>
<p>
Here's an script, quite complex, for combining two fonts into one. Maybe not for the newbie, but if you're into it try to figure out how it works. It uses a couple of new concepts, like <strong>Sets</strong> and <strong>DigestPens</strong>. If it is too complicated: don't worry.
</p>
<div class="pythonsource"><pre># robothon 2006<br># merge two fonts<br> <br><span class="py_res">from</span> <span class="py_key">robofab</span>.<span class="py_key">world</span> <span class="py_res">import</span> <span class="py_key">SelectFont</span>, <span class="py_key">NewFont</span><br><span class="py_res">from</span> <span class="py_key">robofab</span>.<span class="py_key">pens</span>.<span class="py_key">digestPen</span> <span class="py_res">import</span> <span class="py_key">DigestPointPen</span><br><span class="py_res">from</span> <span class="py_key">sets</span> <span class="py_res">import</span> <span class="py_key">Set</span><br> <br><span class="py_key">font1</span> = <span class="py_key">SelectFont</span>(<span class="py_str">"Select base font"</span>)<br><span class="py_key">font2</span> = <span class="py_key">SelectFont</span>(<span class="py_str">"Select alternate font"</span>)<br> <br><span class="py_key">font1Names</span> = <span class="py_key">Set</span>(<span class="py_key">font1</span>.<span class="py_key">keys</span>())<br><span class="py_key">font2Names</span> = <span class="py_key">Set</span>(<span class="py_key">font2</span>.<span class="py_key">keys</span>())<br> <br><span class="py_key">commonNames</span> = <span class="py_key">font1Names</span> &amp; <span class="py_key">font2Names</span><br><span class="py_key">uncommonNames</span> = <span class="py_key">font2Names</span> - <span class="py_key">font1Names</span><br> <br><span class="py_res">for</span> <span class="py_key">glyphName</span> <span class="py_res">in</span> <span class="py_key">commonNames</span>:<br>&nbsp; &nbsp; <span class="py_key">glyph1</span> = <span class="py_key">font1</span>[<span class="py_key">glyphName</span>]<br>&nbsp; &nbsp; <span class="py_key">pointPen</span> = <span class="py_key">DigestPointPen</span>()<br>&nbsp; &nbsp; <span class="py_key">glyph1</span>.<span class="py_key">drawPoints</span>(<span class="py_key">pointPen</span>)<br>&nbsp; &nbsp; <span class="py_key">digest1</span> = <span class="py_key">pointPen</span>.<span class="py_key">getDigest</span>()<br>&nbsp; &nbsp; <br>&nbsp; &nbsp; <span class="py_key">glyph2</span> = <span class="py_key">font2</span>[<span class="py_key">glyphName</span>]<br>&nbsp; &nbsp; <span class="py_key">pointPen</span> = <span class="py_key">DigestPointPen</span>()<br>&nbsp; &nbsp; <span class="py_key">glyph2</span>.<span class="py_key">drawPoints</span>(<span class="py_key">pointPen</span>)<br>&nbsp; &nbsp; <span class="py_key">digest2</span> = <span class="py_key">pointPen</span>.<span class="py_key">getDigest</span>()<br>&nbsp; &nbsp; <br>&nbsp; &nbsp; <span class="py_res">if</span> <span class="py_key">digest1</span> != <span class="py_key">digest2</span>:<br>&nbsp; &nbsp; &nbsp; &nbsp; <span class="py_res">print</span> <span class="py_str">'&gt; alt &gt;'</span>, <span class="py_key">glyphName</span><br>&nbsp; &nbsp; &nbsp; &nbsp; <span class="py_key">glyph3</span> = <span class="py_key">font1</span>.<span class="py_key">insertGlyph</span>(<span class="py_key">glyph2</span>, <span class="py_key">as</span>=<span class="py_key">glyphName</span>+<span class="py_str">'.alt'</span>)<br>&nbsp; &nbsp; &nbsp; &nbsp; <span class="py_key">glyph3</span>.<span class="py_key">mark</span> = <span class="py_num">1</span><br>&nbsp; &nbsp; &nbsp; &nbsp; <span class="py_key">glyph3</span>.<span class="py_key">update</span>()<br> <br><span class="py_res">for</span> <span class="py_key">glyphName</span> <span class="py_res">in</span> <span class="py_key">uncommonNames</span>:<br>&nbsp; &nbsp; <span class="py_res">print</span> <span class="py_str">'&gt;'</span>, <span class="py_key">glyphName</span><br>&nbsp; &nbsp; <span class="py_key">glyph</span> = <span class="py_key">font1</span>.<span class="py_key">insertGlyph</span>(<span class="py_key">font2</span>[<span class="py_key">glyphName</span>])<br>&nbsp; &nbsp; <span class="py_key">glyph</span>.<span class="py_key">mark</span> = <span class="py_num">60</span><br>&nbsp; &nbsp; <span class="py_key">glyph</span>.<span class="py_key">update</span>()<br>&nbsp; &nbsp; <br><span class="py_key">font1</span>.<span class="py_key">update</span>()<br></pre></div><div class="pythonsourcetitle"><a href="examples/mergeTwoFonts.py" target="new">download examples/mergeTwoFonts.py</a></div>
<p>
</p>
<h2>Dealing with Robofab limitations</h2>
<p>
A handful of FontLab's own glyph and font methods are not supported in RoboFab. The reasons for this vary, some of them are very FontLab specific (for instance <strong>fl.productnumber</strong> or <strong>fl.username</strong>), but most of the missing stuff was just not needed very often — the following examples show how to get access to all functionality and attributes in the FontLab layer.
</p>
<h3>FontLab layer</h3>
<p>
To get to the FontLab layer, Robofab's Font and Glyph objects have a <strong>naked()</strong> method which returns the FontLab object. Note that you can still use the Robofab functionality like CurrentFont, CurrentGlyph, pens etc. The FontLab layer <a href="http://dev.fontlab.net/flpydoc/view_html.html" class="reference" target="new">is documented here.</a> Maybe you remember the <strong>naked()</strong> method from the cookie cutter example.
</p>
<div class="pythonsource"><pre># show the objects from the fontlab layer<br><span class="py_res">from</span> <span class="py_key">robofab</span>.<span class="py_key">world</span> <span class="py_res">import</span> <span class="py_key">CurrentFont</span><br><span class="py_key">f</span> = <span class="py_key">CurrentFont</span>()<br><span class="py_res">print</span> <span class="py_key">f</span>.<span class="py_key">naked</span>()<br> <br><span class="py_key">g</span> =&nbsp; <span class="py_key">f</span>[<span class="py_str">"A"</span>]<br><span class="py_res">print</span> <span class="py_key">g</span>.<span class="py_key">naked</span>()</pre></div>
<div class="pythonoutput"><pre>&lt;<span class="py_key">Font</span>: <span class="py_str">'MyFont'</span>&gt;<br>&lt;<span class="py_key">Glyph</span>: <span class="py_str">'A'</span>, <span class="py_num">0</span> <span class="py_key">nodes</span>, <span class="py_key">parent</span>: <span class="py_str">'MyFont'</span>&gt;</pre></div>
<p>
Other things you need to dig deeper for. Note that some of these objects appear to be broken.
<ul>
<li>
<strong>PostScript hints</strong>: the vertical and horizontal hint zones as well as blue values can be read and set.
<div class="pythonsource"><pre># show vhints for current glyph<br><span class="py_key">g</span> = <span class="py_key">CurrentGlyph</span>()<br><span class="py_key">g</span>.<span class="py_key">naked</span>().<span class="py_key">vhints</span></pre></div>
<div class="pythonoutput"><pre>[&lt;<span class="py_key">VHint</span>: <span class="py_key">p</span>=<span class="py_num">25</span>, <span class="py_key">w</span>=<span class="py_num">163</span>, <span class="py_key">parent</span>: <span class="py_str">"a"</span>&gt;,&lt;<span class="py_key">VHint</span>: <span class="py_key">p</span>=<span class="py_num">42</span>, <span class="py_key">w</span>=<span class="py_num">146</span>, <span class="py_key">parent</span>: <span class="py_str">"a"</span>&gt;]</pre></div>
</li>
<li>
<strong>All name fields</strong>: the FontLab table of OpenType names, the naming record, is available. See also the <a href="http://dev.fontlab.net/flpydoc/html/NameRecord.xml.html" class="reference" target="new">the FontLab reference for NameRecord</a>
<div class="pythonsource"><pre># robothon06<br># show OpenType naming records<br># in the fontlab API<br><span class="py_res">from</span> <span class="py_key">robofab</span>.<span class="py_key">world</span> <span class="py_res">import</span> <span class="py_key">CurrentFont</span><br><span class="py_key">f</span> = <span class="py_key">CurrentFont</span>()<br><span class="py_key">fn</span> = <span class="py_key">f</span>.<span class="py_key">naked</span>()<br><span class="py_res">for</span> <span class="py_key">r</span> <span class="py_res">in</span> <span class="py_key">fn</span>.<span class="py_key">fontnames</span>:<br>&nbsp; &nbsp; <span class="py_res">print</span> <span class="py_key">r</span>.<span class="py_key">nid</span>, <span class="py_key">r</span>.<span class="py_key">pid</span>, <span class="py_key">r</span>.<span class="py_key">eid</span>, <span class="py_key">r</span>.<span class="py_key">lid</span>, <span class="py_key">r</span>.<span class="py_key">name</span><span class="py_com"></span></pre></div><div class="pythonsourcetitle"><a href="examples/showNamingRecords.py" target="new">download examples/showNamingRecords.py</a></div>
<div class="pythonoutput"><pre><span class="py_num">256</span> <span class="py_num">1</span> <span class="py_num">0</span> <span class="py_num">0</span> <span class="py_key">Bold</span><br><span class="py_num">256</span> <span class="py_num">3</span> <span class="py_num">1</span> <span class="py_num">1033</span> <span class="py_key">Bold</span></pre></div>
</li>
<li>
<strong>Encodings</strong>.The FontLab Encoding object. See also the
<a href="http://dev.fontlab.net/flpydoc/html/Encoding.xml.html" class="reference" target="new">the FontLab reference for Encoding</a>
<div class="pythonsource"><pre># robothon06<br># show encoding <br><span class="py_res">from</span> <span class="py_key">robofab</span>.<span class="py_key">world</span> <span class="py_res">import</span> <span class="py_key">CurrentFont</span><br><span class="py_key">f</span> = <span class="py_key">CurrentFont</span>()<br><span class="py_key">fn</span> = <span class="py_key">f</span>.<span class="py_key">naked</span>()<br> <br># object containing encoding records<br># you can iterate through it by using<br># an index.<br><span class="py_res">print</span> <span class="py_key">fn</span>.<span class="py_key">encoding</span><br><span class="py_res">for</span> <span class="py_key">i</span> <span class="py_res">in</span> <span class="py_key">range</span>(<span class="py_key">len</span>(<span class="py_key">fn</span>.<span class="py_key">encoding</span>)):<br>&nbsp; &nbsp; <span class="py_key">er</span> = <span class="py_key">fn</span>.<span class="py_key">encoding</span>[<span class="py_key">i</span>]<br>&nbsp; &nbsp; <span class="py_res">print</span> <span class="py_key">er</span>, <span class="py_key">er</span>.<span class="py_key">name</span>, <span class="py_key">er</span>.<span class="py_key">unicode</span><br><span class="py_com"></span></pre></div><div class="pythonsourcetitle"><a href="examples/showEncoding.py" target="new">download examples/showEncoding.py</a></div>
<div class="pythonoutput"><pre>&lt;<span class="py_key">Encoding</span>: <span class="py_key">parent</span>: <span class="py_str">"MyDemoRegular"</span>&gt;<br>...<br>&lt;<span class="py_key">EncodingRecord</span>: <span class="py_str">"eacute"</span>, <span class="py_key">unicode</span>: <span class="py_num">233</span>&gt; <span class="py_key">eacute</span> <span class="py_num">233</span><br>&lt;<span class="py_key">EncodingRecord</span>: <span class="py_str">"ecircumflex"</span>, <span class="py_key">unicode</span>: <span class="py_num">234</span>&gt; <span class="py_key">ecircumflex</span> <span class="py_num">234</span><br>&lt;<span class="py_key">EncodingRecord</span>: <span class="py_str">"edieresis"</span>, <span class="py_key">unicode</span>: <span class="py_num">235</span>&gt; <span class="py_key">edieresis</span> <span class="py_num">235</span><br>&lt;<span class="py_key">EncodingRecord</span>: <span class="py_str">"igrave"</span>, <span class="py_key">unicode</span>: <span class="py_num">236</span>&gt; <span class="py_key">igrave</span> <span class="py_num">236</span><br>&lt;<span class="py_key">EncodingRecord</span>: <span class="py_str">"iacute"</span>, <span class="py_key">unicode</span>: <span class="py_num">237</span>&gt; <span class="py_key">iacute</span> <span class="py_num">237</span><br>&lt;<span class="py_key">EncodingRecord</span>: <span class="py_str">"icircumflex"</span>, <span class="py_key">unicode</span>: <span class="py_num">238</span>&gt; <span class="py_key">icircumflex</span> <span class="py_num">238</span><br>..<span class="py_key">etc</span>..</pre></div>
</li>
</ul>
</p>
</div>
</body></html>