728x90
마크다운이란?
<h1>안녕하세요!</h1>
<p>이것은 <strong>굵은 글씨</strong>와 <em>기울임꼴</em> 입니다.</p>
<ul>
<li>목록 아이템</li>
<li>또 다른 아이템</li>
</ul>
보시다시피 HTML은 태그가 많아 다소 번거롭고, 글 자체의 가독성을 해치기도 합니다. 글을 쓰기 위한 목적보다는 문서의 구조를 정의하는 데 더 초점이 맞춰져 있었죠.
이런 불편함을 해소하기 위해 2004년 존 그루버(John Gruber)는 "쉽게 쓰고, 쉽게 읽히고, 쉽게 HTML로 변환되는" 마크다운 언어를 만들었습니다.
쉬운 문법: #, *, - 와 같이 간단한 기호 몇 가지만으로도 서식을 표현할 수 있습니다.
# 제목 → <h1>제목</h1>
**굵게** → <strong>굵게</strong>
* 목록 → <ul><li>목록</li></ul>
높은 가독성: 마크다운 문법 자체가 읽기 쉽게 디자인되어 있습니다. HTML처럼 복잡한 태그 없이도 글의 구조를 파악하기 용이합니다.
플랫폼 호환성: 텍스트 파일이면 어디서든 작성하고 읽을 수 있으며, 다양한 도구를 통해 HTML, PDF 등 여러 형식으로 쉽게 변환할 수 있습니다.
간편한 협업: 글쓰기에 집중할 수 있어 블로그, README 파일, 개발 문서, 메시지 등 다양한 환경에서 널리 사용됩니다. GitHub의 README 파일이 대표적인 예시 입니다.
import React, { useState, useEffect, useRef } from 'react'; // useRef 추가
import './App.css';
import { marked } from 'marked';
function App() {
const [markdown, setMarkdown] = useState(`
# 안녕하세요!
이것은 **마크다운 프리뷰어** 입니다.
## 사용법
1. 왼쪽 텍스트 영역에 마크다운을 입력하세요.
2. 오른쪽 영역에서 실시간 미리보기를 확인하세요.
### 코드 예시
\`\`\`javascript
function greet() {
console.log("Hello, Markdown!");
}
greet();
\`\`\`
- 목록 아이템 1
- 목록 아이템 2
> 인용 블록입니다.
`);
// textarea 엘리먼트에 접근하기 위한 ref
const editorRef = useRef(null);
const [editorHeight, setEditorHeight] = useState(0); // 초기 높이를 0으로 설정
useEffect(() => {
const updateHeight = () => {
if (editorRef.current) {
// 실제 textarea 엘리먼트의 높이를 viewport 높이에 맞춥니다.
// padding 등 고려하여 약간의 여유를 줄 수도 있습니다.
// 여기서는 간단하게 viewport 높이의 85%를 사용합니다.
setEditorHeight(window.innerHeight * 0.85);
}
};
// 컴포넌트가 마운트된 후에 최초 한 번 실행하여 초기 높이 설정
updateHeight();
// 창 크기 변경 이벤트 리스너 추가
window.addEventListener('resize', updateHeight);
// 컴포넌트가 언마운트될 때 이벤트 리스너 제거
return () => {
window.removeEventListener('resize', updateHeight);
};
}, []); // 컴포넌트가 처음 마운트될 때만 실행
// textarea에 동적으로 스타일 적용
const textareaStyle = {
height: `${editorHeight}px`,
};
return (
<div className="app-container">
<div className="editor-pane">
<textarea
id="editor"
ref={editorRef} // textarea 엘리먼트에 ref 연결
value={markdown}
onChange={(e) => setMarkdown(e.target.value)}
style={textareaStyle}
></textarea>
</div>
<div className="preview-pane">
<div
id="preview"
dangerouslySetInnerHTML={{ __html: marked(markdown) }}
></div>
</div>
</div>
);
}
export default App;
body {
margin: 0;
font-family: sans-serif;
background-color: #f0f0f0;
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
overflow: hidden; /* 스크롤 방지 */
}
.app-container {
display: flex;
width: 90vw;
height: 85vh;
background-color: #fff;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
border-radius: 8px;
overflow: hidden;
}
.editor-pane,
.preview-pane {
flex: 1;
padding: 20px;
overflow-y: auto; /* 내용이 길어지면 스크롤 */
height: 100%;
box-sizing: border-box;
}
.editor-pane {
border-right: 1px solid #ccc;
resize: horizontal; /* 사용자가 너비 조절 가능하게 */
overflow: hidden; /* textarea 자체가 resize 되므로 필요 */
}
.editor-pane textarea {
width: 100%;
height: 100%;
border: none;
outline: none;
font-size: 16px;
line-height: 1.5;
resize: none; /* textarea 자체 resize는 비활성화 (부모 pane이 resize) */
padding: 10px;
box-sizing: border-box;
color: #333;
background-color: #f9f9f9;
}
.preview-pane {
background-color: #fff;
}
.preview-pane h1,
.preview-pane h2,
.preview-pane h3 {
margin-top: 1.2em;
margin-bottom: 0.5em;
}
.preview-pane h1 {
font-size: 2em;
border-bottom: 2px solid #ccc;
padding-bottom: 0.3em;
}
.preview-pane h2 {
font-size: 1.5em;
border-bottom: 1px solid #eee;
}
.preview-pane code {
font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace;
background-color: #f0f0f0;
padding: 2px 4px;
border-radius: 3px;
}
.preview-pane pre {
background-color: #f0f0f0;
padding: 10px;
border-radius: 5px;
overflow-x: auto; /* 긴 코드 줄 스크롤 */
}
.preview-pane pre code {
background-color: transparent;
padding: 0;
}
.preview-pane blockquote {
border-left: 3px solid #ccc;
padding-left: 10px;
color: #666;
margin-left: 0;
}
'React' 카테고리의 다른 글
[React] 텍스트 입력 시 자동으로 필드 추가하기 (Material UI 활용) (1) | 2025.07.12 |
---|---|
[React] Hook 함수형 컴포넌트 (2) | 2025.06.30 |
[React] useReducer 사용하여 간단한 계산기 만들기 (0) | 2025.06.16 |
[React] Todo-List 만들기 (2) | 2025.06.09 |
[React] 좋아요 버튼 클릭 시 확인 모달 띄우기 (0) | 2025.06.04 |