From e0688711fd8fb640d96044413aa2d7b1b1cd4e03 Mon Sep 17 00:00:00 2001
From: John MacFarlane <jgm@berkeley.edu>
Date: Wed, 23 Apr 2014 10:23:02 -0700
Subject: [PATCH] EPUB writer:  include extension in epub ids.

This fixes a problem with duplicate extensions for fonts and
images with the same base name but different extensions.

Closes #1254.
---
 src/Text/Pandoc/Writers/EPUB.hs | 17 +++++++++++------
 1 file changed, 11 insertions(+), 6 deletions(-)

diff --git a/src/Text/Pandoc/Writers/EPUB.hs b/src/Text/Pandoc/Writers/EPUB.hs
index dae45b90f..9f10554a9 100644
--- a/src/Text/Pandoc/Writers/EPUB.hs
+++ b/src/Text/Pandoc/Writers/EPUB.hs
@@ -35,7 +35,7 @@ import Data.Maybe ( fromMaybe )
 import Data.List ( isInfixOf, intercalate )
 import System.Environment ( getEnv )
 import Text.Printf (printf)
-import System.FilePath ( (</>), takeBaseName, takeExtension, takeFileName )
+import System.FilePath ( (</>), takeExtension, takeFileName )
 import qualified Data.ByteString.Lazy as B
 import qualified Data.ByteString.Lazy.Char8 as B8
 import qualified Text.Pandoc.UTF8 as UTF8
@@ -56,7 +56,7 @@ import Text.XML.Light hiding (ppTopElement)
 import Text.Pandoc.UUID
 import Text.Pandoc.Writers.HTML
 import Text.Pandoc.Writers.Markdown ( writePlain )
-import Data.Char ( toLower, isDigit )
+import Data.Char ( toLower, isDigit, isAlphaNum )
 import Network.URI ( unEscapeString )
 import Text.Pandoc.MIME (getMimeType)
 #if MIN_VERSION_base(4,6,0)
@@ -132,6 +132,11 @@ removeNote :: Inline -> Inline
 removeNote (Note _) = Str ""
 removeNote x        = x
 
+toId :: FilePath -> String
+toId = map (\x -> if isAlphaNum x || x == '-' || x == '_'
+                     then x
+                     else '_') . takeFileName
+
 getEPUBMetadata :: WriterOptions -> Meta -> IO EPUBMetadata
 getEPUBMetadata opts meta = do
   let md = metadataFromMeta opts meta
@@ -427,7 +432,7 @@ writeEPUB opts doc@(Pandoc meta _) = do
 
   -- contents.opf
   let chapterNode ent = unode "item" !
-                           ([("id", takeBaseName $ eRelativePath ent),
+                           ([("id", toId $ eRelativePath ent),
                              ("href", eRelativePath ent),
                              ("media-type", "application/xhtml+xml")]
                             ++ case props ent of
@@ -435,14 +440,14 @@ writeEPUB opts doc@(Pandoc meta _) = do
                                     xs   -> [("properties", unwords xs)])
                         $ ()
   let chapterRefNode ent = unode "itemref" !
-                             [("idref", takeBaseName $ eRelativePath ent)] $ ()
+                             [("idref", takeFileName $ eRelativePath ent)] $ ()
   let pictureNode ent = unode "item" !
-                           [("id", takeBaseName $ eRelativePath ent),
+                           [("id", toId $ eRelativePath ent),
                             ("href", eRelativePath ent),
                             ("media-type", fromMaybe "application/octet-stream"
                                $ mediaTypeOf $ eRelativePath ent)] $ ()
   let fontNode ent = unode "item" !
-                           [("id", takeBaseName $ eRelativePath ent),
+                           [("id", toId $ eRelativePath ent),
                             ("href", eRelativePath ent),
                             ("media-type", fromMaybe "" $ getMimeType $ eRelativePath ent)] $ ()
   let plainTitle = case docTitle meta of