✅ 추가 implementation 'org.commonmark:commonmark:0.21.0'
import org.commonmark.node.Node;
import org.commonmark.parser.Parser;
import org.commonmark.renderer.html.HtmlRenderer;
import org.springframework.stereotype.Component;
@Component
public class CommonUtil {
public String markdown(String markdown) {
Parser parser = Parser.builder().build();
Node document = parser.parse(markdown);
HtmlRenderer renderer = HtmlRenderer.builder().build();
return renderer.render(document);
}
}
CommonUtil 클래스에는 markdown 메서드를 생성했다. markdown 메서드는 마크다운 텍스트를 HTML 문서로 변환하여 리턴한다. 즉, 마크다운 문법이 적용된 일반 텍스트를 변환된(소스코드, 기울이기, 굵게, 링크 등) HTML로 리턴한다.
✅ 수정 전
<!-- 질문 -->
<div class="card my-3">
<h2 class="card-header bg-info text-white border-bottom p-3" th:text="${question.subject}"></h2>
<div class="card-body bg-light">
1 <div class="card-text p-2" style="white-space: pre-line;" th:text="${question.content}"></div>
<div class="d-flex justify-content-end">
(... 생략 ...)
<!-- 답변 반복 시작 -->
<div class="list-group list-group-flush" th:each="answer, loop : ${question.answerList}">
<a th:id="|answer_${answer.id}|"></a>
<div class="list-group-item bg-light">
2 <h8 class="card-text" style="white-space: pre-line;" th:text="${answer.content}"></h8>
<div class="badge bg-primary text-white" th:text="${loop.count}"></div>
(... 생략 ...)
✅ 수정 후
<!-- 질문 -->
<div class="card my-3">
<h2 class="card-header bg-info text-white border-bottom p-3" th:text="${question.subject}"></h2>
<div class="card-body bg-light">
1 <div class="card-text p-2" th:utext="${@commonUtil.markdown(question.content)}"></div>
<div class="d-flex justify-content-end">
(... 생략 ...)
<!-- 답변 반복 시작 -->
<div class="list-group list-group-flush" th:each="answer, loop : ${question.answerList}">
<a th:id="|answer_${answer.id}|"></a>
<div class="list-group-item bg-light">
2 <div class="card-text" style="white-space: pre-line;" th:text="${answer.content}"></div>
<div class="badge bg-primary text-white" th:text="${loop.count}"></div>
(... 생략 ...)
✅ 수정 전 : 1 <div class="card-text p-2" style="white-space: pre-line;" th:text="${question.content}"></div>
✅ 수정 후 : 1 <div class="card-text p-2" th:utext="${@commonUtil.markdown(question.content)}"></div>
✅ 수정 전 : 2 <div class="card-text" style="white-space: pre-line;" th:text="${answer.content}"></div>
✅ 수정 후 : 2 <div class="card-text" th:utext="${@commonUtil.markdown(answer.content)}"></div>
줄 바꿈을 표시하기 위해 사용했던 기존의 style="white-space: pre-line;"
스타일은 삭제하고 ${@commonUtil.markdown(question.content)}
와 같이 마크다운 컴포넌트를 적용했다.
why?
th:text
->th:utext
사용한 이유?
th:utext
대신th:text
를 사용할 경우 HTML의 태그들이 이스케이프(escape)처리되어 태그들이 그대로 화면에 보인다. 마크다운으로 변환된 HTML 문서를 제대로 표시하려면 이스케이프 처리를 하지 않고 출력하는th:utext
를 사용해야 한다.
마크다운 형식으로 출력된다!
✅ 컴포넌트에서 마크다운 메소드 추가
✅ 타임리프 th:utext 속성
✅ 컴포넌트 공부
✅ 타임리프 속성 공부