Skip to content

Commit

Permalink
Restore multiline LaTeX (#2544)
Browse files Browse the repository at this point in the history
  • Loading branch information
odow authored Mar 26, 2021
1 parent d23f4bc commit 2b08a39
Show file tree
Hide file tree
Showing 4 changed files with 61 additions and 55 deletions.
2 changes: 1 addition & 1 deletion docs/Project.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ XLSX = "fdbf4ff8-1666-58a4-91e7-1b58723a45e0"
[compat]
CSV = "0.8"
DataFrames = "0.22"
Documenter = "~0.26"
Documenter = "~0.26.2"
GLPK = "0.14.4"
Ipopt = "0.6"
Literate = "2.8"
Expand Down
5 changes: 4 additions & 1 deletion docs/src/manual/models.md
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,10 @@ Subject to
Use [`latex_formulation`](@ref) to display the model in LaTeX form.
```jldoctest model_print
julia> latex_formulation(model)
$$ \begin{aligned}\max\quad & x\\\text{Subject to} \quad & x \geq 0.0\\\end{aligned} $$
$$ \begin{aligned}
\max\quad & x\\
\text{Subject to} \quad & x \geq 0.0\\
\end{aligned} $$
```

In IJulia (and Documenter), ending a cell in with [`latex_formulation`](@ref)
Expand Down
24 changes: 13 additions & 11 deletions src/print.jl
Original file line number Diff line number Diff line change
Expand Up @@ -305,20 +305,23 @@ An `AbstractModel` subtype should implement `objective_function_string`,
`constraints_string` and `_nl_subexpression_string` for this method to work.
"""
function _print_latex(io::IO, model::AbstractModel)
print(io, "\$\$ \\begin{aligned}")
println(io, "\$\$ \\begin{aligned}")
sense = objective_sense(model)
if sense == MOI.MAX_SENSE
print(io, "\\max\\quad & ")
print(io, objective_function_string(IJuliaMode, model), "\\\\")
println(io, objective_function_string(IJuliaMode, model), "\\\\")
elseif sense == MOI.MIN_SENSE
print(io, "\\min\\quad & ")
print(io, objective_function_string(IJuliaMode, model), "\\\\")
println(io, objective_function_string(IJuliaMode, model), "\\\\")
else
print(io, "\\text{feasibility}\\\\")
println(io, "\\text{feasibility}\\\\")
end
print(io, "\\text{Subject to} \\quad")
for constraint in constraints_string(IJuliaMode, model)
print(io, " & ", constraint, "\\\\")
constraints = constraints_string(IJuliaMode, model)
if !isempty(constraints)
print(io, "\\text{Subject to} \\quad")
end
for constraint in constraints
println(io, " & ", constraint, "\\\\")
end
# TODO: Generalize this when similar functionality is needed for
# `AbstractModel`.
Expand All @@ -327,7 +330,7 @@ function _print_latex(io::IO, model::AbstractModel)
print(io, "\\text{With NL expressions} \\quad")
end
for expr in nl_subexpressions
print(io, " & ", expr, "\\\\")
println(io, " & ", expr, "\\\\")
end
return print(io, "\\end{aligned} \$\$")
end
Expand Down Expand Up @@ -831,8 +834,7 @@ function function_string(
print_mode::Type{IJuliaMode},
A::AbstractMatrix{<:AbstractJuMPScalar},
)
str = sprint(show, MIME"text/plain"(), A)
str = "\\begin{bmatrix}"
str = "\\begin{bmatrix}\n"
for i in 1:size(A, 1)
line = ""
for j in 1:size(A, 2)
Expand All @@ -845,7 +847,7 @@ function function_string(
line *= function_string(print_mode, A[i, j])
end
end
str *= line * "\\\\"
str *= line * "\\\\\n"
end
return str * "\\end{bmatrix}"
end
Expand Down
85 changes: 43 additions & 42 deletions test/print.jl
Original file line number Diff line number Diff line change
Expand Up @@ -593,37 +593,38 @@ Names registered in the model: a, a1, b, b1, c, c1, con, fi, soc, u, x, y, z""",
io_test(
IJuliaMode,
model_1,
"\\begin{aligned}\\max\\quad & a - b + 2 a1 - 10 x\\\\" *
"\\text{Subject to} \\quad & a + b - 10 c + c1 - 2 x \\leq 1.0\\\\" *
" & a\\times b \\leq 2.0\\\\" *
" & \\begin{bmatrix}" *
"a & b\\\\" *
"\\cdot & x\\\\" *
"\\end{bmatrix} \\in \\text{PSDCone()}\\\\" *
" & [a, b, c] \\in \\text{MathOptInterface.PositiveSemidefiniteConeTriangle(2)}\\\\" *
" & \\begin{bmatrix}" *
"a & b\\\\" *
"c & x\\\\" *
"\\end{bmatrix} \\in \\text{PSDCone()}\\\\" *
" & [a, b, c, x] \\in \\text{MathOptInterface.PositiveSemidefiniteConeSquare(2)}\\\\" *
" & [-a + 1, u_{1}, u_{2}, u_{3}] \\in \\text{MathOptInterface.SecondOrderCone(4)}\\\\" *
" & fi = 9.0\\\\" *
" & a \\geq 1.0\\\\" *
" & c \\geq -1.0\\\\" *
" & a1 \\geq 1.0\\\\" *
" & c1 \\geq -1.0\\\\" *
" & b \\leq 1.0\\\\" *
" & c \\leq 1.0\\\\" *
" & b1 \\leq 1.0\\\\" *
" & c1 \\leq 1.0\\\\" *
" & a1 \\in \\mathbb{Z}\\\\" *
" & b1 \\in \\mathbb{Z}\\\\" *
" & c1 \\in \\mathbb{Z}\\\\" *
" & z \\in \\mathbb{Z}\\\\" *
" & x \\in \\{0, 1\\}\\\\" *
" & u_{1} \\in \\{0, 1\\}\\\\" *
" & u_{2} \\in \\{0, 1\\}\\\\" *
" & u_{3} \\in \\{0, 1\\}\\\\" *
"\\begin{aligned}\n" *
"\\max\\quad & a - b + 2 a1 - 10 x\\\\\n" *
"\\text{Subject to} \\quad & a + b - 10 c + c1 - 2 x \\leq 1.0\\\\\n" *
" & a\\times b \\leq 2.0\\\\\n" *
" & \\begin{bmatrix}\n" *
"a & b\\\\\n" *
"\\cdot & x\\\\\n" *
"\\end{bmatrix} \\in \\text{PSDCone()}\\\\\n" *
" & [a, b, c] \\in \\text{MathOptInterface.PositiveSemidefiniteConeTriangle(2)}\\\\\n" *
" & \\begin{bmatrix}\n" *
"a & b\\\\\n" *
"c & x\\\\\n" *
"\\end{bmatrix} \\in \\text{PSDCone()}\\\\\n" *
" & [a, b, c, x] \\in \\text{MathOptInterface.PositiveSemidefiniteConeSquare(2)}\\\\\n" *
" & [-a + 1, u_{1}, u_{2}, u_{3}] \\in \\text{MathOptInterface.SecondOrderCone(4)}\\\\\n" *
" & fi = 9.0\\\\\n" *
" & a \\geq 1.0\\\\\n" *
" & c \\geq -1.0\\\\\n" *
" & a1 \\geq 1.0\\\\\n" *
" & c1 \\geq -1.0\\\\\n" *
" & b \\leq 1.0\\\\\n" *
" & c \\leq 1.0\\\\\n" *
" & b1 \\leq 1.0\\\\\n" *
" & c1 \\leq 1.0\\\\\n" *
" & a1 \\in \\mathbb{Z}\\\\\n" *
" & b1 \\in \\mathbb{Z}\\\\\n" *
" & c1 \\in \\mathbb{Z}\\\\\n" *
" & z \\in \\mathbb{Z}\\\\\n" *
" & x \\in \\{0, 1\\}\\\\\n" *
" & u_{1} \\in \\{0, 1\\}\\\\\n" *
" & u_{2} \\in \\{0, 1\\}\\\\\n" *
" & u_{3} \\in \\{0, 1\\}\\\\\n" *
"\\end{aligned}",
repl = :print,
)
Expand Down Expand Up @@ -737,10 +738,11 @@ Names registered in the model: a, a1, b, b1, c, c1, fi, u, x, y, z""",
io_test(
IJuliaMode,
model_1,
"\\begin{aligned}\\max\\quad & a - b + 2 a1 - 10 x\\\\" *
"\\text{Subject to} \\quad & a + b - 10 c - 2 x + c1 \\leq 1.0\\\\" *
" & a\\times b \\leq 2.0\\\\" *
" & [-a + 1, u_{1}, u_{2}, u_{3}] \\in \\text{MathOptInterface.SecondOrderCone(4)}\\\\" *
"\\begin{aligned}\n" *
"\\max\\quad & a - b + 2 a1 - 10 x\\\\\n" *
"\\text{Subject to} \\quad & a + b - 10 c - 2 x + c1 \\leq 1.0\\\\\n" *
" & a\\times b \\leq 2.0\\\\\n" *
" & [-a + 1, u_{1}, u_{2}, u_{3}] \\in \\text{MathOptInterface.SecondOrderCone(4)}\\\\\n" *
"\\end{aligned}",
repl = :print,
)
Expand Down Expand Up @@ -825,9 +827,10 @@ With NL expressions
io_test(
IJuliaMode,
model,
"\\begin{aligned}\\max\\quad & sin(x)\\\\" *
"\\text{Subject to} \\quad & subexpression_{1} - 0.0 = 0\\\\" *
"\\text{With NL expressions} \\quad & subexpression_{1}: cos(x)\\\\" *
"\\begin{aligned}\n" *
"\\max\\quad & sin(x)\\\\\n" *
"\\text{Subject to} \\quad & subexpression_{1} - 0.0 = 0\\\\\n" *
"\\text{With NL expressions} \\quad & subexpression_{1}: cos(x)\\\\\n" *
"\\end{aligned}",
repl = :print,
)
Expand All @@ -847,8 +850,7 @@ With NL expressions
io_test(
IJuliaMode,
Model(),
"\\begin{aligned}\\text{feasibility}\\\\" *
"\\text{Subject to} \\quad\\end{aligned}",
"\\begin{aligned}\n\\text{feasibility}\\\\\n\\end{aligned}",
repl = :print,
)
end
Expand All @@ -859,8 +861,7 @@ With NL expressions
io_test(
IJuliaMode,
model,
"\\begin{aligned}\\min\\quad & x\\\\" *
"\\text{Subject to} \\quad\\end{aligned}",
"\\begin{aligned}\n\\min\\quad & x\\\\\n\\end{aligned}",
repl = :print,
)
end
Expand Down

0 comments on commit 2b08a39

Please sign in to comment.