
Description
Obsidian์ Obsidian-auto-card-link Plugin์ ๋น์ทํ ํํ๋ก ๊ทธ๋ ค์ค ์ ์๋ Transfomer
- reference
- code ํ๊ทธ์์ cardlink lang์ ์ฐพ์ ํด๋น codeBlock์ Card ํํ๋ก ๋ณํ.
Required
- Obsidian-auto-card-link Plugin ํ์
- Obsidian์์ ํด๋น Plugin์ผ๋ก URL Card๋ฅผ ๋ง๋ค์์ ๋, ํด๋น ๊ฒฐ๊ณผ๋ฌผ์ ํ์ฑํ์ฌ Web์ ๊ทธ๋ ค์ค.
Source
JS
path: quartz/plugins/transformers/custom/cardLink.ts
import { QuartzTransformerPlugin } from "../../types"
import { visit } from "unist-util-visit"
export const CardLink: QuartzTransformerPlugin = () => {
return {
name: "CardLink",
markdownPlugins() {
return [
() => {
return (tree) => {
visit(tree, "code", (node) => {
if (node.lang === "cardlink") {
const cardData = parseCardData(node.value)
if (cardData) {
node.type = "html"
node.value = `
<div class="card-link">
<a href="${cardData.url}" target="_blank" rel="noopener noreferrer">
<div class="card-link-content">
<div class="card-image-container">
<img src="${cardData.image}" alt="${cardData.title}" class="card-image"/>
</div>
<div class="card-text">
<h3 class="card-title">${cardData.title}</h3>
<p class="card-description">${cardData.description}</p>
</div>
</div>
</a>
</div>
`
}
}
})
}
},
]
},
}
}
function parseCardData(cardlink: string) {
const cardData: { [key: string]: string } = {}
const lines = cardlink.split("\n")
for (const line of lines) {
const [key, ...valueParts] = line.split(":")
if (key && valueParts.length > 0) {
const value = valueParts.join(":").trim() // ๋๋จธ์ง ๊ฐ์ ๋ค์ ํฉ์ณ์ ์ฒ๋ฆฌ
cardData[key.trim()] = value
}
}
return {
url: cardData.url || "",
title: cardData.title || "",
description: cardData.description || "",
image: cardData.image || "",
}
}CSS
path: quartz/styles/custom/cardLink.scss
.card-link {
display: flex;
justify-content: center;
margin-top: 1rem;
margin-bottom: 1rem;
.internal {
display: none;
}
.external {
display: flex;
height: 100%;
padding: 0;
margin: 0;
}
/* hover ์ํ */
&:hover .card-link-content {
transform: scale(1.02); /* ํฌ๊ธฐ ํ๋ */
box-shadow: 0 8px 16px rgba(0, 0, 0, 0.2); /* ๊ทธ๋ฆผ์ ํจ๊ณผ */
transition: all 0.3s ease; /* ๋ถ๋๋ฌ์ด ์ ํ ํจ๊ณผ */
}
/* hover ์ํ */
&:hover .card-title {
transform: scale(1.02); /* ํฌ๊ธฐ ํ๋ */
transition: all 0.3s ease; /* ๋ถ๋๋ฌ์ด ์ ํ ํจ๊ณผ */
}
}
.card-link-content {
display: flex;
flex-direction: row; /* ๊ฐ๋ก ๋ฐฉํฅ์ผ๋ก ๋ ์ด์์ ์ค์ */
align-items: center; /* ์ธ๋ก ๊ฐ์ด๋ฐ ์ ๋ ฌ */
border: 1px solid #ddd;
border-radius: 8px;
overflow: hidden;
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
width: 100%;
height: 10rem;
box-sizing: border-box; /* padding, border ํฌํจํ์ฌ ๊ณ์ฐ */
transition: all 0.3s ease; /* ๋ถ๋๋ฌ์ด ์ ํ ํจ๊ณผ */
}
.card-image-container {
width: 15rem; /* ์ด๋ฏธ์ง ๋๋น */
height: 100%; /* ์ด๋ฏธ์ง ๋์ด */
border-right: 1px solid #ddd; /* ์ด๋ฏธ์ง์ ํ
์คํธ ์ฌ์ด์ ๊ตฌ๋ถ์ */
padding: 0;
margin: 0;
}
.card-image {
width: 100%; /* ๋ถ๋ชจ์ ํฌ๊ธฐ๋ฅผ 100%๋ก ๋ง์ถ๊ธฐ */
height: 100%; /* ๋ถ๋ชจ์ ํฌ๊ธฐ๋ฅผ 100%๋ก ๋ง์ถ๊ธฐ */
object-fit: fill; /* ์ด๋ฏธ์ง๊ฐ ์์ญ์ ๋ง๊ฒ ์๋ฅด๊ธฐ */
display: block; /* img ์์๊ฐ block์ผ๋ก ์ทจ๊ธ๋์ด ๋ถ๋ชจ ์์ญ์ ๋ง๊ฒ ํ์ฅ๋จ */
margin: 0;
}
.card-text {
padding: 15px;
flex-grow: 1; /* ํ
์คํธ ์์ญ์ด ๋จ์ ๊ณต๊ฐ์ ์ฐจ์งํ๋๋ก ์ค์ */
}
.card-title {
font-size: 20px; /* ์ ๋ชฉ ํฌ๊ธฐ */
font-weight: bold;
margin-bottom: 10px;
color: #333;
}
.card-description {
font-size: 14px;
color: #555;
line-height: 1.6;
overflow: hidden;
text-overflow: ellipsis;
display: -webkit-box;
-webkit-line-clamp: 3; /* ์ต๋ 3์ค๋ก ํ
์คํธ ์๋ฅด๊ธฐ */
-webkit-box-orient: vertical;
}
.card-content a {
text-decoration: none;
color: inherit;
}
.card-content a:hover {
text-decoration: underline;
}