git.iko.soy/typeable/pandoc
on master help sign in
Docx reader: Parse instrText info in fldChar tags.

We introduce a new module, Text.Pandoc.Readers.Docx.Fields which contains a simple parsec parser. At the moment, only simple hyperlink fields are accepted, but that can be extended in the future.

commitae8c0cdba82c9cfb847025c3f5ca410407b0fb96 authorJesse Rosenthal <jrosenthal@jhu.edu> dateTue 16 Jan 2018, 12:50 (9 years ago) parent404706d
3 files changed+103−5
pandoc.cabal+1 src/Text/Pandoc/Readers/Docx/Fields.hs+89 src/Text/Pandoc/Readers/Docx/Parse.hs+13−5
pandoc.cabal+1
@@ -508,6 +508,7 @@ library
508508 Text.Pandoc.Readers.Docx.Parse,
509509 Text.Pandoc.Readers.Docx.Util,
510510 Text.Pandoc.Readers.Docx.StyleMap,
511+ Text.Pandoc.Readers.Docx.Fields,
511512 Text.Pandoc.Readers.Odt.Base,
512513 Text.Pandoc.Readers.Odt.Namespaces,
513514 Text.Pandoc.Readers.Odt.StyleReader,
src/Text/Pandoc/Readers/Docx/Fields.hsnew file+89
@@ -0,0 +1,89 @@
1+{-
2+Copyright (C) 2014-2018 Jesse Rosenthal <jrosenthal@jhu.edu>
3+
4+This program is free software; you can redistribute it and/or modify
5+it under the terms of the GNU General Public License as published by
6+the Free Software Foundation; either version 2 of the License, or
7+(at your option) any later version.
8+
9+This program is distributed in the hope that it will be useful,
10+but WITHOUT ANY WARRANTY; without even the implied warranty of
11+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+GNU General Public License for more details.
13+
14+You should have received a copy of the GNU General Public License
15+along with this program; if not, write to the Free Software
16+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17+-}
18+
19+{- |
20+ Module : Text.Pandoc.Readers.Docx.Fields
21+ Copyright : Copyright (C) 2014-2018 Jesse Rosenthal
22+ License : GNU GPL, version 2 or above
23+
24+ Maintainer : Jesse Rosenthal <jrosenthal@jhu.edu>
25+ Stability : alpha
26+ Portability : portable
27+
28+For parsing Field definitions in instText tags, as described in
29+ECMA-376-1:2016, §17.16.5 -}
30+
31+module Text.Pandoc.Readers.Docx.Fields ( FieldInfo(..)
32+ , parseFieldInfo
33+ ) where
34+
35+import Text.Parsec
36+import Text.Parsec.String (Parser)
37+
38+type URL = String
39+
40+data FieldInfo = HyperlinkField URL
41+ | UnknownField
42+ deriving (Show)
43+
44+parseFieldInfo :: String -> Either ParseError FieldInfo
45+parseFieldInfo = parse fieldInfo ""
46+
47+fieldInfo :: Parser FieldInfo
48+fieldInfo =
49+ (try $ HyperlinkField <$> hyperlink)
50+ <|>
51+ return UnknownField
52+
53+escapedQuote :: Parser String
54+escapedQuote = string "\\\""
55+
56+inQuotes :: Parser String
57+inQuotes = do
58+ (try escapedQuote) <|> (anyChar >>= (\c -> return [c]))
59+
60+quotedString :: Parser String
61+quotedString = do
62+ char '"'
63+ concat <$> manyTill inQuotes (try (char '"'))
64+
65+unquotedString :: Parser String
66+unquotedString = manyTill anyChar (try (space))
67+
68+fieldArgument :: Parser String
69+fieldArgument = quotedString <|> unquotedString
70+
71+-- there are other switches, but this is the only one I've seen in the wild so far, so it's the first one I'll implement. See §17.16.5.25
72+hyperlinkSwitch :: Parser (String, String)
73+hyperlinkSwitch = do
74+ sw <- string "\\l"
75+ spaces
76+ farg <- fieldArgument
77+ return (sw, farg)
78+
79+hyperlink :: Parser URL
80+hyperlink = do
81+ many space
82+ string "HYPERLINK"
83+ spaces
84+ farg <- fieldArgument
85+ switches <- (spaces *> many hyperlinkSwitch)
86+ let url = case switches of
87+ ("\\l", s) : _ -> farg ++ ('#': s)
88+ _ -> farg
89+ return url
src/Text/Pandoc/Readers/Docx/Parse.hs+13−5
@@ -54,6 +54,7 @@ module Text.Pandoc.Readers.Docx.Parse ( Docx(..)
5454 , TrackedChange(..)
5555 , ChangeType(..)
5656 , ChangeInfo(..)
57+ , FieldInfo(..)
5758 , archiveToDocx
5859 , archiveToDocxWithWarnings
5960 ) where
@@ -70,6 +71,7 @@ import qualified Data.Map as M
7071import Data.Maybe
7172import System.FilePath
7273import Text.Pandoc.Readers.Docx.Util
74+import Text.Pandoc.Readers.Docx.Fields
7375import Text.Pandoc.Shared (filteredFilesFromArchive, safeRead)
7476import qualified Text.Pandoc.UTF8 as UTF8
7577import Text.TeXMath (Exp)
@@ -286,10 +288,6 @@ data Run = Run RunStyle [RunElem]
286288 | InlineChart -- placeholder
287289 deriving Show
288290
289−data FieldInfo = HyperlinkField URL
290− | UnknownField
291− deriving (Show)
292−
293291data RunElem = TextRun String | LnBrk | Tab | SoftHyphen | NoBreakHyphen
294292 deriving Show
295293
@@ -802,8 +800,18 @@ elemToParPart ns element
802800 return NullParPart
803801 FldCharContent info runs | fldCharType == "end" -> do
804802 modify $ \st -> st {stateFldCharState = FldCharClosed}
805− return $ Field info runs
803+ return $ Field info $ reverse runs
806804 _ -> throwError WrongElem
805+elemToParPart ns element
806+ | isElem ns "w" "r" element
807+ , Just instrText <- findChildByName ns "w" "instrText" element = do
808+ fldCharState <- gets stateFldCharState
809+ case fldCharState of
810+ FldCharOpen -> do
811+ info <- eitherToD $ parseFieldInfo $ strContent instrText
812+ modify $ \st -> st{stateFldCharState = FldCharFieldInfo info}
813+ return NullParPart
814+ _ -> return NullParPart
807815elemToParPart ns element
808816 | isElem ns "w" "r" element = do
809817 run <- elemToRun ns element