diff --git a/README.md b/README.md
--- a/README.md
+++ b/README.md
@@ -19,11 +19,11 @@
 - Import recipe files
 - Generate shopping lists
 - Keep track of recipes with tags
-- Set default unit systems, serving sizes, and recipe file path in ``config.hs``
+- Set default unit systems, serving sizes, language, and recipe file path in ``config.hs``
 
 ### What's new:
-- Yarr! Herm's now supports both English and Pirate! Simply make it ``language = "pirate"`` in your ``config.hs``!
-- "Pirate" is but the first language that Herm's is now capable of supporting. We need your help to translate it into others! Currently in progress: Português, Español 
+- Bonjour! Herm's now has language support for Français (French), English, and Pirate. Set your language preferences in ``config.hs``!
+- These are but the first languages that Herm's is now capable of supporting. We need your help to translate it into others! Currently in progress: Português (Portuguese), Español (Spanish)
 
 ### Installation
 
@@ -49,7 +49,7 @@
 
 ##### Via Hackage and Cabal:
 
-_Note_: Your milage may vary with dependency resolution
+_Note_: Your mileage may vary with dependency resolution
 
 ```
 cabal update
@@ -58,8 +58,6 @@
 
 ##### Manually with Cabal:
 
-_Note_: Your milage may vary with dependency resolution
-
 ```
 git clone https://github.com/JackKiefer/herms
 cd herms
@@ -86,6 +84,8 @@
         herms edit RECIPE_NAME                          edit a recipe
 
         herms import FILE_NAME                          import a recipe file
+        
+        herms export DESTINATION                        export recipes to DESTINATION
 
         herms remove RECIPE_NAMES                       remove the particular recipes
 
@@ -131,8 +131,8 @@
 
 - `defaultUnit` : The default unit system to show recipes in. Options: `Imperial`, `Metric`, `None`. Setting to `None` will simply show recipes in whatever unit system they're stored in.
 - `defaultServingSize` : Default serving size to calculate when showing recipes. Can be any non-negative integer; set to `0` for no default. This can be useful when you're always cooking for the same number of people!
-- `recipesFile` : The recipes file to use. This option currently supports relative (but not absolute) location, as well; if your data directory is `~/herms/data`, for example, and you want a recipe file in your home directoy called `~/GrandmasHugeCookbook.herms`, set this option to `"../../GrandmasHugeCookbook.herms"`.
-- `language` : Human language to use. Currently supported: ``"english"``, ``"pirate"``
+- `recipesFile` : The recipes file to use. This option currently supports relative (but not absolute) location, as well; if your data directory is `~/herms/data`, for example, and you want a recipe file in your home directory called `~/GrandmasHugeCookbook.herms`, set this option to `"../../GrandmasHugeCookbook.herms"`.
+- `language` : Human language to use. Currently supported: ``"Français"``, ``"English"``, ``"Pirate"``
 
 
 ---
diff --git a/app/herms.hs b/app/herms.hs
--- a/app/herms.hs
+++ b/app/herms.hs
@@ -11,6 +11,7 @@
 import Data.List
 import Data.Maybe
 import Data.Semigroup ((<>))
+import Data.String    (IsString(..))
 import Data.Ratio
 import Control.Applicative
 import Options.Applicative hiding (str)
@@ -29,7 +30,7 @@
 
 -- Global constants
 versionStr :: String
-versionStr = "1.9.0.0"
+versionStr = "1.9.0.2"
 
 configPath :: IO FilePath
 configPath = getDataFileName "config.hs"
@@ -75,7 +76,7 @@
     saveOrDiscard input oldRecp
 
 add :: HermsReader IO ()
-add = do 
+add = do
   (config, recipeBook) <- ask
   input <- liftIO $ getAddInput (translator config)
   saveOrDiscard input Nothing
@@ -93,7 +94,7 @@
         ingrs    = toStr ingredientName
         dirs     = unlines (directions recp)
         attrs    = toStr attribute
-        tag      = unlines (tags recp)
+        tag      = unwords (tags recp)
 
 edit :: String -> HermsReader IO ()
 edit target = do
@@ -128,6 +129,15 @@
     forM_ otherRecipeBook $ \recipe ->
       putStrLn $ "  " ++ recipeName recipe
 
+export :: [String] -> HermsReader IO ()
+export targets = do
+  (config, recipeBook) <- ask
+  let t = translator config
+  liftIO $ forM_ targets $ \ target ->
+    putText $ case readRecipeRef target recipeBook of
+      Nothing   -> target ~~ (t Str.doesNotExist)
+      Just recp -> fromString $ show recp
+
 getServingsAndConv :: Int -> String -> Config -> (Maybe Int, Conversion)
 getServingsAndConv serv convName config = (servings, conv)
   where servings = case serv of
@@ -318,6 +328,7 @@
 runWithOpts Add                                     = add
 runWithOpts (Edit target)                           = edit target
 runWithOpts (Import target)                         = importFile target
+runWithOpts (Export targets)                        = export targets
 runWithOpts (Remove targets)                        = remove targets
 runWithOpts (View targets serving step conversion)  = if step 
                                                       then viewByStep targets serving conversion
@@ -336,15 +347,17 @@
              | Add                               -- ^ adds the recipe (interactively)
              | Edit    String                    -- ^ edits the recipe
              | Import  String                    -- ^ imports a recipe file
+             | Export  [String]                  -- ^ exports recipes to stdout
              | Remove [String]                   -- ^ removes specified recipes
              | Shop   [String] Int               -- ^ generates the shopping list for given recipes
              | DataDir                           -- ^ prints the directory of recipe file and config.hs
 
-listP, addP, viewP, editP, importP, shopP, dataDirP :: Translator -> Parser Command
+listP, addP, viewP, editP, importP, exportP, shopP, dataDirP :: Translator -> Parser Command
 listP    t = List   <$> (words <$> (tagsP t)) <*> (groupByTagsP t) <*> (nameOnlyP t)
 addP     _ = pure Add
 editP    t = Edit   <$> (recipeNameP t)
 importP  t = Import <$> (fileNameP t)
+exportP  t = Export <$> (severalRecipesP t)
 removeP  t = Remove <$> (severalRecipesP t)
 viewP    t = View   <$> (severalRecipesP t) <*> (servingP t) <*> (stepP t) <*> (conversionP t)
 shopP    t = Shop   <$> (severalRecipesP t) <*> (servingP t)
@@ -433,6 +446,9 @@
      <> command (t Str.import')
                 (info  (helper <*> importP t)
                        (progDesc (t Str.importDesc)))
+     <> command (t Str.export)
+                (info  (helper <*> exportP t)
+                       (progDesc (t Str.exportDesc)))
      <> command (t Str.remove)
                 (info  (helper <*> removeP t)
                        (progDesc (t Str.removeDesc)))
diff --git a/herms.cabal b/herms.cabal
--- a/herms.cabal
+++ b/herms.cabal
@@ -16,7 +16,7 @@
 -- PVP summary:      +-+------- New features or improvements with significant API change
 --                   | | +----- Bugfixes and improvements with minor change to API
 --                   | | | +--- Bugfixes and improvements with no change to API
-version:             1.9.0.0
+version:             1.9.0.2
 
 -- A short (one-line) description of the package.
 synopsis:            A command-line manager for delicious kitchen recipes
@@ -76,6 +76,7 @@
                      , Lang.Strings
                      , Lang.Pirate
                      , Lang.Portuguese
+                     , Lang.French
 
   -- LANGUAGE extensions used by modules in this package.
   other-extensions:    OverloadedStrings, TemplateHaskell, RankNTypes
@@ -89,7 +90,7 @@
                      , microlens-th >=0.4 && <0.5
                      , mtl >= 2.2.1 && <= 2.2.2
                      , optparse-applicative >=0.14 && <0.15
-                     , semigroups >= 0.18.3 && <= 0.18.4
+                     , semigroups >= 0.18.3 && < 0.19
                      , split >=0.2 && <0.3
                      , vty >=5.15 && < 5.22
 
diff --git a/src/AddCLI.hs b/src/AddCLI.hs
--- a/src/AddCLI.hs
+++ b/src/AddCLI.hs
@@ -80,12 +80,12 @@
             (str (t Str.tuiServingSize) <+> (hLimit 3 e3)) <=>
             str " " <=>
             str (t Str.tuiHeaders) <=>
-            (str (t Str.tuiIngrs) 
+            (str (t Str.tuiIngrs)
               <+> (hLimit 7 $ vLimit 7 e4)
               <+> (hLimit 9 $ vLimit 7 e5)
               <+> (hLimit 28 $ vLimit 7 e6)
               <+> (hLimit 18 $ vLimit 7 e7))
-              <=> 
+              <=>
             str " " <=>
             (str (t Str.tuiDirs) <+> (hLimit 62 $ vLimit 8 e8)) <=>
             str " " <=>
@@ -102,27 +102,27 @@
         V.EvKey V.KEsc [] -> M.halt st
         V.EvKey (V.KChar '\t') [] -> M.continue $ st & focusRing %~ F.focusNext
         V.EvKey V.KBackTab [] -> M.continue $ st & focusRing %~ F.focusPrev
-        
+
         -- Ctrl + <Arrow Keys>
-        V.EvKey V.KDown [V.MCtrl] -> 
+        V.EvKey V.KDown [V.MCtrl] ->
           M.continue $ st & focusRing %~ (determineNextFocus FocusDown st)
-        V.EvKey V.KUp [V.MCtrl] -> 
+        V.EvKey V.KUp [V.MCtrl] ->
           M.continue $ st & focusRing %~ (determineNextFocus FocusUp st)
-        V.EvKey V.KRight [V.MCtrl] -> 
+        V.EvKey V.KRight [V.MCtrl] ->
           M.continue $ st & focusRing %~ (determineNextFocus FocusRight st)
-        V.EvKey V.KLeft [V.MCtrl] -> 
+        V.EvKey V.KLeft [V.MCtrl] ->
           M.continue $ st & focusRing %~ (determineNextFocus FocusLeft st)
 
         -- Meta + <h-j-k-l>
-        V.EvKey (V.KChar 'h') [V.MMeta] -> 
+        V.EvKey (V.KChar 'h') [V.MMeta] ->
           M.continue $ st & focusRing %~ (determineNextFocus FocusLeft st)
-        V.EvKey (V.KChar 'j') [V.MMeta] -> 
+        V.EvKey (V.KChar 'j') [V.MMeta] ->
           M.continue $ st & focusRing %~ (determineNextFocus FocusDown st)
-        V.EvKey (V.KChar 'k') [V.MMeta] -> 
+        V.EvKey (V.KChar 'k') [V.MMeta] ->
           M.continue $ st & focusRing %~ (determineNextFocus FocusUp st)
-        V.EvKey (V.KChar 'l') [V.MMeta] -> 
+        V.EvKey (V.KChar 'l') [V.MMeta] ->
           M.continue $ st & focusRing %~ (determineNextFocus FocusRight st)
- 
+
         _ -> M.continue =<< case F.focusGetCurrent (st^.focusRing) of
                Just RecipeName -> T.handleEventLensed st edit1 E.handleEditorEvent ev
                Just Description -> T.handleEventLensed st edit2 E.handleEditorEvent ev
@@ -137,9 +137,9 @@
 appEvent st _ = M.continue st
 
 determineNextFocus :: FocusChange -> St -> F.FocusRing n -> F.FocusRing n
-determineNextFocus action st = 
+determineNextFocus action st =
   case action of
-    FocusDown -> case currentFocus of 
+    FocusDown -> case currentFocus of
         Just RecipeName -> (F.focusNext)
         Just Description -> (F.focusNext)
         Just ServingSize -> (F.focusNext)
@@ -227,9 +227,9 @@
              , E.getEditContents $ st^.edit5
              , E.getEditContents $ st^.edit6
              , E.getEditContents $ st^.edit7
-             , E.getEditContents $ st^.edit8 
+             , E.getEditContents $ st^.edit8
              , E.getEditContents $ st^.edit9
-             ] 
+             ]
 
 getAddInput :: Translator -> IO ([[String]])
 getAddInput t = do 
@@ -241,6 +241,6 @@
              , E.getEditContents $ st^.edit5
              , E.getEditContents $ st^.edit6
              , E.getEditContents $ st^.edit7
-             , E.getEditContents $ st^.edit8 
+             , E.getEditContents $ st^.edit8
              , E.getEditContents $ st^.edit9
-             ] 
+             ]
diff --git a/src/Lang/French.hs b/src/Lang/French.hs
new file mode 100644
--- /dev/null
+++ b/src/Lang/French.hs
@@ -0,0 +1,86 @@
+module Lang.French where
+
+import Lang.Strings
+
+french :: String -> String
+french str
+  | is tuiTitle       = "                                    Herm's - Ajouter une recette"
+  | is tuiName        = "           Nom: "
+  | is tuiDesc        = "   Description: "
+  | is tuiServingSize = "       Portion: "
+  | is tuiHeaders     = "                  qté.   unité              nom                 attribut"
+  | is tuiIngrs       = "  Ingrédients: \n(un par ligne)  " 
+  | is tuiDirs        = "   Directions: \n(un par ligne)  "
+  | is tuiTags        = "     Mots-clés: "
+  | is tuiHelp1       = "                      Tab / Shift+Tab           - Champ suivant / précédent"
+  | is tuiHelp2       = "                      Ctrl + <flêches>          - Parcourir les champs"
+  | is tuiHelp3       = "                      [Meta or Alt] + <h-j-k-l> - Parcourir les champs"
+  | is tuiHelp4       = "                      Esc                       - Enregistrer ou Annuler"
+  | is headerServs    = "\nPortions: "
+  | is headerIngrs    = "\nIngrédients:\n"
+  | is saveRecipeYesNoEdit = "Enregister la recette? (O)ui  (N)on (E)diter"
+  | is y              = "o" 
+  | is yCap           = "O"
+  | is n              = "n" 
+  | is nCap           = "N"
+  | is e              = "e" 
+  | is eCap           = "E"
+  | is recipeSaved    = "Recette enregistrée!"
+  | is changesDiscarded = "Modifications annulées."
+  | is badEntry         = "Merci de SEULEMENT entrer 'o', 'n' ou 'e'"
+  | is doesNotExist     = " n'existe pas\n"
+  | is nothingToImport  = "Rien a importer"
+  | is importedRecipes  = "Recettes importées:"
+  | is metric         = "métrique"
+  | is imperial       = "impériale"
+  | is more           = " [plus]"
+  | is capTags        = "Mots-clés"
+  | is removingRecipe = "Enlever la recette: "
+  | is group          = "grouper"
+  -- | is groupShort     = "g"
+  | is groupDesc      = "grouper les recettes par mots-cles"
+  | is nameOnly       = "nom"
+  -- | is nameOnlyShort  = "n"
+  | is nameOnlyDesc   = "afficher que le nom des recettes"
+  | is tags           = "mots-clés"
+  | is tagsMetavar    = "MOTS-CLES"
+  | is tagsDesc       = "afficher les recettes avec des mots-clés particuliers"
+  | is serving        = "portion"
+  -- | is servingShort   = "p"
+  | is servingDesc    = "spécifier la portion en affichant"
+  | is servingMetavar = "INT"
+  | is step           = "pas"
+  -- | is stepShort      = "t"
+  | is stepDesc       = "s'il faut afficher un pas après l'autre"
+  | is convert        = "convertir"
+  -- | is convertShort   = "c"
+  | is convertDesc    = "convertit les unités de la recette en métrique ou impérial."
+  | is convertMetavar = "CONV_UNIT"
+  | is none           = "aucun"
+  | is recipeNameMetavar = "NOM_RECETTE"
+  | is recipeNameDesc    = "index ou nom de recette"
+  | is fileNameMetavar   = "NOM_FICHIER"
+  | is fileNameDesc      = "nom du fichier"
+  | is list           = "lister"
+  | is listDesc       = "lister les recettes"
+  | is view           = "afficher"
+  | is viewDesc       = "afficher les recettes particulières"
+  | is add            = "ajouter"
+  | is addDesc        = "ajouter une nouvelle recette (interactivement)"
+  | is edit           = "éditer"
+  | is editDesc       = "éditer une recette"
+  | is import'        = "importer"
+  | is importDesc     = "importer un ficher de recette"
+  | is remove         = "retirer"
+  | is removeDesc     = "retirer les recettes particulières"
+  | is shopping       = "course"
+  | is shoppingDesc   = "générer une liste de course pour les recettes données"
+  | is datadir        = "datadir"
+  | is datadirDesc    = "afficher l'emplacement des fichers de configuration et de recettes"
+  | is version        = "version"
+  -- | is versionShort   = "v"
+  | is versionDesc    = "afficher la version"
+  | is progDesc       = "HeRM's: Un gestionnaire de recette en Haskell. Taper \"herms --help\" pour les options"
+  | otherwise         = str
+
+  where is = (str ==)
diff --git a/src/Lang/Strings.hs b/src/Lang/Strings.hs
--- a/src/Lang/Strings.hs
+++ b/src/Lang/Strings.hs
@@ -120,6 +120,9 @@
 import'    = "import"
 importDesc = "import a recipe file"
 
+export     = "export"
+exportDesc = "export recipes to stdout"
+
 remove     = "remove"
 removeDesc = "remove the particular recipes"
 
diff --git a/src/ReadConfig.hs b/src/ReadConfig.hs
--- a/src/ReadConfig.hs
+++ b/src/ReadConfig.hs
@@ -7,6 +7,7 @@
 import Data.Char (toLower)
 import Data.List.Split
 import Lang.Pirate
+import Lang.French
 import Paths_herms
 
 ------------------------------
@@ -32,6 +33,7 @@
 data Language = English
               | Pirate
               | Portuguese
+              | French
 
 type Translator = String -> String
 
@@ -51,6 +53,10 @@
 ------ Language Synonyms -----
 ------------------------------
 
+-- Contributor's note: Make sure that all of these synonyms are lower-case as
+-- we handle case-sensitivity by first converting the user's settings input
+-- to all lower-case.
+
 englishSyns = [ "english"
               , "en"
               , "en-us"
@@ -67,6 +73,14 @@
                  , "pt"
                  ]
 
+frenchSyns = [ "french"
+              , "fr"
+              , "fr-fr"
+              , "français"
+              , "francais"
+              ]
+
+
 ------------------------------
 --------- Functions ----------
 ------------------------------
@@ -76,12 +90,15 @@
   | isIn englishSyns = English
   -- | isIn portugueseSyns = Portuguese
   | isIn pirateSyns  = Pirate
+  -- | isIn frenchSyns = French
+  | isIn frenchSyns  = French
   where isIn = elem (map toLower $ language c)
 
 getTranslator :: Language -> Translator
 getTranslator lang = case lang of
                        English -> id :: String -> String
                        Pirate  -> pirate
+                       French  -> french
 
 dropComments :: String -> String
 dropComments = unlines . map (head . splitOn "--") . lines
diff --git a/src/Types.hs b/src/Types.hs
--- a/src/Types.hs
+++ b/src/Types.hs
@@ -7,6 +7,7 @@
 import Data.Ord
 import RichText
 import qualified Lang.Strings as Str
+import Text.Read (readMaybe)
 
 data Ingredient = Ingredient { quantity :: Ratio Int
                              , unit :: String
@@ -103,7 +104,7 @@
                         ingredients = i, directions = dir, tags = t }
   where n   = concat $ head r
         des = concat $ r !! 1
-        s   = read $ concat $ r !! 2
+        s   = fromMaybe 1 $ readMaybe $ concat $ r !! 2
         i   = adjustIngredients (1 % s) $ readIngredients [r !! 3, r !! 4, r !! 5, r !! 6]
         dir = r !! 7
         unparsedTags = concat (r !! 8)
