이번에는 getTextUsingTransformations() 함수를 살펴볼 차례죠?
제 생각에 오늘로 소스 분석이 모두 끝날 것 같습니다.
사실 제가 할 작업은 지금까지 분석한 것으로도 충분하거든요.
벌써 미팅에서 결과를 공유했고 그 다음 단계가 진행중입니다.
하지만 시작했으니 마저 끝마쳐보죠.
pdf2text() 함수의 맨 마지막 return 문에 있는 코드 입니다.
return getTextUsingTransformations($texts, $transformations);
파라미터로는 getDirtyTexts() 함수에서 얻었던 $texts 가 첫번째에 있네요.
이 내용은 지난 글 말미에 보여드렸습니다.
두번째 파라미터는 getDecodedStream() 함수를 통해서 얻었던 $data 입니다.
getTextUsingTransformations($texts, $transformations) 함수를 볼까요?
function getTextUsingTransformations($texts, $transformations) {
$document = "";
for ($i = 0; $i < count($texts); $i++) {
$isHex = false;
$isPlain = false;
$hex = "";
$plain = "";
for ($j = 0; $j < strlen($texts[$i]); $j++) {
$c = $texts[$i][$j];
switch($c) {
case "<":
$hex = "";
$isHex = true;
break;
case ">":
$hexs = str_split($hex, 4);
for ($k = 0; $k < count($hexs); $k++) {
$chex = str_pad($hexs[$k], 4, "0");
if (isset($transformations[$chex]))
$chex = $transformations[$chex];
$document .= html_entity_decode("&#x".$chex.";");
}
$isHex = false;
break;
case "(":
$plain = "";
$isPlain = true;
break;
case ")":
$document .= $plain;
$isPlain = false;
break;
case "\\":
$c2 = $texts[$i][$j + 1];
if (in_array($c2, array("\\", "(", ")"))) $plain .= $c2;
elseif ($c2 == "n") $plain .= '\n';
elseif ($c2 == "r") $plain .= '\r';
elseif ($c2 == "t") $plain .= '\t';
elseif ($c2 == "b") $plain .= '\b';
elseif ($c2 == "f") $plain .= '\f';
elseif ($c2 >= '0' && $c2 <= '9') {
$oct = preg_replace("#[^0-9]#", "", substr($texts[$i], $j + 1, 3));
$j += strlen($oct) - 1;
$plain .= html_entity_decode("&#".octdec($oct).";");
}
$j++;
break;
default:
if ($isHex)
$hex .= $c;
if ($isPlain)
$plain .= $c;
break;
}
}
$document .= "\n";
}
return $document;
}
먼저 $document 변수를 만들어 놓네요. 맨 밑에 보니까 return 될 값이 들어갈 변수입니다.
즉 사람이 읽을 수 있는 완전한 데이터가 들어갈 변수죠.
다음은 $texts 의 count 만큼 for 문을 돌립니다.
그 for문 안에서 맨 먼저 하는 일은 4개의 변수를 정의해 놓는 거네요.
$isHex와 $isPlain 는 boolean 값이 들어갈 변수고 $hex와 $plain 은 어떤 문자 같은게 들어갈 변수인것 같습니다.
여기서 다시 for 문을 돌립니다. $texts 가 이중배열이라서 이렇게 작업하나 봅니다.
두번째 for 문에서는 $c 변수에 $texts[$i][$j] 를 담습니다.
그 다음에 switch 문이 나오는데... 처음에 < 와 > 를 체크하는 군요.
편의를 위해서 어제 봤던 데이터 중 일부를 아래 복사해 넣겠습니다.
(W)-36(e)7(e)7(k )46(o)7(f)
( )
(Oct)-11(o)5(ber )10(1)4( )
<00B2>
( )
(Oct)-11(o)5(ber )10(5)
( )
( )
( )
(Who)5(l)7(e)7( )-19(+ )-2(S)3(um)5( )
( )
( )
(Choice)
( )
(+)
( )
(F)20(lavor)
<00B2> 가 있네요. < 인 경우에는 $isHex 가 true 이고 > 인 경우에는 false 입니다.
그리고 > 인 경우에는 $hex 값을 array 로 바꿉니다.
str_split() 함수에서 그 일을 하죠.
<?php
$str = "Hello Friend";
$arr1 = str_split($str);
$arr2 = str_split($str, 3);
print_r($arr1);
print_r($arr2);
?>
위 소스를 돌리면 아래 값을 얻습니다.
Array ( [0] => H [1] => e [2] => l [3] => l [4] => o [5] => [6] => F [7] => r [8] => i [9] => e [10] => n [11] => d ) Array ( [0] => Hel [1] => lo [2] => Fri [3] => end )
어떤 일을 하는 함수인지 아시겠죠?
그 다음에는 $hexs 의 count 만큼 for 문을 돌립니다.
그 다음 그 각각의 값을 지난번에도 나왔던 str_pad() 함수를 사용해서 0을 4칸 붙이네요.
그 다음에 if 문에서 $transformations[$chex] 이 세팅돼 있으면 $chex 변수에 $transformations[$chex]을 대입합니다.
그리고 나서 $document 에 값을 집어 넣는데요.
html_entity_decode() 함수를 사용합니다.
이 것은 html 을 string 으로 바꿔 주는 함수입니다.
<?php
$orig = "I'll \"walk\" the <b>dog</b> now";
$a = htmlentities($orig);
$b = html_entity_decode($a);
echo $a; // I'll "walk" the <b>dog</b> now
echo $b; // I'll "walk" the <b>dog</b> now
?>
위 예제를 보시면 어떤 일을 하는지 아시겠죠?
그러니까 <> 감싸여진 데이터는 hex 코드라서 이 case 문에서 그것을 처리하는 거네요.
그 다음 case 문에서는 (,) 를 체크합니다.
() 로 둘러싸인 부분은 그냥 text 죠. 사람이 읽을 수 있는..
그러니까 별다른 처리를 하지 않아도 되기 때문에 ) 인 경우에 $document 에 $plain 을 그냥 추가해 버리는 겁니다.
다음에는 \\ 를 체크하는데요.
우리가 다루는 pdf 파일에서는 이 값이 추출 되지 않았습니다.
어쨌든 내용을 보면 줄바꿈, 탭 뭐 이런 것들을 해당 sign 으로 바꿔서 $plain 에 넣는 일을 하네요. 숫자인 경우에는 거기에 맞게 또 처리를 하구요.
디폴트로는 $isHex 일 경우 $hex 에 $c를 추가하고 $isPlain 일 경우 $plain 에 $c를 추가합니다.
그리고 이렇게 만든 $document 를 이전 for 문에서 만든 $document 에 가를 하구요.
이렇게 for 문이 다 돌고 $document 에 값이 다 쌓였으면 이 값을 return 합니다.
그 return 값이 사람이 볼 수 있는 text 입니다.
이렇게 해서 얻은 결과는 아래와 같습니다.
잘 안 보이실 텐데요. 1번 글에서 업로드한 파일들을 다운 받아서 돌려 보시면 됩니다.
참고로 이 데이터를 가지고 요일별 메뉴를 display 하는 함수를 제가 만들어 봤는데요.
function menus($sources){
$resultlen = strlen($sources);
$menuDate = substr($sources,0,48);
echo "<b><font size=6>Start Menu</font> <p><br> ". $menuDate. "<p></b>";
$result = preg_replace("/\s+/",'_',$sources);
$fs1 = strrpos($result,'_M_');
$menu1 = substr($result,$fs1,$resultlen);
$startTue = strpos($menu1,'_T_');
$startWed = strpos($menu1,'_W_');
$startThu = strrpos($menu1,'_T_');
$startFri = strpos($menu1,'_F_');
$endFri = strpos($menu1,'WEEKLY');
$Monday = str_replace('_', ' ' ,str_replace('_M_','Monday <br>',str_replace('FIT','FIT<br>',substr($menu1,0,$startTue))));
$Tuesday = str_replace('_', ' ' ,str_replace('_T_','Tuesday <br>',str_replace('FIT','FIT<br>',substr($menu1,$startTue,$startWed-$startTue))));
$Wednsday = str_replace('_', ' ' ,str_replace('_W_','Wednsday <br>',str_replace('FIT','FIT<br>',substr($menu1,$startWed,$startThu-$startWed))));
$Thuesday = str_replace('_', ' ' ,str_replace('_T_','Thusday <br>',str_replace('FIT','FIT<br>',substr($menu1,$startThu,$startFri-$startThu))));
$Friday = str_replace('_', ' ' ,str_replace('_F_','Friday <br>',str_replace('FIT','FIT<br>',substr($menu1,$startFri))));
echo "<table width=50%><tr><td>";
echo "<p> ". $Monday . "<p>";
echo "<p> ". $Tuesday . "<p>";
echo "<p> ". $Wednsday . "<p>";
echo "<p> ". $Thuesday . "<p>";
echo "<p> ". $Friday . "<p>";
echo "</td></tr></table><p><br><p> ";
}
그리고 함수 밖에서 이걸 부르면 되죠.
menus($result);
이렇게 하면 아래와 같은 결과가 나옵니다.
이렇게 해서 PDF 를 TEXT 로 변환하는 PHP 프로그램을 모두 분석해 봤습니다.
오랫만에 목욕해서 때를 싹 밀었을 때 처럼 개운하네요.
분석결과 위 소스는 제가 일하는데에서는 맞지 않아서 사용하지 않기로 했거든요.
그래서 저 결과도 깔끔하게 나온 것은 아닙니다.
참고하시구요.
다음에 또 소스 분석할 일 있으면 블로그에 정리해 놓을 께요.
이번 글은 기분 좋게 7번째 만에 마무리 했네요.
|
|
'etc. > PHP' 카테고리의 다른 글
PDF 내용을 Text 로 추출하는 PHP 프로그램 분석해 보기 6 (0) | 2013.01.16 |
---|---|
PDF 내용을 Text 로 추출하는 PHP 프로그램 분석해 보기 5 (0) | 2013.01.15 |
PDF 내용을 Text 로 추출하는 PHP 프로그램 분석해 보기 4 (0) | 2013.01.08 |
PDF 내용을 Text 로 추출하는 PHP 프로그램 분석해 보기 3 (0) | 2013.01.08 |
PDF 내용을 Text 로 추출하는 PHP 프로그램 분석해 보기 2 (0) | 2013.01.08 |
PDF 내용을 Text 로 추출하는 PHP 프로그램 분석해 보기 1 (0) | 2013.01.05 |
PHP와 XSL 로 XML 변환하기 (0) | 2012.12.21 |
PHP로 XML , JSON 다루기 (2) | 2012.08.24 |
-PHP - Proxy 통해 원격 파일 존재 여부 파악하기 (0) | 2012.07.19 |