ods2csv 0.1 → 0.1.0.1
raw patch · 2 files changed
+37/−14 lines, 2 filesdep ~optparse-applicative
Dependency ranges changed: optparse-applicative
Files
- ods2csv.cabal +6/−3
- src/Main.hs +31/−11
ods2csv.cabal view
@@ -1,5 +1,5 @@ Name: ods2csv-Version: 0.1+Version: 0.1.0.1 Synopsis: Convert Open Document Spreadsheet ODS to CSV Description: Usually you would convert ODS to CSV via @libreoffice --headless@@@ -16,7 +16,7 @@ but might not be true if generated or manipulated by other tools. . You can feed generated CSV files to LaTeX @datatool.sty@, @csvmidi@,- or @csvreplace@ from Haskell package @spreadsheet@.+ Hledger's CSV import or @csvreplace@ from Haskell package @spreadsheet@. . Example runs of the program: .@@ -33,8 +33,11 @@ The program supports UTF-8 encoding for FODS/XML input, and applies Latin1 decoding otherwise. For writing CSV it uses the system's default encoding.+ You may only feed FODS, not ODS via pipe/stdin to the program. . ToDo: Provide FODS parser as library function, maybe in @spreadsheet@.+ .+ Alternatives: <https://www.visidata.org/>, <https://csvkit.rtfd.org/> Homepage: https://hub.darcs.net/thielema/ods2csv License: BSD3 License-File: LICENSE@@ -45,7 +48,7 @@ Cabal-Version: >=1.10 Source-Repository this- Tag: 0.1+ Tag: 0.1.0.1 Type: darcs Location: https://hub.darcs.net/thielema/ods2csv
src/Main.hs view
@@ -5,12 +5,13 @@ import qualified Options.Applicative as OP +import qualified Text.HTML.Tagchup.Format as TagFormat import qualified Text.HTML.Tagchup.Parser as TagParser import qualified Text.HTML.Tagchup.Process as TagProc import qualified Text.HTML.Tagchup.Tag.Match as TagMatch import qualified Text.HTML.Tagchup.Tag as Tag import qualified Text.XML.Basic.Attribute as Attr-import qualified Text.XML.Basic.Name.MixedCase as Name -- Qualified would also be appropriate+import qualified Text.XML.Basic.Name.MixedCase as Name import qualified Text.XML.Basic.Name as NameC import qualified Codec.Archive.Zip as Zip@@ -25,7 +26,8 @@ import qualified Data.Char as Char import Data.Function.HT (Id) import Data.Tuple.HT (mapSnd)-import Data.Maybe (mapMaybe)+import Data.Maybe.HT (toMaybe)+import Data.Maybe (mapMaybe, fromMaybe) import Data.Monoid ((<>)) import Control.Monad (join, guard)@@ -91,21 +93,39 @@ =<< readInput +{-+LibreOffice escapes double spaces as in @Foo Bar@ like so:++> <text:p>Foo <text:s/>Baar</text:p>+-}+flattenText :: [Tag.T Name.T String] -> String+flattenText =+ concatMap+ (\tag ->+ fromMaybe+ (printf "*** unexpected tag %s in cell text ***"+ (TagFormat.xml [tag] "")) $+ Tag.maybeText tag+ <|>+ toMaybe (TagMatch.openNameLit "text:s" tag) " "+ <|>+ toMaybe (TagMatch.closeNameLit "text:s" tag) "")+ extractTablesContents :: [Tag.T Name.T String] -> [(String, [[String]])] extractTablesContents = map (mapSnd ( map (concatMap (uncurry $ \n ->- (\texts ->- replicate n $- case texts of- text:_ -> text- [] -> "")- .- mapMaybe Tag.maybeText- .- dropWhile (not . TagMatch.openNameLit "text:p"))+ replicate n+ .+ flattenText+ .+ takeWhile (not . TagMatch.closeNameLit "text:p")+ .+ drop 1+ .+ dropWhile (not . TagMatch.openNameLit "text:p")) . snd .