관리 메뉴

세줄코딩

marked 활용하여 html 가이드 파일 만들기. 본문

Programming language/javascript

marked 활용하여 html 가이드 파일 만들기.

개발 hello-world 2019.09.03 15:01

README.md

요새는 대체로 작업할 때 git을 많이 쓰게 된다.

그러다 보니 readme.md 파일에 많은 정보를 기재하고 그것을 가지고 가이드로써 전달한다.

예전처럼 산출물에 대한 가이드를 html table 코딩하여 전달하지 않게 되었다.

물론 Task list는 테이블 형식이긴 하다.

하지만 안타깝게도 그러한 추세에도 마크다운 형식의 파일을 원하지 않는 곳도 있고

하기에 결국 ppt파일이나 html 로 작업목록을 작성해 전달해야 할때가 있다.

그렇다고 이러한 방식을 접을 순 없다......

찾아보니 역시역시!!!!!!!!!!!!!!!!!!!!!!!

markdown -> html 변환작업을 해주는 라이브러리가 있으니 그것은 바로 markedjs

백문이 불여일견.

작성된 README.md 파일을 같은 경로상에 준비하고 아래와 같이 작업했다.

( html을 꾸며주는 CSS 파일도 알아서 별로도 준비..... )

docs.html

<head>
 ............중략......................
    <script src="./dist/vendors/jquery-1.10.2.min.js"></script>
    <script src="https://unpkg.com/axios/dist/axios.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/marked/marked.min.js"></script>
</head>
<body>

<div class="container"></div>

javascript( docs.html 맨하단에 위치 )

/**
* marked 연동
*/
axios.get('./README.md')
  .then( function(res){
  $('.container').append( marked(res.data) )
  }).catch(function(err){
  // console.log( err )
});

뙁 !!!! 하고 나의 README.md 가 html 로 변신

~

근데 한가지 문제가 생긴다.

생성시킨 docs.html 파일을 단독으로 실행시 Chrome 에서 CORS 정책으로 걸고 넘어져서

내용이 보이지 않게되는 대참사가 벌어진다.

물론 IDE로 실행했을 때는 잘 실행되서 보인다.

문제는 클라이언트가 html파일을 단독으로 실행했을때 안보인다는 것이다.

그래서 아래와 같이 gulp로 해결해 봤다.

디펜던시 파일( gulp 실행시 관련 파일 )은 아래와 같다.

package.json

{
 ......중략........
  "devDependencies": {
    "@babel/core": "^7.5.5",
    "@babel/preset-env": "^7.5.5",
    "@babel/register": "^7.5.5",
    "del": "^5.1.0",
    "gulp": "^4.0.2",
    "gulp-babel": "^8.0.0",
    "gulp-cheerio": "^0.6.3",
    "gulp-markdown": "^5.0.0",
    "gulp-rename": "^1.4.0"
  }
}

gulpfile.babel.js

import gulp from 'gulp';
import del from 'del';
import markdown from 'gulp-markdown';
import cheerio from 'gulp-cheerio';
import rename from 'gulp-rename';

export const clean = () => del([ 'docs.html' ]);

export function markdownToHTML() {
    return gulp.src('./README.md')
        .pipe( markdown() )
        .pipe( cheerio( ( $, file )=>{
            let titleTxt = '타이틀';
            $.root().empty();
            $.root().append(`<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>${titleTxt}</title>
<link rel="stylesheet" href="docs/base.css">
<style>
    body{font-size:14px;}
    blockquote>p{font-size:16px;}
</style>
<script src="client/assets/vendors/jquery/jquery-1.9.1.min.js"></script>
</head><body><div class="container"></div>
</body></html>`);
            $('.container').html( file.contents.toString() )
        } ) )
        .pipe(rename('docs.html'))
        .pipe( gulp.dest('./') )
}

const build = gulp.series( clean, markdownToHTML );

export default build;

터미널에서 gulp 하고 나면 docs.html 파일이 생성되고.....

위의 코드처럼 대충 저렇게 상대경로로 불러들이는 css,js 파일도 잘 로드가 된다.

 

 

아래부터는 고민했던 후기글 이랄까~~~~

 

............................

 

 

여튼 제일 고민했던 부분은 markdown에서 html파일로 변환 시 의도대로 예쁘게 잘 꾸며져야 하는 것...

즉 html파일 내용을 꾸며줄 css , js로 중무장을 시키는 것이였다.

 

근데 제일 큰 문제가 gulp-markdown 모듈에서 그냥 markdown() 실행하면 html/head/body 없이 그냥 

마크다운에 입력했던 글에 대한 각각의 태그들만 만들어진다. 

아래 코드처럼 말이다.......머랄까 접시도 데코도 없이 음식만 덩그러니 있는 느낌이랄까? 

 

<h2>Image &#xBC0F; Font &#xAD6C;&#xC870;</h2>
<table>
<thead>
<tr>
<th align="left">Directory</th>
<th align="left">Discription</th>
</tr>
</thead>
<tbody><tr>
<td align="left"></td>
<td align="left">&#xC774;&#xBBF8;&#xC9C0; &#xACBD;&#xB85C;</td>
</tr>
<tr>
<td align="left"></td>
<td align="left">&#xACF5;&#xD1B5;&#xC694;&#xC18C; &#xC774;&#xBBF8;&#xC9C0; &#xACBD;&#xB85C;</td>
</tr>
<tr>
<td align="left"></td>
<td align="left">&#xACF5;&#xD1B5; &#xD3F0;&#xD2B8; &#xACBD;&#xB85C;</td>
</tr>
</tbody></table>
<blockquote>
<p>note :</p>
<ul>
<li>font&#xB294; <strong>&#xB098;&#xB214;&#xBC14;&#xB978;&#xACE0;&#xB515;(&#xAD6D;&#xBB38;)</strong></li>
</ul>
</blockquote>
<hr>
<table>

근데 이걸 어떻게 온전한 html 파일로 만들지?????????????????????? 

꼬리에 꼬리를 무는 고민과 무한한 삽질 끝에 

gulp-cheerio모듈( gulp에서 jquery selector문법 지원 )로 해결.

 

cheerio( ( $, file ) => { ~~~~ } )

 

첫번째 매개변수 $는 jquery처럼 $(선택자) 처럼 이용할 수 있다.

두번째 매개변수는 변환되서 들어온 gulp 파일객체이다.

 

중요한 부분은 저 걸프 파일객체인데 저 파일 객체를 이용할 줄을 몰라서 엄청 해멨다.

gulp-markdown 모듈을 뜯어보니 적용되는 부분이 아래와 같았다.

'use strict';
const {promisify} = require('util');
const through = require('through2');
const marked = require('marked');
const PluginError = require('plugin-error');

const pMarked = promisify(marked);

module.exports = options => {
	return through.obj(async (file, encoding, callback) => {
		if (file.isNull()) {
			callback(null, file);
			return;
		}

		if (file.isStream()) {
			callback(new PluginError('gulp-markdown', 'Streaming not supported'));
			return;
		}

		try {
			const data = await pMarked(file.contents.toString(), options);
			file.contents = Buffer.from(data);
			file.extname = '.html';
			callback(null, file);
		} catch (error) {
			callback(new PluginError('gulp-markdown', error, {fileName: file.path}));
		}
	});
};

module.exports.marked = marked;

머 전부를 이해할 필요는 없을 거 같았고 걍 핵심적인 부분만 보면 될 거 같았다.( 그래야만 정신건강이 편할거 같다는 느낌이~ )

 

그래서 핵심이 먼데???????

 

아무래도 실질적으로 실행되는 부분인 try 부분이다. ( 맞겠지? )

 

const data = await pMarked(file.contents.toString(), options);
file.contents = Buffer.from(data);
file.extname = '.html';
callback(null, file);

 

nodejs의 Buffer는 패스~ ( 어렵 ㅠㅠ  )

핵심이 file.contents.toString() 라고 생각되어

console을 찍어보니 와우~ 정답~~~~

 

글서 아래와 같이 컨테이너 하나 만들어 놓고 그 컨테이너에 변환된 html알맹이들을 쏵 채웠다.

$('.container').html( file.contents.toString() )

 

마지막으로 gulp-rename 모듈을 이용하여 파일 이름을 입맛에 맞게 변경시키고 

gulp.dest() 로 원하는 경로에 파일 배출..

 

마지막으로 터미널에서 명령어 gulp 뙁 치고나니 docs.html  생성

실행해 보니 이쁘게 변환된 모습을 볼 수 있었다.

 

나름 만족 ~

( 코드는 겁나 짧은데.......저거 안되서리 반나절을 삽질~ㅠㅠ )

0 Comments
댓글쓰기 폼