Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Resize long expressions in LaTeX to prevent overflow #3910

Merged
merged 6 commits into from
Aug 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 22 additions & 6 deletions code/drasil-printers/lib/Language/Drasil/TeX/Helpers.hs
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,7 @@ import Data.List (isSuffixOf)
-- | Helper for adding fencing symbols.
br, sq, parens, quote :: D -> D
-- | Curly braces.
br x = lb <> x <> rb
where
lb = pure $ text "{"
rb = pure $ text "}"
br x = lbrace <> x <> rbrace
-- | Square brackets.
sq x = ls <> x <> rs
where
Expand All @@ -45,6 +42,12 @@ quote x = lq <> x <> rq
lq = pure $ text "``"
rq = pure $ text "''"

lbrace, rbrace :: D
-- | Helper for opening curly brace.
lbrace = pure $ text "{"
-- | Helper for closing curly brace.
rbrace = pure $ text "}"

-- | 0-argument command.
command0 :: String -> D
command0 s = pure $ H.bslash TP.<> text s
Expand Down Expand Up @@ -276,8 +279,21 @@ useTikz = usepackage "luatex85" $+$ command0 "def" <>
-- on Monad...

-- | toEqn is special; it switches to 'Math', but inserts an equation environment.
toEqn :: D -> D
toEqn (PL g) = equation $ PL (\_ -> g Math)
-- The 'scale' parameter determines the maximum width of the equation based on
-- the corresponding scaling command.
toEqn :: ExprScale -> D -> D
toEqn scale (PL g) = equation $ command2D "resizeExpression" (PL (\_ -> g Math)) (command0 (show scale))

-- | Represents the scaling factor for an equation.
-- 'InDef' and 'OutDef' correspond to predefined scaling commands.
-- Commands are defined in 'Preamble.hs'
data ExprScale = InDef | OutDef

-- | Provides a string representation for 'ExprScale' values.
-- Used to convert 'ExprScale' to the corresponding command string.
instance Show ExprScale where
show InDef = "inDefScale"
show OutDef = "outDefScale"

-----------------------------------------------------------------------------
-- | Helper(s) for String-Printing in TeX where it varies from HTML/Plaintext.
Expand Down
4 changes: 4 additions & 0 deletions code/drasil-printers/lib/Language/Drasil/TeX/Monad.hs
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,10 @@ vpunctuate x = tpRunPrint (TP.vcat . TP.punctuate x)
-- Combine 'TP.hcat' and 'TP.punctuate'.
hpunctuate :: TP.Doc -> [D] -> D
hpunctuate x = tpRunPrint (TP.hcat . TP.punctuate x)

-- | Nest a 'D' by a specified indentation level.
nest :: Int -> D -> D
nest i (PL f) = PL $ \ctx -> TP.nest i (f ctx)
--------
-- | MathContext operations.
lub :: MathContext -> MathContext -> MathContext
Expand Down
31 changes: 28 additions & 3 deletions code/drasil-printers/lib/Language/Drasil/TeX/Preamble.hs
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,12 @@ module Language.Drasil.TeX.Preamble (genPreamble) where

import Data.List (nub)

import Text.PrettyPrint (text)
import Language.Drasil.Printing.LayoutObj (LayoutObj(..))
import Language.Drasil.TeX.Monad (D, vcat, (%%))
import Language.Drasil.TeX.Monad (D, vcat, (%%), nest)
import Language.Drasil.TeX.Helpers (docclass, command, command1o, command2, command3,
usepackage)
usepackage, command0, lbrace, rbrace, ExprScale(InDef, OutDef))
import Language.Drasil.Printing.Helpers (sq, brace)

import Language.Drasil.Config (hyperSettings, fontSize, bibFname)

Expand Down Expand Up @@ -35,6 +37,8 @@ data Package = AMSMath -- ^ Improves information structure for mathematical
| EnumItem -- ^ Contol basic list environments.
| SVG -- ^ For rendering svg diagrams.
| Float -- ^ For enhanced control over placement of figures and tables.
| Graphicx -- ^ Resizebox for large expressions.
| Calc -- ^ Perform arithmetic operation in LaTeX commands.
deriving Eq

-- | Adds a 'Package' to the LaTeX document.
Expand Down Expand Up @@ -66,6 +70,8 @@ addPackage Unicode = usepackage "unicode-math"
addPackage EnumItem = usepackage "enumitem"
addPackage SVG = usepackage "svg"
addPackage Float = usepackage "float"
addPackage Graphicx = usepackage "graphicx"
addPackage Calc = usepackage "calc"

-- | Common LaTeX commands.
data Def = Bibliography
Expand All @@ -74,6 +80,10 @@ data Def = Bibliography
| SetMathFont
| SymbDescriptionP1
| SymbDescriptionP2
| SaveBox
| InDefScale
| OutDefScale
| ResizeExpr
deriving Eq

-- | Define common LaTeX commands.
Expand All @@ -84,6 +94,21 @@ addDef LessThan = command2 "newcommand" "\\lt" "\\ensuremath <"
addDef SetMathFont = command "setmathfont" "Latin Modern Math"
addDef SymbDescriptionP1 = command3 "newlist" "symbDescription" "description" "1"
addDef SymbDescriptionP2 = command1o "setlist" (Just "symbDescription") "noitemsep, topsep=0pt, parsep=0pt, partopsep=0pt"
addDef SaveBox = command "newsavebox" "\\mybox"
addDef InDefScale = command0 "def" <> command (show InDef) "0.8"
addDef OutDefScale = command0 "def" <> command (show OutDef) "1.0"
addDef ResizeExpr = vcat [
command "newcommand" "\\resizeExpression" <> pure (sq "2") <> lbrace,
nest 2 $ vcat [
command2 "savebox" "\\mybox" "$#1$",
command0 "ifdim" <> command0 "wd" <> command0 "mybox" <> pure (text ">#2") <> command0 "linewidth",
nest 2 $ command3 "resizebox" "#2\\textwidth" "!" ("\\usebox" ++ brace "\\mybox"),
command0 "else",
nest 2 $ command "usebox" "\\mybox",
command0 "fi"
],
rbrace
]

-- | Generates LaTeX document preamble.
genPreamble :: [LayoutObj] -> D
Expand Down Expand Up @@ -117,6 +142,6 @@ parseDoc los' =
parseDoc' Header{} = ([], [])
parseDoc' Paragraph{} = ([], [])
parseDoc' List{} = ([EnumItem], [])
parseDoc' EqnBlock{} = ([], [])
parseDoc' EqnBlock{} = ([Graphicx, Calc], [InDefScale, OutDefScale, SaveBox, ResizeExpr])
parseDoc' Cell{} = ([], [])
parseDoc' CodeBlock{} = ([], [])
29 changes: 21 additions & 8 deletions code/drasil-printers/lib/Language/Drasil/TeX/Print.hs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ import Language.Drasil.TeX.Helpers (author, bold, br, caption, center, centering
empty, enumerate, externalref, figure, fraction, includegraphics, item, item',
itemize, label, maketitle, maketoc, mathbb, mkEnv, mkEnvArgBr, mkEnvArgSq,
mkMinipage, newline, newpage, parens, quote, sec, snref, sq, superscript,
symbDescription, texSym, title, toEqn)
symbDescription, texSym, title, toEqn, ExprScale(InDef, OutDef))
import Language.Drasil.TeX.Monad (D, MathContext(Curr, Math, Text), (%%), ($+$),
hpunctuate, lub, runPrint, switch, toMath, toText, unPL, vcat, vpunctuate)
import Language.Drasil.TeX.Preamble (genPreamble)
Expand Down Expand Up @@ -62,7 +62,7 @@ lo :: LayoutObj -> PrintingInformation -> D
lo (Header d t l) _ = sec d (spec t) %% label (spec l)
lo (HDiv _ con _) sm = print sm con -- FIXME ignoring 2 arguments?
lo (Paragraph contents) _ = toText $ newline (spec contents)
lo (EqnBlock contents) _ = makeEquation contents
lo (EqnBlock contents) _ = makeEquation contents OutDef
lo (Table _ rows r bl t) _ = toText $ makeTable rows (spec r) bl (spec t)
lo (Definition _ ssPs l) sm = toText $ makeDefn sm ssPs $ spec l
lo (List l) _ = toText $ makeList l
Expand All @@ -76,10 +76,22 @@ lo (Graph ps w h c l) _ = toText $ makeGraph
lo (Cell _) _ = empty
lo (CodeBlock _) _ = empty

-- | Helper for converting layout objects into a more printable form.
-- This function is specific to definitions.
lo' :: LayoutObj -> PrintingInformation -> D
lo' (HDiv _ con _) sm = printDef sm con
JacquesCarette marked this conversation as resolved.
Show resolved Hide resolved
lo' (EqnBlock contents) _ = makeEquation contents InDef
lo' obj sm = lo obj sm

-- | Converts layout objects into a document form.
print :: PrintingInformation -> [LayoutObj] -> D
print sm = foldr (($+$) . (`lo` sm)) empty

-- | Converts layout objects into a document form.
-- Specific to Definitions.
printDef :: PrintingInformation -> [LayoutObj] -> D
printDef sm = foldr (($+$) . (`lo'` sm)) empty

-- | Determine wether braces and brackets are opening or closing.
data OpenClose = Open | Close

Expand Down Expand Up @@ -345,17 +357,18 @@ makeDefTable sm ps l = mkEnvArgBr "tabular" (col rr colAwidth ++ col (rr ++ "\\a

-- | Helper that makes the rows of a definition table.
makeDRows :: PrintingInformation -> [(String,[LayoutObj])] -> D
makeDRows _ [] = error "No fields to create Defn table"
makeDRows sm ls = foldl1 (%%) $ map (\(f, d) -> dBoilerplate %% pure (text (f ++ " & ")) <> print sm d) ls
where dBoilerplate = pure $ dbs <+> text "\\midrule"
makeDRows _ [] = error "No fields to create Defn table"
makeDRows sm ls = foldl1 (%%) $ map (\(f, d) ->
pure (dbs <+> text "\\midrule") %%
pure (text (f ++ " & ")) <> printDef sm d) ls

-----------------------------------------------------------------
------------------ EQUATION PRINTING------------------------
-----------------------------------------------------------------

-- | Prints an equation.
makeEquation :: Spec -> D
makeEquation contents = toEqn (spec contents)
-- | Prints an equation with a maximum width determined by the given scale.
makeEquation :: Spec -> ExprScale -> D
makeEquation contents scale = toEqn scale (spec contents)

--TODO: Add auto-generated labels -> Need to be able to ensure labeling based
-- on chunk (i.e. "eq:h_g" for h_g = ...
Expand Down
Loading