Description

contents 내부의 code를 보기 좋게 만듦.

  • CodeBlock
inlineCodeSample
``\`{langauge} title="{codeTitle}" fold
{code}
``\`
  • InlineCode
inlineCodeSample
`{code{:langauge}}`
  • Icon
    • Langauge & Icon 매칭:
      • 일반적인 케이스들은 이름으로 Icon을 바로 매칭시켜줌.
      • 예외케이스는 customLanguageParser()를 통해 변환해줌.
        • sql azureasqldatabase
        • log powershell
        • sh bash
    • 출처:

Required

none.

Source

JS

path: quartz/components/scripts/custom/syntax.inline.ts

syntax.inline.ts
const customLanguageParser = (language: string | null) => {  
  if (!language) return "powershell"  
  
  if (language === "sql") return "azuresqldatabase"  
  if (language === "log") return "powershell"  
  if (language === "sh") return "bash"  
  
  return language  
}  
  
document.addEventListener("nav", function () {  
  document.querySelectorAll("figure[data-rehype-pretty-code-figure]").forEach((figure) => {  
    let figcaption = figure.querySelector("figcaption")  
  
    // if figcaption none -> add figcaption  
    if (!figcaption) {  
      figcaption = document.createElement("figcaption")  
      figcaption.setAttribute("data-rehype-pretty-code-title", "")  
      figcaption.textContent = "code"  
      figure.insertBefore(figcaption, figure.firstChild)  
    }  
  
    // parse language  
    const language = customLanguageParser(figcaption.getAttribute("data-language"))  
  
    let titleWrapper = document.createElement("div")  
    titleWrapper.className = "code-title-wrapper"  
  
    let title = document.createElement("span")  
    title.textContent = figcaption.textContent  
    figcaption.textContent = ""  
  
    // add language Icon  
    let languageIcon = document.createElement("i")  
    languageIcon.className = `devicon-${language}-plain colored`  
  
    titleWrapper.insertBefore(title, titleWrapper.firstChild)  
  
    titleWrapper.insertBefore(languageIcon, titleWrapper.firstChild)  
  
    figcaption.insertBefore(titleWrapper, figcaption.firstChild)  
  
    // add toggle Button  
    let toggleButton = document.createElement("button")  
    toggleButton.className = "fold-button"  
    toggleButton.textContent = "OPEN"  
    let pre = figure.querySelector("pre")  
    if (!pre) return  
    pre.style.display = "none"  
    figcaption.onclick = function () {  
      if (pre.style.display === "none") {  
        pre.style.display = "block"  
        toggleButton.textContent = "FOLD"  
      } else {  
        pre.style.display = "none"  
        toggleButton.textContent = "OPEN"  
      }  
    }  
  
    figcaption.appendChild(toggleButton)  
  })  
})  
  
document.addEventListener("nav", function () {  
  document.querySelectorAll("span[data-rehype-pretty-code-figure]").forEach((span) => {  
    const code= span.querySelector("code")  
    if (!code) return  
  
    // parse language  
    const language = customLanguageParser(code.getAttribute("data-language"))  
  
    let languageIcon = document.createElement("i")  
    languageIcon.className = `devicon-${language}-plain colored`  
  
    code.insertBefore(languageIcon,code.firstChild)  
  })  
})

CSS

path: quartz/styles/custom/syntax.scss

syntax.scss
figure[data-rehype-pretty-code-figure] {  
  margin: 0;  
  border-radius: 5px;  
  position: relative;  
  line-height: 1.6rem;  
  position: relative;  
  background: linear-gradient(to right, #8fbc8f 40%, var(--gray) 80%);  
  
  .clipboard-button {  
    background-color: #eeeeee;  
    border: none;  
  }  
  & > [data-rehype-pretty-code-title] {  
    margin: 10px;  
    font-family: var(--codeFont);  
    font-size: 0.9rem;  
    width: fit-content;  
    border-radius: 5px;  
    color: var(--gray);  
  }  
  
  & > pre {  
    padding: 0;  
    border: none;  
    margin-top: -0.5rem;  
  }  
}  
  
pre {  
  font-family: var(--codeFont);  
  padding: 0 0.5rem;  
  overflow-x: auto;  
  border: 1px solid var(--lightgray);  
  position: relative;  
  
  &:has(> code.mermaid) {  
    border: none;  
  }  
  
  code[data-line-numbers] {  
    counter-reset: line;  
  }  
  
  code[data-line-numbers] > [data-line]::before {  
    counter-increment: line;  
    content: counter(line);  
  
    /* Other styling */  
    display: inline-block;  
    width: 0.75rem;  
    margin-right: 2rem;  
    text-align: right;  
    color: gray;  
  }  
  
  code[data-line-numbers-max-digits="2"] > [data-line]::before {  
    width: 1.25rem;  
  }  
  
  code[data-line-numbers-max-digits="3"] > [data-line]::before {  
    width: 1.75rem;  
  }  
  
  code[data-line-numbers-max-digits="4"] > [data-line]::before {  
    width: 2.25rem;  
  }  
  
  & > code {  
    background: none;  
    font-size: 0.85rem;  
    counter-reset: line;  
    counter-increment: line 0;  
    display: grid;  
    padding: 0.5rem 0;  
    overflow-x: auto;  
  
    & [data-highlighted-chars] {  
      background-color: var(--highlight);  
      border-radius: 5px;  
    }  
  
    & > [data-line] {  
      padding: 0 0.25rem;  
      box-sizing: border-box;  
      border-left: 3px solid transparent;  
  
      &[data-highlighted-line] {  
        background-color: var(--highlight);  
        border-left: 3px solid var(--secondary);  
      }  
  
      &::before {  
        content: counter(line);  
        counter-increment: line;  
        width: 1rem;  
        margin-right: 1rem;  
        display: inline-block;  
        text-align: right;  
        color: rgba(115, 138, 148, 0.6);  
      }  
    }  
  
    &[data-line-numbers-max-digits="2"] > [data-line]::before {  
      width: 2rem;  
    }  
  
    &[data-line-numbers-max-digits="3"] > [data-line]::before {  
      width: 3rem;  
    }  
  }  
}  
  
code {  
  font-size: 0.9em;  
  color: var(--dark);  
  font-family: var(--codeFont);  
  border-radius: 5px;  
  padding: 0.1rem 0.2rem;  
  background: var(--lightgray);  
}  
  
figcaption {  
  font-family: var(--bodyFont) !important;  
  display: flex;  
  justify-content: space-between;  
  align-items: center;  
  width: auto !important;  
  
  i {  
    margin-right: 5px;  
  }  
}  
  
figure[data-rehype-pretty-code-figure] {  
  code {  
    border-radius: 0;  
    border: none;  
  }  
}  
  
.code-title-wrapper {  
  display: flex;  
  margin-top: 5px;  
  margin-bottom: 5px;  
  align-items: center;  
  color: darkgreen;  
  font-weight: bold;  
}  
  
.fold-button {  
  margin-left: auto;  
  color: darkgreen;  
  border: none;  
  background-color: rgba(0, 0, 0, 0);  
  font-weight: bold;  
}  
  
.fold-button {  
  transition: transform 0.2s ease-in-out;  
}  
  
.fold-button:hover {  
  transform: scale(1.1);  
}