Dave Jarvis' Repositories

git clone https://repo.autonoma.ca/repo/recipe-books.git
example-book.xml
<recipe-book>
<book>
- <title>Book Name</title>
- <author>Dave Jarvis</author>
+ <title>Tasty Tongue Twizzlers</title>
+ <author/>
<isbn/>
- <created format="YYYY-MM-DD">2013-02-08</created>
- <photo>
- <uri/>
+ <created format="YYYY-MM-DD">2013-02-02</created>
+ <photo use="front-cover">
+ <uri>http://i.imgur.com/p71y6mq.jpg</uri>
</photo>
</book>
- <ingredients>
- <ingredient name="avocado" id="701">
- <categories>
- <category name="fruit" id="11"/>
- </categories>
- </ingredient>
- <ingredient name="bread flour" id="1361">
- <categories>
- <category name="bread" id="2"/>
- <category name="seed,grain,wheat,flour" id="71"/>
- </categories>
- </ingredient>
- <ingredient name="carrot" id="117">
- <categories>
- <category name="vegetable" id="23"/>
- </categories>
- </ingredient>
- <ingredient name="chianti mushroom" id="4165">
- <categories>
- <category name="vegetable,fungi,mushroom" id="52"/>
- </categories>
- </ingredient>
- <ingredient name="chili oil" id="4166">
- <categories>
- <category name="oil" id="15"/>
- </categories>
- </ingredient>
- <ingredient name="cold water" id="3168">
- <categories>
- <category name="water" id="79"/>
- </categories>
- </ingredient>
- <ingredient name="dried shiitake mushroom" id="2071">
- <categories>
- <category name="vegetable,fungi,mushroom" id="52"/>
- </categories>
- </ingredient>
- <ingredient name="garlic clove" id="1405"/>
- <ingredient name="ginger" id="247">
- <categories>
- <category name="spice" id="19"/>
- </categories>
- </ingredient>
- <ingredient name="grapefruit" id="786">
- <categories>
- <category name="fruit,citrus" id="6"/>
- </categories>
- </ingredient>
- <ingredient name="lime juice" id="353">
- <categories>
- <category name="fruit,citrus" id="6"/>
- </categories>
- </ingredient>
- <ingredient name="olive oil" id="424">
- <categories>
- <category name="oil" id="15"/>
- </categories>
- </ingredient>
- <ingredient name="onion" id="425"/>
- <ingredient name="ramen noodle" id="4163"/>
- <ingredient name="red miso" id="2829">
- <categories>
- <category name="vegetable,legume" id="38"/>
- </categories>
- </ingredient>
- <ingredient name="sesame oil" id="1307">
- <categories>
- <category name="oil" id="15"/>
- </categories>
- </ingredient>
- <ingredient name="sesame seed" id="1308">
- <categories>
- <category name="seed" id="18"/>
- </categories>
- </ingredient>
- <ingredient name="sugar" id="549"/>
- <ingredient name="tomato" id="579">
- <categories>
- <category name="fruit" id="11"/>
- </categories>
- </ingredient>
- <ingredient name="water" id="1481">
- <categories>
- <category name="water" id="79"/>
- </categories>
- </ingredient>
- <ingredient name="white miso" id="2874">
- <categories>
- <category name="vegetable,legume" id="38"/>
- </categories>
- </ingredient>
- <ingredient name="white onion" id="1485"/>
- <ingredient name="yeast" id="1349">
- <categories>
- <category name="vegetable,fungi,yeast" id="45"/>
- </categories>
- </ingredient>
- </ingredients>
<recipe>
<description>
- <title>Pizza Dough</title>
+ <title>Thai-Style Roast Duck</title>
<photo use="recipe-inset">
- <uri>http://static.flickr.com/3005/2950536388_c7795e9af9_b.jpg</uri>
+ <uri>http://www.templeofthai.com/images/recipes/duck-curry-1000x665-Pangfolio-shutterstock.jpg</uri>
</photo>
</description>
<preparation/>
<equipment>
- <bakeware>
- <object id="2">bowl</object>
- </bakeware>
- <cookware/>
+ <bakeware/>
+ <cookware>
+ <object id="1">wok</object>
+ </cookware>
<kitchenware/>
- <electric>
- <object id="1">mixer</object>
- </electric>
+ <electric/>
<miscellaneous/>
<utensils/>
</equipment>
<ingredients id="1" label="ingredients">
- <ingredient id="1361" seq="1" min-quantity="6.5" unit="cup" condition="" optional="false"/>
- <ingredient id="1349" seq="2" min-quantity="2" unit="teaspoon" condition="" optional="false"/>
- <ingredient id="3168" seq="3" min-quantity="3.25" unit="cup" condition="" optional="false"/>
- <ingredient id="424" seq="4" min-quantity="6" unit="tablespoon" condition="" optional="false"/>
- <ingredient id="549" seq="5" min-quantity="2" max-quantity="3" unit="teaspoon" condition="salt" optional="false"/>
+ <ingredient id="1" min-quantity="1" condition="" optional="false">duck</ingredient>
+ <ingredient id="2" min-quantity="900" max-quantity="900" unit="millilitre" condition="" optional="false">coconut milk</ingredient>
+ <ingredient id="3" min-quantity="4" unit="tablespoon" condition="" optional="false">curry paste</ingredient>
+ <ingredient id="4" min-quantity="5" unit="tablespoon" condition="" optional="false">fish sauce</ingredient>
</ingredients>
<directions/>
<directions label="instructions">
- <step action="mix" min-time="1" seq="1">yeast, sugar and salt together with a cup of water</step>
- <step action="put" min-time="1" seq="2">5 cups of flour in mixer</step>
- <step action="add" min-time="1" seq="3">yeast mixture, olive oil and water</step>
- <step action="start" min-time="1" seq="4">mixing</step>
- <step action="add" min-time="1" seq="5">remaining flour until you get a moist ball of dough</step>
- <step action="do" min-time="1" seq="6">not put to much flour in because the dough will get too dry</step>
- <step action="knead" min-time="1" seq="7">dough for around 10 minutes</step>
- <step action="leave" min-time="1" seq="8">it in the mixer and let the dough hook do the trick</step>
- <step action="cut" min-time="1" seq="9">the dough ball into 8 individual balls</step>
- <step action="coat" min-time="1" seq="10">each ball with more olive oil, put them in a bowl and let them rise over night in the fridge</step>
- <step action="take" min-time="1" seq="11">them out of the fridge an hour prior to cooking</step>
- <step action="take" min-time="1" seq="12">3 or 4 minutes to cook depending on toppings</step>
+ <step action="boil" min-time="1" seq="1">some water in a wok</step>
+ <step action="blanch" min-time="1" seq="2">duck for 10 minutes to remove odour</step>
+ <step action="remove" min-time="1" seq="3">and rinse well</step>
+ <step action="boil" min-time="1" seq="4">coconut milk and green curry paste in a clean wok</step>
+ <step action="lower" min-time="1" seq="5">heat and simmer contents for 10 minutes before adding in fish sauce and duck pieces</step>
+ <step action="simmer" min-time="1" seq="6">duck for 45 minutes to an hour</step>
+ <step action="simmer" min-time="1" seq="7">process</step>
+ <step action="chill" min-time="1" seq="8">separately overnight</step>
+ <step action="thaw" min-time="1" seq="9">duck pieces and grill till golden</step>
+ <step action="serve" min-time="1" seq="10">with warmed stock</step>
</directions>
<tags>
- <tag category="type" sequence="6">pizza</tag>
+ <tag category="cuisine" sequence="10">thai</tag>
+ <tag category="ingredient" sequence="2">duck</tag>
</tags>
</recipe>
<recipe>
<description>
- <title>Ramen With Shiitake Mushroom Base</title>
+ <title>Orange Juice Chicken</title>
<photo use="recipe-inset">
- <uri>http://static.flickr.com/7110/6878257218_19a31691df_h.jpg</uri>
+ <uri>http://3.bp.blogspot.com/-CBO-ehbIwbc/T5oslwe_gFI/AAAAAAAACTw/LoC-NP1e5fw/s1600/orange+chicken+and+peach+cobbler+120.JPG</uri>
</photo>
</description>
- <preparation/>
+ <preparation>
+ <oven unit="F" temperature="375"/>
+ </preparation>
<equipment>
<bakeware/>
<cookware>
- <object id="1">pot</object>
+ <object id="1">saucepan</object>
</cookware>
<kitchenware/>
<electric/>
<miscellaneous/>
<utensils/>
</equipment>
- <ingredients id="1" label="vegetables">
- <ingredient id="1485" seq="1" min-quantity="1" condition="" optional="false"/>
- <ingredient id="4165" seq="2" min-quantity="5" condition="" optional="false"/>
- <ingredient id="1405" seq="3" min-quantity="1" condition="" optional="false"/>
- <ingredient id="1481" seq="4" min-quantity="1" unit="cup" condition="" optional="false"/>
- <ingredient id="117" seq="5" min-quantity="1" condition="" optional="false"/>
- <ingredient id="2071" seq="6" min-quantity="2" condition="" optional="false"/>
- <ingredient id="1308" seq="7" min-quantity="1" unit="teaspoon" condition="" optional="false"/>
- <ingredient id="1307" seq="8" min-quantity="1" unit="tablespoon" condition="" optional="false"/>
- <ingredient id="4166" seq="9" min-quantity="1" unit="tablespoon" condition="" optional="false"/>
- <ingredient id="247" seq="10" min-quantity="1" unit="tablespoon" condition="" optional="false"/>
- </ingredients>
- <ingredients id="2" label="broth">
- <ingredient id="2829" seq="11" min-quantity="1" unit="tablespoon" condition="" optional="false"/>
- <ingredient id="2874" seq="12" min-quantity="1" unit="tablespoon" condition="" optional="false"/>
- <ingredient id="3168" seq="13" min-quantity="9" unit="cup" condition="" optional="false"/>
- <ingredient id="4163" seq="14" min-quantity="1" unit="package" condition="" optional="false"/>
+ <ingredients id="1" label="ingredients">
+ <ingredient id="1" min-quantity="4" condition="" optional="false">boneless chicken breast</ingredient>
+ <ingredient id="2" min-quantity="1" condition="" optional="false">half-and-half</ingredient>
+ <ingredient id="3" min-quantity="2" unit="tablespoon" condition="prepare" optional="false">dijon mustard</ingredient>
+ <ingredient id="4" min-quantity="1" condition="" optional="false">mustard</ingredient>
+ <ingredient id="5" min-quantity="0.5" unit="cup" condition="chop" optional="false">onion</ingredient>
+ <ingredient id="6" min-quantity="0.5" unit="cup" condition="pack,divide" optional="false">brown sugar</ingredient>
+ <ingredient id="7" min-quantity="2" unit="cup" condition="" optional="false">orange juice</ingredient>
+ <ingredient id="8" min-quantity="2" unit="tablespoon" condition="" optional="false">butter</ingredient>
+ <ingredient id="9" min-quantity="2" unit="tablespoon" condition="" optional="false">all-purpose flour</ingredient>
</ingredients>
<directions/>
- <directions label="vegetables">
- <step action="add" min-time="1" seq="1">onion, chianti mushrooms, and garlic to a pot of water</step>
- <step action="add" min-time="1" seq="2">salt and pepper to taste</step>
- <step action="cover" min-time="1" seq="3">and cook on medium heat for two minutes</step>
- <step action="add" min-time="1" seq="4">carrots, dried shiitake mushrooms, sesame seeds, sesame oil, and chili oil</step>
- <step action="cook" min-time="1" seq="5">for 10 minutes</step>
- <step action="combine" min-time="1" seq="6">ginger and both miso, then add them to the mix</step>
- <step action="cook" min-time="1" seq="7">for one to two minutes</step>
- <step action="pour" min-time="1" seq="8">9 cups of cold water</step>
- <step action="bring" min-time="1" seq="9">to a boil</step>
- <step action="let" min-time="1" seq="10">simmer for two hours</step>
- </directions>
- <directions label="noodles">
- <step action="drain" min-time="1" seq="11">the vegetables and press to make a broth</step>
- <step action="boil" min-time="1" seq="12">broth with noodles and add toppings</step>
+ <directions label="instructions">
+ <step action="place" min-time="1" seq="1">chicken in a 9 x13 inch baking dish</step>
+ <step action="spread" min-time="1" seq="2">mustard evenly over the chicken and sprinkle with chopped onion</step>
+ <step action="coat" min-time="1" seq="3">lightly with 1/4 cup of the brown sugar and pour in enough orange juice to cover chicken</step>
+ <step action="add" min-time="1" seq="4">butter on top</step>
+ <step action="sprinkle" min-time="1" seq="5">chicken with remaining 1/4 cup brown sugar and return to oven</step>
+ <step action="whisk" min-time="1" seq="6">flour into sauce in saucepan</step>
+ <step action="add" min-time="1" seq="7">any leftover orange juice and heat on high until the sauce thickens</step>
+ <step action="remove" min-time="1" seq="8">chicken from oven and place on a serving dish; pour sauce over the chicken or into a gravy boat, and</step>
</directions>
<tags>
- <tag category="type" sequence="6">soup</tag>
+ <tag category="ingredient" sequence="2">chicken</tag>
+ <tag category="type" sequence="6">fruit</tag>
</tags>
</recipe>
<recipe>
<description>
- <title>Candied Grapefruit Peel</title>
+ <title>Pizza Dough</title>
<photo use="recipe-inset">
- <uri>http://static.flickr.com/2399/2231161820_cee7e9d100_b.jpg</uri>
+ <uri>http://warmvanillasugar.files.wordpress.com/2010/10/pizza_dough_main.jpg</uri>
</photo>
</description>
<preparation/>
<equipment>
<bakeware>
<object id="2">bowl</object>
</bakeware>
- <cookware>
- <object id="1">pot</object>
- </cookware>
+ <cookware/>
<kitchenware/>
- <electric/>
+ <electric>
+ <object id="1">mixer</object>
+ </electric>
<miscellaneous/>
<utensils/>
</equipment>
<ingredients id="1" label="ingredients">
- <ingredient id="549" seq="1" min-quantity="2" unit="cup" condition="" optional="false"/>
- <ingredient id="1481" seq="2" min-quantity="2" unit="cup" condition="" optional="false"/>
- <ingredient id="786" seq="3" min-quantity="10" condition="peel,quarter" optional="false"/>
+ <ingredient id="1" min-quantity="6.5" unit="cup" condition="" optional="false">bread flour</ingredient>
+ <ingredient id="2" min-quantity="2" unit="teaspoon" condition="" optional="false">yeast</ingredient>
+ <ingredient id="3" min-quantity="3.25" unit="cup" condition="" optional="false">cold water</ingredient>
+ <ingredient id="4" min-quantity="6" unit="tablespoon" condition="" optional="false">olive oil</ingredient>
+ <ingredient id="5" min-quantity="2" max-quantity="3" unit="teaspoon" condition="salt" optional="false">sugar</ingredient>
</ingredients>
<directions/>
<directions label="instructions">
- <step action="cut" min-time="1" seq="1">the fruit away from the peel</step>
- <step action="peel" min-time="1" seq="2">into slivers, approximately a centimeter wide</step>
- <step action="put" min-time="1" seq="3">sliced peels in cooking pot</step>
- <step action="add" min-time="1" seq="4">sugar and enough water to cover the peels</step>
- <step action="boil" min-time="1" seq="5">for a few hours until peels are translucent</step>
- <step action="cool" min-time="1" seq="6">in pot</step>
- <step action="roll" min-time="1" seq="7">in a bowl of granulated sugar when cool enough to handle yet still tacky</step>
- <step action="serve" min-time="1" seq="8">on fresh waxed paper</step>
+ <step action="mix" min-time="1" seq="1">yeast, sugar and salt together with a cup of water</step>
+ <step action="put" min-time="1" seq="2">5 cups of flour in mixer</step>
+ <step action="add" min-time="1" seq="3">yeast mixture, olive oil and water</step>
+ <step action="start" min-time="1" seq="4">mixing</step>
+ <step action="add" min-time="1" seq="5">remaining flour until you get a moist ball of dough</step>
+ <step action="do" min-time="1" seq="6">not put to much flour in because the dough will get too dry</step>
+ <step action="knead" min-time="1" seq="7">dough for around 10 minutes</step>
+ <step action="leave" min-time="1" seq="8">it in the mixer and let the dough hook do the trick</step>
+ <step action="cut" min-time="1" seq="9">the dough ball into 8 individual balls</step>
+ <step action="coat" min-time="1" seq="10">each ball with more olive oil, put them in a bowl and let them rise over night in the fridge</step>
+ <step action="take" min-time="1" seq="11">them out of the fridge an hour prior to cooking</step>
+ <step action="take" min-time="1" seq="12">3 or 4 minutes to cook depending on toppings</step>
</directions>
<tags>
- <tag category="type" sequence="6">candy</tag>
+ <tag category="type" sequence="6">pizza</tag>
</tags>
</recipe>
<recipe>
<description>
- <title>Basic Guacamole</title>
- <photo use="recipe-inset">
- <uri>http://static.flickr.com/2794/4135509624_df3329d4fb_z.jpg?zz=1</uri>
- </photo>
+ <title>Empty Recipe</title>
</description>
<preparation/>
<equipment>
<bakeware/>
<cookware/>
<kitchenware/>
+ <electric/>
+ <miscellaneous/>
+ <utensils/>
+ </equipment>
+ <ingredients id="1" label="ingredients"/>
+ <directions/>
+ <directions label="instructions"/>
+ <tags></tags>
+ </recipe>
+ <recipe>
+ <description>
+ <title>Breaded Chicken</title>
+ </description>
+ <preparation>
+ <oven unit="F" temperature="375"/>
+ </preparation>
+ <equipment>
+ <bakeware/>
+ <cookware/>
+ <kitchenware>
+ <object id="1">plate</object>
+ </kitchenware>
<electric/>
<miscellaneous/>
<utensils/>
</equipment>
<ingredients id="1" label="ingredients">
- <ingredient id="701" seq="1" min-quantity="3" max-quantity="4" condition="" optional="false"/>
- <ingredient id="425" seq="2" min-quantity="1" condition="dice" optional="false"/>
- <ingredient id="1405" seq="3" min-quantity="1" condition="mince" optional="false"/>
- <ingredient id="579" seq="4" min-quantity="1" condition="chop" optional="false"/>
- <ingredient id="353" seq="5" min-quantity="1" unit="teaspoon" condition="" optional="false"/>
+ <ingredient id="1" min-quantity="1" unit="teaspoon" condition="breaded" optional="false">chicken</ingredient>
+ <ingredient id="2" min-quantity="2" condition="" optional="false">chicken breast</ingredient>
+ <ingredient id="3" min-quantity="2" condition="" optional="false">egg</ingredient>
+ <ingredient id="4" min-quantity="1" unit="cup" condition="season" optional="false">bread crumb</ingredient>
+ <ingredient id="5" min-quantity="1" unit="tablespoon" condition="" optional="false">canola oil</ingredient>
</ingredients>
<directions/>
<directions label="instructions">
- <step action="add" min-time="1" seq="1">salt and pepper to taste</step>
- <step action="combine" min-time="1" seq="2">and mash</step>
+ <step action="broil" min-time="1" seq="1">the minuscule chicken</step>
+ <step action="grease" min-time="1" seq="2">a flat baking sheet with canola oil</step>
+ <step action="set" min-time="1" seq="3">out three shallow pie dishes or deep plates: one with flour, one with beaten egg, one with seasoned</step>
+ <step action="thin" min-time="1" seq="4">by either slicing them in half or pounding them flatter</step>
+ <step action="dip" min-time="1" seq="5">the chicken first into flour, shaking off any excess</step>
+ <step action="dip" min-time="1" seq="6">it into the egg, shaking off any excess</step>
+ <step action="dip" min-time="1" seq="7">it into the seasoned bread crumbs</step>
+ <step action="lay" min-time="1" seq="8">the breaded chicken on the greased baking sheet</step>
+ <step action="sprinkle" min-time="1" seq="9">some drops of canola oil over each chicken piece</step>
+ <step action="bake" min-time="1" seq="10">for 6 to 8 minutes on each side, or until the chicken is white in the middle</step>
+ <step action="bake" min-time="1" seq="11">time depends on the thickness of the chicken</step>
</directions>
<tags>
- <tag category="type" sequence="6">condiment</tag>
+ <tag category="type" sequence="6">bread</tag>
+ <tag category="ingredient" sequence="2">chicken</tag>
+ <tag category="type" sequence="6">soup</tag>
</tags>
</recipe>
xsl/latex.xsl
<xsl:for-each select="key('preg',@id)/categories/category">
<xsl:text>\index[catingred]{</xsl:text>
- <xsl:apply-templates select="@name" />
+ <xsl:call-template name="split">
+ <xsl:with-param name="pText" select="@name" />
+ <xsl:with-param name="pToken" select="','" />
+ <xsl:with-param name="pSubst" select="' \to '" />
+ </xsl:call-template>
<xsl:text>!</xsl:text>
<xsl:apply-templates select="../../@name" />
<xsl:text>}&#xa;</xsl:text>
</xsl:for-each>
</xsl:if>
<xsl:text>\index[flatingred]{</xsl:text>
<xsl:apply-templates select="key('preg', @id)/@name" />
<xsl:text>}&#xa;</xsl:text>
+</xsl:template>
+
+<!--
+ | Splits a delimited string by substitution text.
+ +-->
+<xsl:template name="split">
+ <xsl:param name="pText"/>
+ <xsl:param name="pToken"/>
+ <xsl:param name="pSubst" />
+
+ <xsl:choose>
+ <!-- End of recursion. -->
+ <xsl:when test="string-length($pText) = 0" />
+
+ <!-- While there are more tokens... -->
+ <xsl:when test="contains($pText, $pToken)">
+ <xsl:value-of select="substring-before($pText, $pToken)"/>
+ <xsl:value-of select="$pSubst"/>
+
+ <xsl:call-template name="split">
+ <xsl:with-param name="pText" select="substring-after($pText, $pToken)"/>
+ <xsl:with-param name="pToken" select="$pToken"/>
+ <xsl:with-param name="pSubst" select="$pSubst" />
+ </xsl:call-template>
+ </xsl:when>
+ <xsl:otherwise>
+ <!-- The text had no tokens, so display it without parsing. -->
+ <xsl:value-of select="$pText"/>
+ </xsl:otherwise>
+ </xsl:choose>
</xsl:template>
+
+<!--
+ | Splits a space-delimited string, wrapping values in an "id" element.
+ +-->
+<xsl:template name="output-tokens">
+ <xsl:param name="list" />
+ <xsl:variable name="newlist" select="concat(normalize-space($list), ' ')" />
+ <xsl:variable name="first" select="substring-before($newlist, ' ')" />
+ <xsl:variable name="remaining" select="substring-after($newlist, ' ')" />
+ <id>
+ <xsl:value-of select="$first" />
+ </id>
+ <xsl:if test="$remaining">
+ <xsl:call-template name="output-tokens">
+ <xsl:with-param name="list" select="$remaining" />
+ </xsl:call-template>
+ </xsl:if>
+</xsl:template>
<xsl:template match="directions[1]">

Converted comma-separted index items to use an arrow separator. Nesting goes more levels than is supported by makeindex.

Author Dave Jarvis <email>
Date 2013-02-17 23:52:40 GMT-0800
Commit dcd9e9703d561b27e8f444d13425b5d8bc0441eb
Parent 659f29a
Delta 174 lines added, 198 lines removed, 24-line decrease