#in 에 마크다운을 작성하게 되면 #out에 htm로 자동 변환되는 상황에서 검색창을 입력하여 내가 원하는 단어를 찾는 간단한 Javascript이용하여 쉽게 만들 수 있을거라고 생각하였다. 하지만 만들면서 여러 문제점이 발생하였다. 화면에 표출되는 #out 부분의 제목 부분이 #, ##, ### 과 같이 해시를 사용하여 이상한 반복이 발생하는 경우도 있고 또는 #out 부분이 없어지거나 #in 마크다운 내용으로 바뀌는 경우등 많은 문제점들이 발생하였다.
기본 HTML 틀
<div id="in">
<form>
<textarea id="code" contenteditable="true">
# News Title 1
## Subheading 1
### Subheading 1.1
# Another topic
</textarea>
</form>
</div>
<div id="out" class="markdown-body"></div>
<div id="tree"></div>
<div id="search-box">
<input type="text" id="search-input" placeholder="Search">
</div>
이전 자동 목록 만들기와 구조는 유사하다.
전체코드
<div id="in">
<form>
<textarea id="code" contenteditable="true">
# News Title 1
## Subheading 1
### Subheading 1.1
# Another topic
</textarea>
</form>
</div>
<div id="out" class="markdown-body"></div>
<div id="tree"></div>
<script>
// Markdown을 HTML로 변환하는 함수
function convertMarkdownToHTML() {
var markdownText = document.getElementById('code').value;
var converter = new showdown.Converter();
var htmlText = converter.makeHtml(markdownText);
return htmlText;
}
// #in의 textarea 내용이 변경될 때마다 호출
document.getElementById('code').addEventListener('input', function () {
var htmlText = convertMarkdownToHTML();
document.getElementById('out').innerHTML = htmlText;
});
var lastSearchQuery = '';
var lastMatchedIndices = [];
var currentIndex = -1;
function clearHighlight() {
var outputDiv = document.getElementById('out');
var highlightedHTML = outputDiv.innerHTML;
highlightedHTML = highlightedHTML.replace(/<mark class="highlight">([^<]+)<\/mark>/gi, '$1');
outputDiv.innerHTML = highlightedHTML;
}
function searchAndHighlight() {
var query = document.getElementById('search-input').value;
var outputDiv = document.getElementById('out');
var textToSearch = outputDiv.innerText; // HTML 태그를 제외한 텍스트만 검색
var regex = new RegExp(query, 'gi');
var matches = Array.from(textToSearch.matchAll(regex));
// 검색을 시작할 때 이전에 강조된 부분을 초기화
clearHighlight();
// 검색 결과 저장
lastMatchedIndices = matches.map(function (match) {
return match.index;
});
// 다음 일치 항목 찾기
currentIndex = (currentIndex + 1) % lastMatchedIndices.length;
var nextIndex = lastMatchedIndices[currentIndex];
// 일치 항목을 강조 표시
var highlightedHTML = outputDiv.innerHTML;
if (nextIndex !== undefined) {
var matchText = matches[currentIndex][0];
highlightedHTML = highlightedHTML.replace(
new RegExp('(' + matchText + ')(?![^<]*>)', 'gi'),
'<mark class="highlight">$1</mark>'
);
// 스크롤 위치 조정
var newScrollPosition = nextIndex;
outputDiv.scrollTop = newScrollPosition;
}
outputDiv.innerHTML = highlightedHTML;
}
document.getElementById('search-input').addEventListener('keydown', function (event) {
if (event.key === 'Enter') {
event.preventDefault();
searchAndHighlight();
}
});
// 초기에 Markdown을 HTML로 변환하여 #out에 표시
var initialHTML = convertMarkdownToHTML();
document.getElementById('out').innerHTML = initialHTML;
</script>

세부코드 설명
Markdown을 HTML로 변환하는 함수:
// Markdown을 HTML로 변환하는 함수
function convertMarkdownToHTML() {
var markdownText = document.getElementById('code').value;
var converter = new showdown.Converter();
var htmlText = converter.makeHtml(markdownText);
return htmlText;
}
이 함수는 showdown 라이브러리를 사용하여 Markdown 형식의 텍스트를 HTML로 변환한다.
#code 요소의 값을 가져와 Markdown을 HTML로 변환하고 결과를 반환한다.
Markdown 입력 내용이 변경될 때 HTML 업데이트:
// #in의 textarea 내용이 변경될 때마다 호출
document.getElementById('code').addEventListener('input', function () {
var htmlText = convertMarkdownToHTML();
document.getElementById('out').innerHTML = htmlText;
});
#code 요소의 내용이 변경되면, convertMarkdownToHTML 함수를 호출하여 Markdown을 HTML로 변환하고, 변환된 HTML을 #out 요소에 업데이트한다.
검색 및 강조 표시 기능:
var lastSearchQuery = '';
var lastMatchedIndices = [];
var currentIndex = -1;
// ...
function searchAndHighlight() {
// ...
// 검색을 시작할 때 이전에 강조된 부분을 초기화
clearHighlight();
// 검색 결과 저장
lastMatchedIndices = matches.map(function (match) {
return match.index;
});
// ...
// 일치 항목을 강조 표시
var highlightedHTML = outputDiv.innerHTML;
if (nextIndex !== undefined) {
// ...
}
outputDiv.innerHTML = highlightedHTML;
}
// ...
// 검색 입력 필드에서 Enter 키를 누를 때 처리
document.getElementById('search-input').addEventListener('keydown', function (event) {
if (event.key === 'Enter') {
event.preventDefault();
searchAndHighlight();
}
});
이 부분은 사용자가 검색어를 입력하고 Enter 키를 누를 때 검색 및 강조 표시를 수행하는 기능이다.
clearHighlight 함수를 사용하여 이전에 강조된 부분을 제거.
검색 결과를 찾고, 일치하는 항목을 강조 표시한다.
검색 결과는 lastSearchQuery, lastMatchedIndices, currentIndex 변수를 사용하여 관리된다.
초기 변환 및 HTML 출력
// 초기에 Markdown을 HTML로 변환하여 #out에 표시
var initialHTML = convertMarkdownToHTML();
document.getElementById('out').innerHTML = initialHTML;
페이지가 로드될 때 초기 Markdown을 HTML로 변환하고, 변환된 HTML을 #out 요소에 출력한다.
솔직히 그냥 구글에 돌아다니는 코드 복붙하면 10분이면 끝나겠다고 생각하였지만 바로 내용을 찾는게 아닌 숨겨진? 내용이나 좀 얽힌 내용이 많아 너무 많은 삽질을하였다....
'업무 기록 > WEB' 카테고리의 다른 글
프로젝트 요약 정리 SpringBoot 와 Node ExpressJs (1) | 2023.10.21 |
---|---|
Markdown Viewer for Multiple Documents and Loader(배열이용) 랜더링 (0) | 2023.09.11 |
자바스크립트 이용한 마크다운 자동 목차 만들기 (0) | 2023.09.07 |
JSP 모달창 버튼 출력 조건 (0) | 2023.08.30 |
Node js, Express js - res.render 렌더링 (0) | 2023.08.01 |