Skip to content

Commit 7f8a3c6

Browse files
hftfjgm
authored andcommitted
Consistent underline for Readers (#2270)
* Added underlineSpan builder function. This can be easily updated if needed. The purpose is for Readers to transform underlines consistently. * Docx Reader: Use underlineSpan and update test * Org Reader: Use underlineSpan and add test * Textile Reader: Use underlineSpan and add test case * Txt2Tags Reader: Use underlineSpan and update test * HTML Reader: Use underlineSpan and add test case
1 parent 2ddf086 commit 7f8a3c6

File tree

14 files changed

+39
-15
lines changed

14 files changed

+39
-15
lines changed

src/Text/Pandoc/Readers/Docx.hs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,12 +52,13 @@ implemented, [-] means partially implemented):
5252
* Inlines
5353
5454
- [X] Str
55-
- [X] Emph (italics and underline both read as Emph)
55+
- [X] Emph
5656
- [X] Strong
5757
- [X] Strikeout
5858
- [X] Superscript
5959
- [X] Subscript
6060
- [X] SmallCaps
61+
- [-] Underline (was previously converted to Emph)
6162
- [ ] Quoted
6263
- [ ] Cite
6364
- [X] Code (styled with `VerbatimChar`)
@@ -287,7 +288,7 @@ runStyleToTransform rPr
287288
| Just SubScrpt <- rVertAlign rPr =
288289
subscript . (runStyleToTransform rPr {rVertAlign = Nothing})
289290
| Just "single" <- rUnderline rPr =
290-
emph . (runStyleToTransform rPr {rUnderline = Nothing})
291+
underlineSpan . (runStyleToTransform rPr {rUnderline = Nothing})
291292
| otherwise = id
292293

293294
runToInlines :: PandocMonad m => Run -> DocxContext m Inlines

src/Text/Pandoc/Readers/HTML.hs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ import Text.Pandoc.Definition
4545
import qualified Text.Pandoc.Builder as B
4646
import Text.Pandoc.Builder (Blocks, Inlines, trimInlines, HasMeta(..))
4747
import Text.Pandoc.Shared ( extractSpaces, addMetaField
48-
, escapeURI, safeRead, crFilter )
48+
, escapeURI, safeRead, crFilter, underlineSpan )
4949
import Text.Pandoc.Options (
5050
ReaderOptions(readerExtensions,readerStripComments), extensionEnabled,
5151
Extension (Ext_epub_html_exts,
@@ -627,6 +627,7 @@ inline = choice
627627
, pSuperscript
628628
, pSubscript
629629
, pStrikeout
630+
, pUnderline
630631
, pLineBreak
631632
, pLink
632633
, pImage
@@ -696,6 +697,9 @@ pStrikeout = do
696697
contents <- mconcat <$> manyTill inline (pCloses "span")
697698
return $ B.strikeout contents)
698699

700+
pUnderline :: PandocMonad m => TagParser m Inlines
701+
pUnderline = pInlinesInTags "u" underlineSpan <|> pInlinesInTags "ins" underlineSpan
702+
699703
pLineBreak :: PandocMonad m => TagParser m Inlines
700704
pLineBreak = do
701705
pSelfClosing (=="br") (const True)

src/Text/Pandoc/Readers/Org/Inlines.hs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ import Text.Pandoc.Class (PandocMonad)
4545
import Text.Pandoc.Definition
4646
import Text.Pandoc.Options
4747
import Text.Pandoc.Readers.LaTeX (inlineCommand, rawLaTeXInline)
48+
import Text.Pandoc.Shared (underlineSpan)
4849
import Text.TeXMath (DisplayType (..), readTeX, writePandoc)
4950
import qualified Text.TeXMath.Readers.MathML.EntityMap as MathMLEntityMap
5051

@@ -572,9 +573,8 @@ strong = fmap B.strong <$> emphasisBetween '*'
572573
strikeout :: PandocMonad m => OrgParser m (F Inlines)
573574
strikeout = fmap B.strikeout <$> emphasisBetween '+'
574575

575-
-- There is no underline, so we use strong instead.
576576
underline :: PandocMonad m => OrgParser m (F Inlines)
577-
underline = fmap B.strong <$> emphasisBetween '_'
577+
underline = fmap underlineSpan <$> emphasisBetween '_'
578578

579579
verbatim :: PandocMonad m => OrgParser m (F Inlines)
580580
verbatim = return . B.code <$> verbatimBetween '='

src/Text/Pandoc/Readers/Textile.hs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ import Text.Pandoc.Options
6868
import Text.Pandoc.Parsing
6969
import Text.Pandoc.Readers.HTML (htmlTag, isBlockTag, isInlineTag)
7070
import Text.Pandoc.Readers.LaTeX (rawLaTeXBlock, rawLaTeXInline)
71-
import Text.Pandoc.Shared (trim, crFilter)
71+
import Text.Pandoc.Shared (trim, crFilter, underlineSpan)
7272
import Data.Text (Text)
7373
import qualified Data.Text as T
7474

@@ -468,7 +468,7 @@ inlineMarkup = choice [ simpleInline (string "??") (B.cite [])
468468
, simpleInline (string "__") B.emph
469469
, simpleInline (char '*') B.strong
470470
, simpleInline (char '_') B.emph
471-
, simpleInline (char '+') B.emph -- approximates underline
471+
, simpleInline (char '+') underlineSpan
472472
, simpleInline (char '-' <* notFollowedBy (char '-')) B.strikeout
473473
, simpleInline (char '^') B.superscript
474474
, simpleInline (char '~') B.subscript

src/Text/Pandoc/Readers/Txt2Tags.hs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ import qualified Text.Pandoc.Builder as B
4141
import Text.Pandoc.Definition
4242
import Text.Pandoc.Options
4343
import Text.Pandoc.Parsing hiding (space, spaces, uri)
44-
import Text.Pandoc.Shared (compactify, compactifyDL, escapeURI, crFilter)
44+
import Text.Pandoc.Shared (compactify, compactifyDL, escapeURI, crFilter, underlineSpan)
4545
import Control.Monad (guard, void, when)
4646
import Control.Monad.Reader (Reader, asks, runReader)
4747
import Data.Default
@@ -393,7 +393,7 @@ bold :: T2T Inlines
393393
bold = inlineMarkup inline B.strong '*' (B.str)
394394

395395
underline :: T2T Inlines
396-
underline = inlineMarkup inline B.emph '_' (B.str)
396+
underline = inlineMarkup inline underlineSpan '_' (B.str)
397397

398398
strike :: T2T Inlines
399399
strike = inlineMarkup inline B.strikeout '-' (B.str)

src/Text/Pandoc/Shared.hs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ module Text.Pandoc.Shared (
7272
addMetaField,
7373
makeMeta,
7474
eastAsianLineBreakFilter,
75+
underlineSpan,
7576
-- * TagSoup HTML handling
7677
renderTags',
7778
-- * File handling
@@ -563,6 +564,13 @@ eastAsianLineBreakFilter = bottomUp go
563564
_ -> x:SoftBreak:y:zs
564565
go xs = xs
565566

567+
-- | Builder for underline.
568+
-- This probably belongs in Builder.hs in pandoc-types.
569+
-- Will be replaced once Underline is an element.
570+
underlineSpan :: Inlines -> Inlines
571+
underlineSpan = B.spanWith ("", ["underline"], [])
572+
573+
566574
--
567575
-- TagSoup HTML handling
568576
--

test/Tests/Readers/Org.hs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import Test.Tasty
88
import Tests.Helpers
99
import Text.Pandoc
1010
import Text.Pandoc.Builder
11+
import Text.Pandoc.Shared (underlineSpan)
1112

1213
org :: Text -> Pandoc
1314
org = purely $ readOrg def{ readerExtensions = getDefaultExtensions "org" }
@@ -57,6 +58,10 @@ tests =
5758
" */super/*" =?>
5859
para (strong . emph $ "super")
5960

61+
, "Underline" =:
62+
"_underline_" =?>
63+
para (underlineSpan $ "underline")
64+
6065
, "Strikeout" =:
6166
"+Kill Bill+" =?>
6267
para (strikeout . spcSep $ [ "Kill", "Bill" ])

test/Tests/Readers/Txt2Tags.hs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import Text.Pandoc
1010
import Text.Pandoc.Arbitrary ()
1111
import Text.Pandoc.Builder
1212
import Text.Pandoc.Class
13+
import Text.Pandoc.Shared (underlineSpan)
1314

1415
t2t :: Text -> Pandoc
1516
-- t2t = handleError . readTxt2Tags (T2TMeta "date" "mtime" "in" "out") def
@@ -69,12 +70,12 @@ tests =
6970

7071
, "Inline markup is greedy" =:
7172
"***** ///// _____ ----- ````` \"\"\"\"\" '''''" =?>
72-
para (spcSep [strong "*", emph "/", emph "_"
73+
para (spcSep [strong "*", emph "/", underlineSpan "_"
7374
, strikeout "-", code "`", text "\""
7475
, rawInline "html" "'"])
7576
, "Markup must be greedy" =:
7677
"********** ////////// __________ ---------- `````````` \"\"\"\"\"\"\"\"\"\" ''''''''''" =?>
77-
para (spcSep [strong "******", emph "//////", emph "______"
78+
para (spcSep [strong "******", emph "//////", underlineSpan "______"
7879
, strikeout "------", code "``````", text "\"\"\"\"\"\""
7980
, rawInline "html" "''''''"])
8081
, "Inlines must be glued" =:

test/docx/inline_formatting.native

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
[Para [Str "Regular",Space,Str "text",Space,Emph [Str "italics"],Space,Strong [Str "bold",Space,Emph [Str "bold",Space,Str "italics"]],Str "."]
22
,Para [Str "This",Space,Str "is",Space,SmallCaps [Str "Small",Space,Str "Caps"],Str ",",Space,Str "and",Space,Str "this",Space,Str "is",Space,Strikeout [Str "strikethrough"],Str "."]
3-
,Para [Str "Some",Space,Str "people",Space,Str "use",Space,Emph [Str "single",Space,Str "underlines",Space,Str "for",Space,Emph [Str "emphasis"]],Str "."]
3+
,Para [Str "Some",Space,Str "people",Space,Str "use",Space,Span ("",["underline"],[]) [Str "single",Space,Str "underlines",Space,Str "for",Space,Emph [Str "emphasis"]],Str "."]
44
,Para [Str "Above",Space,Str "the",Space,Str "line",Space,Str "is",Space,Superscript [Str "superscript"],Space,Str "and",Space,Str "below",Space,Str "the",Space,Str "line",Space,Str "is",Space,Subscript [Str "subscript"],Str "."]
55
,Para [Str "A",Space,Str "line",LineBreak,Str "break."]]

test/html-reader.html

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -317,6 +317,8 @@ <h1>Inline Markup</h1>
317317
<p>So is <strong><em>this</em></strong> word.</p>
318318
<p>This is code: <code>&gt;</code>, <code>$</code>, <code>\</code>, <code>\$</code>, <code>&lt;html&gt;</code>.</p>
319319
<p>This is <span style="font-variant: small-caps;">small caps</span>.</p>
320+
<p>These are all underlined: <u>foo</u> and <ins>bar</ins>.</p>
321+
<p>These are all strikethrough: <s>foo</s>, <strike>bar</strike>, and <del>baz</del>.</p>
320322
<hr />
321323
<h1>Smart quotes, ellipses, dashes</h1>
322324
<p>"Hello," said the spider. "'Shelob' is my name."</p>

0 commit comments

Comments
 (0)