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

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

cadLink.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;  
}