newtype Book = Book
{ bookParts :: [Part]
}
parseJSON = withObject "Book" $ \v ->
Book
<$> v .: "part"
toJSON Book {..} =
object
[ "part" .= bookParts
]
data Part = Part
{ partTitle :: Text,
withObject "Part" $ \v ->
Part
<$> v .: "title"
<*> v .: "chapter"
<*> v .:? "frontmatter" .!= False
<*> v .:? "mainmatter" .!= False
<*> v .:? "backmatter" .!= False
toJSON Part {..} =
object
[ "title" .= partTitle,
"chapter" .= partChapters,
"frontmatter" .= partFrontmatter,
"mainmatter" .= partMainmatter,
"backmatter" .= partBackmatter
]
data Chapter = Chapter
{ chapterInclude :: FilePath,
withObject "Chapter" $ \v ->
Chapter
<$> v .: "include"
<*> v .:? "epub-type" .!= "bodymatter"
toJSON Chapter {..} =
object
[ "include" .= chapterInclude,
"epub-type" .= chapterEpubType
]
newtype ChapterTable = ChapterTable {chapterBimap :: Bimap.Bimap FilePath FilePath}
ChapterTable {..}
where
Bimap.fromList $ zip chapterList (tail chapterList)
flattenBook book
where
flattenPart <=< bookParts
flattenChapter <=< partChapters
return . chapterInclude
Bimap.lookup src chapterBimap
Bimap.lookupR src chapterBimap