Skip to content

Commit

Permalink
Merge pull request #7928 from quarto-dev/bugfix/3323
Browse files Browse the repository at this point in the history
crossreferenceable Remarks and Solutions
  • Loading branch information
cscheid authored Dec 15, 2023
2 parents aafa590 + e644af3 commit b44ceb1
Show file tree
Hide file tree
Showing 20 changed files with 341 additions and 164 deletions.
1 change: 0 additions & 1 deletion news/changelog-1.4.md
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,6 @@
- ([#5969](https://github.com/quarto-dev/quarto-cli/issues/5969)): Correctly detect a required rerun for biblatex when using backref link options.
- ([#5690](https://github.com/quarto-dev/quarto-cli/issues/5690)): Improve validation of `pdf-engine`
- ([#6077](https://github.com/quarto-dev/quarto-cli/issues/6077)): Make sure proof environments are tight around contents.
- ([#6298](https://github.com/quarto-dev/quarto-cli/issues/6298)): Handle multiple margin and caption specifiers on a single image.
- ([#6907](https://github.com/quarto-dev/quarto-cli/issues/6907)): Fix issue with footnote mark line processor not triggering.
- ([#6990](https://github.com/quarto-dev/quarto-cli/issues/6990)): Fix an issue where underscore in `filename` code cell attribute were not escaped.
- ([#7175](https://github.com/quarto-dev/quarto-cli/issues/7175)): Fix an issue with code annotations when more than one digit is used for annotation number.
Expand Down
27 changes: 8 additions & 19 deletions src/project/project-config.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
/*
* project-config.ts
*
* Copyright (C) 2020-2022 Posit Software, PBC
*/
* project-config.ts
*
* Copyright (C) 2020-2022 Posit Software, PBC
*
*/

import { join } from "path/mod.ts";

Expand All @@ -16,34 +17,28 @@ import { SidebarItem } from "./types.ts";

export type SidebarContext = {
counter: number;
itemCounter: number;
};

export const sidebarContext = (): SidebarContext => {
return { counter: 0, itemCounter: 0 };
return { counter: 0 };
};

export function normalizeSidebarItem(
projectDir: string,
item: SidebarItem,
context: SidebarContext,
context: { counter: number },
): SidebarItem {
// clone so we can mutate
item = ld.cloneDeep(item);

if (typeof item === "string") {
context.itemCounter = context.itemCounter + 1;
const id = `${kQuartoSidebarItemPrefix}${context.itemCounter}`;

if (typeof (item) === "string") {
if (safeExistsSync(join(projectDir, item))) {
item = {
href: item,
id,
};
} else {
item = {
text: item,
id,
};
}
} else {
Expand Down Expand Up @@ -72,11 +67,6 @@ export function normalizeSidebarItem(
// If this is a section, we should insist that it have 'contents'
// even if they are empty.
item.contents = item.contents || [];
} else {
context.itemCounter = context.itemCounter + 1;
item.id = item.id === undefined
? `${kQuartoSidebarItemPrefix}${context.itemCounter}`
: item.id;
}

// handle subitems
Expand All @@ -95,7 +85,6 @@ export function normalizeSidebarItem(
}

const kQuartoSidebarPrefix = "quarto-sidebar-section-";
const kQuartoSidebarItemPrefix = "quarto-sidebar-item-";

export function resolveHrefAttribute(
item: { href?: string; file?: string; url?: string },
Expand Down
6 changes: 3 additions & 3 deletions src/project/types/website/website-navigation-md.ts
Original file line number Diff line number Diff line change
Expand Up @@ -243,7 +243,7 @@ const sidebarContentsHandler = (context: NavigationPipelineContext) => {
if (item.sectionId) {
markdown[`${kSidebarIdPrefix}${item.sectionId}`] = item.text;
} else {
markdown[`${kSidebarIdPrefix}${item.id || ""}${item.href}`] =
markdown[`${kSidebarIdPrefix}${item.href}${item.text}`] =
item.text;
}
}
Expand All @@ -258,11 +258,11 @@ const sidebarContentsHandler = (context: NavigationPipelineContext) => {
);
for (let i = 0; i < sidebarItemEls.length; i++) {
const sidebarEl = sidebarItemEls[i] as Element;
const link = sidebarEl.querySelector(".menu-text");
const href = sidebarEl.getAttribute("href");
const link = sidebarEl.querySelector(".menu-text");
if (link) {
const sidebarText =
rendered[`${kSidebarIdPrefix}${sidebarEl.id}${href}`];
rendered[`${kSidebarIdPrefix}${href}${link.innerText}`];
if (sidebarText) {
link.innerHTML = sidebarText.innerHTML;
}
Expand Down
6 changes: 1 addition & 5 deletions src/project/types/website/website-navigation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,6 @@ import {
import {
normalizeSidebarItem,
resolveHrefAttribute,
SidebarContext,
sidebarContext,
} from "../../project-config.ts";
import { projectType } from "../project-types.ts";
Expand Down Expand Up @@ -1058,10 +1057,7 @@ async function resolveSidebarItems(
}
}

async function resolveSidebarItem(
project: ProjectContext,
item: SidebarItem,
) {
async function resolveSidebarItem(project: ProjectContext, item: SidebarItem) {
if (item.href) {
item = await resolveItem(
project,
Expand Down
25 changes: 0 additions & 25 deletions src/resources/filters/common/theorems.lua
Original file line number Diff line number Diff line change
@@ -1,27 +1,2 @@
-- theorems.lua
-- Copyright (C) 2020-2022 Posit Software, PBC

proofTypes = {
proof = {
env = 'proof',
title = 'Proof'
},
remark = {
env = 'remark',
title = 'Remark'
},
solution = {
env = 'solution',
title = 'Solution'
}
}

function proofType(el)
local type = el.attr.classes:find_if(function(clz) return proofTypes[clz] ~= nil end)
if type ~= nil then
return proofTypes[type]
else
return nil
end

end
5 changes: 4 additions & 1 deletion src/resources/filters/crossref/crossref.lua
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ import("../quarto-pre/panel-input.lua")
import("../quarto-pre/panel-layout.lua")
import("../quarto-pre/panel-sidebar.lua")
import("../quarto-pre/parsefiguredivs.lua")
import("../quarto-pre/parseblockreftargets.lua")
import("../quarto-pre/project-paths.lua")
import("../quarto-pre/resourcefiles.lua")
import("../quarto-pre/results.lua")
Expand All @@ -117,6 +118,7 @@ import("../customnodes/decoratedcodeblock.lua")
import("../customnodes/callout.lua")
import("../customnodes/panel-tabset.lua")
import("../customnodes/floatreftarget.lua")
import("../customnodes/proof.lua")
import("../customnodes/theorem.lua")
import("../customnodes/panellayout.lua")

Expand Down Expand Up @@ -176,7 +178,8 @@ local quarto_normalize_filters = {
name = "normalize-combine-2",
filter = combineFilters({
parse_md_in_html_rawblocks(),
parse_reftargets(),
parse_floatreftargets(),
parse_blockreftargets(),
}),
},
}
Expand Down
52 changes: 29 additions & 23 deletions src/resources/filters/crossref/theorems.lua
Original file line number Diff line number Diff line change
Expand Up @@ -3,27 +3,22 @@

-- preprocess theorem to ensure that embedded headings are unnumered
function crossref_preprocess_theorems()
local types = theorem_types
return {
Div = function(el)
local type = refType(el.attr.identifier)
if types[type] ~= nil or proofType(el) ~= nil then
if theorem_types[type] ~= nil or proof_type(el) ~= nil then
return _quarto.ast.walk(el, {
Header = function(el)
el.classes:insert("unnumbered")
return el
end
})
end

end
}
end

function crossref_theorems()

local types = theorem_types

return {
Theorem = function(thm)
local label = thm.identifier
Expand All @@ -32,19 +27,29 @@ function crossref_theorems()
thm.order = add_crossref(label, type, title)
return thm
end,
Proof = function(proof)
local label = proof.identifier
if label == "" then
return nil -- it's an unnumbered proof
end
local type = refType(label)
local title = quarto.utils.as_blocks(proof.name)
proof.order = add_crossref(label, type, title)
return proof
end,
Div = function(el)

local type = refType(el.attr.identifier)
local theoremType = types[type]
local theoremType = theorem_types[type]
if theoremType then
internal_error()
else
-- see if this is a proof, remark, or solution
local proof = proofType(el)
local proof = proof_type(el)
if proof ~= nil then

-- ensure requisite latex is injected
crossref.usingTheorems = true
crossref.using_theorems = true

if proof.env ~= "proof" then
el.attr.classes:insert("proof")
Expand Down Expand Up @@ -135,7 +140,7 @@ function jatsTheorem(el, label, title)
-- </p>
-- </statement>

if title then
if #title > 0 then
tprepend(el.content, {
pandoc.RawBlock("jats", "<title>"),
pandoc.Plain(title),
Expand Down Expand Up @@ -179,39 +184,40 @@ end
function theoremLatexIncludes()

-- determine which theorem types we are using
local types = theorem_types
local refs = tkeys(crossref.index.entries)
local usingTheorems = crossref.usingTheorems
local using_theorems = crossref.using_theorems
for k,v in pairs(crossref.index.entries) do
local type = refType(k)
if types[type] then
usingTheorems = true
types[type].active = true
if theorem_types[type] then
using_theorems = true
theorem_types[type].active = true
end
end

-- return requisite latex if we are using theorems
if usingTheorems then
if using_theorems then
local secType
if crossrefOption("chapters", false) then
secType = "chapter"
else
secType = "section"
end
local theoremIncludes = "\\usepackage{amsthm}\n"
for _, type in ipairs(tkeys(types)) do
if types[type].active then
for _, type in ipairs(tkeys(theorem_types)) do
if theorem_types[type].active then
theoremIncludes = theoremIncludes ..
"\\theoremstyle{" .. types[type].style .. "}\n" ..
"\\newtheorem{" .. types[type].env .. "}{" ..
titleString(type, types[type].title) .. "}[" .. secType .. "]\n"
"\\theoremstyle{" .. theorem_types[type].style .. "}\n" ..
"\\newtheorem{" .. theorem_types[type].env .. "}{" ..
titleString(type, theorem_types[type].title) .. "}[" .. secType .. "]\n"
end
end
theoremIncludes = theoremIncludes ..
"\\theoremstyle{remark}\n" ..
"\\AtBeginDocument{\\renewcommand*{\\proofname}{" .. envTitle("proof", "Proof") .. "}}\n" ..
"\\newtheorem*{remark}{" .. envTitle("remark", "Remark") .. "}\n" ..
"\\newtheorem*{solution}{" .. envTitle("solution", "Solution") .. "}\n"
"\\newtheorem*{solution}{" .. envTitle("solution", "Solution") .. "}\n" ..
"\\newtheorem{refremark}{" .. envTitle("remark", "Remark") .. "}[" .. secType .. "]\n" ..
"\\newtheorem{refsolution}{" .. envTitle("solution", "Solution") .. "}[" .. secType .. "]\n"

return theoremIncludes
else
return nil
Expand Down
37 changes: 8 additions & 29 deletions src/resources/filters/customnodes/floatreftarget.lua
Original file line number Diff line number Diff line change
Expand Up @@ -363,41 +363,20 @@ end, function(float)
-- do the longtable fixups below
float.content = _quarto.ast.walk(quarto.utils.as_blocks(float.content), {
Table = function(tbl)
return pandoc.RawBlock("latex-merge", pandoc.write(pandoc.Pandoc({tbl}), "latex"))
return pandoc.RawBlock("latex", pandoc.write(pandoc.Pandoc({tbl}), "latex"))
end
})

if float_type == "tbl" then
local raw
-- have to call as_blocks() again here because assigning to float.content
-- goes through our AST metaclasses which coalesce a singleton list to a single AST element
float.content = _quarto.ast.walk(quarto.utils.as_blocks(float.content), {
-- coalesce rawblocks ahead of table fixups
Blocks = function(blocks)
local result = pandoc.Blocks({})
local prev
for _,block in ipairs(blocks) do
if prev == nil then
prev = block
elseif prev.t == "RawBlock" and block.t == "RawBlock" and prev.format == block.format then
prev.text = prev.text .. "\n" .. block.text
else
result:insert(prev)
prev = block
end
end
if prev ~= nil then
result:insert(prev)
end
return result
end
})
_quarto.ast.walk(quarto.utils.as_blocks(float.content), {
RawBlock = function(el)
if _quarto.format.isRawLatex(el) and el.text:match(_quarto.patterns.latexLongtablePattern) then
raw = el
end
end,
end
})
-- special case for singleton longtable floats
if raw then
Expand Down Expand Up @@ -434,14 +413,14 @@ end, function(float)
local result = pandoc.Blocks({latex_caption, pandoc.RawInline("latex", "\\tabularnewline")})
-- if cap_loc is top, insert content on bottom
if cap_loc == "top" then
result:insert(pandoc.RawBlock("latex-merge", content))
result:insert(pandoc.RawBlock("latex", content))
else
result:insert(1, pandoc.RawBlock("latex-merge", content))
result:insert(1, pandoc.RawBlock("latex", content))
end
result:insert(1, pandoc.RawBlock("latex-merge", start))
result:insert(1, pandoc.RawBlock("latex-merge", longtable_preamble))
result:insert(pandoc.RawBlock("latex-merge", "\\end{longtable}"))
result:insert(pandoc.RawBlock("latex-merge", longtable_postamble))
result:insert(1, pandoc.RawBlock("latex", start))
result:insert(1, pandoc.RawBlock("latex", longtable_preamble))
result:insert(pandoc.RawBlock("latex", "\\end{longtable}"))
result:insert(pandoc.RawBlock("latex", longtable_postamble))
return result
end
end
Expand Down
Loading

0 comments on commit b44ceb1

Please sign in to comment.