Total: Today: Yesterday:
연구소/이것저것 | 2016. 4. 28. 14:11 | Posted by 자수씨


엑셀 시트로 저장된 데이터를 레드마인 위키에 옮길 때 주로 사용하던 컨버팅페이지가 있었는데, 단위가 큰 수를 적용하니 오류가 발생하였습니다.


방법을 궁리하다가 얼마전에 해보았던 Google Sheets Script editor 를 이용하여 포팅을 도전해보았습니다.



#h3 첫번째 시도



위와 같은 데이터가 있을 때 레드마인에서 테이블 형식으로 사용하기 위해서는 다음과 같은 문법으로 작성 되어야 합니다.


|_. 이름 |_. 출생년도 |_. 주급 | 

| 이정주 | 1983 | 500000 |
| 이은호 | 1986 | 480000 |
| 이수진 | 1989 | 450000 |
| 이혜원 | 1900 | 445000 | 


위와 같은 레드마인용 컨텐츠를 작성해주는 Google Sheets 용 script 를 작성해보았습니다.


### js


function toRedmine(input, hasTitle) {

  

  var _redmineContent = '';

  

  for (var i = 0; i < input.length; i++) {

    var _row = input[i];

    for (var j = 0; j < _row.length; j++) {

      var _col = _row[j];

      

      _redmineContent += '|';

      if (hasTitle == true && i == 0)

        _redmineContent += '_.';

      _redmineContent += ' ' + _col + ' ';

    }

    _redmineContent += '|\r\n'

  }

  

  return _redmineContent;

}


커스텀 함수를 사용하게되면 위와 같은 레드마인 문법으로 포팅된 것을 확인할 수 있습니다.


=toRedmine(A1:C5, true)



실제로 레드마인에 붙여보면 내용은 잘 나오지만 시트에서 본 형식이 아니라 만족스럽지는 않습니다.



포맷이 적용된 데이터를 보고싶은데 말이죠...




#h3 포맷팅된 값으로...


구글 시트의 문서를 찾아보니 range 를 이용하여 현재 화면에 보여지는 값을 가지고 올 수 있다고 합니다.

해당 함수를 이용하여 새로운 커스텀 함수를 만들어보았습니다.


### js


function toRedmine2(range, hasTitle) {

  

  var _redmineContent = '';

  var _values = SpreadsheetApp.getActiveSheet().getRange(range).getDisplayValues();

  

  for (var i = 0; i < _values.length; i++) {

    var _row = _values[i];

    for (var j = 0; j < _row.length; j++) {

      var _col = _row[j];

      

      _redmineContent += '|';

      if (hasTitle == true && i == 0)

        _redmineContent += '_.';

      _redmineContent += ' ' + _col + ' ';

    }

    _redmineContent += '|\r\n'

  }

  

  return _redmineContent;

}

새로만든 커스텀 함수는 기존과는 다르게 ```range```  를 문자열 형식으로 전달해야 합니다.


=toRedmine2("A1:C5", true)






처음에 설정했던 목표는 달성했으나 뭔가 정렬되지 않은게 아쉽습니다.




#h3 정렬을 해보자!!


구글 문서를 살펴보니 정렬된 데이터를 가지고 오는 함수가 있었습니다. ```range.getHorizontalAlignments()``` 해당 함수를 이용하여 레드마인의 정렬 문법을 적용시켜보았습니다.


### js


function toRedmine3(range, hasTitle) {

  

  var _redmineContent = '';

  var _range = SpreadsheetApp.getActiveSheet().getRange(range);

  var _values = _range.getDisplayValues();

  var _aligns = _range.getHorizontalAlignments();

  

  for (var i = 0; i < _values.length; i++) {

    var _row = _values[i];

    for (var j = 0; j < _row.length; j++) {

      var _col = _row[j];

      var _align = _aligns[i][j];

      

      _redmineContent += '|';

      if (hasTitle == true && i == 0)

        _redmineContent += '_.';

      else {

        if (_align.indexOf('right') > -1)

          _redmineContent += '>.';

        else if (_align.indexOf('left') > -1)

          _redmineContent += '<.';

        else if (_align.indexOf('center') > -1)

          _redmineContent += '=.';

      }

      _redmineContent += ' ' + _col + ' ';

    }

    _redmineContent += '|\r\n'

  }

  

  return _redmineContent;

}


세번째 커스텀 함수는 사용방법이 두번째와 동일합니다. 헤더 영역은 정렬이 먹지 않으므로 그 부분만 정렬되지 않도록 구성하였습니다.


=toRedmine3("A1:C5", true)






엑셀의 VBScript 는 문법이 손에 익지 않아 불편했는데 Google Sheets 는 주특기로 사용했던 자바스크립트로 개발이 가능하여 훨씬 빠르고 수월하게 원하는 기능을 만들 수 있었습니다.


앞으로도 자주 애용해야겠네요~




#h3 References

 - https://www.joecullin.com/data_converter/

 - https://developers.google.com/apps-script/reference/spreadsheet/range

 - http://webapps.stackexchange.com/questions/10629/how-to-pass-a-range-into-a-custom-function-in-google-spreadsheets

 - http://www.redmine.org/projects/redmine/wiki/RedmineTextFormattingTextile

연구소/이것저것 | 2016. 4. 18. 22:01 | Posted by 자수씨


최근에 나오는 라이브러리를 보면 ```"use strict"``` 라는 문구가 자주 보입니다.


strict 미국·영국 [strɪkt]

1. (규칙 등이) 엄격한

2. (사람이 남에 대해) 엄격한

3. (사람이 자신의 종교・신념 등에 대해) 엄격한


- 네이버 어학사전


사전에서 볼 수 있듯이 무언가 엄격하게 사용한다는 의미로 생각이 되는데, 간단하게 알아보려 합니다.



#h3 strict 모드의 정의


strict 모드로 설정하는 방법은 간단합니다. 코드 앞쪽에 ```"use strict"``` 를 추가하는 것 입니다.

### js


"use strict";

x = 3.14;       // This will cause an error (x is not defined)

위의 예제를 실행하면 콘솔 창에 아래와 같은 오류가 찍히게 됩니다.


Uncaught ReferenceError: x is not defined


정의가 되지 않은 x 로 인해 정상적으로 동작을 하지 않습니다.


### js


"use strict";

myFunction();


function myFunction() {

    y = 3.14;   // This will also cause an error (y is not defined)

}

위의 예제도 y 가 정의되지 않아 정상적으로 실행되지 않습니다.




### js


x = 3.14;       // This will not cause an error. 

myFunction();


function myFunction() {

   "use strict";

    y = 3.14;   // This will cause an error (y is not defined)

}

위의 예제는 x 가 사용되기 전에는 ```"use strict"``` 가 선언되지 않았으므로 y 에 대해서만 오류가 발생합니다.



#h3 왜 strict 모드를 사용하는가?


"보안" 자바스크립트를 작성하는 쉬운 방법이기 때문입니다. 다른 이유는 "올바르지 않은 문법" 을 사전에 검출할 수 있습니다.


strict 모드는 쓰기금지 프로퍼티의 정의, getter 전용 프로터피, 존재 하지 않는 프로퍼티, 존재하지 않는 변수, 존재하지 않는 객체에 대해 에러를 발생시킵니다.



#h3 strict 모드에서 허용되지 않는 문법


1. 정의되지 않은 변수의 사용

### js


"use strict";

x = 3.14;                // This will cause an error (x is not defined)

### js


"use strict";

x = {p1:10, p2:20};      // This will cause an error (x is not defined)


2. 변수나 객체의 삭제

### js


"use strict";

var x = 3.14;

delete x;                // This will cause an error


3. 함수 파라미터에 중복된 이름

### js


"use strict";

function x(p1, p1) {};   // This will cause an error


4. 8진수

### js


"use strict";

var x = 010;             // This will cause an error


5. 이스케이프 문자

### js


"use strict";

var x = \010;            // This will cause an error


6. 읽기전용 프로퍼티에 값 설정

### js


"use strict";

var obj = {};

Object.defineProperty(obj, "x", {value:0, writable:false});


obj.x = 3.14;            // This will cause an error


7. 조회 전용 프로퍼티에 값 설정

### js


"use strict";

var obj = {get x() {return 0} };


obj.x = 3.14;            // This will cause an error


8. ```eval```, ```arguments``` 문자열에 대한 변수로의 사용

### js


"use strict";

var eval = 3.14;         // This will cause an error

var arguments = 3.14;    // This will cause an error


9. ```with``` 사용

### js


"use strict";

with (Math){x = cos(2)}; // This will cause an error


10. ```eval()``` 에 정의된 변수 사용

### js


"use strict";

eval ("var x = 2");

alert (x);               // This will cause an error



#h3 References

http://www.w3schools.com/js/js_strict.asp

연구소/이것저것 | 2016. 4. 18. 15:12 | Posted by 자수씨

이전 포스팅에서는 너무 무지한 상태에서 쓰다보니 다시 봐도 이해가 안되는 듯 하여 쉬운 예제를 통해 정리해보겠습니다.


기존에 promise 패턴이 아닌 callback 방식의 경우에는 아래와 같이 코딩을 하였습니다.

### js


$.ajax({

  url: "/ServerResource.txt",

  success: successFunction,

  error: errorFunction

});


대부분 함수의 파라미터 객체에 function 을 설정하여 결과에 대한 처리를 했습니다. 이러한 경우 callback 이 중첩되어 소스의 가독성도 떨어질 뿐더러 관리가 안되는 단점이 있었습니다.



jQuery 1.5 버전 이후부터는 아래와 같이 ```done()```, ```fail()```, ```always()``` 를 이용하여 결과에 대한 처리를 지정합니다.

### js


var promise = $.ajax({

  url: "/ServerResource.txt"

});

  

promise.done(successFunction);

promise.fail(errorFunction);

promise.always(alwaysFunction);


```jQuery.ajax()``` 는 ```jQuery XMLhttpRequest(jqXHR)``` 을 반환하기 때문에 아래와 같은 방식으로도 구현이 가능합니다.

### js


$.ajax( "example.php" )    

    .done(function() { alert("success"); })    

    .fail(function() { alert("error"); })    

    .always(function() { alert("complete"); }); 


체인 방식이 아니더라도 jqXHR 객체에 직접 지정도 가능합니다.

### js


var jqxhr = $.ajax( "example.php" )    

    .done(function() { alert("success"); })    

    .fail(function() { alert("error"); })    

    .always(function() { alert("complete"); }); 

     

    // perform some work here ... 

     

    // Set another completion function for the request above

    jqxhr.always(function() { alert("another complete"); });



jQuery 1.8 버전 이후부터는 ```then()``` 함수를 사용하여 Promise 패턴을 적용할 수 있습니다.

```then()``` 의 첫번째 인자는 성공에 대한 액션, 두번째 인자에는 실패에 대한 액션을 지정할 수 있습니다.

### js


$.ajax({url: "/ServerResource.txt"}).then([successFunction1, successFunction2, successFunction3], 

                                          [errorFunction1, errorFunction2]);

 

//same as

 

var jqxhr = $.ajax({

  url: "/ServerResource.txt"

});

  

jqxhr.done(successFunction1);

jqxhr.done(successFunction2);

jqxhr.done(successFunction3);

jqxhr.fail(errorFunction1);

jqxhr.fail(errorFunction2);

### js


var promise = $.ajax({

  url: "/ServerResource.txt"

});

  

promise.then(successFunction, errorFunction);

### js


var promise = $.ajax({

  url: "/ServerResource.txt"

});

 

promise.then(successFunction); //no handler for the fail() event




Deferred 객체를 직접 만들어서 사용할 수 있는데, 그 방법은 아래와 같습니다.


### js


var timer;

$('#result').html('waiting…');

  

var promise = process();

promise.done(function() {

  $('#result').html('done.');

});

promise.progress(function() {

  $('#result').html($('#result').html() + '.');

});

 

function process() {

  var deferred = $.Deferred();

 

  timer = setInterval(function() {

    deferred.notify();

  }, 1000);

   

  setTimeout(function() {

     clearInterval(timer);

     deferred.resolve();

  }, 10000);

   

  return deferred.promise();

}




Promise 에 등록된 callback 들을 Deferred 가 각 상황에 맞게 호출해주는 방식입니다.


```then()``` 함수를 이용하면 아래와 같이 구현할 수 있습니다.

### js


var timer;

 

(function process() {

  $('#result').html('waiting…');

  var deferred = $.Deferred();

     

  timer = setInterval(function() {

    deferred.notify();

  }, 1000);

   

  setTimeout(function() {

     clearInterval(timer);

     deferred.resolve();

  }, 10000);

   

  return deferred.promise();

})().then(function() { $('#result').html('done.'); },

          null,

          function() { $('#result').html($('#result').html() + '.'); });



#h3 References

http://www.htmlgoodies.com/beyond/javascript/making-promises-with-jquery-deferred.html

https://api.jquery.com/category/deferred-object/




연구소/이것저것 | 2016. 4. 18. 14:05 | Posted by 자수씨

20대에는 신기술에 관심이 많아서 이것저것 많이 해보고 실무에 적용도 했었는데, 30대가 되고나니 업무도 많아지고 귀찮음 때문에 신기술에 대해 관심이 점점 떨어져갔습니다.


최근에 다시 신기술에 대해 공부하다보니 너무 많은 것들이 쏟아져 나와있었습니다. 그 중 하나가 promise 패턴인데, 항상 callback 가 진리라 생각하고 불편한 상황에서도 계속 쓰고만 있었습니다.



promise 패턴은 스펙 구현체들을 로드하여 사용할 수 있는데, 최근 가장 많이 쓴는 jQuery 에서도 promise 패턴을 활용할 수 있습니다.


jQuery 에서는 ```jQuery.when(deferreds)``` 로 제공이 되며 API 에 있는 예제를 하나씩 확인해보겠습니다.



아래 예제는 ```jQuery.when()``` 의 파라미터인 ```deferred``` 가 정상적으로 처리되면 ```deferred.then``` 에서 콜백과 같은 처리를 합니다. 기존의 방식과는 달리 콜백이 중첩되지 않는 구조입니다.


### js


$.when( $.ajax( "test.aspx" ) ).then(function( data, textStatus, jqXHR ) {

  alert( jqXHR.status ); // Alerts 200

});



```jQuery.when()``` 의 파라미터가 Deferred 나 Promise 가 아닐 경우에는 done 콜백이 즉시 실행됩니다.

### js


$.when( { testing: 123 } ).done(function( x ) {

  alert( x.testing ); // Alerts "123"

});


파라미터가 없는 경우에도 즉시 실행됩니다.

### js


$.when().then(function( x ) {

  alert( "I fired immediately" );

});




아래는 ```jQuery.Deferred()``` 를 이용한 예제인데, 아직 잘 이해가 되지 않는 부분이 있습니다. Deferred 객체에 대해 학습 후에 다시 정리해야겠습니다.

### js


var d1 = $.Deferred();

var d2 = $.Deferred();

 

$.when( d1, d2 ).done(function ( v1, v2 ) {

    console.log( v1 ); // "Fish"

    console.log( v2 ); // "Pizza"

});

 

d1.resolve( "Fish" );

d2.resolve( "Pizza" );


### js


var d1 = $.Deferred();

var d2 = $.Deferred();

var d3 = $.Deferred();

 

$.when( d1, d2, d3 ).done(function ( v1, v2, v3 ) {

    console.log( v1 ); // v1 is undefined

    console.log( v2 ); // v2 is "abc"

    console.log( v3 ); // v3 is an array [ 1, 2, 3, 4, 5 ]

});

 

d1.resolve();

d2.resolve( "abc" );

d3.resolve( 1, 2, 3, 4, 5 );




#h3 References

https://api.jquery.com/jquery.when/

https://api.jquery.com/category/deferred-object/

연구소/이것저것 | 2016. 4. 10. 21:58 | Posted by 자수씨

syntaxhighlighter 4 빌드 실패로 인해 다른 highlighter 를 찾다가 highlight.js 를 발견하고 블로그에 적용해보았습니다.




적용 방법은 간단합니다.

### html

<!-- cdn 에서 라이브러리 로드 -->

<link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.3.0/styles/default.min.css">

<script src="//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.3.0/highlight.min.js"></script>


### html

<pre><code class="html">...</code></pre>



위와 같이 CDN 에 있는 라이브러리를 로드할 수 있도록 <link> 태그와 <script> 를 추가하고, <pre><code> 태그 안에 실제 코드를 삽입합니다.




위의 방식만으로는 티스토리에서 작성하는 것이 힘들어서 예전에 syntaxhighlighter 티스토리용 플러그인을 만드셨던 분의 소스(sh4tistory)를 참고하여 highlight.js 티스토리 플러그인을 만들어보았습니다.


https://github.com/Vince-Yi/highlightjs4tistory




사용하는 방법은 기존의 티스토리 플러그인과 같이 인용구에 소스코드를 삽입하는 방식으로 "###" + brushName 을 이용하였습니다.






연구소/이것저것 | 2016. 4. 10. 21:46 | Posted by 자수씨

부트스트랩 스터디 첫 작품인 티스토리 블로그 스킨을 팀블로그에 적용하였습니다.





부트스트랩 자체가 반응형 웹을 위한 도구이기 때문에 모바일에서도 잘 나오네요~ 후후


highlighter 도 적당한 걸 연동하였으니 필요한건 조금씩 추가해나가면 될 것 같습니다.







연구소/이것저것 | 2016. 4. 8. 21:01 | Posted by 자수씨

이 프로젝트 빌드를 위해 gulp 와 gulp 플러그인 들을 설치했는데 정상적으로 빌드가 되지 않는다.


프로젝트 github 의 위키에서 제시한대로 진행했는데 계속 오류만... 또르르...



깃헙에서 프로젝트를 내려받아서 npm 를 통해 관련 라이브러리들을 내려받는 작업까지는 순조로웠다.


git clone https://github.com/syntaxhighlighter/syntaxhighlighter.git

cd syntaxhighlighter

npm install




서브 프로젝트에 있는 브러쉬와 테마를 받는 것도 문제 없음


gulp setup-project




블로그에 사용하기 위해 전체 브러쉬와 기본 테마로 빌드를 하였으나 실패...


gulp build --brushes=all --theme=default






오류가 나길래 단일 브러쉬로도 빌드해봤으나 동일한 결과...


아 그냥 다른 라이브러리 써야겠다.





연구소/이것저것 | 2016. 4. 6. 16:03 | Posted by 자수씨

최근에 다양한 오픈소스를 검색하다보니 다양한 웹폰트로 꾸며진 블로그들이 있었습니다.

신기해서 조금 검색해보니 구글에서 제공해주는 웹폰트가 있었습니다.



Google Fonts Early Access!: https://www.google.com/fonts/earlyaccess



graduated 부터 시작된 이 프로젝트는 한글폰트도 제공해줍니다.



티스토리에 적용하는 방법은 엄청 쉽습니다.


1. 관리자페이지 > HTML/CSS 편집 > CSS 파일 선택

2. css import

3. font-family 편집






많은 공수를 들이지않고 블로그가 달라짐을 느낄 수 있습니다//