수학 교사를 위한 자바스크립트 트릭들

국내 수학교사/강사의 절대다수는 한/글을 워드 프로세서로 사용하고 있다고 추정한다. 여태 살면서 한/글 이외의 워드 프로세서를 사용하여 수학문제를 편집하는 수학 선생을 본 적이 없다-_- 혹시 있으면 댓글 함 달아 주시면 매우 감사하겠습니다. ㅋㅋㅋ

한/글에는 스크립트 기능이 있는데, 이게 자바스크립트랑 엄청 유사해서 자바스크립트의 트릭들이 다 적용된다. 이거 잘 쓰면 되게 편리한데, 지금까지 살아오면서 본인이 편리하다고 생각되지만 잘 모를법한 트릭들을 기록해 둔다. ㅋ

1. replace, RegExp 함수 대신 split, join 함수 쓰기

ㅌ=4ㅅ 라고 입력하면 x=4t 라고 짜잔! 하고 변환하고 싶은데 다음과 같은 루프를 쓰면 왠지 될 것 같다-_-

var k_list =['ㅁ','ㅠ','ㅊ','ㅇ','ㄷ','ㄹ','ㅎ','ㅗ','ㅑ','ㅓ','ㅏ','ㅣ',
'ㅡ','ㅜ','ㅐ','ㅔ','ㅂ','ㄱ','ㄴ','ㅅ','ㅕ','ㅍ','ㅈ','ㅌ','ㅛ','ㅋ',
'ㄲ','ㄸ','ㅃ','ㅆ','ㅉ','ㅖ','ㅒ'],
e_list =['a','b','c','d','e','f','g','h','i','j','k','l',
'm','n','o','p','q','r','s','t','u','v','w','x','y','z',
'R','E','Q','T','W','P','O'];

for(i=0;i<k_list2.length;i++)
{
	text=text.replace(RegExp(k_list[i], "g"), e_list[i]);
}

근데 ‘xy’라고 치면 ‘툐’가 되어버리므로 이래서는 곤란하다. k_list 목록에 ‘툐’ 같은 걸 추가하면 될 것 같은데, 이게 또 초성이 없는 조합들이 안 먹힌다. 예를 들어 ‘over’라고 치면 ‘ㅐㅍㄷㄱ’인데, 한/글은 초성이 없는 한글문자를 지원하므로 깨지게 된다. 이 경우 RegExp 함수의 문제 같은데, replace 함수 대신에 split, join을 사용하여 치환하는 트릭[1]을 사용하면 ‘ㅐㅍㄷㄱ’이 ‘over’로 깔끔하게 변형된다.

text=text.split(k_list[i]).join(e_list[i]);

2. Byte order mark 제거

위와 같은 트릭을 쓰려면 처음에 텍스트를 유니코드로 받아야 하는데, 한/글 스크립트 팁이라면서 인터넷에 널리 퍼져 있는 다음과 같은 코드는 작동하지 않는다.

text = GetTextFile("TEXT", "saveblock")

저 TEXT 부분을 UNICODE로 바꾸면 된다. 이 경우 텍스트 앞쪽에 Byte order mark가 첨가되어 텍스트 앞부분의 더미를 아무리 치환하려고 해도 제거가 되지 않는데, 이걸 몰라서 원인을 찾느라 열라게 삽질했다-_- 다음과 같이 코드를 사용하면 된다.

text = GetTextFile("UNICODE", "saveblock")
text=text.replace(/^\uFEFF(1\.  )?/, '');

3. indexOf의 정규식 사용

자바스크립트의 indexOf에는 정규식이 안 통하는데, search에는 통한다. 근데 search에는 특정 위치부터 검색을 시작하는 옵션이 없다. stack overflow에 누군가 아주 훌륭한 함수[2]를 올려두었으니 그대로 카피해 쓸 수 있다.

function regexIndexOf(text, re, i) {
    var indexInSuffix = text.slice(i).search(re);
    return indexInSuffix < 0 ? indexInSuffix : indexInSuffix + i;
}

4. 반올림 처리

대부분의 프로그래밍 언어에서 이진수의 특성 때문에 0.1 + 0.2를 하면 0.3이 안 나오는데, 심지어 웹사이트[3]도 있고, 이를 이용한 smbc의 개그[4]도 있다. ㅋㅋ

이런 특성이 자동 보기[5]를 만들때 곤란한 경우가 있는데, 어느 웹사이트[6]에 있는 다음과 같은 코드를 쓰면 된다.

function roundXL(n, digits) {
	if (digits >= 0) return parseFloat(n.toFixed(digits));		// 소수부 반올림

	digits = Math.pow(10, digits);					// 정수부 반올림
	var t = Math.round(n * digits) / digits;

	return parseFloat(t.toFixed(0));
}

5. 특정 문자의 대문자

수학문제에 확률변수 X라든가 선분 AB 같은 것들은 대부분 대문자를 쓰고 있는데, 자동으로 대문자로 뿅 변하면 무척 편리하다. ㅋㅋ 문자열의 특정 부분만 대문자로 바꾸는 트릭은 stack overflow[7]에 있다. 다음과 같이 pos에서 pos2 사이를 대문자로 만들 수 있다.

text = text.substring(0,pos) + text.substring(pos,pos2).toUpperCase() + text.substring(pos2);

6. right 자동 넣기

수식에 left … right를 많이 쓰는데 은근 치기 귀찮다. right가 없을 때만 right를 자동으로 넣는 정규식

text = text.replace(/left\s*(((?!right)[^\}])*)([\}\)\]])?$/,'left$1 right$3');

7. 이미지 사이즈 절대 크기

클립보드의 이미지를 스크립트로 붙여 넣을 때, 항상 사이즈를 50%로 하고싶으면

HAction.Run("Paste");
FindCtrl();
HAction.GetDefault("ShapeObjDialog", HParameterSet.HShapeObject.HSet);
with (HParameterSet.HShapeObject)
{
	Height = Height*0.5;
	Width = Width*0.5;
}
HAction.Execute("ShapeObjDialog", HParameterSet.HShapeObject.HSet);

라고 하면 될 것 같지만 안된다-_- 왜냐하면 붙여 넣는 순간에 한/글이 이미지 사이즈를 조정하여 원본 크기가 아니라 편집용지 크기에 맞춰 붙여 넣어 주기 때문이다. 이걸 해결 못해서 매번 손으로 삽질했는데-_- 다음과 같이 변경하면 된다.

	Height = ShapeDrawImageAttr.OriginalSizeY*0.5;
	Width = ShapeDrawImageAttr.OriginalSizeX*0.5;

8. 한/글의 미주 버그

커서가 미주 안에 편집 상태에 있을 때, 미주를 생성하는 스크립트 HAction.Run(“InsertEndnote”) 를 실행하면 에러가 나면서 한/글이 비정상 종료가 된다. 문서를 날려먹는 멘붕을 몇 번 겪은 끝에-_- 다음과 같은 트릭을 쓰면 방지가 가능하다는 걸 알았다.

if ( HAction.Run("InsertEndnote") )
{
//커서가 미주 밖
} else
{
//커서가 미주 안
}

 


[1] [javascript|자바스크립트] 특정 문자 모두 바꾸기 (replaceAll) 쉽게 사용하기 in 젠트의 프로그래밍 세상
[2] Is there a version of JavaScript’s String.indexOf() that allows for regular expressions? in stackoverflow
[3] http://0.30000000000000004.com/
[4] http://www.smbc-comics.com/?id=2999
[5] 내 백과사전 아래 한글 수식 관련 매크로 스크립트 2015년 8월 19일
[6] [자바스크립트] 실수로 반올림, 소수점 자릿수 지정, Round To Float, JavaScript in mwultong Blog
[7] How do I make the first letter of a string uppercase in JavaScript? in stackoverflow