epub-tools 2.4 → 2.5
raw patch · 12 files changed
+299/−76 lines, 12 files
Files
- README.md +2/−2
- TODO +0/−2
- changelog.md +14/−0
- epub-tools.cabal +1/−1
- src/EpubTools/EpubMeta/Opts.hs +1/−1
- src/EpubTools/EpubName/Doc/Rules.hs +20/−10
- src/EpubTools/EpubName/Format/Author.hs +2/−1
- src/EpubTools/EpubName/Format/Format.hs +1/−1
- src/EpubTools/EpubName/Format/Util.hs +11/−10
- src/EpubTools/EpubName/Opts.hs +1/−1
- src/EpubTools/EpubZip/Opts.hs +1/−1
- testsuite/EpubTools/Test/EpubName/Format.hs +245/−46
README.md view
@@ -70,9 +70,9 @@ ## Getting source - Download the cabalized source package [from Hackage](http://hackage.haskell.org/package/epub-tools)-- Download the cabalized source tarball [from here](http://ui3.info/d/proj/epub-tools/epub-tools-2.4.tar.gz)+- Download the cabalized source tarball [from here](http://ui3.info/d/proj/epub-tools/epub-tools-2.5.tar.gz) - epub-tools is available for Arch Linux [from the AUR](http://aur.archlinux.org/packages/epub-tools/)-- Download [binaries for Windows](http://ui3.info/d/proj/epub-tools/epub-tools-2.4-win.zip)+- Download [binaries for Windows](http://ui3.info/d/proj/epub-tools/epub-tools-2.5-win.zip) - Get the source with darcs: `$ darcs get http://ui3.info/darcs/epub-tools` - If you're just looking, [browse the source](http://ui3.info/darcs/epub-tools)
TODO view
@@ -3,8 +3,6 @@ - Some notes in README about installing epubcheck if possible -- Add more (all?) of the darcs-tracked files to cabal so they're part of the sdist- - Would like to way to be able to insert a publishing year tag into the OPF data like these: <dc:date opf:event="publication">2011</dc:date> <dc:date opf:event="original-publication">2011</dc:date>
changelog.md view
@@ -1,3 +1,17 @@+2.5 (2014-04-04)++ * Additions and modifications to the stock rules to both support+ more books and also use more generic rules than before++ * Added code to set proper case for Roman numerals in titles++ * Added code to handle file-as names with parenthesized name info++ * Simplified and consolidated special-character filtering code++ * Added support for multiline fields in the Metadata++ 2.4 (2014-03-19) * Fixed problem in Windows cmd shell with missing UNIX HOME
epub-tools.cabal view
@@ -1,6 +1,6 @@ name: epub-tools cabal-version: >= 1.8-version: 2.4+version: 2.5 build-type: Simple license: BSD3 license-file: LICENSE
src/EpubTools/EpubMeta/Opts.hs view
@@ -105,5 +105,5 @@ , " epub3: http://www.idpf.org/epub/30/spec/epub30-publications.html" , "" , ""- , "Version 2.4 Dino Morelli <dino@ui3.info>"+ , "Version 2.5 Dino Morelli <dino@ui3.info>" ]
src/EpubTools/EpubName/Doc/Rules.hs view
@@ -63,13 +63,9 @@ , " titlePat \".* Magazine Issue ([0-9]+) ::.*\"" , " name \"GUDMagazine(pad 2 1)\"" , ""- , "magInterzone_old"- , " titlePat \"^(Interzone)[^0-9]*([0-9]+)$\""- , " name \"(1)SFF(pad 3 2)\""- , "" , "magInterzone"- , " titlePat \"^(Interzone) ([0-9]+).*$\""- , " name \"(1)SFF(pad 3 2)\""+ , " titlePat \"^(Interzone|INTERZONE)[^0-9]+([0-9]+).*\""+ , " name \"(scrub 1)SFF(pad 3 2)\"" , "" , "magLightspeed_date" , " titlePat \"(Lightspeed) Magazine, (.*) (.*)\""@@ -91,10 +87,6 @@ , " titlePat \"^(Something Wicked)[^0-9]*([0-9]+)\"" , " name \"(scrub 1)(pad 3 2)\"" , ""- , "magUniverse"- , " titlePat \"^(Jim Baen's Universe)-Vol ([^ ]+) Num ([^ ]+)\""- , " name \"(scrub 1)Vol(pad 2 2)Num(pad 2 3)\""- , "" , "magWeirdTales" , " titlePat \"^(Weird Tales)[^0-9]*([0-9]+)$\"" , " name \"(scrub 1)(pad 3 2)\""@@ -106,6 +98,24 @@ , "magGenericWithIssue" , " titlePat \"(.* Magazine):? Issue ([0-9]+).*\"" , " name \"(scrub 1)(pad 2 2)\""+ , ""+ , "magGenericSubjWithIssue"+ , " subjectMatch \"magazine\""+ , " titlePat \"(.*) Issue ([0-9]+).*\""+ , " name \"(scrub 1)Magazine(pad 2 2)\""+ , ""+ , "magGenericVolNo3"+ , " titlePat \"(.*)Vol(ume)? ([0-9]{1,2}),? (No|Num)[^0-9]+([0-9]{3}).*\""+ , " name \"(scrub 1)Vol(pad 2 3)No(pad 3 5)\""+ , ""+ , "magGenericVolNo2"+ , " titlePat \"(.*)Vol(ume)? ([0-9]{1,2}),? (No|Num)[^0-9]+([0-9]{1,2})[^0-9]?.*\""+ , " name \"(scrub 1)Vol(pad 2 3)No(pad 2 5)\""+ , ""+ , "nonficWomensInstituteLibrary"+ , " authorMatch \"Woman's Institute\""+ , " titlePat \"(.*)\""+ , " name \"(scrub 1)\"" , "" , "anthology" , " subjectMatch \"anthology\""
src/EpubTools/EpubName/Format/Author.hs view
@@ -92,7 +92,8 @@ authorSingle :: [String] -> String authorSingle (last:rest:_) = printf "%s%s-" (scrubString last) (scrubString rest)-authorSingle [n] = printf "%s-" $ scrubString n+authorSingle [n] =+ printf "%s-" $ scrubString $ takeWhile (/= '(') n authorSingle _ = undefined
src/EpubTools/EpubName/Format/Format.hs view
@@ -161,7 +161,7 @@ [] -> throwError "format failed, no title present" ts -> return . head $ ts - case matchRegex (mkRegex re) oldTitle of+ case matchRegex (mkRegexWithOpts re False True) oldTitle of Just matches -> return matches Nothing -> throwError $ printf "extract title failed: %s" re
src/EpubTools/EpubName/Format/Util.hs view
@@ -49,6 +49,9 @@ camelCase :: String -> String camelCase s = concat $ map capFirst $ words s where+ capFirst s'@('I':'I':_) = map toUpper s'+ capFirst s'@('I':'V':_) = map toUpper s'+ capFirst s'@('I':'X':_) = map toUpper s' capFirst (first:rest) = (toUpper first) : (map toLower rest) capFirst _ = undefined @@ -58,18 +61,16 @@ -} aggressiveFilters :: [(String -> String)] aggressiveFilters =- [ repl "[',\\?();#’]" ""- , repl "\\." " "- , repl ":" "_"+ [ repl "[',\\?();#’\\*!]" ""+ , repl "]" "" -- Tricky to put this in [ ]+ , repl "[./]" " "+ , repl ":" "_"+ , repl "[\\[\\\n]" "_ "+ , repl "-" "- " , filter (/= '"')- , repl "]" ""- , repl "\\*" ""- , repl "!" ""- , repl "[-/]" " "- , repl "\\[" "_ " -- Decided that I like the article included in titles- --, repl "^The " ""- , repl "&" " And "+ --, repl "^The " ""+ , repl "&" " And " , camelCase ]
src/EpubTools/EpubName/Opts.hs view
@@ -219,5 +219,5 @@ , " epub3: http://www.idpf.org/epub/30/spec/epub30-publications.html" , "" , ""- , "Version 2.4 Dino Morelli <dino@ui3.info>"+ , "Version 2.5 Dino Morelli <dino@ui3.info>" ]
src/EpubTools/EpubZip/Opts.hs view
@@ -70,5 +70,5 @@ , " epub3: http://www.idpf.org/epub/30/spec/epub30-publications.html" , "" , ""- , "Version 2.4 Dino Morelli <dino@ui3.info>"+ , "Version 2.5 Dino Morelli <dino@ui3.info>" ]
testsuite/EpubTools/Test/EpubName/Format.hs view
@@ -29,17 +29,22 @@ , testAuthorOneName , testAuthorRole , testAuthorFileas+ , testAuthorFileasParens , testAuthorFull , testMultiAutCreators , testMultiAutOneString , testNoAuthor+ , testColon , testCreatorsNoAuthor , testCreatorsNoAuthorPubDate , testCreatorLastFirst- , testCapsTitle- , testColon- , testBracketTitle- , testNoTitle+ , testTitleCaps+ , testTitleBracket+ , testTitleNone+ , testTitleMultiline+ , testTitleHyphen+ , testTitleHyphenDates+ , testTitleRomanNum , testAllPunctuation , testPubYearNoDatesPresent , testPubYearEpub3@@ -66,9 +71,10 @@ , testGudShort , testGudLong , testGudVeryLong- , testInterzoneOldShort- , testInterzoneOldLong , testInterzone+ , testInterzoneCaps+ , testInterzoneOldLong+ , testInterzoneOldShort , testNemesisShort , testNemesisLong , testMagSomethingWicked@@ -93,6 +99,10 @@ , testMagGalaxysEdge , testMagPlasmaFreq , testMagPlasmaFreqMonth+ , testMagPunchinello1800s+ , testMagGenericVolNo3+ , testMagSubjWithIssue+ , testWomensInstituteLib , testAnthology ] @@ -168,6 +178,24 @@ ) +testAuthorFileasParens :: (Globals, [Formatter]) -> Test+testAuthorFileasParens (gs, fs) = TestCase $+ assertNewName gs { gMetadata = meta } fs+ "author with file-as and pesky parenthesized full names" expected+ where+ meta = emptyMetadata+ { metaCreators = [Creator Nothing+ (Just "Fletcher, J. S. (Joseph Smith)")+ Nothing+ "J. S. Fletcher"]+ , metaTitles = [Title Nothing Nothing Nothing "The Middle of Things"]+ }+ expected =+ ( "ordinary_book"+ , "FletcherJS-TheMiddleOfThings.epub"+ )++ testAuthorFull :: (Globals, [Formatter]) -> Test testAuthorFull (gs, fs) = TestCase $ assertNewName gs { gMetadata = meta } fs "author fully filled out" expected@@ -258,6 +286,23 @@ ) +testColon :: (Globals, [Formatter]) -> Test+testColon (gs, fs) = TestCase $+ assertNewName gs { gMetadata = meta } fs+ "colon becomes underscore" expected+ where+ meta = emptyMetadata+ { metaCreators = [Creator Nothing Nothing Nothing+ "Ed Howdershelt"]+ , metaTitles = [Title Nothing Nothing Nothing + "Book 1: 3rd World Products, Inc."]+ }+ expected =+ ( "ordinary_book"+ , "HowdersheltEd-Book1_3rdWorldProductsInc.epub"+ )++ testCreatorsNoAuthorPubDate :: (Globals, [Formatter]) -> Test testCreatorsNoAuthorPubDate (gs, fs) = TestCase $ assertNewName gs { gMetadata = meta } fs@@ -300,8 +345,8 @@ ) -testCapsTitle :: (Globals, [Formatter]) -> Test-testCapsTitle (gs, fs) = TestCase $+testTitleCaps :: (Globals, [Formatter]) -> Test+testTitleCaps (gs, fs) = TestCase $ assertNewName gs { gMetadata = meta } fs "title all caps" expected where meta = emptyMetadata@@ -314,25 +359,8 @@ ) -testColon :: (Globals, [Formatter]) -> Test-testColon (gs, fs) = TestCase $- assertNewName gs { gMetadata = meta } fs- "colon becomes underscore" expected- where- meta = emptyMetadata- { metaCreators = [Creator Nothing Nothing Nothing- "Ed Howdershelt"]- , metaTitles = [Title Nothing Nothing Nothing - "Book 1: 3rd World Products, Inc."]- }- expected =- ( "ordinary_book"- , "HowdersheltEd-Book1_3rdWorldProductsInc.epub"- )---testBracketTitle :: (Globals, [Formatter]) -> Test-testBracketTitle (gs, fs) = TestCase $+testTitleBracket :: (Globals, [Formatter]) -> Test+testTitleBracket (gs, fs) = TestCase $ assertNewName gs { gMetadata = meta } fs "title with brackets" expected where@@ -347,8 +375,8 @@ ) -testNoTitle :: (Globals, [Formatter]) -> Test-testNoTitle (gs, fs) = TestCase $+testTitleNone :: (Globals, [Formatter]) -> Test+testTitleNone (gs, fs) = TestCase $ assertNewName gs { gMetadata = meta } fs "missing title" expected where meta = emptyMetadata@@ -361,6 +389,85 @@ ) +testTitleMultiline :: (Globals, [Formatter]) -> Test+testTitleMultiline (gs, fs) = TestCase $+ assertNewName gs { gMetadata = meta } fs+ "multiline title" expected+ where+ meta = emptyMetadata+ { metaCreators = [Creator+ Nothing+ (Just "Castleman, Virginia Carter")+ Nothing+ "Virginia Carter Castleman"]+ , metaTitles = [Title Nothing Nothing Nothing+ "Pocahontas.\nA Poem"]+ }+ expected =+ ( "ordinary_book"+ , "CastlemanVirginiaCarter-Pocahontas_APoem.epub"+ )+++testTitleHyphen :: (Globals, [Formatter]) -> Test+testTitleHyphen (gs, fs) = TestCase $+ assertNewName gs { gMetadata = meta } fs+ "title with hyphen" expected+ where+ meta = emptyMetadata+ { metaCreators = [Creator+ Nothing+ (Just "Spinoza, Benedictus de")+ Nothing+ "Benedictus de Spinoza"]+ , metaTitles = [Title Nothing Nothing Nothing+ "Theologico-Political Treatise"]+ }+ expected =+ ( "ordinary_book"+ , "SpinozaBenedictusDe-Theologico-PoliticalTreatise.epub"+ )+++testTitleHyphenDates :: (Globals, [Formatter]) -> Test+testTitleHyphenDates (gs, fs) = TestCase $+ assertNewName gs { gMetadata = meta } fs+ "title with hyphen separating dates" expected+ where+ meta = emptyMetadata+ { metaCreators = [Creator+ Nothing+ (Just "Anonymous")+ Nothing+ "Anonymous"]+ , metaTitles = [Title Nothing Nothing Nothing+ "Queen Victoria\nStory of Her Life and Reign, 1819-1901"]+ }+ expected =+ ( "ordinary_book"+ , "Anonymous-QueenVictoria_StoryOfHerLifeAndReign1819-1901.epub"+ )++testTitleRomanNum :: (Globals, [Formatter]) -> Test+testTitleRomanNum (gs, fs) = TestCase $+ assertNewName gs { gMetadata = meta } fs+ "title with Roman numerals" expected+ where+ meta = emptyMetadata+ { metaCreators = [Creator+ Nothing+ (Just "Hauptmann, Gerhart")+ Nothing+ "Gerhart Hauptmann"]+ , metaTitles = [Title Nothing Nothing Nothing+ "The Dramatic Works of Gerhart Hauptmann\nVolume III"]+ }+ expected =+ ( "ordinary_book"+ , "HauptmannGerhart-TheDramaticWorksOfGerhartHauptmann_VolumeIII.epub"+ )++ testAllPunctuation :: (Globals, [Formatter]) -> Test testAllPunctuation (gs, fs) = TestCase $ assertNewName gs { gMetadata = meta } fs "big test of all punctuation" expected@@ -373,7 +480,7 @@ } expected = ( "ordinary_book"- , "MorelliDino-TheCrazy_SandBoxOfSmedleysDiscontentLoathingFearAndMalnourishmentMaybeNot_Part2.epub"+ , "MorelliDino-TheCrazy_Sand-BoxOfSmedleysDiscontentLoathingFearAndMalnourishmentMaybeNot_Part2.epub" ) @@ -806,23 +913,40 @@ ) -testInterzoneOldShort :: (Globals, [Formatter]) -> Test-testInterzoneOldShort (gs, fs) = TestCase $+testInterzone :: (Globals, [Formatter]) -> Test+testInterzone (gs, fs) = TestCase $ assertNewName gs { gMetadata = meta } fs- "Interzone Magazine, old style, short" expected+ "Interzone Magazine, Smashwords style" expected where meta = emptyMetadata { metaCreators = [Creator Nothing Nothing - Nothing "TTA Press Authors"]+ Nothing "TTA Press"] , metaTitles = [Title Nothing Nothing Nothing - "Interzone SFF #212"]+ "Interzone 233 Mar - Apr 2011"] } expected =- ( "magInterzone_old"- , "InterzoneSFF212.epub"+ ( "magInterzone"+ , "InterzoneSFF233.epub" ) +testInterzoneCaps :: (Globals, [Formatter]) -> Test+testInterzoneCaps (gs, fs) = TestCase $+ assertNewName gs { gMetadata = meta } fs+ "Interzone Magazine, started in 2014" expected+ where+ meta = emptyMetadata+ { metaCreators = [Creator Nothing (Just "Interzone 249")+ Nothing "TTA Press"]+ , metaTitles = [Title Nothing Nothing Nothing + "INTERZONE #249 SCIENCE FICTION & FANTASY MAGAZINE (NOVâ\x80\x93DEC 2013)"]+ }+ expected =+ ( "magInterzone"+ , "InterzoneSFF249.epub"+ )++ testInterzoneOldLong :: (Globals, [Formatter]) -> Test testInterzoneOldLong (gs, fs) = TestCase $ assertNewName gs { gMetadata = meta } fs@@ -835,25 +959,25 @@ "Interzone Science Fiction and Fantasy Magazine #216"] } expected =- ( "magInterzone_old"+ ( "magInterzone" , "InterzoneSFF216.epub" ) -testInterzone :: (Globals, [Formatter]) -> Test-testInterzone (gs, fs) = TestCase $+testInterzoneOldShort :: (Globals, [Formatter]) -> Test+testInterzoneOldShort (gs, fs) = TestCase $ assertNewName gs { gMetadata = meta } fs- "Interzone Magazine, Smashwords style" expected+ "Interzone Magazine, old style, short" expected where meta = emptyMetadata { metaCreators = [Creator Nothing Nothing - Nothing "TTA Press"]+ Nothing "TTA Press Authors"] , metaTitles = [Title Nothing Nothing Nothing - "Interzone 233 Mar - Apr 2011"]+ "Interzone SFF #212"] } expected = ( "magInterzone"- , "InterzoneSFF233.epub"+ , "InterzoneSFF212.epub" ) @@ -1151,8 +1275,8 @@ "Jim Baen's Universe-Vol 4 Num 6"] } expected =- ( "magUniverse"- , "JimBaensUniverseVol04Num06.epub"+ ( "magGenericVolNo2"+ , "JimBaensUniverse-Vol04No06.epub" ) @@ -1285,6 +1409,81 @@ expected = ( "magGenericWithIssue" , "PlasmaFrequencyMagazine08.epub"+ )+++testMagPunchinello1800s :: (Globals, [Formatter]) -> Test+testMagPunchinello1800s (gs, fs) = TestCase $+ assertNewName gs { gMetadata = meta } fs+ "Punchinello magazine from the 1800s" expected+ where+ meta = emptyMetadata+ { metaTitles = [Title Nothing Nothing Nothing+ "Punchinello, Volume 1, No. 06, May 7, 1870"]+ }+ expected =+ ( "magGenericVolNo2"+ , "PunchinelloVol01No06.epub"+ )+++testMagGenericVolNo3 :: (Globals, [Formatter]) -> Test+testMagGenericVolNo3 (gs, fs) = TestCase $+ assertNewName gs { gMetadata = meta } fs+ "generic magazine with volume and 3-digit number" expected+ where+ meta = emptyMetadata+ { metaTitles = [Title Nothing Nothing Nothing+ "Blackwood's Edinburgh Magazine Volume 53, No. 327, January, 1843"]+ }+ expected =+ ( "magGenericVolNo3"+ , "BlackwoodsEdinburghMagazineVol53No327.epub"+ )+++testMagSubjWithIssue :: (Globals, [Formatter]) -> Test+testMagSubjWithIssue (gs, fs) = TestCase $+ assertNewName gs { gMetadata = meta } fs+ "with magazine subject and issue" expected+ where+ meta = emptyMetadata+ { metaTitles = [Title Nothing Nothing Nothing "The Dark Issue 1"]+ , metaCreators =+ [ Creator (Just "aut") (Just "Okorafor, Nnedi & Swirsky, Rachel & Slatter, Angela & Hannett, Lisa L.") Nothing+ "Nnedi Okorafor"+ , Creator (Just "aut") Nothing Nothing+ "Rachel Swirsky"+ ]+ , metaDates = [Date (Just "publication") "2013-10-01"]+ , metaSubjects =+ [ "magazine"+ , "horror"+ , "dark fantasy"+ ]+ }+ expected =+ ( "magGenericSubjWithIssue"+ , "TheDarkMagazine01.epub"+ )+++testWomensInstituteLib :: (Globals, [Formatter]) -> Test+testWomensInstituteLib (gs, fs) = TestCase $+ assertNewName gs { gOpts = testOpts, gMetadata = meta } fs+ "Women's Institute Library" expected+ where+ testOpts = (gOpts gs) { optPublisher = True }+ meta = emptyMetadata+ { metaCreators = [Creator Nothing+ (Just "Woman's Institute of Domestic Arts and Sciences")+ Nothing "Woman's Institute of Domestic Arts and Sciences"]+ , metaTitles = [Title Nothing Nothing Nothing+ "Woman's Institute Library of Cookery\nVolume 1: Essentials of Cookery; Cereals; Bread; Hot Breads"]+ }+ expected =+ ( "nonficWomensInstituteLibrary"+ , "WomansInstituteLibraryOfCookery_Volume1_EssentialsOfCookeryCerealsBreadHotBreads.epub" )