[gimp-web/gimp-web-static] Porting more tutorials over



commit 828c515a26c44145b9744f1a21865ce2660619da
Author: Pat David <patdavid gmail com>
Date:   Tue Aug 18 14:34:46 2015 -0500

    Porting more tutorials over

 content/about/meta/file-list.md                    |    6 +-
 .../tutorials/Automate_Editing_in_GIMP/index.md    |  429 ++++++++++----------
 .../AutomatedJpgToXcf/example-jpeg-to-xcf.py       |   81 ++++
 .../AutomatedJpgToXcf/gimp_jpg_to_xcf_popup.jpg    |  Bin 0 -> 50118 bytes
 .../AutomatedJpgToXcf/gimp_menu_compare.jpg        |  Bin 0 -> 62086 bytes
 content/tutorials/AutomatedJpgToXcf/index.md       |  355 ++++++++++++++++
 .../script-fu-example-jpg-to-xcf.scm               |  150 +++++++
 content/tutorials/Basic_Batch/index.md             |   89 ++++
 .../Color_circle_%28hue-sat%29_trans.png           |  Bin 0 -> 148446 bytes
 .../Basic_Color_Curves/Kuler_orange_teal.jpg       |  Bin 0 -> 29784 bytes
 .../curves-dialog-darks-blue-boost-add-yellow.png  |  Bin 0 -> 31004 bytes
 .../curves-dialog-darks-blue-boost.png             |  Bin 0 -> 29815 bytes
 .../curves-dialog-darks-green-suppress.png         |  Bin 0 -> 30038 bytes
 .../curves-dialog-darksmidslights.png              |  Bin 0 -> 31089 bytes
 .../Basic_Color_Curves/curves-dialog-midtones.png  |  Bin 0 -> 29816 bytes
 .../curves-dialog-orangeteal-blue-high.png         |  Bin 0 -> 34230 bytes
 .../curves-dialog-orangeteal-blue-low.png          |  Bin 0 -> 35156 bytes
 .../curves-dialog-orangeteal-green-high.png        |  Bin 0 -> 32365 bytes
 .../curves-dialog-orangeteal-green-low.png         |  Bin 0 -> 36855 bytes
 .../curves-dialog-orangeteal-red-high.png          |  Bin 0 -> 30489 bytes
 .../curves-dialog-orangeteal-red-low.png           |  Bin 0 -> 36328 bytes
 .../curves-dialog-orangeteal-value-final.png       |  Bin 0 -> 37347 bytes
 .../curves-dialog-original-IO.png                  |  Bin 0 -> 30122 bytes
 .../Basic_Color_Curves/curves-dialog-original.png  |  Bin 0 -> 26106 bytes
 .../Basic_Color_Curves/curves-dialog-slight-s.png  |  Bin 0 -> 29926 bytes
 .../curves-dialog-value-rgb-select.png             |  Bin 0 -> 32105 bytes
 .../curves-house-square-full.jpg                   |  Bin 0 -> 27562 bytes
 .../curves-house-square-zoom-1.jpg                 |  Bin 0 -> 29530 bytes
 .../curves-house-square-zoom-2.jpg                 |  Bin 0 -> 9369 bytes
 .../curves-house-square-zoom-3.png                 |  Bin 0 -> 10555 bytes
 .../Basic_Color_Curves/curves-your-pixel-info.png  |  Bin 0 -> 13006 bytes
 ...imple-5636649561-dark-blue-boost-add-yellow.jpg |  Bin 0 -> 78982 bytes
 .../flickr-qsimple-5636649561-dark-blue-boost.jpg  |  Bin 0 -> 78396 bytes
 ...ckr-qsimple-5636649561-dark-green-suppresst.jpg |  Bin 0 -> 78671 bytes
 .../flickr-qsimple-5636649561-mid-boostl.jpg       |  Bin 0 -> 78572 bytes
 ...kr-qsimple-5636649561-orangeteal-blue-highs.jpg |  Bin 0 -> 81121 bytes
 ...ckr-qsimple-5636649561-orangeteal-blue-lows.jpg |  Bin 0 -> 81768 bytes
 ...r-qsimple-5636649561-orangeteal-green-highs.jpg |  Bin 0 -> 80662 bytes
 ...kr-qsimple-5636649561-orangeteal-green-lows.jpg |  Bin 0 -> 83582 bytes
 ...ckr-qsimple-5636649561-orangeteal-red-highs.jpg |  Bin 0 -> 80351 bytes
 ...ickr-qsimple-5636649561-orangeteal-red-lows.jpg |  Bin 0 -> 83166 bytes
 ...r-qsimple-5636649561-orangeteal-value-final.jpg |  Bin 0 -> 83430 bytes
 .../flickr-qsimple-5636649561-original.jpg         |  Bin 0 -> 77923 bytes
 .../flickr-qsimple-5636649561-slight-s.jpg         |  Bin 0 -> 80221 bytes
 content/tutorials/Basic_Color_Curves/index.md      |  391 ++++++++++++++++++
 .../tutorials/Basic_Color_Curves/th_tranquil.jpg   |  Bin 0 -> 89620 bytes
 content/tutorials/Basic_Color_Curves/tranquil.jpg  |  Bin 0 -> 299178 bytes
 47 files changed, 1284 insertions(+), 217 deletions(-)
---
diff --git a/content/about/meta/file-list.md b/content/about/meta/file-list.md
index ab01452..9beb214 100644
--- a/content/about/meta/file-list.md
+++ b/content/about/meta/file-list.md
@@ -156,9 +156,9 @@ The main page links go to legacy WGO, the link icon (if there) will go to the po
 <del><http://www.gimp.org/tutorials/3d_Logo/index.html></del> [<i class="fa 
fa-link"></i>]({filename}../../tutorials/3D_Logo/index.md)    
 <del><http://www.gimp.org/tutorials/Advanced_Animations/index.html></del> [<i class="fa 
fa-link"></i>]({filename}../../tutorials/Advanced_Animations/index.md)  
 <del><http://www.gimp.org/tutorials/Anti-Aliased_Threshold/index.html></del> [<i class="fa 
fa-link"></i>]({filename}../../tutorials/Anti-Aliased_Threshold/index.md)  
-<http://www.gimp.org/tutorials/Automate_Editing_in_GIMP/index.html>  
-<http://www.gimp.org/tutorials/AutomatedJpgToXcf/index.html>  
-<http://www.gimp.org/tutorials/Basic_Batch/index.html>  
+<del><http://www.gimp.org/tutorials/Automate_Editing_in_GIMP/index.html></del> [<i class="fa 
fa-link"></i>]({filename}../../tutorials/Automate_Editing_in_GIMP/index.md)  
+<del><http://www.gimp.org/tutorials/AutomatedJpgToXcf/index.html></del> [<i class="fa 
fa-link"></i>]({filename}../../tutorials/AutomatedJpgToXcf/index.md)  
+<del><http://www.gimp.org/tutorials/Basic_Batch/index.html></del> [<i class="fa 
fa-link"></i>]({filename}../../tutorials/Basic_Batch/index.md)  
 <http://www.gimp.org/tutorials/Basic_Color_Curves/index.html>  
 <http://www.gimp.org/tutorials/Basic_Perl/index.html>  
 <http://www.gimp.org/tutorials/Basic_Scheme/index.html>  
diff --git a/content/tutorials/Automate_Editing_in_GIMP/index.md 
b/content/tutorials/Automate_Editing_in_GIMP/index.md
index d9daacd..ae99ee6 100644
--- a/content/tutorials/Automate_Editing_in_GIMP/index.md
+++ b/content/tutorials/Automate_Editing_in_GIMP/index.md
@@ -5,7 +5,7 @@ Author: Stephen Kiel
 
 
 [![Creative Commons 
License](http://i.creativecommons.org/l/by-sa/3.0/80x15.png)](http://creativecommons.org/licenses/by-sa/3.0/deed.en_US)
  
-<span xmlns:dct="http://purl.org/dc/terms/";>GIMP Tutorial - Luminosity Masks (text)</span> by <a 
rel="cc:attributionURL" xmlns:cc="http://creativecommons.org/ns#";>Stephen Kiel</a> is licensed under a 
[Creative Commons Attribution-ShareAlike 3.0 Unported 
License](http://creativecommons.org/licenses/by-sa/3.0/deed.en_US). The code sources in this tutorial are 
licensed by Stephen Kiel under the conditions of the [GNU Public License GPL 
V3](https://www.gnu.org/copyleft/gpl.html).
+<span xmlns:dct="http://purl.org/dc/terms/";>GIMP Tutorial - Automate Editing</span> by <a 
rel="cc:attributionURL" xmlns:cc="http://creativecommons.org/ns#";>Stephen Kiel</a> is licensed under a 
[Creative Commons Attribution-ShareAlike 3.0 Unported 
License](http://creativecommons.org/licenses/by-sa/3.0/deed.en_US). The code sources in this tutorial are 
licensed by Stephen Kiel under the conditions of the [GNU Public License GPL 
V3](https://www.gnu.org/copyleft/gpl.html).
 
 ## Table of Contents
 
@@ -62,8 +62,12 @@ Suppose we wanted to set up the grid spacing so that it is centered on the image
     >>> pdb.gimp_image_grid_set_style(theImage, GRID_ON_OFF_DASH)
 
 
-<div class="caption">![CommandsPythonConsole.jpg](CommandsPythonConsole.jpg)  
-<span>Commands in the Python Console</span></div>
+<figure>
+<img src="CommandsPythonConsole.jpg" alt="CommandsPythonConsole.jpg" />
+<figcaption> 
+Commands in the Python Console
+</figcaption> 
+</figure>
 
 If you watch the image as you enter the commands and have the Grid turned “ON” you will see the grid spacing 
on the active image change as we execute these commands.
 
@@ -80,15 +84,19 @@ Let's touch upon the main ideas that we are going to use to implement the macro
 3.  From the named Macro, the data structure will return a list of commands.
 4.  The list of commands will be run in an 'exec' loop:
 
-<div class="caption"><span style="font-style: italic">Example - “Exec” Loop</span>
+Example "Exec" Loop:
 
-<pre class="code" style="text-align: left;">    for Cmd in commandList:
-        exec(Cmd)</pre>
+    for Cmd in commandList:
+        exec(Cmd)
 
-</div>
 
-<div class="caption">![CommanderMacroSubMenu.jpg](CommanderMacroSubMenu.jpg)  
-<span>Commander Macro Sub-Menu</span></div>
+
+<figure>
+<img src="CommanderMacroSubMenu.jpg" alt="CommanderMacroSubMenu.jpg" />
+<figcaption> 
+Commander Macro Sub-Menu
+</figcaption> 
+</figure>
 
 ### Architecture
 
@@ -124,25 +132,24 @@ A final thing that we need to talk about that is not a 'category' of execution b
 *   An architectural advantage is we create this list with a function that reads a configuration file. We 
only have to define and maintain this configuration list in one place within our system and use the resulting 
list in as many places as we want by calling a reading function. This is how we will get new macros to show 
up in the menus when we add them.
 *   The following skeletal code fragments illustrate defining a list 'cmdList' at the top level – 'main', 
and using it within the registration block and function. Because it is defined at the ‘main’ level, we can 
reference it within the function and registration block. We can recover the argument from the index (passed 
by the widget) because we are using the same list in both places:
 
-<div class="caption"><span style="font-style: italic">Example - Lists and Scope in Functions</span>
-
-<pre class="code" style="text-align: left;">cmdList = cmdrReadObj.CommanderMacros()
-#
-def autoCommander(theImage, cmdListIndex):
-    ...
-    commanderName = cmdList[cmdListIndex]
-    ...     
-#
-register (
-    "autoCommander",         # Name registered in Procedure Browser
-    ...
-    [
-    ...
-    ( PF_OPTION, "cmdSet", "Select a command", 0, cmdList ),
-    ],
-main()</pre>
-
-</div>
+<span style="font-style: italic">Example - Lists and Scope in Functions</span>
+
+    cmdList = cmdrReadObj.CommanderMacros()
+    #
+    def autoCommander(theImage, cmdListIndex):
+        ...
+        commanderName = cmdList[cmdListIndex]
+        ...     
+    #
+    register (
+        "autoCommander",         # Name registered in Procedure Browser
+        ...
+        [
+        ...
+        ( PF_OPTION, "cmdSet", "Select a command", 0, cmdList ),
+        ],
+    main()
+
 
 ### Data Model
 
@@ -156,18 +163,22 @@ Python has several built in data structures such as dictionaries, lists to name
 2.  A branch can hold an indefinite number of elements, and those elements can be either a leaf with 
attributes or a sub-branch to another level. This lends a lot of flexibility with the way we structure of the 
data.
 3.  The input / output format is XML, which is not only hierarchical, but it is text so it is human readable 
and portable to any platform (computer / OS).
 
-<div class="caption">![XmlHierarchyContainers.jpg](XmlHierarchyContainers.jpg)  
-<span>XML Hierarchy - Containers</span></div>
+<figure>
+<img src="XmlHierarchyContainers.jpg" alt="XmlHierarchyContainers.jpg" />
+<figcaption> 
+XML Hierarchy - Containers
+</figcaption> 
+</figure>
 
 The examples use ElementTree to read and write the data between trees and XML. ElementTree is included with 
Python and described in the Python documentation, so we will not go into detail about the mechanics of tree 
structures here.
 
 You might be wondering at this point where these XML file will be located. The functions that read and write 
the XML files are expecting to find the XML under a directory named ‘myXml’ which you will have to create 
under you user gimp directory. If you are using Linux and your home directory is ‘stephen’ the path would 
look something like:
 
-<pre class="code">/home/stephen/.gimp-2.8/myXml</pre>
+    /home/stephen/.gimp-2.8/myXml
 
 If you are using Windows the path would look something like:
 
-<pre class="code">C:\Users\stephen\.gimp-2.8\myXml</pre>
+    C:\Users\stephen\.gimp-2.8\myXml
 
 We will be dealing with a couple of types of pseudo code and xml files, and those will be keep in separate 
directories under myXml, but we will get to that in a bit.
 
@@ -183,60 +194,66 @@ We can begin writing a pseudo code file by copying and pasting a set of commands
 
 The pseudo code will be in a file, in this example it is named NormalGridCanvas.def. Each line begins with a 
keyword. Keyword choices are: “commander>”, “macro>”, “comment>”, or “>>>”.
 
-The class XmlGenerator() in autoBase.py contains a function GenCommanderXml() which reads all of the *.def 
files in ~/.gimp-2.8/myXml/commander, inserts the lines into a tree (after removing the keyword), and then 
writes the tree out to a file named combinedCommander.xml.
+The class XmlGenerator() in autoBase.py contains a function GenCommanderXml() which reads all of the \*.def 
files in ~/.gimp-2.8/myXml/commander, inserts the lines into a tree (after removing the keyword), and then 
writes the tree out to a file named combinedCommander.xml.
 
 The keyword will determine both the “tag” associated with the line of pseudo code, and whether it is a 
“branch” element (macro name) or a “leaf” element (command or comment). We are assigning both a definition 
and a level in the hierarchy for each line of pseudo code text as we read it into the tree.
 
-<div class="caption"><span style="font-style: italic">Example - Pseudo Code Example - 
NormalGridCanvas.def</span>
-
-<pre class="code" style="text-align: left; margin-right: 1em;">commander>Normal Grid and Canvas
-   macro>
-      comment>Shrink the Canvas back to fit the layer
-      >>>theImage.resize_to_layers()
-      comment>Set grid to origin and size = image
-      >>>pdb.gimp_image_grid_set_offset(theImage, 0, 0)
-      >>>pdb.gimp_image_grid_set_spacing(theImage, theImage.width, theImage.height)</pre>
-
-</div>
-
-After all of the *.def files are read into the tree and written back out in the form of an XML file, the 
formatting is done. Writing out a tree automatically generates all of the containing enclosures, essentially 
making properly formatting the XML a trivial task. The fragment from combinedCommander.xml illustrates the 
XML from the pseudo code in NormalGridCanvas.def.
-
-<div class="caption"><span style="font-style: italic">Example - combinedCommander.xml (fragment)</span>
-
-<pre class="code" style="text-align: left; margin-right: 1em;"><combined>
-  Definition
- ...
-  <commander>
-    Normal Grid and Canvas
-    <comment>
-      Shrink the Canvas back to fit the layer
-    </comment>
-    <command>
-      theImage.resize_to_layers()
-    </command>
-    <comment>
-      Set grid to origin and size = image
-    </comment>
-    <command>
-      pdb.gimp_image_grid_set_offset(theImage, 0, 0)
-    </command>
-    <command>
-      pdb.gimp_image_grid_set_spacing(theImage, theImage.width, theImage.height)
-    </command>
-  </commander>
-  ...
-</combined>
-        </pre>
-
-<span style="font-style: italic;">* The XML above was run through an online XML pretty printer for 
readability. The XML from ElementTree is functional, but hard to read.</span></div>
-
-<div class="caption">![PseudoCodetoXmlFunction.jpg](PseudoCodetoXmlFunction.jpg)  
-<span>Creating XML from *.def files</span></div>
+*Example - Pseudo Code Example - NormalGridCanvas.def*
+
+    commander>Normal Grid and Canvas
+       macro>
+          comment>Shrink the Canvas back to fit the layer
+          >>>theImage.resize_to_layers()
+          comment>Set grid to origin and size = image
+          >>>pdb.gimp_image_grid_set_offset(theImage, 0, 0)
+          >>>pdb.gimp_image_grid_set_spacing(theImage, theImage.width, theImage.height)
+
+
+After all of the \*.def files are read into the tree and written back out in the form of an XML file, the 
formatting is done. Writing out a tree automatically generates all of the containing enclosures, essentially 
making properly formatting the XML a trivial task. The fragment from combinedCommander.xml illustrates the 
XML from the pseudo code in NormalGridCanvas.def.
+
+<span style="font-style: italic">Example - combinedCommander.xml (fragment)</span>
+
+    <combined>
+      Definition
+     ...
+      <commander>
+        Normal Grid and Canvas
+        <comment>
+          Shrink the Canvas back to fit the layer
+        </comment>
+        <command>
+          theImage.resize_to_layers()
+        </command>
+        <comment>
+          Set grid to origin and size = image
+        </comment>
+        <command>
+          pdb.gimp_image_grid_set_offset(theImage, 0, 0)
+        </command>
+        <command>
+          pdb.gimp_image_grid_set_spacing(theImage, theImage.width, theImage.height)
+        </command>
+      </commander>
+      ...
+    </combined>
+
+_\* The XML above was run through an online XML pretty printer for readability. The XML from ElementTree is 
functional, but hard to read._
+
+<figure markdown="span">
+<img src="PseudoCodetoXmlFunction.jpg" alt="PseudoCodetoXmlFunction.jpg" />
+<figcaption>
+Creating XML from \*.def files
+</figcaption>
+</figure>
 
 The Xml generator can be called from a GUI menu.
 
-<div class="caption">![PseudoCodeImported.jpg](PseudoCodeImported.jpg)  
-<span>Xml files built</span></div>
+<figure>
+<img src="PseudoCodeImported.jpg" alt="PseudoCodeImported.jpg" />
+<figcaption> 
+Xml files built
+</figcaption> 
+</figure>
 
 ### Displaying the Macro Names in a Menu
 
@@ -263,7 +280,7 @@ The discussion above has described how we can generate a macro by running a set
 
 The code for transforming the pseudo code into a macro is in autoWriteXml.py. The code to display the menu 
of Macros you have written and execute them is in autoCommander.py. The Classes referenced by these two 
scripts are in autoBase.py.
 
-The text files that you write for your macro definition need to be put in a directory 
~/.gimp-2.x/myXml/commander and have an extension of '.def'. Create a separate *.def file for each macro.
+The text files that you write for your macro definition need to be put in a directory 
~/.gimp-2.x/myXml/commander and have an extension of '.def'. Create a separate \*.def file for each macro.
 
 ## An Introduction to Automated Editing
 
@@ -318,29 +335,28 @@ There are two special types of data for the automated flow:
 
 ### The Image and Parasites (or Property) Data
 
-The Image type that we will be using for all of our work is the native Gimp *.xcf format. This image format 
saves all of the layers and modes that we might set while editing and also saves a type of data called 
Parasites, which are similar to Properties on many other systems.
+The Image type that we will be using for all of our work is the native Gimp \*.xcf format. This image format 
saves all of the layers and modes that we might set while editing and also saves a type of data called 
Parasites, which are similar to Properties on many other systems.
 
 Parasites are like variable can be referenced by name in order to access their value. Like variables they 
can be assigned and read. Unlike variables, parasites are persistent, very persistent. A parasite, when 
assigned to an image, becomes part of the image and is saved with the image file. A parasite that is assigned 
and saved with an image can be read after gimp is closed and reopened, it is just like any other file data in 
that respect.
 
-Parasites are also very portable, you can read and write parasites using either the scheme based or python 
based scripts. They are also independent of the operating system, so you can write a parasite to an image on 
your Linux Desktop machine, and read it a week later on your windows based laptop assuming that you saved the 
images in the native gimp *.xcf file format. Parasites can also be written to specific layers, but for our 
present needs, the image parasites are all we are using.
+Parasites are also very portable, you can read and write parasites using either the scheme based or python 
based scripts. They are also independent of the operating system, so you can write a parasite to an image on 
your Linux Desktop machine, and read it a week later on your windows based laptop assuming that you saved the 
images in the native gimp \*.xcf file format. Parasites can also be written to specific layers, but for our 
present needs, the image parasites are all we are using.
 
 Because the parasite is associated with the image, and it is persistent until it is overwritten or removed, 
it is an ideal tool for keeping track of the state of the image's progress in the editing process. Beyond 
being able to just take notes, the values of the parasites can be used like a property to make decisions and 
influence the execution of the script that has read the parasite data.
 
 If for example we opened an image that had two parasites (properties), named 'UpdateFlag' and 'Flow', we 
could use the values from those parasites to make decisions:
 
-<div class="caption"><span style="font-style: italic">Example – Decisions based on Parasite / Property 
Values</span>
+_Example – Decisions based on Parasite / Property Values_
 
-<pre class="code" style="text-align: left;">UpdateFlag = str(theImage.parasite_find('UpdateFlag'))
-Flow = str(theImage.parasite_find('Flow'))
-if (UpdateFlag == 'YES'):
-       if (Flow == 'Standard'):
-               { run commands for Standard flow }
-       elif (Flow == 'SemiAuto'):
-               { run commands for SemiAuto Flow }
-elif (UpdateFlag == 'NO'):
-       { do nothing }</pre>
+    UpdateFlag = str(theImage.parasite_find('UpdateFlag'))
+    Flow = str(theImage.parasite_find('Flow'))
+    if (UpdateFlag == 'YES'):
+        if (Flow == 'Standard'):
+            { run commands for Standard flow }
+        elif (Flow == 'SemiAuto'):
+            { run commands for SemiAuto Flow }
+    elif (UpdateFlag == 'NO'):
+        { do nothing }
 
-</div>
 
 Reading and writing parasites to an image does have one idiosyncrasy worth comment on which is the format of 
the data being written. You must express the parasite as an ordered set of 'Name', 'Index', and 'Value'. Name 
and Value are both strings, and the Index is a small integer, (stay between 1 and 254). If you have not used 
parasites before you might be wondering how you determine a 'correct' value for the index. You may:
 
@@ -365,8 +381,12 @@ The mechanics for creating XML from pseudo code for the workflows, properties, a
 
 The export XCF to JPG function in the “Automation” menu opens each xcf file in the source / work directory 
and looks at the properties of the image. If the image is “Finished”, at the end of the flow, it is exported. 
The images that are still being work on are left alone.
 
-<div class="caption">![RunningAutoUpdate.jpg](RunningAutoUpdate.jpg)  
-<span>Running AutoUpdate</span></div>
+<figure>
+<img src="RunningAutoUpdate.jpg" alt="RunningAutoUpdate.jpg" />
+<figcaption>
+Running AutoUpdate
+</figcaption>
+</figure>
 
 ## Automation Tool Implementation – Details
 
@@ -374,11 +394,11 @@ The export XCF to JPG function in the “Automation” menu opens each xcf file
 
 #### Workflow Pseudo Code
 
-You can generate the list of commands that we wish to perform on an image in the python console and when you 
have it working just right for the step you would like to perform you can copy and paste them into a pseudo 
code text file. The “Pseudocode to XML” function will be looking for files that have the file extension 
“.def” so it will convert all of the *.def files in the flow directory into XML.
+You can generate the list of commands that we wish to perform on an image in the python console and when you 
have it working just right for the step you would like to perform you can copy and paste them into a pseudo 
code text file. The “Pseudocode to XML” function will be looking for files that have the file extension 
“.def” so it will convert all of the \*.def files in the flow directory into XML.
 
 As in the case of the macros, you can put in comment lines beginning with “comment>” and blank lines to make 
the code fragments more readable and easier to understand when you come back to make enhancements in a couple 
of months.
 
-Each set of commands is contained by a “Step” which uses the key “step>”. The top level container is the 
Workflow which uses the key “flow>”. Each workflow can be specified in its own “.def” file. The “Pseudocode 
to XML” function will read all of the *.def files and create a single XML file named combinedFlow.xml in the 
myXml/flow directory.
+Each set of commands is contained by a “Step” which uses the key “step>”. The top level container is the 
Workflow which uses the key “flow>”. Each workflow can be specified in its own “.def” file. The “Pseudocode 
to XML” function will read all of the \*.def files and create a single XML file named combinedFlow.xml in the 
myXml/flow directory.
 
 #### Property / Parasite Pseudo Code
 
@@ -388,8 +408,12 @@ There are three properties that are assigned by the automation scripts and are n
 
 You can see all of the properties and current assigned values for a particular image using the menu function 
“Automation” -> “A1) Display Assigned Parasites (File)”.
 
-<div class="caption">![ParasitesImage.jpg](ParasitesImage.jpg)  
-<span>Assigned Parasites</span></div>
+<figure>
+<img src="ParasitesImage.jpg" alt="ParasitesImage.jpg" />
+<figcaption>
+Assigned Parasites
+</figcaption>
+</figure>
 
 ### Properties and Image State – Flow Control Parasites
 
@@ -399,95 +423,66 @@ The Flow Control Parasites provide a method to make each image “self aware”
 
 Let's examine the steps of the “Standard” flow example that is included with this tutorial. The steps the 
image will go through are:
 
-<div class="caption"><span style="font-style: italic">Example – States or Steps in the Standard Flow 
Example</span>
+<span style="font-style: italic">Example – States or Steps in the Standard Flow Example</span>
 
-<table>
+<style>
+table {
+max-width: 40rem;
+font-size: 0.85rem;
+margin: 1rem auto;
+}
+table td {
+    padding: 0.25rem;
+    border: solid 1px #eee;
+}
 
-<tbody>
+</style>
 
+<table>
+<tbody>
 <tr>
-
+<th></th>
 <td class="emphesize">CurrentStep</td>
-
 <td class="emphesize">NextStep</td>
-
 </tr>
-
 <tr>
-
 <th>1.</th>
-
 <td>First</td>
-
 <td>Alignment</td>
-
 </tr>
-
 <tr>
-
 <th>2.</th>
-
 <td>Alignment</td>
-
 <td>DynamicRange</td>
-
 </tr>
-
 <tr>
-
 <th>3.</th>
-
 <td>DynamicRange</td>
-
 <td>Retinex-Filter</td>
-
 </tr>
-
 <tr>
-
 <th>4.</th>
-
 <td>Retinex-Filter</td>
-
 <td>Sharpen</td>
-
 </tr>
-
 <tr>
-
 <th>5.</th>
-
 <td>Sharpen</td>
-
 <td>ColorAdjust</td>
-
 </tr>
-
 <tr>
-
 <th>6.</th>
-
 <td>ColorAdjust</td>
-
 <td>FINISHED</td>
-
 </tr>
-
 <tr>
-
 <th>7.</th>
-
 <td>FINISHED</td>
-
 <td>FINISHED</td>
-
 </tr>
-
 </tbody>
-
 </table>
 
-</div>
 
 The state “First” is assigned by the Jpeg to Xcf function. This step is assigned automatically regardless of 
the flow. The steps following the “First” step, “Alignment”, “DynamicRange”, “Retinex-Filter”, “Sharpen”, and 
“ColorAdjust” are assigned through the Xml representation of the flow. The Step “FINISHED” is assigned 
automatically when the end of the list of steps is reached.
 
@@ -513,19 +508,26 @@ Using an automated workflow has changed the way that I use Gimp for editing my p
 
 ## Appendix – Notes
 
-The following Appendices contain notes which are more specific to setting up the example scripts, the 
example *.def files, and comments on debugging.
+The following Appendices contain notes which are more specific to setting up the example scripts, the 
example \*.def files, and comments on debugging.
 
 ### Setting up the Example Scripts
 
 All of the example scripts begin with “auto”, e.g. autoAutoUpdate.py, autoBase.py, ... If you try them but 
then decide you don't like them they should be pretty easy to find and remove. The following example scripts 
should be loaded into your gimp/plug-ins directory. Something like /home/stephen/.gimp-2.8/plug-ins if your 
user name is stephen and you were using gimp 2.8\. Click on the filename to download.
 
-1.  [autoAutoUpdate.py](plug-ins/autoAutoUpdate.py) - Runs the auto update function on a directory of images.
-2.  [autoBase.py](plug-ins/autoBase.py) - Contains the classes that read and write the XML files that affect 
how the update works.
-3.  [autoCommander.py](plug-ins/autoCommander.py) - Runs the 'Commander' macros.
-4.  [autoJpegToXcf.py](plug-ins/autoJpegToXcf.py) - Imports the images into xcf format and assigns 
properties to image.
-5.  [autoRWparasites.py](plug-ins/autoRWparasites.py) - User Interface functions to read and write image 
parasites from the menu.
-6.  [autoWriteXml.py](plug-ins/autoWriteXml.py) - Reads *.def files and generates XML for commander macros, 
workflows, and properties.
-7.  [autoXcfToJpg.py](plug-ins/autoXcfToJpg.py) – Exports the finished images back to jpeg format.
+1.  [autoAutoUpdate.py](plug-ins/autoAutoUpdate.py)  
+    Runs the auto update function on a directory of images.
+2.  [autoBase.py](plug-ins/autoBase.py)  
+    Contains the classes that read and write the XML files that affect how the update works.
+3.  [autoCommander.py](plug-ins/autoCommander.py)  
+    Runs the 'Commander' macros.
+4.  [autoJpegToXcf.py](plug-ins/autoJpegToXcf.py)  
+    Imports the images into xcf format and assigns properties to image.
+5.  [autoRWparasites.py](plug-ins/autoRWparasites.py)  
+    User Interface functions to read and write image parasites from the menu.
+6.  [autoWriteXml.py](plug-ins/autoWriteXml.py)  
+    Reads \*.def files and generates XML for commander macros, workflows, and properties.
+7.  [autoXcfToJpg.py](plug-ins/autoXcfToJpg.py)  
+    Exports the finished images back to jpeg format.
 
 ### Setting up the Example Pseudo Code
 
@@ -533,7 +535,7 @@ Underneath your gimp directory (something like /home/stephen/.gimp-2.8) you need
 
 #### Pseudo Code for Commander Macros
 
-Copy the following example *.def files into the “commander” directory 
(/home/stephen/.gimp-2.8/myXml/commander – assuming a home directory of /user/stephen and a gimp version 
2.8). They are example Commander Macros pseudo code files. Click on the filename to download.
+Copy the following example \*.def files into the “commander” directory 
(/home/stephen/.gimp-2.8/myXml/commander – assuming a home directory of /user/stephen and a gimp version 
2.8). They are example Commander Macros pseudo code files. Click on the filename to download.
 
 1.  [centeredgrid.def](myXml/commander/centeredgrid.def)
 2.  [colorAdjust.def](myXml/commander/colorAdjust.def)
@@ -547,11 +549,11 @@ Copy the following example *.def files into the “commander” directory (/home
 
 Hopefully with the comments and by running them, their function will be apparent. They should be enough to 
get you started writing some macros of your own.
 
-When you run the “Pseudocode to XML” Utility function, it will read all of the *.def files in this directory 
and write an XML file in this directory called “combinedCommander.xml”. “combinedCommander.xml” is the file 
that is accessed to list and run all of your macros.
+When you run the “Pseudocode to XML” Utility function, it will read all of the \*.def files in this 
directory and write an XML file in this directory called “combinedCommander.xml”. “combinedCommander.xml” is 
the file that is accessed to list and run all of your macros.
 
 #### Pseudo Code for Automation Workflows
 
-Copy the following *.def files into the “flow” directory (/home/stephen/.gimp-2.8/myXml/flow). They are 
example Workflow pseudo code files.
+Copy the following \*.def files into the “flow” directory (/home/stephen/.gimp-2.8/myXml/flow). They are 
example Workflow pseudo code files.
 
 1.  [fullauto.def](myXml/flow/fullauto.def)
 2.  [semiauto.def](myXml/flow/semiauto.def)
@@ -559,15 +561,15 @@ Copy the following *.def files into the “flow” directory (/home/stephen/.gim
 
 These three workflows all follow the same basicsteps of the standard workflow. The semiauto and fullauto 
workflows combine some of the steps. The idea is to give you a couple of different workflows to play with. 
The fullauto illustrates that you really can pack a lot of editing into a “step” but is probably too 
automatic to be of practical use.
 
-When you run the “Pseudocode to XML” Utility function, it will read all of the *.def files in this directory 
and write an XML file in this directory called “combinedFlow.xml”.
+When you run the “Pseudocode to XML” Utility function, it will read all of the \*.def files in this 
directory and write an XML file in this directory called “combinedFlow.xml”.
 
 #### Pseudo Code for Properties
 
-Copy the following *.def file into the “property” directory (/home/stephen/.gimp-2.8/myXml/property). It is 
an example Property pseudo code file (for Flag Properties / Parasites).
+Copy the following \*.def file into the “property” directory (/home/stephen/.gimp-2.8/myXml/property). It is 
an example Property pseudo code file (for Flag Properties / Parasites).
 
 1.  [flagProperties.def](myXml/property/flagProperties.def)
 
-When you run the “Pseudocode to XML” Utility function, it will read *.def file in this directory and write 
an XML file in this directory called “flagProperties.xml”.
+When you run the “Pseudocode to XML” Utility function, it will read \*.def file in this directory and write 
an XML file in this directory called “flagProperties.xml”.
 
 ### Pseudo Code Syntax
 
@@ -575,26 +577,25 @@ When you run the “Pseudocode to XML” Utility function, it will read *.def fi
 
 There are three keywords used for writing commander pseudo code:
 
-1.  **commander>** - The text following this keyword is the Macro Name. This keyword must be the first 
keyword in the file. This is the “container” or the root of the tree for the following comments and commands.
-2.  **comment>** - The text following this keyword is for descriptive comments. The comments will be 
represented in the pseudo code *.def file and in the resulting XML. When the XML is read for processing, 
comments will be ignored.
-3.  **>>>** - The text following this keyword is taken as a python statement. Then the resulting XML is 
read, the command statements will be passed to the commander script to be processed in order.
+1.  `commander>` - The text following this keyword is the Macro Name. This keyword must be the first keyword 
in the file. This is the “container” or the root of the tree for the following comments and commands.
+2.  `comment>` - The text following this keyword is for descriptive comments. The comments will be 
represented in the pseudo code \*.def file and in the resulting XML. When the XML is read for processing, 
comments will be ignored.
+3.  `>>>` - The text following this keyword is taken as a python statement. Then the resulting XML is read, 
the command statements will be passed to the commander script to be processed in order.
 
 Note that lines beginning with “#” are ignored. You may indent if you like for readability. Leading white 
space is stripped off.
 
-<div class="caption"><span style="font-style: italic">Example - Commander Pseudo Code Example</span>
+_Example - Commander Pseudo Code Example_
 
-<pre class="code" style="text-align: left; margin-right: 1em;">commander>Centered Grid
-   comment>** Set up the grid for Rotate and or Perspective Transform
-   comment>*    Set values from python-fu image object
-   >>>centerX = theImage.width/2
-   >>>centerY = theImage.height/2
-   >>>gridSpacing = max(theImage.width, theImage.height)/24
-   comment>*    configure grid with PDB functions
-   >>>pdb.gimp_image_grid_set_offset(theImage, centerX, centerY)
-   >>>pdb.gimp_image_grid_set_spacing(theImage, gridSpacing, gridSpacing)
-   >>>pdb.gimp_image_grid_set_style(theImage, GRID_ON_OFF_DASH)</pre>
+    commander>Centered Grid
+       comment>** Set up the grid for Rotate and or Perspective Transform
+       comment>*    Set values from python-fu image object
+       >>>centerX = theImage.width/2
+       >>>centerY = theImage.height/2
+       >>>gridSpacing = max(theImage.width, theImage.height)/24
+       comment>*    configure grid with PDB functions
+       >>>pdb.gimp_image_grid_set_offset(theImage, centerX, centerY)
+       >>>pdb.gimp_image_grid_set_spacing(theImage, gridSpacing, gridSpacing)
+       >>>pdb.gimp_image_grid_set_style(theImage, GRID_ON_OFF_DASH)
 
-</div>
 
 #### Property Pseudo Code
 
@@ -602,40 +603,39 @@ There are five keywords used for writing property pseudo code:
 
 1.  **flags** - The text following this keyword is the top level container, or in other words, the root of 
the tree.
 2.  **property** - The text following the keyword is the name of the property / parasite. This is a second 
level container or a branch of the tree. It will contain all of the following leaf keywords (comment, 
default, and option) until the next property statement.
-3.  **comment** - The text following this keyword is for descriptive comments. The comments will be 
represented in the pseudo code *.def file and in the resulting XML. When the XML is read for processing, 
comments will be ignored. The comments are leafs of the tree.
+3.  **comment** - The text following this keyword is for descriptive comments. The comments will be 
represented in the pseudo code \*.def file and in the resulting XML. When the XML is read for processing, 
comments will be ignored. The comments are leafs of the tree.
 4.  **default** - The text following this keyword is the default property value. The default value is a leaf 
of the tree.
 5.  **option** - The text following this keyword is one of the possible property values. There can be 
several option values for any given property. The option values are leafs of the tree.
 
-<div class="caption"><span style="font-style: italic">Example - Property Pseudo Code Example</span>
+_Example - Property Pseudo Code Example_
 
-<pre class="code" style="text-align: left; margin-right: 1em;">flags>Control Properties
-property>UpdateFlag
-    comment>Initial value set on import to Xcf
-    comment>Set by user on Image from Automation Menu
-    comment>Read by autoAutoUpdate (updateImage function)
-    comment>Updates Image (executes Next Step in Flow) if YES
-    comment>Reset to NO by updateImage
-    default>YES
-    option>NO
-    option>YES
+    flags>Control Properties
+    property>UpdateFlag
+        comment>Initial value set on import to Xcf
+        comment>Set by user on Image from Automation Menu
+        comment>Read by autoAutoUpdate (updateImage function)
+        comment>Updates Image (executes Next Step in Flow) if YES
+        comment>Reset to NO by updateImage
+        default>YES
+        option>NO
+        option>YES
 
-property>EnhanceColorLevel
-    default>NORMAL
-    option>EXTRA
-    option>NORMAL
-    option>MID
-    option>NONE</pre>
+    property>EnhanceColorLevel
+        default>NORMAL
+        option>EXTRA
+        option>NORMAL
+        option>MID
+        option>NONE
 
-</div>
 
 #### Flow Pseudo Code
 
 There are four keywords used for writing flow pseudo code:
 
-1.  **flow** The text following this keyword is the top level container, or in other words, the root of the 
tree. This is the name of the flow.
-2.  **step** The text following this keyword is the first level branch from the root. The step contains 
comments and commands. The steps select groups of commands for execution.
-3.  **comment** Comments are leafs of the tree.
-4.  **>>>** Commands are leafs of the tree. When the Xml is read the commands will be processed in the order 
in which they appear in the step.
+1.  `flow` The text following this keyword is the top level container, or in other words, the root of the 
tree. This is the name of the flow.
+2.  `step` The text following this keyword is the first level branch from the root. The step contains 
comments and commands. The steps select groups of commands for execution.
+3.  `comment` Comments are leafs of the tree.
+4.  `>>>` Commands are leafs of the tree. When the Xml is read the commands will be processed in the order 
in which they appear in the step.
 
 Lines beginning with a “#” are ignored. Leading white space before the keywords is stripped out. White space 
after the keyword is stripped out.
 
@@ -645,13 +645,13 @@ The Python-Fu console is a python shell in which you can run not only the gimp p
 
 First, set up and verify Python Path to include your user plug-ins directory:
 
-<div class="caption"><span style="font-style: italic;">Example – Setting the Python path in the Python-Fu 
Console</span>
+_Example – Setting the Python path in the Python-Fu Console_
 
-<pre class="code" style="text-align: left; margin-right: 1em;">>>> import sys
->>> sys.path.append('/home/stephen/.gimp-2.8/plug-ins/')
->>> sys.path</pre>
+    >>> import sys
+    >>> sys.path.append('/home/stephen/.gimp-2.8/plug-ins/')
+    >>> sys.path
 
-<span style="font-style: italic;">echos back a list of paths that include path added above</span></div>
+_echos back a list of paths that include path added above_
 
 Next, run your python functions in the Gimp Python-Console . This example uses the 'TestBench' class to run 
functions in the other classes in the autoBase.py module. Object instances of the TestBench class echo back 
results to the screen.
 
@@ -660,26 +660,27 @@ Next, run your python functions in the Gimp Python-Console . This example uses t
 3.  Create and instance of the TestBench class
 4.  Run the TestXmlGen and TestXmlRead functions
 
-<div class="caption"><span style="font-style: italic;">Example – Running your own Functions in the Python-Fu 
Console</span>
+_Example – Running your own Functions in the Python-Fu Console_
 
-<pre class="code" style="text-align: left; margin-right: 1em;">>>> import os
->>> os.chdir('/home/stephen/.gimp-2.8/plug-ins')
->>> from autoBase import *
->>> testola = TestBench()
->>> testola.TestXmlGen()
->>> testola.TestXmlRead()</pre>
+    >>> import os
+    >>> os.chdir('/home/stephen/.gimp-2.8/plug-ins')
+    >>> from autoBase import *
+    >>> testola = TestBench()
+    >>> testola.TestXmlGen()
+    >>> testola.TestXmlRead()
 
-</div>
 
 The screen shot below illustrates the process on the Windows version of Gimp / Python Console (TestXmlGen is 
pictured, TestXmlRead produces several pages of output):
 
-<div class="caption">![Appendix-testing-in-python-console.JPG](Appendix-testing-in-python-console.JPG)  
-<span>Image - Running your code in the Gimp Python Console</span></div>
+<figure>
+<img src="Appendix-testing-in-python-console.JPG" alt="Appendix-testing-in-python-console.JPG" />
+<figcaption>
+Image - Running your code in the Gimp Python Console
+</figcaption>
+</figure>
 
 ## Further Reading
 
 *   [Automated JPG to XCF](../AutomatedJpgToXcf)
 
-<div style="text-align: left;">[![Creative Commons 
License](http://i.creativecommons.org/l/by-sa/3.0/80x15.png)](http://creativecommons.org/licenses/by-sa/3.0/deed.en_US)
  
-<span xmlns:dct="http://purl.org/dc/terms/";>GIMP Tutorial - Luminosity Masks (text)</span> by <a 
rel="cc:attributionURL" xmlns:cc="http://creativecommons.org/ns#";>Stephen Kiel</a> is licensed under a 
[Creative Commons Attribution-ShareAlike 3.0 Unported 
License](http://creativecommons.org/licenses/by-sa/3.0/deed.en_US). The code sources in this tutorial are 
licensed by Stephen Kiel under the conditions of the [GNU Public License GPL 
V3](https://www.gnu.org/copyleft/gpl.html).</div>
-
+<a href="http://creativecommons.org/licenses/by-sa/3.0/deed.en_US"; rel="license"><img alt="Creative Commons 
License" src="http://i.creativecommons.org/l/by-sa/3.0/80x15.png"; style="border-width:0"></a><br><span 
xmlns:dct="http://purl.org/dc/terms/";>GIMP Tutorial - Automate Editing</span> by <a rel="cc:attributionURL" 
xmlns:cc="http://creativecommons.org/ns#";>Stephen Kiel</a> is licensed under a <a 
href="http://creativecommons.org/licenses/by-sa/3.0/deed.en_US"; rel="license">Creative Commons 
Attribution-ShareAlike 3.0 Unported License</a>. The code sources in this tutorial are licensed by Stephen 
Kiel under the conditions of the <a href="https://www.gnu.org/copyleft/gpl.html";>GNU Public License GPL 
V3</a>.
diff --git a/content/tutorials/AutomatedJpgToXcf/example-jpeg-to-xcf.py 
b/content/tutorials/AutomatedJpgToXcf/example-jpeg-to-xcf.py
new file mode 100644
index 0000000..1a93a8c
--- /dev/null
+++ b/content/tutorials/AutomatedJpgToXcf/example-jpeg-to-xcf.py
@@ -0,0 +1,81 @@
+#! /usr/bin/env python
+#
+#   File = example-jpeg-to-xcf.py
+#
+#   This program is free software: you can redistribute it and/or modify
+#   it under the terms of the GNU General Public License as published by
+#   the Free Software Foundation; either version 3 of the License, or
+#   (at your option) any later version.
+#
+#   This program is distributed in the hope that it will be useful,
+#   but WITHOUT ANY WARRANTY; without even the implied warranty of
+#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#   GNU General Public License for more details.
+#
+#   You should have received a copy of the GNU General Public License
+#   along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+############################################################################
+#
+from gimpfu import *
+import os
+import re
+#
+def exampleJpgToXcf(srcPath, tgtPath):
+    """Registered function exampleJpgToXcf, Converts all of the
+    jpegs in the source directory into xcf files in a target 
+    directory.  Requires two arguments, the paths to the source and
+    target directories.  DOES NOT require an image to be open.
+    """
+    ###
+    open_images, image_ids = pdb.gimp_image_list()
+    if open_images > 0:
+        pdb.gimp_message ("Close open Images & Rerun")
+    else:
+        # list all of the files in source & target directories
+        allFileList = os.listdir(srcPath)
+        existingList = os.listdir(tgtPath)
+        srcFileList = []
+        tgtFileList = []
+        xform = re.compile('\.jpg', re.IGNORECASE)
+        # Find all of the jpeg files in the list & make xcf file names
+        for fname in allFileList:
+            fnameLow = fname.lower()
+            if fnameLow.count('.jpg') > 0:
+                srcFileList.append(fname)
+                tgtFileList.append(xform.sub('.xcf',fname))
+        # Dictionary - source & target file names
+        tgtFileDict = dict(zip(srcFileList, tgtFileList))
+        # Loop on jpegs, open each & save as xcf
+        for srcFile in srcFileList:
+            # Don't overwrite existing, might be work in Progress
+            if tgtFileDict[srcFile] not in existingList:
+                # os.path.join inserts the right kind of file separator
+                tgtFile = os.path.join(tgtPath, tgtFileDict[srcFile])
+                srcFile = os.path.join(srcPath, srcFile)
+                theImage = pdb.file_jpeg_load(srcFile, srcFile)
+                theDrawable = theImage.active_drawable
+                pdb.gimp_xcf_save(0, theImage, theDrawable, tgtFile, tgtFile)
+                pdb.gimp_image_delete(theImage)
+#
+############################################################################
+#
+register (
+    "exampleJpgToXcf",         # Name registered in Procedure Browser
+    "Convert jpg files to xcf", # Widget title
+    "Convert jpg files to xcf", # 
+    "Stephen Kiel",         # Author
+    "Stephen Kiel",         # Copyright Holder
+    "July 2013",            # Date
+    "1) Import JPG to XCF (Directory)", # Menu Entry
+    "",     # Image Type - No image required
+    [
+    ( PF_DIRNAME, "srcPath", "JPG Originals (source) Directory:", "" ),
+    ( PF_DIRNAME, "tgtPath", "XCF Working (target) Directory:", "" ),
+    ],
+    [],
+    exampleJpgToXcf,   # Matches to name of function being defined
+    menu = "<Image>/Example-Py"  # Menu Location
+    )   # End register
+
+main()
diff --git a/content/tutorials/AutomatedJpgToXcf/gimp_jpg_to_xcf_popup.jpg 
b/content/tutorials/AutomatedJpgToXcf/gimp_jpg_to_xcf_popup.jpg
new file mode 100644
index 0000000..953d3f8
Binary files /dev/null and b/content/tutorials/AutomatedJpgToXcf/gimp_jpg_to_xcf_popup.jpg differ
diff --git a/content/tutorials/AutomatedJpgToXcf/gimp_menu_compare.jpg 
b/content/tutorials/AutomatedJpgToXcf/gimp_menu_compare.jpg
new file mode 100644
index 0000000..8546c7e
Binary files /dev/null and b/content/tutorials/AutomatedJpgToXcf/gimp_menu_compare.jpg differ
diff --git a/content/tutorials/AutomatedJpgToXcf/index.md b/content/tutorials/AutomatedJpgToXcf/index.md
new file mode 100644
index 0000000..3e974b2
--- /dev/null
+++ b/content/tutorials/AutomatedJpgToXcf/index.md
@@ -0,0 +1,355 @@
+Title: Automatic Creation of XCF from JPG
+Date: 2015-08-18T12:24:32-05:00
+Modified: 2015-08-18T12:24:36-05:00
+Author: Stephen Kiel
+
+<small>
+[![Creative Commons 
License](http://i.creativecommons.org/l/by-sa/3.0/80x15.png)](http://creativecommons.org/licenses/by-sa/3.0/deed.en_US)
  
+<span xmlns:dct="http://purl.org/dc/terms/";>GIMP Tutorial - Automated Jpeg to XCF (text & images)</span> by 
<a rel="cc:attributionURL" xmlns:cc="http://creativecommons.org/ns#";>Stephen Kiel</a>   
+is licensed under a [Creative Commons Attribution-ShareAlike 3.0 Unported 
License](http://creativecommons.org/licenses/by-sa/3.0/deed.en_US). The code sources in this tutorial are 
licensed by Stephen Kiel under the conditions of the [GNU](http://www.gnu.org/) Public License GPL V3.
+</small>
+
+## Motivation
+
+<figure>
+<img src="gimp_jpg_to_xcf_popup.jpg" alt="gimp_jpg_to_xcf_popup.jpg" />
+</figure>
+
+While it is easy to do, opening a Jpeg file and saving it in the native GIMP \*.xcf format is tedious and 
time consuming. You may also want to perform the same operation, like setting the grid spacing as an example, 
on all of the images that you import as part of the process. Automating the parts of the editing process that 
are the same for each image saves time, produces consistent results, and allows you to focus your attention 
on the part of the image editing process that really needs your attention.
+
+This tutorial is a scripting example that is intended to illustrate automating part of the editing process. 
The script opens all of the Jpeg images in the source directory, and saves them as xcf files in the target 
directory. This is not a basic scripting tutorial, a basic understanding of writing GIMP scripts is assumed.
+
+## Requirements that are different than most scripts.
+
+1.  The script needs to be available and run when there is no image open.
+2.  The script has to be able to provide a GUI to identify the Source and Target directories, identify all 
of jpg files in the source directory and convert them.
+3.  The script needs to be aware of the type of operating system of the host machine, or more specifically 
whether the filename separator is a "\" or a "/".
+4.  The script has to be smart enough to not overwrite work in progress, (Xcf files with the same name in 
the target directory).
+
+Let's look at the **first requirement**, to be able to run the script without an open image. We are working 
on a group of several images not just one, and since we want to start our script from a know point, we don't 
want to have an image open for edit, just the GIMP framework or application.
+
+The availability of a script from within the GIMP application is established and controlled within the 
script-fu-register block. After the function name are an ordered set of strings of required information 
followed by an optional number of GUI widget declarations that may feed selected information to the script. 
The required strings are:
+
+1.  _Function Name_ - Matches the name of the function in the opening 'define' statement.
+2.  _Menu Label_ - The label identifying the function in the menus and the way to invoke the script.
+3.  _Description_ - The description that will be displayed about the script in the Procedure Browser.
+4.  _Author_ - Name of the Author
+5.  _Copyright_ - Copyright information.
+6.  _Creation Date_ - Date you wrote the script.
+7.  _**Valid Image Type**_ - The type of image the script is permitted to work upon.
+
+The content of the _Valid Image Type_ is the way that we specify whether we can run the script without an 
image open. You might be tempted to use an image type of "\*" to specify running all of the time, but that is 
not quite what it does. The "Valid Image Type" is a way to restrict the script from running in an unintended 
context, "\*" is the way to specify "any open image". What we want instead is an **empty string - ""** - to 
specify running without an image open. The registration block for the script-fu version of the program would 
look like (the Python registration block follows a similar pattern):
+
+#### Registration Block
+
+    :::scheme
+    ( script-fu-register "script-fu-example-jpg-to-xcf" ; Function Name
+       "1 ) Import JPG to XCF (Directory)"    ; Menu Label
+       "This script is an interactive script to convert all of the jpegs 
+       in a source directory into GIMP xcf format files in a target 
+       directory.  The script is designed to be run WITHOUT ANY IMAGE 
+       LOADED. Runs from GIMP shell in Linux and Windows."
+       "Stephen Kiel"       ; Author
+       "2013, Stephen Kiel" ; Copyright
+       "July 2013"          ; Creation Date
+       **""                   ; Valid Image Type - No Image required**
+        ; We actually don't want any images open when we run this
+        ;   script, so it must be available from the menu when an
+        ;   image is not loaded.  This script will determine the IDs
+        ;   of the Image and Drawable itself rather than having them
+        ;   passed as parameters.
+       ; Interactive widgets
+       SF-DIRNAME "JPG Originals (source) Directory" ""
+       SF-DIRNAME "XCF Working   (target) Directory" ""
+    ) ; End script-fu-register
+    ( script-fu-menu-register 
+       "script-fu-example-jpg-to-xcf" "<Image>/Example-Scm")
+
+The image below shows menu items with and without an image loaded. The menu items numbered 1 & 2 have image 
type = **""**. The items numbered 3 & 4 have image type = **"*"**.
+
+
+#### Function Menus
+
+<figure>
+<img src="gimp_menu_compare.jpg" alt="Menu Compare - Image types" />
+</figure>
+
+Our **second requirement**, to be able to use the GUI to browse to our Jpeg source file directory and our 
Xcf target file directory is handled first in the registration block by using the "**SF-DIRNAME**" widgets to 
label the GUI selection fields and pass the collected results as inputs to the script (above). Once we have 
the path names to our source and target directories we will use the "**file-glob**" (os.listdir in python-fu) 
function within the main program to create a list of all of the image files in those directories.
+
+We address the **third requirement** of determining the operating system type within the function itself. We 
want the function to be portable, so it can run on either the Linux desktop unit you have in your home, or 
the Windows laptop you carry out on the road. We need to know the OS type in order to determine the pathname 
separator, either a "\" or "/" and deal with it in the script.
+
+Fortunately once we have the pathname to the source directory it is easy to determine which operating system 
generated it by using the script-fu "**strbreakup**" function. We can compare the number of pieces by 
breaking on the "/" and "\" character and use the result with the greater number of pieces to determine the 
platform's operating system. If we are using the python-fu scripting language we can check the value of 
os.name directly.
+
+
+#### Script-fu file-glob and strbreakup
+
+    :::scheme
+     ( isLinux (  >  
+        ( length ( strbreakup sourceDirectory "/" ) )
+        ( length ( strbreakup sourceDirectory "\\" ) ) ) )
+     ; Form path/file patternSource based on OS 
+     ( patternSource ( if isLinux
+        ( string-append sourceDirectory "/*.[jJ][pP][gG]" )
+        ( string-append sourceDirectory "\\*.[jJ][pP][gG]" ) ) )
+     ( patternTarget ( if isLinux
+        ( string-append targetDirectory "/*.[xX][cC][fF]" )
+        ( string-append targetDirectory "\\*.[xX][cC][fF]" ) ) )
+     ; List of files to be converted formatted for current Host
+     ; O/S
+     ( filelistSource ( cadr ( file-glob patternSource 1 ) ) )
+     ( filelistExists ( cadr ( file-glob patternTarget 1 ) ) )
+
+Our **fourth requirement** to not overwrite existing \*.xcf files which may have ongoing work in progress is 
solved by building a list of files in the target directory and checking that list for existence before 
writing each new file.
+
+## Conclusion
+
+The working example script is pretty straightforward; building a list of file names, running through that 
list in a loop, opening each source file and exporting it in turn. An equivalent python-fu version is 
included as well. You should be able to use this example as a model to build similar functions, examples of 
similar functions might be to convert a directory of xcf files to jpg files, to scale original jpg files to a 
smaller size, etc.
+
+When using the GIMP widgets to Browse through the file system, you will probably need to select "Other" to 
get to navigate where you really want. When using an automated script it is **ALWAYS** a good idea to run on 
a **COPY** of your original images.
+
+## The Scripts
+
+The following scripts are the _script-fu_ and _python-fu_ versions of the Jpg to Xcf function discussed 
above.
+
+*   [script-fu-example-jpg-to-xcf.scm](script-fu-example-jpg-to-xcf.scm)
+*   [example-jpeg-to-xcf.py](example-jpeg-to-xcf.py)
+
+### script-fu-example-jpg-to-xcf.scm
+
+    :::scheme
+    ;   File = example-jpeg-to-xcf.py
+    ;
+    ;   This program is free software: you can redistribute it and/or modify
+    ;   it under the terms of the GNU General Public License as published by
+    ;   the Free Software Foundation; either version 3 of the License, or
+    ;   (at your option) any later version.
+    ;
+    ;   This program is distributed in the hope that it will be useful,
+    ;   but WITHOUT ANY WARRANTY; without even the implied warranty of
+    ;   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    ;   GNU General Public License for more details.
+    ;
+    ;   You should have received a copy of the GNU General Public License
+    ;   along with this program.  If not, see <http://www.gnu.org/licenses/>.
+    ;
+    ;=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+    ;;;  Function - script-fu-example-jpg-to-xcf
+    ;;;
+    ;;;  Converts all jpeg images in selected directory to GIMP xcf
+    ;;;  format.
+    ;;;
+    ;;;  Filename Case insensitive. (converts xyz.jpg or XYZ.JPG)
+    ;;;
+    ;;;  Interactive program to be run WITHOUT AN IMAGE LOADED.
+    ;;;
+    ;;;  Program prompts for a source (jpgs) and target (xcfs)
+    ;;;  directories.
+    ;;;
+    ;;;  Program runs on either Linux or Windows Host O/S, using the
+    ;;;  appropriate path - filename separator ( "/" or "\").
+    ;;;
+    ;=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+    ( define ( script-fu-example-jpg-to-xcf 
+       sourceDirectory targetDirectory )
+       ( let*
+          (
+             ; Declare and Init local variables
+             ( returnVal #f )
+             ; Guess host OS based on directory path separator
+             ( isLinux (  >  
+                ( length ( strbreakup sourceDirectory "/" ) )
+                ( length ( strbreakup sourceDirectory "\\" ) ) ) )
+             ; Form path/file patternSource based on OS 
+             ( patternSource ( if isLinux
+                ( string-append sourceDirectory "/*.[jJ][pP][gG]" )
+                ( string-append sourceDirectory "\\*.[jJ][pP][gG]" ) ) )
+             ( patternTarget ( if isLinux
+                ( string-append targetDirectory "/*.[xX][cC][fF]" )
+                ( string-append targetDirectory "\\*.[xX][cC][fF]" ) ) )
+             ; List of files to be converted formatted for current Host
+             ; O/S
+             ( filelistSource ( cadr ( file-glob patternSource 1 ) ) )
+             ( filelistExists ( cadr ( file-glob patternTarget 1 ) ) )
+             ( checkFileExists filelistExists )
+             ; Place holders for image variables - updated per image
+             ( theImage 0 )
+             ( theDrawable 0 )
+             ( currentFile "" )
+             ( baseName "" )
+             ( outFilename "" )
+             ; Constants used to assign values to parasites on new image
+             ( doIt #t )
+             ( checkFile "" )
+          ) ; End declaration of Local Variables
+          ;
+          ; Run if images closed, message if not.
+          ( if ( < 0 ( car ( gimp-image-list ) ) )
+             ( gimp-message "Close open Images & Rerun" )
+             ( begin
+                ;
+                ; Run within scope of let* and local variables
+                ; 'baseName' is filename without .jpg extension
+                ; 'outFilename' is filename with .xcf extension
+                ; Step through each file in list with while loop.
+                ( while ( not ( null? filelistSource ) )
+                   ( set! doIt #t )
+                   ( set! checkFileExists filelistExists )
+                   ( set! currentFile ( car filelistSource ) )
+                   ; Get open and get Image ID of current file
+                   ( set! theImage
+                      ( car ( gimp-file-load RUN-NONINTERACTIVE 
+                         currentFile currentFile ) ) )
+                   ( if isLinux
+                      ; Target path-filename if Host OS is Linux
+                      ( begin 
+                         ( set! baseName ( car ( reverse
+                            ( strbreakup currentFile "/" ) ) ) )
+                         ( set! baseName ( car ( strbreakup baseName "." ) ) )
+                         ( set! outFilename ( string-append
+                               targetDirectory "/" baseName ".xcf" ) )
+                      ) ; End begin - Host OS is Linux
+                      ; Target path-filename if Host OS is Windows
+                      ( begin 
+                         ( set! baseName ( car ( reverse
+                            ( strbreakup currentFile "\\" ) ) ) )
+                         ( set! baseName ( car ( strbreakup baseName "." ) ) )
+                         ( set! outFilename ( string-append
+                               targetDirectory "\\" baseName ".xcf" ) )
+                      ) ; End begin - if Host OS is Windows
+                   ) ; End if isLinux
+                   ; Check to see if outFilename exists so we don't overwrite
+                   ( while ( not ( null? checkFileExists ) )
+                      ( set! checkFile ( car checkFileExists ) )
+                      ( if ( string=? outFilename checkFile )
+                         ( set! doIt #f ) )
+                      (set! checkFileExists ( cdr checkFileExists ) )
+                   ) ; End while checkFileExists
+                   ( if doIt
+                      ( begin
+                         ; Get / set Drawable ID, need it for file save.
+                         ( set! theDrawable ( car 
+                            ( gimp-image-merge-visible-layers theImage 0 ) ) )
+                         ; Save file - GIMP xcf format
+                         ( gimp-xcf-save 
+                            RUN-NONINTERACTIVE theImage theDrawable
+                            outFilename outFilename )
+                      ) ; End begin
+                   ) ; End if doIt
+                   ( gimp-image-delete theImage )
+                   ; Update while loop iteration parameter
+                   (set! filelistSource ( cdr filelistSource ) )
+                ) ; End while
+             ); End outer begin
+          ) ; End outer if
+          ( set! returnVal #t )
+       ) ; End let*
+    ) ; End define
+    ;=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+    ( script-fu-register "script-fu-example-jpg-to-xcf" ; Function Name
+       "1 ) Import JPG to XCF (Directory)"    ; Menu Label
+       "This script is an interactive script to convert all of the jpegs 
+       in a source directory into GIMP xcf format files in a target 
+       directory.  The script is designed to be run WITHOUT ANY IMAGE 
+       LOADED. Runs from GIMP shell in Linux and Windows."
+       "Stephen Kiel"       ; Author
+       "2013, Stephen Kiel" ; Copyright
+       "July 2013"          ; Creation Date
+       ""                   ; Valid Image Type - No Image required
+        ; We actually don't want any images open when we run this
+        ;   script, so it must be available from the menu when an
+        ;   image is not loaded.  This script will determine the IDs
+        ;   of the Image and Drawable itself rather than having them
+        ;   passed as parameters.
+       ; Interactive widgets
+       SF-DIRNAME "JPG Originals (source) Directory" ""
+       SF-DIRNAME "XCF Working   (target) Directory" ""
+    ) ; End script-fu-register
+    ( script-fu-menu-register 
+       "script-fu-example-jpg-to-xcf" "<Image>/Example-Scm")
+    ;=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+### example-jpeg-to-xcf.py
+
+    :::python
+    #! /usr/bin/env python
+    #
+    #   File = example-jpeg-to-xcf.py
+    #
+    #   This program is free software: you can redistribute it and/or modify
+    #   it under the terms of the GNU General Public License as published by
+    #   the Free Software Foundation; either version 3 of the License, or
+    #   (at your option) any later version.
+    #
+    #   This program is distributed in the hope that it will be useful,
+    #   but WITHOUT ANY WARRANTY; without even the implied warranty of
+    #   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    #   GNU General Public License for more details.
+    #
+    #   You should have received a copy of the GNU General Public License
+    #   along with this program.  If not, see <http://www.gnu.org/licenses/>.
+    #
+    ############################################################################
+    #
+    from gimpfu import *
+    import os
+    import re
+    #
+    def exampleJpgToXcf(srcPath, tgtPath):
+        """Registered function exampleJpgToXcf, Converts all of the
+        jpegs in the source directory into xcf files in a target 
+        directory.  Requires two arguments, the paths to the source and
+        target directories.  DOES NOT require an image to be open.
+        """
+        ###
+        open_images, image_ids = pdb.gimp_image_list()
+        if open_images > 0:
+            pdb.gimp_message ("Close open Images & Rerun")
+        else:
+            # list all of the files in source & target directories
+            allFileList = os.listdir(srcPath)
+            existingList = os.listdir(tgtPath)
+            srcFileList = []
+            tgtFileList = []
+            xform = re.compile('\.jpg', re.IGNORECASE)
+            # Find all of the jpeg files in the list & make xcf file names
+            for fname in allFileList:
+                fnameLow = fname.lower()
+                if fnameLow.count('.jpg') > 0:
+                    srcFileList.append(fname)
+                    tgtFileList.append(xform.sub('.xcf',fname))
+            # Dictionary - source & target file names
+            tgtFileDict = dict(zip(srcFileList, tgtFileList))
+            # Loop on jpegs, open each & save as xcf
+            for srcFile in srcFileList:
+                # Don't overwrite existing, might be work in Progress
+                if tgtFileDict[srcFile] not in existingList:
+                    # os.path.join inserts the right kind of file separator
+                    tgtFile = os.path.join(tgtPath, tgtFileDict[srcFile])
+                    srcFile = os.path.join(srcPath, srcFile)
+                    theImage = pdb.file_jpeg_load(srcFile, srcFile)
+                    theDrawable = theImage.active_drawable
+                    pdb.gimp_xcf_save(0, theImage, theDrawable, tgtFile, tgtFile)
+                    pdb.gimp_image_delete(theImage)
+    #
+    ############################################################################
+    #
+    register (
+        "exampleJpgToXcf",         # Name registered in Procedure Browser
+        "Convert jpg files to xcf", # Widget title
+        "Convert jpg files to xcf", # 
+        "Stephen Kiel",         # Author
+        "Stephen Kiel",         # Copyright Holder
+        "July 2013",            # Date
+        "1) Import JPG to XCF (Directory)", # Menu Entry
+        "",     # Image Type - No image required
+        [
+        ( PF_DIRNAME, "srcPath", "JPG Originals (source) Directory:", "" ),
+        ( PF_DIRNAME, "tgtPath", "XCF Working (target) Directory:", "" ),
+        ],
+        [],
+        exampleJpgToXcf,   # Matches to name of function being defined
+        menu = "<Image>/Example-Py"  # Menu Location
+        )   # End register
+
+    main()
+
diff --git a/content/tutorials/AutomatedJpgToXcf/script-fu-example-jpg-to-xcf.scm 
b/content/tutorials/AutomatedJpgToXcf/script-fu-example-jpg-to-xcf.scm
new file mode 100644
index 0000000..3c94feb
--- /dev/null
+++ b/content/tutorials/AutomatedJpgToXcf/script-fu-example-jpg-to-xcf.scm
@@ -0,0 +1,150 @@
+;   File = example-jpeg-to-xcf.py
+;
+;   This program is free software: you can redistribute it and/or modify
+;   it under the terms of the GNU General Public License as published by
+;   the Free Software Foundation; either version 3 of the License, or
+;   (at your option) any later version.
+;
+;   This program is distributed in the hope that it will be useful,
+;   but WITHOUT ANY WARRANTY; without even the implied warranty of
+;   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;   GNU General Public License for more details.
+;
+;   You should have received a copy of the GNU General Public License
+;   along with this program.  If not, see <http://www.gnu.org/licenses/>.
+;
+;=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+;;;  Function - script-fu-example-jpg-to-xcf
+;;;
+;;;  Converts all jpeg images in selected directory to gimp xcf
+;;;  format.
+;;;
+;;;  Filename Case insensitive. (converts xyz.jpg or XYZ.JPG)
+;;;
+;;;  Interactive program to be run WITHOUT AN IMAGE LOADED.
+;;;
+;;;  Program prompts for a source (jpgs) and target (xcfs)
+;;;  directories.
+;;;
+;;;  Program runs on either Linux or Windows Host O/S, using the
+;;;  appropriate path - filename separator ( "/" or "\").
+;;;
+;=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+( define ( script-fu-example-jpg-to-xcf 
+   sourceDirectory targetDirectory )
+   ( let*
+      (
+         ; Declare and Init local variables
+         ( returnVal #f )
+         ; Guess host OS based on directory path separator
+         ( isLinux (  >  
+            ( length ( strbreakup sourceDirectory "/" ) )
+            ( length ( strbreakup sourceDirectory "\\" ) ) ) )
+         ; Form path/file patternSource based on OS 
+         ( patternSource ( if isLinux
+            ( string-append sourceDirectory "/*.[jJ][pP][gG]" )
+            ( string-append sourceDirectory "\\*.[jJ][pP][gG]" ) ) )
+         ( patternTarget ( if isLinux
+            ( string-append targetDirectory "/*.[xX][cC][fF]" )
+            ( string-append targetDirectory "\\*.[xX][cC][fF]" ) ) )
+         ; List of files to be converted formatted for current Host
+         ; O/S
+         ( filelistSource ( cadr ( file-glob patternSource 1 ) ) )
+         ( filelistExists ( cadr ( file-glob patternTarget 1 ) ) )
+         ( checkFileExists filelistExists )
+         ; Place holders for image variables - updated per image
+         ( theImage 0 )
+         ( theDrawable 0 )
+         ( currentFile "" )
+         ( baseName "" )
+         ( outFilename "" )
+         ; Constants used to assign values to parasites on new image
+         ( doIt #t )
+         ( checkFile "" )
+      ) ; End declaration of Local Variables
+      ;
+      ; Run if images closed, message if not.
+      ( if ( < 0 ( car ( gimp-image-list ) ) )
+         ( gimp-message "Close open Images & Rerun" )
+         ( begin
+            ;
+            ; Run within scope of let* and local variables
+            ; 'baseName' is filename without .jpg extension
+            ; 'outFilename' is filename with .xcf extension
+            ; Step through each file in list with while loop.
+            ( while ( not ( null? filelistSource ) )
+               ( set! doIt #t )
+               ( set! checkFileExists filelistExists )
+               ( set! currentFile ( car filelistSource ) )
+               ; Get open and get Image ID of current file
+               ( set! theImage
+                  ( car ( gimp-file-load RUN-NONINTERACTIVE 
+                     currentFile currentFile ) ) )
+               ( if isLinux
+                  ; Target path-filename if Host OS is Linux
+                  ( begin 
+                     ( set! baseName ( car ( reverse
+                        ( strbreakup currentFile "/" ) ) ) )
+                     ( set! baseName ( car ( strbreakup baseName "." ) ) )
+                     ( set! outFilename ( string-append
+                           targetDirectory "/" baseName ".xcf" ) )
+                  ) ; End begin - Host OS is Linux
+                  ; Target path-filename if Host OS is Windows
+                  ( begin 
+                     ( set! baseName ( car ( reverse
+                        ( strbreakup currentFile "\\" ) ) ) )
+                     ( set! baseName ( car ( strbreakup baseName "." ) ) )
+                     ( set! outFilename ( string-append
+                           targetDirectory "\\" baseName ".xcf" ) )
+                  ) ; End begin - if Host OS is Windows
+               ) ; End if isLinux
+               ; Check to see if outFilename exists so we don't overwrite
+               ( while ( not ( null? checkFileExists ) )
+                  ( set! checkFile ( car checkFileExists ) )
+                  ( if ( string=? outFilename checkFile )
+                     ( set! doIt #f ) )
+                  (set! checkFileExists ( cdr checkFileExists ) )
+               ) ; End while checkFileExists
+               ( if doIt
+                  ( begin
+                     ; Get / set Drawable ID, need it for file save.
+                     ( set! theDrawable ( car 
+                        ( gimp-image-merge-visible-layers theImage 0 ) ) )
+                     ; Save file - gimp xcf format
+                     ( gimp-xcf-save 
+                        RUN-NONINTERACTIVE theImage theDrawable
+                        outFilename outFilename )
+                  ) ; End begin
+               ) ; End if doIt
+               ( gimp-image-delete theImage )
+               ; Update while loop iteration parameter
+               (set! filelistSource ( cdr filelistSource ) )
+            ) ; End while
+         ); End outer begin
+      ) ; End outer if
+      ( set! returnVal #t )
+   ) ; End let*
+) ; End define
+;=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+( script-fu-register "script-fu-example-jpg-to-xcf" ; Function Name
+   "1 ) Import JPG to XCF (Directory)"    ; Menu Label
+   "This script is an interactive script to convert all of the jpegs 
+   in a source directory into Gimp xcf format files in a target 
+   directory.  The script is designed to be run WITHOUT ANY IMAGE 
+   LOADED. Runs from Gimp shell in Linux and Windows."
+   "Stephen Kiel"       ; Author
+   "2013, Stephen Kiel" ; Copyright
+   "July 2013"          ; Creation Date
+   ""                   ; Valid Image Type - No Image required
+    ; We actually don't want any images open when we run this
+    ;   script, so it must be available from the menu when an
+    ;   image is not loaded.  This script will determine the IDs
+    ;   of the Image and Drawable itself rather than having them
+    ;   passed as parameters.
+   ; Interactive widgets
+   SF-DIRNAME "JPG Originals (source) Directory" ""
+   SF-DIRNAME "XCF Working   (target) Directory" ""
+) ; End script-fu-register
+( script-fu-menu-register 
+   "script-fu-example-jpg-to-xcf" "<Image>/Example-Scm")
+;=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
diff --git a/content/tutorials/Basic_Batch/index.md b/content/tutorials/Basic_Batch/index.md
new file mode 100644
index 0000000..f21b08c
--- /dev/null
+++ b/content/tutorials/Basic_Batch/index.md
@@ -0,0 +1,89 @@
+Title: GIMP Batch Mode
+Date: 2015-08-18T12:24:32-05:00
+Modified: 2015-08-18T12:24:36-05:00
+Author: Pat David
+
+
+## Introduction
+
+GIMP comes with a so-called batch mode that allows you to do image processing from the command line. It also 
makes it easy to apply the same set of operations to a number of images. We have got a lot of questions on 
the mailing-lists on how to use the batch mode and this small page tries to explain the basics to you.
+
+GIMP can be started with a number of command-line options. Let's have a closer look at the output of `gimp 
--help`:
+
+    :::bash
+    GIMP version 2.4.1
+
+    Usage: gimp [option ... ] [file ... ]
+
+    Options:
+      -?, --help              Show help options
+      -v, --version           Show version information and exit
+      --verbose               Be more verbose
+      -d, --no-data           Do not load brushes, gradients, palettes, patterns, ...
+      -f, --no-fonts          Do not load any fonts
+      -i, --no-interface      Run without a user interface
+      --batch-interpreter=<procedure>
+                              The procedure to process batch commands with
+      -b, --batch=<commands>  Batch command to run (can be used multiple times)
+      ...
+
+In order to do image processing from the command-line, you usually use the Script-Fu batch interpreter. This 
is the default, which makes things simple. To give you an impression of what can be done, try the interactive 
console mode:
+
+    gimp -b -
+
+This will tell GIMP to start in batch mode and accept commands on the command-line. This is essentially the 
same as using the Script-Fu console. It would however be tedious to enter the commands here, so instead we 
will create a simple script and show you how to run that:
+
+
+## A simple example
+
+    (define (simple-unsharp-mask filename
+                                  radius
+                      amount
+                      threshold)
+       (let* ((image (car (gimp-file-load RUN-NONINTERACTIVE filename filename)))
+              (drawable (car (gimp-image-get-active-layer image))))
+         (plug-in-unsharp-mask RUN-NONINTERACTIVE
+                           image drawable radius amount threshold)
+         (gimp-file-save RUN-NONINTERACTIVE image drawable filename filename)
+         (gimp-image-delete image)))
+
+This simple script takes a filename and some numeric parameters. It opens the respective file, applies the 
Unsharp Mask filter and saves the image again (be careful, for the sake of simplicity this script overwrites 
the original image). It does all this w/o any user interaction, so we can run it without any user interface. 
In order to do that, save the script with the .scm extension in the **~/.gimp-2.4/scripts** directory. Then 
run it like this:
+
+    gimp -i -b '(simple-unsharp-mask "foo.png" 5.0 0.5 0)' -b '(gimp-quit 0)'
+
+
+There is a catch here: Some plugins or Script-Fu scripts create new layers and then flatten the image again. 
This changes the drawable ID. If this is the case insert the following line to get the current drawable ID 
just before saving the image:
+
+    (set! drawable (car (gimp-image-get-active-layer image)))
+
+
+
+## Processing several files
+
+You might want to apply an effect to a number of files, typically to a set of files in the same directory. 
GIMP 2.2 added a very useful function for this purpose, the **file-glob** plug-in. This turns GIMP into a 
versatile batch processor. In order to use it, we will need to do some modifications to our script:
+
+      (define (batch-unsharp-mask pattern
+                                  radius
+                                  amount
+                                  threshold)
+      (let* ((filelist (cadr (file-glob pattern 1))))
+        (while (not (null? filelist))
+               (let* ((filename (car filelist))
+                      (image (car (gimp-file-load RUN-NONINTERACTIVE
+                                                  filename filename)))
+                      (drawable (car (gimp-image-get-active-layer image))))
+                 (plug-in-unsharp-mask RUN-NONINTERACTIVE
+                                       image drawable radius amount threshold)
+                 (gimp-file-save RUN-NONINTERACTIVE
+                                 image drawable filename filename)
+                 (gimp-image-delete image))
+               (set! filelist (cdr filelist)))))
+
+This version of the script takes a glob pattern instead of a filename and will apply the Unsharp Mask filter 
to all files matching this pattern. In order to sharpen all PNG images in the current directory, you would 
run the following command:
+
+    gimp -i -b '(batch-unsharp-mask "*.png" 5.0 0.5 0)' -b '(gimp-quit 0)'
+
+## Further information
+
+If you want to write your own scripts for batch processing, we suggest you use the **Procedure Browser** as 
found in the **Help** menu. It gives you a detailed list of all commands.
+
diff --git a/content/tutorials/Basic_Color_Curves/Color_circle_%28hue-sat%29_trans.png 
b/content/tutorials/Basic_Color_Curves/Color_circle_%28hue-sat%29_trans.png
new file mode 100644
index 0000000..fb62de9
Binary files /dev/null and b/content/tutorials/Basic_Color_Curves/Color_circle_%28hue-sat%29_trans.png differ
diff --git a/content/tutorials/Basic_Color_Curves/Kuler_orange_teal.jpg 
b/content/tutorials/Basic_Color_Curves/Kuler_orange_teal.jpg
new file mode 100644
index 0000000..4a00879
Binary files /dev/null and b/content/tutorials/Basic_Color_Curves/Kuler_orange_teal.jpg differ
diff --git a/content/tutorials/Basic_Color_Curves/curves-dialog-darks-blue-boost-add-yellow.png 
b/content/tutorials/Basic_Color_Curves/curves-dialog-darks-blue-boost-add-yellow.png
new file mode 100644
index 0000000..7d57b80
Binary files /dev/null and 
b/content/tutorials/Basic_Color_Curves/curves-dialog-darks-blue-boost-add-yellow.png differ
diff --git a/content/tutorials/Basic_Color_Curves/curves-dialog-darks-blue-boost.png 
b/content/tutorials/Basic_Color_Curves/curves-dialog-darks-blue-boost.png
new file mode 100644
index 0000000..79e4a9e
Binary files /dev/null and b/content/tutorials/Basic_Color_Curves/curves-dialog-darks-blue-boost.png differ
diff --git a/content/tutorials/Basic_Color_Curves/curves-dialog-darks-green-suppress.png 
b/content/tutorials/Basic_Color_Curves/curves-dialog-darks-green-suppress.png
new file mode 100644
index 0000000..9619a8d
Binary files /dev/null and b/content/tutorials/Basic_Color_Curves/curves-dialog-darks-green-suppress.png 
differ
diff --git a/content/tutorials/Basic_Color_Curves/curves-dialog-darksmidslights.png 
b/content/tutorials/Basic_Color_Curves/curves-dialog-darksmidslights.png
new file mode 100644
index 0000000..3a940b1
Binary files /dev/null and b/content/tutorials/Basic_Color_Curves/curves-dialog-darksmidslights.png differ
diff --git a/content/tutorials/Basic_Color_Curves/curves-dialog-midtones.png 
b/content/tutorials/Basic_Color_Curves/curves-dialog-midtones.png
new file mode 100644
index 0000000..be075c0
Binary files /dev/null and b/content/tutorials/Basic_Color_Curves/curves-dialog-midtones.png differ
diff --git a/content/tutorials/Basic_Color_Curves/curves-dialog-orangeteal-blue-high.png 
b/content/tutorials/Basic_Color_Curves/curves-dialog-orangeteal-blue-high.png
new file mode 100644
index 0000000..8f26d46
Binary files /dev/null and b/content/tutorials/Basic_Color_Curves/curves-dialog-orangeteal-blue-high.png 
differ
diff --git a/content/tutorials/Basic_Color_Curves/curves-dialog-orangeteal-blue-low.png 
b/content/tutorials/Basic_Color_Curves/curves-dialog-orangeteal-blue-low.png
new file mode 100644
index 0000000..c6f3465
Binary files /dev/null and b/content/tutorials/Basic_Color_Curves/curves-dialog-orangeteal-blue-low.png differ
diff --git a/content/tutorials/Basic_Color_Curves/curves-dialog-orangeteal-green-high.png 
b/content/tutorials/Basic_Color_Curves/curves-dialog-orangeteal-green-high.png
new file mode 100644
index 0000000..3218e98
Binary files /dev/null and b/content/tutorials/Basic_Color_Curves/curves-dialog-orangeteal-green-high.png 
differ
diff --git a/content/tutorials/Basic_Color_Curves/curves-dialog-orangeteal-green-low.png 
b/content/tutorials/Basic_Color_Curves/curves-dialog-orangeteal-green-low.png
new file mode 100644
index 0000000..1704839
Binary files /dev/null and b/content/tutorials/Basic_Color_Curves/curves-dialog-orangeteal-green-low.png 
differ
diff --git a/content/tutorials/Basic_Color_Curves/curves-dialog-orangeteal-red-high.png 
b/content/tutorials/Basic_Color_Curves/curves-dialog-orangeteal-red-high.png
new file mode 100644
index 0000000..964e85c
Binary files /dev/null and b/content/tutorials/Basic_Color_Curves/curves-dialog-orangeteal-red-high.png differ
diff --git a/content/tutorials/Basic_Color_Curves/curves-dialog-orangeteal-red-low.png 
b/content/tutorials/Basic_Color_Curves/curves-dialog-orangeteal-red-low.png
new file mode 100644
index 0000000..fbd78c3
Binary files /dev/null and b/content/tutorials/Basic_Color_Curves/curves-dialog-orangeteal-red-low.png differ
diff --git a/content/tutorials/Basic_Color_Curves/curves-dialog-orangeteal-value-final.png 
b/content/tutorials/Basic_Color_Curves/curves-dialog-orangeteal-value-final.png
new file mode 100644
index 0000000..084ded0
Binary files /dev/null and b/content/tutorials/Basic_Color_Curves/curves-dialog-orangeteal-value-final.png 
differ
diff --git a/content/tutorials/Basic_Color_Curves/curves-dialog-original-IO.png 
b/content/tutorials/Basic_Color_Curves/curves-dialog-original-IO.png
new file mode 100644
index 0000000..2154454
Binary files /dev/null and b/content/tutorials/Basic_Color_Curves/curves-dialog-original-IO.png differ
diff --git a/content/tutorials/Basic_Color_Curves/curves-dialog-original.png 
b/content/tutorials/Basic_Color_Curves/curves-dialog-original.png
new file mode 100644
index 0000000..4362cdf
Binary files /dev/null and b/content/tutorials/Basic_Color_Curves/curves-dialog-original.png differ
diff --git a/content/tutorials/Basic_Color_Curves/curves-dialog-slight-s.png 
b/content/tutorials/Basic_Color_Curves/curves-dialog-slight-s.png
new file mode 100644
index 0000000..946b89e
Binary files /dev/null and b/content/tutorials/Basic_Color_Curves/curves-dialog-slight-s.png differ
diff --git a/content/tutorials/Basic_Color_Curves/curves-dialog-value-rgb-select.png 
b/content/tutorials/Basic_Color_Curves/curves-dialog-value-rgb-select.png
new file mode 100644
index 0000000..03f48bc
Binary files /dev/null and b/content/tutorials/Basic_Color_Curves/curves-dialog-value-rgb-select.png differ
diff --git a/content/tutorials/Basic_Color_Curves/curves-house-square-full.jpg 
b/content/tutorials/Basic_Color_Curves/curves-house-square-full.jpg
new file mode 100644
index 0000000..5b2b9d1
Binary files /dev/null and b/content/tutorials/Basic_Color_Curves/curves-house-square-full.jpg differ
diff --git a/content/tutorials/Basic_Color_Curves/curves-house-square-zoom-1.jpg 
b/content/tutorials/Basic_Color_Curves/curves-house-square-zoom-1.jpg
new file mode 100644
index 0000000..70e4b4b
Binary files /dev/null and b/content/tutorials/Basic_Color_Curves/curves-house-square-zoom-1.jpg differ
diff --git a/content/tutorials/Basic_Color_Curves/curves-house-square-zoom-2.jpg 
b/content/tutorials/Basic_Color_Curves/curves-house-square-zoom-2.jpg
new file mode 100644
index 0000000..b814fda
Binary files /dev/null and b/content/tutorials/Basic_Color_Curves/curves-house-square-zoom-2.jpg differ
diff --git a/content/tutorials/Basic_Color_Curves/curves-house-square-zoom-3.png 
b/content/tutorials/Basic_Color_Curves/curves-house-square-zoom-3.png
new file mode 100644
index 0000000..09a85e8
Binary files /dev/null and b/content/tutorials/Basic_Color_Curves/curves-house-square-zoom-3.png differ
diff --git a/content/tutorials/Basic_Color_Curves/curves-your-pixel-info.png 
b/content/tutorials/Basic_Color_Curves/curves-your-pixel-info.png
new file mode 100644
index 0000000..4b3d9a9
Binary files /dev/null and b/content/tutorials/Basic_Color_Curves/curves-your-pixel-info.png differ
diff --git a/content/tutorials/Basic_Color_Curves/flickr-qsimple-5636649561-dark-blue-boost-add-yellow.jpg 
b/content/tutorials/Basic_Color_Curves/flickr-qsimple-5636649561-dark-blue-boost-add-yellow.jpg
new file mode 100644
index 0000000..f672bf6
Binary files /dev/null and 
b/content/tutorials/Basic_Color_Curves/flickr-qsimple-5636649561-dark-blue-boost-add-yellow.jpg differ
diff --git a/content/tutorials/Basic_Color_Curves/flickr-qsimple-5636649561-dark-blue-boost.jpg 
b/content/tutorials/Basic_Color_Curves/flickr-qsimple-5636649561-dark-blue-boost.jpg
new file mode 100644
index 0000000..bc30b4d
Binary files /dev/null and 
b/content/tutorials/Basic_Color_Curves/flickr-qsimple-5636649561-dark-blue-boost.jpg differ
diff --git a/content/tutorials/Basic_Color_Curves/flickr-qsimple-5636649561-dark-green-suppresst.jpg 
b/content/tutorials/Basic_Color_Curves/flickr-qsimple-5636649561-dark-green-suppresst.jpg
new file mode 100644
index 0000000..a526b06
Binary files /dev/null and 
b/content/tutorials/Basic_Color_Curves/flickr-qsimple-5636649561-dark-green-suppresst.jpg differ
diff --git a/content/tutorials/Basic_Color_Curves/flickr-qsimple-5636649561-mid-boostl.jpg 
b/content/tutorials/Basic_Color_Curves/flickr-qsimple-5636649561-mid-boostl.jpg
new file mode 100644
index 0000000..132e9b3
Binary files /dev/null and b/content/tutorials/Basic_Color_Curves/flickr-qsimple-5636649561-mid-boostl.jpg 
differ
diff --git a/content/tutorials/Basic_Color_Curves/flickr-qsimple-5636649561-orangeteal-blue-highs.jpg 
b/content/tutorials/Basic_Color_Curves/flickr-qsimple-5636649561-orangeteal-blue-highs.jpg
new file mode 100644
index 0000000..53789ea
Binary files /dev/null and 
b/content/tutorials/Basic_Color_Curves/flickr-qsimple-5636649561-orangeteal-blue-highs.jpg differ
diff --git a/content/tutorials/Basic_Color_Curves/flickr-qsimple-5636649561-orangeteal-blue-lows.jpg 
b/content/tutorials/Basic_Color_Curves/flickr-qsimple-5636649561-orangeteal-blue-lows.jpg
new file mode 100644
index 0000000..21bff26
Binary files /dev/null and 
b/content/tutorials/Basic_Color_Curves/flickr-qsimple-5636649561-orangeteal-blue-lows.jpg differ
diff --git a/content/tutorials/Basic_Color_Curves/flickr-qsimple-5636649561-orangeteal-green-highs.jpg 
b/content/tutorials/Basic_Color_Curves/flickr-qsimple-5636649561-orangeteal-green-highs.jpg
new file mode 100644
index 0000000..36ac461
Binary files /dev/null and 
b/content/tutorials/Basic_Color_Curves/flickr-qsimple-5636649561-orangeteal-green-highs.jpg differ
diff --git a/content/tutorials/Basic_Color_Curves/flickr-qsimple-5636649561-orangeteal-green-lows.jpg 
b/content/tutorials/Basic_Color_Curves/flickr-qsimple-5636649561-orangeteal-green-lows.jpg
new file mode 100644
index 0000000..76e8b19
Binary files /dev/null and 
b/content/tutorials/Basic_Color_Curves/flickr-qsimple-5636649561-orangeteal-green-lows.jpg differ
diff --git a/content/tutorials/Basic_Color_Curves/flickr-qsimple-5636649561-orangeteal-red-highs.jpg 
b/content/tutorials/Basic_Color_Curves/flickr-qsimple-5636649561-orangeteal-red-highs.jpg
new file mode 100644
index 0000000..f2d389b
Binary files /dev/null and 
b/content/tutorials/Basic_Color_Curves/flickr-qsimple-5636649561-orangeteal-red-highs.jpg differ
diff --git a/content/tutorials/Basic_Color_Curves/flickr-qsimple-5636649561-orangeteal-red-lows.jpg 
b/content/tutorials/Basic_Color_Curves/flickr-qsimple-5636649561-orangeteal-red-lows.jpg
new file mode 100644
index 0000000..cb3d469
Binary files /dev/null and 
b/content/tutorials/Basic_Color_Curves/flickr-qsimple-5636649561-orangeteal-red-lows.jpg differ
diff --git a/content/tutorials/Basic_Color_Curves/flickr-qsimple-5636649561-orangeteal-value-final.jpg 
b/content/tutorials/Basic_Color_Curves/flickr-qsimple-5636649561-orangeteal-value-final.jpg
new file mode 100644
index 0000000..217d987
Binary files /dev/null and 
b/content/tutorials/Basic_Color_Curves/flickr-qsimple-5636649561-orangeteal-value-final.jpg differ
diff --git a/content/tutorials/Basic_Color_Curves/flickr-qsimple-5636649561-original.jpg 
b/content/tutorials/Basic_Color_Curves/flickr-qsimple-5636649561-original.jpg
new file mode 100644
index 0000000..8a835f6
Binary files /dev/null and b/content/tutorials/Basic_Color_Curves/flickr-qsimple-5636649561-original.jpg 
differ
diff --git a/content/tutorials/Basic_Color_Curves/flickr-qsimple-5636649561-slight-s.jpg 
b/content/tutorials/Basic_Color_Curves/flickr-qsimple-5636649561-slight-s.jpg
new file mode 100644
index 0000000..c8d7b5f
Binary files /dev/null and b/content/tutorials/Basic_Color_Curves/flickr-qsimple-5636649561-slight-s.jpg 
differ
diff --git a/content/tutorials/Basic_Color_Curves/index.md b/content/tutorials/Basic_Color_Curves/index.md
new file mode 100644
index 0000000..ab1a7be
--- /dev/null
+++ b/content/tutorials/Basic_Color_Curves/index.md
@@ -0,0 +1,391 @@
+Title: Basic Color Curves
+Date: 2015-08-18T13:18:54-05:00
+Modified: 2015-08-18T13:19:00-05:00
+Author: Pat David
+
+<noscript>
+<style>
+.comp {
+    width: 450px;
+}
+</style>
+</noscript>
+
+<small>
+[![Creative Commons 
License](http://i.creativecommons.org/l/by-sa/3.0/80x15.png)](http://creativecommons.org/licenses/by-sa/3.0/deed.en_US)
  
+<span xmlns:dct="http://purl.org/dc/terms/";>GIMP Tutorial - Basic Color Curves (text & images)</span> by 
[Pat David](http://blog.patdavid.net) is licensed under a [Creative Commons Attribution-ShareAlike 3.0 
Unported License](http://creativecommons.org/licenses/by-sa/3.0/deed.en_US) (except _Hollow Moon_ by 
_qsimple/Eric_ on [Flickr](https://www.flickr.com/people/qsimple/)).
+</small>
+
+Color has this amazing ability to evoke emotional responses from us. From the warm glow of a sunny summer 
afternoon to a cool refreshing early evening in fall. We associate colors with certain moods, places, 
feelings, and memories (consciously or not).
+
+Volumes have been written on color and I am in no ways even remotely qualified to speak on it. So I won’t.
+
+Instead, we are going to take a look at the use of the **Curves** tool in [GIMP](http://www.gimp.org). Even 
though GIMP is used to demonstrate these ideas, the principles are generic to just about any RGB curve 
adjustments.
+
+## Your Pixels and You[](#your-pixels-and-you)
+
+First there’s something you need to consider if you haven’t before, and that’s what goes into representing a 
colored pixel on your screen.
+
+<figure>
+<img src="curves-house-square-full.jpg" alt="PIXLS.US House Zoom Example" />
+<figcaption>
+Open up an image in GIMP.
+</figcaption>
+</figure>
+
+
+<figure>
+<img src="curves-house-square-zoom-1.jpg" alt="PIXLS.US House Zoom Example" />
+<figcaption>
+Now zoom in.
+</figcaption>
+</figure>
+
+<figure>
+<img src="curves-house-square-zoom-2.jpg" alt="PIXLS.US House Zoom Example" />
+<figcaption>
+Nope - don’t be shy now, zoom in more!
+</figcaption>
+</figure>
+
+<figure>
+<img src="curves-house-square-zoom-3.png" alt="PIXLS.US House Zoom Example" />
+<figcaption>
+Aaand there’s your pixel. So let’s investigate what goes into making your pixel.
+</figcaption>
+</figure>
+
+
+Remember, each pixel is represented by a combination of 3 colors: **Red**, **Green**, and **Blue**. In GIMP 
(currently at 8-bit), that means that each RGB color can have a value from **0 - 255**, and combining these 
three colors with varying levels in each channel will result in all the colors you can see in your image.
+
+If all three channels have a value of 255 - then the resulting color will be pure white. If all three 
channels have a value of 0 - then the resulting color will be pure black.
+
+If all three channels have the same value, then you will get a shade of gray (128,128,128 would be a middle 
gray color for instance).
+
+So now let’s see what goes into making up your pixel:
+
+<figure>
+<img src="curves-your-pixel-info.png" alt="GIMP Color Picker Pixel View" >
+<figcaption>
+The RGB components that mix into your final <span style="color: #7ba3ce;">blue pixel</span>.
+</figcaption>
+</figure>
+
+As you can see, there is more blue than anything else (it is a blue-ish pixel after all), followed by green, 
then a dash of red. If we were to change the values of each channel, but kept ratio the same between Red, 
Green, and Blue, then we would keep the same color and just lighten or darken the pixel by some amount.
+
+## Curves: Value[](#curves-value)
+
+So let’s leave your pixel alone for the time being, and actually have a look at the **Curves** dialog. I’ll 
be using this wonderful image by [Eric](http://www.flickr.com/photos/qsimple/) from 
[Flickr](http://www.flickr.com).
+
+<figure markdown="span">
+<img src="flickr-qsimple-5636649561-original.jpg" alt="Hollow Moon by Eric qsimple Flickr" >
+<figcaption>
+[Hollow Moon](http://www.flickr.com/photos/qsimple/5636649561/) by 
[qsimple/Eric](http://www.flickr.com/photos/qsimple/) on [Flickr](http://www.flickr.com). 
([cc-by-nc-sa](http://creativecommons.org/licenses/by-nc-sa/2.0/))
+</figcaption>
+</figure>
+
+Opening up my **Curves** dialog shows me the following:
+
+<div class="MenuCmd"><span>Colors → Curves…</span></div>
+
+<figure>
+<img src="curves-dialog-original.png" alt="GIMP Base Curves Dialog" />
+</figure>
+
+We can see that I start off with the curve for the **Value** of the pixels. I could also use the drop down 
for **“Channel”** to change to red, green or blue curves if I wanted to. For now let’s look at **Value**, 
though.
+
+In the main area of the dialog I am presented with a linear curve, behind which I will see a histogram of 
the value data for the entire image (showing the amount of each value across my image). Notice a spike in the 
high values on the right, and a small gap at the brightest values.
+
+<figure>
+<img src="curves-dialog-original-IO.png" alt="GIMP Base Curves Dialog Input Output" />
+</figure>
+
+What we can do right now is to adjust the values of each pixel in the image using this curve. The best way 
to visualize it is to remember that the bottom range from black to white represents the <span style="color: 
#0000ff">**_current_** value of the pixels</span>, and the left range is the <span style="color: 
#ff6f00">value to be mapped to</span>.
+
+So to show an example of how this curve will affect your image, suppose I wanted to remap all the values in 
the image that were in the midtones, and to make them all lighter. I can do this by clicking on the curve 
near the midtones, and dragging the curve higher in the Y direction:
+
+<figure>
+<img src="curves-dialog-midtones.png" alt="GIMP Base Curves Dialog Push Midtones" />
+</figure>
+
+What this curve does is takes the values around the midtones, and pushes their values to be much lighter 
than they were. In this case, values around <span style="color: #0000ff">128</span> were re-mapped to now be 
closer to <span style="color: #ff6f00">192</span>.
+
+Because the curve is set **Smooth**, there will be a gradual transition for all the tones surrounding my 
point to be pulled in the same direction (this makes for a smoother fall-off as opposed to an abrupt change 
at one value). Because there is only a single point in the curve right now, this means that all values will 
be pulled higher.
+
+<figure>
+<noscript><img alt="Hollow Moon Example" class="comp" src="flickr-qsimple-5636649561-original.jpg" 
/></noscript>
+<img class="comp" src="flickr-qsimple-5636649561-mid-boostl.jpg" alt="Hollow Moon Example Pushed Midtones" 
data-swap-src="flickr-qsimple-5636649561-original.jpg" />
+<figcaption>
+The results of pushing the midtones of the value curve higher<br/>
+(click to compare to original).
+<noscript><br /> (Original on left)</noscript>
+</figcaption>
+</figure>
+
+Care should be taken when fiddling with these curves to not blow things out or destroy detail, of course. I 
only push the curves here to illustrate what they do.
+
+A very common curve adjustment you may hear about is to apply a slight “S” curve to your values. The effect 
of this curve would be to darken the dark tones, and to lighten the light tones - in effect increasing global 
contrast on your image. For instance, if I click on another point in the curves, and adjust the points to 
form a shape like so:
+
+<figure>
+<img src="curves-dialog-slight-s.png" alt="GIMP Base Curves Dialog S shaped curve" >
+<figcaption>
+A slight “S” curve
+</figcaption>
+</figure>
+
+This will now cause dark values to become even darker, while the light values get a small boost. The curve 
still passes through the midpoint, so middle tones will stay closer to what they were.
+
+<figure>
+<noscript><img alt="" class="comp" src="flickr-qsimple-5636649561-original.jpg" alt="Hollow Moon Example" 
/></noscript>
+<img src="flickr-qsimple-5636649561-slight-s.jpg" alt="Hollow Moon Example S curve applied" 
data-swap-src="flickr-qsimple-5636649561-original.jpg" class="comp" />
+<figcaption>Slight “S” curve increases global contrast (click for original).
+<noscript><br /> (Original on left)</noscript>
+</figcaption>
+</figure>
+
+In general, I find it easiest to visualize in terms of which regions in the curve will effect different 
tones in your image. Here is a quick way to visualize it (that is true for value as well as RGB curves):
+
+<figure>
+<img src="curves-dialog-darksmidslights.png" alt="GIMP Base Curves darks mids lights zones" />
+</figure>
+
+If there is one thing you take away from reading this, let it be the image above.
+
+## Curves: <span style="color:red;">Co</span><span style="color:green;">lo</span><span 
style="color:blue;">rs</span>[](#curves-span-style-color-red-co-span-span-style-color-green-lo-span-span-style-color-blue-rs-span-)
+
+So how does this apply to other channels? Let’s have a look.
+
+The exact same theory applies in the RGB channels as it did with values. The relative positions of the 
darks, midtones, and lights are still the same in the curve dialog. The primary difference now is that you 
can control the contribution of color in specific tonal regions of your image.
+
+<figure>
+<img src="curves-dialog-value-rgb-select.png" alt="" >
+<figcaption>
+Value, Red, Green, Blue channel picker.
+</figcaption>
+</figure>
+
+You choose which channel you want to adjust from the **“Channel”** drop-down.
+
+To begin demonstrating what happens here it helps to have an idea of generally what effect you would like to 
apply to your image. This is often the hardest part of adjusting the color tones if you don’t have a clear 
idea to start with.
+
+For example, perhaps we wanted to “cool” down the shadows of our image. “Cool” shadows are commonly seen 
during the day in shadows out of direct sunlight. The light that does fall in shadows is mostly reflected 
light from a blue-ish sky, so the shadows will trend slightly more blue.
+
+To try this, let’s adjust the **Blue** channel to be a little more prominent in the darker tones of our 
image, but to get back to normal around the midtones and lighter.
+
+<figure>
+<img src="curves-dialog-darks-blue-boost.png" alt="" >
+<figcaption>
+Boosting blues in darker tones
+</figcaption>
+</figure>
+
+<figure>
+<noscript><img alt="" class="comp" src="flickr-qsimple-5636649561-original.jpg" /></noscript>
+<img src="flickr-qsimple-5636649561-dark-blue-boost.jpg" alt="Dark Blue Boost" class="comp" 
data-swap-src="flickr-qsimple-5636649561-original.jpg" />
+<figcaption>Pushing up blues in darker tones (click for original).
+<noscript><br /> (Original on left)</noscript>
+</figcaption>
+</figure>
+
+Now, here’s a question: If I wanted to “cool” the darker tones with more blue, what if I wanted to “warm” 
the lighter tones by adding a little yellow?
+
+Well, there’s no “Yellow” curve to modify, so how to approach that? Have a look at this HSV color wheel 
below:
+
+<figure>
+<img src="Color_circle_%2528hue-sat%2529_trans.png" alt="Color Circle Hue" />
+</figure>
+
+The thing to look out for here is that opposite your blue tones on this wheel, you’ll find yellow. In fact, 
for each of the Red, Green, and Blue channels, the opposite colors on the color wheel will show you what an 
absence of that color will do to your image. So remember:
+
+<div style="text-align: center;"><span style="color: red;">Red</span> → <span style="color: 
cyan;">Cyan</span></span><br/><span><span style="color: green;">Green</span> → <span style="color: 
magenta;">Magenta</span></span><br/><span><span style="color: blue;">Blue</span> → <span style="color: 
yellow;">Yellow</span></div>
+
+What this means to you while manipulating curves is that if you drag a curve for blue up, you will boost the 
blue in that region of your image. If instead you drag the curve for blue down, you will be **_removing_** 
blues (or boosting the **Yellows** in that region of your image).
+
+So to boost the blues in the dark tones, but increase the yellow in the lighter tones, you could create a 
sort of “reverse” S-curve in the blue channel:
+
+<figure>
+<img src="curves-dialog-darks-blue-boost-add-yellow.png" alt="Blue Boost add Yellow" />
+</figure>
+
+<figure>
+<noscript><img alt="Original" class="comp" src="flickr-qsimple-5636649561-original.jpg" /></noscript>
+<img src="flickr-qsimple-5636649561-dark-blue-boost-add-yellow.jpg" alt="Blue boost add yellow" 
data-swap-src="flickr-qsimple-5636649561-original.jpg" class="comp" />
+<figcaption>Boost blues in darks, boost yellow in high tones (click for original).
+<noscript><br /> (Original on left)</noscript>
+</figcaption>
+</figure>
+
+In the green channel for instance, you can begin to introduce more magenta into the tones by decreasing the 
curve. So dropping the green curve in the dark tones, and letting it settle back to normal towards the high 
tones will produce results like this:
+
+<figure>
+<img src="curves-dialog-darks-green-suppress.png" alt="" />
+</figure>
+
+<figure markdown='span'>
+<noscript><img alt="Original" class="comp" src="flickr-qsimple-5636649561-original.jpg" /></noscript>
+<img src="flickr-qsimple-5636649561-dark-green-suppresst.jpg" alt="Dark green suppress" 
data-swap-src="flickr-qsimple-5636649561-original.jpg" class="comp" />
+<figcaption>Suppressing the **green** channel in darks/mids adds a bit of **magenta**   
+(click for original).
+<noscript><br /> (Original on left)</noscript>
+</figcaption>
+</figure>
+
+In isolation, these curves are fun to play with, but I think that perhaps walking through some actual 
examples of color toning/grading would help to illustrate what I’m talking about here. I’ll choose a couple 
of common toning examples to show what happens when you begin mixing all three channels up.
+
+## Color Toning/Grading
+
+### **Orange** and **Teal** Hell
+
+I use the (_cinema film_) term _color grading_ here because the first adjustment we will have a look at to 
illustrate curves is a horrible hollywood trend that is best described by [Todd Miro on his 
blog](http://theabyssgazes.blogspot.com/2010/03/teal-and-orange-hollywood-please-stop.html).
+
+_Grading_ is a term for color toning on film, and Todd’s post is a funny look at the prevalence of orange 
and teal in modern film palettes. So it’s worth a look just to see how silly this is (and hopefully to raise 
awareness of the obnoxiousness of this practice).
+
+The general thought here is that caucasian skin tones trend towards orange, and if you have a look at a 
complementary color on the color wheel, you’ll notice that directly opposite orange is a teal color.
+
+<figure markdown='span'>
+<img src="Kuler_orange_teal.jpg" alt="" >
+<figcaption>
+Screenshot from [Kuler](https://color.adobe.com) borrowed from Todd.
+</figcaption>
+</figure>
+
+If you don’t already know about it, Adobe has online a fantastic tool for color visualization and palette 
creation called [<del>Kuler</del>](http://kuler.adobe.com) [**Adobe Color CC**](https://color.adobe.com). It 
lets you work on colors based on some classic rules, or even generate a color palette from images. Well worth 
a visit and a fantastic bookmark for fiddling with color.
+
+So a quick look at the desired effect would be to keep/boost the skin tones into a sort of orange-y pinkish 
color, and to push the darker tones into a teal/cyan combination. (Colorists on films tend to use a Lift, 
Gamma, Gain model, but we’ll just try this out with our curves here).
+
+Quick disclaimer - I am purposefully exaggerating these modifications to illustrate what they do. Like most 
things, moderation and restraint will go a long ways towards not causing your viewers eyeballs to bleed. 
_Remember - **light touch!**_
+
+So I know that I want to see my skin tones head into an orange-ish color. In my image the skin tones are in 
the upper mids/low highs range of values, so I will start around there.
+
+<figure>
+<img src="curves-dialog-orangeteal-red-high.png" alt="orangeteal red high" />
+</figure>
+
+What I’ve done is put a point around the low midtones to anchor the curve closer to normal for those tones. 
This lets me fiddle with the red channel and to isolate it roughly to the mid and high tones only. The skin 
tones in this image in the red channel will fall toward the upper end of the mids, so I’ve boosted the reds 
there. Things may look a little weird at first:
+
+<figure>
+<img src="flickr-qsimple-5636649561-orangeteal-red-highs.jpg" alt="orangeteal red highs" />
+</figure>
+
+If you look back at the color wheel again, you’ll notice that between red and green, there is a yellow, and 
if you go a bit closer towards red the yellow turns to more of an orange. What this means is that if we add 
some more green to those same tones, the overall colors will start to shift towards an orange.
+
+So we can switch to the green channel now, put a point in the lower midtones again to hold things around 
normal, and slightly boost the green. Don’t boost it all the way to the reds, but about 2/3<sup>rds</sup> or 
so to taste.
+
+<figure>
+<img src="curves-dialog-orangeteal-green-high.png" alt="orangeteal green high" />
+</figure>
+
+<figure>
+<img src="flickr-qsimple-5636649561-orangeteal-green-highs.jpg" alt="orangeteal green high" />
+</figure>
+
+This puts a little more red/orange-y color into the tones around the skin. You could further adjust this by 
perhaps including a bit more yellow as well. To do this, I would again put an anchor point in the low mid 
tones on the blue channel, then slightly drop the blue curve in the upper tones to introduce a bit of yellow.
+
+<figure>
+<img src="curves-dialog-orangeteal-blue-high.png" alt="orangeteal blue high" />
+</figure>
+
+<figure>
+<img src="flickr-qsimple-5636649561-orangeteal-blue-highs.jpg" alt="orangeteal blue high" />
+</figure>
+
+Remember, we’re experimenting here so feel free to try things out as we move along. I may consider the upper 
tones to be finished at the moment, and now I would want to look at introducing a more blue/teal color into 
the darker tones.
+
+I can start by boosting a bit of blues in the dark tones. I’m going to use the anchor point I already 
created, and just push things up a bit.
+
+<figure>
+<img src="curves-dialog-orangeteal-blue-low.png" alt="orangeteal blue low" />
+</figure>
+
+<figure>
+<img src="flickr-qsimple-5636649561-orangeteal-blue-lows.jpg" alt="orangeteal blue low" />
+</figure>
+
+Now I want to make the darker tones a bit more teal in color. Remember the color wheel - **teal** is the 
absence of red - so we will drop down the red channel in the lower tones as well.
+
+<figure>
+<img src="curves-dialog-orangeteal-red-low.png" alt="orangeteal red low" />
+</figure>
+
+<figure>
+<img src="flickr-qsimple-5636649561-orangeteal-red-lows.jpg" alt="orangeteal red low" />
+</figure>
+
+And finally to push a very slight magenta into the dark tones as well, I’ll push down the green channel a 
bit.
+
+<figure>
+<img src="curves-dialog-orangeteal-green-low.png" alt="orangeteal green low" />
+</figure>
+
+<figure>
+<img src="flickr-qsimple-5636649561-orangeteal-green-lows.jpg" alt="orangeteal green low" />
+</figure>
+
+If I wanted to go a step further, I could also put an anchor point up close to the highest values to keep 
the brightest parts of the image closer to a white instead of carrying over a color cast from our previous 
operations.
+
+If your previous operations also darkened the image a bit, you could also now revisit the **Value** channel, 
and make modifications there as well. In my case I bumped the midtones of the image just a bit to brighten 
things up slightly.
+
+<figure>
+<img src="curves-dialog-orangeteal-value-final.png" alt="orangeteal value final" />
+</figure>
+
+Finally to end up at something like this.
+
+<figure>
+<noscript><img alt="Original" class="comp" src="flickr-qsimple-5636649561-original.jpg" /></noscript>
+<img src="flickr-qsimple-5636649561-orangeteal-value-final.jpg" alt="orangeteal value final" 
data-swap-src="flickr-qsimple-5636649561-original.jpg" class="comp" />
+<figcaption>After fooling around a bit - disgusting, isn’t it?   
+(click for original).
+<noscript><br /> (Original on left)</noscript>
+</figcaption>
+</figure>
+
+I am exaggerating things here to illustrate a point. Please don’t do this to your photos. :)
+
+If you’d like to download the curves file of the results we reached above, get it here:  
+[Orange Teal Hell Color Curves](https://docs.google.com/open?id=0B21lPI7Ov4CVdmJnOXpkQjN4aWc)
+
+## Conclusion[](#conclusion)
+
+Remember, think about what the color curves represent in your image to help you achieve your final results. 
Begin looking at the different tonalities in your image and how you’d like them to appear as part of your 
final vision.
+
+For even more fun - realize that the colors in your images can help to evoke emotional responses in the 
viewer, and adjust things accordingly. I’ll leave it as an exercise for the reader to determine some of the 
associations between colors and different emotions.
+
+The original tutorial this was adapted from may be found 
[here](http://blog.patdavid.net/2012/06/getting-around-in-gimp-color-curves.html) or 
[here](https://pixls.us/articles/basic-color-curves/) on [pixls.us](https://pixls.us) (possibly with updated 
information).
+
+<small>
+[![Creative Commons 
License](http://i.creativecommons.org/l/by-sa/3.0/80x15.png)](http://creativecommons.org/licenses/by-sa/3.0/deed.en_US)
  
+<span xmlns:dct="http://purl.org/dc/terms/";>GIMP Tutorial - Basic Color Curves (text & images)</span> by 
[Pat David](http://blog.patdavid.net) is licensed under a [Creative Commons Attribution-ShareAlike 3.0 
Unported License](http://creativecommons.org/licenses/by-sa/3.0/deed.en_US) (except _Hollow Moon_ by 
_qsimple/Eric_ on [Flickr](https://www.flickr.com/people/qsimple/)).
+</small>
+
+<script type="text/javascript">
+<!-- 
+/* 
+* Simple image swapping using html5 data-* attributes. 
+* Get all images with the 'data-swap-src' attribute. 
+* For each image, set the 'data-swap' attribute to a start value 
+* Add event listener to the images to trigger swap function 
+* swap function swaps out the current src and data-swap values 
+*/
+
+var imgs = document.querySelectorAll('[data-swap-src]');
+var images_pre = new Array();
+
+for ( var i = 0; i < imgs.length; i++ ){ 
+    imgs[i].setAttribute('data-swap', imgs[i].getAttribute('data-swap-src') );
+    imgs[i].addEventListener('click', swap, false);
+    imgs[i].style.cursor = "crosshair";
+    images_pre[i] = new Image();
+    images_pre[i].src = imgs[i].getAttribute('data-swap-src');
+}
+
+function swap(evt){ 
+    var et = evt.target;
+    var tmp = et.src;
+    et.src = et.getAttribute('data-swap');
+    et.setAttribute('data-swap', tmp);
+    et.style.cursor == "crosshair" ? et.style.cursor = "w-resize" : et.style.cursor = "crosshair";
+ } 
+
+--></script>
+
diff --git a/content/tutorials/Basic_Color_Curves/th_tranquil.jpg 
b/content/tutorials/Basic_Color_Curves/th_tranquil.jpg
new file mode 100644
index 0000000..d81495e
Binary files /dev/null and b/content/tutorials/Basic_Color_Curves/th_tranquil.jpg differ
diff --git a/content/tutorials/Basic_Color_Curves/tranquil.jpg 
b/content/tutorials/Basic_Color_Curves/tranquil.jpg
new file mode 100644
index 0000000..581da3f
Binary files /dev/null and b/content/tutorials/Basic_Color_Curves/tranquil.jpg differ


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]