Skip to content

Commit

Permalink
It's back
Browse files Browse the repository at this point in the history
- Updated quartz
- Pages are now fixed (no fake 404s)
- Homepage for all sections have been made (Like /h-docs/sfinder-docs/solution-finder/ has been moved to /h-docs/sfinder-docs/, and a page-listing section added)
- Moved PCO and Jigsaw to Openers folder
- Renamed sfinder docs to be less repetitive
- Deleted sfinder prerequisites. Useless page
  • Loading branch information
Hsterts committed Jan 18, 2023
1 parent ae747ad commit e3be25f
Show file tree
Hide file tree
Showing 55 changed files with 502 additions and 266 deletions.
42 changes: 42 additions & 0 deletions .github/workflows/docker-publish.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
name: Create and publish a Docker image

on:
push:
branches: ['hugo']

env:
REGISTRY: ghcr.io
IMAGE_NAME: ${{ github.repository }}

jobs:
build-and-push-image:
if: github.repository == 'jackyzha0/quartz'
runs-on: ubuntu-latest
permissions:
contents: read
packages: write

steps:
- name: Checkout repository
uses: actions/checkout@v3

- name: Log in to the Container registry
uses: docker/login-action@f054a8b539a109f9f41c372932f1ae047eff08c9
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}

- name: Extract metadata (tags, labels) for Docker
id: meta
uses: docker/metadata-action@98669ae865ea3cffbcbaa878cf57c20bbf1c6c38
with:
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}

- name: Build and push Docker image
uses: docker/build-push-action@ad44023a93711e3deb337508980b4b5e9bcdc5dc
with:
context: .
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
6 changes: 5 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,8 @@ update-force: ## Forcefully pull all changes and don't ask to patch
git checkout upstream/hugo -- layouts .github Makefile assets/js assets/styles/base.scss assets/styles/darkmode.scss config.toml data

serve: ## Serve Quartz locally
hugo-obsidian -input=content -output=assets/indices -index -root=. && hugo server --enableGitInfo --minify
hugo-obsidian -input=content -output=assets/indices -index -root=.
hugo server --enableGitInfo --minify --bind=$(or $(HUGO_BIND),0.0.0.0) --baseURL=$(or $(HUGO_BASEURL),http://localhost) --port=$(or $(HUGO_PORT),1313) --appendPort=$(or $(HUGO_APPENDPORT),true) --liveReloadPort=$(or $(HUGO_LIVERELOADPORT),-1)

docker: ## Serve locally using Docker
docker run -it --volume=$(shell pwd):/quartz -p 1313:1313 ghcr.io/jackyzha0/quartz:hugo
59 changes: 32 additions & 27 deletions assets/js/clipboard.js
Original file line number Diff line number Diff line change
@@ -1,40 +1,45 @@
const svgCopy =
'<svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true"><path fill-rule="evenodd" d="M0 6.75C0 5.784.784 5 1.75 5h1.5a.75.75 0 010 1.5h-1.5a.25.25 0 00-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 00.25-.25v-1.5a.75.75 0 011.5 0v1.5A1.75 1.75 0 019.25 16h-7.5A1.75 1.75 0 010 14.25v-7.5z"></path><path fill-rule="evenodd" d="M5 1.75C5 .784 5.784 0 6.75 0h7.5C15.216 0 16 .784 16 1.75v7.5A1.75 1.75 0 0114.25 11h-7.5A1.75 1.75 0 015 9.25v-7.5zm1.75-.25a.25.25 0 00-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 00.25-.25v-7.5a.25.25 0 00-.25-.25h-7.5z"></path></svg>';
const svgCheck =
'<svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" style="fill: var(--secondary); filter: contrast(1);"><path fill-rule="evenodd" fill="rgb(63, 185, 80)" d="M13.78 4.22a.75.75 0 010 1.06l-7.25 7.25a.75.75 0 01-1.06 0L2.22 9.28a.75.75 0 011.06-1.06L6 10.94l6.72-6.72a.75.75 0 011.06 0z"></path></svg>';
'<svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true"><path fill-rule="evenodd" fill="rgb(63, 185, 80)" d="M13.78 4.22a.75.75 0 010 1.06l-7.25 7.25a.75.75 0 01-1.06 0L2.22 9.28a.75.75 0 011.06-1.06L6 10.94l6.72-6.72a.75.75 0 011.06 0z"></path></svg>';


const addCopyButtons = () => {
let els = document.getElementsByClassName("highlight");
// for each highlight
for (let i = 0; i < els.length; i++) {
if (els[i].getElementsByClassName("clipboard-button").length) continue;
try {
if (els[i].getElementsByClassName("clipboard-button").length) continue;

// find pre > code inside els[i]
let codeBlocks = els[i].getElementsByTagName("code");
// find pre > code inside els[i]
let codeBlocks = els[i].getElementsByTagName("code");

// line numbers are inside first code block
let lastCodeBlock = codeBlocks[codeBlocks.length - 1];
const button = document.createElement("button");
button.className = "clipboard-button";
button.type = "button";
button.innerHTML = svgCopy;
// remove every second newline from lastCodeBlock.innerText
button.addEventListener("click", () => {
navigator.clipboard.writeText(lastCodeBlock.innerText.replace(/\n\n/g, "\n")).then(
() => {
button.blur();
button.innerHTML = svgCheck;
setTimeout(() => {
button.innerHTML = svgCopy
button.style.borderColor = ""
}, 2000);
},
(error) => (button.innerHTML = "Error")
);
});
// find chroma inside els[i]
let chroma = els[i].getElementsByClassName("chroma")[0];
els[i].insertBefore(button, chroma);
// line numbers are inside first code block
let lastCodeBlock = codeBlocks[codeBlocks.length - 1];
const button = document.createElement("button");
button.className = "clipboard-button";
button.type = "button";
button.innerHTML = svgCopy;
button.ariaLabel = "opy the shown code";
// remove every second newline from lastCodeBlock.innerText
button.addEventListener("click", () => {
navigator.clipboard.writeText(lastCodeBlock.innerText.replace(/\n\n/g, "\n")).then(
() => {
button.blur();
button.innerHTML = svgCheck;
setTimeout(() => {
button.innerHTML = svgCopy
button.style.borderColor = ""
}, 2000);
},
(error) => (button.innerHTML = "Error")
);
});
// find chroma inside els[i]
let chroma = els[i].getElementsByClassName("chroma")[0];
els[i].insertBefore(button, chroma);
} catch(error) {
console.debug(error);
}
}
}
22 changes: 13 additions & 9 deletions assets/js/code-title.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,17 @@

function addTitleToCodeBlocks() {
var els = document.getElementsByClassName("highlight");
for (var i = 0; i < els.length; i++) {
if (els[i].title.length) {
let div = document.createElement("div");
if (els[i].getElementsByClassName("code-title").length) continue;
div.textContent=els[i].title;
div.classList.add("code-title")
els[i].insertBefore(div, els[i].firstChild);
const els = document.getElementsByClassName("highlight");
for (let i = 0; i < els.length; i++) {
try {
if (els[i].title.length) {
let div = document.createElement("div");
if (els[i].getElementsByClassName("code-title").length) continue;
div.textContent = els[i].title;
div.classList.add("code-title")
els[i].insertBefore(div, els[i].firstChild);
}
} catch (error) {
console.debug(error);
}
}
};
}
6 changes: 3 additions & 3 deletions assets/js/full-text-search.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
(async function() {
; (async function() {
const encoder = (str) => str.toLowerCase().split(/([^a-z]|[^\x00-\x7F])/)
const contentIndex = new FlexSearch.Document({
cache: true,
Expand Down Expand Up @@ -35,7 +35,7 @@
})

registerHandlers((e) => {
term = e.target.value
const term = e.target.value
const searchResults = contentIndex.search(term, [
{
field: "content",
Expand All @@ -56,6 +56,6 @@
}
const allIds = new Set([...getByField("title"), ...getByField("content")])
const finalResults = [...allIds].map(formatForDisplay)
displayResults(finalResults, true)
displayResults(term, finalResults, true)
})
})()
4 changes: 2 additions & 2 deletions assets/js/graph.js
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ async function drawGraph(baseUrl, isHome, pathColors, graphConfig) {
.append("svg")
.attr("width", width)
.attr("height", height)
.attr('viewBox', [-width / 2 * 1 / scale, -height / 2 * 1 / scale, width * 1 / scale, height * 1 / scale])
.attr('viewBox', [-width / 2 / scale, -height / 2 / scale, width / scale, height / scale])

if (enableLegend) {
const legend = [{ Current: "var(--g-node-active)" }, { Note: "var(--g-node)" }, ...pathColors]
Expand Down Expand Up @@ -155,7 +155,7 @@ async function drawGraph(baseUrl, isHome, pathColors, graphConfig) {
const nodeRadius = (d) => {
const numOut = index.links[d.id]?.length || 0
const numIn = index.backlinks[d.id]?.length || 0
return 2 + Math.sqrt(numOut + numIn)/2
return 2 + Math.sqrt(numOut + numIn)
}

// draw individual nodes
Expand Down
6 changes: 3 additions & 3 deletions assets/js/popover.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,14 @@ function htmlToElement(html) {
return template.content.firstChild
}

function initPopover(baseURL, useContextualBacklinks, renderLatex) {
function initPopover(baseURL, useContextualBacklinks) {
const basePath = baseURL.replace(window.location.origin, "")
fetchData.then(({ content }) => {
const links = [...document.getElementsByClassName("internal-link")]
links
.filter(li => li.dataset.src || (li.dataset.idx && useContextualBacklinks))
.forEach(li => {
var el
let el
if (li.dataset.ctx) {
const linkDest = content[li.dataset.src]
const popoverElement = `<div class="popover">
Expand Down Expand Up @@ -42,7 +42,7 @@ function initPopover(baseURL, useContextualBacklinks, renderLatex) {

if (el) {
li.appendChild(el)
if (renderLatex) {
if (LATEX_ENABLED) {
renderMathInElement(el, {
delimiters: [
{ left: '$$', right: '$$', display: false },
Expand Down
66 changes: 41 additions & 25 deletions assets/js/semantic-search.js
Original file line number Diff line number Diff line change
@@ -1,38 +1,54 @@
const apiKey = "{{$.Site.Data.config.operandApiKey}}"
// Note: Currently, we use the REST API for Operand because of some unpkg/webpack issues.
// In the future, we'd like to use the SDK (https://github.com/operandinc/typescript-sdk).
// If someone knows how to do this w/o breaking the Operand typescript-sdk for npm users,
// please let Morgan (@morgallant) and/or (@_jzhao) know! <3

const apiKey = "{{$.Site.Data.config.search.operandApiKey}}"
const indexId = "{{$.Site.Data.config.search.operandIndexId}}"

function parseSearchResults(searchResults) {
return searchResults.matches.map((m) => ({
content: m.content,
title: searchResults.objects[m.objectId].properties.properties._title.text,
url: searchResults.objects[m.objectId].properties.properties._url.text,
}))
}

async function searchContents(query) {
const response = await fetch('https://prod.operand.ai/v3/search/objects', {
method: 'POST',
const result = await fetch("https://api.operand.ai/operand.v1.ObjectService/SearchWithin", {
method: "POST",
headers: {
'Content-Type': 'application/json',
Authorization: apiKey,
"Content-Type": "application/json",
Authorization: `${apiKey}`,
"Operand-Index-ID": `${indexId}`,
},
body: JSON.stringify({
query,
max: 10
query: query,
limit: 10,
}),
});
return (await response.json());
})
if (result.ok) {
return parseSearchResults(await result.json())
} else {
console.error(result)
}
}

function debounce(func, timeout = 200) {
let timer;
let timer
return (...args) => {
clearTimeout(timer)
timer = setTimeout(() => { func.apply(this, args); }, timeout)
};
timer = setTimeout(() => {
func.apply(this, args)
}, timeout)
}
}

registerHandlers(debounce((e) => {
term = e.target.value
if (term !== "") {
searchContents(term)
.then((res) => res.results.map(entry => ({
url: entry.object.properties.url,
content: entry.snippet,
title: entry.object.metadata.title
})
))
.then(results => displayResults(results))
}
}))
registerHandlers(
debounce((e) => {
let term = e.target.value
if (term !== "") {
searchContents(term).then((results) => displayResults(term, results))
}
}),
)
42 changes: 27 additions & 15 deletions assets/js/util.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,8 @@ const removeMarkdown = (
.replace(/^\s{0,3}>\s?/g, "")
.replace(/(^|\n)\s{0,3}>\s?/g, "\n\n")
.replace(/^\s{1,2}\[(.*?)\]: (\S+)( ".*?")?\s*$/g, "")
.replace(/([\*_]{1,3})(\S.*?\S{0,1})\1/g, "$2")
.replace(/([\*_]{1,3})(\S.*?\S{0,1})\1/g, "$2")
.replace(/([\*_]{1,3})(\S.*?\S?)\1/g, "$2")
.replace(/([\*_]{1,3})(\S.*?\S?)\1/g, "$2")
.replace(/(`{3,})(.*?)\1/gm, "$2")
.replace(/`(.+?)`/g, "$1")
.replace(/\n{2,}/g, "\n\n")
Expand All @@ -65,7 +65,7 @@ const highlight = (content, term) => {
.split(" ")
.slice(0, h)
return (
(before.length == h ? `...${before.join(" ")}` : before.join(" ")) +
(before.length === h ? `...${before.join(" ")}` : before.join(" ")) +
`<span class="search-highlight">${term}</span>` +
after.join(" ")
)
Expand Down Expand Up @@ -115,9 +115,11 @@ const resultToHTML = ({ url, title, content }) => {
}

const redir = (id, term) => {
// SPA navigation
const shouldTrim = PRODUCTION && SEARCH_ENABLED
const baseURLPrefix = shouldTrim ? "" : BASE_URL.replace(/\/$/g, "")
const urlString = `${baseURLPrefix}${id}#:~:text=${encodeURIComponent(term)}/`
window.Million.navigate(
new URL(`${BASE_URL.replace(/\/$/g, "")}${id}#:~:text=${encodeURIComponent(term)}/`),
new URL(urlString),
".singlePage",
)
closeSearch()
Expand Down Expand Up @@ -179,7 +181,7 @@ const registerHandlers = (onInputFn) => {
})
}

const displayResults = (finalResults, extractHighlight = false) => {
const displayResults = (term, finalResults, extractHighlight = false) => {
const results = document.getElementById("results-container")
if (finalResults.length === 0) {
results.innerHTML = `<button class="result-card">
Expand All @@ -189,18 +191,28 @@ const displayResults = (finalResults, extractHighlight = false) => {
} else {
results.innerHTML = finalResults
.map((result) => {
if (extractHighlight) {
return resultToHTML({
url: result.url,
title: highlight(result.title, term),
content: highlight(removeMarkdown(result.content), term)
})
} else {
return resultToHTML(result)
}
if (extractHighlight) {
return resultToHTML({
url: result.url,
title: highlight(result.title, term),
content: highlight(removeMarkdown(result.content), term)
})
} else {
return resultToHTML(result)
}
}
)
.join("\n")
if (LATEX_ENABLED) {
renderMathInElement(results, {
delimiters: [
{ left: '$$', right: '$$', display: false },
{ left: '$', right: '$', display: false },
],
throwOnError: false
})
}

const anchors = [...document.getElementsByClassName("result-card")]
anchors.forEach((anchor) => {
anchor.onclick = () => redir(anchor.id, term)
Expand Down
Loading

0 comments on commit e3be25f

Please sign in to comment.