카테고리 없음

브라우저에서 한글 표 정보 수정하기

hyuckkim 2025. 1. 11. 14:28


참고로 여기서 한글은 진짜 이 한글 프로그램이 맞다.

 

어제 연등 때 취사반 애들이랑 얘기하다 들었던 이야기인데, 매일 한글 파일로 이루어진 식단 내용을 수정해야 한다고 한다. 그러면서 그 과정을 자동화해 줄 수 있는지 물어봤었는데, 난 프로그래머니까 일단 된다고 했다.

진짜 되는지 알아보려고 오늘 확인해본 것들을 올린다.

 

우선 한글 파일에 무지개색 표 하나를 만들고 시작한다.

 

표를 복사한 다음, Clipboard Inspector에 들어가서 텍스트 데이터를 확인해 보았다.

표 안의 텍스트가 text/plain으로 있었고,

 

hide_bottom

엄청 긴 text/html 데이터,

 

hide_bottom

그리고 엄청 긴 text/rtf 데이터가 있었다.

 

그냥 한글에서 복사하고 붙여넣으면, 별다른 문제 없이 잘 붙여넣어진다. 즉 내가 데이터를 임의로 생성해도 이 셋만 있으면 한글에서 정상적으로 붙여넣어질 것이다.

 

그러면 html 파일을 어떻게 구성해야 할지 감이 왔다.

<!DOCTYPE html>

<textarea placeholder="text/plain"></textarea>
<textarea placeholder="text/html"></textarea>
<textarea placeholder="text/rtf"></textarea>
<button>복사!</button>
<script>
document.querySelector('button').addEventListener('click', e => {
    const item = {};
    for (const e of document.querySelectorAll('textarea')) {
        item[e.placeholder] = new Blob([e.value], { type: e.placeholder });
    }

    navigator.clipboard.write([
        new ClipboardItem(item)
    ]).then(v => {
        console.log('복사 완료');
    }).catch(e => {
        console.error(`복사 실패: ${e}`);
    });
});
</script>

 

버튼을 누르면 각 textarea에서 텍스트를 가져와서 item을 만들고, navigator의 clipboard api로 클립보드에 쓴다.

이거를 html로 실행해 보면,

창이 3개.

 

각 위치에 아까 Inspector에서 가져온 파일을 넣고 복사 버튼을 누르면...?

 

안됨

 

https://stackoverflow.com/questions/68897154

스택오버플로를 뒤져 보면 MIME 타입을 3개밖에 지원 안 한다고 한다.

그래도 text/plain이랑 text/html은 지원하니까 text/rtf만 없애고 한 번 다시 실행해 보면...

복사도 되고...

잘 붙여넣어진다.

 

다만 이미 있는 표에 덮어씌워서 붙여넣으려고 하면 표가 망가진다..

 

new Blob([e.value.replace('빨강', '빠아아아알강')], { type: e.placeholder });

 

마지막으로 텍스트 수정이 되는지만 확인해보고 마치도록 하자.

잘 된다.

 

 

이제 한글 파일을 html로 수정해달라는 요청을 받아도 js로 hwp 파일 파서를 직접 만들지 않는 한에서 어떻게든 할 수 있게 되었다.

 

마지막으로 테스트에 쓰인 최종 버전을 올린다. Clipboard Inspector 소스에서 extractData를 가져와서 앞에 조건문 하나를 덧붙였다.

<!DOCTYPE html>

<textarea placeholder="text/plain"></textarea>
<textarea placeholder="text/html"></textarea>
<button id="load">불러오기!</button>
<button id="copy">복사!</button>
<script>
// https://evercoder.github.io/clipboard-inspector/
async function extractData(data) {
    if (!data) {
        return undefined;
    }
    if (Array.isArray(data)) data = data[0];

    const file_info = file =>
        file
            ? {
                name: file.name,
                size: file.size,
                type: file.type,
                url: URL.createObjectURL(file)
            }
            : null;

    if (data instanceof DataTransfer) {
        return {
            type: 'DataTransfer',
            types: Array.from(data.types).map(type => ({
                type,
                data: data.getData(type)
            })),
            items: data.items
                ? Array.from(data.items).map(item => ({
                    kind: item.kind,
                    type: item.type,
                    as_file: file_info(item.getAsFile())
                }))
                : null,
            files: data.files ? Array.from(data.files).map(file_info) : null
        };
    }

    if (data instanceof ClipboardItem) {
        return {
            type: 'ClipboardItem',
            types: await Promise.all(
                Array.from(data.types).map(async type => {
                    const blob = await data.getType(type);
                    return {
                        type: type,
                        data: blob.type.match(/^text\//)
                            ? await blob.text()
                            : file_info(blob)
                    };
                })
            )
        };
    }
    return undefined;
}

document.querySelector('#load').addEventListener('click', async e => {
    const extracted_data = await extractData(await navigator.clipboard.read());
    console.log(extracted_data);

    for (const d of extracted_data.types) {
        document.querySelector(`textarea[placeholder="${d.type}"]`).value = d.data;
    }
});

document.querySelector('#copy').addEventListener('click', e => {
    const item = {};
    const replacer = [
        t => t.replace('빨강', '빠아아아알강'),
    ];

    for (const e of document.querySelectorAll('textarea')) {
        let text = e.value;
        for (const r of replacer) {
            text = r(text);
        }
        item[e.placeholder] = new Blob([text], { type: e.placeholder });
    }

    navigator.clipboard.write([
        new ClipboardItem(item)
    ]).then(v => {
        console.log('복사 완료');
    }).catch(e => {
        console.error(`복사 실패: ${e}`);
    });
});
</script>

 

+)

뭐야 이게 왜 떠요 아깐 안떴잖아

난 역시 한글과컴퓨터가 싫다.