pdf viewer c# open source : Create pdf bookmarks from word Library SDK class asp.net .net azure ajax calibre17-part875

calibre User Manual, Release 2.56.0
The key parameter here is --url-prefix /calibre. This causes the content server to serve all URLs prefixed
by calibre. To see this in action, visit http://localhost:8080/calibre in your browser. You shouldsee the
normal content server website,but now it will run under/calibre.
Now suppose you are using Apache as your main server. First enable the proxy modules in apache, by adding the
following to httpd.conf:
LoadModule proxy_module modules/mod_proxy.so
LoadModule proxy_http_module modules/mod_proxy_http.so
The exact technique for enabling the proxy modules will vary depending on your Apache installation. Once you have
the proxy modules enabled, add the following rules to httpd.conf (or if you are using virtual hosts to the conf file for
the virtual host in question):
RewriteEngine on
RewriteRule ^/calibre/(.
*
) http://localhost:8080/calibre/$1 [proxy]
RewriteRule ^/calibre http://localhost:8080 [proxy]
SetEnv force-proxy-request-1.0 1
SetEnv proxy-nokeepalive 1
That’s all, you will now be able to access the calibre Content Server under the /calibre URL in your apache server.
The above rules pass allrequests under/calibre to the calibre server running onport 8080and thanks to the –url-prefix
option above,the calibre server handles them transparently.
Note: If you are willing to devote an entire VirtualHost to the content server, then there is no need to use –url-prefix
and RewriteRule, instead just use the ProxyPass directive.
Note: Theserverengine calibre uses,CherryPy,can have trouble withproxying andKeepAlive requests,soturnthem
offin Apache,with the SetEnv directives shown above.
In process
The calibre content servercan berundirectly,in process,inside a host serverlike Apache using the WSGI framework.
Note: For this to work, all the dependencies needed by calibre must be installed on your system. Doing so is highly
non-trivial and you are encouraged not to use in process servers. You will not get any assistance with debugging in
process server problems.
First, we have to create a WSGI adapter for the calibre content server. Here is a template you can use forthe purpose.
Replace the paths as directed in the comments
# WSGI script file to run calibre content server as a WSGI app
import sysos
# You can get the paths referenced here by running
# calibre-debug --paths
# on your server
# The first entry from CALIBRE_PYTHON_PATH
sys.path.insert(0'/home/kovid/work/calibre/src')
1.9. Tutorials
167
Create pdf bookmarks from word - add, remove, update PDF bookmarks in C#.net, ASP.NET, MVC, Ajax, WinForms, WPF
Empower Your C# Project with Rapid PDF Internal Navigation Via Bookmark and Outline
creating bookmarks in a pdf document; add bookmarks to pdf
Create pdf bookmarks from word - VB.NET PDF bookmark library: add, remove, update PDF bookmarks in vb.net, ASP.NET, MVC, Ajax, WinForms, WPF
Empower Your VB.NET Project with Rapid PDF Internal Navigation Via Bookmark and Outline
bookmark pdf in preview; create bookmarks in pdf reader
calibre User Manual, Release 2.56.0
# CALIBRE_RESOURCES_PATH
sys.resources_location '/home/kovid/work/calibre/resources'
# CALIBRE_EXTENSIONS_PATH
sys.extensions_location '/home/kovid/work/calibre/src/calibre/plugins'
# Path to directory containing calibre executables
sys.executables_location '/usr/bin'
# Path to a directory for which the server has read/write permissions
# calibre config will be stored here
os.environ['CALIBRE_CONFIG_DIRECTORY''/var/www/localhost/calibre-config'
del sys
del os
from calibre.library.server.main import create_wsgi_app
application = create_wsgi_app(
# The mount point of this WSGI application (i.e. the first argument to
# the WSGIScriptAlias directive). Set to empty string is mounted at /
prefix='/calibre',
# Path to the calibre library to be served
# The server process must have write permission for all files/dirs
# in this directory or BAD things will happen
path_to_library='/home/kovid/documents/demo library',
# The virtual library (restriction) to be used when serving this
# library.
virtual_library=None
)
del create_wsgi_app
Save this adapter as calibre-wsgi-adpater.py somewhere your serverwill have access to it.
Let’s suppose that we want to use WSGI in Apache. First enable WSGI in Apache by adding the following to
httpd.conf:
LoadModule wsgi_module modules/mod_wsgi.so
The exact technique for enabling the wsgi module will vary depending on your Apache installation. Once you have
the proxy modules enabled, add the following rules to httpd.conf (or if you are using virtual hosts to the conf file for
the virtual host in question:
WSGIScriptAlias /calibre /var/www/localhost/cgi-bin/calibre-wsgi-adapter.py
Change the path to calibre-wsgi-adapter.py to wherever you saved it previously (make sure Apache has
access to it).
That’s all,you will now be able to access the calibre Content Server under the /calibre URL in yourapache server.
Note: For more help with using mod_wsgi in Apache,seemod_wsgi81.
81
http://code.google.com/p/modwsgi/wiki/WhereToGetHelp
168
Chapter 1. Sections
VB.NET PDF File Compress Library: Compress reduce PDF size in vb.
Bookmarks. inputFilePath = Program.RootPath + "\\" 3.pdf"; String outputFilePath = Program.RootPath + "\\" 3_optimized.pdf"; 'create optimizing options
create bookmark in pdf automatically; excel print to pdf with bookmarks
C# PDF File Split Library: Split, seperate PDF into multiple files
Split PDF file by top level bookmarks. The following C# codes explain how to split a PDF file into multiple ones by PDF bookmarks or outlines.
creating bookmarks pdf files; bookmarks pdf file
calibre User Manual, Release 2.56.0
1.9.6 Writing your own plugins to extend calibre’s functionality
calibre has a very modular design. Almost all functionality in calibre comes in the form of plugins. Plugins are used
for conversion,for downloading news (though these are called recipes), for various components of the user interface,
to connect to different devices, to process files when adding themto calibre and so on. You can get a complete list of
all the built-in plugins in calibre bygoing to Preferences->Plugins.
Here,we will teach you how to create your own plugins to add new features to calibre.
Contents
• Anatomyofacalibreplugin(page 169)
• AUserInterfaceplugin(page 170)
– __init__.py(page 171)
– ui.py(page 172)
– main.py(page 173)
– Gettingresourcesfromthepluginzipfile(page 176)
– Enablinguserconfigurationofyourplugin(page 176)
• EditBookplugins(page 178)
– main.py(page 178)
• Addingtranslationstoyourplugin(page 181)
• ThepluginAPI(page 182)
• Debuggingplugins(page 182)
• Morepluginexamples(page 182)
• Sharingyourpluginswithothers(page 182)
Note: This only applies to calibre releases >= 0.8.60
Anatomy of a calibre plugin
Acalibre plugin is very simple, it’s just a zip file that contains some python code and any other resources like image
files needed by the plugin. Without further ado, let’s see a basic example.
Suppose you have aninstallationofcalibrethatyouare usingto selfpublish various e-documents in EPUB andMOBI
formats. You would like all files generated by calibre to have their publisherset as “Hello world”, here’s how to do it.
Create a file named __init__.py (this is a special name and must always be used forthe main file of your plugin)
and enterthe following Python code into it:
import os
from calibre.customize import FileTypePlugin
class HelloWorld(FileTypePlugin):
name
'Hello World Plugin' # Name of the e plugin
description
'Set the publisher r to o Hello World for all l new w conversions'
supported_platforms = ['windows''osx''linux'# Platforms s this plugin n will l run on
author
'Acme Inc.' # The e author of f this plugin
version
(100)
# The version number of this plugin
file_types
set(['epub''mobi']) # The e file types that this plugin will be e applied d to
on_postprocess
True # Run n this plugin after r conversion n is complete
minimum_calibre_version = (0753)
def run(self, path_to_ebook):
1.9. Tutorials
169
VB.NET PDF File Split Library: Split, seperate PDF into multiple
how to split a PDF file into multiple ones by PDF bookmarks or outlines Valid value for each index: 1 to (Page Count - 1). ' Create output PDF file path
bookmarks in pdf reader; copy bookmarks from one pdf to another
C# PDF File Compress Library: Compress reduce PDF size in C#.net
Bookmarks. inputFilePath = Program.RootPath + "\\" 3.pdf"; String outputFilePath = Program.RootPath + "\\" 3_optimized.pdf"; // create optimizing options
create pdf bookmarks online; pdf bookmark
calibre User Manual, Release 2.56.0
from calibre.ebooks.metadata.meta import get_metadata, set_metadata
file open(path_to_ebook, 'r+b')
ext
os.path.splitext(path_to_ebook)[-1][1:].lower()
mi = get_metadata(file, ext)
mi.publisher 'Hello World'
set_metadata(file, mi, ext)
return path_to_ebook
That’s all. To add this code to calibre as a plugin, simply run the following in the directory in which you created
__init__.py:
calibre-customize -.
Note:
On OS X, the command line tools are inside the calibre bundle, for ex-
ample,
if you
installed
calibre
in
/Applications
the
command
line
tools are
in
/Applications/calibre.app/Contents/console.app/Contents/MacOS/.
You candownload the Hello World plugin fromhelloworld_plugin.zip82.
Every time you use calibre to convert a book, the plugin’s run() method will be called and the converted book will
have its publisher set to “Hello World”. This is a trivial plugin,lets move on to a more complex example that actually
adds a component to the user interface.
AUser Interface plugin
This plugin will be spread over a few files (to keep the code clean). It will show you how to get resources (images
or data files) from the plugin zip file, allow users to configure your plugin, how to create elements in the calibre user
interface and how to access and query the books database in calibre.
You can download this plugin frominterface_demo_plugin.zip
83
The first thing to note is that this zip file has a lot
more files in it, explained below,pay particular attention to plugin-import-name-interface_demo.txt.
plugin-import-name-interface_demo.txt An empty text file used to enable the multi-file plugin magic.
This file must be present in all plugins that use more than one .py file. It should be empty and its
filename must be of the form: plugin-import-name-some_name.txt The presence of this file allows
you to import code from the .py files present inside the zip file, using a statement like:
from calibre_plugins.some_name.some_module import some_object
The prefix calibre_plugins must always be present. some_name comes from the filename
of the empty text file. some_module refers to some_module.py file inside the zip file. Note
that this importing is just as powerful as regular python imports. You can create packages and
subpackages of.py modules inside the zipfile,justlike you wouldnormally(by defining__init__.py
in each sub-directory), and everything shouldJust Work.
The name you use for some_name enters a global namespace shared by all plugins, so make it as
unique as possible. But remember that it must be avalid pythonidentifier(onlyalphabets,numbers
and the underscore).
__init__.py As before, the file that defines the pluginclass
main.py This file contains the actual code that does something useful
82
http://calibre-ebook.com/downloads/helloworld_plugin.zip
83
http://calibre-ebook.com/downloads/interface_demo_plugin.zip
170
Chapter 1. Sections
C# Create PDF Library SDK to convert PDF from other file formats
Create multipage PDF from OpenOffice and CSV file. Create and save editable PDF with a blank page, bookmarks, links, signatures, etc.
export pdf bookmarks to text file; export bookmarks from pdf to excel
XDoc.Word for .NET, Advanced .NET Word Processing Features
& rotation; Outlines, bookmarks, & thumbnail display; Integrated annotation; More about Web Viewer ▶. Conversion. Word Create. Create Word from PDF; Create Word
pdf bookmark editor; adding bookmarks to pdf reader
calibre User Manual, Release 2.56.0
ui.py This file defines the interface part of the plugin
images/icon.png The icon for this plugin
about.txt A text file with information about the plugin
translations A folder containing .mo files with the translations of the user interface of your plugin into
different languages. See below fordetails.
Now let’s look at the code.
__init__.py
First, the obligatory __init__.py to define the plugin metadata:
# The class that all Interface Action plugin wrappers must inherit from
from calibre.customize import InterfaceActionBase
class InterfacePluginDemo(InterfaceActionBase):
'''
This class is a simple wrapper that provides information about the actual
plugin class. The actual interface plugin class is called InterfacePlugin
and is defined in the ui.py file, as specified in the actual_plugin field
below.
The reason for having two classes is that it allows the command line
calibre utilities to run without needing to load the GUI libraries.
'''
name
'Interface Plugin n Demo'
description
'An advanced d plugin n demo'
supported_platforms = ['windows''osx''linux']
author
'Kovid Goyal'
version
(100)
minimum_calibre_version = (0753)
#: This field defines the GUI plugin class that contains all the code
#: that actually does something. Its format is module_path:class_name
#: The specified class must be defined in the specified module.
actual_plugin
'calibre_plugins.interface_demo.ui:InterfacePlugin'
def is_customizable(self):
'''
This method must return True to enable customization via
Preferences->Plugins
'''
return True
def config_widget(self):
'''
Implement this method and :meth:`save_settings` in your plugin to
use a custom configuration dialog.
This method, if implemented, must return a QWidget. The widget can have
an optional method validate() that takes no arguments and is called
immediately after the user clicks OK. Changes are applied if and only
if the method returns True.
If for some reason you cannot perform the configuration at this time,
return a tuple of two strings (message, details), these will be
1.9. Tutorials
171
.NET PDF SDK - Description of All PDF Processing Control Feastures
& rotation; Outlines, bookmarks, & thumbnail display; Integrated annotation; More about Web Viewer ▶. Conversion. PDF Create. Create PDF from Word (docx, doc
add bookmark pdf; editing bookmarks in pdf
VB.NET Create PDF Library SDK to convert PDF from other file
Create multipage PDF from OpenOffice and CSV file. Create and save editable PDF with a blank page, bookmarks, links, signatures, etc.
display bookmarks in pdf; export pdf bookmarks to text
calibre User Manual, Release 2.56.0
displayed as a warning dialog to the user and the process will be
aborted.
The base class implementation of this method raises NotImplementedError
so by default no user configuration is possible.
'''
# It is important to put this import statement here rather than at the
# top of the module as importing the config class will also cause the
# GUI libraries to be loaded, which we do not want when using calibre
# from the command line
from calibre_plugins.interface_demo.config import ConfigWidget
return ConfigWidget()
def save_settings(self, config_widget):
'''
Save the settings specified by the user with config_widget.
:param config_widget: The widget returned by :meth:`config_widget`.
'''
config_widget.save_settings()
# Apply the changes
ac self.actual_plugin_
if ac is not None:
ac.apply_settings()
The onlynoteworthy feature is the fieldactual_plugin. Since calibre has both command line andGUIinterfaces,
GUI plugins like this one should not load any GUI libraries in __init__.py. The actual_plugin field does this for you,
bytelling calibre that the actual pluginis to be found inanotherfile inside your ziparchive, which will only be loaded
in a GUI context.
Remember that for this to work, you must have a plugin-import-name-some_name.txt file in your plugin zip file, as
discussed above.
Also there are a couple of methods forenabling user configuration ofthe plugin. These are discussed below.
ui.py
Nowlet’s lookat ui.py which defines the actual GUIplugin. The source code is heavily commented and shouldbe self
explanatory:
# The class that all interface action plugins must inherit from
from calibre.gui2.actions import InterfaceAction
from calibre_plugins.interface_demo.main import DemoDialog
class InterfacePlugin(InterfaceAction):
name 'Interface Plugin n Demo'
# Declare the main action associated with this plugin
# The keyboard shortcut can be None if you dont want to use a keyboard
# shortcut. Remember that currently calibre has no central management for
# keyboard shortcuts, so try to use an unusual/unused shortcut.
action_spec = ('Interface Plugin Demo'None,
'Run the Interface Plugin Demo', 'Ctrl+Shift+F1')
172
Chapter 1. Sections
calibre User Manual, Release 2.56.0
def genesis(self):
# This method is called once per plugin, do initial setup here
# Set the icon for this interface action
# The get_icons function is a builtin function defined for all your
# plugin code. It loads icons from the plugin zip file. It returns
# QIcon objects, if you want the actual data, use the analogous
# get_resources builtin function.
#
# Note that if you are loading more than one icon, for performance, you
# should pass a list of names to get_icons. In this case, get_icons
# will return a dictionary mapping names to QIcons. Names that
# are not found in the zip file will result in null QIcons.
icon = get_icons('images/icon.png')
# The qaction is automatically created from the action_spec defined
# above
self.qaction.setIcon(icon)
self.qaction.triggered.connect(self.show_dialog)
def show_dialog(self):
# The base plugin object defined in __init__.py
base_plugin_object self.interface_action_base_plugin
# Show the config dialog
# The config dialog can also be shown from within
# Preferences->Plugins, which is why the do_user_config
# method is defined on the base plugin class
do_user_config = base_plugin_object.do_user_config
# self.gui is the main calibre GUI. It acts as the gateway to access
# all the elements of the calibre user interface, it should also be the
# parent of the dialog
= DemoDialog(self.gui, self.qaction.icon(), do_user_config)
d.show()
def apply_settings(self):
from calibre_plugins.interface_demo.config import prefs
# In an actual non trivial plugin, you would probably need to
# do something based on the settings in prefs
prefs
main.py
The actual logic to implement the Interface Plugin Demo dialog.
from PyQt5.Qt import QDialog, QVBoxLayout, QPushButton, , QMessageBox, , QLabel
from calibre_plugins.interface_demo.config import prefs
class DemoDialog(QDialog):
def __init__(self, gui, icon, do_user_config):
QDialog.__init__(self, gui)
self.gui gui
self.do_user_config do_user_config
1.9. Tutorials
173
calibre User Manual, Release 2.56.0
# The current database shown in the GUI
# db is an instance of the class LibraryDatabase from db/legacy.py
# This class has many, many methods that allow you to do a lot of
# things. For most purposes you should use db.new_api, which has
# a much nicer interface from db/cache.py
self.db gui.current_db
self.QVBoxLayout()
self.setLayout(self.l)
self.label QLabel(prefs['hello_world_msg'])
self.l.addWidget(self.label)
self.setWindowTitle('Interface Plugin n Demo')
self.setWindowIcon(icon)
self.about_button QPushButton('About', self)
self.about_button.clicked.connect(self.about)
self.l.addWidget(self.about_button)
self.marked_button QPushButton(
'Show books with only one format in the calibre GUI'self)
self.marked_button.clicked.connect(self.marked)
self.l.addWidget(self.marked_button)
self.view_button QPushButton(
'View the most recently added book'self)
self.view_button.clicked.connect(self.view)
self.l.addWidget(self.view_button)
self.update_metadata_button QPushButton(
'Update metadata in a book\'s files'self)
self.update_metadata_button.clicked.connect(self.update_metadata)
self.l.addWidget(self.update_metadata_button)
self.conf_button QPushButton(
'Configure this plugin'self)
self.conf_button.clicked.connect(self.config)
self.l.addWidget(self.conf_button)
self.resize(self.sizeHint())
def about(self):
# Get the about text from a file inside the plugin zip file
# The get_resources function is a builtin function defined for all your
# plugin code. It loads files from the plugin zip file. It returns
# the bytes from the specified file.
#
# Note that if you are loading more than one file, for performance, you
# should pass a list of names to get_resources. In this case,
# get_resources will return a dictionary mapping names to bytes. Names that
# are not found in the zip file will not be in the returned dictionary.
text = get_resources('about.txt')
QMessageBox.about(self'About the e Interface Plugin Demo',
text.decode('utf-8'))
def marked(self):
''' Show books with only one format '''
174
Chapter 1. Sections
calibre User Manual, Release 2.56.0
db self.db.new_api
matched_ids = {book_id for book_id in db.all_book_ids() if len(db.formats(book_id)) == 1}
# Mark the records with the matching ids
# new_api does not know anything about marked books, so we use the full
# db object
self.db.set_marked_ids(matched_ids)
# Tell the GUI to search for all marked records
self.gui.search.setEditText('marked:true')
self.gui.search.do_search()
def view(self):
''' View the most recently added book '''
most_recent = most_recent_id None
db self.db.new_api
for book_id, timestamp in db.all_field_for('timestamp', db.all_book_ids()).iteritems():
if most_recent is None or timestamp most_recent:
most_recent = timestamp
most_recent_id = book_id
if most_recent_id is not None:
# Get a reference to the View plugin
view_plugin self.gui.iactions['View']
# Ask the view plugin to launch the viewer for row_number
view_plugin._view_calibre_books([most_recent_id])
def update_metadata(self):
'''
Set the metadata in the files in the selected book's record to
match the current metadata in the database.
'''
from calibre.ebooks.metadata.meta import set_metadata
from calibre.gui2 import error_dialog, info_dialog
# Get currently selected books
rows self.gui.library_view.selectionModel().selectedRows()
if not rows or len(rows) == 0:
return error_dialog(self.gui, 'Cannot update e metadata',
'No books selected', show=True)
# Map the rows to book ids
ids list(map(self.gui.library_view.model().id, rows))
db self.db.new_api
for book_id in ids:
# Get the current metadata for this book from the db
mi = db.get_metadata(book_id, get_cover=True, cover_as_data=True)
fmts = db.formats(book_id)
if not fmts:
continue
for fmt in fmts:
fmt = fmt.lower()
# Get a python file object for the format. This will be either
# an in memory file or a temporary on disk file
ffile = db.format(book_id, fmt, as_file=True)
ffile.seek(0)
# Set metadata in the format
set_metadata(ffile, mi, fmt)
ffile.seek(0)
# Now replace the file in the calibre library with the updated
1.9. Tutorials
175
calibre User Manual, Release 2.56.0
# file. We dont use add_format_with_hooks as the hooks were
# already run when the file was first added to calibre.
db.add_format(book_id, fmt, ffile, run_hooks=False)
info_dialog(self'Updated files',
'Updated the metadata in the files of %d book(s)'%len(ids),
show=True)
def config(self):
self.do_user_config(parent=self)
# Apply the changes
self.label.setText(prefs['hello_world_msg'])
Gettingresources from the pluginzipfile
calibre’s plugin loading system defines a couple ofbuilt-in functions that allow you to conveniently get files from the
plugin zip file.
get_resources(name_or_list_of_names) This function should be called witha listofpaths tofiles inside
the zip file. For example toaccess the file icon.png in the directory images inthe zip file, you would
use: images/icon.png. Always use a forward slash as the path separator, even on windows.
When you pass in a single name, the function will return the raw bytes of that file or None if the
name was not found in the zip file. Ifyou pass in more than one name then it returns a dict mapping
the names to bytes. If a name is not found, it will not be present in the returned dict.
get_icons(name_or_list_of_names) A convenience wrapper for get_resources() that creates QIcon ob-
jects from the raw bytes returned by get_resources. If a name is not found in the zip file the corre-
spondingQIcon will be null.
Enabling user configuration of your plugin
To allow users to configure your plugin, you must define three methods in your base plugin class, ‘is_customizable,
config_widget and save_settings as shown below:
def is_customizable(self):
'''
This method must return True to enable customization via
Preferences->Plugins
'''
return True
def config_widget(self):
'''
Implement this method and :meth:`save_settings` in your plugin to
use a custom configuration dialog.
This method, if implemented, must return a QWidget. The widget can have
an optional method validate() that takes no arguments and is called
immediately after the user clicks OK. Changes are applied if and only
if the method returns True.
If for some reason you cannot perform the configuration at this time,
return a tuple of two strings (message, details), these will be
displayed as a warning dialog to the user and the process will be
176
Chapter 1. Sections
Documents you may be interested
Documents you may be interested