본문 바로가기
Dev.Stuff

[Brackets] Markdown Preview Extension - Copy parsed markdown HTML to clipboard 기능 추가

by Devkin 2015. 4. 16.

Adobe에서 만든 Web design에 최적화된 Open source text editor인 Brackets는 기본 기능만으로도 에디터로 충실하나 사용하다 보면 세세하게 아쉬운 기능들이 하나 둘 생기기 시작한다. 오픈 소스 기반인만큼 Extension Manager를 통해 다른 개발자들이 만들어 배포하는 기능들을 설치하거나 직접 개발하여 설치 가능하다.

많이 사용하는 Extension중 하나인 Markdown Preview의 경우, 순수하게 작성한 Markdown의 HTML 미리보기 기능만 제공한다. Markdown을 지원하지 않는 블로그등에 글을 작성할 경우, Markdown을 파싱한 HTML을 Copy하거나 Export하는 기능이 필요하여 클립보드에 복사하는 기능을 기존 Markdown Preview에 추가.

Add UI

기존 Setting 다이얼로그에 복사 버튼을 하나 추가하고, _showSettings function에 click 이벤트 추가.

Add Button

templates/settings.html

<div>
  <span class="md-settings-label"></span>
  <button id="markdown-preview-copy-html">Copy HTML to clipboard</button>
</div>

Add Click Event

main.js

function _showSettings(e) {
    $settings.find("#markdown-preview-copy-html")
        .click(function () {
            // TODO : call 'copy' function
    });
}

Implementation To Use Node module

Brackets에서 빌트인 node.js 서버가 사이드 프로세스로 돌아가 Extension 개발 시 노드 코드 사용이 가능하기 때문에, clipboard copy 기능은 node-copy-paste 노드 모듈을 이용.

Create Domain

Brackets에서 노드 모듈은 domain을 통해 접근 가능하고, DomainManager를 통해 domain의 load/init 이 이뤄진다. DomainManagerregisterCommand()를 통해 클라이언트 사이드에 노출될 Function을 등록.

Coding Convention에 따라 노드 모듈은 /node/node_modules/ 디렉토리에 추가하고, domain 파일은 /node/디렉토리에 생성. node/clipboard_domain.js

function init(DomainManager) {
    if (!DomainManager.hasDomain("clipboard")) {
        DomainManager.registerDomain("clipboard", {major: 0, minor: 1});
    }

    DomainManager.registerCommand(
        "clipboard",    // domain name
        "copy",     // command name
        cmdCopy,    // command handler function
        false,          // this command is synchronous
        "copies to clipboard",
        [{name: "data", type: "string", description: "data to be copied"}],            
        []
    );

    DomainManager.registerCommand(
        "clipboard",       // domain name
        "load",    // command name
        cmdLoad,   // command handler function
        false,          // this command is synchronous
        "Loads clipboard",
        [],             // no parameters
        []
    );
}

Create Load Domain

NodeConnection을 통해 domain load.

lib/clipboard.js

function loadClipboardDomain() {
    var path = ExtensionUtils.getModulePath(module, '../node/clipboard_domain'),
        loadPromise = nodeConnection.loadDomains([path], true);
    loadPromise.fail(function (err) {
        console.error('[brackets-clipboard-node] failed to load domain.', err);
    });
    return loadPromise;
}

Add node-copy-paste module

앞서 언급한 Convention에 따라 /node/node_modules/ 디렉토리에 node-copy-paste 모듈 추가. npm install 사용 가능.

node-copy-paste original repo의 경우, Windows 환경에서 copy기능을 위해 clip을 사용하는데, 클립보드에 복사를 utf16-le로 하기 때문에 한글의 경우 붙여넣기 시 깨져서 출력된다. forked repo에 텍스트를 utf16-le로 인코딩하는 코드 추가.

if(process.platform === 'win32') {
    var utf16le = new Buffer(text, 'utf16le');
    child.stdin.end(utf16le);
}

Complete

main.js에서 clipboard.js에 노출된 function을 사용하여 node module function 사용.

var clipboard = require("lib/clipboard");
var parsedHTML = "";
...
function _loadDoc(doc, isReload) {
    ...
    bodyText = marked(docText);
    parsedHTML = bodyText;
    ...
}
...
function _copy(text) {
    return clipboard.copy(text);
}

clipboard.done(function () {
    console.log('[brackets-clipboard-node] node module loaded.');
});
...
function _showSettings(e) {
    ...
    $settings.find("#markdown-preview-copy-html")
        ...
        .click(function () {
            _copy(parsedHTML);
        });
    ...
}

Result

Github Repo : https://github.com/metalkin/MarkdownPreview

References

반응형

댓글