Latex 書籤中文亂碼解決方案

來源:互聯網
上載者:User

Latex 書籤中文亂碼解決方案

作者:playerc

本文連結:http://www.cnblogs.com/playerc/archive/2013/05/20/latex_utf8_bookmark_c.html

最近使用 pdflatex 寫文檔的時候,發現 utf8 書籤中文出現亂碼,網上搜尋,發現一個有價值的解決方案。

他使用一個 python 實現的轉碼方案。下文中簡稱 方案1

http://www.thinkemb.com/wordpress/?p=260

我就照著寫了個 c 語言的。程式的原理在 方案1 中說的很明白,就是  pdflatex 產生含有 書籤或目錄 的pdf檔案時,需要執行兩次,第一次先產生一些準備檔案,比如  *.out ,這個檔案就是儲存了書籤資訊。第二次再根據第一次產生的檔案產生 含有書籤或目錄的 pdf 檔案,也就是說,第一次執行時,產生的pdf檔案不包含書籤或目錄。

關於書籤亂碼的原因,就是當pdf閱讀器讀取書籤時,只能識別 UNICODE 編碼,當我們使用的tex文本環境是utf8或gbk 編碼時,產生的 *.out 也就使用了 utf8或gbk編碼,產生的pdf也同樣保留了編碼。所以pdf書籤中包含的非 ascii 字元就出現亂碼了。

這個 轉換工具 所做的工作,就是把 *.out 中書籤名字串由 utf8編碼轉換成unicode 編碼。需要用到 utf8 編碼知識,和 unicode編碼知識。

使用gcc 或 vs 編譯後,使用命令列,運行

  utf82uni  <  src.out  > dst .out

src.out 是準備轉換的檔案,dst.out是轉換後的檔案。

/** * utf82uni.c -- translate bookmark names  in Latex's .out file,Utf8 encoded to Unicode; 
* compile: cc -o utf82uni utf82uni.c */#include<stdio.h>#define UNICODE_PREFIX "\\376\\377"#define UTF8_MAX_BYTES (6)#define UTF8_THREE (14)void init_int_array(int * array, int length){ while(length>0){ *(array+(--length)) = 0; }}//eo init_int_arrayint main(int argc,char *argv[]){ int bi; //byte number int str[UTF8_MAX_BYTES]={0}; //all byte int gb[2]={0}; int i; int is_begin = 0; //is begin translate int count_brace = 0; int is_brace_begin = 0; int is_brace_end = 0; int is_line_end = 0; while(!feof(stdin)){ i=0; init_int_array(str,UTF8_MAX_BYTES); bi = fread(&str[0],1,1,stdin); is_brace_begin = ((str[0]&0x7f) == '{') ? 1:0; is_brace_end = (str[0]&0x7f) =='}' ? 1:0; is_line_end = (str[0]&0x7f)=='\n' ? 1:0; if(is_brace_begin||is_brace_end){ count_brace ++; }else if(is_line_end){ count_brace=0; } if((count_brace !=3) || is_brace_begin ||is_brace_end){ fwrite(&str[0],bi,1,stdout); is_begin = 0; continue; } // count_brace == 3 ,translate Utf8 code to Unicode with \ooo format; if(is_begin == 0){ printf(UNICODE_PREFIX); is_begin = 1; } if(((str[0]>>4)&0xff)== UTF8_THREE ){ bi = 3; for(i=1; (i< bi) && (!feof(stdin)); i++){ fread(&str[i], 1, 1, stdin); } init_int_array(gb, 2); /** * 1110xxxx , 10 xxxx xx , 10 xxxxxx */ gb[0] = ((str[0]<<4)&0xF0)|((str[1]>>2)&0x0F); gb[1] = ((str[1]<<6)& 0xF0) | ((str[2])& 0x3F); printf("\\%03o\\%03o",gb[0],gb[1]); }else{ printf("\\%03o\\%03o",0,(str[0])&0x7f); } }//eof while return 0;}//eof main

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.