diff --git a/CHANGELOG.md b/CHANGELOG.md index f1255e7..a29b5b6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,7 +5,11 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). - + ## [v1.1.0] - 2023-11-13 ### Added diff --git a/Project.toml b/Project.toml index a3c9abe..ae29cdc 100644 --- a/Project.toml +++ b/Project.toml @@ -2,7 +2,17 @@ name = "Changelog" uuid = "5217a498-cd5d-4ec6-b8c2-9b85a09b6e3e" version = "1.1.0" +[deps] +AbstractTrees = "1520ce14-60c1-5f80-bbc7-55ef81b5835c" +CommonMark = "a80b9123-70ca-4bc0-993e-6e3bcb318db6" +Dates = "ade2ca70-3891-5945-98fb-dc099432e06a" +MarkdownAST = "d0879d2d-cac2-40c8-9cee-1863dc0c7391" + [compat] +AbstractTrees = "0.4.5" +CommonMark = "0.8.15" +Dates = "1" +MarkdownAST = "0.1.2" julia = "1.6" [extras] diff --git a/README.md b/README.md index e405841..d22e5f3 100644 --- a/README.md +++ b/README.md @@ -52,3 +52,44 @@ The typical workflow is as follows: - Description of new feature with reference to pull request ([#123](https://github.com/JuliaDocs/Changelog.jl/issues/123)). ``` + +### Parsing changelogs + +Changelog also provides functionality for parsing changelogs into a simple structure which can be programmatically queried, +e.g. to check what the changes are for a particular version. This functionality is primarily intended for parsing [KeepAChangeLog](https://keepachangelog.com/en/1.1.0/)-style changelogs, that have a title as a H1 (e.g. `#`) markdown header, followed by a list of versions with H2-level headers (`##`) formatted like `[1.1.0] - 2019-02-15` with or without a link on the version number, followed by a bulleted list of changes, potentially in subsections, each with H3 header. For such changelogs, parsing should be stable. We may also attempt to parse a wider variety of headers, for which the extent that we can parse may change in non-breaking releases (typically improving the parsing, but potentially regressing in some cases). + +The API for this functionality consists of: + +- `SimpleChangelog`: structure that contains a simple representation of a changelog. +- `VersionInfo`: structure that contains a simple representation of a version in a changelog. +- `Base.parse(SimpleChangelog, str)`: parse a markdown-formatted string into a `SimpleChangelog` and likewise `Base.tryparse` +- `Changelog.parsefile` (and `Changelog.tryparsefile`): parses a markdown-formatted file into a `SimpleChangelog` + +For example, using `Changelog.parsefile` on the [CHANGELOG.md](./CHANGELOG.md) as of version 1.1 gives: + +```julia +julia> changelog = Changelog.parsefile("CHANGELOG.md") +SimpleChangelog with +- title: Changelog.jl changelog +- intro: All notable changes to this project will be documented in this file. +- 2 versions: + - 1.1.0 + - url: https://github.com/JuliaDocs/Changelog.jl/releases/tag/v1.1.0 + - date: 2023-11-13 + - changes + - Added + - Links of the form `[]`, where `` is a commit hashof length 7 or 40, are now linkified. (#4) + - 1.0.0 + - url: https://github.com/JuliaDocs/Changelog.jl/releases/tag/v1.0.0 + - date: 2023-11-13 + - changes + - First release. See README.md for currently supported functionality. +``` + +The changes for 1.1.0 can be obtained by `changelog.versions[1].sectioned_changes`: + +```julia +julia> changelog.versions[1].sectioned_changes +1-element Vector{Pair{String, Vector{String}}}: + "Added" => ["Links of the form `[]`, where `` is a commit hashof length 7 or 40, are now linkified. (#4)"] +``` diff --git a/src/Changelog.jl b/src/Changelog.jl index 84b4065..04da3b0 100644 --- a/src/Changelog.jl +++ b/src/Changelog.jl @@ -7,9 +7,27 @@ documentation. """ module Changelog -VERSION >= v"1.11.0-DEV.469" && eval(Meta.parse("public generate")) +using MarkdownAST +using Dates +using AbstractTrees +import CommonMark as CM + +VERSION >= v"1.11.0-DEV.469" && eval(Meta.parse("public parsefile, VersionInfo, SimpleChangelog, generate, tryparsefile")) # generate Documenter changelogs and links include("generate.jl") +# CommonMark <> MarkdownAST code +include("commonmark_markdownast_interop.jl") +using .CommonMarkMarkdownASTInterop: md_convert + +# Convert MarkdownAST tree to our own tree +include("heading_tree.jl") + +# SimpleChangelog and VersionInfo types, as well as API entrypoints +include("SimpleChangelog.jl") + +# Tree traversal and parsing code +include("parse_changelog.jl") + end # module diff --git a/src/SimpleChangelog.jl b/src/SimpleChangelog.jl new file mode 100644 index 0000000..42762c9 --- /dev/null +++ b/src/SimpleChangelog.jl @@ -0,0 +1,153 @@ +""" + VersionInfo + +A struct representing the information in a changelog about a particular version, with properties: + +- `version::Union{Nothing, String}`: a string representation of a version number or name (e.g. "Unreleased" or "1.2.3"). +- `url::Union{Nothing, String}`: a URL associated to the version, if available +- `date::Union{Nothing, Date}`: a date associated to the version, if available +- `toplevel_changes::Vector{String}`: a list of changes which are not within a section +- `sectioned_changes::Vector{Pair{String, Vector{String}}}`: an ordered mapping of section name to a list of changes in that section. + +""" +struct VersionInfo + version::Union{Nothing, String} + url::Union{Nothing, String} + date::Union{Nothing, Date} + toplevel_changes::Vector{String} + sectioned_changes::Vector{Pair{String, Vector{String}}} +end +function Base.show(io::IO, ::MIME"text/plain", v::VersionInfo) + return full_show(io, v) +end + +function full_show(io, v::VersionInfo; indent = 0, showtype = true) + pad = " "^indent + if showtype + print(io, pad, VersionInfo, " with") + print(io, pad, "\n- version: ", v.version) + else + print(io, pad, "- ", v.version) + pad *= " " + end + if v.url !== nothing + print(io, "\n", pad, "- url: ", v.url) + end + print(io, "\n", pad, "- date: ", v.date) + return if isempty(v.sectioned_changes) && isempty(v.toplevel_changes) + print(io, "\n", pad, "- and no documented changes") + else + print(io, "\n", pad, "- changes") + if !isempty(v.toplevel_changes) + for b in v.toplevel_changes + print(io, "\n", pad, " - $b") + end + end + + if !isempty(v.sectioned_changes) + for (section_name, bullets) in v.sectioned_changes + print(io, "\n", pad, " - $section_name") + for b in bullets + print(io, "\n", pad, " - $b") + end + end + end + end +end + +""" + SimpleChangelog + +A simple in-memory changelog format, with properties: + +- `title::Union{Nothing, String}` +- `intro::Union{Nothing, String}` +- `versions::Vector{VersionInfo}` + +A `SimpleChangelog` can be parsed out of a markdown-formatted string with `Base.parse`. + +SimpleChangelogs are not intended to be roundtrippable in-memory representations of markdown +changelogs; rather, they discard most formatting and other details to provide a simple +view to make it easy to query if the changelog has an entry for some particular version, +or what the changes are for that version. + +See also: [`VersionInfo`](@ref), [`parsefile`](@ref). +""" +struct SimpleChangelog + title::Union{Nothing, String} + intro::Union{Nothing, String} + versions::Vector{VersionInfo} +end + +function Base.show(io::IO, ::MIME"text/plain", c::SimpleChangelog) + print(io, SimpleChangelog, " with") + print(io, "\n- title: ", c.title) + print(io, "\n- intro: ", c.intro) + n_versions = length(c.versions) + plural = n_versions > 1 ? "s" : "" + print(io, "\n- $(n_versions) version$plural:") + n_to_show = 5 + for v in first(c.versions, n_to_show) + print(io, "\n") + full_show(io, v; showtype = false, indent = 2) + end + if n_versions > n_to_show + print(io, "\n ⋮") + end + return +end + +""" + parse(::Type{SimpleChangelog}, text::AbstractString) + +Parse a [`SimpleChangelog`](@ref) from a markdown-formatted string. + +!!! note + This functionality is primarily intended for parsing [KeepAChangeLog](https://keepachangelog.com/en/1.1.0/)-style changelogs, that have a title as a H1 (e.g. `#`) markdown header, followed by a list of versions with H2-level headers (`##`) formatted like `[1.1.0] - 2019-02-15` with or without a link on the version number, followed by a bulleted list of changes, potentially in subsections, each with H3 header. For such changelogs, parsing should be stable. We may also attempt to parse a wider variety of headers, for which the extent that we can parse may change in non-breaking releases (typically improving the parsing, but potentially regressing in some cases). +""" +function Base.parse(::Type{SimpleChangelog}, text::AbstractString) + # parse into CommonMark AST + parser = CM.Parser() + CM.enable!(parser, CM.FootnoteRule()) + ast = parser(text) + # convert to MarkdownAST AST + ast = md_convert(MarkdownAST.Node, ast) + return _parse_simple_changelog!(ast) +end + +""" + tryparse(::Type{SimpleChangelog}, text::AbstractString) + +Try to parse a [`SimpleChangelog`](@ref) from a markdown-formatted string, +returning `nothing` if unable to. + +""" +function Base.tryparse(::Type{SimpleChangelog}, text::AbstractString) + return try + parse(SimpleChangelog, text) + catch e + # This may be handy occasionally if we want to understand why we couldn't parse + # and don't want to manually run `parse(SimpleChangelog, text)`. + @debug "Error when parsing `SimpleChangelog` from changelog, returning `nothing`" exception = sprint(Base.display_error, e, catch_backtrace()) + nothing + end +end + +""" + parsefile(path) -> SimpleChangelog + +Parse a [`SimpleChangelog`](@ref) from a file path `path`. +""" +function parsefile(path) + return parse(SimpleChangelog, read(path, String)) +end + +""" + tryparsefile(path) -> SimpleChangelog + +Try to parse a [`SimpleChangelog`](@ref) from a file path `path`, returning +`nothing` if unable to. +""" +function tryparsefile(path) + return tryparse(SimpleChangelog, read(path, String)) +end diff --git a/src/commonmark_markdownast_interop.jl b/src/commonmark_markdownast_interop.jl new file mode 100644 index 0000000..79b0650 --- /dev/null +++ b/src/commonmark_markdownast_interop.jl @@ -0,0 +1,115 @@ +# Copy of: +# https://github.com/MichaelHatherly/CommonMark.jl/pull/56 +# by Morten Piibeleht +# That PR is not merged, so we will vendor a copy here. +# We rename the function `md_convert` instead of `Base.convert` +# to avoid piracy. +# We stick it into a module to avoid unexpected side-effects, so hopefully we can cleanly +# delete this file once the PR is merged. +module CommonMarkMarkdownASTInterop +using CommonMark: Node, AbstractContainer, NULL_NODE, + Document, Paragraph, BlockQuote, ThematicBreak, HtmlBlock, DisplayMath, + Heading, CodeBlock, Admonition, List, Item, FootnoteDefinition, + LineBreak, Backslash, SoftBreak, Emph, Strong, HtmlInline, Math, FootnoteLink, Text, + Code, Image, Link, JuliaValue, Table, TableBody, TableCell, TableHeader, TableRow + +import MarkdownAST + +function md_convert(::Type{MarkdownAST.Node}, node::Node) + mdast = _mdast_node(node) + let child = node.first_child + while child != NULL_NODE + mdast_child = md_convert(MarkdownAST.Node, child) + push!(mdast.children, mdast_child) + child = child.nxt + end + end + return mdast +end + +_mdast_node(node::Node) = _mdast_node(node, node.t) + +# Fallback convert function +struct UnsupportedContainerError <: Exception + container_type::Type{<:AbstractContainer} +end +function Base.showerror(io::IO, e::UnsupportedContainerError) + return print( + io, + "UnsupportedContainerError: container of type '$(e.container_type)' is not supported in MarkdownAST", + ) +end + +function _mdast_node(::Node, ::T) where {T <: AbstractContainer} + throw(UnsupportedContainerError(T)) +end + +# For all singleton containers that map trivially (i.e. they have no attributes), +# we can have a single implementation. +const SINGLETON_CONTAINER_MAP = Dict( + Document => MarkdownAST.Document, + Paragraph => MarkdownAST.Paragraph, + BlockQuote => MarkdownAST.BlockQuote, + ThematicBreak => MarkdownAST.ThematicBreak, + LineBreak => MarkdownAST.LineBreak, + Backslash => MarkdownAST.Backslash, + SoftBreak => MarkdownAST.SoftBreak, + Emph => MarkdownAST.Emph, + Strong => MarkdownAST.Strong, + # CommonMark.Item contains a field, but it's discarded in MarkdownAST + Item => MarkdownAST.Item, + # Internal nodes for tables + TableBody => MarkdownAST.TableBody, + TableHeader => MarkdownAST.TableHeader, + TableRow => MarkdownAST.TableRow, +) +const SINGLETON_CONTAINERS = Union{keys(SINGLETON_CONTAINER_MAP)...} +function _mdast_node(node::Node, container::SINGLETON_CONTAINERS) + e = SINGLETON_CONTAINER_MAP[typeof(container)]() + return MarkdownAST.Node(e) +end + +# Some containers use the .literal field of the Node object to store the content, +# which generally maps to MarkdownAST.T(node.literal). +const LITERAL_CONTAINER_MAP = Dict( + Text => MarkdownAST.Text, + HtmlBlock => MarkdownAST.HTMLBlock, + HtmlInline => MarkdownAST.HTMLInline, + DisplayMath => MarkdownAST.DisplayMath, + Math => MarkdownAST.InlineMath, + Code => MarkdownAST.Code, +) +const LITERAL_CONTAINERS = Union{keys(LITERAL_CONTAINER_MAP)...} +function _mdast_node(node::Node, container::LITERAL_CONTAINERS) + e = LITERAL_CONTAINER_MAP[typeof(container)](node.literal) + return MarkdownAST.Node(e) +end + +# Containers that need special handling +_mdast_node(n::Node, c::Heading) = MarkdownAST.Node(MarkdownAST.Heading(c.level)) +_mdast_node(n::Node, c::Link) = MarkdownAST.Node(MarkdownAST.Link(c.destination, c.title)) +_mdast_node(n::Node, c::Image) = MarkdownAST.Node(MarkdownAST.Image(c.destination, c.title)) +_mdast_node(n::Node, c::List) = + MarkdownAST.Node(MarkdownAST.List(c.list_data.type, c.list_data.tight)) +_mdast_node(n::Node, c::CodeBlock) = + MarkdownAST.Node(MarkdownAST.CodeBlock(c.info, n.literal)) +_mdast_node(n::Node, c::Admonition) = + MarkdownAST.Node(MarkdownAST.Admonition(c.category, c.title)) +_mdast_node(n::Node, c::FootnoteDefinition) = + MarkdownAST.Node(MarkdownAST.FootnoteDefinition(c.id)) +_mdast_node(n::Node, c::FootnoteLink) = MarkdownAST.Node(MarkdownAST.FootnoteLink(c.id)) +_mdast_node(n::Node, c::Table) = MarkdownAST.Node(MarkdownAST.Table(c.spec)) +_mdast_node(n::Node, c::TableCell) = + MarkdownAST.Node(MarkdownAST.TableCell(c.align, c.header, c.column)) +_mdast_node(n::Node, c::JuliaValue) = MarkdownAST.Node(MarkdownAST.JuliaValue(c.ex, c.ref)) + +# Unsupported containers (no MarkdownAST equivalent currently): +# +# Attributes, Citation, CitationBracket, FrontMatter, ReferenceList, References, +# LaTeXBlock, LaTeXInline +# +# Should never appear in a CommonMark tree: +# +# TablePipe (internal use), TableComponent (abstract), JuliaExpression (internal use) + +end # module diff --git a/src/heading_tree.jl b/src/heading_tree.jl new file mode 100644 index 0000000..2e01e2e --- /dev/null +++ b/src/heading_tree.jl @@ -0,0 +1,114 @@ +# Here we transform MarkdownAST trees into a new "MarkdownHeadingTree" which has slightly different semantics, with the goal that content under a heading in the markdown document is a _descendent_ of the corresponding `MarkdownHeadingTree`. +# Semantics: +# - Each `MarkdownAST.Heading` (and the `MarkdownAST.Document`) node maps to a `MarkdownHeadingTree` object +# - All other "top-level" elements (i.e. all children thereof) map to `Elt` objects +# - The children of `MarkdownHeadingTree`s are all the corresponding `Elt` objects as well as any `MarkdownHeadingTree` corresponding nested subheadings +# - The children of `Elt` objects are their usual children (deferring to MarkdownAST's notion of a child) +# Note therefore MarkdownAST's children of `MarkdownAST.Heading` objects are disconnected / not present in the final tree, since the headings are nodes themselves in this new tree. +# To access them, when necessary we will traverse `obj.heading_node` for `obj::MarkdownHeadingTree`, +# instead of traversing `obj`'s children. + +# Generic "element" +struct Elt + value::MarkdownAST.Node +end + +# simply passes along children and values to MarkdownAST's definitions +AbstractTrees.children(n::Elt) = AbstractTrees.children(n.value) +AbstractTrees.nodevalue(n::Elt) = AbstractTrees.nodevalue(n.value) +MarkdownAST.unlink!(n::Elt) = MarkdownAST.unlink!(n.value) + +# Heading or Document +struct MarkdownHeadingTree + heading_node::MarkdownAST.Node # either MarkdownAST.Heading or MarkdownAST.Document elements + level::Int # matches `heading_node.level` when heading, otherwise 0 for Document + children::Vector{Union{Elt, MarkdownHeadingTree}} +end + +Base.summary(io::IO, m::MarkdownHeadingTree) = print(io, MarkdownHeadingTree, "(level=$(m.level))") +# Passes to `n.children`, each of which has its own semantics (Elt or MarkdownHeadingTree) +AbstractTrees.children(n::MarkdownHeadingTree) = n.children +# the nodevalue is the MarkdownAST node itself (which itself has children, but they form a disconnected separate tree) +AbstractTrees.nodevalue(n::MarkdownHeadingTree) = AbstractTrees.nodevalue(n.heading_node) +MarkdownAST.unlink!(n::MarkdownHeadingTree) = MarkdownAST.unlink!(n.heading_node) + +# Main function: transform a node for MarkdownAST.Document into a MarkdownHeadingTree +function build_heading_tree!(ast) + if !(nodevalue(ast) isa MarkdownAST.Document) + throw(ArgumentError("The initial node should be a `MarkdownAST.Document`")) + end + + itr = PreOrderDFS(ast) do node + # don't recurse into Headings + nodevalue(node) isa MarkdownAST.Heading && return false + # optimization: don't recurse into values which can't contain a heading + # (the `seen` mechanism below should ensure correctness regardless of what we do here, + # but this can be prevent unnecessary traversal) + # Note: currently this seems to be load-bearing for correctness, not sure why + MarkdownAST.can_contain(nodevalue(node), MarkdownAST.Heading(1)) || return false + return true + end + # First we will build a flat list of *all* headings, with all content "within" the heading + # as a child of that heading. + flat = MarkdownHeadingTree[] + # we will keep track of non-heading elements we have seen, so we can avoid adding + # both a parent and its child which would disrupt the tree structure (flattening it) + seen = Set() + for node in itr + # we treat the Document as a special level-0 heading + if nodevalue(node) isa MarkdownAST.Document + push!(flat, MarkdownHeadingTree(node, 0, [])) + elseif nodevalue(node) isa MarkdownAST.Heading + push!(flat, MarkdownHeadingTree(node, nodevalue(node).level, [])) + elseif isempty(flat) + # This should not be possible, the first element should always be a document + @assert false + elseif AbstractTrees.parent(node) in seen + # has a parent in the tree already; nothing to do + else + push!(flat[end].children, Elt(node)) + push!(seen, node) + end + end + + # Now, we can't do this while traversing, but since we have finished traversing + # the tree, we need to unlink markdown AST node. They retain their children after unlinking, so we can continue e.g. + # traversing through `Elt`s to their children, but we want to remove connections to their parent, since + # they have a new parent, namely the `MarkdownHeadingTree` corresponding to the markdown heading the are "under", and this parent-child connection is encoded elsewhere (i.e. by being in the `.children` field) + for heading in flat + for c in heading.children + MarkdownAST.unlink!(c) + end + end + + # Now we have a list of all markdown headers in order, e.g. + # [Header 1, Header 2, Header 3] + # but we want some of these to be children of others, e.g. for + # ```markdown + # # Header 1 + # abc + # ## Header 2 + # def + # ## Header 3 + # ``` + # we should have Header 2/3 as children of Header 1, but Header 3 is not a child of Header 2. + # We will do this as follows. Note theoretically we can have multiple "roots", but since + # we treat the Document itself as a level-0 header, that should be the unique root. + # We will write the logic generally, then assert there is only 1 root at the end. + roots = MarkdownHeadingTree[] + for i in eachindex(flat) + current = flat[i] + if i == 1 + push!(roots, current) + else + parent_idx = findlast(j -> flat[j].level < current.level, 1:(i - 1)) + if parent_idx === nothing + push!(roots, current) + else + push!(flat[parent_idx].children, current) + end + end + end + + return only(roots) +end diff --git a/src/parse_changelog.jl b/src/parse_changelog.jl new file mode 100644 index 0000000..1008ec8 --- /dev/null +++ b/src/parse_changelog.jl @@ -0,0 +1,202 @@ +##### +##### Parsing headings +##### + +const HEADING_REGEX = let + prefix = raw"^(?:[V|v]ersion)?v?" # can start with Version, or just "v", or not (or versionv) + space = raw"\s*" + name = space * raw"(?.+?)" * space # a version "name" is anything + df1 = raw"\d{4}-\d{2}-\d{2}" # matches yyyy-mm-dd + df2 = raw"\w+ \d{1,2},? \d{4}" # matches Feb 1, 2024 or March 1, 2024 or March 1 2024 + df3 = raw"\d{1,2} \w+,? \d{4}" # matches 1 January 2024 + date = space * "(?$df1|$df2|$df3)?" * space # match any date + suffix = raw"$" # end of line + Regex(string(prefix, name, raw"-?", date, suffix)) +end + +const DATE_FORMATS = ( + Dates.ISODateFormat, + dateformat"U d, Y", + dateformat"U d Y", + dateformat"u d, Y", + dateformat"u d Y", + dateformat"d u Y", + dateformat"d u, Y", + dateformat"d U Y", + dateformat"d U, Y", +) + +function findfirst_dateformat(str, dateformats = DATE_FORMATS) + for df in dateformats + date = tryparse(Date, str, df) + date === nothing || return date + end + return nothing +end + +function replace_until_convergence(str, repl...) + for _ in 1:1000 + # 1.6-compatible multiple replacements + newstr = foldl(replace, repl, init = str) + if newstr == str + return str + else + str = newstr + end + end + error("did not converge") +end + +# Parse version header for name and date +function parse_version_header(str; header_regex = HEADING_REGEX, dateformats = DATE_FORMATS) + header_text = replace_until_convergence( + strip(str), + r"\[(.*)\]" => s"\1", + r"\((.*)\)" => s"\1", + r"`(.*)`" => s"\1", + ) + m = match(header_regex, header_text) + if m === nothing + return (; name = header_text, date = nothing) + end + date = m[:date] + if date !== nothing + date = findfirst_dateformat(date, dateformats) + end + return (; name = something(m[:name], header_text), date) +end + +##### +##### Extracting text +##### + +# Extract text content from a node +# should this be a markdown writer like https://github.com/JuliaDocs/MarkdownAST.jl/issues/18? +function text_content(node) + if nodevalue(node) isa MarkdownAST.Text + return nodevalue(node).text + elseif !isempty(AbstractTrees.children(node)) + return join(text_content(child) for child in AbstractTrees.children(node)) + elseif nodevalue(node) isa MarkdownAST.Code + return string("`", nodevalue(node).code, "`") + else # are there any other nodes to deal with? + # error(string(typeof(nodevalue(node)), ": ", nodevalue(node))) + return "" + end +end + +##### +##### Tree traversal helpers +##### + +function find_first_child(node, ::Type{T}) where {T} + for x in AbstractTrees.children(node) + if nodevalue(x) isa T + return x + end + end + return nothing +end + +function filter_children(node, ::Type{T}) where {T} + return Iterators.filter(AbstractTrees.children(node)) do x + nodevalue(x) isa T + end +end + +function filter_tree(node, ::Type{T}) where {T} + filter = node -> !(nodevalue(node) isa T) # don't recurse _into_ Ts + return Iterators.filter(PreOrderDFS(filter, node)) do x + nodevalue(x) isa T + end +end + +function find_first_tree(node, ::Type{T}) where {T} + for x in PreOrderDFS(node) + if nodevalue(x) isa T + return x + end + end + return nothing +end + +function bullets_to_list(items) + # If there were no bullets, just text, then combine them + # (Note: we could add a dependency on StatsBase to get `rle` (or reimplement it), + # then merge all consecutive runs of `MarkdownAST.Text` into a single bullet.) + if all(x -> nodevalue(x) isa MarkdownAST.Text, items) + return [join((text_content(x) for x in items), " ")] + else + return [text_content(x) for x in items] + end +end + +##### +##### Main parsing code +##### + +# see `SimpleChangelog.jl` for the API entrypoints (`Base.parse` and `parsefile`) +function _parse_simple_changelog!(ast::MarkdownAST.Node) + # convert into a "MarkdownHeadingTree" where elements of a section are children of the section + root = build_heading_tree!(ast) + # Now, we have a tree where content under a heading in the markdown document is a descendent + # of the corresponding `MarkdownHeadingTree` object in the tree. + # content which was a child of the heading itself (e.g. the text within the heading) + # is disconnected from the main tree, and is only reachable by traversing `x.heading_node` for `x::MarkdownHeadingTree` + + # debug + # print_tree(root; maxdepth=20) + + # build the changelog + @assert root.level == 0 + + # find highest-level header in document + top_header = find_first_tree(root, MarkdownAST.Heading) + + title = text_content(top_header.heading_node) # reach into the heading node to get the actual context + + # Now back to the "main" tree, look for the first paragraph under the top-heading to get an "intro" + intro_para = find_first_child(top_header, MarkdownAST.Paragraph) + intro = isnothing(intro_para) ? nothing : text_content(intro_para) + + # Now we will parse the versions. We assume each heading below the top-heading is a separate version. + versions = VersionInfo[] + for version_section in filter_children(top_header, MarkdownAST.Heading) + # try to parse the version "name" (could be version number, or "Unreleased" etc) and date + version, date = parse_version_header(text_content(version_section.heading_node)) + # if we couldn't get the name, then skip. But allow missing date. + version === nothing && continue + + # See if we have a link for this version by checking for a text node with the same content as the version name + # here we check within the heading node itself (so the link is in the heading, not below it) + links = Iterators.filter(filter_tree(version_section.heading_node, MarkdownAST.Link)) do link + c = find_first_child(link, MarkdownAST.Text) + # Note: here we use contains, as we have processed version names by removing `v`'s, quoting, etc. + # However we don't add anything, so `contains` should be true. We are also only searching within the heading itself + # (not content below the heading), so I don't expect there to be multiple links that all contain the version name/number, where + # the first one is not the correct one. + return !isnothing(c) && contains(nodevalue(c).text, version) + end + version_url = isempty(links) ? nothing : nodevalue(first(links)).destination + + # Now let us formulate the changelog for this version + # We may have subsections or just a flat list of changes + sectioned_changes = Pair{String, Vector{String}}[] + seen = Set() + for subsection in filter_children(version_section, MarkdownAST.Heading) + subsection_name = text_content(subsection.heading_node) + # Note: `filter_tree` doesn't recurse into the types we are looking for, so + # here if there is an item, we will choose that one (and not the text contained in it), + # and if we hit a text, we know it's not contained in an item that we are also pulling out. + items = filter_tree(subsection, Union{MarkdownAST.Item, MarkdownAST.Text}) + union!(seen, items) + push!(sectioned_changes, subsection_name => bullets_to_list(items)) + end + # see if there were items not within a subsection + other_items = setdiff(filter_tree(version_section, Union{MarkdownAST.Item, MarkdownAST.Text}), seen) + toplevel_changes = filter!(!isempty, bullets_to_list(other_items)) + + push!(versions, VersionInfo(version, version_url, date, toplevel_changes, sectioned_changes)) + end + return SimpleChangelog(title, intro, versions) +end diff --git a/test/SimpleChangelog.jl b/test/SimpleChangelog.jl new file mode 100644 index 0000000..111a980 --- /dev/null +++ b/test/SimpleChangelog.jl @@ -0,0 +1,29 @@ +using Changelog: VersionInfo, SimpleChangelog, tryparsefile +@testset "VersionInfo and SimpleChangelog printing" begin + v = VersionInfo("1.0.0", nothing, Date("2024-12-27"), ["One change"], ["Section" => ["c1"]]) + v_str = repr("text/plain", v) + @test contains(v_str, "- version: 1.0.0") + @test contains(v_str, "- date: 2024-12-27") + @test contains(v_str, "- One change") + @test contains(v_str, "Section") + @test contains(v_str, "- c1") + + c = SimpleChangelog("title", "intro", [v]) + c_str = repr("text/plain", c) + @test contains(c_str, "- title: title") + @test contains(c_str, "- intro: intro") + @test contains(c_str, "- 1 version:") + @test contains(c_str, "- date: 2024-12-27") + + c = SimpleChangelog("title", "intro", fill(v, 10)) + # Only show newest 5 versions + c_str = repr("text/plain", c) + @test contains(c_str, "⋮") + @test contains(c_str, "- 10 versions:") + @test count("- 1.0.0", c_str) == 5 +end + +@testset "tryparse" begin + @test tryparse(SimpleChangelog, "") === nothing + @test tryparsefile(test_path("empty.md")) === nothing +end diff --git a/test/parse_changelog.jl b/test/parse_changelog.jl new file mode 100644 index 0000000..4fdbed2 --- /dev/null +++ b/test/parse_changelog.jl @@ -0,0 +1,144 @@ +@testset "parse_version_header" begin + @testset "valid header with date" begin + header = "[1.0.0] - 2023-10-01" + result = parse_version_header(header) + @test result.name == "1.0.0" + @test result.date == Date("2023-10-01") + end + + @testset "valid header without date" begin + header = "[1.0.0]" + result = parse_version_header(header) + @test result.name == "1.0.0" + @test result.date === nothing + end + + @testset "header with invalid date" begin + header = "[1.0.0] - invalid-date" + result = parse_version_header(header) + # note we pass the whole thing as the name - potentially we could improve things + # so we only skip the date + @test result.name == "1.0.0 - invalid-date" + @test result.date === nothing + end + + @testset "header without version" begin + header = "[] - 2023-10-01" + result = parse_version_header(header) + # again, not optimal + @test result.name == "-" + @test result.date == Date("2023-10-01") + end + + @testset "header without brackets" begin + header = "1.0.0 - 2023-10-01" + result = parse_version_header(header) + @test result.name == "1.0.0" + @test result.date == Date("2023-10-01") + end + + @testset "invalid header" begin + header = "Invalid Header" + result = parse_version_header(header) + @test result.name == "Invalid Header" + @test result.date === nothing + end + + @testset "multiple quotes" begin + header = "[1.0.0] (`2024-12-25`)" + result = parse_version_header(header) + @test result.name == "1.0.0" + @test result.date === Date("2024-12-25") + end + + @testset "date $date_str" for date_str in [ + "2024-02-01", + "February 1, 2024", + "February 1 2024", + "Feb 1, 2024", + "Feb 1 2024", + "1 February 2024", + "1 February, 2024", + "1 Feb 2024", + "1 Feb, 2024", + ] + header = "v1.0.0 - $date_str" + result = parse_version_header(header) + @test result.name == "1.0.0" + date = Changelog.findfirst_dateformat(date_str) + @test result.date == date == Date("2024-02-01") + end +end + +@testset "parsefile" begin + # Here we test some point-in-time examples. This is not intended to test anything about + # JuMP itself (e.g. if it is keeping a consistently formatted changelog), but rather that we can parse + # its changelog as of when this file was committed (Dec 2024), to test the parsing code on in-the-wild examples. + @testset "JuMP changelog" begin + jump = parsefile(test_path("jump.md")) + # we parse dates for every entry + @test isempty(filter(x -> x.date === nothing, jump.versions)) + # and find at least one change per version + @test isempty(filter(x -> isempty(x.sectioned_changes) && isempty(x.toplevel_changes), jump.versions)) + # there are no URLs in the section headers, so we shouldn't find any + @test isempty(filter(x -> !isnothing(x.url), jump.versions)) + end + + # Similarly we check that we can parse Documenter's changelog (as of Dec 2024). + @testset "Documenter changelog" begin + documenter = parsefile(test_path("documenter.md")) + # we parse dates for every entry + @test isempty(filter(x -> x.date === nothing, documenter.versions)) + # and find at least one change per version + @test isempty(filter(x -> isempty(x.sectioned_changes), documenter.versions)) + # and we parse a URL for every version + @test isempty(filter(x -> isnothing(x.url), documenter.versions)) + end + + @testset "v1.1 changelog" begin + # Here we check in the changelog for this package as `v1.1.md` + # This is a tricky one, as for v1.0.0, there are no bullet points (nor sections), only text. + + v1p1 = parsefile(test_path("v1.1.md")) + # we parse dates for every entry + @test isempty(filter(x -> x.date === nothing, v1p1.versions)) + # and find at least one change per version + @test isempty(filter(x -> isempty(x.toplevel_changes) && isempty(x.sectioned_changes), v1p1.versions)) + # and we parse a URL for every version + @test isempty(filter(x -> isnothing(x.url), v1p1.versions)) + @test length(v1p1.versions) == 2 + ver_1p1, ver_1p0 = v1p1.versions + + @test ver_1p1.version == "1.1.0" + @test ver_1p1.url == "https://github.com/JuliaDocs/Changelog.jl/releases/tag/v1.1.0" + @test ver_1p1.date == Date("2023-11-13") + @test ver_1p1.sectioned_changes == ["Added" => ["Links of the form `[]`, where `` is a commit hashof length 7 or 40, are now linkified. (#4)"]] + + @test ver_1p0.version == "1.0.0" + @test ver_1p0.url == "https://github.com/JuliaDocs/Changelog.jl/releases/tag/v1.0.0" + @test ver_1p0.date == Date("2023-11-13") + @test ver_1p0.toplevel_changes == ["First release. See README.md for currently supported functionality."] + end + + # Next we check several quite similar changelogs which have some differences in formatting + @testset "$file" for file in readdir(test_path("good"); join = true) + c = parsefile(file) + @test c.title == "Changelog" + @test c.intro == "Intro" + # All have these versions, in this order + @test [v.version for v in c.versions] == ["Unreleased", "1.0.0"] + unreleased = c.versions[1] + v1 = c.versions[2] + @test unreleased.date === nothing + @test v1.date == Date("2024-12-25") + @test !isempty(unreleased.sectioned_changes) || !isempty(unreleased.toplevel_changes) + @test !isempty(v1.sectioned_changes) || !isempty(v1.toplevel_changes) + end + + # Lastly, we check that we don't error on some "bad" examples, + # which have e.g. inconsistent or missing headings + @testset "$file" for file in readdir(test_path("bad"); join = true) + c = parsefile(file) + @test c.title == "Changelog" + end +end diff --git a/test/runtests.jl b/test/runtests.jl index f3e41c5..ed8f208 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -1,3 +1,10 @@ using Changelog, Test +using Changelog: parse_version_header, parsefile +using Dates + + +test_path(filename) = joinpath(pkgdir(Changelog), "test", "test_changelogs", filename) include("generate.jl") +include("parse_changelog.jl") +include("SimpleChangelog.jl") diff --git a/test/test_changelogs/bad/bad1.md b/test/test_changelogs/bad/bad1.md new file mode 100644 index 0000000..e30aa62 --- /dev/null +++ b/test/test_changelogs/bad/bad1.md @@ -0,0 +1,11 @@ +# Changelog + +### Version 1.0.0 + +- Added homepage redesign +- Bug fixes + +#### Unreleased + +- Feature X +- Performance tweaks diff --git a/test/test_changelogs/bad/bad2.md b/test/test_changelogs/bad/bad2.md new file mode 100644 index 0000000..b0f5c65 --- /dev/null +++ b/test/test_changelogs/bad/bad2.md @@ -0,0 +1,9 @@ +# Changelog + +2024-12-25: +- Initial release +- Bug fixes + +2024-12-26: +- Added user authentication +- Performance improvements diff --git a/test/test_changelogs/bad/bad3.md b/test/test_changelogs/bad/bad3.md new file mode 100644 index 0000000..d9a8962 --- /dev/null +++ b/test/test_changelogs/bad/bad3.md @@ -0,0 +1,7 @@ +# Changelog + +- Added login page +- Removed deprecated API +- Optimized database queries +- Fixed issue with data serialization +- Updated libraries diff --git a/test/test_changelogs/documenter.md b/test/test_changelogs/documenter.md new file mode 100644 index 0000000..d9bcc7e --- /dev/null +++ b/test/test_changelogs/documenter.md @@ -0,0 +1,1923 @@ +# Release notes + +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), +and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). + +## Version [v1.8.0] - 2024-11-07 + +### Changed + +* `deploydocs` now ignores any global GPG signing Git settings (i.e. `commit.gpgSign = false`). ([#2592]) + +### Fixed + +* The search modal no longer runs into a race condition with loading the search index and consistently opens correctly. ([#2593]) + +### Other + +* Documenter now uses [Runic.jl](https://github.com/fredrikekre/Runic.jl) for code formatting. + +## Version [v1.7.0] - 2024-09-04 + +### Added + +* The `User-Agent` header set in the linkcheck HTTP(S) requests can now be customized with the `linkcheck_useragent` option to `makedocs`. ([#2557], [#2562], [#2571]) +* Admonitions with category `todo` are now colored purple. Previously they were default-colored like all other unknown admonitions categories. ([#2526]) +* A `checkdocs_ignored_modules` keyword argument to `makedocs(...)`, which prevents `checkdocs` from warning about missing documentation in certain modules. ([#2233]) + +### Changed + +* The default `User-Agent` header set in the linkcheck HTTP(S) requests now reports `Chrome/127.0.0.0` instead of `Chrome/51.0.2704.103`. This _may_ change how servers interpret the linkcheck requests, and cause previously passing checks to failing, but it is more likely to fix previous spurious failures. ([#2557], [#2569]) + +### Fixed + +* The paths for `size_threshold_ignore` option of `Documenter.HTML` are now correctly normalized and no longer sensitive to platform-dependent differences in path separators. ([#2560], [#2561]) + +## Version [v1.6.0] - 2024-08-20 + +### Changed + +* The MathJax3 setup now uses `tex-svg-full.js` and additionally draws in `mhchem` by default, allowing for chemistry symbols to be rendered (consistent with Pluto.jl). ([#2549]) + +### Fixed + +* Collapsing of docstrings in the HTML output can now only be triggered when clicking on the icon or the empty area only. ([#2204], [#2551]) + +## Version [v1.5.0] - 2024-06-26 + +### Added + +* Four new *experimental* themes (`catppuccin-latte`, `catppuccin-frappe`, + `catppuccin-macchiato`, and `catppuccin-mocha`) have been added. These are based on the + [Catppuccin](https://catppuccin.com/) color palette. The existing themes + (`documenter-light` and `documenter-dark`) are still the default light and dark theme, + respectively. ([#2496]) + +### Changed + +* Coloring of admonitions have been toned down in order to make them slightly less + eye-catching. ([#2499]) +* Thickness and rounding of docstrings and code blocks have been adjusted to match + admonitions. ([#2499]) +* _All_ search terms in the HTML search must now match the result, as opposed to _any_. In other words, they are now `AND`-ed together, and not `OR`-ed. ([#2514]) + +### Fixed + +* The search prompt in the HTML output again correctly handles parenthesis and other special character that would previously cause the search to crash. ([#2513]) + +## Version [v1.4.1] - 2024-05-02 + +### Fixed + +* In HTML output, links in inline code are now correctly colored on hover. ([#2497]) +* Doctest fixing functionality handles another edge case. ([#2303], [#2378]) + +## Version [v1.4.0] - 2024-04-14 + +### Changed + +* A fully qualified `@ref` link now resolves in `Main` as well, in addition to `CurrentModule`. For any package whose docstrings are included in the documentation, as long as that package is loaded in `make.jl`, fully qualified `@ref` links to docstrings in the package will work from anywhere. This simplifies, e.g., linking between docstrings for packages that use sub-modules. ([#2470]) +* `HTMLWriter` saw several refactoring, which should not lead to any user-visible changes, but may affect plugins that are relying on Documenter's internals. ([#2475], [#2480], [#2482]) + +## Version [v1.3.0] - 2024-03-01 + +### Added + +* Added support for a `CollapsedDocStrings` key in every page's `@meta` block. Setting `CollapsedDocStrings = true` for a particular page essentially clicks the "Collapse all docstrings" in the navigation bar after the page loads, collapsing all docstrings on that page. This can make API documentation pages much more readable. ([#2282], [#2394], [#2459], [#2460]) +* Automatically write an `objects.inv` inventory file to be be included in every online deployment of the documentation. With the help of the [`DocumenterInterLinks` plugin](http://juliadocs.org/DocumenterInterLinks.jl/stable/), any other project using Documenter or [Sphinx](https://www.sphinx-doc.org/en/master/) can then externally link to any page, heading, or docstring in the documentation. ([#2366], [#2424]) +* Added a parameter `inventory_version` to the `HTML()` options that may be passed to `makedocs`. This option sets the `version` metadata field in the new `objects.inv` inventory file. In most cases, the project version for the inventory will be automatically detected from the main `Project.toml` file, respectively, during deployment in `deploydocs`, from the git tag of the release. Any project may still want to explicitly set `inventory_version` via, e.g., [`pkgversion(MyProject)`](https://docs.julialang.org/en/v1/base/base/#Base.pkgversion-Tuple{Module}) instead of relying on an auto-detected version. Projects with a non-standard setup (documentation-only-repos, monorepos) *should* modify their existing configuration to explicitly set `inventory_version`. ([#2449]) + +### Changed + +* The search in the HTML output: + - Is now case-insensitive. ([#2373], [#2374]) + - Prioritizes prefix matches. ([#2203], [#2375]) + - Utilizes webworkers and is more responsive. ([#2415]) + - Clearing the search query no longer deselects filters. ([#2415]) + - When selecting one filter all others are automatically deselected. ([#2415]) + +### Fixed + +* Fix escaping special html entities in search output. ([#2441], [#2461]) +* Fix the search filter toggle button styling in the HTML output. ([#2406], [#2408]) +* The theme selector for the HTML output now correctly picks `Automatic (OS)` if the user hasn't explicitly set the theme. ([#2414], [#2438]) +* Fix the search window sometimes not appearing in the HTML output. ([#2430], [#2458]) + +## Version [v1.2.1] - 2023-12-02 + +### Fixed + +* Fix an erroneous warning about the `CurrentModule` argument of `@meta` blocks. ([#2364], [#2365]) + +## Version [v1.2.0] - 2023-11-29 + +### Changed + +* `id` anchors may now start with a numeric digit. ([#744], [#2325]) +* Documenter prints a more informative warning now if there is unexpected Julia interpolation in the Markdown (e.g. from errant `$` signs). ([#2288], [#2327]) +* Documenter now warns when it encounters invalid keys in the various key-value at-blocks. ([#2306], [#2324]) +* File sizes are now expressed in more human-readable format. ([#2272], [#2344]) +* Documenter now uses [Git.jl](https://github.com/JuliaVersionControl/Git.jl) (as opposed to the system's `git` binary) for Git operations. ([#2348]) +* Woodpecker CI 1.x and 2.x are now also supported. ([#2337], [#2335], [#2339]) + +### Fixed + +* Enabled text wrapping in docstring header on smaller screens. ([#2293], [#2307]) +* Fixed breadcrumb overflow with long page title on narrow screens (mobile). ([#2317]) +* Fixed `linkcheck` not checking inside of docstrings. ([#2329], [#2330]) +* Headings are now rewritten to `` in lists found in docstrings. ([#2308], [#2313]) + +## Version [v1.1.2] - 2023-10-23 + +### Fixed + +* Non-breaking spaces are now properly converted as "~" in the `LaTeXWriter`. ([#2300]) + +## Version [v1.1.1] - 2023-10-12 + +### Fixed + +* Fixed, docstring collapse/expand icon not changing correctly when clicking rapidly. ([#2103], [#2217]) + +## Version [v1.1.0] - 2023-09-28 + +### Added + +* Added `Remotes.GitLab` for specifying a `Remote` hosted on gitlab.com or a self-hosted GitLab instance. ([#2279]) + +### Fixed + +* Fixed display of inline LaTeX math `$ ... $` from `show` methods in HTMLWriter. ([#2280], [#2281]) +* Fixed a crash in GitHub remote link checking when `remotes = nothing`. ([#2274], [#2285]) +* Fix an error occurring with `DocTestFilters = nothing` in `@meta` blocks. ([#2273], [#1696]) + +## Version [v1.0.1] - 2023-09-18 + +### Fixed + +* Docstring with an unwrapped `Markdown.MD` object, such as the ones created when the `Markdown.@doc_str` macro is used, are correctly handled again. ([#2269]) + +## Version [v1.0.0] - 2023-09-15 + +### Version changes + +* The (minimum) required Julia version has been raised from 1.0 to 1.6. For older Julia versions the 0.27.X release can still be used. ([#1835], [#1841]) + +### Breaking + +* The `strict` keyword argument to `makedocs` has been removed and replaced with `warnonly`. `makedocs` now **fails builds by default** if any of the document checks fails (previously it only issued warnings by default). ([#2051], [#2194]) + + **For upgrading:** If you are running with `strict = true`, you can just drop the `strict` option. + If you are currently being strict about specific error classes, you can invert the list of error classes with `Documenter.except`. + + If you were not setting the `strict` keyword, but your build is failing now, you should first endeavor to fix the errors that are causing the build to fail. + If that is not feasible, you can exclude specific error categories from failing the build (e.g. `warnonly = [:footnote, :cross_references]`). + Finally, setting `warnonly = true` can be used to recover the old `strict = false` default behavior, turning all errors back into warnings. + +* The Markdown backend has been fully removed from the Documenter package, in favor of the external [DocumenterMarkdown package](https://github.com/JuliaDocs/DocumenterMarkdown.jl). This includes the removal of the exported `Deps` module. ([#1826]) + + **For upgrading:** To keep using the Markdown backend, refer to the [DocumenterMarkdown package](https://github.com/JuliaDocs/DocumenterMarkdown.jl). That package might not immediately support the latest Documenter version, however. + +* `@eval` blocks now require the last expression to be either `nothing` or of type `Markdown.MD`, with other cases now issuing an `:eval_block` error, and falling back to a text representation of the object. ([#1919], [#2260]) + + **For upgrading:** The cases where an `@eval` results in a object that is not `nothing` or `::Markdown.MD`, the returned object should be reviewed. In case the resulting object is of some `Markdown` node type (e.g. `Markdown.Paragraph` or `Markdown.Table`), it can simply be wrapped in `Markdown.MD([...])` for block nodes, or `Markdown.MD([Markdown.Paragraph([...])])` for inline nodes. In other cases Documenter was likely not handling the returned object in a correct way, but please open an issue if this change has broken a previously working use case. The error can be ignored by passing `:eval_block` to the `warnonly` keyword. + +* The handling of remote repository (e.g. GitHub) URLs has been overhauled. ([#1808], [#1881], [#2081], [#2232]) + + In addition to generating source and edit links for the main repository, Documenter can now also be configured to generate correct links for cases where some files are from a different repository (e.g. with vendored dependencies). There have also been changes and fixes to the way the automatic detection of source and edit links works. + + The fallbacks to `TRAVIS_REPO_SLUG` and `GITHUB_REPOSITORY` variables have been removed in favor of explicitly specifying the `repo` keyword in the `makedocs` call. + + Documenter is now also more strict about the cases where it is unable to determine the URLs, and therefore previously successful builds may break. + + **For upgrading:** As the fallbacks to CI variables have been removed, make sure that you have your source checked out as a proper Git repository when building the documentation, so that Documenter could determine the repository link automatically from the Git `origin` URL. On GitHub Actions, this should normally already be the case, and user action is unlikely to be necessary. In other cases, if necessary, you can configure the `repo` and/or `remotes` keywords of `makedocs` appropriately. + + These changes should mostly affect more complex builds that include docstrings or files from various sources, such as when including docstrings from multiple packages. In the latter case in particular, you should make sure that all the relevant packages are also fully cloned and added as development dependencies to the `docs/Project.toml` (or equivalent) environment (or that the `remotes` keyword is configured for the `Pkg.add`-ed packages). + + Finally, in general, even if the build succeeds, double check that the various remote links (repository links, source links, edits links) have been generated correctly. If you run into any unexpected errors, please open an issue. + +* Documenter now checks that local links (e.g. to other Markdown files, local images; such as `[see the other page](other.md)`) are pointing to existing files. ([#2130], [#2187]) + + This can cause existing builds to fail because previously broken links are now caught by the Documenter's document checks, in particular because Documenter now runs in strict mode by default. + + **For upgrading:** You should double check and fix all the offending links. Alternatively, you can also set `warnonly = :cross_references`, so that the errors would be reduced to warnings (however, this is not recommended, as you will have broken links in your generated documentation). + +* The HTML output now enforces size thresholds for the generated HTML files, to catch cases where Documenter is deploying extremely large HTML files (usually due to generated content, like figures). If any generated HTML file is above either of the thresholds, Documenter will either error and fail the build (if above `size_threshold`), or warn (if above `size_threshold_warn`). The size threshold can also be ignored for specific pages with `size_threshold_ignore`. ([#2142], [#2205], [#2211], [#2252]) + + **For upgrading:** If your builds are now failing due to the size threshold checks, you should first investigate why the generated HTML files are so large (e.g. you are likely automatically generating too much HTML, like extremely large inline SVG figures), and try to reduce them below the default thresholds. + If you are unable to reduce the generated file size, you can increase the `size_threshold` value to just above the maximum size, or disable the enforcement of size threshold checks altogether by setting `size_threshold = nothing`. + If it is just a few specific pages that are offending, you can also ignore those with `size_threshold_ignore`. + +* User-provided `assets/search.js` file no longer overrides Documenter's default search implementation, and the user-provided files will now be ignored by default. ([#2236]) + + **For upgrading:** The JS file can still be included via the `assets` keyword of `format = HTML(...)`. However, it will likely conflict with Documenter's default search implementation. If you require an API to override Documenter's search engine, please open an issue. + +* Plugin objects which were formally passed as (undocumented) positional keyword arguments to `makedocs` are now given as elements of a list `plugins` passed as a keyword argument ([#2245], [#2249]) + + **For upgrading:** If you are passing any plugin objects to `makedocs` (positionally), pass them via the `plugins` keyword instead. + +* `makedocs` will now throw an error if it gets passed an unsupported keyword argument. ([#2259]) + + **For upgrading:** Remove the listed keyword arguments from the `makedocs` call. If the keyword was previously valid, consult this CHANGELOG for upgrade instructions. + +### Added + +* Doctest filters can now be specified as regex/substitution pairs, i.e. `r"..." => s"..."`, in order to control the replacement (which defaults to the empty string, `""`). ([#1989], [#1271]) + +* Documenter is now more careful not to accidentally leak SSH keys (in e.g. error messages) by removing `DOCUMENTER_KEY` from the environment when it is not needed. ([#1958], [#1962]) + +* Admonitions are now styled with color in the LaTeX output. ([#1931], [#1932], [#1946], [#1955]) + +* Improved the styling of code blocks in the LaTeXWriter. ([#1933], [#1935], [#1936], [#1944], [#1956], [#1957]) + +* Automatically resize oversize `tabular` environments from `@example` blocks in LaTeXWriter. ([#1930], [#1937]) + +* The `ansicolor` keyword to `HTML()` now defaults to true, meaning that executed outputs from `@example`- and `@repl`-blocks are now by default colored (if they emit colored output). ([#1828]) + +* Documenter now shows a link to the root of the repository in the top navigation bar. The link is determined automatically from the remote repository, unless overridden or disabled via the `repolink` argument of `HTML`. ([#1254]) + +* A more general API is now available to configure the remote repository URLs via the `repo` argument of `makedocs` by passing objects that are subtypes of `Remotes.Remote` and implement its interface (e.g. `Remotes.GitHub`). ([#1808], [#1881]) + +* Broken issue references (i.e. links like `[#1234](@ref)`, but when Documenter is unable to determine the remote GitHub repository) now generate `:cross_references` errors that can be caught via the `strict` keyword. ([#1808]) + + This is **potentially breaking** as it can cause previously working builds to fail if they are being run in strict mode. However, such builds were already leaving broken links in the generated documentation. + + **For upgrading:** the easiest way to fix the build is to remove the offending `@ref` links. Alternatively, the `repo` argument to `makedocs` can be set to the appropriate `Remotes.Remote` object that implements the `Remotes.issueurl` function, which would make sure that correct URLs are generated. + +* Woodpecker CI is now automatically supported for documentation deployment. ([#1880]) + +* The `@contents`-block now support `UnitRange`s for the `Depth` argument. This makes it possible to configure also the *minimal* header depth that should be displayed (`Depth = 2:3`, for example). This is supported by the HTML and the LaTeX/PDF backends. ([#245], [#1890]) + +* The code copy buttons in HTML now have `title` and `aria-label` attributes. ([#1903]) + +* The at-ref links are now more flexible, allowing arbitrary links to point to both docstrings and section headings. ([#781], [#1900]) + +* Code blocks like `@example` or `@repl` are now also expanded in nested contexts (e.g. admonitions, lists or block quotes). ([#491], [#1970]) + +* The new `pagesonly` keyword to `makedocs` can be used to restrict builds to just the Markdown files listed in `pages` (as opposed to all `.md` files under `src/`). ([#1980]) + +* Search engine and social media link previews are now supported, with Documenter generating the relevant HTML `meta` tags. ([#1321], [#1991]) + +* `deploydocs` now supports custom tag prefixes; see section "Deploying from a monorepo" in the docs. ([#1291], [#1792], [#1993]) + +* The `target` keyword of `deploydocs` is now required to point to a subdirectory of `root` (usually the directory where `make.jl` is located). ([#2019]) + +* Added keyboard shortcuts for search box (`Ctrl + /` or `Cmd + /` to focus into the search box, `Esc` to focus out of it). ([#1536], [#2027]) + +* The various JS and font dependencies of the HTML backend have been updated to the latest non-breaking versions. ([#2066], [#2067], [#2070], [#2071], [#2213]) + + - KaTeX has been updated from `v0.13.24` to `v0.16.8` (major version bump). + - Font Awesome has been updated from `v5.15.4` to `v6.4.2` (major version bump). + - bulma.sass has been updated from `v0.7.5` to `v0.9.4` (major version bump). + - darkly.scss been updated to `v0.8.1`. + - highlight.js has been updated from `v11.5.1` to `v11.8.0`. + - JuliaMono has been updated from `v0.045` to `v0.050`. + - jQuery UI has been updated from `v1.12.1` to `v1.13.2`. + - jquery has been updated from `v3.6.0` to `v3.7.0`. + - MathJax 2 has been updated from `v2.7.7` to `v2.7.9`. + +* Move the mobile layout sidebar toggle (hamburger) from the right side to the left side. ([#1312], [#2076], [#2169], [#2215], [#2216]) + +* Added the ability to expand/collapse individual as well as all docstrings. ([#1393], [#2078]) + +* Invalid local link warnings during HTML rendering now print a bit more context, helping in pinpointing the offending link. ([#2100]) + +* Admonitions with category `details` are now rendered as (collapsed) `
` in the HTML backend. The admonition title is used as the ``. ([#2128]) + +* Theme switcher now includes an "Automatic (OS preference)" option that makes the site follow the user's OS setting. ([#1745], [#2085], [#2170]) + +* Documenter now generates a `.documenter-siteinfo.json` file in the HTML build, that contains some metadata about the build. ([#2181]) + +* The search UI has had a complete overhaul, with a fresh new modal UI with better context for search results and a filter mechanism to remove unwanted results. The client-side search engine has been changed from LunrJs to MinisearchJs. ([#1437], [#2141], [#2147], [#2202]) + +* The `doctest` routine can now receive the same `plugins` keyword argument as `makedocs`. This enables `doctest` to run if any plugin with a mandatory `Plugin` object is loaded, e.g., [DocumenterCitations](https://github.com/JuliaDocs/DocumenterCitations.jl). ([#2245]) + +* The HTML output will automatically write larger `@example`-block outputs to files, to make the generated HTML files smaller. The size threshold can be controlled with the `example_size_threshold` option to `HTML`. ([#2143], [#2247]) + +* The `@docs` and `@autodocs` blocks can now be declared non-canonical, allowing multiple copied of the same docstring to be included in the manual. ([#1079], [#1570], [#2237]) + +### Fixed + +* Line endings in Markdown source files are now normalized to `LF` before parsing, to work around [a bug in the Julia Markdown parser][JuliaLang/julia#29344] where parsing is sensitive to line endings, and can therefore cause platform-dependent behavior. ([#1906]) + +* `HTMLWriter` no longer complains about invalid URLs in docstrings when `makedocs` gets run multiple time in a Julia session, as it no longer modifies the underlying docstring objects. ([#505], [#1924]) + +* Docstring doctests now properly get checked on each `makedocs` run, when run multiple times in the same Julia session. ([#974], [#1948]) + +* The default decision for whether to deploy preview builds for pull requests have been changed from `true` to `false` when not possible to verify the origin of the pull request. ([#1969]) + +* `deploydocs` now correctly handles version symlinks where the destination directory has been deleted. ([#2012]) + +### Other + +* Documenter now uses [MarkdownAST](https://github.com/JuliaDocs/MarkdownAST.jl) to internally represent Markdown documents. While this change should not lead to any visible changes to the user, it is a major refactoring of the code. Please report any novel errors or unexpected behavior you encounter when upgrading to 0.28 on the [Documenter issue tracker](https://github.com/JuliaDocs/Documenter.jl/issues). ([#1892], [#1912], [#1924], [#1948]) + +* The code layout has changed considerably, with many of the internal submodules removed. This **may be breaking** for code that hooks into various Documenter internals, as various types and functions now live at different code paths. ([#1976], [#1977], [#2191], [#2214]) + + +## Version [v0.27.25] - 2023-07-03 + +### Fixed + +* Page headings are now correctly escaped in `LaTeXWriter`. ([#2134]) + +* Compiling the dark theme with Sass no longer emits deprecation warnings about `!global` assignments. ([#1766], [#1983], [#2145]) + +* The CSS Documenter ships is now minified. ([#2153], [#2157]) + +## Version [v0.27.24] - 2023-01-23 + +### Security + +* `deploydocs` now takes extra care to avoid committing the temporary SSH key file to the Git repo. ([#2018]) + +## Version [v0.27.23] - 2022-08-26 + +### Added + +* The `native` and `docker` PDF builds now run with the `-interaction=batchmode` (instead of `nonstopmode`) and `-halt-on-error` options to make the LaTeX error logs more readable and to fail the build early. ([#1908]) + +### Fixed + +* The PDF/LaTeX output now handles hard Markdown line breaks (i.e. `Markdown.LineBreak` nodes). ([#1908]) + +* Previously broken links within the PDF output are now fixed. ([JuliaLang/julia#38054], [JuliaLang/julia#43652], [#1909]) + +## Version [v0.27.22] - 2022-07-24 + +### Other + +* Documenter is now compatible with DocStringExtensions v0.9. ([#1885], [#1886]) + +## Version [v0.27.21] - 2022-07-13 + +### Fixed + +* Fix a regression where Documenter throws an error on systems that do not have Git available. ([#1870], [#1871]) + +## Version [v0.27.20] - 2022-07-10 + +### Added + +* The various JS and font dependencies of the HTML backend have been updated to the latest non-breaking versions. ([#1844], [#1846]) + + - MathJax 3 has been updated from v3.2.0 to v3.2.2. + - JuliaMono has been updated from v0.044 to v0.045. + - Font Awesome has been updated from v5.15.3 to v5.15.4. + - highlight.js has been updated from v11.0.1 to v11.5.1. + - KaTeX has been updated from v0.13.11 to v0.13.24. + +* **Experimental**: `deploydocs` now supports "deploying to tarball" (rather than pushing to the `gh-pages` branch) via the undocumented experiments `archive` keyword. ([#1865]) + +### Fixed + +* When including docstrings for an alias, Documenter now correctly tries to include the exactly matching docstring first, before checking for signature subtypes. ([#1842]) + +* When checking for missing docstrings, Documenter now correctly handles docstrings for methods that extend bindings from other modules that have not been imported into the current module. ([#1695], [#1857], [#1861]) + +* By overriding `GIT_TEMPLATE_DIR`, `git` no longer picks up arbitrary user templates and hooks when internally called by Documenter. ([#1862]) + +## Version [v0.27.19] - 2022-06-05 + +### Added + +* Documenter can now build draft version of HTML documentation by passing `draft=true` to `makedocs`. Draft mode skips potentially expensive parts of the building process and can be useful to get faster feedback when writing documentation. Draft mode currently skips doctests, `@example`-, `@repl`-, `@eval`-, and `@setup`-blocks. Draft mode can be disabled (or enabled) on a per-page basis by setting `Draft = true` in an `@meta` block. ([#1836]) + +* On the HTML search page, pressing enter no longer causes the page to refresh (and therefore does not trigger the slow search index rebuild). ([#1728], [#1833], [#1834]) + +* For the `edit_link` keyword to `HTML()`, Documenter automatically tries to figure out if the remote default branch is `main`, `master`, or something else. It will print a warning if it is unable to reliably determine either `edit_link` or `devbranch` (for `deploydocs`). ([#1827], [#1829]) + +* Profiling showed that a significant amount of the HTML page build time was due to external `git` commands (used to find remote URLs for docstrings). These results are now cached on a per-source-file basis resulting in faster build times. This is particularly useful when using [LiveServer.jl](https://github.com/JuliaDocs/LiveServer.jl)s functionality for live-updating the docs while writing. ([#1838]) + +## Version [v0.27.18] - 2022-05-25 + +### Added + +* The padding of the various container elements in the HTML style has been reduced, to improve the look of the generated HTML pages. ([#1814], [#1818]) + +### Fixed + +* When deploying unversioned docs, Documenter now generates a `siteinfo.js` file that disables the version selector, even if a `../versions.js` happens to exists. ([#1667], [#1825]) + +* Build failures now only show fatal errors, rather than all errors. ([#1816]) + +* Disable git terminal prompt when detecting remote HEAD branch for ssh remotes, and allow ssh-agent authentication (by appending rather than overriding ENV). ([#1821]) + +## Version [v0.27.17] - 2022-05-09 + +### Added + +* PDF/LaTeX output can now be compiled with the [Tectonic](https://tectonic-typesetting.github.io) LaTeX engine. ([#1802], [#1803]) + +* The phrasing of the outdated version warning in the HTML output has been improved. ([#1805]) + +* Documenter now provides the `Documenter.except` function which can be used to "invert" the list of errors that are passed to `makedocs` via the `strict` keyword. ([#1811]) + +### Fixed + +* When linkchecking HTTP and HTTPS URLs, Documenter now also passes a realistic `accept-encoding` header along with the request, in order to work around servers that try to block non-browser requests. ([#1807]) + +* LaTeX build logs are now properly outputted to the `LaTeXWriter.{stdout,stderr}` files when using the Docker build option. ([#1806]) + +* `makedocs` no longer fails with an `UndefVarError` if it encounters a specific kind of bad docsystem state related to docstrings attached to the call syntax, but issues an `@autodocs` error/warning instead. ([JuliaLang/julia#45174], [#1192], [#1810], [#1811]) + +## Version [v0.27.16] - 2022-04-19 + +### Added + +* Update CSS source file for JuliaMono, so that all font variations are included (not just `JuliaMono Regular`) and that the latest version (0.039 -> 0.044) of the font would be used. ([#1780], [#1784]) + +* The table of contents in the generated PDFs have more space between section numbers and titles to avoid them overlapping. ([#1785]) + +* The preamble of the LaTeX source of the PDF build can now be customized by the user. ([#1746], [#1788]) + +* The package version number shown in the PDF manual can now be set by the user by passing the `version` option to `format = LaTeX()`. ([#1795]) + +### Fixed + +* Fix `strict` mode to properly print errors, not just a warnings. ([#1756], [#1776]) + +* Disable git terminal prompt when detecting remote HEAD branch. ([#1797]) + +* When linkchecking HTTP and HTTPS URLs, Documenter now passes a realistic browser (Chrome) `User-Agent` header along with the request, in order to work around servers that try to use the `User-Agent` to block non-browser requests. ([#1796]) + +## Version [v0.27.15] - 2022-03-17 + +### Added + +* Documenter now deploys documentation from scheduled jobs (`schedule` on GitHub actions). ([#1772], [#1773]) + +* Improve layout of the table of contents section in the LaTeX/PDF output. ([#1750]) + +### Fixed + +* Improve the fix for extraneous whitespace in REPL blocks. ([#1774]) + +## Version [v0.27.14] - 2022-03-02 + +### Fixed + +* Fix a CSS bug causing REPL code blocks to contain extraneous whitespace. ([#1770], [#1771]) + +## Version [v0.27.13] - 2022-02-25 + +### Fixed + +* Fix a CSS bug causing the location of the code copy button to not be fixed in the upper right corner. ([#1758], [#1759]) + +* Fix a bug when loading the `copy.js` script for the code copy button. ([#1760], [#1762]) + +## Version [v0.27.12] - 2022-01-17 + +### Fixed + +* Fix code copy button in insecure contexts (e.g. pages hosted without https). ([#1754]) + +## Version [v0.27.11] - 2022-01-16 + +### Added + +* Documenter now deploys documentation from manually triggered events (`workflow_dispatch` on GitHub actions). ([#1554], [#1752]) + +* MathJax 3 has been updated to v3.2.0 (minor version bump). ([#1743]) + +* HTML code blocks now have a copy button. ([#1748]) + +* Documenter now tries to detect the development branch using `git` with the old default (`master`) as fallback. If you use `main` as the development branch you shouldn't need to specify `devbranch = "main"` as an argument to deploydocs anymore. ([#1443], [#1727], [#1751]) + +## Version [v0.27.10] - 2021-10-20 + +### Fixed + +* Fix depth of headers in LaTeXWriter. ([#1716]) + +## Version [v0.27.9] - 2021-10-18 + +### Fixed + +* Fix some errors with text/latex MIME type in LaTeXWriter. ([#1709]) + +## Version [v0.27.8] - 2021-10-14 + +### Added + +* The keyword argument `strict` in `makedocs` is more flexible: in addition to a boolean indicating whether or not any error should result in a failure, `strict` also accepts a `Symbol` or `Vector{Symbol}` indicating which error(s) should result in a build failure. ([#1689]) + +* Allow users to inject custom JavaScript resources to enable alternatives to Google Analytics like plausible.io. ([#1706]) + +### Fixed + +* Fix a few accessibility issues in the HTML output. ([#1673]) + +## Version [v0.27.7] - 2021-09-27 + +### Fixed + +* Fix an error when building documentation for the first time with `push_preview`. ([#1693], [#1704]) + +* Fix a rare logger error for failed doctests. ([#1698], [#1699]) + +* Fix an error occurring with `DocTestFilters = nothing` in `@meta` blocks. ([#1696]) + +## Version [v0.27.6] - 2021-09-07 + +### Added + +* Add support for generating `index.html` to redirect to `dev` or `stable`. The redirected destination is the same as the outdated warning. If there's already user-generated `index.html`, Documenter will not overwrite the file. ([#937], [#1657], [#1658]) + +### Fixed + +* Checking whether a PR comes from the correct repository when deciding to deploy a preview on GitHub Actions now works on Julia 1.0 too. ([#1665]) + +* When a doctest fails, pass file and line information associated to the location of the doctest instead of the location of the testing code in Documenter to the logger. ([#1687]) + +* Enabled colored printing for each output of `@repl`-blocks. ([#1691]) + +## Version [v0.27.5] - 2021-07-27 + +### Fixed + +* Fix an error introduced in version v0.27.4 (PR([#1634]) which was triggered by trailing comments in `@eval`/`@repl`/`@example` blocks. ([#1655], [#1661]) + +## Version [v0.27.4] - 2021-07-19 + +### Added + +* `@example`- and `@repl`-blocks now support colored output by mapping ANSI escape sequences to HTML. This requires Julia >= 1.6 and passing `ansicolor=true` to `Documenter.HTML` (e.g. `makedocs(format=Documenter.HTML(ansicolor=true, ...), ...)`). In Documenter 0.28.0 this will be the default so to (preemptively) opt-out pass `ansicolor=false`. ([#1441], [#1628], [#1629], [#1647]) + +* **Experimental** Documenter's HTML output can now prerender syntax highlighting of code blocks, i.e. syntax highlighting is applied when generating the HTML page rather than on the fly in the browser after the page is loaded. This requires (i) passing `prerender=true` to `Documenter.HTML` and (ii) a `node` (NodeJS) executable available in `PATH`. A path to a `node` executable can be specified by passing the `node` keyword argument to `Documenter.HTML` (for example from the `NodeJS_16_jll` Julia package). In addition, the `highlightjs` keyword argument can be used to specify a file path to a highlight.js library (if this is not given the release used by Documenter will be used). Example configuration: + ```julia + using Documenter, NodeJS_16_jll + + makedocs(; + format = Documenter.HTML( + prerender = true, # enable prerendering + node = NodeJS_16_jll.node(), # specify node executable (required if not available in PATH) + # ... + ) + # ... + ) + ``` + _This feature is experimental and subject to change in future releases._ ([#1627]) + +* The `julia>` prompt is now colored in green in the `julia-repl` language highlighting. ([#1639], [#1641]) + +* The `.hljs` CSS class is now added to all code blocks to make sure that the correct text color is used for non-highlighted code blocks and if JavaScript is disabled. ([#1645]) + +* The sandbox module used for evaluating `@repl` and `@example` blocks is now removed (replaced with `Main`) in text output. ([#1633]) + +* `@repl`, `@example`, and `@eval` blocks now have `LineNumberNodes` inserted such that e.g. `@__FILE__` and `@__LINE__` give better output and not just `"none"` for the file and `1` for the line. This requires Julia 1.6 or higher (no change on earlier Julia versions). ([#1634]) + +### Fixed + +* Dollar signs in the HTML output no longer get accidentally misinterpreted as math delimiters in the browser. ([#890], [#1625]) + +* Fix overflow behavior for math environments to hide unnecessary vertical scrollbars. ([#1575], [#1649]) + +## Version [v0.27.3] - 2021-06-29 + +### Added + +* Documenter can now deploy documentation directly to the "root" instead of versioned folders. ([#1615], [#1616]) + +* The version of Documenter used for generating a document is now displayed in the build information. ([#1609], [#1611]) + +### Fixed + +* The HTML front end no longer uses ligatures when displaying code (with JuliaMono). ([#1610], [#1617]) + +## Version [v0.27.2] - 2021-06-18 + +### Added + +* The default font has been changed to `Lato Medium` so that the look of the text would be closer to the old Google Fonts version of Lato. ([#1602], [#1604]) + +## Version [v0.27.1] - 2021-06-17 + +### Added + +* The HTML output now uses [JuliaMono](https://cormullion.github.io/pages/2020-07-26-JuliaMono/) as the default monospace font, retrieved from CDNJS. Relatedly, the Lato font is also now retrieved from CDNJS, and the generated HTML pages no longer depend on Google Fonts. ([#618], [#1561], [#1568], [#1569]), [JuliaLang/www.julialang.org](https://github.com/JuliaLang/www.julialang.org/issues/1272) + +* The wording of the text in the the old version warning box was improved. ([#1595]) + +### Fixed + +* Documenter no longer throws an error when generating the version selector if there are no deployed versions. ([#1594], [#1596]) + +## Version [v0.27.0] - 2021-06-11 + +### Added + +* The JS dependencies have been updated to their respective latest versions. + + - highlight.js has been updated to v11.0.1 (major version bump), which also brings various updates to the highlighting of Julia code. Due to the changes in highlight.js, code highlighting will not work on IE11. ([#1503], [#1551], [#1590]) + + - Headroom.js has been updated to v0.12.0 (major version bump). ([#1590]) + + - KaTeX been updated to v0.13.11 (major version bump). ([#1590]) + + - MathJax versions have been updated to v2.7.7 (patch version bump) and v3.1.4 (minor version bump), for MathJax 2 and 3, respectively. ([#1590]) + + - jQuery been updated to v3.6.0 (minor version bump). ([#1590]) + + - Font Awesome has been updated to v5.15.3 (patch version bump). ([#1590]) + + - lunr.js has been updated to v2.3.9 (patch version bump). ([#1590]) + + - lodash.js has been updated to v4.17.21 (patch version bump). ([#1590]) + +* `deploydocs` now throws an error if something goes wrong with the Git invocations used to deploy to `gh-pages`. ([#1529]) + +* In the HTML output, the site name at the top of the sidebar now also links back to the main page of the documentation (just like the logo). ([#1553]) + +* The generated HTML sites can now detect if the version the user is browsing is not for the latest version of the package and display a notice box to the user with a link to the latest version. In addition, the pages get a `noindex` tag which should aid in removing outdated versions from search engine results. ([#1302], [#1449], [#1577]) + +* The analytics in the HTML output now use the `gtag.js` script, replacing the old deprecated setup. ([#1559]) + +### Fixed + +* A bad `repo` argument to `deploydocs` containing a protocol now throws an error instead of being misinterpreted. ([#1531], [#1533]) + +* SVG images generated by `@example` blocks are now properly scaled to page width by URI-encoding the images, instead of directly embedding the SVG tags into the HTML. ([#1537], [#1538]) + +* `deploydocs` no longer tries to deploy pull request previews from forks on GitHub Actions. ([#1534], [#1567]) + +### Other + +* Documenter is no longer compatible with IOCapture v0.1 and now requires IOCapture v0.2. ([#1549]) + +## Version [v0.26.3] - 2021-03-02 + +### Fixed + +* The internal naming of the temporary modules used to run doctests changed to accommodate upcoming printing changes in Julia. ([JuliaLang/julia#39841], [#1540]) + +## Version [v0.26.2] - 2021-02-15 + +### Added + +* `doctest()` no longer throws an error if cleaning up the temporary directory fails for some reason. ([#1513], [#1526]) + +* Cosmetic improvements to the PDF output. ([#1342], [#1527]) + +* If `jldoctest` keyword arguments fail to parse, these now get logged as doctesting failures, rather than being ignored with a warning or making `makedocs` throw an error (depending on why they fail to parse). ([#1556], [#1557]) + +### Fixed + +* Script-type doctests that have an empty output section no longer crash Documenter. ([#1510]) + +* When checking for authentication keys when deploying, Documenter now more appropriately checks if the environment variables are non-empty, rather than just whether they are defined. ([#1511]) + +* Doctests now correctly handle the case when the repository has been checked out with `CRLF` line endings (which can happen on Windows with `core.autocrlf=true`). ([#1516], [#1519], [#1520]) + +* Multiline equations are now correctly handled in at-block outputs. ([#1518]) + +## Version [v0.26.1] - 2020-12-16 + +### Fixed + +* HTML assets that are copied directly from Documenters source to the build output now has correct file permissions. ([#1497]) + +## Version [v0.26.0] - 2020-12-10 + +### Breaking +* The PDF/LaTeX output is again provided as a Documenter built-in and can be enabled by passing an instance of `Documenter.LaTeX` to `format`. The DocumenterLaTeX package has been deprecated. ([#1493]) + + **For upgrading:** If using the PDF/LaTeX output, change the `format` argument of `makedocs` to `format = Documenter.LaTeX(...)` and remove all references to the DocumenterLaTeX package (e.g. from `docs/Project.toml`). + +### Added + +* Objects that render as equations and whose `text/latex` representations are wrapped in display equation delimiters `\[ ... \]` or `$$ ... $$` are now handled correctly in the HTML output. ([#1278], [#1283], [#1426]) + +* The search page in the HTML output now shows the page titles in the search results. ([#1468]) + +* The HTML front end now respects the user's OS-level dark theme preference (determined via the `prefers-color-scheme: dark` media query). ([#1320], [#1456]) + +* HTML output now bails early if there are no pages, instead of throwing an `UndefRefError`. In addition, it will also warn if `index.md` is missing and it is not able to generate the main landing page (`index.html`). ([#1201], [#1491]) + +* `deploydocs` now prints a warning on GitHub Actions, Travis CI and Buildkite if the current branch is `main`, but `devbranch = "master`, which indicates a possible Documenter misconfiguration due to GitHub changing the default primary branch of a repository to `main`. ([#1489]) + +## Version [v0.25.5] - 2020-11-23 + +### Fixed + +* In the HTML output, display equations that are wider than the page now get a scrollbar instead of overflowing. ([#1470], [#1476]) + +## Version [v0.25.4] - 2020-11-19 + +### Added + +* Documenter can now deploy from Buildkite CI to GitHub Pages with `Documenter.Buildkite`. ([#1469]) + +* Documenter now support Azure DevOps Repos URL scheme when generating edit and source links pointing to the repository. ([#1462], [#1463], [#1471]) + +### Fixed + +* Type aliases of `Union`s (e.g. `const MyAlias = Union{Foo,Bar}`) are now correctly listed as "Type" in docstrings. ([#1466], [#1474]) + +* HTMLWriter no longer prints a warning when encountering `mailto:` URLs in links. ([#1472]) + +## Version [v0.25.3] - 2020-10-28 + +### Added + +* Documenter can now deploy from GitLab CI to GitHub Pages with `Documenter.GitLab`. ([#1448]) + +* The URL to the MathJax JS module can now be customized by passing the `url` keyword argument to the constructors (`MathJax2`, `MathJax3`). ([#1428], [#1430]) + +### Fixed + +* `Documenter.doctest` now correctly accepts the `doctestfilters` keyword, similar to `Documenter.makedocs`. ([#1364], [#1435]) + +* The `Selectors.dispatch` function now uses a cache to avoid calling `subtypes` on selectors multiple times during a `makedocs` call to avoid slowdowns due to [`subtypes` being slow][julia-38079]. ([#1438], [#1440], [#1452]) + +## Version [v0.25.2] - 2020-08-18 + +### Deprecated + +* The `Documenter.MathJax` type, used to specify the mathematics rendering engine in the HTML output, is now deprecated in favor of `Documenter.MathJax2`. ([#1362], [#1367]) + + **For upgrading:** simply replace `MathJax` with `MathJax2`. I.e. instead of + + ``` + makedocs( + format = Documenter.HTML(mathengine = Documenter.MathJax(...), ...), + ... + ) + ``` + + you should have + + ``` + makedocs( + format = Documenter.HTML(mathengine = Documenter.MathJax2(...), ...), + ... + ) + ``` + +### Added + +* It is now possible to use MathJax v3 as the mathematics rendering in the HTML output. This can be done by passing `Documenter.MathJax3` as the `mathengine` keyword to `HTML`. ([#1362], [#1367]) + +* The deployment commits created by Documenter are no longer signed by the **@zeptodoctor** user, but rather with the non-existing `documenter@juliadocs.github.io` email address. ([#1379], [#1388]) + +### Fixed + +* REPL doctest output lines starting with `#` right after the input code part are now correctly treated as being part of the output (unless prepended with 7 spaces, in line with the standard heuristic). ([#1369]) + +* Documenter now throws away the extra information from the info string of a Markdown code block (i.e. ` ```language extra-info`), to correctly determine the language, which should be a single word. ([#1392], [#1400]) + +* Documenter now works around a Julia 1.5.0 regression ([JuliaLang/julia#36953]) which broke doctest fixing if the original doctest output was empty. ([#1337], [#1389]) + +## Version [v0.25.1] - 2020-07-21 + +### Added + +* When automatically determining the page list (i.e. `pages` is not passed to `makedocs`), Documenter now lists `index.md` before other pages. ([#1355]) + +* The output text boxes of `@example` blocks are now style differently from the code blocks, to make it easier to visually distinguish between the input and output. ([#1026], [#1357], [#1360]) + +* The generated HTML site now displays a footer by default that mentions Julia and Documenter. This can be customized or disabled by passing the `footer` keyword to `Documeter.HTML`. ([#1184], [#1365]) + +* Warnings that cause `makedocs` to error when `strict=true` are now printed as errors when `strict` is set to `true`. ([#1088], [#1349]) + +### Fixed + +* In the PDF/LaTeX output, equations that use the `align` or `align*` environment are no longer further wrapped in `equation*`/`split`. ([#1368]) + +## Version [v0.25.0] - 2020-06-30 + +### Added + +* When deploying with `deploydocs`, any SSH username can now be used (not just `git`), by prepending `username@` to the repository URL in the `repo` argument. ([#1285]) + +* The first link fragment on each page now omits the number; before the rendering resulted in: `#foobar-1`, `#foobar-2`, and now: `#foobar`, `#foobar-2`. For backwards compatibility the old fragments are also inserted such that old links will still point to the same location. ([#1292]) + +* When deploying on CI with `deploydocs`, the build information in the version number (i.e. what comes after `+`) is now discarded when determining the destination directory. This allows custom tags to be used to fix documentation build and deployment issues for versions that have already been registered. ([#1298]) + +* You can now optionally choose to push pull request preview builds to a different branch and/or different repository than the main docs builds, by setting the optional `branch_previews` and/or `repo_previews` keyword arguments to the `deploydocs` function. Also, you can now optionally choose to use a different SSH key for preview builds, by setting the optional `DOCUMENTER_KEY_PREVIEWS` environment variable; if the `DOCUMENTER_KEY_PREVIEWS` environment variable is not set, then the regular `DOCUMENTER_KEY` environment variable will be used. ([#1307], [#1310], [#1315]) + +* The LaTeX/PDF backend now supports the `platform="none"` keyword, which outputs only the TeX source files, rather than a compiled PDF. ([#1338], [#1339]) + +* Linkcheck no longer prints a warning when encountering a `302 Found` temporary redirect. ([#1344], [#1345]) + +### Fixed + +* `Deps.pip` is again a closure and gets executed during the `deploydocs` call, not before it. ([#1240]) + +* Custom assets (CSS, JS etc.) for the HTML build are now again included as the very last elements in the `` tag so that it would be possible to override default the default assets. ([#1328]) + +* Docstrings from `@autodocs` blocks are no longer sorted according to an undocumented rule where exported names should come before unexported names. Should this behavior be necessary, the `@autodocs` can be replaced by two separate blocks that use the `Public` and `Private` options to filter out the unexported or exported docstrings in the first or the second block, respectively. ([#964], [#1323]) + +## Version [v0.24.11] - 2020-05-06 + +### Fixed + +* Some sections and page titles that were missing from the search results in the HTML backend now show up. ([#1311]) + +## Version [v0.24.10] - 2020-04-26 + +### Added + +* The `curl` timeout when checking remote links is now configurable with the `linkcheck_timeout` keyword. ([#1057], [#1295]) + +### Fixed + +* Special characters are now properly escaped in admonition titles in LaTeX/PDF builds and do not cause the PDF build to fail anymore. ([#1299]) + +## Version [v0.24.9] - 2020-04-15 + +### Fixed + +* Canonical URLs are now properly prettified (e.g. `/path/` instead of `/path/index.html`) when using `prettyurls=true`. ([#1293]) + +## Version [v0.24.8] - 2020-04-13 + +### Added + +* Non-standard admonition categories are (again) applied to the admonition `
` elements in HTML output (as `is-category-$category`). ([#1279], [#1280]) + +## Version [v0.24.7] - 2020-03-23 + +### Fixed + +* Remove `only`, a new export from `Base` on Julia 1.4, from the JS search filter. ([#1264]) + +* Fix errors in LaTeX builds due to bad escaping of certain characters. ([#1118], [#1119], [#1200], [#1269]) + +## Version [v0.24.6] - 2020-03-12 + +### Added + +* Reorganize some of the internal variables in Documenter's Sass sources, to make it easier to create custom themes on top of the Documenter base theme. ([#1258]) + +## Version [v0.24.5] - 2020-01-31 + +### Added + +* Documenter now correctly emulates the "REPL softscope" (Julia 1.5) in REPL-style doctest blocks and `@repl` blocks. ([#1232]) + +## Version [v0.24.4] - 2020-01-18 + +### Added + +* Change the inline code to less distracting black color in the HTML light theme. ([#1212], [#1222]) + +* Add the ability specify the `lang` attribute of the `html` tag in the HTML output, to better support documentation pages in other languages. By default Documenter now defaults to `lang="en"`. ([#1223]) + +## Version [v0.24.3] - 2019-12-16 + +### Fixed + +* Fix a case where Documenter's deployment would fail due to git picking up the wrong ssh config file on non-standard systems. ([#1216]) + +## Version [v0.24.2] - 2019-11-26 + +### Other + +* Improvements to logging in `deploydocs`. ([#1195]) + +## Version [v0.24.1] - 2019-11-25 + +### Fixed + +* Fix a bad `mktempdir` incantation in `LaTeXWriter`. ([#1194]) + +## Version [v0.24.0] - 2019-11-22 + +### Breaking + +* Documenter no longer creates a symlink between the old `latest` url to specified `devurl`. ([#1151]) + + **For upgrading:** Make sure that links to the latest documentation have been updated (e.g. the package README). + +* The deprecated `makedocs` keywords (`html_prettyurls`, `html_disable_git`, `html_edit_branch`, `html_canonical`, `assets`, `analytics`) have been removed. ([#1107]) + + **For upgrading:** Pass the corresponding values to the `HTML` constructor when settings the `format` keyword. + +### Deprecated + +* The `edit_branch` keyword to `Documenter.HTML` has been deprecated in favor of the new `edit_link` keyword. As a new feature, passing `edit_link = nothing` disables the "Edit on GitHub" links altogether. ([#1173]) + + **For upgrading:** If using `edit_branch = nothing`, use `edit_link = :commit` instead. If passing a `String` to `edit_branch`, pass that to `edit_link` instead. + +### Added + +* Documenter can now deploy preview documentation from pull requests (with head branch in the same repository, i.e. not from forks). This is enabled by passing `push_preview=true` to `deploydocs`. ([#1180]) + +* Deployment is now more customizable and thus not as tied to Travis CI as before. ([#1147], [#1171], [#1180]) + +* Documenter now has builtin support for deploying from GitHub Actions. Documenter will autodetect the running system, unless explicitly specified. ([#1144], [#1152]) + +* When using GitHub Actions Documenter will (try to) post a GitHub status with a link to the generated documentation. This is especially useful for pull request preview builds (see above). ([#1186]) + +* The Documenter HTML front end now uses [KaTeX](https://katex.org/) as the default math rendering engine. ([#1097]) + + **Possible breakage:** This may break the rendering of equations that use some more esoteric features that are only supported in MathJax. It is possible to switch back to MathJax by passing `mathengine = Documenter.MathJax()` to the `HTML` constructor in the `format` keyword. + +* The HTML front end generated by Documenter has been redesigned and now uses the [Bulma CSS framework](https://bulma.io/). ([#1043]) + + **Possible breakage:** Packages overriding the default Documenter CSS file, relying on some external CSS or relying on Documenter's CSS working in a particular way will not build correct-looking sites. Custom themes should now be developed as Sass files and compiled together with the Documenter and Bulma Sass dependencies (under `assets/html/scss`). + +* The handling of JS and CSS assets is now more customizable: + + * The `asset` function can now be used to declare remote JS and CSS assets in the `assets` keyword. ([#1108]) + * The `highlights` keyword to `HTML` can be used to declare additional languages that should be highlighted in code blocks. ([#1094]) + * It is now possible to choose between MathJax and KaTeX as the math rendering engine with the `mathengine` keyword to `HTML` and to set their configuration in the `make.jl` script directly. ([#1097]) + +* The JS and CSS dependencies of the front end have been updated to the latest versions. ([#1189]) + +* Displaying of the site name at the top of the sidebar can now be disabled by passing `sidebar_sitename = false` to `HTML` in the `format` keyword. ([#1089]) + +* For deployments that have Google Analytics enabled, the URL fragment (i.e. the in-page `#` target) also stored in analytics. ([#1121]) + +* Page titles are now boosted in the search, yielding better search results. ([#631], [#1112], [#1113]) + +* In the PDF/LaTeX output, images that are wider than the text are now being scaled down to text width automatically. The PDF builds now require the `adjustbox` LaTeX package to be available. ([#1137]) + +* If the TeX compilation fails for the PDF/LaTeX output, `makedocs` now throws an exception. ([#1166]) + +### Fixed + +* `LaTeXWriter` now outputs valid LaTeX if an `@contents` block is nested by more than two levels, or if `@contents` or `@index` blocks do not contain any items. ([#1166]) + +## Version [v0.23.4] - 2019-10-09 + +### Fixed + +* The `include` and `eval` functions are also available in `@setup` blocks now. ([#1148], [#1153]) + +## Version [v0.23.3] - 2019-08-28 + +### Fixed + +* Fix file permission error when `Pkg.test`ing Documenter. ([#1115]) + +## Version [v0.23.2] - 2019-08-04 + +### Fixed + +* Empty Markdown headings no longer cause Documenter to crash. ([#1081], [#1082]) + +## Version [v0.23.1] - 2019-07-28 + +### Fixed + +* Documenter no longer throws an error if the provided `EditURL` argument is missing. ([#1076], [#1077]) + +* Non-standard Markdown AST nodes no longer cause Documenter to exit with a missing method error in doctesting and HTML output. Documenter falls back to `repr()` for such nodes. ([#1073], [#1075]) + +* Docstrings parsed into nested `Markdown.MD` objects are now unwrapped correctly and do not cause Documenter to crash with a missing method error anymore. The user can run into that when reusing docstrings with the `@doc @doc(foo) function bar end` pattern. ([#1075]) + +## Version [v0.23.0] - 2019-07-18 + +### Version changes + +* Documenter v0.23 requires Julia v1.0. ([#1015]) + +### Breaking + +* `DocTestSetup`s that are defined in `@meta` blocks no longer apply to doctests that are in docstrings. ([#774]) + + - Specifically, the pattern where `@docs` or `@autodocs` blocks were surrounded by `@meta` blocks, setting up a shared `DocTestSetup` for many docstrings, no longer works. + + - Documenter now exports the `DocMeta` module, which provides an alternative way to add `DocTestSetup` to docstrings. + + **For upgrading:** Use `DocMeta.setdocmeta!` in `make.jl` to set up a `DocTestSetup` that applies to all the docstrings in a particular module instead and, if applicable, remove the now redundant `@meta` blocks. See the ["Setup code" section under "Doctesting"](https://documenter.juliadocs.org/v0.23/man/doctests/#Setup-Code-1) in the manual for more information. + +### Added + +* `makedocs` now accepts the `doctest = :only` keyword, which allows doctests to be run while most other build steps, such as rendering, are skipped. This makes it more feasible to run doctests as part of the test suite (see the manual for more information). ([#198], [#535], [#756], [#774]) + +* Documenter now exports the `doctest` function, which verifies the doctests in all the docstrings of a given module. This can be used to verify docstring doctests as part of test suite, or to fix doctests right in the REPL. ([#198], [#535], [#756], [#774], [#1054]) + +* `makedocs` now accepts the `expandfirst` argument, which allows specifying a set of pages that should be evaluated before others. ([#1027], [#1029]) + +* The evaluation order of pages is now fixed (unless customized with `expandfirst`). The pages are evaluated in the alphabetical order of their file paths. ([#1027], [#1029]) + +* The logo image in the HTML output will now always point to the first page in the navigation menu (as opposed to `index.html`, which may or may not exist). When using pretty URLs, the `index.html` part now omitted from the logo link URL. ([#1005]) + +* Minor changes to how doctesting errors are printed. ([#1028]) + +* Videos can now be included in the HTML output using the image syntax (`![]()`) if the file extension matches a known format (`.webm`, `.mp4`, `.ogg`, `.ogm`, `.ogv`, `.avi`). ([#1034]) + +* The PDF output now uses the DejaVu Sans and DejaVu Sans Mono fonts to provide better Unicode coverage. ([#803], [#1066]) + +* **Experimental** The current working directory when evaluating `@repl` and `@example` blocks can now be set to a fixed directory by passing the `workdir` keyword to `makedocs`. _The new keyword and its behaviour are experimental and not part of the public API._ ([#1013], [#1025]) + +### Fixed + +* The HTML output now outputs HTML files for pages that are not referenced in the `pages` keyword too (Documenter finds them according to their extension). But they do exists outside of the standard navigation hierarchy (as defined by `pages`). This fixes a bug where these pages could still be referenced by `@ref` links and `@contents` blocks, but in the HTML output, the links ended up being broken. ([#1031], [#1047]) + +* `makedocs` now throws an error when the format objects (`Documenter.HTML`, `LaTeX`, `Markdown`) get passed positionally. The format types are no longer subtypes of `Documenter.Plugin`. ([#1046], [#1061]) + +* Doctesting now also handles doctests that contain invalid syntax and throw parsing errors. ([#487], [#1062]) + +* Stacktraces in doctests that throw an error are now filtered more thoroughly, fixing an issue where too much of the stacktrace was included when `doctest` or `makedocs` was called from a more complicated context. ([#1062]) + +## Version [v0.22.6] - 2019-07-18 + +### Other + +* Add DocStringExtensions 0.8 as an allowed dependency version. ([#1071]) + +## Version [v0.22.5] - 2019-07-03 + +### Fixed + +* Fix a test dependency problem revealed by a bugfix in Julia / Pkg. ([#1037]) + +## Version [v0.22.4] - 2019-05-09 + +### Fixed + +* Documenter no longer crashes if the build includes doctests from docstrings that are defined in files that do not exist on the file system (e.g. if a Julia Base docstring is included when running a non-source Julia build). ([#1002]) + +* URLs for files in the repository are now generated correctly when the repository is used as a Git submodule in another repository. ([#1000], [#1004]) + +* When checking for omitted docstrings, Documenter no longer gives "`Package.Package` missing" type false positives. ([#1009]) + +* `makedocs` again exits with an error if `strict=true` and there is a doctest failure. ([#1003], [#1014]) + +## Version [v0.22.3] - 2019-04-12 + +### Fixed + +* Fixed filepaths for images included in the .tex file for PDF output on Windows. ([#999]) + +## Version [v0.22.2] - 2019-04-05 + +### Fixed + +* Error reporting for meta-blocks now handles missing files gracefully instead of throwing. ([#996]) + +### Added + +* The `sitename` keyword argument to `deploydocs`, which is required for the default HTML output, is now properly documented. ([#995]) + +## Version [v0.22.1] - 2019-03-30 + +### Fixed + +* Fixed a world-age related bug in doctests. ([#994]) + +## Version [v0.22.0] - 2019-03-28 + +### Deprecated + +* The `assets` and `analytics` arguments to `makedocs` have been deprecated in favor of the corresponding arguments of the `Documenter.HTML` format plugin. ([#953]) + + **For upgrading:** pass the corresponding arguments with the `Documenter.HTML` plugin instead. E.g. instead of + + ``` + makedocs( + assets = ..., analytics = ..., + ... + ) + ``` + + you should have + + ``` + makedocs( + format = Documenter.HTML(assets = ..., analytics = ...), + ... + ) + ``` + + _**Note:** It is technically possible to specify the same argument twice with different values by passing both variants. In that case the value passed to `makedocs` takes precedence._ + +### Added + +* Documentation is no longer deployed on Travis CI cron jobs. ([#917]) + +* Log messages from failed `@meta`, `@docs`, `@autodocs`, + `@eval`, `@example` and `@setup` blocks now include information about the source location + of the block. ([#929]) + +* Docstrings from `@docs`-blocks are now included in the + rendered docs even if some part(s) of the block failed. ([#928], [#935]) + +* The Markdown and LaTeX output writers can now handle multimedia + output, such as images, from `@example` blocks. All the writers now also handle `text/markdown` + output, which is preferred over `text/plain` if available. ([#938], [#948]) + +* The HTML output now also supports SVG, WebP, GIF and JPEG logos. ([#953]) + +* Reporting of failed doctests are now using the logging + system to be consistent with the rest of Documenter's output. ([#958]) + +* The construction of the search index in the HTML output has been refactored to make it easier to use with other search backends in the future. The structure of the generated search index has also been modified, which can yield slightly different search results. Documenter now depends on the lightweight [JSON.jl](https://github.com/JuliaIO/JSON.jl) package. ([#966]) + +* Docstrings that begin with an indented code block (such as a function signature) now have that block highlighted as Julia code by default. + This behaviour can be disabled by passing `highlightsig=false` to `makedocs`. ([#980]) + +### Fixed + +* Paths in `include` calls in `@eval`, `@example`, `@repl` and `jldoctest` + blocks are now interpreted to be relative `pwd`, which is set to the output directory of the + resulting file. ([#941]) + +* `deploydocs` and `git_push` now support non-github repos correctly and work when the `.ssh` directory does not already exist or the working directory contains spaces. ([#971]) + +* Tables now honor column alignment in the HTML output. If a column does not explicitly specify its alignment, the parser defaults to it being right-aligned, whereas previously all cells were left-aligned. ([#511], [#989]) + +* Code lines ending with `# hide` are now properly hidden for CRLF inputs. ([#991]) + +## Version [v0.21.5] - 2019-02-22 + +### Fixed + +* Deprecation warnings for `format` now get printed correctly when multiple formats are passed as a `Vector`. ([#967]) + +## Version [v0.21.4] - 2019-02-16 + +### Fixed + +* A bug in `jldoctest`-blocks that, in rare cases, resulted in + wrong output has been fixed. ([#959], [#960]) + +## Version [v0.21.3] - 2019-02-12 + +### Security + +* The lunr.js and lodash JavaScript dependencies have been updated to their latest patch versions (from 2.3.1 to 2.3.5 and 4.17.4 to 4.17.11, respectively). + This is in response to a vulnerability in lodash <4.17.11 ([CVE-2018-16487](https://nvd.nist.gov/vuln/detail/CVE-2018-16487)). ([#946]) + +## Version [v0.21.2] - 2019-02-06 + +### Fixed + +* `linkcheck` now handles servers that do not support `HEAD` requests + and properly checks for status codes of FTP responses. ([#934]) + +## Version [v0.21.1] - 2019-01-29 + +### Fixed + +* `@repl` blocks now work correctly together with quoted + expressions. ([#923], [#926]) + +* `@example`, `@repl` and `@eval` blocks now handle reserved words, + e.g. `try`/`catch`, correctly. ([#886], [#927]) + +## Version [v0.21.0] - 2018-12-11 + +### Deprecated + +* The symbol values to the `format` argument of `makedocs` (`:html`, `:markdown`, `:latex`) have been deprecated in favor of the `Documenter.HTML`, `Markdown` and `LaTeX` + objects. The `Markdown` and `LaTeX` types are exported from the [DocumenterMarkdown](https://github.com/JuliaDocs/DocumenterMarkdown.jl) and [DocumenterLaTeX](https://github.com/JuliaDocs/DocumenterLaTeX.jl) packages, + respectively. HTML output is still the default. ([#891]) + + **For upgrading:** If you don't specify `format` (i.e. you rely on the default) you don't have to do anything. + Otherwise update calls to `makedocs` to use struct instances instead of symbols, e.g. + + ``` + makedocs( + format = :markdown + ) + ``` + + should be changed to + + ``` + using DocumenterMarkdown + makedocs( + format = Markdown() + ) + ``` + +* The `html_prettyurls`, `html_canonical`, `html_disable_git` and `html_edit_branch` arguments to `makedocs` have been deprecated in favor of the corresponding arguments of the `Documenter.HTML` format plugin. ([#864], [#891]) + + **For upgrading:** pass the corresponding arguments with the `Documenter.HTML` plugin instead. E.g. instead of + + ``` + makedocs( + html_prettyurls = ..., html_canonical = ..., + ... + ) + ``` + + you should have + + ``` + makedocs( + format = Documenter.HTML(prettyurls = ..., canonical = ...), + ... + ) + ``` + + _**Note:** It is technically possible to specify the same argument twice with different values by passing both variants. In that case the value to the deprecated `html_*` variant takes precedence._ + +### Added + +* Packages extending Documenter can now define subtypes of `Documenter.Plugin`, + which can be passed to `makedocs` as positional arguments to pass options to the extensions. ([#864]) + +* `@autodocs` blocks now support the `Filter` keyword, which allows passing a user-defined function that will filter the methods spliced in by the at-autodocs block. ([#885]) + +* `linkcheck` now supports checking URLs using the FTP protocol. ([#879]) + +* Build output logging has been improved and switched to the logging macros from `Base`. ([#876]) + +* The default `documenter.sty` LaTeX preamble now include `\usepackage{graphicx}`. ([#898]) + +* `deploydocs` is now more helpful when it fails to interpret `DOCUMENTER_KEY`. It now also uses the `BatchMode` SSH option and throws an error instead of asking for a passphrase and timing out the Travis build when `DOCUMENTER_KEY` is broken. ([#697], [#907]) + +* `deploydocs` now have a `forcepush` keyword argument that can be used to + force-push the built documentation instead of adding a new commit. ([#905]) + +## Version [v0.20.0] - 2018-10-27 + +### Version changes + +* Documenter v0.20 requires at least Julia v0.7. ([#795]) + +### Breaking + +* Documentation deployment via the `deploydocs` function has changed considerably. + + - The user-facing directories (URLs) of different versions and what gets displayed in the version selector have changed. By default, Documenter now creates the `stable/` directory (as before) and a directory for every minor version (`vX.Y/`). The `release-X.Y` directories are no longer created. ([#706], [#813], [#817]) + + Technically, Documenter now deploys actual files only to `dev/` and `vX.Y.Z/` directories. The directories (URLs) that change from version to version (e.g. `latest/`, `vX.Y`) are implemented as symlinks on the `gh-pages` branch. + + The version selector will only display `vX.Y/`, `stable/` and `dev/` directories by default. This behavior can be customized with the `versions` keyword of `deploydocs`. + + - Documentation from the development branch (e.g. `master`) now deploys to `dev/` by default (instead of `latest/`). This can be customized with the `devurl` keyword. ([#802]) + + - The `latest` keyword to `deploydocs` has been deprecated and renamed to `devbranch`. ([#802]) + + - The `julia` and `osname` keywords to `deploydocs` are now deprecated. ([#816]) + + - The default values of the `target`, `deps` and `make` keywords to `deploydocs` have been changed. See the default format change below for more information. ([#826]) + + **For upgrading:** + + - If you are using the `latest` keyword, then just use `devbranch` with the same value instead. + + - Update links that point to `latest/` to point to `dev/` instead (e.g. in the README). + + - Remove any links to the `release-X.Y` branches and remove the directories from your `gh-pages` branch. + + - The operating system and Julia version should be specified in the Travis build stage configuration (via `julia:` and `os:` options, see "Hosting Documentation" in the manual for more details) or by checking the `TRAVIS_JULIA_VERSION` and `TRAVIS_OS_NAME` environment variables in `make.jl` yourself. + +* `makedocs` will now build Documenter's native HTML output by default and `deploydocs`' defaults now assume the HTML output. ([#826]) + + - The default value of the `format` keyword of `makedocs` has been changed to `:html`. + + - The default value of the `target` keyword to `deploydocs` has been changed to `"build"`. + + - The default value of the `make` and `deps` keywords to `deploydocs` have been changed to `nothing`. + + **For upgrading:** If you are relying on the Markdown/MkDocs output, you now need to: + + - In `makedocs`, explicitly set `format = :markdown` + + - In `deploydocs`, explicitly set + + ```julia + target = "site" + deps = Deps.pip("pygments", "mkdocs") + make = () -> run(`mkdocs build`) + ``` + + - Explicitly import `DocumenterMarkdown` in `make.jl`. See the `MarkdownWriter` deprecation below. + + If you already specify any of the changed keywords, then you do not need to make any changes to those keywords you already set. + + However, if you are setting any of the values to the new defaults (e.g. when you are already using the HTML output), you may now rely on the new defaults. + +* "Pretty URLs" are enabled by default now for the HTML output. The default value of the `html_prettyurls` has been changed to `true`. + + For a page `foo/page.md` Documenter now generates `foo/page/index.html`, instead of `foo/page.html`. + On GitHub pages deployments it means that your URLs look like `foo/page/` instead of `foo/page.html`. + + For local builds you should explicitly set `html_prettyurls = false`. + + **For upgrading:** If you wish to retain the old behavior, set `html_prettyurls = false` in `makedocs`. If you already set `html_prettyurls`, you do not need to change anything. + +* The `Travis.genkeys` and `Documenter.generate` functions have been moved to a separate [DocumenterTools.jl package](https://github.com/JuliaDocs/DocumenterTools.jl). ([#789]) + +### Deprecated + +* The Markdown/MkDocs (`format = :markdown`) and PDF/LaTeX (`format = :latex`) outputs now require an external package to be loaded ([DocumenterMarkdown](https://github.com/JuliaDocs/DocumenterMarkdown.jl) and [DocumenterLaTeX](https://github.com/JuliaDocs/DocumenterLaTeX.jl), respectively). ([#833]) + + **For upgrading:** Make sure that the respective extra package is installed and then just add `using DocumenterMarkdown` or `using DocumenterLaTeX` to `make.jl`. + +### Added + +* If Documenter is not able to determine which Git hosting service is being used to host the source, the "Edit on XXX" links become "Edit source" with a generic icon. ([#804]) + +* The at-blocks now support `MIME"text/html"` rendering of objects (e.g. for interactive plots). I.e. if a type has `show(io, ::MIME"text/html", x)` defined, Documenter now uses that when rendering the objects in the document. ([#764]) + +* Addeds to the sidebar. When loading a page, the sidebar will jump to the current page now. Also, the scrollbar in WebKit-based browsers look less intrusive now. ([#792], [#854], [#863]) + +* Minor style enhancements to admonitions. ([#841]) + +### Fixed + +* The at-blocks that execute code can now handle `include` statements. ([#793], [#794]) + +* At-docs blocks no longer give an error when containing empty lines. ([#823], [#824]) + + + + +[v0.20.0]: https://github.com/JuliaDocs/Documenter.jl/releases/tag/v0.20.0 +[v0.21.0]: https://github.com/JuliaDocs/Documenter.jl/releases/tag/v0.21.0 +[v0.21.1]: https://github.com/JuliaDocs/Documenter.jl/releases/tag/v0.21.1 +[v0.21.2]: https://github.com/JuliaDocs/Documenter.jl/releases/tag/v0.21.2 +[v0.21.3]: https://github.com/JuliaDocs/Documenter.jl/releases/tag/v0.21.3 +[v0.21.4]: https://github.com/JuliaDocs/Documenter.jl/releases/tag/v0.21.4 +[v0.21.5]: https://github.com/JuliaDocs/Documenter.jl/releases/tag/v0.21.5 +[v0.22.0]: https://github.com/JuliaDocs/Documenter.jl/releases/tag/v0.22.0 +[v0.22.1]: https://github.com/JuliaDocs/Documenter.jl/releases/tag/v0.22.1 +[v0.22.2]: https://github.com/JuliaDocs/Documenter.jl/releases/tag/v0.22.2 +[v0.22.3]: https://github.com/JuliaDocs/Documenter.jl/releases/tag/v0.22.3 +[v0.22.4]: https://github.com/JuliaDocs/Documenter.jl/releases/tag/v0.22.4 +[v0.22.5]: https://github.com/JuliaDocs/Documenter.jl/releases/tag/v0.22.5 +[v0.22.6]: https://github.com/JuliaDocs/Documenter.jl/releases/tag/v0.22.6 +[v0.23.0]: https://github.com/JuliaDocs/Documenter.jl/releases/tag/v0.23.0 +[v0.23.1]: https://github.com/JuliaDocs/Documenter.jl/releases/tag/v0.23.1 +[v0.23.2]: https://github.com/JuliaDocs/Documenter.jl/releases/tag/v0.23.2 +[v0.23.3]: https://github.com/JuliaDocs/Documenter.jl/releases/tag/v0.23.3 +[v0.23.4]: https://github.com/JuliaDocs/Documenter.jl/releases/tag/v0.23.4 +[v0.24.0]: https://github.com/JuliaDocs/Documenter.jl/releases/tag/v0.24.0 +[v0.24.1]: https://github.com/JuliaDocs/Documenter.jl/releases/tag/v0.24.1 +[v0.24.2]: https://github.com/JuliaDocs/Documenter.jl/releases/tag/v0.24.2 +[v0.24.3]: https://github.com/JuliaDocs/Documenter.jl/releases/tag/v0.24.3 +[v0.24.4]: https://github.com/JuliaDocs/Documenter.jl/releases/tag/v0.24.4 +[v0.24.5]: https://github.com/JuliaDocs/Documenter.jl/releases/tag/v0.24.5 +[v0.24.6]: https://github.com/JuliaDocs/Documenter.jl/releases/tag/v0.24.6 +[v0.24.7]: https://github.com/JuliaDocs/Documenter.jl/releases/tag/v0.24.7 +[v0.24.8]: https://github.com/JuliaDocs/Documenter.jl/releases/tag/v0.24.8 +[v0.24.9]: https://github.com/JuliaDocs/Documenter.jl/releases/tag/v0.24.9 +[v0.24.10]: https://github.com/JuliaDocs/Documenter.jl/releases/tag/v0.24.10 +[v0.24.11]: https://github.com/JuliaDocs/Documenter.jl/releases/tag/v0.24.11 +[v0.25.0]: https://github.com/JuliaDocs/Documenter.jl/releases/tag/v0.25.0 +[v0.25.1]: https://github.com/JuliaDocs/Documenter.jl/releases/tag/v0.25.1 +[v0.25.2]: https://github.com/JuliaDocs/Documenter.jl/releases/tag/v0.25.2 +[v0.25.3]: https://github.com/JuliaDocs/Documenter.jl/releases/tag/v0.25.3 +[v0.25.4]: https://github.com/JuliaDocs/Documenter.jl/releases/tag/v0.25.4 +[v0.25.5]: https://github.com/JuliaDocs/Documenter.jl/releases/tag/v0.25.5 +[v0.26.0]: https://github.com/JuliaDocs/Documenter.jl/releases/tag/v0.26.0 +[v0.26.1]: https://github.com/JuliaDocs/Documenter.jl/releases/tag/v0.26.1 +[v0.26.2]: https://github.com/JuliaDocs/Documenter.jl/releases/tag/v0.26.2 +[v0.26.3]: https://github.com/JuliaDocs/Documenter.jl/releases/tag/v0.26.3 +[v0.27.0]: https://github.com/JuliaDocs/Documenter.jl/releases/tag/v0.27.0 +[v0.27.1]: https://github.com/JuliaDocs/Documenter.jl/releases/tag/v0.27.1 +[v0.27.2]: https://github.com/JuliaDocs/Documenter.jl/releases/tag/v0.27.2 +[v0.27.3]: https://github.com/JuliaDocs/Documenter.jl/releases/tag/v0.27.3 +[v0.27.4]: https://github.com/JuliaDocs/Documenter.jl/releases/tag/v0.27.4 +[v0.27.5]: https://github.com/JuliaDocs/Documenter.jl/releases/tag/v0.27.5 +[v0.27.6]: https://github.com/JuliaDocs/Documenter.jl/releases/tag/v0.27.6 +[v0.27.7]: https://github.com/JuliaDocs/Documenter.jl/releases/tag/v0.27.7 +[v0.27.8]: https://github.com/JuliaDocs/Documenter.jl/releases/tag/v0.27.8 +[v0.27.9]: https://github.com/JuliaDocs/Documenter.jl/releases/tag/v0.27.9 +[v0.27.10]: https://github.com/JuliaDocs/Documenter.jl/releases/tag/v0.27.10 +[v0.27.11]: https://github.com/JuliaDocs/Documenter.jl/releases/tag/v0.27.11 +[v0.27.12]: https://github.com/JuliaDocs/Documenter.jl/releases/tag/v0.27.12 +[v0.27.13]: https://github.com/JuliaDocs/Documenter.jl/releases/tag/v0.27.13 +[v0.27.14]: https://github.com/JuliaDocs/Documenter.jl/releases/tag/v0.27.14 +[v0.27.15]: https://github.com/JuliaDocs/Documenter.jl/releases/tag/v0.27.15 +[v0.27.16]: https://github.com/JuliaDocs/Documenter.jl/releases/tag/v0.27.16 +[v0.27.17]: https://github.com/JuliaDocs/Documenter.jl/releases/tag/v0.27.17 +[v0.27.18]: https://github.com/JuliaDocs/Documenter.jl/releases/tag/v0.27.18 +[v0.27.19]: https://github.com/JuliaDocs/Documenter.jl/releases/tag/v0.27.19 +[v0.27.20]: https://github.com/JuliaDocs/Documenter.jl/releases/tag/v0.27.20 +[v0.27.21]: https://github.com/JuliaDocs/Documenter.jl/releases/tag/v0.27.21 +[v0.27.22]: https://github.com/JuliaDocs/Documenter.jl/releases/tag/v0.27.22 +[v0.27.23]: https://github.com/JuliaDocs/Documenter.jl/releases/tag/v0.27.23 +[v0.27.24]: https://github.com/JuliaDocs/Documenter.jl/releases/tag/v0.27.24 +[v0.27.25]: https://github.com/JuliaDocs/Documenter.jl/releases/tag/v0.27.25 +[v1.0.0]: https://github.com/JuliaDocs/Documenter.jl/releases/tag/v1.0.0 +[v1.0.1]: https://github.com/JuliaDocs/Documenter.jl/releases/tag/v1.0.1 +[v1.1.0]: https://github.com/JuliaDocs/Documenter.jl/releases/tag/v1.1.0 +[v1.1.1]: https://github.com/JuliaDocs/Documenter.jl/releases/tag/v1.1.1 +[v1.1.2]: https://github.com/JuliaDocs/Documenter.jl/releases/tag/v1.1.2 +[v1.2.0]: https://github.com/JuliaDocs/Documenter.jl/releases/tag/v1.2.0 +[v1.2.1]: https://github.com/JuliaDocs/Documenter.jl/releases/tag/v1.2.1 +[v1.3.0]: https://github.com/JuliaDocs/Documenter.jl/releases/tag/v1.3.0 +[v1.4.0]: https://github.com/JuliaDocs/Documenter.jl/releases/tag/v1.4.0 +[v1.4.1]: https://github.com/JuliaDocs/Documenter.jl/releases/tag/v1.4.1 +[v1.5.0]: https://github.com/JuliaDocs/Documenter.jl/releases/tag/v1.5.0 +[v1.6.0]: https://github.com/JuliaDocs/Documenter.jl/releases/tag/v1.6.0 +[v1.7.0]: https://github.com/JuliaDocs/Documenter.jl/releases/tag/v1.7.0 +[v1.8.0]: https://github.com/JuliaDocs/Documenter.jl/releases/tag/v1.8.0 +[#198]: https://github.com/JuliaDocs/Documenter.jl/issues/198 +[#245]: https://github.com/JuliaDocs/Documenter.jl/issues/245 +[#487]: https://github.com/JuliaDocs/Documenter.jl/issues/487 +[#491]: https://github.com/JuliaDocs/Documenter.jl/issues/491 +[#505]: https://github.com/JuliaDocs/Documenter.jl/issues/505 +[#511]: https://github.com/JuliaDocs/Documenter.jl/issues/511 +[#535]: https://github.com/JuliaDocs/Documenter.jl/issues/535 +[#618]: https://github.com/JuliaDocs/Documenter.jl/issues/618 +[#631]: https://github.com/JuliaDocs/Documenter.jl/issues/631 +[#697]: https://github.com/JuliaDocs/Documenter.jl/issues/697 +[#706]: https://github.com/JuliaDocs/Documenter.jl/issues/706 +[#744]: https://github.com/JuliaDocs/Documenter.jl/issues/744 +[#756]: https://github.com/JuliaDocs/Documenter.jl/issues/756 +[#764]: https://github.com/JuliaDocs/Documenter.jl/issues/764 +[#774]: https://github.com/JuliaDocs/Documenter.jl/issues/774 +[#781]: https://github.com/JuliaDocs/Documenter.jl/issues/781 +[#789]: https://github.com/JuliaDocs/Documenter.jl/issues/789 +[#792]: https://github.com/JuliaDocs/Documenter.jl/issues/792 +[#793]: https://github.com/JuliaDocs/Documenter.jl/issues/793 +[#794]: https://github.com/JuliaDocs/Documenter.jl/issues/794 +[#795]: https://github.com/JuliaDocs/Documenter.jl/issues/795 +[#802]: https://github.com/JuliaDocs/Documenter.jl/issues/802 +[#803]: https://github.com/JuliaDocs/Documenter.jl/issues/803 +[#804]: https://github.com/JuliaDocs/Documenter.jl/issues/804 +[#813]: https://github.com/JuliaDocs/Documenter.jl/issues/813 +[#816]: https://github.com/JuliaDocs/Documenter.jl/issues/816 +[#817]: https://github.com/JuliaDocs/Documenter.jl/issues/817 +[#823]: https://github.com/JuliaDocs/Documenter.jl/issues/823 +[#824]: https://github.com/JuliaDocs/Documenter.jl/issues/824 +[#826]: https://github.com/JuliaDocs/Documenter.jl/issues/826 +[#833]: https://github.com/JuliaDocs/Documenter.jl/issues/833 +[#841]: https://github.com/JuliaDocs/Documenter.jl/issues/841 +[#854]: https://github.com/JuliaDocs/Documenter.jl/issues/854 +[#863]: https://github.com/JuliaDocs/Documenter.jl/issues/863 +[#864]: https://github.com/JuliaDocs/Documenter.jl/issues/864 +[#876]: https://github.com/JuliaDocs/Documenter.jl/issues/876 +[#879]: https://github.com/JuliaDocs/Documenter.jl/issues/879 +[#885]: https://github.com/JuliaDocs/Documenter.jl/issues/885 +[#886]: https://github.com/JuliaDocs/Documenter.jl/issues/886 +[#890]: https://github.com/JuliaDocs/Documenter.jl/issues/890 +[#891]: https://github.com/JuliaDocs/Documenter.jl/issues/891 +[#898]: https://github.com/JuliaDocs/Documenter.jl/issues/898 +[#905]: https://github.com/JuliaDocs/Documenter.jl/issues/905 +[#907]: https://github.com/JuliaDocs/Documenter.jl/issues/907 +[#917]: https://github.com/JuliaDocs/Documenter.jl/issues/917 +[#923]: https://github.com/JuliaDocs/Documenter.jl/issues/923 +[#926]: https://github.com/JuliaDocs/Documenter.jl/issues/926 +[#927]: https://github.com/JuliaDocs/Documenter.jl/issues/927 +[#928]: https://github.com/JuliaDocs/Documenter.jl/issues/928 +[#929]: https://github.com/JuliaDocs/Documenter.jl/issues/929 +[#934]: https://github.com/JuliaDocs/Documenter.jl/issues/934 +[#935]: https://github.com/JuliaDocs/Documenter.jl/issues/935 +[#937]: https://github.com/JuliaDocs/Documenter.jl/issues/937 +[#938]: https://github.com/JuliaDocs/Documenter.jl/issues/938 +[#941]: https://github.com/JuliaDocs/Documenter.jl/issues/941 +[#946]: https://github.com/JuliaDocs/Documenter.jl/issues/946 +[#948]: https://github.com/JuliaDocs/Documenter.jl/issues/948 +[#953]: https://github.com/JuliaDocs/Documenter.jl/issues/953 +[#958]: https://github.com/JuliaDocs/Documenter.jl/issues/958 +[#959]: https://github.com/JuliaDocs/Documenter.jl/issues/959 +[#960]: https://github.com/JuliaDocs/Documenter.jl/issues/960 +[#964]: https://github.com/JuliaDocs/Documenter.jl/issues/964 +[#966]: https://github.com/JuliaDocs/Documenter.jl/issues/966 +[#967]: https://github.com/JuliaDocs/Documenter.jl/issues/967 +[#971]: https://github.com/JuliaDocs/Documenter.jl/issues/971 +[#974]: https://github.com/JuliaDocs/Documenter.jl/issues/974 +[#980]: https://github.com/JuliaDocs/Documenter.jl/issues/980 +[#989]: https://github.com/JuliaDocs/Documenter.jl/issues/989 +[#991]: https://github.com/JuliaDocs/Documenter.jl/issues/991 +[#994]: https://github.com/JuliaDocs/Documenter.jl/issues/994 +[#995]: https://github.com/JuliaDocs/Documenter.jl/issues/995 +[#996]: https://github.com/JuliaDocs/Documenter.jl/issues/996 +[#999]: https://github.com/JuliaDocs/Documenter.jl/issues/999 +[#1000]: https://github.com/JuliaDocs/Documenter.jl/issues/1000 +[#1002]: https://github.com/JuliaDocs/Documenter.jl/issues/1002 +[#1003]: https://github.com/JuliaDocs/Documenter.jl/issues/1003 +[#1004]: https://github.com/JuliaDocs/Documenter.jl/issues/1004 +[#1005]: https://github.com/JuliaDocs/Documenter.jl/issues/1005 +[#1009]: https://github.com/JuliaDocs/Documenter.jl/issues/1009 +[#1013]: https://github.com/JuliaDocs/Documenter.jl/issues/1013 +[#1014]: https://github.com/JuliaDocs/Documenter.jl/issues/1014 +[#1015]: https://github.com/JuliaDocs/Documenter.jl/issues/1015 +[#1025]: https://github.com/JuliaDocs/Documenter.jl/issues/1025 +[#1026]: https://github.com/JuliaDocs/Documenter.jl/issues/1026 +[#1027]: https://github.com/JuliaDocs/Documenter.jl/issues/1027 +[#1028]: https://github.com/JuliaDocs/Documenter.jl/issues/1028 +[#1029]: https://github.com/JuliaDocs/Documenter.jl/issues/1029 +[#1031]: https://github.com/JuliaDocs/Documenter.jl/issues/1031 +[#1034]: https://github.com/JuliaDocs/Documenter.jl/issues/1034 +[#1037]: https://github.com/JuliaDocs/Documenter.jl/issues/1037 +[#1043]: https://github.com/JuliaDocs/Documenter.jl/issues/1043 +[#1046]: https://github.com/JuliaDocs/Documenter.jl/issues/1046 +[#1047]: https://github.com/JuliaDocs/Documenter.jl/issues/1047 +[#1054]: https://github.com/JuliaDocs/Documenter.jl/issues/1054 +[#1057]: https://github.com/JuliaDocs/Documenter.jl/issues/1057 +[#1061]: https://github.com/JuliaDocs/Documenter.jl/issues/1061 +[#1062]: https://github.com/JuliaDocs/Documenter.jl/issues/1062 +[#1066]: https://github.com/JuliaDocs/Documenter.jl/issues/1066 +[#1071]: https://github.com/JuliaDocs/Documenter.jl/issues/1071 +[#1073]: https://github.com/JuliaDocs/Documenter.jl/issues/1073 +[#1075]: https://github.com/JuliaDocs/Documenter.jl/issues/1075 +[#1076]: https://github.com/JuliaDocs/Documenter.jl/issues/1076 +[#1077]: https://github.com/JuliaDocs/Documenter.jl/issues/1077 +[#1079]: https://github.com/JuliaDocs/Documenter.jl/issues/1079 +[#1081]: https://github.com/JuliaDocs/Documenter.jl/issues/1081 +[#1082]: https://github.com/JuliaDocs/Documenter.jl/issues/1082 +[#1088]: https://github.com/JuliaDocs/Documenter.jl/issues/1088 +[#1089]: https://github.com/JuliaDocs/Documenter.jl/issues/1089 +[#1094]: https://github.com/JuliaDocs/Documenter.jl/issues/1094 +[#1097]: https://github.com/JuliaDocs/Documenter.jl/issues/1097 +[#1107]: https://github.com/JuliaDocs/Documenter.jl/issues/1107 +[#1108]: https://github.com/JuliaDocs/Documenter.jl/issues/1108 +[#1112]: https://github.com/JuliaDocs/Documenter.jl/issues/1112 +[#1113]: https://github.com/JuliaDocs/Documenter.jl/issues/1113 +[#1115]: https://github.com/JuliaDocs/Documenter.jl/issues/1115 +[#1118]: https://github.com/JuliaDocs/Documenter.jl/issues/1118 +[#1119]: https://github.com/JuliaDocs/Documenter.jl/issues/1119 +[#1121]: https://github.com/JuliaDocs/Documenter.jl/issues/1121 +[#1137]: https://github.com/JuliaDocs/Documenter.jl/issues/1137 +[#1144]: https://github.com/JuliaDocs/Documenter.jl/issues/1144 +[#1147]: https://github.com/JuliaDocs/Documenter.jl/issues/1147 +[#1148]: https://github.com/JuliaDocs/Documenter.jl/issues/1148 +[#1151]: https://github.com/JuliaDocs/Documenter.jl/issues/1151 +[#1152]: https://github.com/JuliaDocs/Documenter.jl/issues/1152 +[#1153]: https://github.com/JuliaDocs/Documenter.jl/issues/1153 +[#1166]: https://github.com/JuliaDocs/Documenter.jl/issues/1166 +[#1171]: https://github.com/JuliaDocs/Documenter.jl/issues/1171 +[#1173]: https://github.com/JuliaDocs/Documenter.jl/issues/1173 +[#1180]: https://github.com/JuliaDocs/Documenter.jl/issues/1180 +[#1184]: https://github.com/JuliaDocs/Documenter.jl/issues/1184 +[#1186]: https://github.com/JuliaDocs/Documenter.jl/issues/1186 +[#1189]: https://github.com/JuliaDocs/Documenter.jl/issues/1189 +[#1192]: https://github.com/JuliaDocs/Documenter.jl/issues/1192 +[#1194]: https://github.com/JuliaDocs/Documenter.jl/issues/1194 +[#1195]: https://github.com/JuliaDocs/Documenter.jl/issues/1195 +[#1200]: https://github.com/JuliaDocs/Documenter.jl/issues/1200 +[#1201]: https://github.com/JuliaDocs/Documenter.jl/issues/1201 +[#1212]: https://github.com/JuliaDocs/Documenter.jl/issues/1212 +[#1216]: https://github.com/JuliaDocs/Documenter.jl/issues/1216 +[#1222]: https://github.com/JuliaDocs/Documenter.jl/issues/1222 +[#1223]: https://github.com/JuliaDocs/Documenter.jl/issues/1223 +[#1232]: https://github.com/JuliaDocs/Documenter.jl/issues/1232 +[#1240]: https://github.com/JuliaDocs/Documenter.jl/issues/1240 +[#1254]: https://github.com/JuliaDocs/Documenter.jl/issues/1254 +[#1258]: https://github.com/JuliaDocs/Documenter.jl/issues/1258 +[#1264]: https://github.com/JuliaDocs/Documenter.jl/issues/1264 +[#1269]: https://github.com/JuliaDocs/Documenter.jl/issues/1269 +[#1271]: https://github.com/JuliaDocs/Documenter.jl/issues/1271 +[#1278]: https://github.com/JuliaDocs/Documenter.jl/issues/1278 +[#1279]: https://github.com/JuliaDocs/Documenter.jl/issues/1279 +[#1280]: https://github.com/JuliaDocs/Documenter.jl/issues/1280 +[#1283]: https://github.com/JuliaDocs/Documenter.jl/issues/1283 +[#1285]: https://github.com/JuliaDocs/Documenter.jl/issues/1285 +[#1291]: https://github.com/JuliaDocs/Documenter.jl/issues/1291 +[#1292]: https://github.com/JuliaDocs/Documenter.jl/issues/1292 +[#1293]: https://github.com/JuliaDocs/Documenter.jl/issues/1293 +[#1295]: https://github.com/JuliaDocs/Documenter.jl/issues/1295 +[#1298]: https://github.com/JuliaDocs/Documenter.jl/issues/1298 +[#1299]: https://github.com/JuliaDocs/Documenter.jl/issues/1299 +[#1302]: https://github.com/JuliaDocs/Documenter.jl/issues/1302 +[#1307]: https://github.com/JuliaDocs/Documenter.jl/issues/1307 +[#1310]: https://github.com/JuliaDocs/Documenter.jl/issues/1310 +[#1311]: https://github.com/JuliaDocs/Documenter.jl/issues/1311 +[#1312]: https://github.com/JuliaDocs/Documenter.jl/issues/1312 +[#1315]: https://github.com/JuliaDocs/Documenter.jl/issues/1315 +[#1320]: https://github.com/JuliaDocs/Documenter.jl/issues/1320 +[#1321]: https://github.com/JuliaDocs/Documenter.jl/issues/1321 +[#1323]: https://github.com/JuliaDocs/Documenter.jl/issues/1323 +[#1328]: https://github.com/JuliaDocs/Documenter.jl/issues/1328 +[#1337]: https://github.com/JuliaDocs/Documenter.jl/issues/1337 +[#1338]: https://github.com/JuliaDocs/Documenter.jl/issues/1338 +[#1339]: https://github.com/JuliaDocs/Documenter.jl/issues/1339 +[#1342]: https://github.com/JuliaDocs/Documenter.jl/issues/1342 +[#1344]: https://github.com/JuliaDocs/Documenter.jl/issues/1344 +[#1345]: https://github.com/JuliaDocs/Documenter.jl/issues/1345 +[#1349]: https://github.com/JuliaDocs/Documenter.jl/issues/1349 +[#1355]: https://github.com/JuliaDocs/Documenter.jl/issues/1355 +[#1357]: https://github.com/JuliaDocs/Documenter.jl/issues/1357 +[#1360]: https://github.com/JuliaDocs/Documenter.jl/issues/1360 +[#1362]: https://github.com/JuliaDocs/Documenter.jl/issues/1362 +[#1364]: https://github.com/JuliaDocs/Documenter.jl/issues/1364 +[#1365]: https://github.com/JuliaDocs/Documenter.jl/issues/1365 +[#1367]: https://github.com/JuliaDocs/Documenter.jl/issues/1367 +[#1368]: https://github.com/JuliaDocs/Documenter.jl/issues/1368 +[#1369]: https://github.com/JuliaDocs/Documenter.jl/issues/1369 +[#1379]: https://github.com/JuliaDocs/Documenter.jl/issues/1379 +[#1388]: https://github.com/JuliaDocs/Documenter.jl/issues/1388 +[#1389]: https://github.com/JuliaDocs/Documenter.jl/issues/1389 +[#1392]: https://github.com/JuliaDocs/Documenter.jl/issues/1392 +[#1393]: https://github.com/JuliaDocs/Documenter.jl/issues/1393 +[#1400]: https://github.com/JuliaDocs/Documenter.jl/issues/1400 +[#1426]: https://github.com/JuliaDocs/Documenter.jl/issues/1426 +[#1428]: https://github.com/JuliaDocs/Documenter.jl/issues/1428 +[#1430]: https://github.com/JuliaDocs/Documenter.jl/issues/1430 +[#1435]: https://github.com/JuliaDocs/Documenter.jl/issues/1435 +[#1437]: https://github.com/JuliaDocs/Documenter.jl/issues/1437 +[#1438]: https://github.com/JuliaDocs/Documenter.jl/issues/1438 +[#1440]: https://github.com/JuliaDocs/Documenter.jl/issues/1440 +[#1441]: https://github.com/JuliaDocs/Documenter.jl/issues/1441 +[#1443]: https://github.com/JuliaDocs/Documenter.jl/issues/1443 +[#1448]: https://github.com/JuliaDocs/Documenter.jl/issues/1448 +[#1449]: https://github.com/JuliaDocs/Documenter.jl/issues/1449 +[#1452]: https://github.com/JuliaDocs/Documenter.jl/issues/1452 +[#1456]: https://github.com/JuliaDocs/Documenter.jl/issues/1456 +[#1462]: https://github.com/JuliaDocs/Documenter.jl/issues/1462 +[#1463]: https://github.com/JuliaDocs/Documenter.jl/issues/1463 +[#1466]: https://github.com/JuliaDocs/Documenter.jl/issues/1466 +[#1468]: https://github.com/JuliaDocs/Documenter.jl/issues/1468 +[#1469]: https://github.com/JuliaDocs/Documenter.jl/issues/1469 +[#1470]: https://github.com/JuliaDocs/Documenter.jl/issues/1470 +[#1471]: https://github.com/JuliaDocs/Documenter.jl/issues/1471 +[#1472]: https://github.com/JuliaDocs/Documenter.jl/issues/1472 +[#1474]: https://github.com/JuliaDocs/Documenter.jl/issues/1474 +[#1476]: https://github.com/JuliaDocs/Documenter.jl/issues/1476 +[#1489]: https://github.com/JuliaDocs/Documenter.jl/issues/1489 +[#1491]: https://github.com/JuliaDocs/Documenter.jl/issues/1491 +[#1493]: https://github.com/JuliaDocs/Documenter.jl/issues/1493 +[#1497]: https://github.com/JuliaDocs/Documenter.jl/issues/1497 +[#1503]: https://github.com/JuliaDocs/Documenter.jl/issues/1503 +[#1510]: https://github.com/JuliaDocs/Documenter.jl/issues/1510 +[#1511]: https://github.com/JuliaDocs/Documenter.jl/issues/1511 +[#1513]: https://github.com/JuliaDocs/Documenter.jl/issues/1513 +[#1516]: https://github.com/JuliaDocs/Documenter.jl/issues/1516 +[#1518]: https://github.com/JuliaDocs/Documenter.jl/issues/1518 +[#1519]: https://github.com/JuliaDocs/Documenter.jl/issues/1519 +[#1520]: https://github.com/JuliaDocs/Documenter.jl/issues/1520 +[#1526]: https://github.com/JuliaDocs/Documenter.jl/issues/1526 +[#1527]: https://github.com/JuliaDocs/Documenter.jl/issues/1527 +[#1529]: https://github.com/JuliaDocs/Documenter.jl/issues/1529 +[#1531]: https://github.com/JuliaDocs/Documenter.jl/issues/1531 +[#1533]: https://github.com/JuliaDocs/Documenter.jl/issues/1533 +[#1534]: https://github.com/JuliaDocs/Documenter.jl/issues/1534 +[#1536]: https://github.com/JuliaDocs/Documenter.jl/issues/1536 +[#1537]: https://github.com/JuliaDocs/Documenter.jl/issues/1537 +[#1538]: https://github.com/JuliaDocs/Documenter.jl/issues/1538 +[#1540]: https://github.com/JuliaDocs/Documenter.jl/issues/1540 +[#1549]: https://github.com/JuliaDocs/Documenter.jl/issues/1549 +[#1551]: https://github.com/JuliaDocs/Documenter.jl/issues/1551 +[#1553]: https://github.com/JuliaDocs/Documenter.jl/issues/1553 +[#1554]: https://github.com/JuliaDocs/Documenter.jl/issues/1554 +[#1556]: https://github.com/JuliaDocs/Documenter.jl/issues/1556 +[#1557]: https://github.com/JuliaDocs/Documenter.jl/issues/1557 +[#1559]: https://github.com/JuliaDocs/Documenter.jl/issues/1559 +[#1561]: https://github.com/JuliaDocs/Documenter.jl/issues/1561 +[#1567]: https://github.com/JuliaDocs/Documenter.jl/issues/1567 +[#1568]: https://github.com/JuliaDocs/Documenter.jl/issues/1568 +[#1569]: https://github.com/JuliaDocs/Documenter.jl/issues/1569 +[#1570]: https://github.com/JuliaDocs/Documenter.jl/issues/1570 +[#1575]: https://github.com/JuliaDocs/Documenter.jl/issues/1575 +[#1577]: https://github.com/JuliaDocs/Documenter.jl/issues/1577 +[#1590]: https://github.com/JuliaDocs/Documenter.jl/issues/1590 +[#1594]: https://github.com/JuliaDocs/Documenter.jl/issues/1594 +[#1595]: https://github.com/JuliaDocs/Documenter.jl/issues/1595 +[#1596]: https://github.com/JuliaDocs/Documenter.jl/issues/1596 +[#1602]: https://github.com/JuliaDocs/Documenter.jl/issues/1602 +[#1604]: https://github.com/JuliaDocs/Documenter.jl/issues/1604 +[#1609]: https://github.com/JuliaDocs/Documenter.jl/issues/1609 +[#1610]: https://github.com/JuliaDocs/Documenter.jl/issues/1610 +[#1611]: https://github.com/JuliaDocs/Documenter.jl/issues/1611 +[#1615]: https://github.com/JuliaDocs/Documenter.jl/issues/1615 +[#1616]: https://github.com/JuliaDocs/Documenter.jl/issues/1616 +[#1617]: https://github.com/JuliaDocs/Documenter.jl/issues/1617 +[#1625]: https://github.com/JuliaDocs/Documenter.jl/issues/1625 +[#1627]: https://github.com/JuliaDocs/Documenter.jl/issues/1627 +[#1628]: https://github.com/JuliaDocs/Documenter.jl/issues/1628 +[#1629]: https://github.com/JuliaDocs/Documenter.jl/issues/1629 +[#1633]: https://github.com/JuliaDocs/Documenter.jl/issues/1633 +[#1634]: https://github.com/JuliaDocs/Documenter.jl/issues/1634 +[#1639]: https://github.com/JuliaDocs/Documenter.jl/issues/1639 +[#1641]: https://github.com/JuliaDocs/Documenter.jl/issues/1641 +[#1645]: https://github.com/JuliaDocs/Documenter.jl/issues/1645 +[#1647]: https://github.com/JuliaDocs/Documenter.jl/issues/1647 +[#1649]: https://github.com/JuliaDocs/Documenter.jl/issues/1649 +[#1655]: https://github.com/JuliaDocs/Documenter.jl/issues/1655 +[#1657]: https://github.com/JuliaDocs/Documenter.jl/issues/1657 +[#1658]: https://github.com/JuliaDocs/Documenter.jl/issues/1658 +[#1661]: https://github.com/JuliaDocs/Documenter.jl/issues/1661 +[#1665]: https://github.com/JuliaDocs/Documenter.jl/issues/1665 +[#1667]: https://github.com/JuliaDocs/Documenter.jl/issues/1667 +[#1673]: https://github.com/JuliaDocs/Documenter.jl/issues/1673 +[#1687]: https://github.com/JuliaDocs/Documenter.jl/issues/1687 +[#1689]: https://github.com/JuliaDocs/Documenter.jl/issues/1689 +[#1691]: https://github.com/JuliaDocs/Documenter.jl/issues/1691 +[#1693]: https://github.com/JuliaDocs/Documenter.jl/issues/1693 +[#1695]: https://github.com/JuliaDocs/Documenter.jl/issues/1695 +[#1696]: https://github.com/JuliaDocs/Documenter.jl/issues/1696 +[#1698]: https://github.com/JuliaDocs/Documenter.jl/issues/1698 +[#1699]: https://github.com/JuliaDocs/Documenter.jl/issues/1699 +[#1704]: https://github.com/JuliaDocs/Documenter.jl/issues/1704 +[#1706]: https://github.com/JuliaDocs/Documenter.jl/issues/1706 +[#1709]: https://github.com/JuliaDocs/Documenter.jl/issues/1709 +[#1716]: https://github.com/JuliaDocs/Documenter.jl/issues/1716 +[#1727]: https://github.com/JuliaDocs/Documenter.jl/issues/1727 +[#1728]: https://github.com/JuliaDocs/Documenter.jl/issues/1728 +[#1743]: https://github.com/JuliaDocs/Documenter.jl/issues/1743 +[#1745]: https://github.com/JuliaDocs/Documenter.jl/issues/1745 +[#1746]: https://github.com/JuliaDocs/Documenter.jl/issues/1746 +[#1748]: https://github.com/JuliaDocs/Documenter.jl/issues/1748 +[#1750]: https://github.com/JuliaDocs/Documenter.jl/issues/1750 +[#1751]: https://github.com/JuliaDocs/Documenter.jl/issues/1751 +[#1752]: https://github.com/JuliaDocs/Documenter.jl/issues/1752 +[#1754]: https://github.com/JuliaDocs/Documenter.jl/issues/1754 +[#1756]: https://github.com/JuliaDocs/Documenter.jl/issues/1756 +[#1758]: https://github.com/JuliaDocs/Documenter.jl/issues/1758 +[#1759]: https://github.com/JuliaDocs/Documenter.jl/issues/1759 +[#1760]: https://github.com/JuliaDocs/Documenter.jl/issues/1760 +[#1762]: https://github.com/JuliaDocs/Documenter.jl/issues/1762 +[#1766]: https://github.com/JuliaDocs/Documenter.jl/issues/1766 +[#1770]: https://github.com/JuliaDocs/Documenter.jl/issues/1770 +[#1771]: https://github.com/JuliaDocs/Documenter.jl/issues/1771 +[#1772]: https://github.com/JuliaDocs/Documenter.jl/issues/1772 +[#1773]: https://github.com/JuliaDocs/Documenter.jl/issues/1773 +[#1774]: https://github.com/JuliaDocs/Documenter.jl/issues/1774 +[#1776]: https://github.com/JuliaDocs/Documenter.jl/issues/1776 +[#1780]: https://github.com/JuliaDocs/Documenter.jl/issues/1780 +[#1784]: https://github.com/JuliaDocs/Documenter.jl/issues/1784 +[#1785]: https://github.com/JuliaDocs/Documenter.jl/issues/1785 +[#1788]: https://github.com/JuliaDocs/Documenter.jl/issues/1788 +[#1792]: https://github.com/JuliaDocs/Documenter.jl/issues/1792 +[#1795]: https://github.com/JuliaDocs/Documenter.jl/issues/1795 +[#1796]: https://github.com/JuliaDocs/Documenter.jl/issues/1796 +[#1797]: https://github.com/JuliaDocs/Documenter.jl/issues/1797 +[#1802]: https://github.com/JuliaDocs/Documenter.jl/issues/1802 +[#1803]: https://github.com/JuliaDocs/Documenter.jl/issues/1803 +[#1805]: https://github.com/JuliaDocs/Documenter.jl/issues/1805 +[#1806]: https://github.com/JuliaDocs/Documenter.jl/issues/1806 +[#1807]: https://github.com/JuliaDocs/Documenter.jl/issues/1807 +[#1808]: https://github.com/JuliaDocs/Documenter.jl/issues/1808 +[#1810]: https://github.com/JuliaDocs/Documenter.jl/issues/1810 +[#1811]: https://github.com/JuliaDocs/Documenter.jl/issues/1811 +[#1814]: https://github.com/JuliaDocs/Documenter.jl/issues/1814 +[#1816]: https://github.com/JuliaDocs/Documenter.jl/issues/1816 +[#1818]: https://github.com/JuliaDocs/Documenter.jl/issues/1818 +[#1821]: https://github.com/JuliaDocs/Documenter.jl/issues/1821 +[#1825]: https://github.com/JuliaDocs/Documenter.jl/issues/1825 +[#1826]: https://github.com/JuliaDocs/Documenter.jl/issues/1826 +[#1827]: https://github.com/JuliaDocs/Documenter.jl/issues/1827 +[#1828]: https://github.com/JuliaDocs/Documenter.jl/issues/1828 +[#1829]: https://github.com/JuliaDocs/Documenter.jl/issues/1829 +[#1833]: https://github.com/JuliaDocs/Documenter.jl/issues/1833 +[#1834]: https://github.com/JuliaDocs/Documenter.jl/issues/1834 +[#1835]: https://github.com/JuliaDocs/Documenter.jl/issues/1835 +[#1836]: https://github.com/JuliaDocs/Documenter.jl/issues/1836 +[#1838]: https://github.com/JuliaDocs/Documenter.jl/issues/1838 +[#1841]: https://github.com/JuliaDocs/Documenter.jl/issues/1841 +[#1842]: https://github.com/JuliaDocs/Documenter.jl/issues/1842 +[#1844]: https://github.com/JuliaDocs/Documenter.jl/issues/1844 +[#1846]: https://github.com/JuliaDocs/Documenter.jl/issues/1846 +[#1857]: https://github.com/JuliaDocs/Documenter.jl/issues/1857 +[#1861]: https://github.com/JuliaDocs/Documenter.jl/issues/1861 +[#1862]: https://github.com/JuliaDocs/Documenter.jl/issues/1862 +[#1865]: https://github.com/JuliaDocs/Documenter.jl/issues/1865 +[#1870]: https://github.com/JuliaDocs/Documenter.jl/issues/1870 +[#1871]: https://github.com/JuliaDocs/Documenter.jl/issues/1871 +[#1880]: https://github.com/JuliaDocs/Documenter.jl/issues/1880 +[#1881]: https://github.com/JuliaDocs/Documenter.jl/issues/1881 +[#1885]: https://github.com/JuliaDocs/Documenter.jl/issues/1885 +[#1886]: https://github.com/JuliaDocs/Documenter.jl/issues/1886 +[#1890]: https://github.com/JuliaDocs/Documenter.jl/issues/1890 +[#1892]: https://github.com/JuliaDocs/Documenter.jl/issues/1892 +[#1900]: https://github.com/JuliaDocs/Documenter.jl/issues/1900 +[#1903]: https://github.com/JuliaDocs/Documenter.jl/issues/1903 +[#1906]: https://github.com/JuliaDocs/Documenter.jl/issues/1906 +[#1908]: https://github.com/JuliaDocs/Documenter.jl/issues/1908 +[#1909]: https://github.com/JuliaDocs/Documenter.jl/issues/1909 +[#1912]: https://github.com/JuliaDocs/Documenter.jl/issues/1912 +[#1919]: https://github.com/JuliaDocs/Documenter.jl/issues/1919 +[#1924]: https://github.com/JuliaDocs/Documenter.jl/issues/1924 +[#1930]: https://github.com/JuliaDocs/Documenter.jl/issues/1930 +[#1931]: https://github.com/JuliaDocs/Documenter.jl/issues/1931 +[#1932]: https://github.com/JuliaDocs/Documenter.jl/issues/1932 +[#1933]: https://github.com/JuliaDocs/Documenter.jl/issues/1933 +[#1935]: https://github.com/JuliaDocs/Documenter.jl/issues/1935 +[#1936]: https://github.com/JuliaDocs/Documenter.jl/issues/1936 +[#1937]: https://github.com/JuliaDocs/Documenter.jl/issues/1937 +[#1944]: https://github.com/JuliaDocs/Documenter.jl/issues/1944 +[#1946]: https://github.com/JuliaDocs/Documenter.jl/issues/1946 +[#1948]: https://github.com/JuliaDocs/Documenter.jl/issues/1948 +[#1955]: https://github.com/JuliaDocs/Documenter.jl/issues/1955 +[#1956]: https://github.com/JuliaDocs/Documenter.jl/issues/1956 +[#1957]: https://github.com/JuliaDocs/Documenter.jl/issues/1957 +[#1958]: https://github.com/JuliaDocs/Documenter.jl/issues/1958 +[#1962]: https://github.com/JuliaDocs/Documenter.jl/issues/1962 +[#1969]: https://github.com/JuliaDocs/Documenter.jl/issues/1969 +[#1970]: https://github.com/JuliaDocs/Documenter.jl/issues/1970 +[#1976]: https://github.com/JuliaDocs/Documenter.jl/issues/1976 +[#1977]: https://github.com/JuliaDocs/Documenter.jl/issues/1977 +[#1980]: https://github.com/JuliaDocs/Documenter.jl/issues/1980 +[#1983]: https://github.com/JuliaDocs/Documenter.jl/issues/1983 +[#1989]: https://github.com/JuliaDocs/Documenter.jl/issues/1989 +[#1991]: https://github.com/JuliaDocs/Documenter.jl/issues/1991 +[#1993]: https://github.com/JuliaDocs/Documenter.jl/issues/1993 +[#2012]: https://github.com/JuliaDocs/Documenter.jl/issues/2012 +[#2018]: https://github.com/JuliaDocs/Documenter.jl/issues/2018 +[#2019]: https://github.com/JuliaDocs/Documenter.jl/issues/2019 +[#2027]: https://github.com/JuliaDocs/Documenter.jl/issues/2027 +[#2051]: https://github.com/JuliaDocs/Documenter.jl/issues/2051 +[#2066]: https://github.com/JuliaDocs/Documenter.jl/issues/2066 +[#2067]: https://github.com/JuliaDocs/Documenter.jl/issues/2067 +[#2070]: https://github.com/JuliaDocs/Documenter.jl/issues/2070 +[#2071]: https://github.com/JuliaDocs/Documenter.jl/issues/2071 +[#2076]: https://github.com/JuliaDocs/Documenter.jl/issues/2076 +[#2078]: https://github.com/JuliaDocs/Documenter.jl/issues/2078 +[#2081]: https://github.com/JuliaDocs/Documenter.jl/issues/2081 +[#2085]: https://github.com/JuliaDocs/Documenter.jl/issues/2085 +[#2100]: https://github.com/JuliaDocs/Documenter.jl/issues/2100 +[#2103]: https://github.com/JuliaDocs/Documenter.jl/issues/2103 +[#2128]: https://github.com/JuliaDocs/Documenter.jl/issues/2128 +[#2130]: https://github.com/JuliaDocs/Documenter.jl/issues/2130 +[#2134]: https://github.com/JuliaDocs/Documenter.jl/issues/2134 +[#2141]: https://github.com/JuliaDocs/Documenter.jl/issues/2141 +[#2142]: https://github.com/JuliaDocs/Documenter.jl/issues/2142 +[#2143]: https://github.com/JuliaDocs/Documenter.jl/issues/2143 +[#2145]: https://github.com/JuliaDocs/Documenter.jl/issues/2145 +[#2147]: https://github.com/JuliaDocs/Documenter.jl/issues/2147 +[#2153]: https://github.com/JuliaDocs/Documenter.jl/issues/2153 +[#2157]: https://github.com/JuliaDocs/Documenter.jl/issues/2157 +[#2169]: https://github.com/JuliaDocs/Documenter.jl/issues/2169 +[#2170]: https://github.com/JuliaDocs/Documenter.jl/issues/2170 +[#2181]: https://github.com/JuliaDocs/Documenter.jl/issues/2181 +[#2187]: https://github.com/JuliaDocs/Documenter.jl/issues/2187 +[#2191]: https://github.com/JuliaDocs/Documenter.jl/issues/2191 +[#2194]: https://github.com/JuliaDocs/Documenter.jl/issues/2194 +[#2202]: https://github.com/JuliaDocs/Documenter.jl/issues/2202 +[#2203]: https://github.com/JuliaDocs/Documenter.jl/issues/2203 +[#2204]: https://github.com/JuliaDocs/Documenter.jl/issues/2204 +[#2205]: https://github.com/JuliaDocs/Documenter.jl/issues/2205 +[#2211]: https://github.com/JuliaDocs/Documenter.jl/issues/2211 +[#2213]: https://github.com/JuliaDocs/Documenter.jl/issues/2213 +[#2214]: https://github.com/JuliaDocs/Documenter.jl/issues/2214 +[#2215]: https://github.com/JuliaDocs/Documenter.jl/issues/2215 +[#2216]: https://github.com/JuliaDocs/Documenter.jl/issues/2216 +[#2217]: https://github.com/JuliaDocs/Documenter.jl/issues/2217 +[#2232]: https://github.com/JuliaDocs/Documenter.jl/issues/2232 +[#2233]: https://github.com/JuliaDocs/Documenter.jl/issues/2233 +[#2236]: https://github.com/JuliaDocs/Documenter.jl/issues/2236 +[#2237]: https://github.com/JuliaDocs/Documenter.jl/issues/2237 +[#2245]: https://github.com/JuliaDocs/Documenter.jl/issues/2245 +[#2247]: https://github.com/JuliaDocs/Documenter.jl/issues/2247 +[#2249]: https://github.com/JuliaDocs/Documenter.jl/issues/2249 +[#2252]: https://github.com/JuliaDocs/Documenter.jl/issues/2252 +[#2259]: https://github.com/JuliaDocs/Documenter.jl/issues/2259 +[#2260]: https://github.com/JuliaDocs/Documenter.jl/issues/2260 +[#2269]: https://github.com/JuliaDocs/Documenter.jl/issues/2269 +[#2272]: https://github.com/JuliaDocs/Documenter.jl/issues/2272 +[#2273]: https://github.com/JuliaDocs/Documenter.jl/issues/2273 +[#2274]: https://github.com/JuliaDocs/Documenter.jl/issues/2274 +[#2279]: https://github.com/JuliaDocs/Documenter.jl/issues/2279 +[#2280]: https://github.com/JuliaDocs/Documenter.jl/issues/2280 +[#2281]: https://github.com/JuliaDocs/Documenter.jl/issues/2281 +[#2282]: https://github.com/JuliaDocs/Documenter.jl/issues/2282 +[#2285]: https://github.com/JuliaDocs/Documenter.jl/issues/2285 +[#2288]: https://github.com/JuliaDocs/Documenter.jl/issues/2288 +[#2293]: https://github.com/JuliaDocs/Documenter.jl/issues/2293 +[#2300]: https://github.com/JuliaDocs/Documenter.jl/issues/2300 +[#2303]: https://github.com/JuliaDocs/Documenter.jl/issues/2303 +[#2306]: https://github.com/JuliaDocs/Documenter.jl/issues/2306 +[#2307]: https://github.com/JuliaDocs/Documenter.jl/issues/2307 +[#2308]: https://github.com/JuliaDocs/Documenter.jl/issues/2308 +[#2313]: https://github.com/JuliaDocs/Documenter.jl/issues/2313 +[#2317]: https://github.com/JuliaDocs/Documenter.jl/issues/2317 +[#2324]: https://github.com/JuliaDocs/Documenter.jl/issues/2324 +[#2325]: https://github.com/JuliaDocs/Documenter.jl/issues/2325 +[#2327]: https://github.com/JuliaDocs/Documenter.jl/issues/2327 +[#2329]: https://github.com/JuliaDocs/Documenter.jl/issues/2329 +[#2330]: https://github.com/JuliaDocs/Documenter.jl/issues/2330 +[#2335]: https://github.com/JuliaDocs/Documenter.jl/issues/2335 +[#2337]: https://github.com/JuliaDocs/Documenter.jl/issues/2337 +[#2339]: https://github.com/JuliaDocs/Documenter.jl/issues/2339 +[#2344]: https://github.com/JuliaDocs/Documenter.jl/issues/2344 +[#2348]: https://github.com/JuliaDocs/Documenter.jl/issues/2348 +[#2364]: https://github.com/JuliaDocs/Documenter.jl/issues/2364 +[#2365]: https://github.com/JuliaDocs/Documenter.jl/issues/2365 +[#2366]: https://github.com/JuliaDocs/Documenter.jl/issues/2366 +[#2373]: https://github.com/JuliaDocs/Documenter.jl/issues/2373 +[#2374]: https://github.com/JuliaDocs/Documenter.jl/issues/2374 +[#2375]: https://github.com/JuliaDocs/Documenter.jl/issues/2375 +[#2378]: https://github.com/JuliaDocs/Documenter.jl/issues/2378 +[#2394]: https://github.com/JuliaDocs/Documenter.jl/issues/2394 +[#2406]: https://github.com/JuliaDocs/Documenter.jl/issues/2406 +[#2408]: https://github.com/JuliaDocs/Documenter.jl/issues/2408 +[#2414]: https://github.com/JuliaDocs/Documenter.jl/issues/2414 +[#2415]: https://github.com/JuliaDocs/Documenter.jl/issues/2415 +[#2424]: https://github.com/JuliaDocs/Documenter.jl/issues/2424 +[#2430]: https://github.com/JuliaDocs/Documenter.jl/issues/2430 +[#2438]: https://github.com/JuliaDocs/Documenter.jl/issues/2438 +[#2441]: https://github.com/JuliaDocs/Documenter.jl/issues/2441 +[#2449]: https://github.com/JuliaDocs/Documenter.jl/issues/2449 +[#2458]: https://github.com/JuliaDocs/Documenter.jl/issues/2458 +[#2459]: https://github.com/JuliaDocs/Documenter.jl/issues/2459 +[#2460]: https://github.com/JuliaDocs/Documenter.jl/issues/2460 +[#2461]: https://github.com/JuliaDocs/Documenter.jl/issues/2461 +[#2470]: https://github.com/JuliaDocs/Documenter.jl/issues/2470 +[#2475]: https://github.com/JuliaDocs/Documenter.jl/issues/2475 +[#2480]: https://github.com/JuliaDocs/Documenter.jl/issues/2480 +[#2482]: https://github.com/JuliaDocs/Documenter.jl/issues/2482 +[#2496]: https://github.com/JuliaDocs/Documenter.jl/issues/2496 +[#2497]: https://github.com/JuliaDocs/Documenter.jl/issues/2497 +[#2499]: https://github.com/JuliaDocs/Documenter.jl/issues/2499 +[#2513]: https://github.com/JuliaDocs/Documenter.jl/issues/2513 +[#2514]: https://github.com/JuliaDocs/Documenter.jl/issues/2514 +[#2526]: https://github.com/JuliaDocs/Documenter.jl/issues/2526 +[#2549]: https://github.com/JuliaDocs/Documenter.jl/issues/2549 +[#2551]: https://github.com/JuliaDocs/Documenter.jl/issues/2551 +[#2557]: https://github.com/JuliaDocs/Documenter.jl/issues/2557 +[#2560]: https://github.com/JuliaDocs/Documenter.jl/issues/2560 +[#2561]: https://github.com/JuliaDocs/Documenter.jl/issues/2561 +[#2562]: https://github.com/JuliaDocs/Documenter.jl/issues/2562 +[#2569]: https://github.com/JuliaDocs/Documenter.jl/issues/2569 +[#2571]: https://github.com/JuliaDocs/Documenter.jl/issues/2571 +[#2592]: https://github.com/JuliaDocs/Documenter.jl/issues/2592 +[#2593]: https://github.com/JuliaDocs/Documenter.jl/issues/2593 +[JuliaLang/julia#36953]: https://github.com/JuliaLang/julia/issues/36953 +[JuliaLang/julia#38054]: https://github.com/JuliaLang/julia/issues/38054 +[JuliaLang/julia#39841]: https://github.com/JuliaLang/julia/issues/39841 +[JuliaLang/julia#43652]: https://github.com/JuliaLang/julia/issues/43652 +[JuliaLang/julia#45174]: https://github.com/JuliaLang/julia/issues/45174 diff --git a/test/test_changelogs/empty.md b/test/test_changelogs/empty.md new file mode 100644 index 0000000..e69de29 diff --git a/test/test_changelogs/general_section.md b/test/test_changelogs/general_section.md new file mode 100644 index 0000000..522cb1e --- /dev/null +++ b/test/test_changelogs/general_section.md @@ -0,0 +1,14 @@ +# Changelog with General section + +Intro + +## [Unreleased] + +Here are some general notes +that are not in a section. + +### General +- Here is a general note in a bullet point in the section General + +And one more, not in a bullet +point. diff --git a/test/test_changelogs/good/ex1.md b/test/test_changelogs/good/ex1.md new file mode 100644 index 0000000..763355d --- /dev/null +++ b/test/test_changelogs/good/ex1.md @@ -0,0 +1,14 @@ +# Changelog + +Intro + +## [Unreleased] + +### Added +- Feature X +- New widget for dashboards + +## [1.0.0] - 2024-12-25 + +### Added +- Initial release with basic functionality diff --git a/test/test_changelogs/good/ex2.md b/test/test_changelogs/good/ex2.md new file mode 100644 index 0000000..6632109 --- /dev/null +++ b/test/test_changelogs/good/ex2.md @@ -0,0 +1,14 @@ +# Changelog + +Intro + +## Unreleased + +### Added +- New feature Y +- Improved API documentation + +## [1.0.0](https://example.com/releases/1.0.0) - 2024-12-25 + +### Added +- First public release of the project diff --git a/test/test_changelogs/good/ex3.md b/test/test_changelogs/good/ex3.md new file mode 100644 index 0000000..c67a1d5 --- /dev/null +++ b/test/test_changelogs/good/ex3.md @@ -0,0 +1,14 @@ +# Changelog + +**Intro** + +## **Unreleased** + +### **Added** +- API integration for new service + +## **1.0.0** - **2024-12-25** +- new feature + +### **Added** +- Basic setup and installation instructions diff --git a/test/test_changelogs/good/ex4.md b/test/test_changelogs/good/ex4.md new file mode 100644 index 0000000..25093e2 --- /dev/null +++ b/test/test_changelogs/good/ex4.md @@ -0,0 +1,12 @@ +# Changelog + +*Intro* + +## [Unreleased] + +- Added a new login page +- Enhanced user profile page + +## [1.0.0] (`2024-12-25`) + +- Initial release with main features diff --git a/test/test_changelogs/good/ex5.md b/test/test_changelogs/good/ex5.md new file mode 100644 index 0000000..fa947fc --- /dev/null +++ b/test/test_changelogs/good/ex5.md @@ -0,0 +1,15 @@ +## Changelog + +Intro + +### Unreleased + +> **Added** +> - A set of new utilities +> - A better user interface + +### Version 1.0.0 - *2024-12-25* + +- **Added** + - New API endpoints for data retrieval + - Improved error handling diff --git a/test/test_changelogs/jump.md b/test/test_changelogs/jump.md new file mode 100644 index 0000000..9a60eaf --- /dev/null +++ b/test/test_changelogs/jump.md @@ -0,0 +1,2138 @@ +```@meta +CurrentModule = JuMP +``` + +# Release notes + +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), +and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). + +## Version 1.23.5 (November 19, 2024) + +### Fixed + + - Fixed a bug broadcasting over [`GenericNonlinearExpr`](@ref) (#3881) + - Fixed a bug in [`@constraint`](@ref) which illegally mutated user expressions + (#3883) (#3885) + +### Other + + - Updated `upload-artifact` GitHub action (#3877) + - Added a section on [Common subexpressions](@ref) (#3879) + - Fixed a printing change for DimensionalData.jl (#3880) + +## Version 1.23.4 (November 8, 2024) + +### Fixed + + - Fixed `UnsupportedNonlinearOperator` error for the single argument + `LinearAlgebra.norm` (#3864) + - Fixed printing `MOI.Interval` with `MIME"text/latex"` (#3866) + +### Other + + - Various minor improvements to the documentation (#3855) (#3860) + - Added [MathOptAI.jl](@ref) and [MathOptSymbolicAD.jl](@ref) to the list of extensions in the documentation (#3858) + - Clarified [`add_to_expression!`](@ref) can add two expressions (#3859) + - Added `SHOT` to the installation table (#3853) + - Improvements to test coverage (#3867) (#3868) (#3869) (#3870) (#3871) (#3872) + (#3873) (#3874) (#3875) + - JuMP now uses [`MOI.add_constrained_variable`](@ref) when adding a scalar + variable with bounds for improving model creation performance with some solvers (#3863) (#3865) + +## Version 1.23.3 (October 21, 2024) + +### Fixed + + - Fixed a printing bug with scientific numbers in `MIME"text/latex"` (#3838) + - Fixed support for `AbstractString` in [`set_attribute`](@ref) (#3840) + - Fixed a bug reporting vector-valued duals in [`solution_summary`](@ref) + (#3846) + - Fixed [`solution_summary`](@ref) when there are duplicate variable and + constraint names (#3848) + +### Other + + - Documentation improvements (#3828) (#3831) (#3841) (#3843) (#3845) + - Added the tutorial [Tolerances and numerical issues](@ref) (#3829) (#3830) + (#3835) + - Improved the [Benders decomposition](@ref benders_decomposition_classical) + tutorial (#38232) (#3833) (#3834) + - Added `DifferentiationInterface.jl` to [Automatic differentiation of user-defined operators](@ref) + (#3836) (#3842) + - Added the tutorial [Writing a solver interface](@ref) (#3844) + - Added the section [Debugging performance problems](@ref) (#3850) + - Formatting improvements (#3849) + +## Version 1.23.2 (September 13, 2024) + +### Fixed + + - Fixed an illegal simplification in `MA.operate!!` for `NonlinearExpr` (#3826) + +### Other + + - Added [Rolling horizon problems](@ref) tutorial (#3815) + - Added more tests for shapes and dual shapes (#3816) + - Added more packages to `extension-tests.yml` (#3817) (#3818) + - Removed an unnecessary test(#3819) + - Documentation improvements (#3820) (#3822) (#3823) + - Added [PiecewiseLinearOpt.jl](@ref) to the docs (#3824) + +## Version 1.23.1 (August 30, 2024) + +### Fixed + + - Fixed a bug with indicator constraints and the `in set` syntax (#3813) + +### Other + + - Updated packages in documentation (#3807) + - Updated the transitioning from MATLAB tutorial (#3809) + - Add tutorial [Performance problems with sum-if formulations](@ref) (#3810) + +## Version 1.23.0 (August 13, 2024) + +### Added + + - Added set inequality syntax for matrices (#3766) + - Improved matrix inequality support (#3778) (#3805) + +### Fixed + + - Fixed a method for calling [`value`](@ref) on a `::Number` (#3776) + - Fixed querying dual of Symmetric and Hermitian equality constraints (#3797) + - Fixed [`read_from_file`](@ref) for coefficient types other than `Float64` + (#3801) + +### Other + + - Documentation improvements + - Fixed missing character in installation instructions (#3777) + - Added a section of querying the Jacobian (#3779) + - Clarify that SCIP does not support lazy constraints (#3784) + - Fixed typo in `knapsack.jl` (#3792) + - Added a warning to docs about tolerances in Bin and Int variables (#3794) + - Clarify where to type installation commands (#3795) + - Improve error message for common incorrect syntax in constraint macro (#3781) + - Changed `show(::IO, ::GenericModel)` to a more informative tree structure + (#3803) + +## Version 1.22.2 (June 17, 2024) + +### Fixed + + - Fixed printing to omit terms when printing a large array of expressions + (#3759) + - Fixed bug in printing when `show` is called on an invalid variable or + constraint (#3763) + +### Other + + - Improved error message for unsupported `kwargs` in variable macro (#3751) + - Improved error message for unsupported container syntax like `x[A][B]` + (#3756) + - Docstring improvements (#3758), (#3760), (#3761), (#3767) + - Added warning to documentation about `Y <= X, Set()` syntax (#3769) + - Work-around change on `nightly` (#3753), (#3754) + - Improved printing of symmetric matrices when used in constraints (#3768) + - Fixed a test for upcoming printing change in MOI (#3772) + - Updated `should_i_use.md` (#3773) + +## Version 1.22.1 (May 17, 2024) + +### Fixed + + - Fixed bug including non-`.jl` files in `src/macros.jl` (#3747) + +### Other + + - Added DSDP to the list of supported solvers (#3745) + - Updated YALMIP migration guide (#3748) + +## Version 1.22.0 (May 12, 2024) + +### Added + + - Added `Base.complex(r, i)` where `r` and `i` may be real-valued variables or + affine or quadratic expressions (#3734) + - Added [`@force_nonlinear`](@ref) for controlling when affine and quadratic + expressions are instead parsed as nonlinear expressions. This can be useful + for advanced users in a limited set of circumstances. (#3732) + - Added support for returning the variable coefficients of a vector-valued + constraint via [`normalized_coefficient`](@ref). In addition, + [`set_normalized_coefficients`](@ref) has been softly deprecated (no warning + is thrown and old code will still work for all future 1.X releases of JuMP) + in favor of [`set_normalized_coefficient`](@ref). This change was made to + unify how we get and set variable coefficients. (#3743) + +### Fixed + + - Fixed missing `promote_operation` method that resulted in slow code (#3730) + - Improved performance of `getindex` for `Containers.DenseAxisArray` (#3731) + - Fixed the error message when the legacy nonlinear API is mixed with the new + nonlinear API. In particular, we now uniformly throw an error message when + unexpected objects occur in nonlinear expressions. (#3741) + +### Other + + - Updated documentation (#3727), (#3728), (#3739) + - Updated versions in GitHub actions (#3735) + +## Version 1.21.1 (April 11, 2024) + +### Fixed + + - Fixed behavior of complex-value related functions like `real`, `imag`, `conj` + and `abs2` when called on [`GenericNonlinearExpr`](@ref). This fixes a method + error when calling `x'` where `x` is an array of nonlinear expressions. As a + related consequence, we now always error when creating nonlinear expressions + with complex components. Previously, only some constructors were checked for + complex expressionns. (#3724) + +### Other + + - Documentation improvements (#3719) (#3720) (#3721) (#3722) + +## Version 1.21.0 (March 31, 2024) + +### Added + + - Added support for matrix inequality constraints with the [`HermitianPSDCone`](@ref) + (#3705) + - Added batched modification methods for [`set_normalized_rhs`](@ref), + [`set_objective_coefficient`](@ref) and [`set_normalized_coefficient`](@ref). + Using these methods can be more efficient for some solvers (#3716) + - Added the private constant `_CONSTRAINT_LIMIT_FOR_PRINTING`, which controls + how many constraints are printed to the screen during `print(model)`. The + main purpose of this is to prevent large quantities of text being printed + when `print(model)` is accidentally called on a large model. (#3686) + +### Fixed + + - Changed [`Containers.SparseAxisArray`](@ref) to use an `OrderedDict` as the + backing data structure. Iterating over the elements in a `SparseAxisArray` + now iterates in the order that the elements were created. Previously, the + order was undefined behavior. (#3681) + - Fixed complex variables for non-Float64 coefficient types (#3691) + - Fixed `LinearAlgebra.hermitan(::AbstractJuMPScalar)` (#3693) + - Fixed multiplying real scalar by Hermitian matrix (#3695) + +### Other + + - Documentation improvements (#3679) (#3683) (#3702) (#3703) (#3706) (#3696) + (#3708) (#3709) (#3711) + - Added new tutorials: + - [Basis matrices](@ref) (#3675) + - [Transitioning from MATLAB](@ref) (#3698) + - [Automatic differentiation of user-defined operators](@ref) (#3713) + - Updated versions and compat bounds (#3687) (#3707) (#3717) + +## Version 1.20.0 (February 15, 2024) + +### Added + + - Added [`is_solved_and_feasible`](@ref) (#3668) + - Added support for `MOI.ModelLike` as the optimizer (#3667) + +### Fixed + + - Fixed compat of DimensionalData (#3666) + - Fixed `convert(::Type{NonlinearExpr}, ::Number)`(#3672) + +### Other + + - Added `Optim` to list of solvers (#3624) + - Improved linking within documentation (#3669) + +## Version 1.19.0 (February 1, 2024) + +### Added + + - Added support for modifying quadratic coefficients (#3658) + +### Fixed + + - Fixed short circuiting of `&&` and `||` in macros (#3655) + +### Other + + - Added SDPLR to list of solvers (#3644) + - Added new roadmap items (#3645) + - Fixed vale.sh version (#3650) + - Improve error messages in macros (#3653) + - Refactoring of `set_normalized_coefficient` (#3660) (#3661) + - Update `docs/packages.toml` (#3662) + +## Version 1.18.1 (January 6, 2024) + +### Fixed + + - Fixed escaping of the `set` keyword in [`@variable`](@ref) (#3647) + +## Version 1.18.0 (January 2, 2024) + +### Added + + - This release includes a large refactoring of the macro code that closes a + roadmap item (#3629) + Contributing pull requests include (#3600), (#3603), (#3606), (#3607), + (#3610), (#3611), (#3612), (#3613), (#3614), (#3615), (#3617), (#3618), + (#3619), (#3620), (#3621), (#3631), (#3632), (#3633) + +### Fixed + + - Fixed error for unsupported objective sense (#3601) + - Fixed `text/latex` printing of [`GenericNonlinearExpr`](@ref) (#3609) + - Fixed compat bounds of `stdlib` packages (#3626) + - Fixed a bug that can accidentally modify the user's expressions in a macro (#3639) + - Fixed a bug converting `AffExpr` to [`GenericNonlinearExpr`](@ref) (#3642) + +### Other + + - Added `DisjunctiveProgramming`to `extension-tests` (#3597) + - Added `DisjunctiveProgramming`to docs (#3598) + - Added DocumenterCitations to the docs (#3596), (#3630) + - Migrate from SnoopPrecompile to PrecompileTools (#3608) + - Minor documentation updates (#3623), (#3628), (#3635), (#3640), (#3643) + +## Version 1.17.0 (December 4, 2023) + +### Added + + - Added [`start_value`](@ref), [`lower_bound`](@ref), and [`upper_bound`](@ref) + support for [`GenericAffExpr`](@ref) that are equivalent to a single + [`GenericVariableRef`](@ref) (#3551) + - Added [`SkipModelConvertScalarSetWrapper`](@ref) which is useful for + extensions looking to avoid [`model_convert`](@ref) (#3552) (#3592) + - Added [`lp_matrix_data`](@ref) (#3573) (#3591) + +### Fixed + + - Fixed [`variable_ref_type`](@ref) for unsupported types (#3556) + - Fixed convert type of constraint starting values (#3571) + - Fixed various methods to support `AbstractJuMPScalar` with `Distances.jl` + (#3583) + - Fixed `eachindex` for multiple arguments of [`Containers.DenseAxisArray`](@ref) + and [`Containers.SparseAxisArray`](@ref) (#3587) + - Expressions with more than 60 terms now print in truncated form. This + prevents large expressions from being accidentally printed to terminal or + IJulia output (#3575) + - Fixed a type instability in [`set_objective_coefficient`](@ref) (#3590) + - Various fixes to the documentation (#3593) (#3595) + +### Other + + - Improved error messages for: + - Addition and subtraction between a matrix and a scalar (#3557) (#3558) + - Variables with non-constant bounds (#3583) + - Invalid indicator constraints (#3584) + - Added new solvers to the documentation: + - `EAGO.jl` (#3560) (#3561) + - `Manopt.jl` (#3568) + - `Percival.jl` (#3567) + - Added new tutorials: + - [Approximating nonlinear functions](@ref) (#3563) + - [Example: classification problems](@ref) (#3569) + - Improved documentation for: + - [`Semicontinuous`](@ref) and [`Semiinteger`](@ref) variables (#3562) + - [`SOS1`](@ref) and [`SOS2`](@ref) (#3565) + - [`start_value`](@ref) of [`HermitianPSDCone`](@ref) (#3564) + - Function tracing (#3570) + - Nonlinear operators with vector arguments (#3577) + - Indicator constraints (#3582) + - Updated package compat bounds (#3578) + +## Version 1.16.0 (October 24, 2023) + +### Added + + - Added `:=` operator for Boolean satisfiability problems (#3530) + +### Fixed + + - Fixed `text/latex` printing of [`MOI.Interval`](@ref) sets (#3537) + - Fixed tests with duplicate function names (#3539) + +### Other + + - Updated documentation list of supported solvers (#3527) (#3529) (#3538) + (#3542) (#3545) (#3546) + - Updated to Documenter@1.1 (#3528) + - Fixed various tutorials (#3534) (#3532) + - Fixed `Project.toml` compat bounds for standard libraries (#3544) + +## Version 1.15.1 (September 24, 2023) + +### Fixed + + - Fixed support for single argument `min` and `max` operators (#3522) + - Fixed error message for [`add_to_expression!`](@ref) when called with a + [`GenericNonlinearExpr`](@ref) (#3506) + - Fixed constraint tags with broadcasted constraints (#3515) + - Fixed MethodError in `MA.scaling` (#3518) + - Fixed support for arrays of [`Parameter`](@ref) variables (#3524) + +### Other + + - Updated to Documenter@1 (#3501) + - Fixed links to data in tutorials (#3512) + - Fixed typo in TSP tutorial (#3516) + - Improved error message for [`VariableNotOwned`](@ref) errors (#3520) + - Fixed various JET errors (#3519) + +## Version 1.15.0 (September 15, 2023) + +This is a large minor release because it adds an entirely new data structure and +API path for working with nonlinear programs. The previous nonlinear interface +remains unchanged and is documented at [Nonlinear Modeling (Legacy)](@ref). The +new interface is a treated as a non-breaking feature addition and is documented +at [Nonlinear Modeling](@ref). + +### Breaking + +Although the new nonlinear interface is a feature addition, there are two +changes which might be breaking for a very small number of users. + + - The syntax inside JuMP macros is parsed using a different code path, even for + linear and quadratic expressions. We made this change to unify how we parse + linear, quadratic, and nonlinear expressions. In all cases, the new code + returns equivalent expressions, but because of the different order of + operations, there are three changes to be aware of when updating: + - The printed form of the expression may change, for example from `x * y` to + `y * x`. This can cause tests which test the `String` representation of a + model to fail. + - Some coefficients may change slightly due to floating point round-off + error. + - Particularly when working with a JuMP extension, you may encounter a + `MethodError` due to a missing or ambiguous method. These errors are due + to previously existing bugs that were not triggered by the previous + parsing code. If you encounter such an error, please open a GitHub issue. + - The methods for `Base.:^(x::VariableRef, n::Integer)` and + `Base.:^(x::AffExpr, n::Integer)` have changed. Previously, these methods + supported only `n = 0, 1, 2` and they always returned a [`QuadExpr`](@ref), + even for the case when `n = 0` or `n = 1`. Now: + - `x^0` returns `one(T)`, where `T` is the [`value_type`](@ref) of the + model (defaults to `Float64`) + - `x^1` returns `x` + - `x^2` returns a [`QuadExpr`](@ref) + - `x^n` where `!(0 <= n <= 2)` returns a [`NonlinearExpr`](@ref). + We made this change to support nonlinear expressions and to align the + mathematical definition of the operation with their return type. (Previously, + users were surprised that `x^1` returned a [`QuadExpr`](@ref).) As a + consequence of this change, the methods are now not type-stable. This means + that the compiler cannot prove that `x^2` returns a [`QuadExpr`](@ref). If + benchmarking shows that this is a performance problem, you can use the + type-stable `x * x` instead of `x^2`. + +### Added + + - Added [`triangle_vec`](@ref) which simplifies adding [`MOI.LogDetConeTriangle`](@ref) + and [`MOI.RootDetConeTriangle`](@ref) constraints (#3456) + - Added the new nonlinear interface. This is a very large change. See the + documentation at [Nonlinear Modeling](@ref) and the (long) discussion in + [JuMP.jl#3106](https://github.com/jump-dev/JuMP.jl/pull/3106). Related PRs + are (#3468) (#3472) (#3475) (#3483) (#3487) (#3488) (#3489) (#3504) (#3509) + +### Fixed + + - Fixed uses of `@nospecialize` which cause precompilation failures in Julia + v1.6.0 and v1.6.1. (#3464) + - Fixed adding a container of [`Parameter`](@ref) (#3473) + - Fixed return type of `x^0` and `x^1` to no longer return `QuadExpr` (see note + in `Breaking` section above) (#3474) + - Fixed error messages in [`LowerBoundRef`](@ref), [`UpperBoundRef`](@ref), + [`FixRef`](@ref), [`IntegerRef`](@ref), [`BinaryRef`](@ref), + [`ParameterRef`](@ref) and related functions (#3494) + - Fixed type inference of empty containers in JuMP macros (#3500) + +### Other + + - Added GAMS to solver documentation (#3357) + - Updated various tutorials (#3459) (#3460) (#3462) (#3463) (#3465) (#3490) (#3492) + (#3503) + - Added [The network multi-commodity flow problem](@ref) tutorial (#3491) + - Added [Two-stage stochastic programs](@ref) tutorial (#3466) + - Added better error messages for unsupported operations in `LinearAlgebra` (#3476) + - Updated to the latest version of Documenter (#3484) (#3495) (#3497) + - Updated GitHub action versions (#3507) + +## Version 1.14.1 (September 2, 2023) + +### Fixed + + - Fix links in Documentation (#3478) + +## Version 1.14.0 (August 27, 2023) + +### Added + + - Added [DimensionalData.jl](@ref) extension (#3413) + - Added syntactic sugar for the [`MOI.Parameter`](@ref) set (#3443) + * [`Parameter`](@ref) + * [`ParameterRef`](@ref) + * [`is_parameter`](@ref) + * [`parameter_value`](@ref) + * [`set_parameter_value`](@ref) + +### Fixed + + - Fixed `model_convert` for `BridgeableConstraint` (#3437) + - Fixed printing models with integer coefficients larger than `typemax(Int)` + (#3447) + - Fixed support for constant left-hand side functions in a complementarity + constraint (#3452) + +### Other + + - Updated packages used in documentation (#3444) (#3455) + - Fixed docstring tests (#3445) + - Fixed printing change for MathOptInterface (#3446) + - Fixed typos in documentation (#3448) (#3457) + - Added SCIP to callback documentation (#3449) + +## Version 1.13.0 (July 27, 2023) + +### Added + + - Added support for generic number types (#3377) (#3385) + - Added fallback for [`MOI.AbstractSymmetricMatrixSetTriangle`](@ref) and + [`MOI.AbstractSymmetricMatrixSetSquare`](@ref) (#3424) + +### Fixed + + - Fixed [`set_start_values`](@ref) with + [`MOI.Bridges.Objective.SlackBridge`](@ref) (#3422) + - Fixed flakey doctest in `variables.md` (#3425) + - Fixed names on `CITATION.bib` (#3423) + +### Other + + - Added Loraine.jl to the installation table (#3426) + - Removed Penopt.jl from packages.toml (#3428) + - Improved problem statement in cannery example of tutorial (#3430) + - Minor cleanups in [`Containers.DenseAxisArray`](@ref) implementation (#3429) + - Changed `nested_problems.jl`: outer/inner to upper/lower (#3433) + - Removed second SDP relaxation in OPF tutorial + (#3432) + +## Version 1.12.0 (June 19, 2023) + +### Added + + - Added `coefficient_type` keyword argument to [`add_bridge`](@ref) and + [`remove_bridge`](@ref) (#3394) + +### Fixed + + - Fixed error message for matrix in [`HermitianPSDCone`](@ref) (#3369) + - Fixed `EditURL` for custom documentation pages (#3373) + - Fixed return type annotations for [`MOI.ConstraintPrimal`](@ref) and + [`MOI.ConstraintDual`](@ref) (#3381) + - Fixed printing change in Julia nightly (#3391) + - Fixed printing of `Complex` coefficients (#3397) + - Fixed printing of constraints in `text/latex` mode (#3405) + - Fixed performance issue in [`Containers.rowtable`](@ref) (#3410) + - Fixed bug when variables added to set of wrong dimension (#3411) + +### Other + + - Added more solver READMEs to the documentation (#3358) (#3360) (#3364) + (#3365) (#3366) (#3368) (#3372) (#3374) (#3376) (#3379) (#3387) (#3389) + - Added StatusSwitchingQP.jl to the installation table (#3354) + - Updated checklist for adding a new solver (#3370) + - Updated `extension-tests.yml` action (#3371) (#3375) + - Color logs in GitHub actions (#3392) + - Added new tutorials + - [Optimal power flow](@ref) (#3395) (#3412) + - [Lovász numbers](@ref) (#3399) + - [Dualization](@ref) (#3402) + - Updated JuMP paper citation (#3400) + - Changed GitHub action to upload LaTeX logs when building documentation + (#3403) + - Fixed printing of SCS log in documentation (#3406) + - Updated solver versions (#3407) + - Updated documentation to use Julia v1.9 (#3398) + - Replaced `_value_type` with `MOI.Utilities.value_type` (#3414) + - Fixed a typo in docstring (#3415) + - Refactored API documentation (#3386) + - Updated SCIP license (#3420) + +## Version 1.11.1 (May 19, 2023) + +### Fixed + + - Fixed a poor error message when `sum(::DenseAxisArray; dims)` was called + (#3338) + - Fixed support for dependent sets in the [`@variable`](@ref) macro (#3344) + - Fixed a performance bug in constraints with sparse symmetric matrices (#3349) + +### Other + + - Improved the printing of complex numbers (#3332) + - When printing, sets which contain constants ending in `.0` now print as + integers. This follows the behavior of constants in functions (#3341) + - Added `InfiniteOpt` to the extensions documentation (#3343) + - Added more documentation for the exponential cone (#3345) (#3347) + - Added checklists for developers (#3346) (#3355) + - Fixed test support upcoming Julia nightly (#3351) + - Fixed `extension-tests.yml` action (#3353) + - Add more solvers to the documentation (#3359) (#3361) (#3362) + +## Version 1.11.0 (May 3, 2023) + +### Added + + - Added new methods to [`print_active_bridges`](@ref) for printing a particular + objective, constraint, or variable (#3316) + +### Fixed + + - Fixed tests for MOI v1.14.0 release (#3312) + - Fixed indexing containers when an axis is `Vector{Any}` that contains a + `Vector{Any}` element (#3280) + - Fixed `getindex(::AbstractJuMPScalar)` which is called for an expression like + `x[]` (#3314) + - Fixed bug in `set_string_names_on_creation` with a vector of variables + (#3322) + - Fixed bug in `memoize` function in nonlinear documentation (#3337) + +### Other + + - Fixed typos in the documentation (#3317) (#3318) (#3328) + - Added a test for the order of setting start values (#3315) + - Added READMEs of solvers and extensions to the docs (#3309) (#3320) (#3327) + (#3329) (#3333) + - Style improvements to `src/variables.jl` (#3324) + - Clarify that column generation does not find global optimum (#3325) + - Add a GitHub actions workflow for testing extensions prior to release (#3331) + - Document the release process for JuMP (#3334) + - Fix links to discourse and chatroom (#3335) + +## Version 1.10.0 (April 3, 2023) + +### Added + + - Added [`Nonnegatives`](@ref), [`Nonpositives`](@ref) and [`Zeros`](@ref), and + support vector-valued inequality syntax in the JuMP macros (#3273) + - Added special support for `LinearAlgebra.Symmetric` and `LinearAlgebra.Hermitian` + matrices in [`Zeros`](@ref) constraints (#3281) (#3296) + - Added [`HermitianMatrixSpace`](@ref) and the `Hermitian` tag for generating a + matrix of variables that is Hermitian (#3292) (#3293) + - Added [`Semicontinuous`](@ref) and [`Semiinteger`](@ref) (#3302) + - Added support for keyword indexing of containers (#3237) + +### Fixed + + - Fixed `[compat]` bound for MathOptInterface in `Project.toml` (#3272) + +### Other + + - Split out the [Nested optimization problems](@ref) tutorial (#3274) + - Updated doctests to ensure none have hidden state (#3275) (#3276) + - Clarified how lazy constraints may revisit points (#3278) + - Added [P-Norm](@ref) example (#3282) + - Clarified docs that macros create new bindings (#3284) + - Fixed threading example (#3283) + - Added plot to [The minimum distortion problem](@ref) (#3288) + - Added Google style rules for Vale and fixed warnings (#3285) + - Added citation for the JuMP 1.0 paper (#3294) + - Updated package versions in the documentation (#3298) + - Added comment for the order in which start values must be set (#3303) + - Improved error message for unrecognized constraint operators (#3311) + +## Version 1.9.0 (March 7, 2023) + +### Added + + - Added [`get_attribute`](@ref) and [`set_attribute`](@ref). These replace + [`get_optimizer_attribute`](@ref) and [`set_optimizer_attribute`](@ref), + although the `_optimizer_` functions remain for backward compatibility. (#3219) + - Added [`set_start_values`](@ref) for setting all supported start values in a + model (#3238) + - Add [`remove_bridge`](@ref) and [`print_active_bridges`](@ref) (#3259) + +### Fixed + + - The matrix returned by a variable in [`HermitianPSDCone`](@ref) is now a + `LinearAlgebra.Hermitian` matrix. This is potentially breaking if you have + written code to assume the return is a `Matrix`. (#3245) (#3246) + - Fixed missing support for `Base.isreal` of expressions (#3252) + +### Other + + - Fixed a thread safety issue in the [Parallelism](@ref) tutorial (#3240) + (#3243) + - Improved the error message when unsupported operators are used in `@NL` + macros (#3236) + - Clarified the documentation to say that matrices in [`HermitianPSDCone`](@ref) + must be `LinearAlgebra.Hermitian` (#3241) + - Minor style fixes to internal macro code (#3247) + - Add [Example: quantum state discrimination](@ref) tutorial (#3250) + - Improve error message when `begin...end` not passed to plural macros (#3255) + - Document how to register function with varying number of input arguments + (#3258) + - Tidy tests by removing unneeded `JuMP.` prefixes (#3260) + - Clarified the introduction to the [Complex number support](@ref) tutorial (#3262) + - Fixed typos in the Documentation (#3263) (#3266) (#3268) (#3269) + +## Version 1.8.2 (February 27, 2023) + +### Fixed + + - Fixed dot product between complex JuMP expression and number (#3244) + +### Other + + - Polish simple SDP examples (#3232) + +## Version 1.8.1 (February 23, 2023) + +### Fixed + + - Fixed support for `init` in nonlinear generator expressions (#3226) + +### Other + + - Use and document `import MathOptInterface as MOI` (#3222) + - Removed references in documentation to multiobjective optimization being + unsupported (#3223) + - Added tutorial on multi-objective portfolio optimization (#3227) + - Refactored some of the conic tutorials (#3229) + - Fixed typos in the documentation (#3230) + - Added tutorial on parallelism (#3231) + +## Version 1.8.0 (February 16, 2023) + +### Added + + - Added `-->` syntax support for indicator constraints. The old syntax of `=>` + remains supported (#3207) + - Added `<-->` syntax for reified constraints. For now, few solvers support + reified constraints (#3206) + - Added [`fix_discrete_variables`](@ref). This is most useful for computing the + dual of a mixed-integer program (#3208) + - Added support for vector-valued objectives. For details, see the + [Multi-objective knapsack](@ref) tutorial (#3176) + +### Fixed + + - Fixed a bug in [`lp_sensitivity_report`](@ref) by switching to an explicit + LU factorization of the basis matrix (#3182) + - Fixed a bug that prevented `[; kwarg]` arguments in macros (#3220) + +### Other + + - Minor fixes to the documentation (#3200) (#3201) (#3203) (#3210) + - Added tutorial [Constraint programming](@ref) (#3202) + - Added more examples to [Modeling with cones](@ref) + - Remove `_distance_to_set` in favor of `MOI.Utilities.distance_to_set` (#3209) + - Improve [The diet problem](@ref) tutorial by adding the variable as a column + in the dataframe (#3213) + - Improve [The knapsack problem example](@ref) tutorial (#3216) (#3217) + - Added the [Example: ellipsoid approximation](@ref) tutorial (#3218) + +## Version 1.7.0 (January 25, 2023) + +### Added + + - Added support for `view` of a [`Containers.DenseAxisArray`](@ref) (#3152) (#3180) + - Added support for containers of variables in [`ComplexPlane`](@ref) (#3184) + - Added support for `minimum` and `maximum` generators in nonlinear expressions + (#3189) + - Added `SnoopPrecompile` statements that reduce the time-to-first-solve in + Julia 1.9 (#3193) (#3195) (#3196) (#3197) + +### Other + + - Large refactoring of the tests (#3166) (#3167) (#3168) (#3169) (#3170) (#3171) + - Remove unreachable code due to `VERSION` checks (#3172) + - Document how to test JuMP extensions (#3174) + - Fix method ambiguities in `Containers` (#3173) + - Improve error message that is thrown when `=` is used instead of `==` in + the [`@constraint`](@ref) macro (#3178) + - Improve the error message when `Bool` is used instead of `Bin` in the + [`@variable`](@ref) macro (#3180) + - Update versions of the documentation (#3185) + - Tidy the import of packages and remove unnecessary prefixes (#3186) (#3187) + - Refactor `src/JuMP.jl` by moving methods into more relevant files (#3188) + - Fix docstring of [`Model`](@ref) not appearing in the documentation (#3198) + +## Version 1.6.0 (January 1, 2023) + +### Added + + - Added a `result` keyword argument to [`solution_summary`](@ref) to allow + summarizing models with multiple solutions (#3138) + - Added [`relax_with_penalty!`](@ref), which is a useful tool when debugging + infeasible models (#3140) + - Added [`has_start_value`](@ref) (#3157) + - Added support for [`HermitianPSDCone`](@ref) in constraints (#3154) + +### Fixed + + - Fixed promotion of complex expressions (#3150) (#3164) + +### Other + + - Added Benders tutorial with in-place resolves (#3145) + - Added more [Tips and tricks](@ref linear_tips_and_tricks) for linear programs + (#3144) (#3163) + - Clarified documentation that `start` can depend on the indices of a + variable container (#3148) + - Replace instances of `length` and `size` by the recommended `eachindex` and + `axes` (#3149) + - Added a warning explaining why the model is dirty when accessing solution + results from a modified model (#3156) + - Clarify documentation that `PSD` ensures a symmetric matrix (#3159) + - Maintenance of the JuMP test suite (#3146) (#3158) (#3162) + +## Version 1.5.0 (December 8, 2022) + +### Added + + - Add support for complex-valued variables: + * [`HermitianPSDCone`](@ref) (#3109) + * [`ComplexPlane`](@ref) and [`ComplexVariable`](@ref) (#3134) + - Add support for [`MOI.OptimizerWithAttributes`](@ref) in + [`set_optimizer_attribute`](@ref) and [`get_optimizer_attribute`](@ref) (#3129) + +### Fixed + + - Fixed error message for vectorized interval constraints (#3123) + - Fixed passing `AbstractString` to [`set_optimizer_attribute`](@ref) (#3127) + +### Other + + - Update package versions used in docs (#3119) (#3133) (#3139) + - Fixed output of diet tutorial (#3120) + - Explain how to use `Dates.period` in [`set_time_limit_sec`](@ref) (#3121) + - Update to `JuliaFormatter` v1.0.15 (#3130) + - Fixed `HTTP` server example in web_app.jl (#3131) + - Update docs to build with `Documenter#master` (#3094) + - Add tests for `LinearAlgebra` operations (#3132) + - Tidy these release notes (#3135) + - Added documentation for [Complex number support](@ref) (#3141) + - Removed the "workforce scheduling" and "steelT3" tutorials (#3143) + +## Version 1.4.0 (October 29, 2022) + +### Added + + - Added [`Containers.rowtable`](@ref) which converts a container into a vector + of `NamedTuple`s to support the Tables.jl interface. This simplifies + converting [`Containers.DenseAxisArray`](@ref) and [`Containers.SparseAxisArray`](@ref) + objects into tabular forms such as a DataFrame (#3104) + - Added a new method to [`Containers.container`](@ref) so that index names are + passed to the container (#3088) + +### Fixed + + - Fixed a bug in `copy_to(dest::Model, src::MOI.ModelLike)` when `src` has + nonlinear components (#3101) + - Fixed the printing of `(-1.0 + 0.0im)` coefficients in complex expressions + (#3112) + - Fixed a parsing bug in nonlinear expressions with generator statements that + contain multiple `for` statements (#3116) + +### Other + + - Converted the multi-commodity flow tutorial to use an SQLite database (#3098) + - Fixed a number of typos in the documentation (#3103) (#3107) (#3018) + - Improved various style aspects of the PDF documentation (#3095) (#3098) + (#3102) + +## Version 1.3.1 (September 28, 2022) + +### Fixed + + - Fixed a performance issue in `relax_integrality` (#3087) + - Fixed the type stability of operators with `Complex` arguments (#3072) + - Fixed a bug which added additional `+()` terms to some nonlinear expressions + (#3091) + - Fixed potential method ambiguities with `AffExpr` and `QuadExpr` objects + (#3092) + +### Other + + - Added [vale](https://vale.sh) as a linter for the documentation (#3080) + - Added a tutorial on debugging JuMP models (#3043) + - Fixed a number of typos in the documentation (#3079) (#3083) + - Many other small tweaks to the documentation (#3068) (#3073) (#3074) (#3075) + (#3076) (#3077) (#3078) (#3081) (#3082) (#3084) (#3085) (#3089) + +## Version 1.3.0 (September 5, 2022) + +### Added + + - Support slicing in `SparseAxisArray` (#3031) + +### Fixed + + - Fixed a bug introduced in v1.2.0 that prevented `DenseAxisArray`s with + `Vector` keys (#3064) + +### Other + + - Released the JuMP logos under the CC BY 4.0 license (#3063) + - Minor tweaks to the documentation (#3054) (#3056) (#3057) (#3060) (#3061) + (#3065) + - Improved code coverage of a number of files (#3048) (#3049) (#3050) (#3051) + (#3052) (#3053) (#3058) (#3059) + +## Version 1.2.1 (August 22, 2022) + +### Fixed + + - Fixed a bug when parsing two-sided nonlinear constraints (#3045) + +## Version 1.2.0 (August 16, 2022) + +### Breaking + +This is a large minor release because it significantly refactors the internal +code for handling nonlinear programs to use the `MathOptInterface.Nonlinear` +submodule that was introduced in MathOptInterface v1.3.0. As a consequence, the +internal datastructure in `model.nlp_data` has been removed, as has the +`JuMP._Derivatives` submodule. Despite the changes, the public API for nonlinear +programming has not changed, and any code that uses only the public API and that +worked with v1.1.1 will continue to work with v1.2.0. + +### Added + + - Added `all_constraints(model; include_variable_in_set_constraints)` which + simplifies returning a list of all constraint indices in the model. + - Added the ability to delete nonlinear constraints via + `delete(::Model, ::NonlinearConstraintRef)`. + - Added the ability to provide an explicit Hessian for a multivariate + user-defined function. + - Added support for querying the primal value of a nonlinear constraint via + `value(::NonlinearConstraintRef)` + +### Fixed + + - Fixed a bug in `Containers.DenseAxisArray` so that it now supports indexing + with keys that hash to the same value, even if they are different types, for + example, `Int32` and `Int64`. + - Fixed a bug printing the model when the solver does not support `MOI.Name`. + +### Other + + - Added a constraint programming formulation to the Sudoku tutorial. + - Added newly supported solvers Pajarito, Clarabel, and COPT to the + installation table. + - Fixed a variety of other miscellaneous issues in the documentation. + +## Version 1.1.1 (June 14, 2022) + +### Other + + - Fixed problem displaying LaTeX in the documentation + - Minor updates to the style guide + - Updated to MOI v1.4.0 in the documentation + +## Version 1.1.0 (May 25, 2022) + +### Added + + - Added `num_constraints(::Model; count_variable_in_set_constraints)` to + simplify the process of counting the number of constraints in a model + - Added `VariableRef(::ConstraintRef)` for querying the variable associated + with a bound or integrality constraint. + - Added `set_normalized_coefficients` for modifying the variable coefficients + of a vector-valued constraint. + - Added `set_string_names_on_creation` to disable creating `String` names for + variables and constraints. This can improve performance. + +### Fixed + + - Fixed a bug passing `nothing` to the `start` keyword of `@variable` + +### Other + + - New tutorials: + - Sensitivity analysis of a linear program + - Serving web apps + - Minimal ellipse SDP tutorial refactored and improved + - Docs updated to the latest version of each package + - Lots of minor fixes and improvements to the documentation + +## Version 1.0.0 (March 24, 2022) + +**Read more about this release, along with an acknowledgement of all the +contributors in our [JuMP 1.0.0 is released](https://jump.dev/blog/1.0.0-release/) +blog post.** + +### Breaking + + - The previously deprecated functions (v0.23.0, v0.23.1) have been removed. + Deprecation was to improve consistency of function names: + - `num_nl_constraints` (see `num_nonlinear_constraints`) + - `all_nl_constraints` (see `all_nonlinear_constraints`) + - `add_NL_expression` (see `add_nonlinear_expression`) + - `set_NL_objective` (see `set_nonlinear_objective`) + - `add_NL_constraint` (see `add_nonlinear_constraint`) + - `nl_expr_string` (see `nonlinear_expr_string`) + - `nl_constraint_string` (see `nonlinear_constraint_string`) + - `SymMatrixSpace` (see `SymmetricMatrixSpace`) + - The unintentionally exported variable `JuMP.op_hint` has been renamed to the + unexported `JuMP._OP_HINT` + +### Fixed + + - Fixed a bug writing .nl files + - Fixed a bug broadcasting `SparseAxisArray`s + +## Version 0.23.2 (March 14, 2022) + +### Added + + - Added `relative_gap` to `solution_summary` + - `register` now throws an informative error if the function is not + differentiable using ForwardDiff. In some cases, the check in `register` + will encounter a false negative, and the informative error will be thrown at + run-time. This usually happens when the function is non-differentiable in a + subset of the domain. + +### Fixed + + - Fixed a scoping issue when extending the `container` keyword of containers + +### Other + + - Docs updated to the latest version of each package + +## Version 0.23.1 (March 2, 2022) + +### Deprecated + + - `nl_expr_string` and `nl_constraint_string` have been renamed to + `nonlinear_expr_string` and `nonlinear_constraint_string`. The old methods + still exist with deprecation warnings. This change should impact very few + users because to call them you must rely on private internals of the + nonlinear API. Users are encouraged to use `sprint(show, x)` instead, where + `x` is the nonlinear expression or constraint of interest. + +### Added + + - Added support for `Base.abs2(x)` where `x` is a variable or affine + expression. This is mainly useful for complex-valued constraints. + +### Fixed + + - Fixed addition of complex and real affine expressions + - Fixed arithmetic for Complex-valued quadratic expressions + - Fixed variable bounds passed as `Rational{Int}(Inf)` + - Fixed printing of the coefficient `(0 + 1im)` + - Fixed a bug when `solution_summary` is called prior to `optimize!` + +## Version 0.23.0 (February 25, 2022) + +**JuMP v0.23.0 is a breaking release. It is also a release-candidate for JuMP +v1.0.0. That is, if no issues are found with the v0.23.0 release, then it will +be re-tagged as v1.0.0.** + +### Breaking + + - Julia 1.6 is now the minimum supported version + - MathOptInterface has been updated to v1.0.0 + - All previously deprecated functionality has been removed + - `PrintMode`, `REPLMode` and `IJuliaMode` have been removed in favor of the + MIME types `MIME"text/plain"` and `MIME"text/latex"`. Replace instances of + `::Type{REPLMode}` with `::MIME"text/plain"`, `REPLMode` with + `MIME("text/plain")`, `::Type{IJuliaMode}` with `::MIME"text/latex"`, and + `IJuliaMode` with `MIME("text/latex")`. + - Functions containing the `nl_` acronym have been renamed to the more + explicit `nonlinear_`. For example, `num_nl_constraints` is now + `num_nonlinear_constraints` and `set_NL_objective` is now + `set_nonlinear_objective`. Calls to the old functions throw an error + explaining the new name. + - `SymMatrixSpace` has been renamed to `SymmetricMatrixSpace` + +### Added + + - Added `nonlinear_dual_start_value` and `set_nonlinear_dual_start_value` + - Added preliminary support for `Complex` coefficient types + +### Fixed + + - Fixed a bug in `solution_summary` + +### Other + + - MILP examples have been migrated from GLPK to HiGHS + - Fixed various typos + - Improved section on setting constraint start values + +### Troubleshooting problems when updating + +If you experience problems when updating, you are likely using previously +deprecated functionality. (By default, Julia does not warn when you use +deprecated features.) + +To find the deprecated features you are using, start Julia with `--depwarn=yes`: +``` +$ julia --depwarn=yes +``` +Then install JuMP v0.22.3: +```julia +julia> using Pkg +julia> pkg"add JuMP@0.22.3" +``` +And then run your code. Apply any suggestions, or search the release notes below +for advice on updating a specific deprecated feature. + +## Version 0.22.3 (February 10, 2022) + +### Fixed + + - Fixed a reproducibility issue in the TSP tutorial + - Fixed a reproducibility issue in the `max_cut_sdp` tutorial + - Fixed a bug broadcasting an empty SparseAxisArray + +### Other + + - Added a warning and improved documentation for the modify-then-query case + - Fixed a typo in the docstring of `RotatedSecondOrderCone` + - Added Aqua.jl as a check for code health + - Added introductions to each section of the tutorials + - Improved the column generation and Benders decomposition tutorials + - Updated documentation to MOI v0.10.8 + - Updated JuliaFormatter to v0.22.2 + +## Version 0.22.2 (January 10, 2022) + +### Added + + - The function `all_nl_constraints` now returns all nonlinear constraints + in a model + - `start_value` and `set_start_value` can now be used to get and set the + primal start for constraint references + - Plural macros now return a tuple containing the elements that were defined + instead of `nothing` + - Anonymous variables are now printed as `_[i]` where `i` is the index of the + variable instead of `noname`. Calling `name(x)` still returns `""` so this + is non-breaking. + +### Fixed + + - Fixed handling of `min` and `max` in nonlinear expressions + - CartesianIndex is no longer allowed as a key for DenseAxisArrays. + +### Other + + - Improved the performance of GenericAffExpr + - Added a tutorial on the Travelling Salesperson Problem + - Added a tutorial on querying the Hessian of a nonlinear program + - Added documentation on using custom solver binaries. + +## Version 0.22.1 (November 29, 2021) + +### Added + + * Export `OptimizationSense` enum, with instances: `MIN_SENSE`, `MAX_SENSE`, + and `FEASIBILITY_SENSE` + * Add `Base.isempty(::Model)` to match `Base.empty(::Model)` + +### Fixed + + * Fix bug in container with tuples as indices + * Fix bug in `set_time_limit_sec` + +### Other + + * Add tutorial "Design patterns for larger models" + * Remove release notes section from PDF + * General edits of the documentation and error messages + +## Version 0.22.0 (November 10, 2021) + +**JuMP v0.22 is a breaking release** + +### Breaking + +JuMP 0.22 contains a number of breaking changes. However, these should be +invisible for the majority of users. You will mostly encounter these breaking +changes if you: wrote a JuMP extension, accessed `backend(model)`, or called +`@SDconstraint`. + +The breaking changes are as follows: + + * MathOptInterface has been updated to v0.10.4. For users who have interacted + with the MOI backend, this contains a large number of breaking changes. Read + the [MathOptInterface release notes](https://jump.dev/MathOptInterface.jl/v0.10/release_notes/#v0.10.0-(September-6,-2021)) + for more details. + * The `bridge_constraints` keyword argument to `Model` and `set_optimizer` has + been renamed `add_bridges` to reflect that more thing were bridged than just + constraints. + * The `backend(model)` field now contains a concrete instance of a + `MOI.Utilities.CachingOptimizer` instead of one with an abstractly typed + optimizer field. In most cases, this will lead to improved performance. + However, calling `set_optimizer` after `backend` invalidates the old + backend. For example: + ```julia + model = Model() + b = backend(model) + set_optimizer(model, GLPK.Optimizer) + @variable(model, x) + # b is not updated with `x`! Get a new b by calling `backend` again. + new_b = backend(model) + ``` + * All usages of `@SDconstraint` are deprecated. The new syntax is + `@constraint(model, X >= Y, PSDCone())`. + * Creating a `DenseAxisArray` with a `Number` as an axis will now display a + warning. This catches a common error in which users write + `@variable(model, x[length(S)])` instead of + `@variable(model, x[1:length(S)])`. + * The `caching_mode` argument to `Model`, for example, + `Model(caching_mode = MOIU.MANUAL)` mode has been removed. For more control + over the optimizer, use `direct_model` instead. + * The previously deprecated `lp_objective_perturbation_range` and + `lp_rhs_perturbation_range` functions have been removed. Use + `lp_sensitivity_report` instead. + * The `.m` fields of `NonlinearExpression` and `NonlinearParameter` have been + renamed to `.model`. + * Infinite variable bounds are now ignored. Thus, `@variable(model, x <= Inf)` + will show `has_upper_bound(x) == false`. Previously, these bounds were passed + through to the solvers which caused numerical issues for solvers expecting + finite bounds. + * The `variable_type` and `constraint_type` functions were removed. This should + only affect users who previously wrote JuMP extensions. The functions can be + deleted without consequence. + * The internal functions `moi_mode`, `moi_bridge_constraints`, + `moi_add_constraint`, and `moi_add_to_function_constant` are no longer + exported. + * The un-used method `Containers.generate_container` has been deleted. + * The `Containers` API has been refactored, and `_build_ref_sets` is now + public as `Containers.build_ref_sets`. + * The `parse_constraint_` methods for extending `@constraint` at parse time + have been refactored in a breaking way. Consult the Extensions documentation + for more details and examples. + +### Added + + * The `TerminationStatusCode` and `ResultStatusCode` enums are now exported + by JuMP. Prefer `termination_status(model) == OPTIMAL` instead of + `== MOI.OPTIMAL`, although the `MOI.` prefix way still works. + * Copy a `x::DenseAxisArray` to an `Array` by calling `Array(x)`. + * `NonlinearExpression` is now a subtype of `AbstractJuMPScalar` + * Constraints such as `@constraint(model, x + 1 in MOI.Integer())` are now + supported. + * `primal_feasibility_report` now accepts a function as the first argument. + * Scalar variables `@variable(model, x[1:2] in MOI.Integer())` creates two + variables, both of which are constrained to be in the set `MOI.Integer`. + * Conic constraints can now be specified as inequalities under a different + partial ordering. So `@constraint(model, x - y in MOI.Nonnegatives())` can + now be written as `@constraint(model, x >= y, MOI.Nonnegatives())`. + * Names are now set for vectorized constraints. + +### Fixed + + * Fixed a performance issue when `show` was called on a `SparseAxisArray` with + a large number of elements. + * Fixed a bug displaying barrier and simplex iterations in `solution_summary`. + * Fixed a bug by implementing `hash` for `DenseAxisArray` and + `SparseAxisArray`. + * Names are now only set if the solver supports them. Previously, this + prevented solvers such as Ipopt from being used with `direct_model`. + * `MutableArithmetics.Zero` is converted into a `0.0` before being returned to + the user. Previously, some calls to `@expression` would return the + undocumented `MutableArithmetics.Zero()` object. One example is summing over + an empty set `@expression(model, sum(x[i] for i in 1:0))`. You will now get + `0.0` instead. + * `AffExpr` and `QuadExpr` can now be used with `== 0` instead of `iszero`. + This fixes a number of issues relating to Julia standard libraries such as + `LinearAlgebra` and `SparseArrays`. + * Fixed a bug when registering a user-defined function with splatting. + +### Other + + * The documentation is now available as a PDF. + * The documentation now includes a full copy of the MathOptInterface + documentation to make it easy to link concepts between the docs. (The + MathOptInterface documentation has also been significantly improved.) + * The documentation contains a large number of improvements and clarifications + on a range of topics. Thanks to @sshin23, @DilumAluthge, and @jlwether. + * The documentation is now built with Julia 1.6 instead of 1.0. + * Various error messages have been improved to be more readable. + +## Version 0.21.10 (September 4, 2021) + +### Added + + * Added `add_NL_expression` + * `add_NL_xxx` functions now support `AffExpr` and `QuadExpr` as terms + +### Fixed + + * Fixed a bug in `solution_summary` + * Fixed a bug in `relax_integrality` + +### Other + + * Improved error message in `lp_sensitivity_report` + +## Version 0.21.9 (August 1, 2021) + +### Added + + * Containers now support arbitrary container types by passing the type to the + `container` keyword and overloading `Containers.container`. + * `is_valid` now supports nonlinear constraints + * Added `unsafe_backend` for querying the inner-most optimizer of a JuMP + model. + * Nonlinear parameters now support the plural `@NLparameters` macro. + * Containers (for example, `DenseAxisArray`) can now be used in vector-valued + constraints. + +### Other + + * Various improvements to the documentation. + +## Version 0.21.8 (May 8, 2021) + +### Added + + * The `@constraint` macro is now extendable in the same way as `@variable`. + * `AffExpr` and `QuadExpr` can now be used in nonlinear macros. + +### Fixed + + * Fixed a bug in `lp_sensitivity_report`. + * Fixed an inference issue when creating empty `SparseAxisArray`s. + +## Version 0.21.7 (April 12, 2021) + +### Added + + * Added `primal_feasibility_report`, which can be used to check whether a + primal point satisfies primal feasibility. + * Added `coefficient`, which returns the coefficient associated with a + variable in affine and quadratic expressions. + * Added `copy_conflict`, which returns the IIS of an infeasible model. + * Added `solution_summary`, which returns (and prints) a struct containing a + summary of the solution. + * Allow `AbstractVector` in vector constraints instead of just `Vector`. + * Added `latex_formulation(model)` which returns an object representing the + latex formulation of a model. Use `print(latex_formulation(model))` to print + the formulation as a string. + * User-defined functions in nonlinear expressions are now automatically + registered to aid quick model prototyping. However, a warning is printed to + encourage the manual registration. + * DenseAxisArray's now support broadcasting over multiple arrays. + * Container indices can now be iterators of `Base.SizeUnknown`. + +### Fixed + + * Fixed bug in `rad2deg` and `deg2rad` in nonlinear expressions. + * Fixed a MethodError bug in `Containers` when forcing container type. + * Allow partial slicing of a DenseAxisArray, resolving an issue from 2014. + * Fixed a bug printing variable names in IJulia. + * Ending an IJulia cell with `model` now prints a summary of the model (like + in the REPL) not the latex formulation. Use `print(model)` to print the latex + formulation. + * Fixed a bug when copying models containing nested arrays. + +### Other + + * Tutorials are now part of the documentation, and more refactoring has taken + place. + * Added JuliaFormatter added as a code formatter. + * Added some precompilation statements to reduce initial latency. + * Various improvements to error messages to make them more helpful. + * Improved performance of `value(::NonlinearExpression)`. + * Improved performance of `fix(::VariableRef)`. + +## Version 0.21.6 (January 29, 2021) + +### Added + + * Added support for skew symmetric variables via + `@variable(model, X[1:2, 1:2] in SkewSymmetricMatrixSpace())`. + * `lp_sensitivity_report` has been added which significantly improves the + performance of querying the sensitivity summary of an LP. + `lp_objective_perturbation_range` and `lp_rhs_perturbation_range` are + deprecated. + * Dual warm-starts are now supported with `set_dual_start_value` and + `dual_start_value`. + * `∈` (`\in`) can now be used in macros instead of `=` or `in`. + * Use `haskey(model::Model, key::Symbol)` to check if a name `key` is + registered in a model. + * Added `unregister(model::Model, key::Symbol)` to unregister a name `key` + from `model`. + * Added `callback_node_status` for use in callbacks. + * Added `print_bridge_graph` to visualize the bridging graph generated by + MathOptInterface. + * Improved error message for containers with duplicate indices. + +### Fixed + + * Various fixes to pass tests on Julia 1.6. + * Fixed a bug in the printing of nonlinear expressions in IJulia. + * Fixed a bug when nonlinear expressions are passed to user-defined functions. + * Some internal functions that were previously exported are now no longer + exported. + * Fixed a bug when relaxing a fixed binary variable. + * Fixed a `StackOverflowError` that occurred when `SparseAxisArray`s had a + large number of elements. + * Removed an unnecessary type assertion in `list_of_constraint_types`. + * Fixed a bug when copying models with registered expressions. + +### Other + + * The documentation has been significantly overhauled. It now has distinct + sections for the manual, API reference, and examples. The existing examples + in `/examples` have now been moved to `/docs/src/examples` and rewritten + using `Literate.jl`, and they are now included in the documentation. + * JuliaFormatter has been applied to most of the codebase. This will continue + to roll out over time, as we fix upstream issues in the formatter, and will + eventually become compulsory. + * The root cause of a large number of method invalidations has been resolved. + * We switched continuous integration from Travis and Appveyor to GitHub + Actions. + +## Version 0.21.5 (September 18, 2020) + +### Fixed + + * Fixed deprecation warnings + * Throw `DimensionMismatch` for incompatibly sized functions and sets + * Unify treatment of `keys(x)` on JuMP containers + +## Version 0.21.4 (September 14, 2020) + +### Added + + * Add debug info when adding unsupported constraints + * Add `relax_integrality` for solving continuous relaxation + * Allow querying constraint conflicts + +### Fixed + + * Dispatch on `Real` for `MOI.submit` + * Implement `copy` for `CustomSet` in tests + * Don't export private macros + * Fix invalid assertion in nonlinear + * Error if constraint has `NaN` right-hand side + * Improve speed of tests + * Lots of work modularizing files in `/test` + * Improve line numbers in macro error messages + * Print nonlinear subexpressions + * Various documentation updates + * Dependency updates: + * Datastructures 0.18 + * MathOptFormat v0.5 + * Prep for MathOptInterface 0.9.15 + +## Version 0.21.3 (June 18, 2020) + +- Added Special Order Sets (SOS1 and SOS2) to JuMP with default weights to ease + the creation of such constraints (#2212). +- Added functions `simplex_iterations`, `barrier_iterations` and `node_count` + (#2201). +- Added function `reduced_cost` (#2205). +- Implemented `callback_value` for affine and quadratic expressions (#2231). +- Support `MutableArithmetics.Zero` in objective and constraints (#2219). +- Documentation improvements: + * Mention tutorials in the docs (#2223). + * Update COIN-OR links (#2242). + * Explicit link to the documentation of `MOI.FileFormats` (#2253). + * Typo fixes (#2261). +- Containers improvements: + * Fix `Base.map` for `DenseAxisArray` (#2235). + * Throw `BoundsError` if number of indices is incorrect for `DenseAxisArray` + and `SparseAxisArray` (#2240). +- Extensibility improvements: + * Implement a `set_objective` method fallback that redirects to + `set_objective_sense` and `set_objective_function` (#2247). + * Add `parse_constraint` method with arbitrary number of arguments (#2051). + * Add `parse_constraint_expr` and `parse_constraint_head` (#2228). + +## Version 0.21.2 (April 2, 2020) + +- Added `relative_gap()` to access `MOI.RelativeGap()` attribute (#2199). +- Documentation fixes: + * Added link to source for docstrings in the documentation (#2207). + * Added docstring for `@variables` macro (#2216). + * Typo fixes (#2177, #2184, #2182). +- Implementation of methods for Base functions: + * Implemented `Base.empty!` for `JuMP.Model` (#2198). + * Implemented `Base.conj` for JuMP scalar types (#2209). + +### Fixed + + * Fixed sum of expression with scalar product in macro (#2178). + * Fixed writing of nonlinear models to MathOptFormat (#2181). + * Fixed construction of empty SparseAxisArray (#2179). + * Fixed constraint with zero function (#2188). + +## Version 0.21.1 (Feb 18, 2020) + +- Improved the clarity of the `with_optimizer` deprecation warning. + +## Version 0.21.0 (Feb 16, 2020) + +### Breaking + +- Deprecated `with_optimizer` (#2090, #2084, #2141). You can replace + `with_optimizer` by either nothing, `optimizer_with_attributes` or a closure: + * replace `with_optimizer(Ipopt.Optimizer)` by `Ipopt.Optimizer`. + * replace `with_optimizer(Ipopt.Optimizer, max_cpu_time=60.0)` + by `optimizer_with_attributes(Ipopt.Optimizer, "max_cpu_time" => 60.0)`. + * replace `with_optimizer(Gurobi.Optimizer, env)` by `() -> Gurobi.Optimizer(env)`. + * replace `with_optimizer(Gurobi.Optimizer, env, Presolve=0)` + by `optimizer_with_attributes(() -> Gurobi.Optimizer(env), "Presolve" => 0)`. + + alternatively to `optimizer_with_attributes`, you can also set the attributes + separately with `set_optimizer_attribute`. +- Renamed `set_parameter` and `set_parameters` to `set_optimizer_attribute` and + `set_optimizer_attributes` (#2150). +- Broadcast should now be explicit inside macros. `@SDconstraint(model, x >= 1)` + and `@constraint(model, x + 1 in SecondOrderCone())` now throw an error + instead of broadcasting `1` along the dimension of `x` (#2107). +- `@SDconstraint(model, x >= 0)` is now equivalent to `@constraint(model, x in PSDCone())` + instead of `@constraint(model, (x .- 0) in PSDCone())` (#2107). +- The macros now create the containers with `map` instead of `for` loops, + as a consequence, containers created by `@expression` can now have any element + type and containers of constraint references now have concrete element types + when possible. This fixes a long-standing issue where `@expression` could + only be used to generate a collection of linear expressions. Now it works for + quadratic expressions as well (#2070). +- Calling `deepcopy(::AbstractModel)` now throws an error. +- The constraint name is now printed in the model string (#2108). + +### Added + +- Added support for solver-independent and solver-specific callbacks (#2101). +- Added `write_to_file` and `read_from_file`, supported formats are CBF, LP, + MathOptFormat, MPS and SDPA (#2114). +- Added support for complementarity constraints (#2132). +- Added support for indicator constraints (#2092). +- Added support for querying multiple solutions with the `result` keyword (#2100). +- Added support for constraining variables on creation (#2128). +- Added method `delete` that deletes a vector of variables at once if it is + supported by the underlying solver (#2135). +- The arithmetic between JuMP expression has be refactored into the + MutableArithmetics package (#2107). +- Improved error on complex values in NLP (#1978). +- Added an example of column generation (#2010). + +### Fixed + +- Incorrect coefficients generated when using Symmetric variables (#2102) + +## Version 0.20.1 (Oct 18, 2019) + +- Add sections on `@variables` and `@constraints` in the documentation (#2062). +- Fixed product of sparse matrices for Julia v1.3 (#2063). +- Added `set_objective_coefficient` to modify the coefficient of a linear term + of the objective function (#2008). +- Added `set_time_limit_sec`, `unset_time_limit_sec` and `time_limit_sec` to set + and query the time limit for the solver in seconds (#2053). + +## Version 0.20.0 (Aug 24, 2019) + +- Documentation updates. +- Numerous bug fixes. +- Better error messages (#1977, #1978, #1997, #2017). +- Performance improvements (#1947, #2032). +- Added LP sensitivity summary functions `lp_objective_perturbation_range` + and `lp_rhs_perturbation_range` (#1917). +- Added functions `dual_objective_value`, `raw_status` and `set_parameter`. +- Added function `set_objective_coefficient` to modify the coefficient of + a linear term of the objective (#2008). +- Added functions `set_normalized_rhs`, `normalized_rhs`, and + `add_to_function_constant` to modify and get the constant part + of a constraint (#1935, #1960). +- Added functions `set_normalized_coefficient` and `normalized_coefficient` + to modify and get the coefficient of a linear term of a constraint + (#1935, #1960). +- Numerous other improvements in MOI 0.9, see the `NEWS.md` file of MOI for more + details. + +## Version 0.19.2 (June 8, 2019) + +- Fix a bug in derivatives that could arise in models with nested nonlinear + subexpressions. + +## Version 0.19.1 (May 12, 2019) + +- Usability and performance improvements. +- Bug fixes. + +## Version 0.19.0 (February 15, 2019) + +**JuMP 0.19 contains significant breaking changes.** + +### Breaking + +- JuMP's abstraction layer for communicating with solvers changed from + [MathProgBase](https://github.com/JuliaOpt/MathProgBase.jl) (MPB) to + [MathOptInterface](https://github.com/JuliaOpt/MathOptInterface.jl) + (MOI). MOI addresses many longstanding design issues. (See @mlubin's + [slides](https://www.juliaopt.org/meetings/bordeaux2018/lubin.pdf) from + JuMP-dev 2018.) JuMP 0.19 is compatible only with solvers that have been + updated for MOI. See the + [installation guide](https://www.juliaopt.org/JuMP.jl/dev/installation/) + for a list of solvers that have and have not yet been updated. + +- Most solvers have been renamed to `PackageName.Optimizer`. For example, + `GurobiSolver()` is now `Gurobi.Optimizer`. + +- Solvers are no longer added to a model via `Model(solver = XXX(kwargs...))`. + Instead use `Model(with_optimizer(XXX, kwargs...))`. For example, `Model(with_optimizer(Gurobi.Optimizer, OutputFlag=0))`. + +- JuMP containers (for example, the objects returned by `@variable`) have been + redesigned. `Containers.SparseAxisArray` replaces `JuMPDict`, `JuMPArray` was + rewritten (inspired by `AxisArrays`) and renamed `Containers.DenseAxisArray`, + and you can now request a container type with the `container=` keyword to the + macros. See the corresponding + [documentation](https://www.juliaopt.org/JuMP.jl/dev/variables/#Variable-containers-1) + for more details. + +- The statuses returned by solvers have changed. See the possible status + values + [here](https://www.juliaopt.org/MathOptInterface.jl/stable/apireference.html#Termination-Status-1). + The MOI statuses are much richer than the MPB statuses and can be used to + distinguish between previously indistinguishable cases (for example, did the solver + have a feasible solution when it stopped because of the time limit?). + +- Starting values are separate from result values. Use `value` to query + the value of a variable in a solution. Use `start_value` and `set_start_value` + to get and set an initial starting point provided to the solver. The solutions + from previous solves are no longer automatically set as the starting points + for the next solve. + +- The data structures for affine and quadratic expressions `AffExpr` and + `QuadExpr` have changed. Internally, terms are stored in dictionaries instead + of lists. Duplicate coefficients can no longer exist. Accessors and iteration + methods have changed. + +- `JuMPNLPEvaluator` no longer includes the linear and quadratic parts of the + model in the evaluation calls. These are now handled separately to allow NLP + solvers that support various types of constraints. + +- JuMP solver-independent callbacks have been replaced by solver-specific + callbacks. See your favorite solver for more details. (See the note below: No + solver-specific callbacks are implemented yet.) + +- The `norm()` syntax is no longer recognized inside macros. Use the + `SecondOrderCone()` set instead. + +- JuMP no longer performs automatic transformation between special quadratic + forms and second-order cone constraints. Support for these + constraint classes depends on the solver. + +- The symbols `:Min` and `:Max` are no longer used as optimization senses. + Instead, JuMP uses the `OptimizationSense` enum from MathOptInterface. + `@objective(model, Max, ...)`, `@objective(model, Min, ...)`, + `@NLobjective(model, Max, ...)`, and `@objective(model, Min, ...)` remain + valid, but `@objective(m, :Max, ...)` is no longer accepted. + +- The sign conventions for duals has changed in some cases for consistency with + conic duality (see the + [documentation](https://www.juliaopt.org/MathOptInterface.jl/v0.6.2/apimanual.html#Duals-1)). + The `shadow_price` helper method returns duals with signs that match + conventional LP interpretations of dual values as sensitivities of the + objective value to relaxations of constraints. + +- `@constraintref` is no longer defined. Instead, create the appropriate + container to hold constraint references manually. For example, + ```julia + constraints = Dict() # Optionally, specify types for improved performance. + for i in 1:N + constraints[i] = @constraint(model, ...) + end + ``` + +- The `lowerbound`, `upperbound`, and `basename` keyword arguments to the `@variable` + macro have been renamed to `lower_bound`, `upper_bound`, and `base_name`, + for consistency with JuMP's new + [style recommendations](https://www.juliaopt.org/JuMP.jl/dev/style/). + +- We rely on broadcasting syntax to apply accessors to collections of + variables, for example, `value.(x)` instead of `getvalue(x)` for collections. (Use + `value(x)` when `x` is a scalar object.) + +### Added + +- Splatting (like `f(x...)`) is recognized in restricted settings in nonlinear + expressions. + +- Support for deleting constraints and variables. + +- The documentation has been completely rewritten using docstrings and + Documenter. + +- Support for modeling mixed conic and quadratic models (for example, conic models + with quadratic objectives and bi-linear matrix inequalities). + +- Significantly improved support for modeling new types of constraints and for + extending JuMP's macros. + +- Support for providing dual warm starts. + +- Improved support for accessing solver-specific attributes (for example, the + irreducible inconsistent subsystem). + +- Explicit control of whether symmetry-enforcing constraints are added to PSD + constraints. + +- Support for modeling exponential cones. + +- Significant improvements in internal code quality and testing. + +- Style and naming guidelines. + +- Direct mode and manual mode provide explicit control over when copies of a + model are stored or regenerated. See the corresponding + [documentation](https://www.juliaopt.org/JuMP.jl/dev/solvers/). + +### Regressions + +There are known regressions from JuMP 0.18 that will be addressed in a future +release (0.19.x or later): + +- Performance regressions in model generation + ([issue](https://github.com/JuliaOpt/JuMP.jl/issues/1403)). Please file an + issue anyway if you notice a significant performance regression. We have + plans to address a number of performance issues, but we might not be aware of + all of them. + +- Fast incremental NLP solves are not yet reimplemented + ([issue](https://github.com/JuliaOpt/JuMP.jl/issues/1185)). + +- We do not yet have an implementation of solver-specific callbacks. + +- The column generation syntax in `@variable` has been removed (that is, the + `objective`, `coefficients`, and `inconstraints` keyword arguments). Support + for column generation will be re-introduced in a future release. + +- The ability to solve the continuous relaxation (that is, via + `solve(model; relaxation = true)`) is not yet reimplemented ([issue](https://github.com/JuliaOpt/JuMP.jl/issues/1611)). + +## Version 0.18.5 (December 1, 2018) + + * Support views in some derivative evaluation functions. + * Improved compatibility with PackageCompiler. + +## Version 0.18.4 (October 8, 2018) + + * Fix a bug in model printing on Julia 0.7 and 1.0. + +## Version 0.18.3 (October 1, 2018) + + * Add support for Julia v1.0 (Thanks @ExpandingMan) + * Fix matrix expressions with quadratic functions (#1508) + +## Version 0.18.2 (June 10, 2018) + + * Fix a bug in second-order derivatives when expressions are present (#1319) + * Fix a bug in `@constraintref` (#1330) + +## Version 0.18.1 (April 9, 2018) + + * Fix for nested tuple destructuring (#1193) + * Preserve internal model when relaxation=true (#1209) + * Minor bug fixes and updates for example + +## Version 0.18.0 (July 27, 2017) + + * Drop support for Julia 0.5. + * Update for ForwardDiff 0.5. + * Minor bug fixes. + +## Version 0.17.1 (June 9, 2017) + + * Use of `constructconstraint!` in `@SDconstraint`. + * Minor bug fixes. + +## Version 0.17.0 (May 27, 2017) + + * **Breaking change**: Mixing quadratic and conic constraints is no longer supported. + * **Breaking change**: The `getvariable` and `getconstraint` functions are replaced by indexing on the corresponding symbol. For instance, to access the variable with name `x`, one should now write `m[:x]` instead of `getvariable(m, :x)`. As a consequence, creating a variable and constraint with the same name now triggers a warning, and accessing one of them afterwards throws an error. This change is breaking only in the latter case. + * Addition of the `getobjectivebound` function that mirrors the functionality of the MathProgBase `getobjbound` function except that it takes into account transformations performed by JuMP. + * Minor bug fixes. + +The following changes are primarily of interest to developers of JuMP extensions: + + * The new syntax `@constraint(model, expr in Cone)` creates the constraint ensuring that `expr` is inside `Cone`. The `Cone` argument is passed to `constructconstraint!` which enables the call to the dispatched to an extension. + * The `@variable` macro now calls `constructvariable!` instead of directly calling the `Variable` constructor. Extra arguments and keyword arguments passed to `@variable` are passed to `constructvariable!` which enables the call to be dispatched to an extension. + * Refactor the internal function `conicdata` (used build the MathProgBase conic model) into smaller sub-functions to make these parts reusable by extensions. + +## Version 0.16.2 (March 28, 2017) + + * Minor bug fixes and printing tweaks + * Address deprecation warnings for Julia 0.6 + +## Version 0.16.1 (March 7, 2017) + + * Better support for `AbstractArray` in JuMP (Thanks @tkoolen) + * Minor bug fixes + +## Version 0.16.0 (February 23, 2017) + + * **Breaking change**: JuMP no longer has a mechanism for selecting solvers by default (the previous mechanism was flawed and incompatible with Julia 0.6). Not specifying a solver before calling `solve()` will result in an error. + * **Breaking change**: User-defined functions are no longer global. The first argument to `JuMP.register` is now a JuMP `Model` object within whose scope the function will be registered. Calling `JuMP.register` without a `Model` now produces an error. + * **Breaking change**: Use the new `JuMP.fix` method to fix a variable to a value or to update the value to which a variable is fixed. Calling `setvalue` on a fixed variable now results in an error in order to avoid silent behavior changes. (Thanks @joaquimg) + * Nonlinear expressions now print out similarly to linear/quadratic expressions (useful for debugging!) + * New `category` keyword to `@variable`. Used for specifying categories of anonymous variables. + * Compatibility with Julia 0.6-dev. + * Minor fixes and improvements (Thanks @cossio, @ccoffrin, @blegat) + +## Version 0.15.1 (January 31, 2017) + + * Bugfix for `@LinearConstraints` and friends + +## Version 0.15.0 (December 22, 2016) + + * Julia 0.5.0 is the minimum required version for this release. + * Document support for BARON solver + * Enable info callbacks in more states than before, for example, for recording solutions. + New `when` argument to `addinfocallback` ([#814](https://github.com/JuliaOpt/JuMP.jl/pull/814), thanks @yeesian) + * Improved support for anonymous variables. This includes new warnings for potentially confusing use of the traditional non-anonymous syntax: + * When multiple variables in a model are given the same name + * When non-symbols are used as names, for example, `@variable(m, x[1][1:N])` + * Improvements in iterating over JuMP containers ([#836](https://github.com/JuliaOpt/JuMP.jl/pull/836), thanks @IssamT) + * Support for writing variable names in .lp file output (Thanks @leethargo) + * Support for querying duals to SDP problems (Thanks @blegat) + * The comprehension syntax with curly braces `sum{}`, `prod{}`, and `norm2{}` has been deprecated + in favor of Julia's native comprehension syntax `sum()`, `prod()` and `norm()` as previously announced. + (For early adopters of the new syntax, `norm2()` was renamed to `norm()` without deprecation.) + * Unit tests rewritten to use Base.Test instead of FactCheck + * Improved support for operations with matrices of JuMP types (Thanks @ExpandingMan) + * The syntax to halt a solver from inside a callback has changed from `throw(CallbackAbort())` to `return JuMP.StopTheSolver` + * Minor bug fixes + +## Version 0.14.2 (December 12, 2016) + + * Allow singleton anonymous variables (includes bugfix) + +## Version 0.14.1 (September 12, 2016) + + * More consistent handling of states in informational callbacks, + includes a new `when` parameter to `addinfocallback` for + specifying in which state an informational callback should be called. + +## Version 0.14.0 (August 7, 2016) + + * Compatibility with Julia 0.5 and ForwardDiff 0.2 + * Support for "anonymous" variables, constraints, expressions, and parameters, for example, + `x = @variable(m, [1:N])` instead of `@variable(m, x[1:N])` + * Support for retrieving constraints from a model by name via `getconstraint` + * `@NLconstraint` now returns constraint references (as expected). + * Support for vectorized expressions within lazy constraints + * On Julia 0.5, parse new comprehension syntax `sum(x[i] for i in 1:N if isodd(i))` + instead of `sum{ x[i], i in 1:N; isodd(i) }`. The old syntax with curly + braces will be deprecated in JuMP 0.15. + * Now possible to provide nonlinear expressions as "raw" Julia `Expr` objects + instead of using JuMP's nonlinear macros. This input format is useful for + programmatically generated expressions. + * `s/Mathematical Programming/Mathematical Optimization/` + * Support for local cuts (Thanks to @madanim, Mehdi Madani) + * Document Xpress interface developed by @joaquimg, Joaquim Dias Garcia + * Minor bug and deprecation fixes (Thanks @odow, @jrevels) + +## Version 0.13.2 (May 16, 2016) + + * Compatibility update for MathProgBase + +## Version 0.13.1 (May 3, 2016) + + * Fix broken deprecation for `registerNLfunction`. + +## Version 0.13.0 (April 29, 2016) + + * Most exported methods and macros have been renamed to avoid camelCase. See the list of changes [here](https://github.com/JuliaOpt/JuMP.jl/blob/e53d0db67cde2a4b80d0c1281f4b49eb0128a1f5/src/deprecated.jl#L30). There is a 1-1 mapping from the old names to the new, and it is safe to simply replace the names to update existing models. + * Specify variable lower/upper bounds in `@variable` using the `lowerbound` and `upperbound` keyword arguments. + * Change name printed for variable using the `basename` keyword argument to `@variable`. + * New `@variables` macro allows multi-line declaration of groups of variables. + * A number of solver methods previously available only through MathProgBase are now exposed directly in JuMP. The fix was [recorded](https://youtu.be/qF1lZPJ3a5A) live. + * Compatibility fixes with Julia 0.5. + * The "end" indexing syntax is no longer supported within JuMPArrays which do not use 1-based indexing until upstream issues are resolved, see [here](https://github.com/JuliaOpt/JuMP.jl/issues/730). + +## Version 0.12.2 (March 9, 2016) + + * Small fixes for nonlinear optimization + +## Version 0.12.1 (March 1, 2016) + + * Fix a regression in slicing for JuMPArrays (when not using 1-based indexing) + +## Version 0.12.0 (February 27, 2016) + + * The automatic differentiation functionality has been completely rewritten with a number of user-facing changes: + - `@defExpr` and `@defNLExpr` now take the model as the first argument. The previous one-argument version of `@defExpr` is deprecated; all expressions should be named. For example, replace `@defExpr(2x+y)` with `@defExpr(jump_model, my_expr, 2x+y)`. + - JuMP no longer uses Julia's variable binding rules for efficiently re-solving a sequence of nonlinear models. Instead, we have introduced nonlinear parameters. This is a breaking change, so we have added a warning message when we detect models that may depend on the old behavior. + - Support for user-defined functions integrated within nonlinear JuMP expressions. + * Replaced iteration over `AffExpr` with `Number`-like scalar iteration; previous iteration behavior is now available via `linearterms(::AffExpr)`. + * Stopping the solver via `throw(CallbackAbort())` from a callback no longer triggers an exception. Instead, `solve()` returns `UserLimit` status. + * `getDual()` now works for conic problems (Thanks @emreyamangil.) + +## Version 0.11.3 (February 4, 2016) + + * Bug-fix for problems with quadratic objectives and semidefinite constraints + +## Version 0.11.2 (January 14, 2016) + + * Compatibility update for Mosek + +## Version 0.11.1 (December 1, 2015) + + * Remove usage of `@compat` in tests. + * Fix updating quadratic objectives for nonlinear models. + +## Version 0.11.0 (November 30, 2015) + + * Julia 0.4.0 is the minimum required version for this release. + * Fix for scoping semantics of index variables in sum{}. Index variables no longer leak into the surrounding scope. + * Addition of the `solve(m::Model, relaxation=true)` keyword argument to solve the standard continuous relaxation of model `m` + * The `getConstraintBounds()` method allows access to the lower and upper bounds of all constraints in a (nonlinear) model. + * Update for breaking changes in MathProgBase + +## Version 0.10.3 (November 20, 2015) + + * Fix a rare error when parsing quadratic expressions + * Fix `Variable()` constructor with default arguments + * Detect unrecognized keywords in `solve()` + +## Version 0.10.2 (September 28, 2015) + + * Fix for deprecation warnings + +## Version 0.10.1 (September 3, 2015) + + * Fixes for ambiguity warnings. + * Fix for breaking change in precompilation syntax in Julia 0.4-pre + +## Version 0.10.0 (August 31, 2015) + + * Support (on Julia 0.4 and later) for conditions in indexing `@defVar` and `@addConstraint` constructs, for example, `@defVar(m, x[i=1:5,j=1:5; i+j >= 3])` + * Support for vectorized operations on Variables and expressions. See the documentation for details. + * New `getVar()` method to access variables in a model by name + * Support for semidefinite programming. + * Dual solutions are now available for general nonlinear problems. You may call `getDual` on a reference object for a nonlinear constraint, and `getDual` on a variable object for Lagrange multipliers from active bounds. + * Introduce warnings for two common performance traps: too many calls to `getValue()` on a collection of variables and use of the `+` operator in a loop to sum expressions. + * Second-order cone constraints can be written directly with the `norm()` and `norm2{}` syntax. + * Implement MathProgBase interface for querying Hessian-vector products. + * Iteration over `JuMPContainer`s is deprecated; instead, use the `keys` and `values` functions, and `zip(keys(d),values(d))` for the old behavior. + * `@defVar` returns `Array{Variable,N}` when each of `N` index sets are of the form `1:nᵢ`. + * Module precompilation: on Julia 0.4 and later, `using JuMP` is now much faster. + +## Version 0.9.3 (August 11, 2015) + + * Fixes for FactCheck testing on julia v0.4. + +## Version 0.9.2 (June 27, 2015) + + * Fix bug in @addConstraints. + +## Version 0.9.1 (April 25, 2015) + + * Fix for Julia 0.4-dev. + * Small infrastructure improvements for extensions. + +## Version 0.9.0 (April 18, 2015) + + * Comparison operators for constructing constraints (for example, `2x >= 1`) have been deprecated. Instead, construct the constraints explicitly in + the `@addConstraint` macro to add them to the model, or in the `@LinearConstraint` macro to create a stand-alone linear constraint instance. + * `getValue()` method implemented to compute the value of a nonlinear subexpression + * JuMP is now released under the Mozilla Public License version 2.0 (was previously LGPL). MPL is a copyleft license which is less restrictive than LGPL, especially for embedding JuMP within other applications. + * A number of performance improvements in ReverseDiffSparse for computing derivatives. + * `MathProgBase.getsolvetime(m)` now returns the solution time reported by the solver, if available. (Thanks @odow, Oscar Dowson) + * Formatting fix for LP format output. (Thanks @sbebo, Leonardo Taccari). + +## Version 0.8.0 (February 17, 2015) + + * Nonlinear subexpressions now supported with the `@defNLExpr` macro. + * SCS supported for solving second-order conic problems. + * `setXXXCallback` family deprecated in favor of `addXXXCallback`. + * Multiple callbacks of the same type can be registered. + * Added support for informational callbacks via `addInfoCallback`. + * A `CallbackAbort` exception can be thrown from callback to safely exit optimization. + +## Version 0.7.4 (February 4, 2015) + + * Reduced costs and linear constraint duals are now accessible when quadratic constraints are present. + * Two-sided nonlinear constraints are supported. + * Methods for accessing the number of variables and constraints in a model are renamed. + * New default procedure for setting initial values in nonlinear optimization: project zero onto the variable bounds. + * Small bug fixes. + +## Version 0.7.3 (January 14, 2015) + + * Fix a method ambiguity conflict with Compose.jl (cosmetic fix) + +## Version 0.7.2 (January 9, 2015) + + * Fix a bug in `sum(::JuMPDict)` + * Added the `setCategory` function to change a variables category (for example, continuous or binary) + after construction, and `getCategory` to retrieve the variable category. + +## Version 0.7.1 (January 2, 2015) + + * Fix a bug in parsing linear expressions in macros. Affects only Julia 0.4 and later. + +## Version 0.7.0 (December 29, 2014) + +### Linear/quadratic/conic programming + + * **Breaking change**: The syntax for column-wise model generation has been changed to use keyword arguments in `@defVar`. + * On Julia 0.4 and later, variables and coefficients may be multiplied in any order within macros. That is, variable*coefficient is now valid syntax. + * ECOS supported for solving second-order conic problems. + +### [Nonlinear programming](@id _nonlinear_programming_release_notes) + + * Support for skipping model generation when solving a sequence of nonlinear models with changing data. + * Fix a memory leak when solving a sequence of nonlinear models. + * The `@addNLConstraint` macro now supports the three-argument version to define sets of nonlinear constraints. + * KNITRO supported as a nonlinear solver. + * Speed improvements for model generation. + * The `@addNLConstraints` macro supports adding multiple (groups of) constraints at once. Syntax is similar to `@addConstraints`. + * Discrete variables allowed in nonlinear problems for solvers which support them (currently only KNITRO). + +### General + + * Starting values for variables may now be specified with `@defVar(m, x, start=value)`. + * The `setSolver` function allows users to change the solver subsequent to model creation. + * Support for "fixed" variables via the `@defVar(m, x == 1)` syntax. + * Unit tests rewritten to use FactCheck.jl, improved testing across solvers. + +## Version 0.6.3 (October 19, 2014) + + * Fix a bug in multiplying two AffExpr objects. + +## Version 0.6.2 (October 11, 2014) + + * Further improvements and bug fixes for printing. + * Fixed a bug in `@defExpr`. + * Support for accessing expression graphs through the MathProgBase NLP interface. + +## Version 0.6.1 (September 19, 2014) + + * Improvements and bug fixes for printing. + +## Version 0.6.0 (September 9, 2014) + + * Julia 0.3.0 is the minimum required version for this release. + * `buildInternalModel(m::Model)` added to build solver-level model in memory without optimizing. + * Deprecate `load_model_only` keyword argument to `solve`. + * Add groups of constraints with `@addConstraints` macro. + * Unicode operators now supported, including `∑` for `sum`, `∏` for `prod`, and `≤`/`≥` + * Quadratic constraints supported in `@addConstraint` macro. + * Quadratic objectives supported in `@setObjective` macro. + * MathProgBase solver-independent interface replaces Ipopt-specific interface for nonlinear problems + - **Breaking change**: `IpoptOptions` no longer supported to specify solver options, use `m = Model(solver=IpoptSolver(options...))` instead. + * New solver interfaces: ECOS, NLopt, and nonlinear support for MOSEK + * New option to control whether the lazy constraint callback is executed at each node in the B&B tree or just when feasible solutions are found + * Add support for semicontinuous and semi-integer variables for those solvers that support them. + * Add support for index dependencies (for example, triangular indexing) in `@defVar`, `@addConstraint`, and `@defExpr` (for example, `@defVar(m, x[i=1:10,j=i:10])`). + - This required some changes to the internal structure of JuMP containers, which may break code that explicitly stored `JuMPDict` objects. + +## Version 0.5.8 (September 24, 2014) + + * Fix a bug with specifying solvers (affects Julia 0.2 only) + +## Version 0.5.7 (September 5, 2014) + + * Fix a bug in printing models + +## Version 0.5.6 (September 2, 2014) + + * Add support for semicontinuous and semi-integer variables for those solvers that support them. + - **Breaking change**: Syntax for `Variable()` constructor has changed (use of this interface remains discouraged) + * Update for breaking changes in MathProgBase + +## Version 0.5.5 (July 6, 2014) + + * Fix bug with problem modification: adding variables that did not appear in existing constraints or objective. + +## Version 0.5.4 (June 19, 2014) + + * Update for breaking change in MathProgBase which reduces loading times for `using JuMP` + * Fix error when MIPs not solved to optimality + +## Version 0.5.3 (May 21, 2014) + + * Update for breaking change in ReverseDiffSparse + +## Version 0.5.2 (May 9, 2014) + + * Fix compatibility with Julia 0.3 prerelease + +## Version 0.5.1 (May 5, 2014) + + * Fix a bug in coefficient handling inside lazy constraints and user cuts + +## Version 0.5.0 (May 2, 2014) + + * Support for nonlinear optimization with exact, sparse second-order derivatives automatically computed. Ipopt is currently the only solver supported. + * `getValue` for `AffExpr` and `QuadExpr` + * **Breaking change**: `getSolverModel` replaced by `getInternalModel`, which returns the internal MathProgBase-level model + * Groups of constraints can be specified with `@addConstraint` (see documentation for details). This is not a breaking change. + * `dot(::JuMPDict{Variable},::JuMPDict{Variable})` now returns the corresponding quadratic expression. + +## Version 0.4.1 (March 24, 2014) + + * Fix bug where change in objective sense was ignored when re-solving a model. + * Fix issue with handling zero coefficients in AffExpr. + +## Version 0.4.0 (March 10, 2014) + + * Support for SOS1 and SOS2 constraints. + * Solver-independent callback for user heuristics. + * `dot` and `sum` implemented for `JuMPDict` objects. Now you can say `@addConstraint(m, dot(a,x) <= b)`. + * Developers: support for extensions to JuMP. See definition of Model in `src/JuMP.jl` for more details. + * Option to construct the low-level model before optimizing. + +## Version 0.3.2 (February 17, 2014) + + * Improved model printing + - Preliminary support for IJulia output + +## Version 0.3.1 (January 30, 2014) + + * Documentation updates + * Support for MOSEK + * CPLEXLink renamed to CPLEX + +## Version 0.3.0 (January 21, 2014) + + * Unbounded/infeasibility rays: `getValue()` will return the corresponding + components of an unbounded ray when a model is unbounded, if supported + by the selected solver. `getDual()` will return an infeasibility ray (Farkas + proof) if a model is infeasible and the selected solver supports this + feature. + * Solver-independent callbacks for user generated cuts. + * Use new interface for solver-independent QCQP. + * `setlazycallback` renamed to `setLazyCallback` for consistency. + +## Version 0.2.0 (December 15, 2013) + +### Breaking + + * Objective sense is specified in `setObjective` instead of in the `Model` + constructor. + * `lpsolver` and `mipsolver` merged into single `solver` option. + +### Added + + * Problem modification with efficient LP restarts and MIP warm-starts. + * Relatedly, column-wise modeling now supported. + * Solver-independent callbacks supported. Currently we support only + a "lazy constraint" callback, which works with Gurobi, CPLEX, and GLPK. + More callbacks coming soon. + +## Version 0.1.2 (November 16, 2013) + + * Bug fixes for printing, improved error messages. + * Allow `AffExpr` to be used in macros; for example, + `ex = y + z; @addConstraint(m, x + 2*ex <= 3)` + +## Version 0.1.1 (October 23, 2013) + + * Update for solver specification API changes in MathProgBase. + +## Version 0.1.0 (October 3, 2013) + + * Initial public release. diff --git a/test/test_changelogs/v1.1.md b/test/test_changelogs/v1.1.md new file mode 100644 index 0000000..a29b5b6 --- /dev/null +++ b/test/test_changelogs/v1.1.md @@ -0,0 +1,29 @@ +# Changelog.jl changelog + +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), +and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). + + + +## [v1.1.0] - 2023-11-13 +### Added +- Links of the form `[]`, where `` is a commit hash + of length 7 or 40, are now linkified. ([#4]) + +## [v1.0.0] - 2023-11-13 +First release. See +[README.md](https://github.com/JuliaDocs/Changelog.jl/blob/master/README.md) +for currently supported functionality. + + + + +[v1.0.0]: https://github.com/JuliaDocs/Changelog.jl/releases/tag/v1.0.0 +[v1.1.0]: https://github.com/JuliaDocs/Changelog.jl/releases/tag/v1.1.0 +[#4]: https://github.com/JuliaDocs/Changelog.jl/issues/4