1. 程式人生 > >自己動手寫AdobeReader書籤外掛——PDF也支援書籤

自己動手寫AdobeReader書籤外掛——PDF也支援書籤

最近經常看一些PDF的電子文件,痛苦的是Adobe Reader竟然沒有提供書籤的功能,每次看完之後再回到上次看的地方都很麻,到網上一找,還真有人就做了PDF的書籤,下載一試效果不錯,於是參看了一下Adobe Reader的SDK,修改了一點地方,以更方便的使用,下面是程式的使用方法

1、開啟編輯的首選項項


2、確保下面的選項都被選中


3、把下面的程式碼儲存為一個bookmark_page.js檔案

// bookmark_page.js, ver. 1.0
// visit: www.pdfhacks.com/bookmark_page/
// edit:cjs 2008-02-17 
// 1 修改為中文標籤
// 2 設定書籤時可以自動獲取當前的書名
// 3 自動獲取當前所在的頁碼與總頁數,方便查閱
// 4 實現更多功能可以參看Adobe Reader的SDK


// use this delimiter for serializing our array
var bp_delim= '%#%#';

function SaveData( data ) 
{
// data is an array of arrays that needs
// to be serialized and stored into a persistent
// global string
var ds= ';
for( ii= 0; ii< data.length; ++ii )
{
   for( jj= 0; jj< 3; ++jj ) 
   {
    if( ii!= 0 || jj!= 0 )
     ds+= bp_delim;
    ds+= data[ii][jj];
   }
}
global.pdf_hacks_js_bookmarks= ds;
global.setPersistent( "pdf_hacks_js_bookmarks", true );
}

function GetData() {
// reverse of SaveData; return an array of arrays
if( global.pdf_hacks_js_bookmarks== null ) {
   return new Array(0);
}

var flat= global.pdf_hacks_js_bookmarks.split( bp_delim );
var data= new Array();
for( ii= 0; ii< flat.length; ) {
   var record= new Array();
   for( jj= 0; jj< 3 && ii< flat.length; ++ii, ++jj ) {
    record.push( flat[ii] );
   }
   if( record.length== 3 ) {
    data.push( record );
   }
}
return data;
}

//Get Current Date
function DateNow(){
var d, s ;
d = new Date();
s = d.getFullYear()+"/";
s += (d.getMonth() + 1) + "/";
s += d.getDate() ;
/**//*
   s += d.getHours() + ":";
   s += d.getMinutes() + ":";
   s += d.getSeconds() ;
*/
return(s);
}


function AddBookmark() {
// query the user for a name, and then combine it with
// the current PDF page to create a record; store this record
var thisfilename=this.documentFileName;
thisfilename=thisfilename.substr(0,thisfilename.lastIndexOf("."));
var numPlugInss=this.pageNum+1;
var currentdate=DateNow();
var label= 
   app.response( "書籤名稱,可以修改以便於記憶:",
   "書籤名稱",
   "《"+thisfilename+"》第 "+numPlugInss+" 頁/共 "+this.numPages+" 頁 "+currentdate,
   false );
if( label!= null ) {
   var record= new Array(3);
   record[0]= label;
   record[1]= this.path;
   record[2]= this.pageNum;
   data= GetData();
   data.push( record );
   SaveData( data );
}
}

function ShowBookmarks() {
// show a pop-up menu; this seems to only work when
// a PDF is alreay in the viewer;
var data= GetData();
var items= ';
for( ii= 0; ii< data.length; ++ii ) {
   if( ii!= 0 )
    items+= ', ';
   items+= '"'+ ii+ ': '+ data[ii][0]+ '"';
}
// assemble the command and the execute it with eval()
var command= 'app.popUpMenu( '+ items+ ' );';
var selection= eval( command );
if( selection== null ) {
   return; // exit
}

// the user made a selection; parse out its index and use it
// to access the bookmark record
var index= 0;
// toString() converts the String object to a string literal
// eval() converts the string literal to a number
index= eval( selection.substring( 0, selection.indexOf(':') ).toString() );
if( index< data.length ) {
   try {
    // the document must be 'disclosed' for us to have any access
    // to its properties, so we use these FirstPage NextPage calls
    //
    app.openDoc( data[index][1] );
    app.execMenuItem( "FirstPage" );
    for( ii= 0; ii< data[index][2]; ++ii ) {
     app.execMenuItem( "NextPage" );
    }
   }
   catch( ee ) {
    var response= 
     app.alert("開啟書籤錯誤. 是否刪除本書籤?", 2, 2,"刪除書籤");
    if( response== 4 && index< data.length ) {
     data.splice( index, 1 );
     SaveData( data );
    }
   }
}
}

function DropBookmark() {
// modelled after ShowBookmarks()
var data= GetData();
var items= ';
for( ii= 0; ii< data.length; ++ii ) {
   if( ii!= 0 )
    items+= ', ';
   items+= '"'+ ii+ ': '+ data[ii][0]+ '"';
}
var command= 'app.popUpMenu( '+ items+ ' );';
var selection= eval( command );
if( selection== null ) {
   return; // exit
}

var index= 0;
index= eval( selection.substring( 0, selection.indexOf(':') ).toString() );
if( index< data.length ) {
   data.splice( index, 1 );
   SaveData( data );
}
}

function ClearBookmarks() {
if( app.alert("確認要清除所有的書籤嗎?", 2, 2,"刪除書籤" )== 4 ) {
   SaveData( new Array(0) );
}
}

app.addMenuItem( {
cName: "-",              // menu divider
cParent: "View",         // append to the View menu
cExec: "void(0);" } );
    
    app.addMenuItem( {
cName: "設定本頁為書籤(&B)",
cParent: "View",
cExec: "AddBookmark();",
cEnable: "event.rc= (event.target != null);" } );
    
    app.addMenuItem( {
cName: "轉到指定書籤(&T)",
cParent: "View",
cExec: "ShowBookmarks();",
cEnable: "event.rc= (event.target != null);" } );
    //cEnable: "event.rc= true;" } );
    
    app.addMenuItem( {
cName: "刪除一個書籤(&D)",
cParent: "View",
cExec: "DropBookmark();",
cEnable: "event.rc= (event.target != null);" } );
    
    app.addMenuItem( {
cName: "清除所有書籤(&C)",
cParent: "View",
cExec: "ClearBookmarks();",
cEnable: "event.rc= true;" } );


4、將檔案拷貝到D:\Program Files\Reader 9.0\Reader\Javascripts目錄下

      注:請注意檢視自己的版本是否是8.0以上的,不是的話不保證支援。

5、重新開啟Adobe Reader,等待10秒,看看下面的圖形,相信不用說任何東西,大家都會用了


相關推薦

自己動手AdobeReader書籤外掛——PDF支援書籤

最近經常看一些PDF的電子文件,痛苦的是Adobe Reader竟然沒有提供書籤的功能,每次看完之後再回到上次看的地方都很麻,到網上一找,還真有人就做了PDF的書籤,下載一試效果不錯,於是參看了一下Adobe Reader的SDK,修改了一點地方,以更方便的使用,下面是程式的

自己動手一個Vue外掛(MD.7)

造不完的輪子,封不完的外掛。網上什麼都有,但是有那找的功夫,自己都寫完了。漫島仍然在向前推進,只是你們看不到最新的更新內容了,剩餘的不會展示,等以後上線了再去看把。 講一下如何寫一個的Vue外掛,(以一個極其簡單的loading效果為例),會了這個其他不愁。 第一步,在compon

自己動手Android外掛化框架,讓老闆對你刮目相看

歡迎大家前往騰訊雲+社群,獲取更多騰訊海量技術實踐乾貨哦~ 本文由達文西發表於雲+社群專欄 最近在工作中接觸到了Android外掛內的開發,發現自己這種技術還缺乏最基本的瞭解,以至於在一些基本問題上浪費不少時間,如外掛Context和主工程Context的區別,許可權必須在主工程申明等,因此花了點時間瞭解

自己動手Docker》PDF

點選下載; 《自己動手寫Docker》 內容簡介 · · · · · · 本書在詳細分析Docker所依賴的技術棧的基礎上,一步一步地通過程式碼例項,讓讀者可以自己循序漸進地用Go語言構建出一個容器的引擎。不同於其他Docker原理介紹或程式碼剖析的

自己動手一個Android Studio外掛

1.介紹 官方文件 在使用Android Studio開發的時候,大部分人都會使用一些外掛來提高開發效率,比如: 像這樣的外掛還有很多很多,但我們不能一直停留在用的程度,這樣太不符合程式猿的風格了,今天就讓我們自己動手來寫一個外掛,當以後自己有好的想法

自己動手一個自動登錄腳本gg

簡單 只需要 自己 不同 enum -s class rep 使用 1.下載一個sshpass工具 2.安裝sshpass,安裝到tools文件夾 3.把tools文件夾的路徑加入到/etc/bashrc vim /etc/bashrc

自己動手javaEE框架-為jqgrid換換皮膚然後加到我的框架裏

就會 cts 客戶 換膚 解析json 狀態 src demo 導航 軟件151 蘇垚  今天讓我倒騰半天的居然不是寫我的javaEE框架,而是更換jqgrid的皮膚。我是相當的討厭jqgrid的默認皮膚,它總讓我想起一直想學而都沒學過的EXTJS,看多了那種淡藍色

自己動手CPU之第九階段(2)——載入存儲指令說明2(lwl、lwr)

上傳 open 送書 運算 ada 讀者 str ast base 將陸續上傳新書《自己動手寫CPU》。今天是第38篇,我盡量每周四篇,可是近期已經非常久沒有實現這個目標了。一直都有事,不好意思哈。 開展曬書評送書活動,在q=%E4%BA%9A%E9%A9%A

自己動手Java String類

實現string ins cas 沒有 min 操作方法 str2 override 英文 很早想造個輪子了,聽說不想造輪子的程序員不是好程序員,用慣了Apache的眾多開源項目,卻沒看過開源一句代碼。最近看了幾篇賣焦慮的文章之後,突然變得慌張起來,於是在百忙之中難得一點閑

自己動手一個單鏈表

兩個指針 isl linklist nextn mob 內部 數組 nds pty 文章有不當之處,歡迎指正,如果喜歡微信閱讀,你也可以關註我的微信公眾號:好好學java,獲取優質學習資源。 一、概述 單向鏈表(單鏈表)是鏈表的一種,其特點是鏈表的鏈接方向是單向的,對鏈表

【原創】自己動手一個服務網關

exception 負責 lis world 前置 create ble ddr load 引言 什麽是網關?為什麽需要使用網關? 如圖所示,在不使用網關的情況下,我們的服務是直接暴露給服務調用方。當調用方增多,勢必需要添加定制化訪問權限、校驗等邏輯。當添加API網關後,

自己動手SSO(單點登錄)

getattr apach tpc style inter -m commons getwriter servle SSO在我們的應用中非常常見,例如我們在OA系統登錄了,我們就可以直接進入采購系統,不需要再登錄了,這樣使我們非常方便。

自己動手爬蟲》筆記

《自己動手寫爬蟲》這本書總體介紹了整個網路爬蟲由淺入深的知識體系,將爬蟲中每個部分分割開來具體的細講,非常適合新手來入門,由於之前只知道使用爬蟲框架,所以一遇到一些錯誤或者想調整一些爬架內容就無從下手,所以還是將一些基礎知識弄明白之後再去使用框架就會得心應手了。書中關於當前的分散式爬蟲的

Java併發程式設計:自己動手一把可重入鎖

關於執行緒安全的例子,我前面的文章Java併發程式設計:執行緒安全和ThreadLocal裡面提到了,簡而言之就是多個執行緒在同時訪問和修改公共資源的時候,由於不同執行緒搶佔CPU問題而導致的結果不確定性,就是在併發程式設計中經常要考慮的執行緒安全問題。前面的做法是使用同步語句synch

自己動手StringBuilder類

繼上一篇自己動手寫Java String類之後,今晚10點鐘下班,感覺稍早,於是手癢癢就想自己動手來寫StringBulder,畢竟程式設計師啥都講究自己動手才能豐衣足食嘛!StringBuilder與String類的區別是String的變數內容是放在final char[]裡面的,而S

自己動手CPU Chapter3

3.1教學版OpenMIPS處理器藍圖 OpenMIPS設計目標    ​ 3.2三級流水線示意圖 ​     但是會有問題,假如的話時間不一致的時候如下,解決取值時間過長的措施是引入快取Cache,處理器從快取讀入資料只需要一個週

自己動手一個小型的TCP/IP協議

TCP/IP協議大家都知道,但真正理解的人不多,不如動手寫一個小型的看看。 我知道看書很枯燥,看不懂,還打擊大家的信心,不是我們的腦袋不如人,是我們的方法錯了。 一切的技術都從應用中發展而來,所以要從下往上走,先動手完成一個任務吧。 需要準備的前提知識 linux驅動程式知識

自己動手java虛擬機器》學習筆記(六)-----解析class檔案(java)

專案地址:https://github.com/gongxianshengjiadexiaohuihui 註釋都寫的很清楚,有一些概念問題,請參考go版本的實現 目錄結構 首先是位元組轉換工具,因為java和go的類庫不同,另外需注意class檔案是大端儲存方式(高位元組放低地址,

自己動手java虛擬機器》學習筆記(五)-----解析class檔案(go)

         專案地址:https://github.com/gongxianshengjiadexiaohuihui   上一節,我們已經通過路徑找到了指定的class檔案,這一節,我們開始解析class檔案,我們知道class檔

自己動手java虛擬機器》學習筆記(四)-----搜尋class檔案(java)

  專案地址:https://github.com/gongxianshengjiadexiaohuihui 首先是定義一個抽象類,把四種路徑的格式抽象出來 Entry.java package classpath; import java.io.IOException;