./PaxHeaders.5700/cb2bib-2.0.10000644000000000000000000000013014011522521012354 xustar0029 mtime=1613145425.31062032 30 atime=1613145424.814620334 29 ctime=1613145425.31062032 cb2bib-2.0.1/0000755000175000001440000000000014011522521013675 5ustar00constansusers00000000000000cb2bib-2.0.1/PaxHeaders.5700/cb2bib.pro0000644000000000000000000000007414011522151014147 xustar0030 atime=1613145424.814620334 30 ctime=1613145424.298620349 cb2bib-2.0.1/cb2bib.pro0000644000175000001440000000012314011522151015535 0ustar00constansusers00000000000000SUBDIRS += src/c2b/c2blib.pro src win32 { SUBDIRS += src/win } TEMPLATE = subdirs cb2bib-2.0.1/PaxHeaders.5700/configure0000644000000000000000000000007414011522151014206 xustar0030 atime=1613145424.814620334 30 ctime=1613145424.370620347 cb2bib-2.0.1/configure0000755000175000001440000003021514011522151015604 0ustar00constansusers00000000000000#!/bin/sh #------------------------------------------------------------------------------ # cb2Bib configuration script: # - Checks for QTDIR # -- If set, checks for qmake at QTDIR # -- If not set, checks for qmake at PATH and other usual locations # - Manages Installation directory data # - Runs qmake # # Modifications for the cb2Bib Gentoo build descriptions # by Hugo Mildenberger and Andreas K. Huettel # Copyright 2009 Hugo Mildenberger and Andreas K. Huettel # - December 2009: do not use temporary files, fix sed regular # expression, set both enable/disable for options, and add # call to qmake option. # # Modifications for the cb2Bib Debian distribution package # by Filippo Rusconi # Copyright 2009 Filippo Rusconi # - June 2009: replace ' ' with ':' along with use of IFS=: as # word-splitting delimiter for PATH-related tasks (Thanks Lionel # Mamane). # - September 2009: protect all shell variables against spaces. # #------------------------------------------------------------------------------ # ( originally based upon 'shell script to configure doxygen', # http://www.stack.nl/~dimitri/doxygen/ # Copyright (C) 1997-2001 by Dimitri van Heesch ) # # Permission to use, copy, modify, and distribute this software and its # documentation under the terms of the GNU General Public License is hereby # granted. No representations are made about the suitability of this software # for any purpose. It is provided "as is" without express or implied warranty # See the GNU General Public License for more details #------------------------------------------------------------------------------ platform=`uname -s` echo echo "Configuration script for cb2Bib (Unix/Linux/MacOSX)" echo f_prefix=/usr f_bindir=/usr/bin f_datadir=/usr/share/cb2bib f_desktopdatadir=/usr/share/applications f_icondir=/usr/share/pixmaps f_qmake=NO f_make=NO f_enable_cbpoll=NO f_enable_lz4=y f_enable_lzo=NO f_enable_lzsse=NO f_enable_qt_zlib=NO f_enable_avx2=NO f_disable_qmake_call=NO while test -n "$1"; do case $1 in --prefix | -prefix) shift; f_prefix="$1" ; f_bindir="$1/bin" ; f_datadir="$1/share/cb2bib" ; f_desktopdatadir="$1/share/applications" ; f_icondir="$1/share/pixmaps" ;; --bindir | -bindir) shift; unset f_prefix ; f_bindir="$1" ;; --datadir | -datadir) shift; unset f_prefix ; f_datadir="$1/cb2bib" ;; --desktopdatadir | -desktopdatadir) shift; unset f_prefix ; f_desktopdatadir="$1" ;; --icondir | -icondir) shift; unset f_prefix ; f_icondir="$1" ;; --qmakepath | -qmakepath) shift; unset f_qmake ; f_qmake="$1" ;; -h | --help | -help) f_help=y ;; --enable-cbpoll | -enable-cbpoll) f_enable_cbpoll=y ;; --disable-cbpoll | -disable-cbpoll) f_enable_cbpoll=NO ;; --enable-lzo | -enable-lzo) f_enable_lz4=NO ; f_enable_lzo=y ; f_enable_lzsse=NO ; f_enable_qt_zlib=NO ;; --enable-lzsse | -enable-lzsse) f_enable_lz4=NO ; f_enable_lzO=NO ; f_enable_lzsse=y ; f_enable_qt_zlib=NO ;; --enable-qt-zlib | -enable-qt-zlib) f_enable_lz4=NO ; f_enable_lzO=NO ; f_enable_lzsse=NO ; f_enable_qt_zlib=y ;; --enable-lz4 | -enable-lz4) f_enable_lz4=y ; f_enable_lzO=NO ; f_enable_lzsse=NO ; f_enable_qt_zlib=NO ;; --enable-avx2 | -enable-avx2) f_enable_avx2=y ;; --enable-qmake-call | -enable-qmake-call) f_disable_qmake_call=NO ;; --disable-qmake-call | -disable-qmake-call) f_disable_qmake_call=y ;; *) echo "-----------------------------------------------------------------------" echo Error: Unknown argument $1 echo "-----------------------------------------------------------------------" echo "" f_help=y f_error=y ;; esac shift done if test "$f_help" = y; then cat </dev/null | grep GNU`"; then make_prog="$j/$i" break 2 fi fi done done unset IFS f_make="$make_prog" fi if test "$f_make" != NO; then echo "using $f_make." else echo "not found." fi #- Setting dirs and start qmake ----------------------------------------------- echo sed -i -e 's%^.*cb2bibdata\.path .*$%cb2bibdata.path = '$f_datadir'%g' \ -e 's%^.*cb2bibdoc\.path .*$%cb2bibdoc.path = '$f_datadir'/doc%g' \ -e 's%^.*target\.path .*$%target.path = '$f_bindir'%g' \ -e 's%^.*script\.path .*$%script.path = '$f_bindir'%g' \ -e 's%^.*desktop\.path .*$%desktop.path = '$f_desktopdatadir'%g' \ -e 's%^.*icons\.path .*$%icons.path = '$f_icondir'%g' src/src.pro sed -i 's%^const QLatin1String C2B_DATA_DIR.*$%const QLatin1String C2B_DATA_DIR("'$f_datadir'/");%g' src/c2b/cb2bib_parameters.h f_configs= if test "$f_enable_cbpoll" = y; then echo "Setting clipboardPoll enabled" f_configs="$f_configs -config enable_cbpoll" fi if test "$f_enable_lz4" = y; then echo "Setting LZ4 enabled" f_configs="$f_configs -config use_lz4" fi if test "$f_enable_lzo" = y; then echo "Setting LZO enabled" f_configs="$f_configs -config use_lzo" fi if test "$f_enable_lzsse" = y; then echo "Setting LZSSE enabled" f_configs="$f_configs -config use_lzsse" fi if test "$f_enable_qt_zlib" = y; then echo "Setting Qt ZLIB enabled" f_configs="$f_configs -config use_qt_zlib" fi if test "$f_enable_avx2" = y; then echo "Setting AVX2 enabled" f_configs="$f_configs -config use_avx2" fi if test "$f_disable_qmake_call" = NO; then echo "" echo "Running $f_qmake $f_configs -o Makefile" "$f_qmake" $f_configs -o Makefile else echo "" echo "Writing qmake flags to file 'qmake-additional-args'" echo $f_configs > qmake-additional-args fi echo " " if test "$f_make" = NO; then echo "-----------------------------------------------------------------------" echo "Configuration ended. 'make' not found." echo "Build toolchain might not be completed." echo "-----------------------------------------------------------------------" exit 1 else echo "-----------------------------------------------------------------------" echo "- NOTE: Type 'make distclean' or, preferably, untar again to set other" echo " configure flags." echo "-----------------------------------------------------------------------" echo " " echo "-----------------------------------------------------------------------" if test "$f_disable_qmake_call" = NO; then echo "Configuration ended. Type 'make' and 'make install'." else echo "Configuration ended. Run qmake, and type 'make' and 'make install'." fi echo "-----------------------------------------------------------------------" echo " " fi cb2bib-2.0.1/PaxHeaders.5700/CHANGELOG0000644000000000000000000000013214011522520013507 xustar0030 mtime=1613145424.322620348 30 atime=1613145424.814620334 30 ctime=1613145424.322620348 cb2bib-2.0.1/CHANGELOG0000644000175000001440000011445014011522520015113 0ustar00constansusers000000000000002021-02-12 RELEASE OF VERSION 2.0.1 2021-02-10 Updated documentation 2021-02-10 Fixed missing network library in Windows package 2021-02-09 Added Pandoc markdown cite command (Thanks to M. Young) 2021-02-08 Added title_first_word cite ID placeholder (Thanks to J. Kalliauer) 2021-02-08 Set LZ4 compressor as default 2020-05-15 Added preliminary document ranking 2020-05-07 Improved title capitalization 2020-05-07 Optimized BibTeX parsing 2020-04-12 Added stemmed context search 2019-12-23 Optimized PDF text cache 2019-12-23 Added LZSSE4 compressor 2019-11-26 Added LZ4 compressor 2019-12-16 Optimized TeX to Unicode conversion 2019-11-24 Addressed Qt5.13 deprecated warnings and changes 2019-11-23 Removed obsolete Qt5.13 calls 2019-11-22 Optimized collection indexing 2019-11-19 Removed memory peak in collection indexing 2019-11-17 Refactored authorString 2019-11-02 Added optimized text matcher for SIMD SSE2 and AVX2 CPUs 2019-03-27 Fixed regression on Update Documents Metadata 2019-02-10 RELEASE OF VERSION 2.0.0 2019-02-08 Updated Windows installer 2019-02-07 Cleanup cppcheck and clazy checks 2018-09-19 Updated abbreviations.txt file 2018-09-19 Fixed journal conversion for LaTeX escaped characters 2018-09-07 RELEASE OF VERSION 1.9.9 2018-09-06 Fixed gcc compiler warning (Thanks to F. Rusconi) 2018-09-05 Updated abbreviations.txt file 2018-09-05 Added alternate abbreviation and full journal processing 2018-08-27 Set to remove conflicting braces on extern author strings 2018-08-27 Updated netqinf.txt file, set reliable queries only 2018-08-27 Added merge metadata actions to netqinf syntax 2018-08-27 Added parsers for arXiv and Crossref 2018-08-23 Fixed break of query chain on single network error 2018-08-07 RELEASE OF VERSION 1.9.8 2018-08-07 Updated bookmark and abbreviation files 2018-08-05 Ported deprecated jsMath newcommand macros to MathJax 2018-08-05 Fixed sub and sup scripts conflicting with MathJax 2018-07-27 Added PDF user manual 2018-07-27 Updated documentation and improved navigation 2017-06-28 RELEASE OF VERSION 1.9.7 2017-06-27 Set MathJax default local for increased security (Thanks to F. Rusconi) 2017-06-27 Fixed broken Cross Ref link 2017-01-14 Added missing Qt dll to Windows installer (Thanks to M. Ivanovski) 2017-01-07 RELEASE OF VERSION 1.9.6 2017-01-07 Fixed regression when invoking internal editor for Annote 2017-01-07 Fixed MacOSX build (Thanks to G. V. Wyngaerd) 2016-07-16 RELEASE OF VERSION 1.9.5 2016-07-16 Fixed main panel tab order regression 2016-05-20 RELEASE OF VERSION 1.9.4 2016-05-18 Set internal editor for Annote 2016-05-18 Updated jsMath interface to MathJax 2016-05-18 Deprecated clipboard poll, removed Qt5X11Extras dependency 2016-05-18 Removed unused What's This button from dialogues 2016-05-15 Set QRegularExpression/PCRE to in-document searches 2016-05-15 Fixed c2bReferenceList QUrl encoding 2016-05-15 Fixed output in c2bconsole 2016-05-15 Updated build scripts for Windows 2016-05-14 Included upcoming QtWebEngine together with QtWebKit 2016-05-13 RELEASE OF VERSION 1.9.3 2016-05-12 Updated and cleaned building scripts 2015-08-10 RELEASE OF VERSION 1.9.2 2015-08-09 Code cleanup through cppcheck 2015-08-09 Removed old modified QRegExp 2015-08-08 Updated indexing 2015-07-24 RELEASE OF VERSION 1.9.1 2015-07-24 Set QRegularExpression/PCRE for full search indexing 2015-07-20 Fixed Qt 5.5.0 compilation 2015-07-18 RELEASE OF VERSION 1.9.0 2015-07-18 Ported to Qt5 2014-12-20 RELEASE OF VERSION 1.5.0 2014-12-18 Fixed document indexing when conversion to text fails 2014-12-17 Improved keyword sentence extraction 2014-12-17 Added modified XPDF code to separate superscripts 2014-12-10 Improved PDF to text postprocessing, code checking and de-hyphenation 2014-08-18 Fix missing keywords for two c2bscripts/*.desktop files (Thanks to F. Rusconi) 2012-12-23 Updated netqinf.txt for PubMed (Thanks to S. Kreisel) 2012-11-05 RELEASE OF VERSION 1.4.9 2012-11-04 Minor improvements in keyword extraction 2012-11-03 Code cleanup and micro optimizations through cppcheck 2012-10-23 Assure tmp path is writable when operating remotely (Thanks to A. Norton) 2012-08-02 Disable Open button when Postprocess does not produce a file (Thanks to J. Welford) 2012-05-15 RELEASE OF VERSION 1.4.8 2012-05-13 Fixed gcc 4.7 compilation, Debian bug 667129 (Thanks to M. Klose and F. Rusconi) 2012-02-17 Added a warning whenever external document to text conversion fails while indexing 2012-01-15 Minor improvements in keyword extraction 2011-12-20 RELEASE OF VERSION 1.4.7 2011-12-17 Added keyword excerpt view 2011-12-13 Optimized keyword extraction citer cleanup 2011-12-05 Propagated --conf flags to child processes 2011-11-18 Improved citer navigation 2011-09-18 Added document similarity view 2011-09-18 Added POS tagger and keyword patterns 2011-08-14 Added automatic keyword extraction from documents 2011-08-03 RELEASE OF VERSION 1.4.6 2011-08-02 Set minor improvements in volume, number, page recognition 2011-08-01 Made shortcuts customizable 2011-06-29 Added XCode ./qmake/cb2bib-osx.pro file (Thanks to J. Ralls) 2011-06-29 Updated netqinf.txt for PubMed 2011-03-21 RELEASE OF VERSION 1.4.5 2011-03-21 Fixed build error, set explicit X11 (Thanks to F. Rusconi, J. Corneli, and A. Wintcher) 2011-01-23 RELEASE OF VERSION 1.4.4 2011-01-23 Consider import multi keywords BibTeX entries (Thanks to C. Dri) 2010-12-17 Added Cyrillic to ASCI transliteration (Thanks to V. Koval) 2010-12-06 Updated bookmark's file netqinf.txt 2010-11-24 Documented comma separated value CSV to BibTeX procedure (Thanks to G. Ranger) 2010-11-05 Fixed three bashisms in file c2btools/bib2pdf (Thanks to F. Rusconi) 2010-10-19 Set executable inside cmake build tree (Thanks to F. Rusconi) 2010-10-11 RELEASE OF VERSION 1.4.3 2010-10-11 Fixed two-letter initial, 'Yu. Last' author parsing 2010-10-10 Fixed trimming leading spaces in Annote verbatim sections 2010-10-10 Removed hard-coded monospace font in Annote's CSS file 2010-10-10 Fixed opened files seen as modified in when using Qt 4.7.0 2010-09-11 RELEASE OF VERSION 1.4.2 2010-08-31 Added initial cmake configure/build/install 2010-08-31 Set fixes and testing cmake configure/build on MacOSX (Thanks to D. Swain) 2010-08-30 Set calling external tools path independent on MacOSX (Thanks to C. Szepesvari) 2010-08-22 Minor code cleanup 2010-08-21 Fixed wrong author parsing if ForeName is missing in XML PubMed (Thanks to F. Rusconi) 2010-05-24 RELEASE OF VERSION 1.4.1 2010-05-23 Improved journal recognition 2010-05-22 Updated bookmark's file netqinf.txt 2010-05-22 Skip saving void documents when "Download document if available" is checked 2010-05-22 Check for document existence and mimetype prior to downloading 2010-05-22 Refactored network classes 2010-04-24 RELEASE OF VERSION 1.4.0 2010-04-23 Set c2bCiter to remember display format 2010-04-22 Set clipboard connected mode default in c2bCiter 2010-04-22 Remember last current citation in c2bCiter 2010-04-22 Updated several icons in editor 2010-03-21 Set workaround for cleared line edits showing cursor (QTBUG-7866) 2010-03-21 Postprocess DOI to clear URL formatting 2010-03-21 Added chronological view in c2bCiter 2010-02-22 RELEASE OF VERSION 1.3.7 2010-02-21 Validate author in PubMed XML parser 2010-02-21 Avoid stopping network queries when one fails 2010-02-21 Set minor improvements in year, volume, page recognition 2010-02-21 Updated style sheet for reference browsing 2010-02-20 Fallback title to booktitle to file name in views 2010-02-20 Set --sloppy to accept all files 2010-02-20 Consider shortcut to write/update source document's metadata (Thanks to S. Kreisel) 2010-02-20 Consider c2bCiter's filter to be connected to clipboard (Thanks to H. Seifzadeh) 2010-02-20 Fixed Medline parsing in some cases with uppercased hyphenated words (Thanks to F. Rusconi) 2010-01-05 RELEASE OF VERSION 1.3.6 2010-01-04 Added 'Fore IJ Last' formatted author recognition 2010-01-02 Minor improvements in journal recognition 2009-12-28 Minor improvements in PubMed XML parser for journal pages and year 2009-12-26 Fixed two cases of author capitalization which conflicted with suffixes and two-letter initials 2009-12-21 Minor improvements in abstract and keywords recognition 2009-12-15 Adapted configure script to Gentoo build descriptions (Thanks to H. Mildenberger and A. K. Huettel) 2009-10-26 RELEASE OF VERSION 1.3.5 2009-10-25 Fixed a regression in single word approximate strings not working for documents 2009-10-21 Fixed wrong automatic extraction for DOIs followed by commas (Thanks to X. Helluy) 2009-10-21 Set reference field shortcuts in manual extraction 2009-10-21 Consider setting manual extraction selection keyboard aware (Thanks to H. Seifzadeh) 2009-10-15 Consider fallback journal to booktitle for inproceedings in views (Thanks to H. Seifzadeh) 2009-10-13 RELEASE OF VERSION 1.3.4 2009-10-12 Skip copy/move document on save if BibTeX file is not writable 2009-10-11 Updated bookmark's file netqinf.txt (Thanks to H. Seifzadeh) 2009-10-09 Added minor improvements in author, pages and volume recognition 2009-10-09 Included citeid in check repeated 2009-09-19 Fixed a typo, --tempdir must be --tmpdir, in bib2pdf (Thanks to F. Rusconi) 2009-09-11 Protected all shell variables against spaces in configure (Thanks to F. Rusconi) 2009-09-10 RELEASE OF VERSION 1.3.3 2009-09-06 Added 'fix string: context' search type 2009-08-26 Optimized search in files, and implemented fast matching for approximate strings 2009-08-26 Fixed compiler -Werror=format-security errors in qDebug calls 2009-08-18 Added --sloppy switch for --doc2bib and --txt2bib actions 2009-08-11 Fixed export entries from search browser 2009-08-06 Added relevant Prism metadata recognition 2009-08-03 Fixed possible separator duplication in keywords 2009-08-03 Wrote a more clarifying documentation for automatic extractions 2009-08-01 Fixed a regression not converting '2nd' and '3rd' PubMed author suffixes 2009-07-27 RELEASE OF VERSION 1.3.2 2009-07-27 Do not ask if document should be saved when closing search results browser 2009-07-27 Added citeid document ID placeholder that keeps both IDs syncronized 2009-07-26 Set not to expand pathless filenames in USB mode permitting to use host PATH tools 2009-07-26 Improved check repeated and added check repeated on save 2009-07-25 Consider title ID placeholder and set cite and document separate IDs (Thanks to O. Sluciak) 2009-07-23 Fixed wrong file name in missing converter message 2009-07-23 Updated build scrips to not require external tools dependence 2009-07-23 Set calling external tools path independent 2009-07-10 Added author_all_abbreviated cite ID placeholder (Thanks to D. Huang) 2009-07-05 Improved configure and tool scripts (Thanks to F. Rusconi and L. Mamane) 2009-06-29 RELEASE OF VERSION 1.3.1 2009-06-27 Added Check Repeated functionality for current reference 2009-06-27 Fixed parser not processing last field in inverted comma style BibTeX 2009-06-27 Set netqinf.txt to use internal XML parser for PubMed 2009-06-27 Fixed packaging, double copying scripts and initial external tool setting 2009-06-01 Fixed c2bciter script not passing all arguments (Thanks to F. Rusconi) 2009-06-01 RELEASE OF VERSION 1.3.0 2009-05-30 Updated configure script (Thanks to F. Rusconi) 2009-05-23 Added module c2bCiter and command line action --citer 2009-05-23 Set cb2Bib not to process clipboard updates if main panel is closed 2009-05-23 Set standard shortcuts to conform to user's desktop 2009-05-23 Improved to ASCII conversion and collation algorithm 2009-05-20 Added example query using HTML to text conversion in netqinf.txt 2009-05-20 Added pre-process script med2bib (Thanks to F. Rusconi) 2009-05-20 Pre and post process scripts cleanup (Thanks to F. Rusconi) 2009-05-17 Fixed wrong display of proper names for BibTeX files written in reverse order 2009-05-17 Improved abstract and keywords heuristics (Thanks to J. P. Eckmann) 2009-05-17 Cleanup command line messages, fixed wrong mention on temporary files deletion 2009-05-17 Convenience script dl_cb2bib renamed to c2bimport 2009-05-10 Improved document to text conversions, removal of non-textual symbols 2009-05-10 Fixed set initial references.bib to user's home directory 2009-05-10 Made temporary file names dependent on cb2Bib session 2009-05-10 Fixed a regression on Windows uninstaller not deleting install directories 2009-05-10 Added convenience shell wrapper c2bconsole on Windows 2009-05-07 RELEASE OF VERSION 1.2.3 2009-05-07 Fixed a regression when setting unsupervised processing 2009-05-07 Renamed settings key for metadata writer 2009-05-06 Improved journal name recognition 2009-05-06 Added conversion htm2txt_query and htm2txt_referenceurl actions in netqinf.txt 2009-05-04 Added --configure command line functionality 2009-05-04 Added --txt2bib and --doc2bib command line functionality 2009-04-05 RELEASE OF VERSION 1.2.2 2009-04-05 Set reference list sorting case and diacritic insensitive 2009-04-05 Improved author string parsing 2009-03-31 Consider parsing reverse order and comma separated author strings (Thanks to D. Comtois) 2009-03-27 Added network access through a proxy host (Thanks to T. Deneux) 2009-03-25 RELEASE OF VERSION 1.2.1 2009-03-25 Improved the pattern/regular expression editor 2009-03-24 Fixed a potential crash if expected and actual captures in user's patterns mismatch 2009-03-15 Improved/optimized journal names lookup 2009-03-07 Added line numbers in embedded editor 2009-03-03 RELEASE OF VERSION 1.2.0 2009-03-01 Moved Qt requirement to version 4.4.0 or later 2009-03-01 Use plain text optimized class QPlainTextEdit for text editing 2009-03-01 Updated bookmark's file netqinf.txt 2009-02-27 Improved built-in network capabilities, including redirections and cookies 2009-02-27 Added author to network query excerpts 2009-02-27 Code cleanup through cppcheck 2009-02-22 Updated build dependencies for Debian 5.0 2009-02-05 RELEASE OF VERSION 1.1.1 2009-01-17 Added heuristic recognition for authors (single and multiple blocks, natural order) 2009-01-10 Revert Latin ligatures in document to plain text conversions 2009-01-10 Improved author string processing 2008-12-27 Improved pages, volume and number recognition 2008-12-23 Convert ' & ' to ' and ' in journal before submitting a network query 2008-12-23 Fixed a regression on month, editor and cite ID fields 2008-12-21 Updated to Qt 4.5.0 QRegExp/QString semantic changes 2008-12-21 Fixed spec file for openSuSE 11.1 build (Thanks to M. Hüwe) 2008-12-17 RELEASE OF VERSION 1.1.0 2008-12-07 Added cb2Bib's Annote viewer 2008-12-07 Added --html-annote and --view-annote command line functionality 2008-12-07 Fixed some issues regarding command line filenames and filedialogs in Windows 2008-12-07 Synchronized BibTeX browser panel with reference line editors 2008-11-30 Code cleanup and refactoring 2008-11-30 Removed no longer needed external client for opening files 2008-11-21 Fixed an issue with percent encoding/tag substitution custom bookmarks 2008-11-21 Updated bookmark's file netqinf.txt for new ACS journals and Science URLs 2008-10-22 RELEASE OF VERSION 1.0.4 2008-10-21 Added 'any word/all words' type searches 2008-10-20 Fixed buttons enabled/disabled in search dialog on Qt > 4.4.0 2008-10-20 Fixed 'About panel' bookmarks not displaying dynamic links on Qt > 4.4.0 2008-10-20 Improved pages, volume and number recognition 2008-09-19 RELEASE OF VERSION 1.0.3 2008-09-18 Recognize and process page format '123-3pp' 2008-09-18 Set arXiv ID as BibTeX URL field 2008-09-18 Fixed a bug when scrolling to 'Edit reference' in search if multiple edits were done 2008-09-17 Force USB mode 'cb2Bib --conf' to use relative to BibTeX document filenames 2008-09-17 Improved managing of relative document filenames 2008-09-17 Added 'Export Entries' to export selected citations in BibTeX editor (Thanks to to A. M. Elena) 2008-07-21 RELEASE OF VERSION 1.0.2 2008-07-20 Added 'Edit reference' in search results 2008-07-20 Fixed a regression for LaTeX-Unicode conversion for letters Å and Æ 2008-07-20 Set LyXPipe in Windows 2008-07-20 Updated PNAS Url 2008-07-10 Optimized approximate string when searching linked documents 2008-07-10 Use Qt::AA_NativeWindows to avoid flickering on Qt 4.4.0 2008-06-17 RELEASE OF VERSION 1.0.1 2008-06-17 Fixed a bug that could result in computing negative word stretch in approximate strings 2008-06-15 Fixed a bug sometimes blocking the reference list filter in BibTeX browser 2008-06-15 Arranged BibTeX browser menus, made context and selection sensitive 2008-06-15 Fixed a regression in BibTeX browser actions not properly showing in menus 2008-06-15 Set sub and superscript conversions from HTML alt tags and [sub/p .] tags 2008-06-15 Fixed BibTeX parser failing in some cases with nested braces 2008-06-15 Added 'Update Documents Metadata' in BibTeX editor 2008-06-10 Set BibTeX to Unicode letter conversions for \LaTeX{} syntax 2008-06-10 Fixed a regression in clipboard's panel multiple line syntax highlighting 2008-06-10 Added tag title for automatic queries, updated netqinf.txt 2008-06-10 Set better flags for calling ExifTool (Thanks to P. Harvey) 2008-06-07 RELEASE OF VERSION 1.0.0.1 2008-06-07 Fixed an error in inserted metadata from PDFImport and multiple files 2008-06-07 Fixed a regression preventing from setting correct djvu extension 2008-06-07 RELEASE OF VERSION 1.0.0 2008-06-07 Updated cb2Bib's license to GPL version 3 2008-06-07 Added metadata writing through ExifTool 2008-06-05 Set double braces to be seen only BibTeX preview and save 2008-06-05 Removed BibTeX separator for author queries 2008-06-05 Updated configuration dialog 2008-06-05 Only set pdf extension in 'file' when none is given 2008-06-05 Set Utf8 as default codec for files on Windows 2008-06-05 Fixed minor bug in suggested regular expression for page 2008-05-31 Added metadata reading and parsing 2008-05-25 Fixed 'Postprocess month' not following settings 2008-05-25 Added Select File in File context menu 2008-05-25 Added clear functionality to combo boxes 2008-05-07 RELEASE OF VERSION 0.9.5 2008-05-07 Set LyX pipe selection for Qt 4.4.0 filedialogs 2008-05-07 Fixed 'Search in files' headers and browser 'Select' icon display for Qt 4.4.0 2008-04-15 Fixed missing HTML special character encoding when searching by field 2008-04-08 Contributed regexps for Earth Planet Sci Lett, 2008-04-08 Phys Earth Planet Inter, Geophys J Int (Thanks to L. A. C. Silva) 2008-04-07 RELEASE OF VERSION 0.9.4 2008-04-07 Updated bookmark netqinf.txt file 2008-04-05 Set optionally file entries relative to current BibTeX file (Thanks to A. M. Elena) 2008-04-03 Added tag selection to dynamic bookmarks 2008-04-03 Added dynamic bookmarks to cb2Bib context menu 2008-03-31 Moved basic edit actions to 'Edit' context submenu 2008-03-05 Added cb2Bib browser context action 'Open Document Url' 2008-03-05 Set cb2Bib browser link preference to local article file, to URL, and to DOI 2008-03-05 Set PubMed ID as BibTeX URL field in PubMed extractions (Thanks to S. Tabibzadeh) 2008-02-01 RELEASE OF VERSION 0.9.3 2008-01-31 Added bookmark menu in the embedded editor 2008-01-30 Fixed/Improved PubMed IDs extraction (update netqinf.txt) 2008-01-30 Fixed ISBN recognition for cases 'ISBN 0: 0-0000-0000-0' 2008-01-30 Fixed an issue when parsing bib keys formatted by KBibTeX (Thanks to D. Car) 2007-12-07 RELEASE OF VERSION 0.9.2 2007-12-07 Fixes/workarounds for filedialog and Qt<4.3.3. Added exec icon for X11. 2007-12-05 Optimized BibTeX parser, searches and composite searches 2007-12-04 Fixed merging of contiguous search excerpts 2007-12-04 Fixed a bug when deleting search patterns, avoid accepting empty patterns 2007-11-25 RELEASE OF VERSION 0.9.1 2007-11-25 Fixed ISBN recognition for cases 'ISBN-0: 0-0000-0000-0' 2007-11-25 Added filter mode selection to browser/editor reference list 2007-11-25 Set filedialog to remember last size 2007-11-25 Fixed compilation issue on Debian 4.1.1-21 (Thanks to A. Matuszak) 2007-10-31 RELEASE OF VERSION 0.9.0 2007-10-30 Show 'search in files' output in text mode if no hits but search errors 2007-10-30 Consider 'editor' if 'author' is empty for cite IDs 2007-10-30 Customizable page number separator (Thanks to C. Ullrich) 2007-10-30 Consistent update of shortcuts: Use standard ones, and Alt modifier in other cases 2007-10-30 Updated Editor/Browser menu 2007-10-28 Added 'Search In Files' for selected text 2007-10-28 Code refactoring: Added resource class c2b 2007-10-27 Remove patterns '(Editor)', '(Ed)', ..., prior to processing an editors string 2007-10-27 Improved heuristic guess for ISBN 2007-10-27 Improved heuristic guess for abstract, considers tag 'summary' 2007-10-26 Updated message dialogs for better desktop integration 2007-10-26 Fixed shortcut for 'Deletes temporary BibTeX output file' 2007-10-26 Set c2bUtils into namespace, some inlining of utilities 2007-09-17 Fixed wrong renaming of non '.pdf' files when original filename has several '.' 2007-09-05 RELEASE OF VERSION 0.8.4 2007-09-05 Setting relative file paths and temporaries when launched with --conf option 2007-09-05 Minor code cleanup 2007-08-02 Updated netqinf.txt file 2007-08-02 Updated PubMed/Medline parser 2007-07-05 RELEASE OF VERSION 0.8.3.1 2007-07-05 Fixed a regression while parsing command line 2007-07-05 RELEASE OF VERSION 0.8.3 2007-07-04 Fixed memory leak from cb2Bib not freeing c2bSearchInFiles 2007-07-03 Fixed file dialog captions when using Qt 4.3.0 2007-07-03 Do not show cb2Bib's main panel when launched with '--bibedit filename.bib' 2007-07-03 Reorganized settings and updated windows installer 2007-07-03 Considered user configuration files, --conf flag (Thanks to S. Oom) 2007-07-03 Fixed Debian/Ubuntu packaging script (Thanks to L. Eraly) 2007-07-02 Updated configure script 2007-06-07 Fixed some dialogs not showing when using Qt 4.3.0 2007-05-07 RELEASE OF VERSION 0.8.2 2007-05-07 Fixed 'Unknown Error' when copying/moving files from PDFImport on Windows 2007-05-07 Scape < and > symbols in browser 2007-05-01 Fixed regression 'Copy instead of moving non-local files' for external clients 2007-04-23 Added approximate string search 2007-04-08 Added search highlight for abstracts 2007-04-08 Added PDF search excerpts 2007-04-08 Added cache for PDF search 2007-04-08 Remember Browser font size 2007-04-01 RELEASE OF VERSION 0.8.1 2007-04-01 Copy instead of moving non-local files 2007-04-01 Improved/optimized Search in Files functionality for composite patterns 2007-04-01 Syncornized BibTeX Editor and Browser navigation 2007-03-24 Set raw mode view as default, instead of tagged mode view 2007-03-24 Set unique BibTeX parsing. Fixes parsing in Editor and Search in Files 2007-03-24 Improved BibTeX recognition and parsing 2007-03-24 Improved PDFImport functionality (Thanks to E. Gaubitzer) 2007-03-18 Updated netqinf.txt and regexps.txt files 2007-03-18 Added excerpt tag for queries 2007-03-18 Improved journal and pages recognition 2007-03-18 Cleanup and reorganization of settings management 2007-03-16 Remove from PDFImport file list unsuccessfully converted files 2007-03-16 Remember last directory/file in PDFImport filedialog (Thanks to E. Gaubitzer) 2007-03-13 RELEASE OF VERSION 0.8.0 2007-03-11 Added HTML browser view to BibTeX editor 2007-03-10 Added 'Search references in files' functionality 2007-03-10 Avoided cb2Bib's tags from interfering with heuristic recognition 2007-03-10 Improved heuristic guess for volume, pages, and number 2007-03-10 Added clear functionality to line editors 2007-03-10 Updated all dialogs to make them consistent and desktop aware 2007-03-10 Fixed preparser 2007-03-10 Improved Find in Text dialog 2007-03-09 Fixed Reference List not displaying booktitle 2007-03-06 Fixed a rare wrong passing of optional arguments to external tools 2007-03-06 Fixed history in filedialogs 2007-03-06 Removed wrong slash in filedialog filenames when file did not exist 2007-03-06 Fixed wrong editor exit when document is modified and cancel is pressed 2007-02-18 RELEASE OF VERSION 0.7.3 2007-02-17 Removed duplicated blank lines in external process logs 2007-02-17 Convert HTML character encodings in PubMed reference import 2007-02-17 Fixed URL encoding for opening files through internal desktop service 2007-02-17 Remove braces in title replacement for Bookmarks 2007-02-17 Fixed pages replacement for Bookmarks (fixes CR bookmark) 2007-02-17 Remember word un/wrap mode in editors 2007-02-17 Check if DOI is a web address in BibTeX editor before being opened 2007-02-17 Added web search customization in BibTeX editor 2007-02-16 Fixed/improved uppercased 'title' capitalization 2006-12-06 RELEASE OF VERSION 0.7.2 2006-12-06 Added choice to write 'title' in double braces 2006-12-06 Fixed pasting of formatted text to BibTeX editor 2006-12-06 Fixed CR regexp in netqinf.txt to not to read HTML-encoded DOI 2006-12-06 Fixed a subtle bug preventing viewers from updating if text was selected 2006-12-06 Added raw, non-preprocessed clipboard view mode (Thanks to M. Wegmann) 2006-12-05 Updated configure and install doc for MacOSX (Thanks to Konstantin and P. Koshevoy) 2006-12-04 Added "Download Reference to cb2Bib" functionality 2006-12-04 Updated cb2Bib command line syntax 2006-12-03 Added Mac OS X cb2bib.icns icon file (Thanks to Konstantin) 2006-12-03 Added missing mingwm10.dll file on Windows package 2006-10-30 RELEASE OF VERSION 0.7.1 2006-10-30 Set default configure prefix to /usr (Thanks to T. Fischer) 2006-10-30 Fixed configure to use -prefix path 2006-10-30 Fixed LyX pipe not shown at file dialogs 2006-10-30 Revert to internal file management if file copy/move/open client is empty 2006-10-19 Fixed local file open on Windows 2006-10-16 RELEASE OF VERSION 0.7.0 2006-10-16 Fixed a regression when setting line/column in Editor 2006-10-16 Improved BibTeX file selection through combo filename list 2006-10-16 Added Editor's modified flag 2006-10-16 Set KDE consistent 'Save'/'Save As' icons in BibTeX Editor 2006-10-16 BibTeX Editor remembers Reference List position 2006-10-16 Set consistent labeling in file dialogs 2006-10-16 Added file history in file dialogs 2006-10-16 Fixed a regression related to wrong file dialog messages 2006-10-16 Consider integrated desktop service for URL opening 2006-10-16 Use QFontComboBox for font selection 2006-10-04 Fixed a regression when copying/moving files from PDFImport 2006-08-31 Fixed a regression when selecting fields in cb2Bib panel 2006-08-30 RELEASE OF PREVIEW 0.6.91 2006-08-30 Fixed a regression in droped files encoding in PDFImport 2006-08-29 Added queries by DOI (Thanks to T. Geissmann) 2006-08-29 Updated netqinf.txt information file 2006-08-29 Fixed a regression in the network functionality 2006-08-29 Fixed a compilation issue on Mac OS (Thanks to M. Bongard) 2006-08-25 RELEASE OF PREVIEW 0.6.90 2006-08-25 Ported to Qt4 2006-05-15 Updated netqinf.txt for NAR 2006-04-24 RELEASE OF VERSION 0.6.1 2006-04-24 Updated netqinf.txt for PNAS 2006-04-24 Keep 'File' synchronized with 'CITEID' 2006-04-24 Concatenate multiple 'title' in regexps, as 'Title: Subtitle' (Thanks to McKay Euan) 2006-04-23 Added tooltip to 'File' with origen file name 2006-04-23 Cleaned and updated network related classes 2006-04-23 Schedule dropped or PDFImport file copying/moving until Bib item is saved 2006-04-23 PDFImport rewritten, fixed several bugs (Thanks to M. Wegmann) 2006-04-02 RELEASE OF VERSION 0.6.0 2006-04-02 Added highlight for 'author|issue|title|volume' in clipboard 2006-04-02 Added contributed regexp for PROLA (Thanks to Martint) 2006-04-02 Added unified, platform independent new line recognition 2006-04-02 Fixed missing 'NewLine' on OSX (Thanks to McKay Euan) 2006-03-28 Fixed ScienceDirect regexp 2006-03-28 Updated Wiley InterScience Example 2006-03-22 Updated cb2Bib's icon 2006-03-22 Added JTCC journal 2006-03-18 Fixed 'Copy/Rename: Keep .djvu, .dvi, .ps, .ps.gz, .tex, .txt extensions' on Windows 2006-03-18 Fixed RC_FILE (Windows and OSX) 2006-02-21 RELEASE OF VERSION 0.5.3 2006-02-21 Added SISC journal, and added contributed_re.txt (Thanks to G. B. @ RWTH) 2006-02-20 Added 'Insert/Overwrite' flag to editor 2006-02-20 Added 'File Save As' functionality to editor 2006-02-20 Copy/Rename: Keep .djvu, .dvi, .ps, .ps.gz, .tex, .txt extensions 2006-02-20 Added preparser scripts isi2bib and ris2bib 2006-02-20 Added external preparser functionality 2006-01-23 RELEASE OF VERSION 0.5.2 2006-01-22 Fixed BibTeX parser for ending non-bracket cases (eg. 'year = 2000}') 2006-01-22 Added Title and ISBN automatic guess 2006-01-22 Fixed Abstract automatic guess 2006-01-21 Added custom syntax colors 2006-01-20 Fixed referencelist.cpp for icc/64 compiler 2006-01-15 Get default font color from the Window Manager 2005-12-12 RELEASE OF VERSION 0.5.1 2005-12-12 Added 'Set active LyX pipe' in BibTeX edit menu 2005-12-12 Added edit menu in BibTeX editor 2005-12-12 BibTeX parser considers non-bracket cases (eg. 'year = 2000,') 2005-12-11 Fixed syntax highlighter for commented lines 2005-11-17 Added http POST command 2005-11-16 Updated netqinf.txt for CR 2005-11-14 Updated netqinf.txt for ACS 2005-10-26 RELEASE OF VERSION 0.5.0 2005-10-08 Proper capitalization: FIRST MID LAST -> First Mid Last 2005-10-08 Added JSTOR regexp (Thanks to B. Goodrich) 2005-10-08 Added citeID customization (Thanks S. Oom for suggestions) 2005-10-07 Set default path /usr/local/bin/pdftotext on Mac OS X 2005-08-20 RELEASE OF VERSION 0.4.6 2005-08-20 Fixed: Set current file when 'cb2bib --bibedit fn.bib' 2005-08-20 Extended Unicode to LaTeX to all entries 2005-08-20 Added equivalent processing for author and editor strings 2005-08-20 Added 'Full Author and Editor Name' option 2005-08-20 (Thanks to J. Schelp and B. Goodrich for suggestions) 2005-08-12 'cb2bib --bibedit', show main maximized if no files are given 2005-08-12 RELEASE OF VERSION 0.4.5 2005-08-12 Fixed memory leak from c2bEditor 2005-08-11 Added web search also in Editor's Reference List 2005-08-11 Menu improvements 2005-08-11 Unicode <-> LaTeX for infinity symbol 2005-08-11 Fixed viewCb2Bib button behavior in BibTeX editor 2005-08-11 BibTeX editor button functionality: edit/set editor on top 2005-08-11 Allow for multiple BibTeX editors 2005-07-06 RELEASE OF VERSION 0.4.4 2005-07-06 Fixed bookmark and regexp editor: save before execute 2005-07-06 Fixed netqinf.txt for PubMed 2005-07-06 Fixed cb2Bib idle in multiple queries + debug file option 2005-07-06 Alternate Journal Name no longer stored in 'annote' field 2005-07-06 Added 'Journals to Full/Abbreviated Name' in editor 2005-07-06 'configure' adapted to knoppix 3.6 (Thanks to cognite) 2005-07-02 Removed 'install' checking in 'configure' script 2005-07-02 ClipboardPoll disabled as default for Mac OS X 2005-06-16 RELEASE OF VERSION 0.4.3 2005-06-15 Set Postprocess widget to modeless 2005-06-15 Added menu entries 2005-06-15 Added heuristic recognition 2005-06-01 Added line number indicator in editor 2005-06-01 Fixed translating '&' to LaTeX multiple times 2005-05-29 Do not reload current BibEditor if ref added to a different file 2005-05-29 Code rearrangement and cleaning: c2bBibParser 2005-05-11 RELEASE OF VERSION 0.4.2 2005-05-11 Added reference navigation in BibTeX editor 2005-05-09 Improved search capabilities in BibTeX editor 2005-05-09 Added LyX pipe citation procedure: 2005-05-09 adapted from R. Stephenson's Tellico 2005-05-09 Added Reference List in BibTeX editor 2005-05-06 Added desktop file 2005-05-04 Uppercase greeks, also in "PNAS-style" {}, (), or [] delimiters 2005-05-04 Added automatic conversion for "PNAS-style" {middle dot} 2005-04-23 RELEASE OF VERSION 0.4.1 2005-04-23 Added scripts bib2pdf and bib2end.bat 2005-04-23 Added Postprocessing of current BibTeX file 2005-04-23 (Thanks to J. Tan for suggestions) 2005-04-19 Added command line 'cb2bib [[--bibedit] filename.bib]' 2005-04-19 Added 'author' to 'Convert string to LaTeX' config 2005-04-19 Added 'Selection to Unicode' in BibTeX editor 2005-04-19 Added 'Selection to LaTeX' in BibTeX editor 2005-04-18 Fixed Clipboard change notifications 2005-04-18 (Thanks to L. Lunak for help and ClipboardPoll code) 2005-04-07 RELEASE OF VERSION 0.4.0 2005-04-06 Added customizable input preprocessing 2005-04-06 Rearrange main window buttons 2005-04-06 Added Editor Search capability 2005-04-06 Fix Modified Editor and Exit main window 2005-04-04 Initialize 'view BibTeX' Scroll Bar position 2005-04-04 Remember 'About' Scroll Bar position 2005-04-04 Added Contextual Help 2005-04-04 Added convenience BibTeX File editor 2005-03-17 RELEASE OF VERSION 0.3.6 2005-03-16 Added ~ 10 more Unicode <-> LaTeX translations 2005-03-16 Improved 'pages' postprocessing 2005-03-16 Consider inverted commas as BibTeX delimiter 2005-02-17 Remove start and end blank in BibTeX field string 2005-02-09 RELEASE OF VERSION 0.3.5 2005-02-09 Parse whole netqinf.txt if 'No article found' 2005-02-07 Remember Config page 2005-02-07 Rearrange About/View BibTeX buttons behavior 2005-01-21 RELEASE OF VERSION 0.3.4 2005-01-20 Add 'Make Network Query' button 2005-01-20 DOI automatic extraction 2005-01-19 'PubMed Search' import (J.Name. year month;vol(n):pp.) 2005-01-19 Add significative error messages for missing filenames 2005-01-19 RegExp/Bookmarks Editor arrangement 2005-01-19 Added convenience bookmarks 2005-01-18 Consider author suffixes in Medline extraction 2005-01-18 Consider Medline AU if FAU isn't available 2005-01-15 Include DOI in Medline extraction 2005-01-14 RELEASE OF VERSION 0.3.3 2005-01-14 Added 'PubMed - Medline Journal' recognition 2005-01-13 Introduced simple Journal-Volume-Page queries 2005-01-10 (Thanks S. Vega and probono for suggestions) 2005-01-08 Added last name prefix 'vande' 2005-01-07 Added complete ACS journal list 2005-01-04 Arrangement copy/move/open for local/network files 2004-12-29 RELEASE OF VERSION 0.3.2 2004-12-29 Previous add conflicted 'van der Wal, Jan and Lieb, Jely A.' 2004-12-28 RELEASE OF VERSION 0.3.1 2004-12-27 'Abcd, E., F. Ghij, ...' citation style (Thanks P. Magwene) 2004-12-27 Fix slow highlighting 2004-12-21 RELEASE OF VERSION 0.3.0 2004-12-20 Consider interlaced authors-affiliations, removed moreauthors 2004-12-20 Regexps deposition note (Thanks J. Vertrees) 2004-12-20 Enable/Disable 'Add BibTeX to file' button 2004-12-20 Added convenience RegExp File editor 2004-12-20 Render disabled icons in grayscale 2004-12-14 Valgrind memory leak debugging 2004-12-08 RELEASE OF VERSION 0.2.8 2004-12-08 Fix a wrong enable/disable behavior in PDFImport button 2004-12-07 Convert to lower case titles completely uppercase 2004-12-07 Fix: PDF renaming consistently managed by cb2Bib instead of kfmclient 2004-12-07 Added error description for file related warnings 2004-12-01 Added 'IOP Electronic Journals' import 2004-10-22 Add abstract|introduction|keywords|key words highlight 2004-10-19 RELEASE OF VERSION 0.2.7 2004-10-19 PDFImport via pdftotext (Thanks F. C. Coelho for suggestions) 2004-09-19 RELEASE OF VERSION 0.2.6 2004-09-19 TeX <-> Unicode translations for Greek letters 2004-09-19 Choice for title Unicode -> LaTeX conversion 2004-09-18 Added some few journal abbreviations 2004-09-18 Fix wrong recognition 'First S.P.'(Thanks S. Oom) 2004-09-18 Fix 'Last, DE' - conflicting First and initials with suffixes 2004-09-18 Added author prefix 'da' and suffix 'Jr' 2004-09-08 RELEASE OF VERSION 0.2.5 2004-09-08 Choice for short/long journal names 2004-09-08 'month' postprocessing (Thanks F. Hedman) 2004-09-08 Added 'Alt D' to delete temporary BibTeX output (Thanks S. Oom) 2004-09-07 Added 'Alt R' accelerator to start automatic recognition 2004-09-07 Proper recognition for 'First I Second, ' 2004-09-02 RELEASE OF VERSION 0.2.4 2004-09-02 Previous fix conflicted with 'First I. Second, ' 2004-08-31 Fix message pointing to wrong file (Thanks G. Palfinger) 2004-08-30 RELEASE OF VERSION 0.2.3 2004-08-30 Fix wrong recognition 'First SP, Second WE, '(Thanks S. Oom) 2004-08-30 RELEASE OF VERSION 0.2.2 2004-08-29 Experimental: kfmclient to retrieve pdf files 2004-08-29 Thanks F. Hedman: 2004-08-28 Improved automatic URL recognition 2004-08-28 Added BibTeX fields 'eprint' and 'doi' 2004-08-22 RELEASE OF VERSION 0.2.1 2004-08-22 Workaround for acrobat, mozilla, qt 3.3.3 issues 2004-08-17 Fixed 'file' - 'eprint' duplication in BibTeX output 2004-08-13 Set 'article' as default type 2004-07-30 RELEASE OF VERSION 0.2.0 2004-07-30 Improved visual input/output presentation 2004-07-29 RegExp format changes: Added extra line for reference types 2004-07-29 RegExp format changes: 'authors' -> 'author' 2004-07-29 Extend reference fields list 2004-07-28 Input reference type list 2004-07-12 RELEASE OF VERSION 0.1.4 2004-07-12 Fix "F.-S. Last" author name processing 2004-07-12 Fix to compile against Qt 3.1.0 or later 2004-07-11 RELEASE OF VERSION 0.1.3 2004-07-09 Improved 'ScienceDirect' import 2004-07-09 Improved TeX <-> Unicode translations 2004-07-09 Added 'Nature from Fisrt Paragraph' import 2004-07-08 Added 'DBLP article' import (thanks to P. Woelfel) 2004-07-08 Consider also '&' as a separator in author automatic recognition 2004-07-08 Fixing 'empty-field {}' error in BibTeX recognition 2004-07-07 Improved MakeCiteID for composite names 2004-07-07 Consider composing sufix 'III' 2004-07-07 Added LastName prefix 'dos' and 'del' 2004-07-07 Corrected JCICS extended journal name 2004-07-05 RELEASE OF VERSION 0.1.2 2004-07-05 Added 'ISI Web of Knowledge Table of Contents Alert' import. 2004-07-05 Fixing: 'Last, FST' -> 'F. S. T. Last' (but not 'LAST, FIRST') 2004-07-05 Proper last name capitalization ('LAST-NAME' -> 'Last-Name') 2004-07-04 Escaping math characters '∂' and '−' 2004-07-03 RELEASE OF VERSION 0.1.1 2004-07-01 Escaping accented characters (MakeCiteID and authors and title in MakeBib) 2004-06-29 RELEASE OF VERSION 0.1.0 cb2bib-2.0.1/PaxHeaders.5700/AUTHORS0000644000000000000000000000007414011522151013352 xustar0030 atime=1613145424.814620334 30 ctime=1613145424.294620349 cb2bib-2.0.1/AUTHORS0000644000175000001440000000001614011522151014741 0ustar00constansusers00000000000000Pere Constans cb2bib-2.0.1/PaxHeaders.5700/LICENSE0000644000000000000000000000007414011522151013307 xustar0030 atime=1613145424.814620334 30 ctime=1613145424.294620349 cb2bib-2.0.1/LICENSE0000644000175000001440000010450514011522151014706 0ustar00constansusers00000000000000 GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007 Copyright (C) 2007 Free Software Foundation, Inc. http://fsf.org/ Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The GNU General Public License is a free, copyleft license for software and other kinds of works. The licenses for most software and other practical works are designed to take away your freedom to share and change the works. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change all versions of a program--to make sure it remains free software for all its users. We, the Free Software Foundation, use the GNU General Public License for most of our software; it applies also to any other work released this way by its authors. You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for them if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs, and that you know you can do these things. To protect your rights, we need to prevent others from denying you these rights or asking you to surrender the rights. Therefore, you have certain responsibilities if you distribute copies of the software, or if you modify it: responsibilities to respect the freedom of others. For example, if you distribute copies of such a program, whether gratis or for a fee, you must pass on to the recipients the same freedoms that you received. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. Developers that use the GNU GPL protect your rights with two steps: (1) assert copyright on the software, and (2) offer you this License giving you legal permission to copy, distribute and/or modify it. For the developers' and authors' protection, the GPL clearly explains that there is no warranty for this free software. For both users' and authors' sake, the GPL requires that modified versions be marked as changed, so that their problems will not be attributed erroneously to authors of previous versions. Some devices are designed to deny users access to install or run modified versions of the software inside them, although the manufacturer can do so. This is fundamentally incompatible with the aim of protecting users' freedom to change the software. The systematic pattern of such abuse occurs in the area of products for individuals to use, which is precisely where it is most unacceptable. Therefore, we have designed this version of the GPL to prohibit the practice for those products. If such problems arise substantially in other domains, we stand ready to extend this provision to those domains in future versions of the GPL, as needed to protect the freedom of users. Finally, every program is threatened constantly by software patents. States should not allow patents to restrict development and use of software on general-purpose computers, but in those that do, we wish to avoid the special danger that patents applied to a free program could make it effectively proprietary. To prevent this, the GPL assures that patents cannot be used to render the program non-free. The precise terms and conditions for copying, distribution and modification follow. TERMS AND CONDITIONS 0. Definitions. "This License" refers to version 3 of the GNU General Public License. "Copyright" also means copyright-like laws that apply to other kinds of works, such as semiconductor masks. "The Program" refers to any copyrightable work licensed under this License. Each licensee is addressed as "you". "Licensees" and "recipients" may be individuals or organizations. To "modify" a work means to copy from or adapt all or part of the work in a fashion requiring copyright permission, other than the making of an exact copy. The resulting work is called a "modified version" of the earlier work or a work "based on" the earlier work. A "covered work" means either the unmodified Program or a work based on the Program. To "propagate" a work means to do anything with it that, without permission, would make you directly or secondarily liable for infringement under applicable copyright law, except executing it on a computer or modifying a private copy. Propagation includes copying, distribution (with or without modification), making available to the public, and in some countries other activities as well. To "convey" a work means any kind of propagation that enables other parties to make or receive copies. Mere interaction with a user through a computer network, with no transfer of a copy, is not conveying. An interactive user interface displays "Appropriate Legal Notices" to the extent that it includes a convenient and prominently visible feature that (1) displays an appropriate copyright notice, and (2) tells the user that there is no warranty for the work (except to the extent that warranties are provided), that licensees may convey the work under this License, and how to view a copy of this License. If the interface presents a list of user commands or options, such as a menu, a prominent item in the list meets this criterion. 1. Source Code. The "source code" for a work means the preferred form of the work for making modifications to it. "Object code" means any non-source form of a work. A "Standard Interface" means an interface that either is an official standard defined by a recognized standards body, or, in the case of interfaces specified for a particular programming language, one that is widely used among developers working in that language. The "System Libraries" of an executable work include anything, other than the work as a whole, that (a) is included in the normal form of packaging a Major Component, but which is not part of that Major Component, and (b) serves only to enable use of the work with that Major Component, or to implement a Standard Interface for which an implementation is available to the public in source code form. A "Major Component", in this context, means a major essential component (kernel, window system, and so on) of the specific operating system (if any) on which the executable work runs, or a compiler used to produce the work, or an object code interpreter used to run it. The "Corresponding Source" for a work in object code form means all the source code needed to generate, install, and (for an executable work) run the object code and to modify the work, including scripts to control those activities. However, it does not include the work's System Libraries, or general-purpose tools or generally available free programs which are used unmodified in performing those activities but which are not part of the work. For example, Corresponding Source includes interface definition files associated with source files for the work, and the source code for shared libraries and dynamically linked subprograms that the work is specifically designed to require, such as by intimate data communication or control flow between those subprograms and other parts of the work. The Corresponding Source need not include anything that users can regenerate automatically from other parts of the Corresponding Source. The Corresponding Source for a work in source code form is that same work. 2. Basic Permissions. All rights granted under this License are granted for the term of copyright on the Program, and are irrevocable provided the stated conditions are met. This License explicitly affirms your unlimited permission to run the unmodified Program. The output from running a covered work is covered by this License only if the output, given its content, constitutes a covered work. This License acknowledges your rights of fair use or other equivalent, as provided by copyright law. You may make, run and propagate covered works that you do not convey, without conditions so long as your license otherwise remains in force. You may convey covered works to others for the sole purpose of having them make modifications exclusively for you, or provide you with facilities for running those works, provided that you comply with the terms of this License in conveying all material for which you do not control copyright. Those thus making or running the covered works for you must do so exclusively on your behalf, under your direction and control, on terms that prohibit them from making any copies of your copyrighted material outside their relationship with you. Conveying under any other circumstances is permitted solely under the conditions stated below. Sublicensing is not allowed; section 10 makes it unnecessary. 3. Protecting Users' Legal Rights From Anti-Circumvention Law. No covered work shall be deemed part of an effective technological measure under any applicable law fulfilling obligations under article 11 of the WIPO copyright treaty adopted on 20 December 1996, or similar laws prohibiting or restricting circumvention of such measures. When you convey a covered work, you waive any legal power to forbid circumvention of technological measures to the extent such circumvention is effected by exercising rights under this License with respect to the covered work, and you disclaim any intention to limit operation or modification of the work as a means of enforcing, against the work's users, your or third parties' legal rights to forbid circumvention of technological measures. 4. Conveying Verbatim Copies. You may convey verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice; keep intact all notices stating that this License and any non-permissive terms added in accord with section 7 apply to the code; keep intact all notices of the absence of any warranty; and give all recipients a copy of this License along with the Program. You may charge any price or no price for each copy that you convey, and you may offer support or warranty protection for a fee. 5. Conveying Modified Source Versions. You may convey a work based on the Program, or the modifications to produce it from the Program, in the form of source code under the terms of section 4, provided that you also meet all of these conditions: a) The work must carry prominent notices stating that you modified it, and giving a relevant date. b) The work must carry prominent notices stating that it is released under this License and any conditions added under section 7. This requirement modifies the requirement in section 4 to "keep intact all notices". c) You must license the entire work, as a whole, under this License to anyone who comes into possession of a copy. This License will therefore apply, along with any applicable section 7 additional terms, to the whole of the work, and all its parts, regardless of how they are packaged. This License gives no permission to license the work in any other way, but it does not invalidate such permission if you have separately received it. d) If the work has interactive user interfaces, each must display Appropriate Legal Notices; however, if the Program has interactive interfaces that do not display Appropriate Legal Notices, your work need not make them do so. A compilation of a covered work with other separate and independent works, which are not by their nature extensions of the covered work, and which are not combined with it such as to form a larger program, in or on a volume of a storage or distribution medium, is called an "aggregate" if the compilation and its resulting copyright are not used to limit the access or legal rights of the compilation's users beyond what the individual works permit. Inclusion of a covered work in an aggregate does not cause this License to apply to the other parts of the aggregate. 6. Conveying Non-Source Forms. You may convey a covered work in object code form under the terms of sections 4 and 5, provided that you also convey the machine-readable Corresponding Source under the terms of this License, in one of these ways: a) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by the Corresponding Source fixed on a durable physical medium customarily used for software interchange. b) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by a written offer, valid for at least three years and valid for as long as you offer spare parts or customer support for that product model, to give anyone who possesses the object code either (1) a copy of the Corresponding Source for all the software in the product that is covered by this License, on a durable physical medium customarily used for software interchange, for a price no more than your reasonable cost of physically performing this conveying of source, or (2) access to copy the Corresponding Source from a network server at no charge. c) Convey individual copies of the object code with a copy of the written offer to provide the Corresponding Source. This alternative is allowed only occasionally and noncommercially, and only if you received the object code with such an offer, in accord with subsection 6b. d) Convey the object code by offering access from a designated place (gratis or for a charge), and offer equivalent access to the Corresponding Source in the same way through the same place at no further charge. You need not require recipients to copy the Corresponding Source along with the object code. If the place to copy the object code is a network server, the Corresponding Source may be on a different server (operated by you or a third party) that supports equivalent copying facilities, provided you maintain clear directions next to the object code saying where to find the Corresponding Source. Regardless of what server hosts the Corresponding Source, you remain obligated to ensure that it is available for as long as needed to satisfy these requirements. e) Convey the object code using peer-to-peer transmission, provided you inform other peers where the object code and Corresponding Source of the work are being offered to the general public at no charge under subsection 6d. A separable portion of the object code, whose source code is excluded from the Corresponding Source as a System Library, need not be included in conveying the object code work. A "User Product" is either (1) a "consumer product", which means any tangible personal property which is normally used for personal, family, or household purposes, or (2) anything designed or sold for incorporation into a dwelling. In determining whether a product is a consumer product, doubtful cases shall be resolved in favor of coverage. For a particular product received by a particular user, "normally used" refers to a typical or common use of that class of product, regardless of the status of the particular user or of the way in which the particular user actually uses, or expects or is expected to use, the product. A product is a consumer product regardless of whether the product has substantial commercial, industrial or non-consumer uses, unless such uses represent the only significant mode of use of the product. "Installation Information" for a User Product means any methods, procedures, authorization keys, or other information required to install and execute modified versions of a covered work in that User Product from a modified version of its Corresponding Source. The information must suffice to ensure that the continued functioning of the modified object code is in no case prevented or interfered with solely because modification has been made. If you convey an object code work under this section in, or with, or specifically for use in, a User Product, and the conveying occurs as part of a transaction in which the right of possession and use of the User Product is transferred to the recipient in perpetuity or for a fixed term (regardless of how the transaction is characterized), the Corresponding Source conveyed under this section must be accompanied by the Installation Information. But this requirement does not apply if neither you nor any third party retains the ability to install modified object code on the User Product (for example, the work has been installed in ROM). The requirement to provide Installation Information does not include a requirement to continue to provide support service, warranty, or updates for a work that has been modified or installed by the recipient, or for the User Product in which it has been modified or installed. Access to a network may be denied when the modification itself materially and adversely affects the operation of the network or violates the rules and protocols for communication across the network. Corresponding Source conveyed, and Installation Information provided, in accord with this section must be in a format that is publicly documented (and with an implementation available to the public in source code form), and must require no special password or key for unpacking, reading or copying. 7. Additional Terms. "Additional permissions" are terms that supplement the terms of this License by making exceptions from one or more of its conditions. Additional permissions that are applicable to the entire Program shall be treated as though they were included in this License, to the extent that they are valid under applicable law. If additional permissions apply only to part of the Program, that part may be used separately under those permissions, but the entire Program remains governed by this License without regard to the additional permissions. When you convey a copy of a covered work, you may at your option remove any additional permissions from that copy, or from any part of it. (Additional permissions may be written to require their own removal in certain cases when you modify the work.) You may place additional permissions on material, added by you to a covered work, for which you have or can give appropriate copyright permission. Notwithstanding any other provision of this License, for material you add to a covered work, you may (if authorized by the copyright holders of that material) supplement the terms of this License with terms: a) Disclaiming warranty or limiting liability differently from the terms of sections 15 and 16 of this License; or b) Requiring preservation of specified reasonable legal notices or author attributions in that material or in the Appropriate Legal Notices displayed by works containing it; or c) Prohibiting misrepresentation of the origin of that material, or requiring that modified versions of such material be marked in reasonable ways as different from the original version; or d) Limiting the use for publicity purposes of names of licensors or authors of the material; or e) Declining to grant rights under trademark law for use of some trade names, trademarks, or service marks; or f) Requiring indemnification of licensors and authors of that material by anyone who conveys the material (or modified versions of it) with contractual assumptions of liability to the recipient, for any liability that these contractual assumptions directly impose on those licensors and authors. All other non-permissive additional terms are considered "further restrictions" within the meaning of section 10. If the Program as you received it, or any part of it, contains a notice stating that it is governed by this License along with a term that is a further restriction, you may remove that term. If a license document contains a further restriction but permits relicensing or conveying under this License, you may add to a covered work material governed by the terms of that license document, provided that the further restriction does not survive such relicensing or conveying. If you add terms to a covered work in accord with this section, you must place, in the relevant source files, a statement of the additional terms that apply to those files, or a notice indicating where to find the applicable terms. Additional terms, permissive or non-permissive, may be stated in the form of a separately written license, or stated as exceptions; the above requirements apply either way. 8. Termination. You may not propagate or modify a covered work except as expressly provided under this License. Any attempt otherwise to propagate or modify it is void, and will automatically terminate your rights under this License (including any patent licenses granted under the third paragraph of section 11). However, if you cease all violation of this License, then your license from a particular copyright holder is reinstated (a) provisionally, unless and until the copyright holder explicitly and finally terminates your license, and (b) permanently, if the copyright holder fails to notify you of the violation by some reasonable means prior to 60 days after the cessation. Moreover, your license from a particular copyright holder is reinstated permanently if the copyright holder notifies you of the violation by some reasonable means, this is the first time you have received notice of violation of this License (for any work) from that copyright holder, and you cure the violation prior to 30 days after your receipt of the notice. Termination of your rights under this section does not terminate the licenses of parties who have received copies or rights from you under this License. If your rights have been terminated and not permanently reinstated, you do not qualify to receive new licenses for the same material under section 10. 9. Acceptance Not Required for Having Copies. You are not required to accept this License in order to receive or run a copy of the Program. Ancillary propagation of a covered work occurring solely as a consequence of using peer-to-peer transmission to receive a copy likewise does not require acceptance. However, nothing other than this License grants you permission to propagate or modify any covered work. These actions infringe copyright if you do not accept this License. Therefore, by modifying or propagating a covered work, you indicate your acceptance of this License to do so. 10. Automatic Licensing of Downstream Recipients. Each time you convey a covered work, the recipient automatically receives a license from the original licensors, to run, modify and propagate that work, subject to this License. You are not responsible for enforcing compliance by third parties with this License. An "entity transaction" is a transaction transferring control of an organization, or substantially all assets of one, or subdividing an organization, or merging organizations. If propagation of a covered work results from an entity transaction, each party to that transaction who receives a copy of the work also receives whatever licenses to the work the party's predecessor in interest had or could give under the previous paragraph, plus a right to possession of the Corresponding Source of the work from the predecessor in interest, if the predecessor has it or can get it with reasonable efforts. You may not impose any further restrictions on the exercise of the rights granted or affirmed under this License. For example, you may not impose a license fee, royalty, or other charge for exercise of rights granted under this License, and you may not initiate litigation (including a cross-claim or counterclaim in a lawsuit) alleging that any patent claim is infringed by making, using, selling, offering for sale, or importing the Program or any portion of it. 11. Patents. A "contributor" is a copyright holder who authorizes use under this License of the Program or a work on which the Program is based. The work thus licensed is called the contributor's "contributor version". A contributor's "essential patent claims" are all patent claims owned or controlled by the contributor, whether already acquired or hereafter acquired, that would be infringed by some manner, permitted by this License, of making, using, or selling its contributor version, but do not include claims that would be infringed only as a consequence of further modification of the contributor version. For purposes of this definition, "control" includes the right to grant patent sublicenses in a manner consistent with the requirements of this License. Each contributor grants you a non-exclusive, worldwide, royalty-free patent license under the contributor's essential patent claims, to make, use, sell, offer for sale, import and otherwise run, modify and propagate the contents of its contributor version. In the following three paragraphs, a "patent license" is any express agreement or commitment, however denominated, not to enforce a patent (such as an express permission to practice a patent or covenant not to sue for patent infringement). To "grant" such a patent license to a party means to make such an agreement or commitment not to enforce a patent against the party. If you convey a covered work, knowingly relying on a patent license, and the Corresponding Source of the work is not available for anyone to copy, free of charge and under the terms of this License, through a publicly available network server or other readily accessible means, then you must either (1) cause the Corresponding Source to be so available, or (2) arrange to deprive yourself of the benefit of the patent license for this particular work, or (3) arrange, in a manner consistent with the requirements of this License, to extend the patent license to downstream recipients. "Knowingly relying" means you have actual knowledge that, but for the patent license, your conveying the covered work in a country, or your recipient's use of the covered work in a country, would infringe one or more identifiable patents in that country that you have reason to believe are valid. If, pursuant to or in connection with a single transaction or arrangement, you convey, or propagate by procuring conveyance of, a covered work, and grant a patent license to some of the parties receiving the covered work authorizing them to use, propagate, modify or convey a specific copy of the covered work, then the patent license you grant is automatically extended to all recipients of the covered work and works based on it. A patent license is "discriminatory" if it does not include within the scope of its coverage, prohibits the exercise of, or is conditioned on the non-exercise of one or more of the rights that are specifically granted under this License. You may not convey a covered work if you are a party to an arrangement with a third party that is in the business of distributing software, under which you make payment to the third party based on the extent of your activity of conveying the work, and under which the third party grants, to any of the parties who would receive the covered work from you, a discriminatory patent license (a) in connection with copies of the covered work conveyed by you (or copies made from those copies), or (b) primarily for and in connection with specific products or compilations that contain the covered work, unless you entered into that arrangement, or that patent license was granted, prior to 28 March 2007. Nothing in this License shall be construed as excluding or limiting any implied license or other defenses to infringement that may otherwise be available to you under applicable patent law. 12. No Surrender of Others' Freedom. If conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot convey a covered work so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not convey it at all. For example, if you agree to terms that obligate you to collect a royalty for further conveying from those to whom you convey the Program, the only way you could satisfy both those terms and this License would be to refrain entirely from conveying the Program. 13. Use with the GNU Affero General Public License. Notwithstanding any other provision of this License, you have permission to link or combine any covered work with a work licensed under version 3 of the GNU Affero General Public License into a single combined work, and to convey the resulting work. The terms of this License will continue to apply to the part which is the covered work, but the special requirements of the GNU Affero General Public License, section 13, concerning interaction through a network will apply to the combination as such. 14. Revised Versions of this License. The Free Software Foundation may publish revised and/or new versions of the GNU General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies that a certain numbered version of the GNU General Public License "or any later version" applies to it, you have the option of following the terms and conditions either of that numbered version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of the GNU General Public License, you may choose any version ever published by the Free Software Foundation. If the Program specifies that a proxy can decide which future versions of the GNU General Public License can be used, that proxy's public statement of acceptance of a version permanently authorizes you to choose that version for the Program. Later license versions may give you additional or different permissions. However, no additional obligations are imposed on any author or copyright holder as a result of your choosing to follow a later version. 15. Disclaimer of Warranty. THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 16. Limitation of Liability. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 17. Interpretation of Sections 15 and 16. If the disclaimer of warranty and limitation of liability provided above cannot be given local legal effect according to their terms, reviewing courts shall apply local law that most closely approximates an absolute waiver of all civil liability in connection with the Program, unless a warranty or assumption of liability accompanies a copy of the Program in return for a fee. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively state the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . Also add information on how to contact you by electronic and paper mail. If the program does terminal interaction, make it output a short notice like this when it starts in an interactive mode: Copyright (C) This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, your program's commands might be different; for a GUI interface, you would use an "about box". You should also get your employer (if you work as a programmer) or school, if any, to sign a "copyright disclaimer" for the program, if necessary. For more information on this, and how to apply and follow the GNU GPL, see http://www.gnu.org/licenses/. The GNU General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. But first, please read http://www.gnu.org/philosophy/why-not-lgpl.html. cb2bib-2.0.1/PaxHeaders.5700/doc0000644000000000000000000000013214011522520012765 xustar0030 mtime=1613145424.318620349 30 atime=1613145424.818620334 30 ctime=1613145424.318620349 cb2bib-2.0.1/doc/0000755000175000001440000000000014011522520014441 5ustar00constansusers00000000000000cb2bib-2.0.1/doc/PaxHeaders.5700/cb2bib_user_manual.pdf0000644000000000000000000000013214011522520017253 xustar0030 mtime=1613145424.318620349 30 atime=1613145424.818620334 30 ctime=1613145424.318620349 cb2bib-2.0.1/doc/cb2bib_user_manual.pdf0000644000175000001440000135070714011522520020667 0ustar00constansusers00000000000000%PDF-1.5 %äüöß 2 0 obj <> stream xRMk0 W<++6Ҧ NA7$9Y[(lKz~zz6h&9HL> D! sФ Bw70>#eweffO3٧Xm lcԣ+x s+Ǥqmi\p]xioƩSeI\%I+KfmvX9fId="y#ّzh$`Ȓ;8vqfӲfLRU^ȃea~gyIEȲEҦkb6򐯇UP_#f]|b\z*:^x"R5 5SV sVD6U6RG,^*hvbjU\/oRučk~2ǹ endstream endobj 3 0 obj 409 endobj 4 0 obj <> stream JFIFC     C   E:" y곬^Vi$]Qin4) *CtBn DmJ85.R%RRlL4%U1D3प2) jR`6کt5@j+TGЬ3Rz=25Ǯ&~OQ2Ε!` IM 2}%R4!0L0-.}M3C!EJ4&D蘘lEeiSSq^QJH4xN/Nz:[)I P4“ N1 a&۪ 4~v5{:zq'g>[y#'|Jݩg93YY! PIA# (%HC2 pOmʆʴ [(,r# ,HuY'DQ+kNZ8,F-utYIRws隨"UdRoDM/Mn1TL):`r+LGbwӻ,^sNhd(J?WZ@R%DIEHȒJ***J (%XAlkUC6!MJ jMMPUM*"nYk,趲)\>@Ic%|;}&e#{,ytN}Fsxrtcn((D_G+ͨ`c v 0h',:&w''Xy1y^,)#"{zlM2 4 Pks\gwp\kG#+#sC=MjchD܅Q():Q9քg1R*Mc>^@VHy + J5 ĘB>kS,zs*b0̼FSYԢ儕r^Q0†8T ` hy]}\[;W'sDןzS@:@B`!ORYՓBd-S^lFgnt=d Dƨ̵P#5ZbI6؛*QXrJ2lC/rw5Mv.t'qv/yŋlwq/ےctכXظp9"7kvŗ=U/,rKNJ^y*j&jSB 3q|=+Ӧ*`@?Ioϛl4Rs\G:2&`tj1U'wgMr\踮Uԓ;RrrOd$Ĝ˥oITM=ßVgP.fTL5lNq|ٞos6sar!zj=EJ#-+ ʝ|zEpgGk(:茍&ϭFS\=( P  :h4"Sקtr٠\` o]f砷lwh侦`ΨYL$hA*IJa UnAHSJZW5*vW.uTM'O<,ūz'jҰ-C Mz'>*VM/ ф~ݻlʭZ" D3- ֈ D͢ Q{eR\p#t)1 0p):8>n-99=LB,DD%Z$A BFF8Dk+ɪZ$HS}p6nHlrY+L C 5>ɧTgF][W6^{դU2JJ?7`~A.|Fe ae!-%) R4%HJ7jZ)6T+#5*. p h`&&2S:Ѭ3l$bU"FTB1痷>g8NȌ.dsu)-Am)&j *W%7z=Cy|_G 9{{%*+2+'Y05l hdBT ! R TR%R$ +DVTUBU#N+;z `  Wڭ/RF1djDYy \^Jˉ4$J*4Vz2dSt["-uVJ< lT@6$؆4L KPC s)z4Gd){ 8:N`|t,GIʫGj1uZ),&J=ü(` ?)E/dZ\R` gkϣLfQR4R -*JHCPIZf⣯Xsr;6#r1#TA`7nM @ 2z'<ީQ<.{(}y|׬\|>|>>p>|F|}>>x6{9v.z5̻Hҳ] "ΣJR\f讁M!C|o~:.e2j00k4S(*r҉ %HT&BB)L$J ld]VsVUmgn'HCp H`C"%猺gs¢XsW~'aIz2E:sik^:~a:>i(4}">q} |:_Q1_08 O 5==_NϪ\d?z/S2  @@Gzvu_C l81)*aĖ4IFV jTB@bJ jA5oLD&T 0bc (3z4GLroL嬸94cj8=nn6ՙ}?g>_ϟ7'*,KΗQԹTuҹrRKrrr rrs@So<ӯ{pv^A'ݹj5XoNjӇu$Zg"fh!NF9A,$ P$*fRJ@Q cL QfO6yuO!5QG>:ߓo#ŊvֹkOvpt)˲YtF*]f&.RVIM! fY.eAs-THZ"2Jڔ2iz>',GxRWzIܙ*@kN k$%yC@&B @%H% * SH+ JRD lp )4f*j nTbWiLe`2bqY,Y mHLE )+yW8=Q1ɥhsG}טk3#矿'^į^g6^><) U|ogzԙ<-;s{n>|P!$hA $sDIqCj!0 i!*$*VF(<ޕȳzrI"sY>G:<{Lgby:{6x=}e1͹fh /y׻Ǐ[={{>oo{d;VxRzI-d-<ַ]??kT5îgGb#qfBɹ70h̥6.sV:͚IMTYo>]3w{\=??휝8J^m @hA*"5(d! [#Bi hH&4}'pY`6M4@BS65]ϥ9#@JAX%A !oWhk; CK@! #` H (FRրv˷O oÀw Eӄ%P )  #0L!L $d $$$-! "1#02@3APB$C`(RJ> ]o#57I}_my/IrUIxt8j.eүFIŽGq#$4*Ƌ˓7,i(Er\\Xm%8E~iNG-bY2PY+BI:غYO[/_/|d? \kh8/+IѲR]QF#㧟Z(.4Bn*K)Gj$8N5JRy$x4S9b }QJ/rtjWV5օQ g|/ֽ?"_/ȩģ+Ro< VThʭ|IH5Yc,,}rQ27||R:>\ C$(q&e kr3a2P%%K7Flr_M W[QFt]ߏ&W/_ /n_ɒνdd̆uf_¾">`$IZ2"_eEjI뫣#FE TDgt!K2;jR*]rOUG>⩩NJ!B*R÷ņ8c.o:2_%_RrV%4ug^&D%፫NdeKYHdѓ2m\%K/|~' CpܸBXT/lHԲT^!פdt81;,lԚ,kgFWcn' lgُPRK[*_sdQ_dm̯ זdU-oJ Tdf ƳK2H˙D⏘A\11IFjTqYK5Cgy?|o/9^12^ N B sU~!Ou8sc BdWq[9[4<5|W7ϟ㜴*eC),95L\Or3'3V%>h~Z6FbıGg/]+WZFkצ|DnM'5~(|y'kʞȲm>Ա$BKh%-Qd|{2dj$Q%}c2Q gkqyGT苿ʌy5ɆV \8O;p=My;p4G/CKEt(@흔,h#hj}(+a]ҶJ1c!~eɏ-=o#rc/$.jy',\ƛWQN9u˕jSrᄶ/';Ŗv\r1}T8/qR|Xȼ>DgcXr}Y|ǖ.,G/, ,X[\tv;hZ545e>Ҋ+|vYDDܢ31Cl'uT$aIQ䯫{g _w*)cdj.*0o 5ް>1q'!+zیabe#~#^}Q{g¾,! M 5YykBQޘPeqp]Trl'U&7"PFҢi6;J"ﶔ]^J+Й&L1<90 Wտ{/䳑cLnVQvGbGNY"8]_`#-zh>|EtՉXD}ɉY.*jy\ɏI,̹-:6#% cKyY-ϑT;jxq}bוEO3^k}U^I.v5֊Q_M/CbTK՚+UrbDGYɗ"r;5+t/"vܤ U Ut?Q*>|t^liIFYU8({]71ܥ[w236pǍ9r4b/QdK.mI%LXHgzgrF6eygH.b'f}`džfH;'KiqlUc$7},U~ el^MDǖ9zr8,PQK]nnl9oeMX#d|&Lyd͛EQEjjhԎ̎Ďď;;;;2;LCSSR.HM 3P8|vZ6g.YХD,elt,QGx܈eIXlnn9f罝3`drbrʐɖEQFmqĐL$.$O؂;Q4FUuMۈA">l|i jSB8$GG,d8CGs&2c.TG&ߕ\܄bqXz/KEŃIucscc4;n-#K:Dh|QF&.$B Q^667766,, ,,͍DKKbhp#xs̵"3!73R\"6*^".EttWnnllwrڜPK<6EPG&GG,QEzlز6__8.D[eQDqII'D>QLٝF-eiLT.R>'u2ת%%"Qx"*pɫNף/o]OWK){QozٖngnLDN16l7$q.\9EQDqG&GJYeQ]<*CcI$o.<ظ>G3菢GHK}<؁؁؁؁>|H 4i8١rX1be 232h'k9,X~KGʉMJn<̳dmfgml٬"K%R>J(A rb)Ō8*r(DH z,ۮŖY}+ty(%"\<}(X"<92<4+n}lk#FvѬKHز7Gr'v'z'~'~'~'z'v'q_ᢺ_GJ5TNON,z}']o[ˎ}d.lK,Ҋ(X#œ#Dp%ubK6ehbY%De$#1+/'nl_(D|>Gvl+;>G3菡G#}OH#Go2>;G} ,Ye%=dry뮭7TQ.Ly(J>eb͋.ATx-#tw;pøw;pr8gbz7%tJ#E8-\&cɼz|U+WJ/jG ##Ŋ$뱱Ǟ_J(6r"rX),ND8dxB:Sv=,JE~$sK>#zc?)qqprnnnnnn9qqpϪEh}ɾ*B!B1ˋ"*F9#ǥaøsTe|j;shBpB!B|\= BYp *r3z1~+дQZ*2㶅 c!Q2! |=*2Tc$!Sa<왒7"7&'Ă)4k<5!1AQa "02@PqBR`b#3cr?L'|4AQ{lLȇ^9"Q]=i ۢ6(f۱ܿFפ]?b/g!D-WS}Jt>N53r6W'Sϴ{xO"ldv6Z_-vg^>thIB TM7'lw"Zg\q(U_US*EPl{1$F,m:~J6S'We~s zd~b+D(:?i,%#H7kXO*}OpQ^ΒoE/='NNIL:LI[\v>gOR.Lq'j ET៩ v+]XksjSP*zftf3rX&5ʤ]EHu#Hj)W̆,z|G"x":ԣkVkV<ι3=M0DfĴJd|*"nB T"" 7b-3GE*٢q짍/̭YJ/ZKgiGQMSy1麳+z*S :jo?6x&lnGRj7RU-IҹY*`ṫ ='tz tu>mkHXzrdΙ2g6- t2#N$LܛoYZ)e).*2ʮsv(m%e-r)].6ՔvtsCӿIyXOR.TF4M6*JUCK*_!#4>,>ܟܜ7u'4ێd7~ }}!<>4E^sϝ΢_}1Ztb 3&4AiЖn9BW$B!!)\ڰn-SByY>Y߈1X/;L)s9#%Ol'ܚL9&5iDF&pf||YNx6Qm%4=^S_L.ܹ_w,yͲj.eigbk`ǸΦ.u wbI'&[DDAsRR?ܭ%% J}WS83|ku<ۧ)b;n%V&N/nίeӖ%GN GR^嗼%HY(2l\MT݉%OMߺjzvU_bU*D K} qUpqTRJ>NB]F<<{U̅޻ס(Kl8CD]R.([-CUU5?D5cK%D&1^OQ0zLi'zY=FQ=%1-QF}zϗk.g| USnmL!vt[6w͛x8~ƗL&ts&L3ɓ&Lՙ0^ TbK>o/2sWL|&tf5s&|0` 0`&t'"<5Rr'˿+OH"0`.i%ϑdθ0`Ǜ iq{jT%%T? nj dr.ƙ-{L,Xƹ2\ifx ܹyI "1̲=.9);?O3d`3%4,`EfC\0p3>]EvfK-.&urdɓ&tɓ&L3 i>lCӓE_y?&~:YivYEvY3Ɨ13w5ɓ: `2gLt9nsHgNDg"-6K"-r{1sdΘ10dr >ɧCӹr9ޖG"i]:Xs]nL3~K. n<ܙq&tkZz,NHzu:5ǶXΘ.\=yN%鏅vHD C|SsWWG㑟:ca/Ĺk)!1AQa q0@?!ׁ$F DЫcLU8떫Э;aī^F 54e1QY1 A< 0bHZ:I0S%^ì+m5οiyaB^ ᱱп 勄%-"X H"T0P_Aelb_ыcJ BdٳM4?M "%)~_e.FɓK)JR^ؒ át%DXm!.~0}/P2C<1vx6Q~:UFbHJLJDwZ/sjX#BRc#ii0c$Y:A+TB)e }oU,65=(|XS_-q!*xo\rof} , ЯDzzV~'QȈU!_"D; !lx ًo <eX=': }$߱"|&e軱"&n kfbiGFWM b%>z.tدobyYF&Y6586w ,. dv{O0GوP*m7P-?~GQvm$ԋ%t"ߦe ,~^E熅/_¾ N44Dܺ/g<֐ CHm{t/ H|j_B"j[_Ά4Vސ!")= _HY?O!BO uQ$'0^2B>GBJ]B/!!h؍^dhNS1E?L RFf!/}QckC(. ^t*cCqqSQ6vkeۍEAD"_BjyB5AnU{Brui5=Iy'I8ic񍶉gDzut~D%C]?LCg}֢t%DE |hm /Hsռ}l!o ([CaPePN[[>5uνsC$&P=$|{p|t6)Z! |BhY!!piS~zVl3Xt2FƷnS#K-l@+lkIBT &*"/ȋKbYjGcƇ;ZHx&*َ)='[*azWFR&ɍc;ŮW3Kd ޵="ukd 2蟃ڝac*YbSˈ* //Q/[|!foc{! 'BqBq8!, !Ke'5؝t4dK l!f64~S,W(Gh^ADav':"mrf;x;};Z B,/ᏕЇ1KJgi4߱ؽz5IGutg%]#Lpy r3Gb hS=LEK.R}^ELW[ױ!6 SD!%5sϛv3u7tySyhi aXx%vk脄B$%OԽp^WHft]>`M GlCv¶fA0m ayl~hDAD! (^"_E_q8AtAKЗxTz!+o:-oNYU)؊߂ٖKfz`3m%$m6ؑK1݇$bgI+)쇠$e&:ã$Y5)bf<N8`X&"]I 4,㢭/>vŖoz3@? HCd:n6-t`vFC񻵵Mg6&ַ.z~I,| 6Ѐ鲶CZ81WO#b$Oێ_¾.zjWFxu-jF" ʯoɏH4dBn>lYs|6k-䴂ld ,ŒJ;cFhj}1!9&Iyǂg;xF^z<6X}0‰S1lxŬgf}J͢H-UgV%'˂s3DF-obسK;V3W*,[Eg`z$+~Yؽt$m:Eq"IEdGFdM N73:Vh7F[NfBq`#!}hS+vU- "48HW&ɵQL$b954gt?> wƆCJAކ݅-}ׇMuBΆ7r\*j>vߊ析OYCeG'7Lqg="F8ddlkbݖK$0[to$=/F$R!)0<pZ%%z*z{卖xo$dcD2$ F_lL+OƠ/f?И&a^3A__s|o9* 1 +`-!R o L6<#V,MyBۘ ;ПfK/?@lޓb^ׄ%SIFa#s⊊œHCk~7Ny{=cB}1943~GUі'}!o^;Eixl _zcNalk$ž(e<- m"y1'ҙyf $&mv3RK34)`D'dk9K9<>nW3'y, J;azv>jO=9*'<>W7S_e=^J&R14dٷ?`/EO(&\vCX)&īgB_ $ZM/HG05؄eҰ<  Z hv7| R,3!&4&"UbI&lmAJvcO +ϏG}SZ!S5X~Rd)ֿsefZ7T=, ΘiHc',1,U ͹OB]֟Wtiy G+=(Ŭ}@ )o2"E_N%ٖe͍­T<v_ש5S[ƑA~3»Hc̷;S,u#cgIT@X Omb$ݛ#ŷh׳[4Xi[&lz1ٴF)It:fJ *&CSz3XpҗcF`!ENjr,8d XiSkz%p1)ѣ~F5F|2g$fy:؋7c1W2= Jy4&[퉕v4WhPbv&LF|TŖhF!&X`Iע{xyw鐐|cbSsxK՘/BפN"ڌV.I$QΞKfjY*V[/2Tt" 4LZ2ϱ㬰{dynƄaQU]={<'44B1_Ɲ/ѡ6CRBX,,/YH:MTX 0}q9|ODN'[=G"JD2߃ ؍_B[א՞OB̔񒞯&ȟOW-9Y. \ۮkcc^x!W9.'#Koy+>?F"mJK#"2[o xL$ٵm)J. 4 )}$\a~9B}m[K/f_mBBpk4#! 8gdw >N/>\Xo|? /3SC'OZHF$'ŢI|>4Q6qzGz ]u:BMMj15X&fBD¢<Ut{iVm eey&FKY>([b0B2譄Y5[.joD'loJDd'{.T6tkopϒ-!(u7B|'3B|'q8i&O4ॣX& gQ!e;JGks N=!,T+}zoAo-qY5dɲR]Ʋ;*GF"Lbjr G n_B%]?f*lɅlD'b܉Ÿ{wFeSr"-Ї.m6S-W1E'=kLPgkBO;N'N' ?h'-sB )|5O"_)OC)'3&_{:H\2q6p݋-HkH"]X:).`Iξ=|_3g3\{XgCߎ@nBSD+> |(.UO66K}Ko?$'//1egk3?m$^NE7i-WuH-\%ef=,%Tg~+Շ? k iM(N' 1ú=c D4:\B Agɓ3 oFi>bC|N'͸wx<#g$gC1"g?efOɔѥό"^ǝAs} BKm޷Md<<Ή O1#;El+%RX.>d\dC Ӎ'? 8d05!k8 l [}6HB&'¸ûȃlmCLL?<`~L?'o65:2 3l^pd2"Iv۠xr]]0L=pN:ɍؼvxC"l}`D!>P&xIyB{e|S}XQeF4O7WE-$&7L}Uy [1?E/>H*3cQ_\(+V=m="C0 ?\ȟBwƭ(1~L#rĮDv.N*H\ 9"|'XI#6{qGbNJjKlO#eᔧߚ>IZ7ʟK3ql2)8O(,3_b!v6f>ϤGG쾊~Lr' "pl[B}^4 x^E$]ĬJ! Ut? l^sljOhb֑GJ$)Q q8о/7c-|^gMP-E|Ğ0xG?IO }Bx3=Cm lCa_h0*/7Cu݉R rH oœA%#z#5O L*Ux_ )50Ee"u!V}'xt6c!+f͉;>!1|5OEC-ȷBfغShHL!!7=)ؾLf}| ĒؓEY4H|NJkL|3oHkg> E=n/\" ;1h0Yr/&> j.Z/ HD(D'+0[,]x't TuBi uKcb7įN{'{|om!܏$~Hv/>b~Ě:^ )q詠6[*|kZXGׯ0baz"w" "z(f;e>E A#@3!Kòhm)fF$A#'߃;( P8v) K\ 9c(l 1nf_oc]=%uEЉ=HG!!>΃wS4GM1~] *4kM@W7B/(G{T+m edć~Ř'^:lC0?df̄fFȋȾUc*%pԂ!ϖZĽ B.!8C;G] I7e_!wMti\ /yRD!Nj $HВ|CA}I'!4#fDl4/?d~G) G_&Wǿxy*aױ9̉nO& *Cv3l3 (hâ | CD0q uHҏUYzXH׹)A"! @Ӌ ۝qJd"o(W f׆]d{lᚌ(ѵCOɍ&8ߏF1Fy3 7 ?%%K>ϲ[gv`YQB*\jsJdl`\=+B|gʹ5C 2!+ WJ;A;m򢝚!&=*$h2~hRL!3/qKe,!2:В再ľ0F.,5~xf|G#l~fM/e2m'Lpl 0U}̸" o0mV  3|R8Vg#CBi M {.ǴC M Q+0"/ɕЊZ3dv-ʧB2=s;D2^!, 8!a;e-啌 fW t䅡}$yN=fSn7 ZQR)?Pp!vA%zN;(`lqAm Vh0ɏ$qw^D/! i ip]eBo~BD/2Xl\?zz16.tt 7T!p|d{D_eB !xdA>Bك.-yFln+z0VOЅ?Fz.hڽtO7K)#D'Jx%%ү s c;1Ҫup_s  W+ 2}/đ.!ΰb)LѹC;:%uDc^ŖW#llc#b4 0Ƈ!b\BJ,뎅>Cx(pVW]^đe" dQ+"z% fd76 p-Ixo##4e0lnH_$G>lㅤe3E”ȹ/A[YcDOB&$RɦĬѣa `H!~-ƙ_a&!i1ճ:064GH h CyW+\ S;zkfzgϳz=H$y?/9<:ߡunǢ`g77$F53,َ~ߑOCsFŕ~ϱ /c,짼";h7@fc5}ɂl$F3#Ti p@9^asut<)D CB%p\l''PBn:ɮNkXWk4-=P~y-ӆ<~;aHJŖU*l!!1,>o%=Y`'F$ 0YCg+П!ҍ]~ bY\~J/Kc~~$F^!cVh|^^ F$f"*)-~x ZLfٗu{M WBD!l- l$JB!iODl]Nݨi p Gm䫍c7bgK{FRs >aAI/.?bAwq=`~AjoG;`#OHSd#-:\ Tnm1g0xa=%D肇_7K}< 0Y6N:}06d25Cl؂(utTCޑ JeB= r8GohisKxB MXPCCTSio#U+"l15[HhgHlLSyG lonpjr^# lۄ5. jn+:R\) |pfcaQ_`oN3E2&< 5M+G[J/άC_% \O$1NkI6z} 70$cD$"i,rS.GQ݋,DD{ dThJΆoO,\1„ፇ!,Cv,>Í ܜ)>G$ .mVkTKI"N{±ܲ ~ Є&R;|~85;(6-BQITS>u5NJ7&Ƹc6!y( K:v5 8/&\xṁ*$9sB0(#{⌧ g 7RVUǿœTym^@ oŸc(@oz9o.ý )2 "9 Ϡ @>q=+m}+C>$s nƤ9p5ˠ|FTmơyKV  .ڥķ` BG*^AˈmI%<\*zgelM c7>v~^ D 蛳 :?Z;l 0rl˵ד12WYH*iXnRgI-CP< kajϩRذ`=׿mX }zC./4 JgZv] B=IA גm yizƔ.,@̨!1뒈} b_^~3bx(7n1Rr!q V#XZ.$pk3ť5R8v;-FzCY8oY'1]ÀyDLIB>lяru>bӧ?Wʍ}W/}vdV"vʈW4<bKgJ;1ӿ2 _fY+ݳ*g԰\z30 9*d@'* ⱸ:J_V ,2 @1GQ,+VIKQmWQ];w"n.YqŝGY4E[Z D:$)!9k9wh4p[VV9_ޥ-:KMt4LaJj;0MP2k{.ެ.SwUzݪ9@*hN+9Y/pA4G9,+;"հCf֕i`zHN {@ު!\Zٯ[7oܒ9'ezE,'qSESng_z/=a}D!K /6o1GHbQElAF! Fs\ؐ6EqaHp ebD,pYf0|(f Vt ^ 1$/ɍTTQEFBW ,j8LJ% ۅ! HE3l"^7f3ED}""495!(U452"0ct,燔B𻟡w N3~X3YCGcugX!%1 !A0Qaq@P?o3 fg'Ƹ~am.cgsOL^4Z3>> |D4t%re66CY_YZɼg|6tA*o?7zF6%!8LCXcɝt>.zѳ H;dZ5e-.1cXn!.MzByžrO1:ΧgNclѨyU Pvϲ#B11O # #4B-͸3f2 w<(t:MСO!O?e } hQx,e5vcSbm \,3`wassPF$:;bgR7ex|^Shh M4B1dü\6# lHH!C&b0(aoGoDdd6Qy/$#kB2d4,l'*S?Ta!6S PiOFC"AQe<Q_E!S"!ݏO wFq_dݝB ,ГeD X]@(D!+#:::&Kn|5qA5$4CQfȱqX Ų}bps2eY+8u.Q_1jv`llH1D4C ގ{; B*`(e..:hbe/ =c(LI etz a mhGhż>>Hi`205#'!1AQaq ?R 6߈mF5bR;f E{{ej8]w@RA%5%@)p &yH/Q)+ 9\h3DDq4+qeVX&Z$G"XaEv6ah1(R8eWhw\ K9g:* erIzM_UƹW;{x|=@U:M&E81\h i'ËE"]@`(̠3/;n Xbhj yQ`ݱ/SGđ5=Ƶxt%cp*+s#pXٮȈ*ed]rl]w8)~ -vo!&ёub{MtT Pwh΅b S%G| ˪% 2Ff%&%pyqRHѽLbKMH`Xܪ_҉7mCR y | .%?ܹvRDH˸` }nĭor xl ګ6y@RG!-)~ wTًA'xPxGVa>ȏY[Ś% ^@Xі9M P (CCyc،̒`r'A[E kÖIzɍ29%.)"ėo[WFta "bvuu\p#)U@ p>}29ؾrL# Ī01z T USm@JQN`̖6bSF om%+B /q\:!K :qAjhGL WT #`.Wc,"v+-8Am~f&R#[{?Có;: ZC߈%ED13]5o"_ )ϒs~ɀeFyCB Yp,.RZUQsJ8Xc6xb*`6`r 0{ħ ^X!JXxmbY-pf'P9_)XCr`ykO+N>%D YOir/9f0s2 YwG[xǀb'6+ٓUQ)W"L0TO5/>"\pӎ|1>WԢeQ1E Je_~%bUW*[Krf^eJ+,^ELn a5e O15B.)tq1(@ DMW1 2c&hf 6X %q2a -\vА,V!PT64y~(\[9$y!5+71O7@+fFgPb#6'CT"[w. 9Nq;27o9^ `Zv.œaS_.2ۑսJHrO/+,q YO`3ΧwpQy7/aVG37oDm̛t4z%Į.V5ӷ13*4Q#Lm%̹ዷ9TQ1Z V +[ *¹e,h0jGtJ.V(Y+ bєcTh1ZAMGĮl;*?ط9C#5Jy 7PnRdy=Lv0ap%&Js̼hLB6'%,)$Jфb#L8X9MD1"{;5S,z_%|@ U`_?ܴ򗣈+w9tFW(>!Bەx/R2E;_p56@B%3]GejKh:1_kbKkQGT(,#3sQFJngӵD\ Yt1q㻀x>cv,pH습k#ӛ($~;דFLWSYs)1CU%m(^%1)~ r/4A{0q8V@{^%-u2|C/1 唻K2-S)@􈷙m2T)VXd@b 3'#+d ޳G8Y}Ms֢w0;o;=XJ(۸}K91/f -E,9?xt2dn7x L&k~v8` pV~ѱ -X8Tkt7i;+oaoʆ9|>+Buq?%^fp?ۘt>"jE AJƥ)@8/Ltb;^̲P 41['r**`ՕbRQmG <̬C;%j{J8Pxq);;%5d 1D?/q"a I^`/k;`9XUl]/k/0.\9@ kǬ{!Od* ثa qT5 r#NE$1oq96x6ĺ3.eac=BVDNUw=+*i]@aG<>"13Ube̮SQf'~_|AU3 }L1ZD[^@-vr !lQEj9HopvbZOH%֫yevUpCN(W9pbTn5WO"9h1o"x /<z'̥UM왃;@w X[™)feV,R&y|J`^ygX)VqǨJyrwÎY2WhMُ0PQ`f JϓNLI;#cd/Yk.W_EӦ#/9 j[d,#i f*? ݳ̳w9 >*4&:5s g2|R^(9=LfݰVe?:u\@R$P7 7}KP>ȟ8I Elq.:4EIpL?Cm$U.YרX7L\WQb%9|E C!ߙ!삢` psZԮξVR>z~ 僆$YP@^RRN+hZ@+!,̿rWJA|j ݶQ(7( x >1N46(!L^X`r `4zGu)& 0U<,ѐj0UFY)zvW3BpK_JZ?fFap}zԱK3Gn9A m?%QYhIEoqCHlQ :ɲ9-('H]Ct _He F+*e1}Sf?n^|##*AfƔ7Ru@WC#!r?ATy% B .]DA*9ǰ=1ᳩ^=,-m, X(*l>oiʴ`|o %4~1ר6âE\ol ,N3a&o:uL%ΠTݐx 7|Ѩn&J[[*fN"!v =4~WQōU U ~#3aD|Ю YuS}0:{._DAh ЁdD/!hC145\F5aKZ%0Ig[ PyK3OA ѮU;`!}^"K`/c C}$?~@Sd;BQ8q<Fm`Jn 6{xa9K,Z{4 n՗܎EJ#2-5(hhƲ8te=Eb[+8!D|0+НMyWuL@jriCcݷjHR,h? @LZ$r)9 :Lg5!*۵0So'ctçKo:(ӿQpĢ<ΫWk,7X,ϸnEy6x`TlpOIg 5d1*Up7:iD>?JSIeD:ЋoUJ3L -+S]OB*hcAC@A[^D_oݷNԱXl߹geV]U<6Y2 %w ft70Rִ~b9$^zVr+@|EEp( :6ɱǖ.*Ս.zrqQ!*M#ኵ\eGJ4ˊ2pW(k3T]D-,o5 |wFEษ@y(<:@ohJ&5' g.`S ~YrG Q$z,:Oid4(rsjAsA[f2 Ϸ]Uߨ@RP:1VpnŦm;̫h_XƽFu|oo>*\2ŮHe.biFG0(t+\t-uVPvpE`Jv~H)ށ$vM,3ψKM媴5cܺ !SN"BB'2겦ciG5g+taYcb~}rM0wyih+Q[@ۊW+UNtƆP䌟w\|?$B#Y~L:zeVϓ'vl^u8F#D+BkaRΪ_jg=s8&V1]`w;h<?8@^"*?A3l1ɶ}ξ?@ט6p5?]fo ۢ8Q,iY{0@;&5Go̠進y)zL 8Qs/S7_uEhMf/ jLi5~cT~c-&L*:L7#,Fڋew|f+0Jmqe;HBۈ3(1FpxNA4-.`DYK,{V*_>bCT((ckRvw $]Z"ayq*ԗ$>OŒҭ s 4jał  me// “1qH`KE;}Wi-9Ρ3K 8>B@zXۣ3E J`" & :@S\CF/@60̂.jkۡ|>"%S?1e1im[ψ1UGs,(8nɗ |?!c<Pf^eJa6Jט/aJLL>.or7Ad12jo_0yУ͚ԲmcP_70aNf(`=5}ʯQ,;CbUFY"*WUS4#hQKZ:-S.JeccPW=%ˈ AQZ` *A{+TfИ'̪Z,e_1ᶾW ]QvZ)Bseo7J.zz~!]&-j l*4+fp^ى0 P_>75jJR.<*K/^{ +@%_<1|(=h` s;+@qLT˗h+ :bi@sWK7@eCNǺ/Ɉ)A|[aab*lqzɒ̊Zy%[/ Xۃm#CY[u=ABֻ@ٗ` 0=z`D j RO=,*"x((BLob)F4鎳^ɥ^>%Ag87' kcreaf :-T )P|^aZ)]{:-r&0e¹X ޠUXf \7 ^`qi tAcL9%"|=MJ rbž%lJAKP +DZGQ"/8f#NRUW̰тz^]Ɩܑ3> * y*ϸ F'=,q WaZmT!_4i_O8.Tb``tus%]GH6~RK&hˋaIG..z`J Kb%v ;ȨB=]V&9So.ԊĶ-o9CV@Kuu|FѫPmEceAio7TcrPq3-P50Ad"m\v\d ׹qAVo1`xR#ҡ[3J[CxUE@ b8X!TqU]ry \ꡟpœ yb(7q[ Th>!AjsG@=eǷ,1e Ck(̸^.6X ޅ]*c_# Paz@}rܟ@L'-)0e4Ύ`v=ܾ6{:ւU{h\?% 5_APg9/Om/R9䕛4Jl0X"a =cw+^b 1BO;>ey<2w+aOqs\f(*F _C*:.AwKnũ1*V*J )s(0|"%Ɯ%ſ?i*8/wD>V%~RD+RJ>fBcX4|Q 9qK\v7xi^"pN̋S,O8UZcX+.&!w- *W\\2G=v놆=ݧkճVpgUw eǺ>c5W\(.X'J@KQˢbU9|DP I0U*dž/q^`mMļN0 bS_ƘQspvoD溢JSB"s*_U.{4-j̠N%<aK.Be(By` }L/ʬYMSaDu_-Vԣ.lu切"U&\&M?,]mscuA6ʼny1}BC] }LDfcC5eqB GiYdA4$b+Ȳ.%qGb_ F]\,&̟U.Bas5\p-GpbC C`eJ7~X1ֽCܨ+qrKg9j<=zEDD=~#ˉZ}B4φ;;-~eZu<9~nq1N+wM_\!uU?6[[GYj0*:C/W3Fm;ƢpvwGR4* 3rɜ|dNdqŽ Eroq mm_ynZKo>eyT[po@jC Zu@˯7qnͿ1m3X%Fk5D.TU$ y3B8BV*90O۹@!DV"UMB8a#(<)BI0rM,zJES25 UiԪK|Jă]9~A^S 11I*1jW0w?^ Yqƣc[`av="%s(Yw jfyQ+$Ho3.Qm %MMPJN2ǁ5o7 5M oR iJa{~bib8 F(jU1rw4kn-+\n;cw[ǒn^aN-|T)W~#*sX(T1P  lDd,~fj|v K]E1H_7W}bt"e^S mn;3NՖfjru ݚe8fnB 0-gPJS/?0yX5d۸})wGA3 ++yJˡλCK)?qqq[jW]soC8W8*wUP`!ĦIT?bԮ"$nRgԔd楮L@\VuFڥc !w#*C<J+ZRܦ9%m#MjfVH<@K*Q}:eM*a-87yhQ1{pTn9nd/~jd?ч0ߨS]C=Uzܻy^7l;53~!šZzfsAVjY@!طL170y1Gq3R숇1μ2WFYGL0Jن&hkfOCp//?2^3#MV&f8^,ʡ*1S.cQN@tLKBtʷN IJV/@sW* e qa9Ux/ UW{/U%u3e\GSg`e6ڻQ±:nQv }&q,ψ-au k,>}G<)0q g| nEeE1J6}ANFl@%Ƭ#TAw nz0c+ PLр}N#v'^Nuwɶ\LWcntܳ5ܺ 8Q3d""Ljb y؁; }Gnen!_q(e[j^.]dgW M#S5)nYalrrn0T9qRlI㸊ke۶0ȃ@b ?*h-u4\½KHiݾ%2pL&\Cg+Vn[dP*P.&,P+f`o]y ?"1C/LOq+`8X3B{@?$+ =\ʡsTN; 3Cz֦`q fV1r-bN: f%0lDA]Eٸ\yPp^ķtb*2sz>%sFp3@ODH `9?V\mZ 1 'b\5 p((Wġ``\08'Q ~cX4pġPicM,K7G5B+;E t@ 2_2b56i9x;!]y/mbpm?pUuaP*R[eL e诿 /T2쁱"QUpTʼMKla8E+qccl,>byy 7ۗkg pS5-UF2C!Haod2"!,o3O 3Tii}@(",LdՔ`T[b; >Xx/ &LfZ :8m'Ƽ׸@V"-T>`J_bJkPӊ8 ]:\r9¿YFR U0i2jųu(` Dsj[-&c f"L0yQBf=' ꥳvT1ŢXP`.@mӘ\WKYN >b蹨2V )m,/!/U-NNj6ķ `aB@!` W3:86%V%1$U3s06u4>fW&اl?SrIka|3C潫m2e/ZgZ<L74,'G cc11fP!/yQ}Ek 3+솕!J:J1S*p&2_.;?pʴ*6Ŀ㛏^f\ԬTuo1{R?xF&ůqKx!FH& xPz/Ĺ;1855hh(\ZkJy ex)3SL 3%]L׈xDj3!6/=@jVfn ዯh@/$s?0~QUP~𓐆8n3ŵ6+> YGо> 22-G@3 u0Գ|bݏf#Q.m||1@8}J ^ [ʎj 7=)}Dl` Szb_[~HM=0yhJ ;f8}& | spbࠇ|,{5Y}U%ԯ̲RS8G8%m\3DF,SP*9ޢ+|?cs 2y{xW~_2alSPFؔX^۹|9qDX}FDejePգ)b0ӘQ7m6P,:bc)lB*T%|Y?@rD Vc.0qb4$583[ MUy%t2,\McvEKEH75 :oq&T\SO{?' 0T^3Sl2HxDO%Z6irǧ3Ɵk#!]-3 +ǸTsw=LC_9Ľ#l$X|Elő\"i*dLQ3@6<|Esf/o9%rX$x4E8ʨk3s+^J =LJ9vx7LPW|M%7tC+#eA2k27M騫"&)QoSBu ٮLk7un#W11wj)Jg@";0.Y>浊EyLM P0J"\K`3L 6DFa%"2F;H}%idQz37j%_2pGr9J0܌ĹJ&e8 %#2&.1̛pEE/1KA9@ǙE׉amyAfu2)o.]~U)@ҞCq4TX~%^UCB.g"g  l| Q-Fs+U\¥T6|9z*jaͅ],^azaQ?0"S Z[HUF5s.n˪%k&(!uR~r36a*oKdyƗ%Ysgq(oTƝo׼NUxb,̢1~>eݡ9JL:%\O ޢi?RQqi֏ ]Kez 6*8z"!R*})r doZj>uL61 Zf i^Q=|'Ku2EP#f2 \QАk9䆔CX#Hu0'"0s4A繡|Z+#c۸dF^be˻L艵lU~f| |J[ȋ'An$PD_ݯsķ5GP@^9Q,R_ax%Lݟ7]?2Ʀטgbb|ʋsq/A2+L|q6-6n,.4a[ĬG#xPF9DJ^z_IYXkƅoxFH2]%C-bS#,6.~?Antso)|Ep,*f(y;ƺ6SmbS`E)wLYoWy/pd4X//x_hNHrb~ɻKb&r~~YF׸?P)KT%ǣe_0 #͘uc2sڧ%(y`ܫjx+z:p3Zx"*Q˸FlmGq2(Q(AXQ"#YH(>%%iRF_Daוq Zsm J 5.c`0 ^|f-Dp9r*,*h^M8$\s&+S6T4w.c G|$?@eI 2W$VK**?0Ee# kf.^w MgRGYg IqǧS;O"<`q7.Ȝ1\_To v^es Z96e^%pjv"Z3&ޢ(U0/1j1|r 6 eRGEW>#dw)3AWD&9,-RmE^%恒*ڽ1]G,؞f>GE:^\/O^&Z-99qQ44=)͒Tx"8_OJm?n@o l%`sx /,Σڽ aG-bN*s%%-rܲ1KL/0$yA> P1NQ\o^rKO.!eZ%P.xLqa^Է]&YOg#Yq.5^'2XX~?4P0 CPC)1dDT1 }ʦ*($"h`ܰ u!dU)nbbcٖ0d; ~+ j[fiJa G#B jY[QcM7rla3 P(-|O+e<ѣ?Pd\~i .zh7rv-gr((cC۩ɣY.kPVEAi@MM5ٵ?Pe*w̱a&ToVJhGrjTTFr\ԭ5,ZzĶ\{/Tycp%3 TqbQU^X1M_`-P{P O:EKY\ [Qؾ%% JC[|((`˘Qt-wS 0EpiEb:ߴ o%-x@,rQr_).b83P8,YcJ bf,Cl0D[%hx}%-rl?QgB芅/?pbp,^9Wk?0+!Q2/=|A>a\F{Tr.*Ç11"D1lvDblr]зPQŗ\E g1P嚊ӸߔrgRD@ɞ!"kB,"4[fE28w2mxmew+.^w#UC1B1B97^e w.b,(#e KFy}%yj6lf|&{WQ\7cj,rL Gar &gyѬ}^cqkmCU+~*gqT( ?B4[pyA#QWkSqYJmY¿0Z  oF.Ht EZW :|!1T2!|GT/b#kr|ŶIc_fi`D8?1J p_F=@LNG/\~7]j*k4y Ky|~YQ]0<B"uJ'A}S_rc uRО(98->%\0}r-MKX6BOpңoi8-`?Wr/> QRE8ܰ?/ Q*5WÙgV([tC)KO7nn))qrX kŕr,*T(mF]Ў+lF厐yk,, \D |g6D0~.G8ms"։̮]5qH08m=abE<55rڂL W.TkAFv8X\L[S2n?,kU@GqNsPB:6 jۊ;g,H*jgYwCu}͂֜MZ~ͼ\q(k/:,m1F]s)agA]ƨU ol9lӘWF|fGP@hK!N3`C4,G'[bXxe1̵p{4AVzsU,~0Q<kd=&K)JJepu2arfCp: Us Wٻ4dq~'רK-J=VZ J}|M-q E<ʕ/z2>nE/YGlX( oQ:>l=CBW3!D 8^0*`2pCqp&!wmȞbLqb:^} ܣku^u' aSOY88# NUCqq_3GP; *@(n $/hB҉J3Km>]SF . EM#isc,FQuM:KnZ%e0Kse RŬͽ- G1qGԦDsD' Fwf; 51Y//#(?bM~"-tE1|):eɚT W&?\"%]b'j)~an1z'۠N {Ly~!MR"IqED<{rdQO틜*jE<ᘫIX 4o(J*ax"4}LӍwL@aŚ z]2\ 5k o]Bۛ^nO9} nV\ #`~ mEҪ>Y<%ʥ6i/pG c\Jѻ[5a\bZ荕\Nfq8 8b.Se;'nʳ"iH)[J*=>!G&5&IB@0[4T>v fZ wؔ~j5薰0g>ߘXnV`|DЈe@P6SQQI Y|(D:)[a*0EB8Cy<*XZ@Q=ռtg;ڸS`{(%X7[='$/䱟HBPEP4TWZ\nVf e7 丱\4{@obkY.',aqCY!Iu܌ F GGN/%%y aZǪF n`x~" D̻ts"> stream xZM6𹰮4`d Jo }/45ĉPh|ib?ob?`FpfZoo?}7wğo/oƎ~p^pu >9˃ BM/>L(냰/ΗW.Bk 7^\u2N~? D8A(˫I$S4Lx >wڏYD"g'tВFQ*Se9L&C^g`+5r͑T_YY()o)LXT:H;z2ai!LQLMF)tz}։ay;z hq/>3t"2S*sW>-MGp%P*}*(JU)SUT5c|_֚k,^IF2RkDPW0"P+eP+)]K3(oe.(S<-$"E$(m2%LPwRýc`!s.?}lhlsB="EQϲ>~w)@kw0Pڽjo)q 1I2[uf~PԙE Ux_̈́iE,X- Sߚa 7=D _uc=(J -NU ;,~tKn+cwh0Ӗ Ifۄ[i BJ;ߞ}n:oiNTF (owE25p*b4sWiLV-ذ3'kT-V|VFАa(;~ۄՕ𭄕)ʫT;N٨5gs< (/?E919Z5 NQ^u_ɳKcmH^R]͞\1Zz[(['$'&G2s?*LF'wp.NJ١wPn=˥^/)0em۩#J&B+yv25<]3Vq&op2y y+qqtU?__$ 6M<0I eȟTNi4P ]1#2xĨڷK.uZO:o 9%y~Yd;u1l&u k 7e֖kV,z7b*aȡ#_YImMЃZS1p2B_xAkDhdkJ}݂ bX%L[f 2]oxHDiQ dq`yŮi!"ybͅoJi#(v)%gsĞKDm/3 endstream endobj 7 0 obj 1618 endobj 9 0 obj <> stream xYˊ6Wx(Ez1Tu܋ e"R=[:=u ^@ 3H+ h9Qlqqa=J2vx>㏑e~\9DXʬ4( mQdDuHt#cm+L0ҟ+LOzpq oPP1sY7sKDJmlm4(xw#)Ld沛g djOXf,I3Gd^b&81foEY7DfEpf&ˑu#)v%M("ۥ&I( ҂zGlǘ TJJ;ApALKE<#1Ju({1K{^pJ0^rx+T}x; ndbT7TȎ=S?j_+*_øV±Z#K \~'Q0Ua"nuuF2ӠTjB%h4vSlhUZ˥'d_e|ɋka?Dq\ng*鮇ӰAWcm1Iqv\Uzwg^CF&\eđJ+,-QWN- J_Vj+ETAM.kW"I}sXhqf7Ԭ~cŢ{3 l E,55V%46y5 e,42 00hHZ КUBGU1?k2h pɚH J@աb 7Y͇;SJJIjPz1 S[GvkS=FqYWop{Fc &>n @ak gw Az05tWH㬪Tx[1¡ɁU㱲i4y9~[j~ kѦ%7٨:#0ֱ+Cu5%Lr(, #8=ƴNR]_;vHmPvusW'[83T4CͶp_CY咰Yt/]~w.YjOf0hK"i =eLt"ײ3u#Ik>EJ%H3l1Q_FX^:+㾔{Eԗ$i3悎o@j7.Gf:/uT+1: y/Obu>.e/ endstream endobj 10 0 obj 1271 endobj 12 0 obj <> stream xZI,GȳKn$tbv'x`|wFH!)K26->IѵMtmg֎}3yNi47i|vjɷv4~􍙚܍y喾uϧԬômf֤Y]c,͇io ؆)m Kv_ޗG~2]|)\S.aD.r!?6~V-l`<{v c90 sQsG"yw%Ahf=,ǻv,tb "Ok]&6LPs"'] >Iwif@ӏQ JN+pVUY>ټ{V_ދ+ ㄀`aĭR hInffH|I>wf;te`z(bCu | NjN-a!  7q&R`BqVt!"UF~Ah2(2zI4nk`A5 badG3%zlԵ}#PG+ٔf-cې!NO(R<"i< [uKD2(! Y0SXӡZ^i[cH0@Dfc>rǢ ;霴gs'XoP\ sc9 ( k;S!l>@x@LG(':af6p;IrH`-,aSeL^Ĺ284Dcf;z~{CJՃVH 5\!"Łr8Zȧh}h(I>L5Zj.IgRkb\ uhd"Tc+I`3k=4{٥&AC>抧9{v9iɫiP~,cu,JFAVa}֔5ًNDdM)>?"F[7tT8KƠLNo_{AAcPv3(7G =06St֭Iqրqb^:}d3ƾxfdnfK( 7k1/8bln09$2 OH2mbե[dRvX-B&yO^Iq|-~*uϥP-b#d7{w P- KXv v"qw?v_h6>ӻ[[U|Xhv}/u9[7:$_Y72FYTm17 A]2z(]Ֆ_}quC]|vi&^zy&gD"n,HqyCNtP*w00^ѷtS7b@*gF4 JDnW\./!J1.T.vvm"q gSfrW#Mi*FIj!j'Xyot +;Wo5q#7n!L J8i5?r;q ى[ sbf: _ބt%KRM4٤Եs'.wO]s 2~oӎOƩ-Gl7Z%GI6TIi4>m$O0gs ,fM@l~)"AL7`jr|Rp.x׀2BJ6:gt5w䲦+ N1DavT=J\fw7TPݎl,،r.;rWLihPIA}%Y4 [JzCF S5\zhpv7 ʯ)RbkT=Q%*C~4L(hu) endstream endobj 13 0 obj 2814 endobj 15 0 obj <> stream x\Mo3 W 0`z(zk@J$q(7-DRÇ"/}E\"v]j/˿zY&˟>EoB޾k5`WC, xWWinW* /ɛ|ͼUP7^,W)^!uӆ1l^AZ߾<\EbRE\{]WiïoeXrCA7tvut?P'/ zwZZ5?z6w_8*E2 >&t|,,N0 ^ZV;~< >;Π6{X,J61>gc.{H>E9T"m&e~"1DpKߝZwWg_XkKbˆ$0ZPB ZG][9*ZO~x>D߷rNM`ZK\Ƞ* /iZ)'eiZ2Uӡ7 /6V']`G?ZT9,&`YnR2C/{QA@wFg%ި9zf'Rご15;:VeVD{"M&S }Ѣ/$v~$N]Kp Ι)TF%bԆcf0($QÝQ81E:LsLU׎,)I$̇'ۑ%;t~2_\i4a`8MAp]\ia8:}P`p'`\ U~Obcye'4 Mɩ G:!ᡀ>㦀pLNɷ(-S[&0'RL\Cq@my5Oٟ8P@ȁyxcCfC- ד` {v޴9I;Acs]xMSʁ"]џ`r kL_7)ڏQGt`sQccQm7FLvF:5K+%d>^P]̷Vgϊq$K`+_&o8I!3cDQꔈ&ȵR@٫ZSi9uhi'?ˮtz:Ŏ5}ySZ)Lpᠨ2r<l컸> Y'iϐKC_v'2Uz[ZI0f⯗1>ڔtŸuPo?8]睩xɋ"N}@J-5L= /%nzL+P-%UY #\*qJm~xO_+8=(ɌW= dJcN@hmI1OcCg H97Qm;8U¼<*E^R'Ѭ0Q& F⸬eȄ]69^`c$ZTP:i_T4rv1!Kϑl%kYwL\P`fyi̖2rȿ۔|Nͪ{s5%DqHB!dFWa:ӈSPp\_A($ qs؅1yږqLAFl& m|mGUNs_W-O2E/]܇H*+c댘 uw +"]#! ]q`*kȃʦ˘.9Jl5gL{T/+ͷ2 RՔEs j:+wct__]zIlQb\j),x[U% Gfx*H5s5O sb_=c[j=07TZ+iRk[՞ۼR7h; 4 Xzul(cc ]$HNFvC? 4dPkc=ǁM*nuqQ"l74{uK=~B}_5|?FB[X%`Bnw(@g lefd,衞iS:<'"AʼnԢpC()㒾@vn"m-DVdT,1^l43t;T# V S)ek{wςWz o'x!7,تݡpF[U:4x~Y dG؎@O\@r ijN` aG;jюչ.w*_0t:oA -(6":>Ŝ'5 %֡齣1 ?}TlB7ƟQnhuQ1[x4-i9B4uww>ptwL8|ư7s+g(K$<7a|;(*إlJif`3RZ/ŘC.\^HaU𵒃Mo~gCsEnr~ѐ߸8ͯ!ÐMN2~*Q5< endstream endobj 16 0 obj 4051 endobj 18 0 obj <> stream x[n+ O h4@A&@f3"ҵopnD8:U3L?w\&Y:3-OaOc֫5Y?nO1e>1n&/?]U_>Es>ˋWg?ɷ>c煏ʨy?yP+]EA\?t0 x c0tAex!-qAb^~JYOnu3 nLƋ,Y"%D.`V8d?ՓZF}+J4EFj"_$=+DPFAXrl_e)K jQ/j4^63U֏Z맗:[>RcxWF"KEA{5c{ʪl==Jbҿ~iKY7/eM6y%GP:=+I*45]=L^])<`~ufى{T1/$(Q!A6~B *ywvx7ܮKJHY9:P(šjO*0TB _k8PKWt^Vxm1C,mE[*rcTLϡ6MŏgYo`*W`67`.l`ŸlqUF al;+No]?Բ4|5+uPgSGV+> q&UMBPN Cۭkmp /GHPU8U(|݈P\Ds ѮEg=,B_ZLve5ד!5 1) T5m :oGɧ_L^^FD4̳9>."EL )JRC&ɔ2y ^3PY „]ȨTJӝ/Hè@\G[sc=|ӳOĦ_'P¯6~^RiV=sI%{,<&cߌ[:鄌9gڎVDڇ'8L#]ʼnEHvD6-Tk*9Ѣ p6gt@(&U&9A^(H|$|j1h$Zmx8 $Tܸ @. t+AGCJ?b{"J(40^} L B#υ(9f796@e9y{ $ɹ6;[ =P!/ך϶!AZK1DB`=l`b7_^4Bz祃ANᱰx9bC:"kA ݠO5K9Ĉ:i^D/lIP"^K>Q!#TЭ$:2veˆ%D`[>: Ldϙ LB*vO~Fh1r&p.VuGU}DF K*:Fngw 4N{Xd!Pf9+㚽ٚm2 B|N0ld+ǖg r!piC8>&u;<-ؓ8XAj%6g]JJ hKFElD X:m\pltMAQAĄ;azPpyZ ]P;ySS=uyNuR`pmT.PDAyBg|6RQSu_5KsX@gF!HvbϰӮR'b1}l?j[6'ԹZ+ oљLrNb{qW{:preԮG_^!:,f?Ǥn6|(s-tD}$g0-vGmXuaHG°kvx~*846QOl"I>oc쳜-{ĐXoMjQHTot(5?^ߚ>6 UtJ9=TX' 2nfOTMDJ1(` _X !-2Ӫ\GJ|+ ڭG֏[wap.Mu>Kwb#S"k6[&SH]5ZxjĩY Иe:IɄD|$fh<;F5.PA8U|DU}qm}cKڸmdW3 8v5h߰j\b$k!΃Ki`Ц ]?VBڋrx-cMO(/BGpOh;f'rrB/(;$aƻ-m:{ѥAǢKșC'7c*v0Ô Kk=AF$ u÷muj50HW~%9I }ۏQ;؇ [ivs.6|IgǩAŒ`X0-WyشX<zqu2}{[I_ƁSjmsmz(ã IT2Omt:jLj S endstream endobj 19 0 obj 3279 endobj 21 0 obj <> stream x\n+z=@+|4v&1EU2 lCHV,Rj;0`Cz:,ZL."&֋̤sYg9V^~?\ W_r|Y*d>E7!<>_~nԤ[ Xv}a -.orޯܤR}jۯ .Yw미 S:O*=\+_K)ƒݍS5|w^7}C[ ZPT{ELCgi,%DTY$( ad LsoC ]cxV"piiR֦߽Τ O +wn" B_徂˴50gxgA;|$I LF'iAMj62do;JZ0UM]Y_"Hmҥ7$p0iͯznv~w=|>f:Va`|0vZ/ܬ@Y2-^/q:.v-d"x5rÛ@K"[\".W嗋/,t*PHvLF"79pW,ut8p+iQi&q4sH[1̇F7 G`lRRq>'W+9XhQz&o!ڞ$SN?n;ck.. %ڐ9rD[~HH7uv>y(ޫ=MnMQڍ)6w8dBHq0fSx]݇gg3aR*{,'GeCsgP >3w!VgJΓF@`)H%-o@MJDKWQ æE, gV  ht! @۩ڊ&Ɖ>oXP8 AwI&"<7ssZA/ yP1]h}Ia#~o Zs&, 1ȑdhvy` FH:d'rvwrkĩP)v]Zr &K&>DyVh=72I& ZU6NJLl 4sQr& 2΅ܟ}$R,NK_勾CoəabNѾc;*b)`CD#^=А o>fXdj;:,?wlD:~32,< TD|0wJ^Uj$0LT 6vfsthg74[|ՙIA-6CĂԲaG .oxoPxf\UZ46-(]{ ` ES!iPrjor[FecjIBPiÒSsxx MSz3.KYP\QfzSc/5OI+CdY“M~nnbI4IAE)T']ט?KFL*򯓔k`&'\?$:7rw$.ݣK.QҕNbŠENƼ+Rш~t6&^GqئDcVl\]eYO<}Xl iϝ`W"' f$q8 #>!%j>I{gk#uZFl#iFm`O[(4YNèNRӉbA%1 gŢTNnLjK#`8 [ Rf8[D rܫJ/³I170" 󜼇ՠh35q+( ֺ&v~X"U] *$ Qs²ugQI롐 xw"*Ĉ>04 |HCJ$ ֱdϛS?p>cֈX7Zsjrꝣ=ͺ}D@Ӧàњ f4v,@XBp[xxȖᓳ )"8su*a\#'Ay5*NB]R^Π!YMc>ȋ \H) zNk#U#CtqЃ" 5a/,07$$X.8I/I_,ƭՒk7Ϋ:gJS ΓvqZ T3xu_;dK6,O[ /F)1^ 1`_JCRZ@1Lh"#7| E+h6ɩh䤿$\+x:zJM[9ʐ@Gr_ ^7Ĉ8cܬ%aC `+~b63{_U9藤婦TVfUWv0! bbRFA'ajZ4 ÷Q_*`_z"QqۄըIZTVm*G 1ޚpSoa.(,4K.me7\w5VAޒ۶hQh"DhC9(P iI"$͊rKB3\&c7&0WmAX͊ =֛HLIyj8儂T"c;͞DgK_uX^CS8eHA=LR޿Sf:c 1Qc(^TQTeTXWnLa( 3/'4{MӧB|#nf&ܥ` L&oCB&SK5I>)/%%-Mg sH֛-M`;_ު-ے haN S6 =B팷wߏ.`Hm1P}a%p iLNB4Da߫(Eb=[944)̟iLEmQɶ *S(#Í#F%PS|Tn8AtϪ+pF-&`mze*:U!$K;oyЦB̘Qi흣f/dO]Fm)$/Ǟ8ѽYyS`φD" &.Gz+KZz8nQ>b<|g焺88f),w-2\*v.ߙ$t:tsFʦV9A`X<Y)V$'2H+$ I!NBvP2\q3S񓝔gQXYa^ "^SDS1 jqs6ʢ1ãCq|g0qfc:o@H"s.fT9f|5NsX'(Ai-o&&@c@0-eۑ"*q_?9|ۮe'vԚٕ~p*#N:ɂ Ȼ,Yv_R_-'Tx?#^ endstream endobj 22 0 obj 3496 endobj 24 0 obj <> stream x[ˊ,Wzzz.hx3 =BJIUw0B߮,I) 5?_؉MLؓ^$f}O|o8__ٞ,c̉=~&,bS~\u= S+p~Hݕf&Wq%zV6*/̮g}aV&_EsUZx~lu×ƫ4Uuֿ)̯/[Q໅{ǝc: f$\LKs(a'p—"Q$$LBIPU(1Ԭ<,Υ?bpO~ D53!፶|-\R{~Y~l0y=mG}Dɨn8A>pWT#ڤc1fej8F=@֢uÆMhͽŀ\s(#ԴttGNvU+5{"H̶<;İ̧|; &*8IZd:'5S=E#Cf+xG"ZB?8sT臘f3$a'vOQA0g)553m%ڡѵ2RLo DaCSlDR&A^unL3ԡ6V'<;ѡQnv>m'R%NsȫJ|3Qi'$n`m@7m of> 7}5 jU>g|ޤ=Lv[PCMDG:)ҿDHwxx!M˭YQGSБbo*CZ uzK$\̫sVsgR`.huw0myB5i۾P o% e^>k R#*LdrMϑ9Ŕle`ykO.`~ʈ7lKr#\Q♓S6pn 셁~^y*dyk9d2I$EE;1TXk]~A/J\$Wx^=<8٦$o_2g}}oro"dxޤ"J?-lzbBQ[YHE ynݐz;)jJ{_6{셑4p=MrA *sϰ۞gAV' Rz],dM09A4Гl?/IgIXi 1s2ߪ;3$nt6!J;4d>cr0mEHEXraS,wgBJTG.qoIW 4nk=?݃zD} >yu3&T`۽E\~LE5-g2!SDAc~:]yg_O_8!y2Xtlkd6L%Y*&‰L ,~$%r>rG$euf?]ϗTb Ӈ҂ktGev2͆"E(G^(2Ok;|qX${ަ^[<@#QeZZ?I6@X0bOHJWnu\B endstream endobj 25 0 obj 3101 endobj 27 0 obj <> stream x[n)<ZMb 2 dd.DJlO`HVkX򟋸Abg;(g/4?˿חe`$0N˟E/?i7X̛˫~SbW b*ߤ][|j|.7q!xXF Xw $'7|qiL-Λ& 0Sٗ"$>p$4ɨǏ<>^M G?B?)f5rf!9 >3]-:%hR gV˜D@ؤ?%%]]W@I%(EfNgIǖ v+:SzP{#X%vQPR1)R=/d}Y|@qY"m!M7UNqȬK B'I8܋7QKLЗKDHJf!t/70|^TɞtsLsv6 b67XZ\D)B&ط5whΌ.|wx-5Y<['R70أg3~hokn=OHft>GUz6TaGu6֬~B a3ӪpgiNj;Sʢ5N!'Y'{i$FK,vy}?Qω[DMDg=CY2D ~G皛2{2r G`P[yѓ&.y &U׳L w c\˫%Wp M*|Cܬ bS:NrpϲSH஁O- -^͊XBCCT>fڙaFa7D$i~f1 ƃ_S>?Y&6k,Ole }&Rqv2ZwFpRb> ?;B"N]AOuR7MBJ@Aw^oh閭vcVux@.9lh>+nJcw&Y,m!RZMnZP`H-'QKI֝e5bGOmIN*=;Űv^!4tr FWЫL)oԃ#} M7`z -ԸR a"KܥAcy^XV:0l㙂g:`]hv^*To^ّ,`T ҉zS&pNLi7߫'-6#&nۆmÎ17F^&zgÌMyaڽ +X-oX% c9MN@_*L BR|Kga@]'ݛZ,3T;}aw: Pk^@*7+F3t6xm~>@mީ==嗀%s9ُ1 >/2qTZu}{wﳇC~tEuI`L@-vIi>b]1Dě b&At黡 N,5uM9HYY ܀mkM_mrdw=柆~O-cȈ'ɉ>f%Ë1*^Oo fz~8 l-$>ScABT+U0&ڱp3[lb62RX%5e0TؔۏR FO Z%,5c :\5$(Aw]g1RfK-#>7BC̱҆Q\1En͞U6B \D endstream endobj 28 0 obj 3230 endobj 30 0 obj <> stream xZIy@7{ ><}ǒTy*UV.O0_Ԭtf-OYOQe􇗙@O_C=Wj}7JVF@Vh*NFF@FhE q!N!YgҼ`[RѯBDڵT2]D|dRi6ӫ>q^Ҳ$#dWv(<ԇ!eZ, `;~DZ<;sjpvm;Y"h]ü( =wOH[<,B XQhgAM쒌 ISfHvFv8lfvoliEb,=![ IE9գPb]ǫ'BuZ| ,&GB,;'.R,Ce'= N@>b =R$=+( EM$kLUDgIA"8H;lmf˨M##"^ ͡0Fa l2I:d'yAwv4EģVٍ$IDk1M*Yhc[ۥx$Jzn>ƃE:N2l1(eHJ\#]ɃK>ɇ\ Ʈ,/\y}wZDF4U#XR qjN1,&GQUXJI2X}m۽=IO.grR86j00-NY~b 6v. C6^O2u ꠆E9M8 BѰxq>xo֐RPl͢5E8<ւ(=Q4OsDLH3]"I"X#yI2̾?4g,,yda]4O[Y.JШz%{7L+K0b/b 6LڼJ$O6Q# 9e3JUsLɝZMzfo=%Ǣ>%#NzvrS[>6w,hmmR"UI/Y!S=|+>Wȸ,A26P_VԲ7ג<דeRO =0H(OaV%|̴Fe@\[;S-KZ[Tk%w 4މK~5摳lQ WL|FD K27:?)jWiY+萞LřJɗW k ҮѦ&R΀6u%E֔he]m( l >H} ^k #05F3oqwTȝ?P^f|,gTq5tK=8͐g\0P,0jkەAy+(jX?^%`[?E8 ĹZT%CEhٗAc"ѧ'xTkTwpGqS/T|Ks zMGcf_i֠=#NZ B qko_MԷiyBR'!826 "~ǒZ( Ffy-28ax8X#Zhۄ)ݬ$=S"Z3 (iҚ \jmiWIG`Gj]+ tDyNʇ 꺶T?ۗwTX3f8`ܕJklh1OJBh5}sҕVfgҚp<`6~~5#*]zU*VK+v{?sk*5T~81{awݵ;!TR;oܮ9 Ԩjm3JepRp/7E?` ZzXnE-%C ީ_d^D+XjsyhH)5i EJgl?r mpW^i]&4MUҝbZE(`1AR ~/q ;-TW7w6Yz麘 ~iZN: endstream endobj 31 0 obj 2295 endobj 33 0 obj <> stream xYɎWhz")R@Ceh-{I,n&[,,KǪSLgz1.:ݷ_CǛhح6.c?ғuotSSwI#hUz]w` f+\ h R73xDs5#fg`>hLySVyCV7yL 8]ʷӅÄ&d.G`/\e-~e40l|mm5 kV6mݛWYo*N#J lp]ңg@#_¡@}Bg#Eq+($LJWJ:'bKfv2g +ٚ՝vh鰢[5g\-:3/?Pcx;Q0%VsMش-VuvO'>~y$<{z5*UmXq JD# r {bNA7rSE=.שX*IDBQn.d5r_nPTlo 0u,$ ,D7b}4q!8K?aB[e<{*&$ƾ#D>F+ϘΘ6Y2NˏCUGHk;2:u!a\(pId49:c91Zs+ܸJ%r[ƗqqKg"Ngi"I #urhp,@{%>z*DkwCOs5XGׇȒ(A1ۭ73k1|wHZ-UsS[Rbdgޭe+!y}o%;e˒:{Εh]vߏ+W~t.2$O_Mm.WJһkr[v%Ҡ~7ZdRYQh+YYY+G[ŝuPQzFhN,vUt-Fì,ЌCâCQHrHلtEЂWMT%-oEm$5bGp>l|wCy:5l*uF?Tmu7"K~q_7_2$%$L1v44to!^?\:<47.JX=D4 ItytKVo^?$]5qYɓ}J$L]Lei]^jl19ʹ#V5DꗖicSi3z,X|Ntp?uQIS endstream endobj 34 0 obj 2069 endobj 36 0 obj <> stream xYK6ϯyaU {@!d9TdIi7e,_=Z0Ϡ5* vDo`` i[vп\_|W#8>tweRpz;q+G~^O8;I* *- &uIKœ7Z x=IY~ִ]Ou<\!j?]=n#6Lj'%QLZ#SDӫ7)GQӳ417 ^Q, z8|4K9>UβٚUA:Hu^V.3 D?EMu8?ލu8;ԨW8$+8FÙtK˦n X@zCOtN $It (tqqm;7^:D$A?T,*@3} qxqM{J1ӄKaܨq#j2a [HO;HP(PsP8@i3NW5!#š^mt=r4S6Y3A[CK1粑,|` oPLH@mGKi#1gRu;qZ ("hȋ2PL~?qs(hDhrW>5>[_7jG{<K|\R=>xoőoޑh3:G[Ccs1n(qĸv1|$'o-GIt>K [^ k1kualWW=bnF< ᱖nR"pHݷޑ'J$,R3BŢ&jI'v~V e,Mm7hȕ+s XY [&mc:%5[D$Vf~,ٕXr*mX*AkE݄5MHmpPHU2Iv6^Kb_ (dsR5\'E;-"Fo"n\RAS]T$u2J[vA-I wV 2|bXruDPCMSF[+#&M$l@gNs}f/slHss:fʫ:m~e$E0AV49 KFEԊ3#R {3lf+7c7yv攉uqUy_)*Jn'xt7mm:{ ` ^5|\jn݄:Fh>](i.Ju"WcS(!#F]֡v'eN+/!1vۢ9ۭ_>J+Sc)x܂4}ͿKI L sBC2fW7s޸y:9IJB51C7rܶjC^\s"u3>l ٛ" endstream endobj 37 0 obj 2144 endobj 39 0 obj <> stream x[ˎW(,DEv.q,W"%$ܖSx&nbb&909 n #},r7'dr/uy7V&~zj71M)HN Wѵs_MϺ(Zߔ~x-?<^ ~1m0\1[~WǞ#`]F3渒_Dfe 6 _ G Aa#Wa_^Ų,ۿf'כ_Zm nآCS_udž IoF䧇^B~K,ˊiqB-_|y4 Fj2MOIPS$]k )XO )>?'fԌjeqO8Ms֯d &Afyr;J2{(`]IUeC5%3uDG;h'ю#5a=~3?Qǩ`d{>P|p<-xbA&ZixF<@݃]ڃRoa+.R3oZzG,gvYI)68bI45&5JwN:o*ݏ.#YC?2@AG/FZNZ j fθ9Woa<0f㣚7K4u ;U7E#[얍2I*(<#g]L)^IU :W9(2b+W4s\x;/D^S@0r@dgcʗa:lTS2l -au $nK@D!d҃{q]O "z\AvԀ`MׯFˌ3>W,PZޘe@ң<DzY *L) =8/$kVƥ:'"B#>ө"YNPr$?T-/ȗ9!e=u[S bgAza\،j'Q!ډmQqͣ\@LBX{_m *jgJ1 W a@=}{ClHs+v<$ͤ8.Un+A=,\2 vQ5ŭ9o2#Ƀ&zrA[z!m$̓r3<7DY'-h=XܵKh]U`(t%Pm(t,gfX>zAc'w3U[H4Q焴L @CV yMBs #M 5qjJaĈERFOn*[ƇSǶ.\NCK|O oiUN=ud7YIΜMB;zsQNo`R_IN=mjqmbT U>q!c7-e?)}Գ ek*YejKV" I(k>Ɣfr|RV8+qc1{Br^;݀8f(e㷖03r`Y:(ߦ*;Z\Ք:FE-JE'-hR`KHפ4[;ᲂˆxe۫ mIBց4Y} ?͘guQo d&2lqW<:)O9:i׏F4J? ߄~x-$ {b JplJgK4UE܀oխ7LV-80]#2p\`4(2SJ"&qX嚆9[oܐPvM Trʠ*#mUP`^SRF]RcHK̞s1C.x gY:?(* E'xWq$]/qd$l G /n87?= )G}iq_Y /a崈1.EVGoފ_4^1uI[#jJ)uW#]xzЙ jRQ3-Rb,z Y9cpKc2¿y=o.O8>5 Wf6^;:h̋%)xRU#˂|m܄f%du 9KXdWox#_됪؂Q.gZEF |.^#2 da5@?R}xXA0E/+4x{j~Үラksh,G{GlE]je9UF/#P %P2ȘW?x )Wҫ+SfQ~/*oZ0/[rgsO9뤙vj.KjBTӓ9 ݩ!yY9kػ9ˑI끮zeϔן!Q:m^@QØEp Īb@5ɍVX)3s~7hLVOV.Ufetzeϑ)h\@pS`NKs7qy`Jt"A4TxMK )"/vYk"G!b7+ڷ rcWRj䨥 ׋۾U_.OvpȔ; v||.UR@ CSzxI3緪N ~<ѹ~*b%& V*Y/Odַ.}וDy*'SqSUPd?a~-yJDF6629Ԝ5xLHs.  xvU_ɵVL$vi]l:q2`p+]Kwts%@Kѩ6W@٣O}&[YܵG b֫]uX5[M)M}ikŻ}O3Fh?1gFګLQMz䲾8⾳b6E]Y~h:B9vYkTlʠ.3(/|- ֽ{WՎԽZR7$˳j{u[Ly%X(?4tHglmALK7(*=kߩQ`4֔2C*xs-γ&k1&~P;o7VUTW`ZǽgNUݖZh#5GeIǎTc\SI=&;j=ƤNzyUim߹Ʋ8V2@Ye۟w#M endstream endobj 40 0 obj 3402 endobj 42 0 obj <> stream x\K$ϯBTBSPU}ma7.`^-)$E^ճ3LwWfJx(_J,oXrEm\*/o?]Oms'IJ|.{߿\ բ C~yWռm}*ߍwaOŻv}Sb?ug?r"$~aPW4)]%q\)ߜYT\oWg e# !&.J_}8,>ϳ_#gi\H8_ͅn U8Ihq셙k7"r"#tѻL-V7tDž'-eg\EVGZ!T_tI{AQ ~C;oZsO7-ؤkܻqUm x^膕mW/떭,eh;2Jzyַ8oڢ9gِb?Ƽ噺La~nqwƿ<8e-5 l9?1CwmV6^ؔRωt)Oez«"A䝦,*,?.~baa q (;<܎ /Ә'dѲZe*Gt"n" i^U ]&{Et4I$Dc`Tb?wyzxw;cQW!p9+!t娓 kُt pP\-\ňJ6v2 7$2\JԮ[-گL|FąD}I Sٮ{ S]Gm7[eN;d˗/=rtCoRZ'DӲ7[1R ىK0Oǰe3G&];ȇ\i٤1vSEe|ez1-(Kk G/D DXA˵,Ex1$ cp%KK˰5VJEiY(])B閥IKCWvVgj@rqr]'->̕#f.KI{.yU (43TP76:jL KSɾU=lnPȞe=Sdid$ 9R$%U%[N~b ?ܨGfo*+vf Ȉ%P'!Ӆ6T1]x%TM5Lpt/UI  zqz/(yƍ1+W0@ui!mjmڮd$k,L04-Bٴ_ uiԛ̄ 1Ui6,%Xb%$jv9xݪߨ^ u[QQ-DQwUCrEC^%AlDfխc}fElEal!Gq߂L^n+Z3)xfQ 0 !Xy sѮiWx-0`" )%\~$ߨ$"Tl~5jΡlmsvąé@Xn V)xFvʑSspVX?^2Ii)'sصWS.bji:#ndH iJ= ȆSI j(gǭsiұs{DR [z5GM`-VYoU &Fu,0f!%3X4f&Cs2n{AT0s2j[6?Zx!{!b{i[b!k;;\qhQ w}]LIIt@?M>[j$Iу]-c[ ϵ>ZH|eCl0*"j\7(dg4@ Ӗ$qcHf:Hx&=Ru!КR2Hf>x8Kc`+cH\A?aBbw#O֜ιA5g>5AmIܩ_tMihc4T)m.ROćP(i /zyQ 8~[zb{ )HL;j"k+xA1>1(N;b%u>+uժR*6U3$y [=Gra 97mov6mM9b],Be[zx\[d9gОiɎN×qəc}'}AG=GFmJ;SQ5hArI-IP,M;ӑu9{уxYG']"{'d 0Q@(cAkYI:>>YY}E(1ײC_jЎ 1bHPG#mhj;㱏암)4!M$Jw: dHGJx\\i%?Ҿ8R{wpnK>$Veri&̿YcH/~Uץp wXo#P~oB݀sZ Qs$G2i/,F2~ig9ydP:㚁XNB> H Q:Yon tH>3%lu}jBx}o㟲攱94n0ȩ߇K =gFW5T]C :g@QG;a?ކ. 1S|/Չ endstream endobj 43 0 obj 4036 endobj 45 0 obj <> stream x\K ϯi@Cn 4C[v!@IDJdTmY"j".b]nً3rq۷r7Ƿ׷]-XV_y˧HuoJԛ߮MfޤŋMlrjpxS5CW'JU4b|?;{nWRUwô\xUV Ӗ26Ħ;qZqwO<-Ho~+͙Eu[3gXMeºmw$e9cq43M2W,۬xƧ `>(p:wbk Gߣʲ2>juݟDʰ$Ů۲wsMz*VvuI$N<+~flIɾK^MJkd6[-k7 (mm-'d|EcK&|k^`tRtXJU4A[ G)"Ԁ\l?lFRZ@$>D*l\L`|-]|Pٰmi)h1X_Փ:"Δo>+zr=]CEQ\(3ze +ʙp(qg!%8S"ZPUDICf93 ː $,"ȉWF̑-z@SCWl]`k`:@M}քӎa'o" yP-Aw5 0^ޠN_59;gfOwMؚ5'F #;\_xTBq6'%Ye!̚9>6AQ^ySlY"+*(|TCv$8]" W9ZWd:}wF} |D,J6ԑ1'Ju}*Az۸r,92qTħ xOu x2HDɔ{$B kOrN%)@$Ɂb"2צHrCrJ;[%bꌜ;*ɈfԆ)#yM2zNIJ˪7Ħ&_c9G'O{juKIr+xCXޑV^S tpr(_QeP鯊!7I2#XĎu;AqWaɊMH\ B(D 0es MH^Ʀj^>@sRL{͍RzčLd`s`>]E J4%NQQ:Pz|8`_)ဇLkjO!xK4܇Ȑn#@>9hM25"g4C=, 9kI-[|7MvA2>EiR&#[C}0J).Qq. R`C(6Ջcho#KAx>sjDS`kԋZmd3?EQ';Nf! (؁,N䁪BS*, Iꟴfrz@YӂoTJ1T0*r˖$S8!<_ I(Ji*-9@B?I 겸4W(vKg Abed6Ҽ$ՠybI3 LIiF9!/X<4bR]| yY]wI/SnC x}m.Y8hN%U)Y>yy**D&ɁK@ODVsbiBBAS[!;s:ʗ3SQuLaLȎGc$'x^z ;3!zny@^QejlN0DUA))u %Ֆi]aY7)fIY *S!Y- 4QɠjLii[&{|DTcz0)ΛVTw"%wMIf!da^RyYde6$xhr'դ4'y%9Ao۰ސ੉j V6gR[ kr& gT"] M f߅\w\)Υ84S4y]K'&$ڋ ؓ@"1G41w?P%FW/'Yݫ۾z2I/|6, AZ~ QX x>ABrʦ@=h\ťLaAK'ؤ%[ ^L?D獺n0BqnA/SE㮁D -e.Hzj[xVӚT-[KQf.'5:bӤk:>!=gXs`Vj:zv@F\%F<6$φNEa'VKPH v Qx1Kx[8\Tޗm,zfYG/ܼI?}!#  ,O+;S@wIi,t8#9,hI"\Nr)Q_Ė}?޺:eM\ƺ=?t-hltGe1ujly/H)qG_9px~vٞm> stream x\M eQ@UW!!-9^#Hʒ3%`۶lGjNjRڟ&0NOO?IR_Oxo~W7q1`.g>/]{^yy%^6 ʇ_5\>?~|H/8Ĕ prq}^*^+u\@ ?ˀ8.4N~ .L~ ɧw䯦7A.h=8-/FHOuIJ@ WǷϯ_{]V'vbuE\lQ*IUijUA|njZ27U0S5-qNsbOR58"/.ru >Wwrk;$sfAMҸe|I*|$ŧ[UH#z7\~lB:Ys6.{!:qL(,+M@!+WdK.^zgvv^&6J^Qks`&? .M(\MoƅO|6Dܔ `F¦ :Z7TT<.4&+ ; $<-k ofN//L 5ڃg>2üb:Uv9T&_.#H%?r9*6'~ G+ c׋!pe,͞2s%Cg\;7aᎊRJ>}햡 NA"8̚6kz?L|OEs#lS?&55'f5. JlWeġN%^=+^Wl,X'Ҕ AI%Cc@ϭË ]@t4'3rw}{A).JA|Fg#xԟN]cЊ&P=9c=yRR#{Ǹ 363j3[oѢ J1P%79L4Px/=wZأ/Ӿ+id:Pv6,3NZQH(T{`[`InԳQ3PLzN}Ъ'gr[Tx(r탴r9+N3gsɊYE 5BلL }IWR\nLuyLY2]>{#5ڍȒK+w|]X]bAɬ69xwB%Gt]%BOYv[JoHuT7p(ҪI_vf|[Ӭh̕ݙaT]ګ l0oIt'V'CzIdQKIh AY\la6I˴x#9L+s3c]52#NnmӮ> LL͹n&3 ڒGa!U8Р|dD.'ZP$^p6Sk^T ڧw]s=0n2m*ϘwrAgH+n) nUA״?ڼ\Suxe &ThaƪPB/+IC3bkn7ciY-Fj-zFdnLhd6|斝R0D-VMVՂdAD猺Kσ5;$?S?V'Ivcǎ1Edk,0sN,rt7v1!^ڤ&8JƄ 0:V{&>hE:UGs4{I#nQf]PMvAkQC@|-Rtm7|wqFJkfZ1085\G +)٬ īk. -aV@/!^FiuK$IǜDE .+T}2fb7U<9DL nAtrw.%\sF1'M%f.+J4t><|7Hkzʆ G?IP)FY`.,|Ȱh#yQMs>S{Jy}͞9q+M5`w) ieɌۖs6eT]ϱ*u7]LnsO@+'ebcݫҭزRBE7K"g1=&֡h$ql2dMy*Ռdb7$mQ6ܢv ..˥XY`n$&=ufu!kcUy1GB*rU63\ 7IE`QV j-Bv{<Үm̎% pXC:"9 ZVbVhȊ쥳9'Ʈڽ1r:w _Uv:KkRxK5qsK (8 aT5&y/ yzP>B@‰tyv/cc*JOT",_Gdl/aaz`D jN3W*8knkX[w[)Vwx!U Ly[v嗀E8Y&'s/H(GE0B?Ew5jza7я,n8S?"2^sDFrw0U> stream x[I$_QJkTBPY>1`\-)$E\1 կŒb~".b]l5ً3rpr7~5b|O"^_Vf5(>”ޤ]M΋atr71-Ws?Skn.W?U+NP~ar)2J/&A\D0O/&g~{qK\9\_H)8>zVFC(\+C?L$͗[L3KFhK202,N&Lz"QÊQ$㯵Ndk FaA 'Gˆe"uR0hNѝTԯ1s@ўhUnGLv IP+b籷wtSdSS.:)S%V⋼C TfUѫMgi-c ?uBuCFWE}ښ,0f!Rˬ5d&q+\^M݋ p 4L3HS0̨':RL Vj 툚(oCx`@*mi!IAxa;w Y\k&IA)'!9DvBveBAȊTz 'cDtݖmR;(eS0S~(XJƪ|N='ֺ"'p,7x/ a4_E"Z Pk([| (TGCEn0 L&lJJP4+ÒTb[TaWe7CRd 0X\C ~X6βm`\SA7K"fodhdЭo},=Jf*\^b83ݟ4>};ږm \^p;'{QAW$5pxTrFCtfwhctlg2P3%PNfX산t[)݉ -.풊Daڦ|D٣UDk~Wq[3m[jra36,Fx6G҅jMSksUyvi9]4]~"'V%\'4gQ cr:. VgА/TuFjsS o?fC"JJC47$udv Scfk5gHrs!No;HOXNt)ޚͷ}Pu2:a]BN_F #@w DGl[<Nbs)ac H̃ٛ4|`]=Gs <2(`Ohzn3&"I:FL0!JFSH#~詭D3bQWO5hm֜,N:}6Ap|Wkz5ΕQVlZ9Pʳ w{Bh!u+ͼj,JIPEXbh n6!=Xa B[Ew٦UKӞ(9 c*ť& q%k/U w:> ?㸩#ќCH)I'Gj3Θ4Vrx:R*^ˋPg|ňk!yJI鿫CJ"Bdž4O9 8J8^ӻ~~-T.vVnޜIxSn1uPߥuӵ?Ρ55ϽgL9IvZ JghSt-I nũ}xl'q% S^-AΆi),Ŭn,G8$87 aSzʺ=ّ~#i~$)o ,QRMW@ vzP ȕPqUvD=π=r졫uiqEMSp` 3}cJȻzauN.tҬCoTc^XDlKDP bKHX1~2CޜĽץhPi)*dyF=J ll]5(p6~p]yue9mfMx6j1w+(GΥ9w%dahCZEМhMiBL {xAUQ? ǂ/J} rIė!H~&J9 54;)K'Aq+*xk,BP.y,LSJ|9aE44ҭRmz`fkRlJ7DU>lZv Td@&^?kc"=Y~R$n@ϵu޺/:(jC<}H#J{L]kqIy RfӊJ5O>J,v?r%tV}C{W @3»͇VY[*b&qv-$Kﵞw3 FSPzzm]O)ke8v3@$q>"l%ZzXe]h,I~3#W-J {F’H/Yoԣε|Q[XQ /T,hݍhwpTDkykD%I\B HJq|B6f 1K޵V %\ > +E5 οku%k/& i~)F̱Un0}\^(L$!1V$.69M})}5qROΗtT砙nb4tn_%!.89/K^aT$9%y`h0ھ+lUxE S5}mFQQ^a"py;T1X/*|zp:{xpbwRBz"m?.-?5ziU endstream endobj 52 0 obj 3489 endobj 54 0 obj <> stream x[M "Ӓ @&)m_v ,%Q-;3b03,?R-y?'qPd';(gO?>bө~qp'-ᷙI[ >>m0ַ+r\|K>a[._6zP=r-J G.vy~[Nnrv궳쑏]m`zCT7fT\dpF?~s!_|<>~j&X&yag}Hygs+anEk.JD"M׳H/v=hL"TI  AeqsΛA_XdBq= bnSDSe,2Pxy&N[7 s+6(30 s/f&dz|G`i0ku\؄Iq@/” .42 4} N! LQݲ|AE`R5ro>.H)q0+ i^lto ݱJ2a@|ayA-Ta"JfClF.V Wa˙U},<39 ˅Hܑ`ܦmIZdVVˆO|#.y)$e@0ٺG ~Bn'i (ۀ`4V#PBSJ)Fa3v~Niɟ) Aa&= SDԈ0-T7B=3*`pExĻ?.1!L`I"4,wAG*' #1Du%dsDE)yˣQ PJ5XN!fd(!=1G`_b]|Jw.dZ9C(쨧5J.IML!auԲU`E ojAO\%CxYP6**̟Gp.K\zZg#rW,c]r/ UYQBUQ[YIZr]8;jc8\ mP٘tU-Osǥum@woE|ΰ*c(ʷ6۳ V‚) ưvYdSPΣ1lUbn!UppNQ{5tЈot]C*_9vHrMzV*&5Ρ 1ݤpN]e $ֺ50R) 87 gW+|hJ=z,.>xlC)p̆j/uzE]Fni;}2=dU:b6WZxޭҹ$+1笾8EN۵/sbUk[yPɸH575eׄ`Z4i&b^k$eYbt-xY/r:YRk׌S?0aM8m;Bd%a!8 Pn03fy)< Eˎ[ &;S\0L}%~7rWU sQ>n\>;1?>rbKk[oOB対j ]+׻U}, JEe%R u )Vc4䤼tKP/.ʇ8570/4vˏldRx j X_]7^]?Zb0Mu$C{le doMca] 2T|"[}ce )W#!_VU:onG=+Gcc:LLN]i,VĢ6ir^;of'K .9^zpQդSXvSɮX)=A]xq bLy ^9ck{"SŰQ^aʙDܡt|+.F:ƻP5g1tJ!^>H Pd6{ Xhӧgts{ү][{4/Dup ܋K"k6/yHDR:Er+x^PTyH.*ĎL$ҵsrxJC psI7) ^(Q^Zׅ]{tm@blBM#7,/lЛIE"TJxGBw 8็ Gh4'7FC&ûM/Z+/k^M\n[ؼ17ŵz1\փZn˓P I>aZIep6tG_L34j[P2$oj1J_ތE >I3ZvbP+1s\bzY_vXg',PA(j|:eZfCL}M|~'W UՇ^5 %,w8Spwƚ ᗓBlIp|MFEÐ7 8{D*l9DH"6dɋV:?>hA"6pB+}#qeϮ>ABǥxVHBs fiYz'S?~V0WRYC0@8a߀͏'y>"ha(Nj-X5MzߴBSCN^ >/FET:yѤW{W(khҫëP}^4UhIBET(yѤW{W7IBETyѤW{W1u2M^ ^*r+Mz5 @mc&;  PE^ ^pIBET1yѤW{Wbw_4Uh>i!Y;辀MN<3l( endstream endobj 55 0 obj 3298 endobj 57 0 obj <> stream x\K, ޟ_ SʆL" Yro @&?l.$ӏ*-ҧOr7vc榭ġoFo?_p?~<~}3êM{O s{ ~Ļx+B<bap#~& 80?,|G 3uSq~ן~JjCRaUI~/?~g 2x#My~=?D}[Ax \eyջI B 2ͨyoGzL^syrdç\xAC/7.?Ww{?i\W{2VU~+aam2n_DIke ^_x-WHG+K;05uO 70W$&}9H7YOɄM_Bg%LoLQ1k`~qJO$Lo^ZessfQd7p M׋L sHʹ3bE; {ؾ^r?ArіavcUăJEZBPx䕘jzQ7Wj'ީ7y-#*"$.$w0ڛ% ar0n>ɢT=%0Е{=qepV v98/z+\Z#&VÕsvj2$i ˮȃʥzzTs( lQy5ZdȻ>f͋yUDDH`(|%- h#HH" L:ap3T*yf;+K\1Rк+kU^Tv)8 Lff# #/=$荼8\ad.ni|D3N1d훡SNN^gį %U,K^Yi@,{İ62yXU=X{,-zB |LML['~&H`'@VzP[֨s?/ !>1KtH#Sp0͎ XgB(x+̦! .gΚ0r'(RiV)A \ڂn?KVz2)G[j>s B=W _,Ê@&!!uϋXKL(h}Pxp"ȔHҢ3~x5,}2!g1 w4LA(*k& Mq{EW؝s.1a紉V"uģ"1쫘nXT=@sK@h7/S`ஶHsz<'ImvT1Ku7= X+CV,!c4zo]1C0쮈ϳRAYUX6x*d lFݲtg0QGLŭꜲG MllPڲoB?bUou7 7b?qǏamԅDXትQGE{1 `ܪ`kP*Pph7jTyXuQaϢ$@PuTk^g|Vp+Inw(&$\8&qB ADxu&Ҕ=)'븧ԊYn蒱tTGI:}ʀABӷt<% f&'$)E)vzg+w|d^_5}O!&)vS,ⷖm0=ԲVP fuwlfJHL}X4N%mKO}QWk/3JtI|idRޣ.K.c%C}%p cbjxib֨gjBRƻ.NqF Czɹ$Ɔ[U"eA8B mJR?>Cia$1x YY 7tf4Jrpa <&5NeS@gl}]H#>͚V U/gS'TLZ4GA:ax2[6 UOGLIMj57sp(A;t۞H{ZkPQo^KTü~#j`Ҥ<Q^ OVГ{niܓ~» D n#)2Z6"!T\9_,Ch'|$׈:6#(ЉoJ^.,|Ҁ#gFGk)ػڅ8; 1Ӳe4INZ7H?q2s_Zgܜ `'G)!C+At> QnP`?'YmMx}yvM.*r8 ΂SD]HdE]mmmac5UϮBT%DjJ.fgSG pBﳝ,5ZZ\ںԞz$O1ȺعeOEQ|6iĪ|o!}:zx\̹Zs L׈,qfݴfac)`]j>oPRɬS wTPš5_+LUUAp3&Ʉ99TL B@M>kdq6Tg)FZ5#zz͐SxPF8- d~i(Ϧ'eAlV`_d Wy~)1O& (ZMFKL7CbZ Ygٜ)#i/~^R]w|ӎRLvu U;Cw65:S::JRah\skPE& DQĘ50,b+.࣠'gO |P;Lu(ԦJ&G0B j&9}CNsYw}Sw%Jh)*B$ig7wø_ݰydHs83SLf`, endstream endobj 58 0 obj 3878 endobj 60 0 obj <> stream xI3~R1xym9ܒ q s*-ZRgxVTj~I$;LҚ0No?! '{֋9A?VN {*0+W/K;85ГENN0F_<6ˤG ?GǠ'1Fk j0 ^?FcX:;-Ր{F3ddoq''4ӟY< n0 % ܴnZ/_?%̺Ƨ!SO{sQgEY˧> q}:=i8@/&~` ?."̫rEd%gD:| ~zʭ?˧K0[ y`+O<'.# 4-˯U d C$_Q3B'AO+Sgf"hSKtaRzP`P*0KoQ5HD!V E&Ew Ri&jVdjv*f2~P@s5_˒=ph_vs JDW} Ѱgc,uXj fQ~- $Y/^>>AsP.d]kvq*;L)LJ5-X=NW&Ƀh+\;5Ԏ2*Oă!d”JR}zّO8m6%_A5 A_K$>=R Ɩ˥J]ws߽9êPbmtve9fUDW)8/ B& o0a$X8џ\Ƒ0 cvhO4j qԼ!e\p%Y,\qJ I[ځ*19 }R[WWmUAjzH J=/qY uG%byJDt'YM?bݐ: j6*wkZW 9i7!q*Ak\y/eâϫZ@laĕ'_.pL5@<9\ZqW/v H oE:v(~Y/=ι^t#޶W.pM'(Ľo|o10qᾸjjQm뚃r!J`]xWlsJ'mzN٠o k#Lu1eUQآ$⽴X:WJ-%Aۑ6!QLUo9 ShVmlb'$S@~zG9G 6E R{Kظ1+4 I̓yt[ԏ^!g9Ì,wa)%0]O T㠥jFo6U:XtHR1=cX䫒1j܆viD喳c}^5N$&LHRilB y~Jn0΂ď-V @pr/<"fbT3S jPnk< ڄvOĮVVrշM| e\NZ ЌĶ[XIRBj^aF*ĚlnXb'SmU^5HCͥXJ~Og S]H*>ǨSoH )i3V'/pk~k$sxeQIܖq퍡tU$ws9Sdb0aYwe"Z=\1}9C'.r%H%겤d85LЛ: F+ aRtܥ8ޭyO:Ig偓tEUn>5d;7;Nt*ӨBXa>l։<=>ˣl]Ց(Q\o/Q+P@S4+.:;5G/&vt+w6j7^2:EFk]&X0 Y뾇9:~uUt_(ͬ;8d)}-`9I fg/\o! HH@:$i/6BUh?-bc }ѿ%KW8%)C`Gzw a(&v"w[?$,"Nӿ~CWzg-s#jXzR)Bs`$Y=:JMdvBu6nsM@;Sg5tռU:^wvCYA^ ,J6NZm y>@2i |20\.W7VZ% 9T~/1:,e>Pz\Xg_$7)R| gicsh utc9 Y^Xvǝdwvi~:Z$۸䦃(LEW7>s\Yȿ1ه8EyHQ*CyV'{wxtlWyИ!ڿ̡㭺Xy۳؎!ӊ^Z*cZqҫC+C!}gvL+NzUwhe0iYEKC\\F{'eH6U("=\D| '`+ endstream endobj 61 0 obj 3433 endobj 63 0 obj <> stream x\Kϯyq%anrdܒ DK~Eaff*~dY/9:+3&yNӨt?Narvx6O|g=g[<LxL!fQÿ 5[۲:oLV-sԴ:7-sahZ|wMsδYݴ:gTVgв:;M/deuֽL-`޲P98 ҟ'b6)EiC/F7p18g8iuˇ]ۗ[;(Btdi`ޟBZ"p *A= dvǠuO66v9 e $}w@kW7=Oe^ޏfVcE=9TXp }/_A"W 'UL)?@UoBݤb\:W=kv,Dr/!{a4?U@ vcx ʻ7 HS\B D]/;P((3ء{wuUO}գ6 FOרoAKOQu)oT:Bխr Ii}  };k*(=LBXeq]mJf1 }4n-6^5LʺaUKH $Wx O1Hy@1P"s(# QL,i *AJL:5KU(F+s}~s - 2JQA18`!/u{NEA!AC6@(K& &+7WP83w:@ӯ$4Sa:sѴR-aQ)zmՁ)(_5?uSUc<׭2\wF ouƻ@z| nX jqPE &*:G9ԲXC)Ҥ^ 3 TKxiYQ~Sv;ni5L>% ̮}ZBR6CүC :,<=zT V0XEQ(bªP.=cEt:Q! $\ UÁoxw٪%R]nݝ˃QO5G|s |@ߨ|lF]9TKXSɯ >7; Pc=r%N{N7_Pmt4IPik=l{*G@ FWR҆Q5; ekMg7ʞU:G 졮L|@\u-ԁG+=ZB$v*x0d~ J=8Wnhupƿ` s$:4b6Pъ-+m^]^f,04(pWOS]/X%\8[y$#"/z挍#P&ו'Uמd驏!e"*%໨2ZI[)gL|Dm"ӧ"|;`Ѽr¶њzQHu<5%#v %joߎ;.A㑜s>|mK[M`zJ6LpzoE^Ͱ]˘mxxPxWCߎ~)RSVEPS*6'c'0[ *))Rgh@zY8u Ƚ9_(x7^DJMo-OJX9E2_t?W|*\ %xF5^?T{츊~BPPX ȁ NMtITb`]p P%ѻDO=CU-b`޸ݚ+k-+W G&Dǭp ,y {REJز f.l'o$gh~j_޳AFs7Wl @:bGK; Y/_I3uWXMŷt(3RrpL&ѯ,| `p^P )x0#(Ɣl |5Cc,k'p2VbhAAehJFroX?.>hPBd(pm/ PZ[h;q#4ٵɾ֮EKZ4 cS$,mMlaSβ|Hp0Ơ}K`VnnJ錪ؑ=?t'efi $nx2 P{eќƓlĵ p2ȵ0,Ya>/_|(w_k.46˹l f\V֟*< =.X/_ibqB5 <C)~!ry`,nQɔi VdI9"MBq: A.oN6M4e*yV+F&-GuK7@Uuw:1Z ?&Z?hb%7ll 4rꅁK9;3d~˧)=Z}n:-=2D2SxIR+Z;O@ndO!Zt@SL_65]6hD{D7Jn$Ln)u[~t+Y64{"Ԉ`&afevxAY@T躐"6v9[DXrK sKQ״ҨonrAa#"l ef[˄QzDYwF[K(/ʶj\# dCZٌ^ R*II1f4Q.ETbv2 jStiq,eOyP"n^أg Ee]˹" ,\XŢp]ڈ]޼{vTɢDBRE,E@U$̂}I*OP-ES+ڐZLӭ5α eϲ@rJV}Vػז1fxI# ~Qé v IәiaaalTJ?_u4VX8Й-ϵIT~EQ^\ CBRJ~Ě vzkrln(r_*6?k,=)}6RW1!+~\bJ,P3A_{jo=O/m5{uttJjmU!8K+㒁?J\2 J\20p+%Dsd@%DsdXB4W;XK oXB4W;XK4r%Dsd@%Dsxޤ4w$+6V%%m,!+%%Dsd@%Dsdu6Vƈ6VחXB4W;XK>XB4W;XK_!mc \a`%.obEnce\2_K {+qɀ|CjK {+qɀH4W;XKm,!+%hw gcXB4W;XKگ7"\a`%.plbEnce\20F$+%6V⒁hw GXB4W;XKٯ7"\a`%.$hw _oDJ\2  ic \a`%.OChX %6V⒁H4W;XKRvK {+qɀF$+%r繍%DsdLF$+%;lB5^`Sn endstream endobj 64 0 obj 4480 endobj 66 0 obj <> stream x[M ﯘsuE}`N.C[AU%%;Mx)E%bOo9Of2t4jF oN~4 5盱;91 4ҜAv2۵E; hVv솩 R7zv)miUk!'1m(+i4Z6YR\kWjԶtxR4,شaq5MVZW f[z yywgi/ "E#9qeq"jxxhX6_dz-5=1hywY]⌫q<\02dlP1]Ml1y\4Yiҗ"xiYJ1fôc vbP -@fi6h`.6N>(a@Qx>h5DAtN8pB7LgR4wO\+)vZHŦ`lvn4b``ɾA1f7];bpY;k=^C)&BfL/hlŵnttٱ"zZCbp.z]m9.8`:)p(~9sY;CE69ON |j 4G3b!˺u0P,yfFy 4Xchnʺl[}atqXP|Q4qɌaa0~?\4ЄdHRAdŻPDZT_rhS[s"* 5S}l׮jpGףHŹ{'滞*F`n_B>?j~YdȜ>9;L{OQ (8Pg tqyR$ήARzAT b΅Ѡ%!6^aga;0-~Wv, %ښ0aem{r9wր^*6mDXk3IEmp}h/ogR~)M}E˝_cGuuø_<:H p2Sۤ ?M.TJ>Wá^J}{:fA3&ZL|RW -ƥ;c._p%B&C7N}.{mײWd`bJ tQ|RL63 Vm,fv+K1ߒoc1;XY ~1;XY*>Q+2 @|ZH1OX+Vb^L`e)&`|RL୫63 'jm,fv+K1X+Vb)b&_aw`+Vbb&_awT"~>LLa2kXWmT"@?&&_ȧ\L`e)&x"b&_aw63 @nW,vhc1;XY +VbW,{Ẋ &Vbvk!ecA{ X[|RLp;XY U^|RL0_&&_awDL`e)&(χW,>kc1;XY*_&&_aWm,fv+K%abv |lb%&_aRLp;+aj˖|O M_+Vb1b&_awW,L`e)&1^+VbcW, /7Wm,> stream x\n )z. rr)ݴ)0 t6d*hRh&QIQ"so/a W;Kp\~?\`K4n!L2/݆ (|z9\]xu饧l\C{{ ;{;i>i'<-s7 zN:BOcO{ _nx'ufu!nͼR.E3i4|=z 3&/x|=zinضl/܊ g}fG+̸~!~HN4Xɱce(C?h7[in2[z`%v}h7A?Ђ"Y03&|,ZNNq[0.aƭ6J3nAܱ `Ta {ָ<WL̜d޲D{p\.ouyżk=6]/NX05W/;r&?vi{D{yrp0&&}'ʿ3Tg "S0GݘGT/`u4(uhgyW 3L+@7IKfY{icRVϬAk橀F&Even>bV:mr((STR!_ zx&1^Ql2>w_n7*-''&.Ndt3LaW ' t8 9ѯ s{p0 6p2鼌{eHȻ.. ̀-+EU)}|GGLU)+EL{G߄/]D\?9Z[qS~Q21%`5P~gQWeJ [HUaeJ [2}<̝j2%a>*7a2%`5)"_͒)1lI:~2%`5)"@>_VK=/Wİ&K"Đe&rاn{q<~xE (ֽwSOB_U޻cV8-K]ՍpY endstream endobj 70 0 obj 3346 endobj 72 0 obj <> stream x[Mϯyq(>!,#mrrK6j{e~ (Em TQ_ k0b /q igRC/ΌeB ƯDn8 gt|d$BONx_>bEc\@RU:Bkk j35Ikvnv; JovEOC)%f+J,gH>;v4IpnRIJsXO_v1҉k_KͮXr!:.0. LI~;sq^\31Mh/;ԞqA^wx3qrGF&>,]9uPorsS sMU x/"2G$[Ut:w82a#'1V#hJd}56jK䲈.!ˍlL.@ޙj!LIOaޞW;3I cRЉrLSi)\N Ua`+a ӦE6Y2\G/p~öz6tĤݑcUȭ'*O#{M+et([Aؑo#*-X./ZǠyZgВP{#MBCa;IBT*}!N N[d!prNi_Q-YC][ul+M2aa\\n7)7Ȧ@YjpijǘƢen~~eZB\dډ&@8^ϲ8Ȱw$4D"$tYb yӐ@²϶Arn|l'ŸP]klvNM"5wCⱠRśGL6h :EIs 'BLS zuYi%XdeFw&eޅ^ :&Tl}gɮα" Kg̖w2̛!LdrDircvAe!MLm2߹kެe6sv oFxּO ˰$X|ν\?ȯڕ'a OllfXQJXx~}>SJ7'H[_qtG}O0;g>{‹.j++T:WwBLkĵPS)>ުTEFh< h,x-.C i.koF (xXV593B}یBT?zIR 3jl%,7t)>F>ޕy={צƹJΏ5u{z+ UmEu iW{{n&Kpֿz{nR_c5xZfNhfj4p"Dz"~V#qaעٳn% אsOh,1g`>fk vzMlXxqroJ^;ҦFQ1ӢN4u6-*hJ`z ƜZU'q8^\6 a6-68V*hBezvݦE"-VE ڴӫ}@+p]U>FQ6-*hJх9\uzhQ!djA0t}^6%"mMB')tQWNM' o(VS_4z( endstream endobj 73 0 obj 3171 endobj 75 0 obj <> stream x[ˎWh=@+C0`f7J2Qf~?UdQ6Iwn4nLxSEYW0IMjV';yw0?0EͫWz꿿źy̎>h'$y8N-4C)Yi,ucٷ,[m h,  :D6u@Xe'ʛ5ā.Wқ-uHż V= )hx^ՋiQgkj[Ll@ (Nv- LrHΎ'"[5XA8ɑʩVT7r4Oy> UQϻEVڸQ˭نle&̹t\wWCPq#ԕ|:^@.~>!Nd5#:Ez+e<lwCe zk/e<ַ4FGLDI9;퇏w!Ҷ}"2figbg8 X05xm }Hu`Mlo29h鴈-kBA ZnGh-W:ޠ}"z; Pl8sc_{\yx"²jA%rVD=~$+ 6¹Cc1͝Y),xݴAz{b'c4u8?n,XT꼸&vBeuYC`n,'=':c|y fdžs}XI a2PH`~ ocs75˷JY/_"r >xAΧz=7 EjF +o+ϥpiҚTe2Bڒ$t⓹~"Bzx\l{otSUT&]>dYO;%(Y[UXݟ^J \Dah a)%"],C6pTm 2ZT~?cW̡]%.r!*Y<`"&ESrD~rk͎p!fXE6P9ͺ.݃!,d3'H\T+@Zb-y=^#4Rܹn:G?IXn%}mvnr[GDܘBزRS-Xű.,I@[h–=/j(W?(.bCBĨt jK{ޠTNw'jF\,ރ],#6X9|@up:u ?qs[IbprNJG'y~`Y Ԑ\>QCȣu S_WE?2:Z a$)++%qZA;M=WT;d=↞/:s/0r.k>C.aEy8т\xdl[j\Gw>/k2Q>A} cPpsX_`^ܷ+Ii~`㥻*d>R-`/EaU2N#GI[2ƒI;R2 X2i;XYJ6L*V~[kL*Vy% d@>GI[Rq J UHɀ>GI[R2 ogdVaw صQiVaw !ڎ 96DV!#,{\xZ_B2i;=545 endstream endobj 76 0 obj 2851 endobj 78 0 obj <> stream x[] ?" 'd;q`3^,j)toW8v2SJiΙq$?$WNuW:;G9/'ԕ'LGہ%ӽ^=^gGq>lL=XN=ơ5v5֏퐳kPݻY#gԏv7ٍ{Ucm9}x0svC][6U0lV]y>Lšݠf-.Q=.MlxM(SO:! |Bܿ1!n͋T] ឿwC/8~0ܵRP}q ̃^뷟?}P;geux:7XH {ӖƝ%/1 S]) F2 $9n%Ϟ7mԃlzN@  s(_zɚ,wh;hI_=I>srp6{D:B+ANsɵxˍz $lr'vԛGO-WʕdSޑ$<'XoztcQX1q78&+ˏ|\E}]/j~i ^^黾~bQ S(c F$?NT4,o(]Þ{6/DxBqxF!@Wٔq^lP$?s ^O^|/( ڤH6*gCRc?~~Ϭtn YMҿhp,M k-_̰n4!Ac4bk8RȱF&[X?*$ޣštXN2}2Oe5KB5K;]<&7 |\tٿq]KB؏:3iQ858{8Vq $QGoC^xbov3$^P$ۣ!W+f!= ~p>Wf ]]HPGSyyNy 9Vw<+U+y%]zk1op`P@ HTP..\a$ ?N'iř0+/L*yO/@:;bxYRt/E+!f[E ư6 %*3\.O3ݯ"~Oq3|[h+Xna/Tx"ibǶGֺ^m0Z5eJ\2`+qɀvXB4XKPH4XK&[>J\a :[rU0)WCON endstream endobj 79 0 obj 2902 endobj 81 0 obj <> stream x\IoW<@+\E h4rm99%8@2?E"J=ņ{Ue6鷷Nlb3vҫѓU| ~_~2Nzl&lZ,$Yj<WF6vϊuf^/nKKo S_j۞r t>]c;YŮ??<_ĕd_㦮.*bLU,7sevQu󽅅^u]k7p_Pk_vcME87} -wHV\ٓqrqc.tu 47r{ h??,gŞVy}R RO>>~qX5B8_T`no(ssad^4< {FGG,LIl;'J@%,BW&ˊ&X| NV̉(i4db54!- %q.|/PFM,PE;+'QݵDC;/lډӾGouV $O0#ue-t4=g݊C4dq#s: |橵:ރD2>_ΥO76]O_b9ܬiY۷^OgIdQ3~WQp,(dxκa#@85A'iFm>;;@VbbxndSwT]fIbõ<~R7z)B% 1dLB {lk _l1XT(ElYx4oS)y 2$2y2$y`ЖA~/,[ b Mʣ$]D/N  6Bgi5n:͂`#q*.p 5RyV;@c+֎u~<ΪL{ ^>7jURjF=h6mI4Ҟy@j qjՆGIfj'bҞ Fv,.:-[ !^:s@rֺgz>A `օs0c@Q3-@!vHW{X,n0mݻ&UrUL@w`p)@b<޻{p;[oxW ˮ Լ_>u@@f#RJJ-CQg *GG=+qQ+=#Njp%2ԓ]裠O)̱yF`{疁w.7h1qפ n\0=cB>$ҏ fߙak#5i;.b"&[U)+3/5(+Y[XTFQ'B 2 x(In`u(2\^|Qt{|u ~U7¾A!4bw.}q{yBb_`dXz~9"_sWSntp}ހL&*~HDLx$w 70",NB{0gW&_30BE2@;2Vַ ւBm:DrOc{t)C[>x@D WB5qΛ\-7 Rq})7ˬr p %Ok`wN$!g *, ~ xCc"E1`̤ i-~TbTُqѧ_+2yR ͓hsw3%C%og~R@?u(Ƚ9 FPotNz  `M`&E6H)Xay 3IssudiH>*4iR(ebyYHI"r˄ d"\ 2<5sP_.V f815 J=Y= 2BJG~1^JL$1^ִ <^K ?Ѧ$DPW-M窊LwzbkJ))ۖEǝ|A0EX,[+0C>;f'RJ҉蠆;vb,z"9DPTZ}'Z+JB?Êg0 }#IdQ&{ %{rTJRT"efGZFrJQ~ '  ڔdDεV)W# YKtE,&t@yQ[a:yFr/^qK ,! NĤ^ML#bZr73׆>^QFiR2ޡ9ijB4&b4RT# R$G, '-NcHKt3s2QpjL!Wv_zE`x*7Gb݋g9NRµ"D5&='tN72F?YA^^5ݘ(ex8 qj<kLM9TK䩬P9R&(t+\؎i%]vK랮A&vI'W򈜰Ir݈)a+DZ%\v½qxrFcxJv+=qzxf k ɦQgE 1YB!(HGuPZBv|sPlrSwx=xC#|GBli|ZN.a6|}4ׇ M)mSGNzTwHdN3g 3iNV|?L}ч3:#?BKx ߬כx!&U'nnW:AOziR+ VtWxϕQʽ…p`s}Us̕{ x諚` /,1[}bOZs endstream endobj 82 0 obj 3565 endobj 84 0 obj <> stream xXK#5Wy4򳥨Lm!'`He>*/a5B#$>/?;թ^a`{ w'md:Ё%l yf- x{§yÌޯΫ^F׾W-86D7cniЀkqMN]55!7^\Sî Wwy^5.WjXЧe:Rk5|^Ͱ ̴`W{h!*t6p ''mj'غۍ̕nNi ]Pbatu=>~0OdzϧQ_G#\9F#y0D)0x}ayYEƳl@=I0\j`k1C> vh/3&3 , D {odhn"+`8?:QSە/w?]0L1[w.>̘L-H$4dV,STPqJB4TP[eF>7G{MWE2஦ğgOؖ-iْHy97\.#y=TsYMRt8fOJR&KwfEވq.RLK9T,^G$ BLI;6oPdQz̢\Zb*"UB|"kB_y7.uUz1Hn"Bd_۬98ǤnS!y0/ĸsA-yEt= T44$;GZGqLeqW)F̨:}:2%ܤW3Mi{gڙ]NdwFm/njRԷ疵tXY(*wVh endstream endobj 85 0 obj 1279 endobj 87 0 obj <> stream xX˪7WhmE`hw&,LVM7=܇ C2]utTUj}\HL0\:ü-waFnqgB|88N{yzڻxl{{\{+Cx,f^ANPc\l񐛊(Ruf'ôs6uNiI8CyQXOyND$qBR{_^7اDdN 6!5y%zc"U1m97+\/C]1q8(* fyVNsy%a99|JaFG$"@c?r ^b*#^zK/vI/Wӡ5UsrT_DL"J^ Zҵ[UJmPAklt=UQ-o4PF5ă4Rیc'!u-˦o)g~ΆEI-G̩;Sk~y ]qPK^Pr׷KXh,klc͟}h^S^.P5ʮNjX _T*ҎE,Y/1j_y'M!  T p=꜊M w?ԺI$ u|\w((DEȱue Y"?Ovt0x?2'-FY-dEhՙ)c}=^_bZmҠly Wm`CAm\Kx)yx/C)x$;?UHG{G:mB{j#ͥ wUͧbJ| x)?o7+Epghpڮ-A[i_b5cqB П*R}0qSSջD.B,2TvAϕ_ꭱF9I+>WRh endstream endobj 88 0 obj 1332 endobj 90 0 obj <> stream xZK6W*Q@oim M撿 2EK6 yZCw': 9vf25?:~2r`Uo;G5u $>`73;ssV&X©V¡ VBkfzhmxUP7F V± V¦'56=1MO haD *,C$.F8uϿv\T{~ӃQ>Ճ8Q= ~oNr'yTʜm6Pi|4B0*{4zBi?]%w~A4/J.dǏ4 ꫵUQ6H0Xl44E7H& 'M #LÄYw;u~>|k!^\1L DviSQg;}Uu|yܢ`\+Ӂ#uW4mn&?}*MNu_ޝv2A1^{فS|FzCصi~IYMY&iClڏԡ_3F땜#(MH? d[d?,S \T"ٮm 90FюnSc ݔ)LS"帥3uuթѰ}N0wvPZ:)Jx$,Ҽ͍$x}:r:k65#ܤ2*Xf*ŬLAahr#1ж3T[Fզ]͙HqRc܀|;g?Do~"sOBǦ@DE= CT ]jN?>S0W #%o2Ym0)h%shgmqϞuŧ-&w nW݇N@Ag-AMǪIq<:yt˿0Iw )_$Ufqk7k9iN3FxV*q&A@H~B'mV˒|1]c)|8YRT.Yp19m9{-S DmrZiʜ,SFENۥdWXxЧ!Nk+qUI"WY{㥵аD:`hVp ne0.6Sv8!)P).@2_iG pK\4W.\2Hm:.|; r7r?w5/5DK:\\M&X!{ApG+tn,YOX@ɛe:Q[5Dx#ФI3lzkwں|HUSIc`K=lG9Rvӟ:t@ v+3ߝrʦ)kz[.?6 s7XN9K4^Y?bk&>vf$tc^ǃ3Ax +[]gZ: e2ՏkU._liI=c4, O&|X˜ҫ?1S;' zˉx3Wn]E}Ar'֚Rty)OE4k̳u:}}_M[1Ć[`avL0YfzDŽ,w7X`|\paOm&Q/VTk,*w(_DUvV<;W~2Ϯ"cmTCN?tw喽:B endstream endobj 91 0 obj 1852 endobj 93 0 obj <> stream x[K+zJm!U L s_~|N&.߭^qca~HZ4-%~iqbWRm3YT/B^UzEOxO.gwlb5w]?VZ[ᢼu\ D\.& xPu9xo&lTT,SXDee\̑NY?so3*:J* j¢} IhRDB\"OAefȣ%OP=H0mο[_qq$~ ş9T7&qN|RLjEJ~g~G At7Bp"&U2fuq̙&/jFDM/ *}=yߌgYa睉Ff[=m#%cpQ]gq.<(Q ŏEtsU;W+EYgX*7φCWݹ wʘuͱ0: doUyxLbQ!rǎܢ"-@¼#1PR F_b dQ+"7Gu&: $ [zΟY6! @-w ";@ =;7NztKPR lLU75)j2 }kuf_CfܮCȁ(.*T{(kB t̓f<tQ/j{d?E}j<2g6` lwp憱$wzmmP+HpՑǰ-N"K*F Lf\ ÷>x̕#y)p|-(dYf丕F2Avecw C s徠| ŸE/`GNF{q})T;5x3Z bdzw('bWfx.wP"\a[m 2w!Ӂa8Y\@<,Jga\@(T@$U gj̪躡SQJWcKڟW*ڹRE9Yل׺pm*sNU٢)Q//WF/`P$z/7XQ6 BG 7{Ȝ",tVBjuMs''yRZk.ԩFdYAL2K{8]*p=cUBdyLIۡv)02Α)@!/'W */$34XVϬbѰ#C*7 +$ENEkBfݔ\|`JСt)G[IST^͔cmY aڥ̫QT) k!hkqjU[Ps+0"lxw)Qj*t`c401ܷwZrtG>,jU+e`A`@.$fo7ZZEgO͘p/J Ur7}MOL0LZ4-z7=1~'a9$h3-psHAΔW1b ROh;~:Ul㾯r"#13x`|Z}pw~φ5?YQ7JeT 5OuM㨩B˵5]U ;utƧ/toIlB`9 \2{R6NpZ3- |&aFx𩪿IĄj81&<Vt&T2+>j>Rh9V@3Fi>^"r"({p)_=ar\LW7 }/⪑Ԗb@2-Q@*NF"V3\xOᚾx?䄔[kg_yjƤ[Q  bh병&%T}̣ΨvxVGEg!FKMD$E[02%N6k;Z;@rXRi7X~#mfJ20U ([p{W.#CH*C[G/= d&ck87B+TbO@'C-Tn0@_um*n ΧPFCաz5ן-X=8y(Ve+rIIjZzbAR(]Fiulr#IJP O&_.DhB 6)J ҋ-/L7dت?IC\ἅvQ3^@lزJyDی+%z~&?L S)ug^(Ͼ{bWt6Y`%}#ԣlq6CJ F?ddSkitdRJk;Mӟ*@hTJ-w024.c@wҠUR Ѽpkp^*κuJw(3L,jK9s!CPV!r /md(2zaY3֬G E&#"50V;Fəw56P:Fʋ\Si|e˳*b2-Dۄ*J[l62p̽߸Wv?el7 N*>znzlZ9U>_kzӠ qm7 ̨Ŗ7t5IO endstream endobj 94 0 obj 3317 endobj 96 0 obj <> stream x[[~_ teh Ӂm2%O@/#t)I%}gf-٪W_],&IH{1b.Vdg_MLj?Ǜ岬o#&e.&cz_~X!ٮ/x.ojx3X?>޾O I&79MoUfnbݮp] ^O?UխMBLWb[>íDu_i/Kg/5p{_.S^0}?tGۮ/ןP/<ϓ ^j)xYM !Z*ħ@Š']PX,-QhbK),kO= / (٬MG; AQn$hpc*3ov:V€Lȡ^W.m|<p\{FO*+Yf֏/7*e6H#Zq `O2<%ƞCMG#Mεd LqU&.#CCFn dJ=A rA{:8F:ƀOKn#c҉ͯdMrG.CCRD]O%P+GCReĶn[Ȏ\ *T}R\z-eRT%&Ӡ; x`9C#P@ %w{W1AoJuE+(2"Pz$bE&HPlTMu⯶wYT--|>&<{G1Nskt-\S dvV]f_=TKPJ̭α*q1ty^kw+F;g4c  Lb0{yTkh>7 ;^>ҖJ_*w"iy[Ƥ]B,$5`Nma>]| "ȩjuj:,Jk*Js.͉Cdu-C(N,EFJ))4"dh0׊+ R7)F=* ܺHMWΖrsL>9af/l!A˰&'W jlk }bYIх'bT~9su&9"ߴθPBN&BEk^x(0SF<-Κ 'Z)7.J\a{He^8e5 yϸ2jh0:mHVDH5 "qqAPU 5vȯjJ-e UN35kC~¨5jh"Q H)KR:W5yT(u ֓q|X~\ ¢&=:}|E2TN?P LNL0tG_s"ٟbHOP.p`Ն|JR·4t{rr?FV*oO`_s1%Ckp)Ll#5Bkq5> ,fn6ŋ[|?M\L/D<%Ārr}{0 So:٘a.|&-ѶGX ^iX'$Yě0VAg~JS8QRz`$wJ1WyEI%Jru ~>8K\im&|Բpc5ԶKE J{IIFj/2fTץc/ WшGJIT E%%mJccPB i/p^] aJڃUW4fCF=BdJMet?F-}4jMTJkS‡*;>ŸlVzai&d5pٓmu|4dpccCu,p nvxA]x b *㸡W4.T. 5>ﴜ}Z_k+M.Yef;;Ƅfeڤs{&G Qt08zZܗ}* iY|v;g5"nI^xzrpRB @KWN WjxNN7VT"jUx7`!S giվdƶJ9GS+I ߖ/ؾ=QYmvo=p[`=:L9 YѸ/g%|ψ-~? F5DMuEg {'ia:`}P[M(wo@]SKI:Zϝ<7q"w G[ 2vՔl1k)Ϲ dLGF bQF )Kluh/GoGA&|=,(_^C%0MYЪMPL>< endstream endobj 97 0 obj 3252 endobj 99 0 obj <> stream x[ˎ Wx=@9  nJ23P.]^!yHb_1QH;Ōr60 qB-CiFz4l;*aFT'˰+8K3avqOj|y7!D|0&k kKN^E#rԏ KH"{0 <j}:UN!0FCB(桊U/;FH΃f2gљP\}-bNZⵈ9i3&bN,s x!'~rp4#&#nL hI|QA1Op 4|i/D^㕻$[+~@]ƕa>,Bݯ.=?.B>߿\~p _WL}1, ty/nw63D=j& hz2UPlխWb+֩7 =+TLU-{æ'e#>*j$!=DGPuIX V2-%Fo+SU|$wtՈ,'zb҉PvۅM<}f?zTa25 XvYBzg.EM{LjjmKȻiL.mv0U.C᱔}痔nuj*uu{z)OIY$vg<[QɣNҰ|Cw, f6&zLQ8V/=*>2~̳N-ֶj?zP)VFc3?wIr2A:NboHY=g͇xc:IU9ne^Ǝ l'h2,wo(ωR|Q]S玶\%pG>/(NLVRw\wa/DGc;) qW/z\Kt0$q9cnӹ7눵.1b%9UK[*5&8yY"h*Kܞk^:cU| MK= *;pwePtMPT.qwY19eg^RghBE;brߌw6]XPw IVJ镡׊yijraz՞ۤbwwݝK/43ِ3CUS3dU{d& Pv֌ wJ5_heư](X5B(י7sz ga뾸͐_[o8 m#I1ތ^&H$U#eз8GjrL.<.c#Ft@ᙯrqry7 }oNhQ0M endstream endobj 100 0 obj 3044 endobj 102 0 obj <> stream xMku_@\}2 q[ݴj;)t6{s$ɒR%%1LbPnj'g90I̛z߿.:Y >NVeJΪ|^<&7zPͿ&'ļmw=I5}anE۳~MHy:R䋶Re&e\7-JK/\|WB{8#\(3|xe l`W(OX+L@|QH]~PC~mtZ w~4. H8?l PL鴇;JC OǧoO?Jļz1ҳ)ҳ/´:3(L+ `@U(׷_R,($P03Q"oYP$@- T3QtҪ$RDLr;N g Ā% 4=V"S4.Q .\m0Ix`xT#MW4L樭-i$Sm~dԒlo]SwVK!sInN@tWG.&|xE\r6LXkYez=KO@>QyRm hǛ&0x{4oZ₇$_!hR/RI)nCk;%^oCJLCw}j_F/cK͍i60f2Q#xbx1>g[JZ "Y l ?d&Ā 33/;Fu );"JZe6ܕ8qLÙщ DGES!ƐlJ.҃ŹF̷[ٖI|Yua\m ewa77oD`%ǻOУ@g4SW.C!lIcCUo3 ^Eɡ +C.RF,}FaeL^hX""t՗ bY%$5,J,HpP]nFjN|p>x~aCISl-. 72+̿}h 9IaQÿ?w $Jh TݳTd3] 0K9Aلз6@Iq#̇8Űdi%soL#K$Gn؝6rh9dL#AWA,J#"9'?n1hTd̤芅W8CΝmK11p( NXGx;نHrK!&"l TaTV;0z[(2QXds-=`;'ZX-"wĻ\]@[hUXPUXpB\TSZnrWB#>QmX:_ɹ\# #I[j, ?A swĔ{K*q+MlX 0#؜w|2ԾM:{7B^ MjHTzY,U3-R"kO/Ci@7,5R_ZQ }μjwhpPJAѐƋJ6F@X8I^;p-ډ$vu~)SewkX6c.0FLReHiNLQGcBOj6(J.?t6M7U Vbɺ|r,eܘk0*bNy˜kˢF2A_3K7`o,ײyeқG1\ rΛh Ĝ\.p+ڕeo8F#"`vMw'cjxvoq67\U3,lɑlgX2 :@9dQУ:'Undi?#+Κ<0)jHN:^,rGN dxr'SYŪlek伏4ڭXVe; UE-jx⣳Ȓ|uby1gK@ݐ>IDŁ=K2N4'O zCBͪ|WO 9u靆@>b)Y"=[Ԭ$8ۖx8#"CB!2.(xVQ2~P{i.c6 lBEQ:4xP:?Б5ʽYQFLї?BɉI3:q,P6=R, b}޹8!v+":~;EZvͲ\8wJ@2w}:՜K*\Yv{U-qL*acEyx/ʩ(%kC?dزc :rferF j{! YT(~),:^O1VNxjE} Vx,e\ 1\ ,ؖ3=k'P y^ {g=G6: @"*~WREO1_[Haվ2duoZMf[y~uB|5,l]hj1E= qYVWއOY[ W>#_@dFʍE-Ǘ7-[^|3~]Nʫ Ϣ>Oʫ膒AogK'gUtZgK'gUx#gG#kj~ W_ endstream endobj 103 0 obj 3437 endobj 105 0 obj <> stream x\I, ϯ賁h) 君r0r ڹRUs`x_uJ)GjԤ/.jRfMfumӶ￾zq˴]6e/_^|˫7u~U,yU͔&p]7<~l&~LWW2=^-(^-Jo]43~pyzq(f/-*}oWyϾ׉gMӸgSqqϼ2Aϴ(qm@-Ȁa4.283O_>^~ndZ-Yˌo ; M7.$}u|k28XtߧiirxZ8;^\hR&kwjZ~hqiAF!ƫQ536җuoiL~mwUSҷA0sr{E^rnħu|"ίѴ+ ! O6țֹcqыe7Zr= y7-[s'i*ˤV6=0riG``IB%zaP>A`\8ø08E#ō}_ܬ"|j\- 8:!~e-a\yK;5ֆElIJK -V4Ww.09 `.4L~YUWT7#3M#mZ_7W $g)h'[~E+쇾 *Gq > |uPHN=5[㑞w#ivoy6?koTg#>$1?Ԣ—mtՂxۚ^"6x9xZSm/$wg5sڧN4[fXH,w,%Q\T1<\oR#|^my\Dm26u,iY xoY+ɚ[EYn7rS'{6lv?.{x"9V z`фpw F:.>Ka䦎Fk\O=I,jP#ÁRon_dƧlRsMA7CWPrs(+cV#k*@&| q^utqH# IXMHJkI6YUm]JL,R0b5[ûA8֯=@]Z`|'I\˓_;2+< ]Ը!fNO3ZM#|D3CKXiě#{R6.ߚ 9_ԙ,{ZAκZToa2 `uhIق+Z)GyfdPtYݍX}Mpدʣ8x?:{. O`_b:yr٦[7_/TM?QfJY3uHeFr驳$ZN Rā.[1y.!qg g8{EJnT|N^t*^~7/7R%N^i"+m$vDm#zj5 .yi47i^o?W4:d5t7<$w}zЗ~32>NB9k[EN7r5̮SB5[D]OZPI3ג;}ֵ%c+ GMaV5:{UwU>=SI\cӑ0MxYzG臊H)ɽ'p4-> 0"gS0uӃRJ(}d"Pb] -bfBMeM_ K$; Of17[V G J1'9l{-.z**ҺKˎJ+СD1Ծ`ˆ+_2BL}J(by$5$ceQ!g.uhdjRn\XQ/E+%a?c2+FcOD KxguQB'p;Ю2ni$Y٪ڙhlmO'K) P15_RC<]xDi@Ȗ_dɠО>dDqbč6Yz]B]ʕqFFB{LFMkiڑvrl :,ApfA[B$vHb>M"1dtIdHDO<{|ԘelYȪ皎y@lzl'k>_DnioD[Dߡ Zq"n`dǶ{M N^},PTNm#aYMӡR@L&IF:ӝB *w' 0D`vKΘ3Zbu[mZ~}:)fBbGy/ɫkIPvFu ៞5~3UӦTm~r98S$4Y9_n#iڤQ *PFd+5mbyC, ':cEJ)YNM&&Y_X$Z \d9TV[GGEMpr̂H-CyȚz\ ݫ*iAmsꀠ:Eb4h@Ҵ $˪ i-H)jO vvtR#(Eo7K 3/ȩ-oc pEj۸(wKd Բj5\h$;I%Q> stream x\K$ ϯ賁U/`@tܜ,CSb?(Dwtu7?R&}狺I2d9=m_y˦Դl?/xm._~ۛ~7*wo\͛QW{i<[jMx=C` rsXD-i>Ll'ץ'_]//{"H}aO/j/&/'wH/qJu6Lh˿tn&Ç|]h瞦˛6:]_mÐT8 =K؛(3/zm> .k3׫ɏMX.~ޮq@~8*~~[o-4!MQ>_= ӊzd)gT0dj lEf_=GFįi#^.êq)4[ s5xIGD/V7.? @I {&O<*rJxiSհX.w]Η5IL[$d2, vtEpi 9tʤr}\+=.BȲqӕM,#L9JUWwr,H} 'Zݹ֙ :l&gmBtLu+4KVP9DuMC5NHC'Ӻ㚙xXvH-TTa-"TFSpSڨJb>%'PRD>iJVȸz\|Zd 96*gs4Yb'C7qUVՃXBzm:D)k5'H׳'ˢ&4Ɔp̱ɅoaLŸ5gOW7}]Υ[bwl~'[>ՇER&zNg" +jc+<\Cz\Wj3Z}R`uԇ'48>-UoH&%[w *)$ڂ@T QϐK*ˬ<1˜oVIăz/֥nralH 2<ڏhS>m?#U\^QpEe]Y|Z' E_ $r#~1 ̊ IމOP'fM @2$Ɋ@#l|S NQ~+lPD>GbXIϛ7]O`pd0d:^ .e9c&2s9INT2a+,bIVw'C.3ZUc"&*+B"MN\mI`6.XG(@q๪ 8 θF Dr1Ol_*]YQQ1$Ey>c~Hti`ƒu;Pe@ I}qXJ7 X5’rfu)p \ՋЉJu" 9`VLhHDy0.'+,BmXxu|s2RegJ\ Ȧ,qr8HrjA6+T rke*F;$  lIt@AO 0f-3؂:Ybr$\gXAƃmVZ+ Jj}X;?STVJmDy,V'2 RP+7 !.@u }O}PB`>OŀEp&qb% aVo6;ꦥGyUHH1WU-lZ[Fy2Tp ؓiQe1 )ܥ+Rq$ 8tr i5ȠLp2SW&\$C"!6!#qy@ ީGon1# ֶvXT/D +M$L8-=oeZB¦Xqts9?2b\ɢz4wjK9%9ê P"܆c$jl,4mJ7&#AhR$e7l-b!V߯)N9f٤ CP#ފ ґb9הzݭL[e\!ꦜU&͕4Rv ѷvd)G.W*+b-EnIWV0,IN dl [Ѓ69Jqۉ3;FXBXoKKE FB$U&=m+)@lsΚ6B*,3 Zs]ݕJ l f2RY)e8ST,>Wu fX;ʠɌXI!u&eeĢ76C8ݤ>⳱ȼ"w֌GW#]IU9d0yeД|O^ |3Z|/`Ĺz®! i-}+)6lfșolC0Z {au B\1,+]CgaIϵq55:!<F‘L;ŧ<?@$lz@5!*tQ0Gx WC> 3Ո"a`C뮐P|8׳7\d,q{ Fn<9v.'7c Sm/MرLYdJ<{.3#B?#r$b)}p*CᨴFbfӸKW_aFkaCVk窓Zr"CMM܃_siZ<\#JMS^+> stream x\Kϯ賁Q(`@?d0<~d")J=NLK⫞_=b_}'1 NvZ9Y~߾;ELz=տeYd4|6Iؓt0wx_i%}.nhbYOv4ܪzzv[? Ӝӗ'N_~MM~jބ:7MJUÝggcr>Mq-GzR+Z+lfRᗿ"D!xפ+Lj†M<\Zg OĿ*2/83D9M_z_|~ uEثæVO9J"\  @\Da&,4͸3- ~("HG8NX=g! Na ұ$9iRܤzR{D6iQ6Дiz~aʊ7AۂQ0=Uُ|{œkVB8̑E؋,Z]CF }yy!XeyntvP < 3#d Hm,e2([$z%~CrQ:*!˄XCC3y+_ItI"@TķsJP#HDUrO"܋dL0ī#vπendu"<mi}5]ژ=o`B.Dfz6 T!G="*xDcNᵼT.`jji!7Hbڨs& :O&`>E| @9FǨE}^^RXAtig4D? ¨g(6$QFqSw)<[/$CKH^,QkN-!j +R8B"] 9S w"YϽHlg@$F ñmbPkjUVRTrɴ+RMd{IOQߕ螚8U)Ia!ɐoJB8Rѡs{ܜ ^`U0ez*_X#̏Yѳ9s 47`bVpkAnp+p1۫,CYʝC5B,wg0+=FixOyԂ)嚰{QcVU8ڨW`[F)SndIn?52H^\ښ"6LSIOhD$+#[4ǭl )\bʼnZ$@Ŕg\ŧLR-(Lhb:h"`tЫFk hzxYTM3g@4DmDvƍU8u0<j+Yh8؁8o4;ê|V*,꫊vQ>Yk Rh>ؘRxX{!zc9BaK>'Xf E#%EkϩA`y)o48b.[:50Hz$%EMe{^3Kiz2oU(W6|V筗X.H~Aw >-rጒ=r:'.au0r%CRu`>R)IU-Y=g!eIub+?qD&3xDIqnUjB%^)kPj0d\Fќ[24$#~?gK9YԷ()>vh*`Ve(3)ٺ1ku84YnKI!ر] FӲ$if:H0Cp3zn؊LUPtK,jԿWj. !ƗG5P)W>8&cvjYղ0U4hleNa`{fל۝ Mqb K CmK D  istݰ)E f^jC.ٹ|wUbdzLjNEYش <ж]ح`yK۩`u񯡃L +CH&HO, Luo4+\I@իX9ز~Hv]yrkkxջرD4x|::~j.^3;N}R>AgsaP/rE)ÔDJJg:v]yfg <!/ {2>Ny.0#oˊwP$6vϣ4=O'$YK`̘DʛXcH|TbAU o9+-h{BɍgqfPI2orY5QTR`D"QKg0U7]&Q≽\F63on^ɩ g,UvX N*.Zo ߜ%B&Y9-ՀmL `)ڸ@aunz\}Ҝl1PaIcX~pNь0/f>0%BucXS>geg<*].ZGZy^v\顏jZeT=j흵ta1t7^ Y+Jsb>QV.X5)Y+JkvSdcSpvOkM endstream endobj 112 0 obj 3746 endobj 114 0 obj <> stream xɎ+>_gpmH r0rKl/);$xx*־,?~$fdW;+g'o9|7M̫zڿܼNQ M%줖<=Ky.v~~]?Wf^GbE|/pr|[լ&/ļu>,>6}n[⾝Y\pEMY6sb;#XPղBLZ&}/RA%YW(R6]?BP".؈ERMKRT$BH2 &xyb2ŦP(͋3cBXOP&}c > (N>q-2ZE.EQc[CmZ9m+B>bWY'3Z.[̫.BNuhpc|b/Q&dE Df~-m!>HgS5HYAAy+P%JE .LPKU5.V N͆fzq;B*M|1.c8  ?q3m`!)L> A 8/m@c-W*t~!9Ə*bSAb!>KX~b-]OiVSKQHHKz4U"6ŜA$,KfOfըgRmU|#h59G:QBpjY% %q)fh_p'R]b+7TV?|YfL'x$hf1'#҇K72w .~s"X%qpC5&sJɇ9*% jxl:]*GmH 昑ϮcԪ_6TtĠ]\y "{JҒDRe=-VMR@F 2t4wyiW֮ޡ2J(-VuQR]P ig`A b,.M,o,uR"UYIdғpU DO*]BM%Ѥirxd:}ѷywko{+z6U9^J VNG4(MdՊC)삸lG⒫p z "B$wDzO28mM˓)z{(=~VPuPDB 8nf eQ EMTc{]5!0<DXJ|4t|ܵZ?Ȯ?.8SrVb]; " Z+$k!G5"?\m I=bG:wfk&+ ep !ʆV-A*`[0ߏ!KęɣB (&^Qe- (Yn)f+huO8DF(dV*w^S9Mh 8Uٞ :߼$id؈:Vhe&+b]S~Ä <= `G~o.כik.;`qWJ ”@]u3yiaL\YeS"0a95LG]_Kc+C\MVW ;.Uz{ v}կa#QะC쪸w`cD`²sVJ ~~L`r_VE endstream endobj 115 0 obj 2669 endobj 117 0 obj <> stream x[KyVX|`!!-9^*%K3,cwS$Ū\AHw15ap#\~_~;?m|F7]>~s|v0k`W5#c@% 9=ɣ8 ~\A&U,+kB߭ >f 8,BvMa8]Ӵ1 N hn]gOMxF8Gṛ%ρbPӥlBNv?`a`_+paNH=)'N ij]8#sHLu 9#cYCf=%2/(%i~NlYRaoRZYmq7&F0ْ|Pq=pP\)m kY6w#6f:xt ҩ PcHb9ď@iQ-$R!=o!:=q` z({BtR8XP$TG$ 4ф* !p H"w0 @F@ a>v޲0BKJx &ZE9Wf{nPNJ~JȅdӁ4ˎŊle8ޭLKcB/<ضWL-ב<< {W*;o#3PDCYx;K)% r'AZc]i҅8^`UށYVe7:0yΨ/M}Wuv(dHE3 aST c y,F[ lC`e駍s㨌3@ٓ^QBƘeAI\'C1,"yn I{Q%NNՒBԝWKx<$ZSl(MQhntdsiްC`. K99B6;$|N@Ew:*]/o|ڙ?cE+xˢ Ui4[Y0qH) , w5L)`-p:RA]iz V*5mWޖ,WK~Қ6ǃd%=]g=63^іxU:zGwRڳujvل_b1FMG*blfZSƚҀ CO\r#W7%_3>N#\K✒T+Jp⡟IpV)ǭ^L|`9֫%?`썋9*gŦ`*ugՒhn6n'!$a|{i{/HXDЦd~KJwSpsxcFx G{w,Nu>+׻1r۹A/ >/\ܹץo7>/&|+X' =xէW_ශQz/nY`8?Wh IJeZ'|JB](s?J Y~lcm `5|7zm endstream endobj 118 0 obj 2802 endobj 120 0 obj <> stream x[I,7ȳsʮ.o7`63o`|wh)̬=`y2KK,_Rߞ7͌I-jFMVl5Lo>yL,S?)=I35K|VoY?\j}2v.?|z y=E)?_ryPc?޿ Bz2_ +YjXrsLMp,{/LK49>x |re։EQ3rDŽ_Mɔ!;%H9ސȠW@ lw?@g[AWvF"R*C-W(L^iܶ~ JB:`P*(gHpk$6Э-pC\&=9"jܪKpj)6- ->=JWWc1E4V ~6 9:#z`x(Tۇ24 /(o uQf[k)a9?]a0|]tu3`\0 2D@;YtV fqfM,f d1aSbIY#YQD#E[hx^+aOE{ײ]iZ(ΈdV#ye&H pu!ӯNmAiQs =ąV !ho3YB:XS1uBX*wڭZ$Z▄9|]$I% B,@^y&l6usoؔ޲sMX `8g g1l"DV6c6_qs֞ǘxsne .HcgAd|Rj7f ONܵ{| 88@3Nj{"z )z!7/FW]z> LF`+rp Ncs0;{591\,DMp[#-d$@T>)4{l6sJmq/'j6Dvl?+vR ;?9TفWv+eN2~I0MBID&EYV:'l$Y; s{0zMDoIJs.;ԵMo-JҨK.&QU)^ϋ⏣lh+bB(]Ӧ N0&e}:ӡ?f.CFf B5JЀQLP JfWC$=4;שɼiq ZzGi!7b%mM\;  =~TElW@U0NdBoc@7Pm#Z 5FX~޽78Csw-z"JMF YKlk:|akbkrPhZ4y>ތ]Ғ4g]媦Q̌mh~GɶV\Y׶T,y+įG9gn,"4;{'o%쨒SJe{-Y)i @jPYK]{7VrY3MRJ&,| NXi-RtDPȸO7H[r0.v乎 Wcayi5%[:7"! 5CՊͅcpܖdҖ~t=JՔ@:/bmt8#Cc_y2NP1n_c_ Mi'Ћk<} ƹAdщqnHIJS p =G5Oܯ\F+K}ܶeBb)ct,Z>븼Z5"C06\+u*\ , ;j}D<|$ xTKC>tNN3'o["X@d܂)#i樣Ӡi8:ػgLͲ2> stream x[I+ϯuX Pk r0rKTqԔi嫅d0߉MlfNʩ5Y 0Ϸ02ۿMLf3W׳TH;C(eOW5>~rwvj߂^`pY}u̸1IBҼDvx=Upd3oIT AyNЂ\G ;LJ^@Ys f9f[fV-H2#iH53Ul3B YR7`%O l7g!ّ]aYf`]Gf $q. pWFP˹\g3ܚU ?*Cjݩz\#;0"_Z; bj4:6~599]ϦBu208i"DĺA G)x] :ES$7ͅ {J Ck0&G@ҧJ*O~a(j{>}N <>FbʏB8æ`pмhdҬT09;<WՙLXnHr&xePLXO3 =~м ϛF *Y+7kLRP_ 9rQJ8 5i`,u~S|874[ӝқk|#[h]yŶ,_ PuKEMRpi5m~fNܹ=iC"&8niO^P4 Ԡ%@(iCьSId?GX3GQ8qK=3h׊߹سaz^Q.L ͫ- 9P7 ӵTocWl_!)2v._Ɉ$ѽNfI`C3#}5@ƶA4[#}'%[/f4\맣?߻ X=WwtfK͖ =++"%K?fS.P=d5[j2dT/u!h<5Q.7rt54幡zgfu5m ΓUυ3 AS&tuSXyh5.KwtQ ?EZR7qlA5[Էؿ%T WM4f0Z0(0`=$Od3i=l`(cd8kxm ʷ)n|xw 1w 6j)b>:s!T^/QAHB*sA:;l>ڣ6θɜl>{h͛$*yˈG ]@UAv,u2fzX땢VsDP#w3j|$,K9--OUVY-ڦ¦RzjVPih,ga1xyUQM>_xT~SrsQ;Ͱ,wP-Fin 3XeGB!1W;E8\U u_ |ӯwkޔp鯱iI [=&~k~/# E^54 endstream endobj 124 0 obj 2603 endobj 126 0 obj <> stream xɎ_V`vM%`笠VEQ5rx).vILۿO$&.vRΞ鷿ӿĴxSoxNn1 Oʞŧ_~Ͻ4y.';9-1_> }u=c&9\[n1ɳlJiGM t[Xc`_Nv˝8}墍xJHq^z9˻QJ{Qx+BM4C8!g~2Zp0:~|q93 ~ %[Tޅ)_@FZ /0 <<8>Eȵ;NY:}yw`x@( gxaD>Oү2#`)z2qQv6>/c, <੅4V%eۙj JƒunrB ~(syEï J=4Wu ^"]z]&<05pj.R4x%R%aaU&׳O`˸cV>KKg&2*LXEP} \)+l\4WʌYU};'/F\{W-2A',T8kbtp; q%V{ڲgЙ&(E WS"0qf.׼&PRĔQX>[n>p l}c-) c<>%"wP~*#DE#Ox@XhvȣavB?H4qӴh[ti]'iQ0dU%KzS&ޞxsآ&ŗ/6f4ЁR̾dZ(z^%<ۢb?Y։"0W'>"61L F{'A[_ᵆY[vJ4 K df6CKA9=I=G_9kJ; B{T29>qEnYXUMu͒$^sԥW9(>T)^(LRw/4o O/Vs^@u)p"G1*7hXEEǏ:$*"aZJ0!d1;N= qr2(UFXnZYZ!-:<:p;LUTԜ6&j?& (AQ>{m5EX& ;ʒh`3jNZ/sHSíT=]Y̓Y_.:GBN锠DK*9J”wG k4jb+G3[戮F]]X&b+5xGOWgavlkNnK;Z%U'F+qxh,yՒh=W+jUL)u mYtkg;]tT7Q آAxՈkzMuNbI]=&lA~eugwI} <+ TQ:[Ix&kki-O!]uYz?eRwiXt!u OHj>hUQ7:TTcUWtf`уXuсL37 r+" H5\~* 7wWzWKTRνwc(3Mb:HEM:_5L Iݩe!v"MFcx Ak>T>GL,2VN8 -#5,CWI[ԢQ#sْJ*<5+(snE'#HmDTY'Ki'ݛjeDsqf1G,yP0ɎEIHm>^ dי.VD^k6q|HD#8}6d%  }B('%Ĩ? R "w63P{0 P+Wnec~$(FD[QV=b?cgrf a=QpXp]6{kOC4$W[4Θer%ⵇ]Xm7~o`kĨeW=R|- *WR>px i$u8t*ңQ3ViJn5#`M~#v4dthjUK}邴l1mL~N%=ܮHc#u]uGBNDٺ}fR3MHl-08d:t RLg2As9ƍZ^ Pë<Ɏ<#tX#dQfOq- ]!hްMN Z;noiMow`WoZ[^}pMImNF#Vo!)4vV>tCFJ~*qE&Wm*!.Mh mbXik vY`+ui6 DfmolPO5$Эѵme#+Z4ĪF*!\/ j\vUQ3+rHa1F\j-e#Q=fxU4IGY!_Iel|A#IXpZ+f~w} wSHLd2N+gykHB rjۣ~(1MAx'xo5gyRjo!u"z>^ s/š- 8 ! jIGsyi5aZnbk,Bm`^4g`KxIfpu&Ifk_vs*iĩ͖0"[njÈwζ%k;i%񀯢^1gظկ`7ںHaD+b.!MĪ q%4δ&F/0Y8[R 2chS7BAc/n"fu2~"|…db8MyFg~':K>5(?zUuÇOG0uѧ4A(;I~I?ެ52ӟ|ɲ򹘭es0eG2>^G6>+Oh9 W%YyGsY*"읳pU%Yg}dka@E߰WYe, |1>iioIj|swU] \0z9y?v|INI;UC؊NX< endstream endobj 127 0 obj 3845 endobj 129 0 obj <> stream x[ˊ,Wzz2(6x7vW`<f~ߒBRBJe܁Bߪ|'Tb/o$fnvVN7Nn??|.T׏W!o_~{|}^ԬW4U=|(M^]eMM]܏߷EQ8Ax6ZoEG-\b2U^OglQ| l Jsi0<$H^*6&6f/X1k;I=[<]VlIunԭw!"WjtUR-̭fYX ZrsIzTE(Y^POНpN`|3*#>L1"48;Xi2jѺ1H# bRv+Wh5Fϋ+[Ucž)PU1ZvⴛUDJw$Pl?Ö} !-gP2^0 0qjy Pޥ'/΢l{~bbX\O,q,oaX~Ox][^'G,T-?p1?"g34If _3̱g\?Y_pFqg?iW_axo=:*2wBWqήӧs,sh)il<,EۈARTQZ^fhD)3 I׿U1T, (RpeiD/s{dbU{ ]c?W kXaawjwYj 1BK3TC#I'"͡ݶ& `T"hk= {bUrDq;u ܉3E BLv HG>$$ajU^ -80 t0mTjr5+Qm`.[p] Z8:pwV8&YO͋@λ%~LƯِZ*ʠf1;)aiDx?zQ9YRqÜ DnF$> ΰ6F  X%`vɁ#PNv7l0CVRV&OzH*ꚠVNAbvp/Ue9O%k"|ܐ_z5 |4O ,s5? yl&| T7`nӠ8"VZI&X`&VK\Qɢd 7QЅXݖ$[+ؘ Ha!@h[P$ Hc9W39 8r#gҐА&R+QrUŒ\=,]]`sO3F=]*YӔnZG.LMjF:-a\^7>ɝ|\%ٷ $֕lCѺ?% Y ڶ/$i%R Ԕ*MkL#DA`N>UmKf<+AdXUQ0;ZH$#)^#xp灎U0Z`ǧ@zWpZ[Ο5ڞz5'"j)gj3;Cbŗu UsȒJQ4YOBǾabQi4=8g|u~*:)Tu+B3J= =ldOnpB1CC7}"ҽ o(pSSqͱA|wh.+e9Θ9kWDL驈,E-Tnf- \j5曵#9#MMwXSk~HJ GAE6Ӄ)xJC6Mmց7 rQ{"kNP _ b+Br9##P8X/ٺ'ZcE':LrCRK`Ւ{g A)|Fs EVZ}f2CbX'tӄH]GtN 84<$RAڃĴ.c[UPP.#x*0UfBvpfLު'+%MQ:{ƭ-43IhmXq##WJH8۔r^@v$DY~S GPIaMQۇ1OrcQJDCNx]GeENh|V:)&`YBim_|@Oa=Հj$*Y>qyR%J9O鴿IH:s. endstream endobj 130 0 obj 3106 endobj 132 0 obj <> stream x\IyܴA! > >31];ȌL`zJRfdEQ{ZiFLjr۟}muXu>6CR tUfWy/*e ˫ԻyU *!bq?ɮd=.}O\{ Ѯv2#_ K~Ou?Xpb^-Eas}5 s=LKW5M9t.8Ldt:ߠFނÖ,8RN2R~}CAK*иXC r #ҹ(P@LP)- y]&=.2muJ*85Уy AZ0%WfۣJ" 9A&m-ct7y=QN*tdj4#5ßVIPk-R~ w{ɺA4*u"" oACdLʨwS=L-wy5:-ᣵ>'90Psr$<`d,%(B ޗIr7 -x2n/gAVrpOt"`E 5| ߟW# Ȓ2j{q1,!fEqq^8%.N^ړ?K(|I3A:#yDYKY5ʊ]׋]OI}˟fLˁ_ĸ ob rR_9FU67_H A *t Epk\AI36sҕKk <(BomG|?&Ng4"~ rdSR)cKMW4\W%]EqL|N"٭Ka)`OQwp"&ᑌ]D[W*#i>%YYJp hg %T]1RV10i 6,GB{i$ 9SWz|\@ɄL$FID1p/~(B"w򵓺=(REk4cN-&nIeȇ#eE7wɼ/$֦ef&:zHx38pI 'Uh7f*Hk %hGvD)A&a*^=C"};#o+_8KYgBz*!OϮ(if%NAf4N^}k*.$@[P3(OmAONgŢTj m U^0C }EJ2n@& E,;̬Rq ?Q9$vD;rZrcpbV9{aqW%_QAarKEOgk\)})1a 1K7^Yx[IhCڿ)K٢R5ᣄˈ_Q9rRw-KɴQDw"-EQO/ʾ^w'9Ф2 4Q;FT jl!԰~!ITmneGi(9zZf ̯fs:=a78i2#iHfm.jJ֙-AO.Gno0+Y1oo#O0W2 ۏ3x6ƓNC U]}JMG"'sY #ߎ|zQ|_BV2j}e'Q=JmqW۬-<d{IJ{\P"p^a h/@#FKl̮E0)T)^ѣg jU 3[Uo9HP(Zz4F) :r9I8'1pIXEXbd P呤~<|Q +zv!OEQ0$?6Zir:éf*DЕ$4/zEX; Dm&t!S\Ϡ['^X:JƗbniSe@HzE(z[MAٴu?=iz/?$=t@KP{ 9w[eZŨٌˉi iW\XM(VklOɥd=^YKeW?T!L&)w6wPZX 5BbBQ! g5gyWЖ~_QUh+3]!rSmTkkTuP^B[[l| nLkn⌙GlR,VFJyRLVXR?i7Ӫ2/I+XxIqSL.Ơ+DG2 :%D(* l6eΟ2 SoȯmGVOx%7M]A'Idl rԩx͔l)FZg+2\w\Ňk.+ĜRo rngB@: M qtu13J|:iG ÿMDZpVl,f. |H,qcj|,o)W8EBOr}٧.0@,HI"Lf:"mNdc]kV`LtwGWKٯq5Da )'Gbg`"=_)ju%- W0GW+/0$l eEs0^wl%w@ ܳv]9WD˽_mr慷)C_I>zӲO0\=I^|dSA`f]]|jbQ $yT&A5.UTӔ;>353~4T,ec?RdI扙=^Ω_"% fVpHD6s ->Ի;}x=%s)gU>9B!S]LNgHj_o.V51"O2s?-\ endstream endobj 133 0 obj 3409 endobj 135 0 obj <> stream x\Ik,WڠkՒ9y*!ms;TU?'멇{%q_^}qj^l/e?˿7_}yw"uZ˗]~/R]ÛZoMH::8Xa<y݇xV%)Dn;_$ { 2ʃ &+ BH1Jtc(Ӟp -+\R'=UONn zF"Kpt8GF?g/f%uCEB DΖ$65SIB.p_',VehG}km{oxLt(M:-RG>!ȢGl Ĩtlgĵ&$Fw9T&v"k⠊);˷Y `,%uhdSpGRܚUPi%JH XV'J#! @88Y_.~5p&JozZ8BXI !ZKrJFͯ:9^M?^,"-ph /b6,XK# ?^pg$X"Fӑ!xYs#L]G#KpehQ=)#oGO^HJjGuH`0涺e'qGPxD0:~ΪO"PU~tÄۮS2 a=`2JeB*M|bR]bJ1r 0)!iQz[fnkX@e^vLSרA9Tq$ʄ4K'ȼ|#wWS vTZLz]6ف45wjK6"WaO>{<5IMskXFWIuPTP_/*: , G:jɆK?o-I)xi(rC+s*gu@hJ["J\ .in|"DB5^,uelih^#A$fU2.DC&~ Dܩ/]n.m;ȓkȀ)L2C]7%lRaAkB#&G`EuzGkVHr>hN׮ vT!a/QIh3eA7|ijg䀄[BʳPwD)]*oRrHmQVc2\ޅ<.^4h uf1o-3.gGH3-hSoքkS&)zs] .,\2*T.b#р#j<;jHmDg"M$jc+^T)&V YceہϻF5b!A0zIyd" O=WK| yjSe^2f1U ʻO%VT+ʲTĊs;x7JvrC? }$+?mبtAH e중u)ذC m,v-=խ0!; fU6踶,!Yt&k~5wDG_BT=*LBYŨgqlOzY:#(Ap3bML+w0Srn06)(+ϋ'C{so\T~1tAۮֲ˫=5xQ3+5բ:MjeY/s6e6YqYU6 q_W_feF~3-m`x4Qv /+zEpH= ,8hA NC h%幢>1zS"ݟyd]}Zљ:9> ?ڌb*UTMETeIPˀ @ݛFAͩgc \qXT֩ 0_:2c?k~+0‰?b*s52OokіAN$ ;kXPBv U F?ȿV`DfS-7XSN'+,3B<2fW tQvɘv`+ aLJo5Y\LoK؇8rl?k5g=٩-̖@ЌH噩ϔcO\c"s0?hkc-fW`Z@Î֕ϱ㯱Cv>{fꡍ@tI0Bmhf,ͼnƶwGϽX_`(zdS˼iK=b޹/s̗r/U\[ԏQL,Sv ZմW{JvRD`>4gҒV :ޒx)@q qa2ю侩)>Tm.wy9PFlq6[wQʭLbHiP5I`5 u =>ohPɚ , xlN$RKL []^G2:3@riM-Bq^wzxQ%?.? ?J endstream endobj 136 0 obj 3546 endobj 138 0 obj <> stream x\[~?ڱ$[`s:M!) l ?E%= ! tmIuQW3.eF^m2_I Uo?˿Ϸݿf;un_~4/_?}\w~5ջ}G>{*\uN7kr딮λC=<03~2v@uQ>n6W)_5YwM{ǙPi5N5gouM&q|E[=_xzQ2N mq,5Ԫ,4\UIżA.O3C#0$!D/aGTz0sOj+/#``w|=LLC&#׽Wk|d@=oMT@͡>ľG麂]r\ !șU~"'xROkVhf ãY[&ПOm!VQ50ıS&OQbWZ7~=~᳡k(7ޮ޷b ~V\>̈EvCT@库bX4R]< ^1E] eO18>ďq6-,2%$Cx@h- c1e{~m%3xke70~V8@x1%̻(aUf&̽N( KPKȻsL(薲B U%# $X>I&Q}SjT{ijބq AQ-YGYhp+ PAM!wǏNA`]ԹɡJoD"X d " XJFC BrxaZs4,Zxv:8N0e~CV0 KtƛłyOɌa$j0?ˬ y v|o\o(2B ߻@ЌUAY4sX7pE, GIqaQ,LDb%(d$  X(s"̠+@Cox-7#7gѩM@,ފwz ?^(އHuzy[3 z2AVQ˸-?AIb00Ɖ(!1׎SAA_hjDH(]"'*!OuZkHr@,hɩEAW9DVK̺ dCQ>cɴIe}W mǀD[Qp̭e,}(wU|Gϻs,E!%vXFĮoU HFJߠa'łvrTӠL\Emi&tz{6Qy8?~?A"~Hk]puȗݹ_xA繰Ϊ:]8o4//v8pe;:B@eE`^!CnK{j·y^t3Q.,:>'M$ɫG!O{3a3p;5cpMA囧f\ƇC*;~v*k[$Z`%,HᶃvJ(=Kb(u+G9Ş=[KN2q]RQ@zjA,/"BMxx W2("޴IޒbtelEBPe1u A[+H!a峺/TemEQ7DVS8n?b%P3i9r>!F"`hCl uvqAS%F|)yʲ1ۖH2H9¸?!Ͱ5$kfFyg.1Z!o1?{}v80Eݏ Zc2M.k U;'ȹR1:)^L1 B ,&"f =%ra@_.)U[~fmh Q8ݢ߅> ^DN~ci #;/ GEu89)J970 oesQp >q19Ҕ~ˬpknl،dhO?>c7\ƁCJTr {UU endstream endobj 139 0 obj 3471 endobj 141 0 obj <> stream x\IoW<-рն6L  s,M0bU_;IBn,W3mm2o&ļlwj9}g"~>w~S7SE"ܞՋXnE7.6r3{0nW='\ t{P_6 A mI{bU1lQ+ZiF H1i"/5:qxt~GNgH6b*"Tl 4XA@Tn(_!JCQB+ft}Xp?%4 sѯַx6aDʺ@aWd3(%00fBTZ!#ʕ=5zB]6kQښ{QZ-i1Q<*"lW,Լ}YmRB iBpߴ37,=3Uj`ɫm7Y43ՆVYvJNiw=Qoۑ:]X ;X 8qśb$*ۈ3fLc&Y^ve%p0q6t8=~*]+%̢uמŜ02-I 3|~*˭uUSZUFRb~.Y9hӄAbA,@g(4wJShO ᠖rYXw!^ .~ɨ$*G&hcWj>;>$x`b+_q'1=; UӟxU¥ uMC אl5ctRh6*!6A;]=bJMI/xi J)&ެ=Y mGlh*}-A*kJ}X^Q% RX5>l) D.Pum%uB1WbqP 1'`Ju<0C% Zj>{Nuj[Mk踨i٬ȏaHx)IFV8@v.IP+Fpi<ǩ X1媓c8o 7\U9\K˪$MW 5*$őIsKg<-`FzdGDW\QGp^hNZ⎂5b瀮kTWbj6ns wTvEH2E H\;;I[J*8i#MmA\|irG0 M!6V;.9ì4 g\Ι=avQ<2T#ay2nf^ /ܚz_]MW6ܮrh("`uVFj?r2"20ŌU뷂5*.ݶOAcFpl/JI{(Ak2lL9PAqi[#4@,GuXw^Z!6gEf_k&Uw b1Nʘ.K+vcǧOqVGD提|\-đN:8gV~WpRi~ wRe:Sn![(y;2;9UhR8;f\`@tTh5V(`pҨa=R"5=4&24 j,i0m`Fl笉ah|Ks-k 4AT%BZߥ 7NSsbg`SNRGg7P$-(y@#u8. HڗLzHPxm@Ϻ'oT% $7@ԇ zŬT(jKK0^YOR3 ra֘ U>PNZ.'{ s0_laQۥ7$ɫN(e-&c3 )l1'sl%V㫙f,*Bӓ4y~~^GEtj %ܾnjF U~-^_NKqrp avź 'gA\ћq?-s4t.Y . u3|D$3Ͽ9)WVۺ,BO2|>–VvȗvZ Z(VW 5 bNf([H:NtU74@,|C.`U7y#)X7^@, j2pPm>줿m7JSE|۬igF[mtHܿq*lbp=0WOC zBW=,Ljf VYY_13eMT}&cXx1ذ9ɀ`A }D;HyT:E1,RްϻPd4S! 6i9? endstream endobj 142 0 obj 3424 endobj 144 0 obj <> stream x[Mϯyd24 3Ӂ6!.l {ٿ}WI*wI/LOb׷Obfһ'lV~M Wzl&#ļ}@N_? RU|.*]fw~\ennݾmq?.X9`x%.&nDJ{U̯MWӲ¾V|-9i6aśA.cu~V|juK[q_*M{8R~ً[.ׯ?}~}fY6P5kIZeq3W%m+l$1J"{޷(WJQ'nڧ=f9ż7@Y ԬuTe#^f Zw)Vz'ma^zNyp[8FXP07~wșRq#fCWto'  83yk5W~m t.F Ԩ FJ[[{ƣ7©L"Ɲ^;;*遪ע_)CBz8p&»zbDoًXX:gr&ɧJ:RJ0Mw!YlSScNe#w9xl|^v6{a岚9.[+ ,ZA-lOݻʱ^&MtI@uUW O4ꨩ:r@j!-L$FyoK4޾jWL#lTiiJpu#)_Wj{+Ȇo~v\k<&@[?9cJ1mg: Z̛H(mM)ELA ( -ordrH^_ WYl§虂z㿢x)i:S<6`]W74^(i3ʠKvSxWQJB+YV+@c12)p\JsU eVIHM,mR1/+Đkq\ gzx0[i!Zu:K/!/{lFt1k,ƾcRbxcŶ rjb Xq=&A%`QF<c?iq}]i{4.͕߆RLu|!@MHACF-;<&XV,H) -X&L!I`b9@Hɓ0PVN6$:MC/j㠚XBr.XdUmROQ5Hɂڥpɖ:Ee*LWFqP!M%QޟtJ`QiT}V@:-7=aMEWMj8 ? #݂No&lx%` M3k)k]yԊ5ʬNOd8XX8UG[E}CȆ\G5InYءk6)+~*PY!PLO]*Tar<}x݉WGRG-fFW0HfI0s)M0BH`̇U U"&yqT@#FJAd d$q04Ms 9(/vt3dHg8:ߗ=OJR-)O/SV1k-}'b! 'Å6B >ԑ>dod@:ѳPRsl|!á9GV$Ae¡9l9*b͚&g]VeyUuEsra5tv[,^-tƃ3+=ڈ݈[{ڢK@5?T}w}r]FrL*DA:ZHtAAڟ_k{xJ1Oً sb<>CBڲNRrSUڪ:fZP#(ن'J069(ݡ5y5ΣJE6V})o=ԙT>|3bF)r0I Yz%Y/m0|}T35`S\udA*YO9+8فzmJozO }=O$?#M=vSӚMN0AZ7zA)=! \h} bsKmRz 'ˤёJi::(\&MLSkPl@Y 3'U+

c9/| f>LjP֮`ųsoq7-`u05-ْ;W>M^7g q nױ8X%ͮJN}ulSC3Oh]Le|@c) sa,Ø?sߞFZB i9t k[tgNe6M8rEm{^幻^|3)M=%U.e%F 9ECZRi5,Bf9s(.f x'$u׿v~_RT>^^z0(bi9N"rS`u=2*a:־߿&R/S/i?Ջ0/8wѝV~4Y9O;LCyy9fy:9`g\kmL!ֲodR4лHW3Sxꃟ?ж)Ӯ~f\!~iIj̨1@:]PuhE6W8q3v=|4)4yg{kz_O;v߻ZMVsOF4hق5"[zذW0>c u_>(Cgu 6*̢})YHɭ#=ǚs,D)fZZfq1RԓB}0_WݿKo ZHeenQ]Xȣ.Pɳd'Yg{ZSݰX)DPsװ֕^=lDZ&(ts j E9& Lb|F+gClQ%s2rO"cZdħa}i ՅF;q"!d<(pX}BHų3=x zϦ:-q#W+u*ÔZþ=nl0k!К|)"-UU3NV.X扷;-bCfgʉ<fٺ[>ڥx !?z5Uq`i~8n;U@>/c& t.>:9|DŽ"I8C8'mL!>W!za'\MRs,dZv&]hO p#\HN0fs3vc-crnE0_ߓ*㪅1ʝEV(_*ՠ1hGYXX)W5P+ _TM_*Ss^yNTfa]0 BJUyE5PμZW`\Rs` {ZA89>OwD#|$ @,?VT;q[(ߔIRp嚑0Nz-W&Htwl~l#RS]u$k*kdwR~}I'C|j4FC~(Gd*:Ňpt4[GH I|C=~Q6 +%#"׉_ѧe94:gRW6,L;gjӪЬ> [oU0$RY> [K1f{e #_e#r\S]Hb6߮wwv=exTVGU"r[)CC(09\R9鐳ʙd:#JD;!byfkC5=a3\ؒwm|/O޲Vw.;Ya)[*R#RV뵻LiUe[ ܲW~UU.Tgmd{\z#]^LL{tTC7߃‌YL;{v/;Kdd僚{m-Ao8!w?ط> endobj 450 0 obj <> stream x]Mn0va; i$ J{b)R1! n_LJ] Ϥe}]?a4 ̢ 0`@һDia{3*zI20Ԯ> endobj 452 0 obj <> stream xeTTmB:Db`!SZdF niD@T@J󾯞wuuf):0:N>n>^1SG8J GaD"]p4fWhik#mQob ? 4 俟w.,\|ZА篘_OhS-+ E|P UFY9KWnQtE"o96`w P@P(k F= xoΓ_PEY"<  刹i:b|Vhٿ @o! 8! 7! (x?t`n$\?ɍ?tn\Ѝ (?t?tn|t;w W4ܼ-D < A2ↈ&Ltux!b )+1P  ,qӰ T`|BKkHʝ}H3aL|H?G7ݺFtP,r4,aqPN:p/ȋ:jz7gOA|?hkJK<;;P'|n!C rs5kG}zVאx1/Bir$0:O&-d\ lH92'& t"O e [wdXA&^z*Ib/ɯ, >|/z8PVw6t.^iN 3I7n*ǹ FwQo's翁=˛YU\&Il$x>{)\׀ʼn;o> ! V6&:?/=ycB[ҝ7/v _7*#E(o`FS,Y=3h݋c8 "C}&I |pC~84K~%5_ swpNŷݐ)@M5.}6RqVɤRxUyyى}`\QT\?k%/xRjz#b77_z?.,{ċg'Wy-"jZQѫ_W`g0ixcB"~OrqJl#NJP.6N(ZҾETq {m.l(ub+L*.iܝ&x!q9^E&`JD4*Jƾs~}1xJ N~ڼr z-dH*V?.BbR?SwVE"ޟ GѻFjV5` g2`JD<6`KNhTžlF[m^YTyKN5d2;䓢JFUTo%'kXK4ٴLJz\ o]kCʛtבQi7bT'gzڲ˟ejEbF|RǢe׫ :ؔSS%dvLK( WKN6^u8S5)zO3(^vs{Ǚtt.鰫$szI=>3a)<ʮ2Ó-gmw~w~JQde&'5VR%hvƟf7? 3s5c 8:0}П$>`[RK;zϹχZ7–*t%'^«JW46MhUﱥҗ]-@s&zm><%&vzT9}Fe=%ZsҠ+fJ-W0y&q:W+ Y,5?@KOJ8` 3E(,DkF Z?~*n^Of0RSߓ5j֔~ǣ,/s|G96Ϡ!{3;}МpeeS&a1$Oaމž<:tr LsHy,PRͰKEK xM4KTrږTTU|I,Z 7_ ,|zF-tkGaVAo>4Lnn|)^0f]q4UM`} ZOtɀ4[δ|tgJ:JͷU]UE_B(L3q׳hI3AnJCb9@eьِ2`m i?Y*1Jo|<~( 2dm&ݑ xա58elHZ*}+r=$.z^i~xgead|8$٣wzmR{vk\r:{އɳ%i1+1j4S.PV4i46syxB愯9;^9 mL(]P_WyzoV)/[DVHEm}]^䵫V_Yv1W 8à]ӘϏy_@Du1f^D.(7k 6^™KZlԀ]5k:zb93.c0$XlX7XΛ9w,;{ޕmOPFMJ3?5Um I<a_xlb1I`U+JSv1uc;pNL&s&qj;2{1YaS1uJ!d~"I2|K(tc3`繁4VGe cKrRΪ_8 e<Ex {310Mu[~RxZx|5^ }[ޖm=6)U"L|-=AFf>^8,:؎Gs(<7CZh2S]Y 9Ή l"W&·y &"ϙ%}z%4x|8 ,I 1w JҶZg\;vC.Cj&K'NЙbP$6O.锺5kjn uFQ'z"zε?klt̚{r1I/2X:ͫ1N1nExƙt =;GaBed@.z]0x!{^Ofyt0D *bMle֜1SKn89$[3ݤMDH0/BiZ򖈕j`r~ۑJhPvt󪊰0vYr.MmY.\ v J2@%Y朂>\`&w{4_.yp`}sV@*Ĺu8 bz7[ <'k%|#_u"Ԯ`DF^pZR7` t@_vRJ?Tw?エٮV%Ig]ő ܅$&eáfEc)MߪWe-x4:輺hO& ,=|Kme Ulp q{1zj'm9ҎNlCg=K"e';O'b ºA?E@jEqGJ'bMO7= i!Y #s(\AAC'H7&NZK\~oZBS8NMR},vAP kF{'aDH9VȳyK:*WO0?6ǂMFNIڥnbu6+wT gO0DvinU{GW_66dO,lk%,Rٵ.ۢMntp8| u;JV.8CsVRR͌7${ȣ: ySex~'"!OjJSvmwCDWg+gφiJjW 4üt}0[rn= L.5܉hGp}ypWQ٩;f8sd[d'<}REP |n~u9ZTܩC{b|؅|`TxӘڛ^(#;sU%%eNGz敽nUȈ*̹PkMEidbg!UcmGG,T)/B^R+۰aI;2s ԠNܽٙ:rB!x2Bbdݲ@$DH~kh7=)4;yH$k#&cNWbEhUv;ΥSiʎ$6E=T>M]? OAn ަ:FY o&y/@  i; k򬳝]bQT:׵_#]N?CnK4It:kC8" b^mw!Dq+W24(x4eތM 7X p4k4] endstream endobj 453 0 obj 5620 endobj 454 0 obj <> endobj 455 0 obj <> stream x]n0 r>B>qȼC.cҜSsaM\1=ˈGdΗ?KW?9#4EMN!9:<77hol endstream endobj 456 0 obj <> endobj 457 0 obj <> stream xgTYC')+'{8 = MҤUJP@:!a5|?ZYguy{?.o썀$% B0& @WGP)  pEw$w%p%#( p迄 p/O][lH6 ^-ɟ&p_d5wŠQ?ݚ D\* `0)5@a]5 (B!0FWn?#Ю :h+Hp__x0j22@ @]A"H1W%w+4 |I?  @.W?@']%1IWQ?* ']E IWYPsq E?f7$  A^.eDvo̓_Ɗ[X朔#CiGnؼE^pK|TB` κ0ρH1]AriIQSP)-$ aLDӾ֞:3QJ[*Ny#>tܥnO"wL7X D-5-pr_pY  7< E7nۺo\4ם֮PRA IixpǽZΛ0 HZ0,,"/fIX6V;K$&3yy$So, +dÚV40 5]~3~3¯dIZ0ٚu9,W{~EUo#D^h6_ 5kiG5۝=ҲbK)Uƃ'j`ҴqbG./DRSm+tq'=)wjw3NgpZ0>9MPvbuw:֌J%fZfdU.zD8jv* 9p#3GQM,S=̶l]I t>79^r /\_zp?%~ )\|8D0XY>BD/ZWd|ĚT /$:GR[Pr{wƞc 6&rije^eqJɇ$< _X;Q + Yέ˸jr\J6HINN[PK"[q/*H9d 3b,PO1<*2sӦz egT+Ψ: i85R9EJBFܚ!A_FFIUC~"F-8@Q>g\qSX[馡s_>tЧ=4Vזhv9P/h-\=5&1M3>{SreH}uFi56iKT]ܗ[l4Sz oXi]jwVnɎK.Ïj;[ct4I{dr3':Etc THG&XW2ׯǍKp2&gZ `FV?S@u4DzvT%~" oNb .#}}bvBz.hK'(YBBT Nc;0s'Mio 5;a5C W]vX$swHgH[{Q =R\ Pxg;GkcKiBADנf4?W؃ģ01c mF'&\''JDTйܯ ={઺ 5tn%J$jD˘ћ3ut5buI=i5n OԁVzL q$i8M|lts' QVS#E`Z :jE^^Li,-[:t֕M^&_LG.T5$ DśMzH6ڗ@GJY%Ψλv#gA2@Oj҇p;e \<~rDڂ]|M{r⥶\2d{(NC3}"@o5j \|hz& mF5]0w;u{BąZ/>y* GrN=Z3M߈9 ֓n'w~-` {TEwj_~q[OJ-jdXL힚mO7T8fQ=ւh\VE|,&jZdRWY}EIGhql%xng֛1HQ]k2FAaTEJoMYCI^|EfNߌoxiE+ˉh<>&(DE(\/G0Vh&x*ݢ嬔]8A#Q.Dy_!Yb4S߱!)|:xm|ݏz^PAL_K~G]|js)*izm>\!{<\ױ0 _( %C N+J;7K@V#<=fݡxjh) eE.nk/u|ez#O>VCk *&RT mxʍϥ/I4 )<䭫RLy5ra̗[&AcfPH X@A˩L{g19{ J+(!)-QGfOPZth(1f@pmoףXFv eCJ]hiNj YRjPM07ݒd=q\K} G`hpu V}OzMstѽU.5[Fr[fOBsO?THWԧiޙs+Bk#J~"%Η/f*cє=eLH,RqsyV`F;-8+z2=j}yjd;6wur04Pe}$$L}yzwOl7J!&ڽ"J1Ŕ%kqϳ.9AoФ !HU\) L_yiܕz'Ȳ&ANr"bs}q3Blyei~w`l!6DN|{\p`BOY"I!,)1i2"Ϸ&m> endobj 460 0 obj <> stream x]n0E /E+$R>T0@-ckVtfޑ}Um*i73,y5hT$I+i9o-V sQk6F>ݪL,IYR B׾n,w?m@Sp> X4`q\ҢiJJ%ydI'cV:N3 |@΃ƞOy;AK㞧\M|| z6_Fj  )Ig]}٪a endstream endobj 461 0 obj <> endobj 462 0 obj <> endobj 463 0 obj <> /ProcSet[/PDF/Text/ImageC/ImageI/ImageB] >> endobj 1 0 obj <>/Contents 2 0 R>> endobj 5 0 obj <>/Contents 6 0 R>> endobj 8 0 obj <>/Contents 9 0 R>> endobj 11 0 obj <>/Contents 12 0 R>> endobj 14 0 obj <>/Contents 15 0 R>> endobj 17 0 obj <>/Contents 18 0 R>> endobj 20 0 obj <>/Contents 21 0 R>> endobj 23 0 obj <>/Contents 24 0 R>> endobj 26 0 obj <>/Contents 27 0 R>> endobj 29 0 obj <>/Contents 30 0 R>> endobj 32 0 obj <>/Contents 33 0 R>> endobj 35 0 obj <>/Contents 36 0 R>> endobj 38 0 obj <>/Contents 39 0 R>> endobj 41 0 obj <>/Contents 42 0 R>> endobj 44 0 obj <>/Contents 45 0 R>> endobj 47 0 obj <>/Contents 48 0 R>> endobj 50 0 obj <>/Contents 51 0 R>> endobj 53 0 obj <>/Contents 54 0 R>> endobj 56 0 obj <>/Contents 57 0 R>> endobj 59 0 obj <>/Contents 60 0 R>> endobj 62 0 obj <>/Contents 63 0 R>> endobj 65 0 obj <>/Contents 66 0 R>> endobj 68 0 obj <>/Contents 69 0 R>> endobj 71 0 obj <>/Contents 72 0 R>> endobj 74 0 obj <>/Contents 75 0 R>> endobj 77 0 obj <>/Contents 78 0 R>> endobj 80 0 obj <>/Contents 81 0 R>> endobj 83 0 obj <>/Contents 84 0 R>> endobj 86 0 obj <>/Contents 87 0 R>> endobj 89 0 obj <>/Contents 90 0 R>> endobj 92 0 obj <>/Contents 93 0 R>> endobj 95 0 obj <>/Contents 96 0 R>> endobj 98 0 obj <>/Contents 99 0 R>> endobj 101 0 obj <>/Contents 102 0 R>> endobj 104 0 obj <>/Contents 105 0 R>> endobj 107 0 obj <>/Contents 108 0 R>> endobj 110 0 obj <>/Contents 111 0 R>> endobj 113 0 obj <>/Contents 114 0 R>> endobj 116 0 obj <>/Contents 117 0 R>> endobj 119 0 obj <>/Contents 120 0 R>> endobj 122 0 obj <>/Contents 123 0 R>> endobj 125 0 obj <>/Contents 126 0 R>> endobj 128 0 obj <>/Contents 129 0 R>> endobj 131 0 obj <>/Contents 132 0 R>> endobj 134 0 obj <>/Contents 135 0 R>> endobj 137 0 obj <>/Contents 138 0 R>> endobj 140 0 obj <>/Contents 141 0 R>> endobj 143 0 obj <>/Contents 144 0 R>> endobj 146 0 obj <>/Contents 147 0 R>> endobj 149 0 obj <>/Contents 150 0 R>> endobj 152 0 obj <>/Contents 153 0 R>> endobj 155 0 obj <>/Contents 156 0 R>> endobj 158 0 obj <>/Contents 159 0 R>> endobj 161 0 obj <>/Contents 162 0 R>> endobj 464 0 obj <> endobj 465 0 obj < /Dest[5 0 R/XYZ 56.7 803.539 0]/Parent 464 0 R/Next 466 0 R>> endobj 466 0 obj < /Dest[11 0 R/XYZ 56.7 803.539 0]/Parent 464 0 R/Prev 465 0 R/Next 477 0 R>> endobj 467 0 obj < /Dest[11 0 R/XYZ 56.7 513.239 0]/Parent 466 0 R/Next 468 0 R>> endobj 468 0 obj < /Dest[11 0 R/XYZ 56.7 162.989 0]/Parent 466 0 R/Prev 467 0 R/Next 472 0 R>> endobj 469 0 obj < /Dest[11 0 R/XYZ 56.7 131.939 0]/Parent 468 0 R/Next 470 0 R>> endobj 470 0 obj < /Dest[17 0 R/XYZ 56.7 629.789 0]/Parent 468 0 R/Prev 469 0 R/Next 471 0 R>> endobj 471 0 obj < /Dest[20 0 R/XYZ 56.7 744.339 0]/Parent 468 0 R/Prev 470 0 R>> endobj 472 0 obj < /Dest[23 0 R/XYZ 56.7 219.739 0]/Parent 466 0 R/Prev 468 0 R/Next 473 0 R>> endobj 473 0 obj < /Dest[26 0 R/XYZ 56.7 570.089 0]/Parent 466 0 R/Prev 472 0 R/Next 476 0 R>> endobj 474 0 obj < /Dest[26 0 R/XYZ 56.7 539.039 0]/Parent 473 0 R/Next 475 0 R>> endobj 475 0 obj < /Dest[26 0 R/XYZ 56.7 236.239 0]/Parent 473 0 R/Prev 474 0 R>> endobj 476 0 obj < /Dest[29 0 R/XYZ 56.7 743.239 0]/Parent 466 0 R/Prev 473 0 R>> endobj 477 0 obj < /Dest[29 0 R/XYZ 56.7 518.589 0]/Parent 464 0 R/Prev 466 0 R/Next 483 0 R>> endobj 478 0 obj < /Dest[29 0 R/XYZ 56.7 481.089 0]/Parent 477 0 R/Next 479 0 R>> endobj 479 0 obj < /Dest[29 0 R/XYZ 56.7 85.489 0]/Parent 477 0 R/Prev 478 0 R/Next 480 0 R>> endobj 480 0 obj < /Dest[32 0 R/XYZ 56.7 566.089 0]/Parent 477 0 R/Prev 479 0 R/Next 481 0 R>> endobj 481 0 obj < /Dest[32 0 R/XYZ 56.7 370.589 0]/Parent 477 0 R/Prev 480 0 R/Next 482 0 R>> endobj 482 0 obj < /Dest[32 0 R/XYZ 56.7 249.789 0]/Parent 477 0 R/Prev 481 0 R>> endobj 483 0 obj < /Dest[35 0 R/XYZ 56.7 214.339 0]/Parent 464 0 R/Prev 477 0 R/Next 493 0 R>> endobj 484 0 obj < /Dest[35 0 R/XYZ 56.7 176.839 0]/Parent 483 0 R/Next 485 0 R>> endobj 485 0 obj < /Dest[38 0 R/XYZ 56.7 563.289 0]/Parent 483 0 R/Prev 484 0 R/Next 486 0 R>> endobj 486 0 obj < /Dest[41 0 R/XYZ 56.7 383.339 0]/Parent 483 0 R/Prev 485 0 R/Next 487 0 R>> endobj 487 0 obj < /Dest[44 0 R/XYZ 56.7 383.639 0]/Parent 483 0 R/Prev 486 0 R/Next 488 0 R>> endobj 488 0 obj < /Dest[47 0 R/XYZ 56.7 514.239 0]/Parent 483 0 R/Prev 487 0 R/Next 489 0 R>> endobj 489 0 obj < /Dest[50 0 R/XYZ 56.7 612.439 0]/Parent 483 0 R/Prev 488 0 R/Next 490 0 R>> endobj 490 0 obj < /Dest[50 0 R/XYZ 56.7 419.089 0]/Parent 483 0 R/Prev 489 0 R/Next 491 0 R>> endobj 491 0 obj < /Dest[53 0 R/XYZ 56.7 726.889 0]/Parent 483 0 R/Prev 490 0 R/Next 492 0 R>> endobj 492 0 obj < /Dest[53 0 R/XYZ 56.7 566.239 0]/Parent 483 0 R/Prev 491 0 R>> endobj 493 0 obj < /Dest[56 0 R/XYZ 56.7 813.539 0]/Parent 464 0 R/Prev 483 0 R/Next 497 0 R>> endobj 494 0 obj < /Dest[56 0 R/XYZ 56.7 776.039 0]/Parent 493 0 R/Next 495 0 R>> endobj 495 0 obj < /Dest[56 0 R/XYZ 56.7 119.189 0]/Parent 493 0 R/Prev 494 0 R/Next 496 0 R>> endobj 496 0 obj < /Dest[59 0 R/XYZ 56.7 350.089 0]/Parent 493 0 R/Prev 495 0 R>> endobj 497 0 obj < /Dest[59 0 R/XYZ 56.7 137.289 0]/Parent 464 0 R/Prev 493 0 R/Next 498 0 R>> endobj 498 0 obj < /Dest[62 0 R/XYZ 56.7 206.589 0]/Parent 464 0 R/Prev 497 0 R/Next 500 0 R>> endobj 499 0 obj < /Dest[65 0 R/XYZ 56.7 627.389 0]/Parent 498 0 R>> endobj 500 0 obj < /Dest[71 0 R/XYZ 56.7 732.289 0]/Parent 464 0 R/Prev 498 0 R/Next 501 0 R>> endobj 501 0 obj < /Dest[74 0 R/XYZ 56.7 369.989 0]/Parent 464 0 R/Prev 500 0 R/Next 506 0 R>> endobj 502 0 obj < /Dest[74 0 R/XYZ 56.7 175.589 0]/Parent 501 0 R>> endobj 503 0 obj < /Dest[74 0 R/XYZ 56.7 81.339 0]/Parent 502 0 R/Next 504 0 R>> endobj 504 0 obj < /Dest[77 0 R/XYZ 56.7 607.739 0]/Parent 502 0 R/Prev 503 0 R/Next 505 0 R>> endobj 505 0 obj < /Dest[77 0 R/XYZ 56.7 321.589 0]/Parent 502 0 R/Prev 504 0 R>> endobj 506 0 obj < /Dest[77 0 R/XYZ 56.7 122.239 0]/Parent 464 0 R/Prev 501 0 R/Next 532 0 R>> endobj 507 0 obj < /Dest[77 0 R/XYZ 56.7 84.739 0]/Parent 506 0 R/Next 515 0 R>> endobj 508 0 obj < /Dest[80 0 R/XYZ 56.7 727.989 0]/Parent 507 0 R/Next 509 0 R>> endobj 509 0 obj < /Dest[80 0 R/XYZ 56.7 376.989 0]/Parent 507 0 R/Prev 508 0 R/Next 510 0 R>> endobj 510 0 obj < /Dest[80 0 R/XYZ 56.7 154.639 0]/Parent 507 0 R/Prev 509 0 R/Next 511 0 R>> endobj 511 0 obj < /Dest[83 0 R/XYZ 56.7 777.039 0]/Parent 507 0 R/Prev 510 0 R/Next 512 0 R>> endobj 512 0 obj < /Dest[83 0 R/XYZ 56.7 349.089 0]/Parent 507 0 R/Prev 511 0 R/Next 513 0 R>> endobj 513 0 obj < /Dest[86 0 R/XYZ 56.7 740.939 0]/Parent 507 0 R/Prev 512 0 R/Next 514 0 R>> endobj 514 0 obj < /Dest[86 0 R/XYZ 56.7 479.489 0]/Parent 507 0 R/Prev 513 0 R>> endobj 515 0 obj < /Dest[89 0 R/XYZ 56.7 273.739 0]/Parent 506 0 R/Prev 507 0 R/Next 518 0 R>> endobj 516 0 obj < /Dest[89 0 R/XYZ 56.7 242.689 0]/Parent 515 0 R/Next 517 0 R>> endobj 517 0 obj < /Dest[92 0 R/XYZ 56.7 471.689 0]/Parent 515 0 R/Prev 516 0 R>> endobj 518 0 obj < /Dest[92 0 R/XYZ 56.7 249.739 0]/Parent 506 0 R/Prev 515 0 R/Next 521 0 R>> endobj 519 0 obj < /Dest[92 0 R/XYZ 56.7 155.489 0]/Parent 518 0 R/Next 520 0 R>> endobj 520 0 obj < /Dest[95 0 R/XYZ 56.7 429.239 0]/Parent 518 0 R/Prev 519 0 R>> endobj 521 0 obj < /Dest[98 0 R/XYZ 56.7 385.989 0]/Parent 506 0 R/Prev 518 0 R/Next 524 0 R>> endobj 522 0 obj < /Dest[98 0 R/XYZ 56.7 354.939 0]/Parent 521 0 R/Next 523 0 R>> endobj 523 0 obj < /Dest[101 0 R/XYZ 56.7 648.339 0]/Parent 521 0 R/Prev 522 0 R>> endobj 524 0 obj < /Dest[101 0 R/XYZ 56.7 214.689 0]/Parent 506 0 R/Prev 521 0 R/Next 527 0 R>> endobj 525 0 obj < /Dest[101 0 R/XYZ 56.7 183.639 0]/Parent 524 0 R/Next 526 0 R>> endobj 526 0 obj < /Dest[107 0 R/XYZ 56.7 813.539 0]/Parent 524 0 R/Prev 525 0 R>> endobj 527 0 obj < /Dest[113 0 R/XYZ 56.7 354.289 0]/Parent 506 0 R/Prev 524 0 R/Next 528 0 R>> endobj 528 0 obj < /Dest[116 0 R/XYZ 56.7 649.439 0]/Parent 506 0 R/Prev 527 0 R/Next 529 0 R>> endobj 529 0 obj < /Dest[119 0 R/XYZ 56.7 759.589 0]/Parent 506 0 R/Prev 528 0 R/Next 530 0 R>> endobj 530 0 obj < /Dest[122 0 R/XYZ 56.7 813.539 0]/Parent 506 0 R/Prev 529 0 R/Next 531 0 R>> endobj 531 0 obj < /Dest[122 0 R/XYZ 56.7 209.339 0]/Parent 506 0 R/Prev 530 0 R>> endobj 532 0 obj < /Dest[128 0 R/XYZ 56.7 756.589 0]/Parent 464 0 R/Prev 506 0 R>> endobj 533 0 obj < /Dest[128 0 R/XYZ 56.7 719.089 0]/Parent 532 0 R>> endobj 534 0 obj < /Dest[128 0 R/XYZ 56.7 688.039 0]/Parent 533 0 R/Next 535 0 R>> endobj 535 0 obj < /Dest[128 0 R/XYZ 56.7 388.339 0]/Parent 533 0 R/Prev 534 0 R/Next 536 0 R>> endobj 536 0 obj < /Dest[128 0 R/XYZ 56.7 154.039 0]/Parent 533 0 R/Prev 535 0 R/Next 537 0 R>> endobj 537 0 obj < /Dest[131 0 R/XYZ 56.7 697.489 0]/Parent 533 0 R/Prev 536 0 R/Next 538 0 R>> endobj 538 0 obj < /Dest[131 0 R/XYZ 56.7 430.489 0]/Parent 533 0 R/Prev 537 0 R/Next 539 0 R>> endobj 539 0 obj < /Dest[134 0 R/XYZ 56.7 777.039 0]/Parent 533 0 R/Prev 538 0 R/Next 540 0 R>> endobj 540 0 obj < /Dest[134 0 R/XYZ 56.7 318.039 0]/Parent 533 0 R/Prev 539 0 R/Next 541 0 R>> endobj 541 0 obj < /Dest[137 0 R/XYZ 56.7 568.789 0]/Parent 533 0 R/Prev 540 0 R/Next 542 0 R>> endobj 542 0 obj < /Dest[137 0 R/XYZ 56.7 109.789 0]/Parent 533 0 R/Prev 541 0 R/Next 543 0 R>> endobj 543 0 obj < /Dest[140 0 R/XYZ 56.7 505.489 0]/Parent 533 0 R/Prev 542 0 R/Next 544 0 R>> endobj 544 0 obj < /Dest[140 0 R/XYZ 56.7 188.939 0]/Parent 533 0 R/Prev 543 0 R/Next 545 0 R>> endobj 545 0 obj < /Dest[143 0 R/XYZ 56.7 568.789 0]/Parent 533 0 R/Prev 544 0 R/Next 546 0 R>> endobj 546 0 obj < /Dest[143 0 R/XYZ 56.7 268.989 0]/Parent 533 0 R/Prev 545 0 R/Next 547 0 R>> endobj 547 0 obj < /Dest[146 0 R/XYZ 56.7 744.339 0]/Parent 533 0 R/Prev 546 0 R/Next 548 0 R>> endobj 548 0 obj < /Dest[146 0 R/XYZ 56.7 524.189 0]/Parent 533 0 R/Prev 547 0 R/Next 549 0 R>> endobj 549 0 obj < /Dest[146 0 R/XYZ 56.7 367.139 0]/Parent 533 0 R/Prev 548 0 R/Next 550 0 R>> endobj 550 0 obj < /Dest[149 0 R/XYZ 56.7 813.539 0]/Parent 533 0 R/Prev 549 0 R/Next 551 0 R>> endobj 551 0 obj < /Dest[149 0 R/XYZ 56.7 157.839 0]/Parent 533 0 R/Prev 550 0 R/Next 552 0 R>> endobj 552 0 obj < /Dest[152 0 R/XYZ 56.7 681.039 0]/Parent 533 0 R/Prev 551 0 R/Next 553 0 R>> endobj 553 0 obj < /Dest[152 0 R/XYZ 56.7 425.689 0]/Parent 533 0 R/Prev 552 0 R/Next 554 0 R>> endobj 554 0 obj < /Dest[155 0 R/XYZ 56.7 552.039 0]/Parent 533 0 R/Prev 553 0 R/Next 555 0 R>> endobj 555 0 obj < /Dest[158 0 R/XYZ 56.7 373.989 0]/Parent 533 0 R/Prev 554 0 R/Next 556 0 R>> endobj 556 0 obj < /Dest[161 0 R/XYZ 56.7 697.489 0]/Parent 533 0 R/Prev 555 0 R>> endobj 416 0 obj <> endobj 164 0 obj <> endobj 165 0 obj <> endobj 166 0 obj <> endobj 167 0 obj <> endobj 168 0 obj <> endobj 169 0 obj <> endobj 170 0 obj <> >> endobj 171 0 obj <> endobj 172 0 obj <> endobj 173 0 obj <> endobj 174 0 obj <> endobj 175 0 obj <> endobj 176 0 obj <> endobj 177 0 obj <> endobj 178 0 obj <> endobj 179 0 obj <> endobj 180 0 obj <> endobj 181 0 obj <> endobj 182 0 obj <> >> endobj 183 0 obj <> endobj 184 0 obj <> >> endobj 185 0 obj <> >> endobj 186 0 obj <> endobj 187 0 obj <> endobj 188 0 obj <> endobj 189 0 obj <> endobj 190 0 obj <> endobj 191 0 obj <> endobj 192 0 obj <> endobj 193 0 obj <> endobj 194 0 obj <> endobj 195 0 obj <> endobj 196 0 obj <> endobj 197 0 obj <> >> endobj 198 0 obj <> endobj 199 0 obj <> endobj 200 0 obj <> endobj 201 0 obj <> endobj 202 0 obj <> endobj 203 0 obj <> endobj 204 0 obj <> >> endobj 205 0 obj <> endobj 206 0 obj <> endobj 207 0 obj <> endobj 208 0 obj <> endobj 209 0 obj <> >> endobj 210 0 obj <> >> endobj 211 0 obj <> >> endobj 212 0 obj <> >> endobj 213 0 obj <> endobj 214 0 obj <> endobj 215 0 obj <> endobj 216 0 obj <> endobj 217 0 obj <> endobj 218 0 obj <> endobj 219 0 obj <> endobj 220 0 obj <> endobj 221 0 obj <> endobj 222 0 obj <> endobj 223 0 obj <> endobj 224 0 obj <> endobj 225 0 obj <> endobj 226 0 obj <> endobj 227 0 obj <> endobj 228 0 obj <> endobj 229 0 obj <> endobj 230 0 obj <> >> endobj 231 0 obj <> endobj 232 0 obj <> endobj 233 0 obj <> endobj 234 0 obj <> endobj 235 0 obj <> endobj 236 0 obj <> endobj 237 0 obj <> >> endobj 238 0 obj <> endobj 239 0 obj <> endobj 240 0 obj <> >> endobj 241 0 obj <> endobj 242 0 obj <> endobj 243 0 obj <> >> endobj 244 0 obj <> endobj 245 0 obj <> endobj 246 0 obj <> endobj 247 0 obj <> endobj 248 0 obj <> endobj 249 0 obj <> endobj 250 0 obj <> endobj 251 0 obj <> endobj 252 0 obj <> endobj 253 0 obj <> endobj 254 0 obj <> endobj 255 0 obj <> endobj 256 0 obj <> endobj 257 0 obj <> >> endobj 258 0 obj <> endobj 259 0 obj <> endobj 260 0 obj <> endobj 261 0 obj <> endobj 262 0 obj <> endobj 263 0 obj <> >> endobj 264 0 obj <> endobj 265 0 obj <> endobj 266 0 obj <> endobj 267 0 obj <> endobj 268 0 obj <> >> endobj 269 0 obj <> endobj 270 0 obj <> endobj 271 0 obj <> >> endobj 272 0 obj <> >> endobj 273 0 obj <> endobj 274 0 obj <> >> endobj 275 0 obj <> >> endobj 276 0 obj <> endobj 277 0 obj <> >> endobj 278 0 obj <> >> endobj 279 0 obj <> >> endobj 280 0 obj <> >> endobj 281 0 obj <> >> endobj 282 0 obj <> >> endobj 283 0 obj <> endobj 284 0 obj <> endobj 285 0 obj <> >> endobj 286 0 obj <> >> endobj 287 0 obj <> >> endobj 288 0 obj <> >> endobj 289 0 obj <> >> endobj 290 0 obj <> endobj 291 0 obj <> endobj 292 0 obj <> endobj 293 0 obj <> endobj 294 0 obj <> endobj 295 0 obj <> endobj 296 0 obj <> endobj 297 0 obj <> endobj 298 0 obj <> endobj 299 0 obj <> endobj 300 0 obj <> endobj 301 0 obj <> endobj 302 0 obj <> endobj 303 0 obj <> endobj 304 0 obj <> endobj 305 0 obj <> endobj 306 0 obj <> >> endobj 307 0 obj <> endobj 308 0 obj <> endobj 309 0 obj <> endobj 310 0 obj <> endobj 311 0 obj <> endobj 312 0 obj <> endobj 313 0 obj <> endobj 314 0 obj <> endobj 315 0 obj <> endobj 316 0 obj <> endobj 317 0 obj <> endobj 318 0 obj <> endobj 319 0 obj <> endobj 320 0 obj <> endobj 321 0 obj <> endobj 322 0 obj <> endobj 323 0 obj <> endobj 324 0 obj <> endobj 325 0 obj <> endobj 326 0 obj <> endobj 327 0 obj <> endobj 328 0 obj <> endobj 329 0 obj <> endobj 330 0 obj <> endobj 331 0 obj <> endobj 332 0 obj <> endobj 333 0 obj <> endobj 334 0 obj <> endobj 335 0 obj <> endobj 336 0 obj <> endobj 337 0 obj <> endobj 338 0 obj <> endobj 339 0 obj <> endobj 340 0 obj <> endobj 341 0 obj <> endobj 342 0 obj <> endobj 343 0 obj <> endobj 344 0 obj <> endobj 345 0 obj <> endobj 346 0 obj <> endobj 347 0 obj <> endobj 348 0 obj <> endobj 349 0 obj <> >> endobj 350 0 obj <> endobj 351 0 obj <> endobj 352 0 obj <> endobj 353 0 obj <> endobj 354 0 obj <> endobj 355 0 obj <> endobj 356 0 obj <> endobj 357 0 obj <> endobj 358 0 obj <> endobj 359 0 obj <> endobj 360 0 obj <> endobj 361 0 obj <> endobj 362 0 obj <> endobj 363 0 obj <> endobj 364 0 obj <> endobj 365 0 obj <> endobj 366 0 obj <> endobj 367 0 obj <> endobj 368 0 obj <> endobj 369 0 obj <> endobj 370 0 obj <> endobj 371 0 obj <> endobj 372 0 obj <> endobj 373 0 obj <> endobj 374 0 obj <> endobj 375 0 obj <> endobj 376 0 obj <> endobj 377 0 obj <> endobj 378 0 obj <> endobj 379 0 obj <> endobj 380 0 obj <> endobj 381 0 obj <> endobj 382 0 obj <> endobj 383 0 obj <> endobj 384 0 obj <> endobj 385 0 obj <> endobj 386 0 obj <> endobj 387 0 obj <> endobj 388 0 obj <> endobj 389 0 obj <> endobj 390 0 obj <> endobj 391 0 obj <> endobj 392 0 obj <> endobj 393 0 obj <> endobj 394 0 obj <> endobj 395 0 obj <> endobj 396 0 obj <> endobj 397 0 obj <> endobj 398 0 obj <> endobj 399 0 obj <> endobj 400 0 obj <> endobj 401 0 obj <> endobj 402 0 obj <> endobj 403 0 obj <> endobj 404 0 obj <> endobj 405 0 obj <> endobj 406 0 obj <> endobj 407 0 obj <> endobj 408 0 obj <> endobj 409 0 obj <> endobj 410 0 obj <> endobj 411 0 obj <> endobj 412 0 obj <> endobj 413 0 obj <> endobj 414 0 obj <> endobj 415 0 obj <> endobj 557 0 obj <> /Outlines 464 0 R /Lang(ca-ES) >> endobj 558 0 obj < /Author /Keywords /Producer /CreationDate(D:20210212165643+01'00')>> endobj xref 0 559 0000000000 65535 f 0000303771 00000 n 0000000019 00000 n 0000000499 00000 n 0000000519 00000 n 0000303943 00000 n 0000054154 00000 n 0000055843 00000 n 0000304470 00000 n 0000055864 00000 n 0000057207 00000 n 0000304845 00000 n 0000057229 00000 n 0000060116 00000 n 0000305070 00000 n 0000060138 00000 n 0000064262 00000 n 0000305335 00000 n 0000064284 00000 n 0000067636 00000 n 0000305648 00000 n 0000067658 00000 n 0000071227 00000 n 0000305913 00000 n 0000071249 00000 n 0000074423 00000 n 0000306178 00000 n 0000074445 00000 n 0000077748 00000 n 0000306515 00000 n 0000077770 00000 n 0000080138 00000 n 0000306724 00000 n 0000080160 00000 n 0000082302 00000 n 0000306933 00000 n 0000082324 00000 n 0000084541 00000 n 0000307142 00000 n 0000084563 00000 n 0000088038 00000 n 0000307367 00000 n 0000088060 00000 n 0000092169 00000 n 0000307656 00000 n 0000092191 00000 n 0000096078 00000 n 0000307857 00000 n 0000096100 00000 n 0000100070 00000 n 0000308122 00000 n 0000100092 00000 n 0000103654 00000 n 0000308296 00000 n 0000103676 00000 n 0000107047 00000 n 0000308470 00000 n 0000107069 00000 n 0000111020 00000 n 0000308671 00000 n 0000111042 00000 n 0000114548 00000 n 0000308872 00000 n 0000114570 00000 n 0000119123 00000 n 0000309089 00000 n 0000119145 00000 n 0000122270 00000 n 0000309298 00000 n 0000122292 00000 n 0000125711 00000 n 0000309472 00000 n 0000125733 00000 n 0000128977 00000 n 0000309646 00000 n 0000128999 00000 n 0000131923 00000 n 0000309911 00000 n 0000131945 00000 n 0000134920 00000 n 0000310128 00000 n 0000134942 00000 n 0000138580 00000 n 0000310337 00000 n 0000138602 00000 n 0000139954 00000 n 0000310511 00000 n 0000139976 00000 n 0000141381 00000 n 0000310685 00000 n 0000141403 00000 n 0000143328 00000 n 0000310859 00000 n 0000143350 00000 n 0000146740 00000 n 0000311076 00000 n 0000146762 00000 n 0000150087 00000 n 0000311250 00000 n 0000150109 00000 n 0000153227 00000 n 0000311424 00000 n 0000153250 00000 n 0000156762 00000 n 0000311683 00000 n 0000156785 00000 n 0000160555 00000 n 0000311910 00000 n 0000160578 00000 n 0000164698 00000 n 0000312105 00000 n 0000164721 00000 n 0000168542 00000 n 0000312281 00000 n 0000168565 00000 n 0000171309 00000 n 0000312492 00000 n 0000171332 00000 n 0000174209 00000 n 0000312695 00000 n 0000174232 00000 n 0000177030 00000 n 0000312906 00000 n 0000177053 00000 n 0000179731 00000 n 0000313117 00000 n 0000179754 00000 n 0000183674 00000 n 0000313312 00000 n 0000183697 00000 n 0000186878 00000 n 0000313523 00000 n 0000186901 00000 n 0000190385 00000 n 0000313699 00000 n 0000190408 00000 n 0000194029 00000 n 0000313934 00000 n 0000194052 00000 n 0000197598 00000 n 0000314161 00000 n 0000197621 00000 n 0000201120 00000 n 0000314356 00000 n 0000201143 00000 n 0000204594 00000 n 0000314551 00000 n 0000204617 00000 n 0000208268 00000 n 0000314727 00000 n 0000208291 00000 n 0000211917 00000 n 0000314903 00000 n 0000211940 00000 n 0000215878 00000 n 0000315098 00000 n 0000215901 00000 n 0000219868 00000 n 0000315274 00000 n 0000219891 00000 n 0000223523 00000 n 0000315450 00000 n 0000223546 00000 n 0000225547 00000 n 0000334993 00000 n 0000335123 00000 n 0000335254 00000 n 0000335384 00000 n 0000335515 00000 n 0000335646 00000 n 0000335777 00000 n 0000335946 00000 n 0000336077 00000 n 0000336208 00000 n 0000336340 00000 n 0000336472 00000 n 0000336603 00000 n 0000336734 00000 n 0000336865 00000 n 0000336996 00000 n 0000337126 00000 n 0000337257 00000 n 0000337388 00000 n 0000337576 00000 n 0000337707 00000 n 0000337868 00000 n 0000338029 00000 n 0000338158 00000 n 0000338287 00000 n 0000338415 00000 n 0000338546 00000 n 0000338678 00000 n 0000338809 00000 n 0000338939 00000 n 0000339070 00000 n 0000339201 00000 n 0000339330 00000 n 0000339461 00000 n 0000339631 00000 n 0000339762 00000 n 0000339892 00000 n 0000340020 00000 n 0000340149 00000 n 0000340280 00000 n 0000340411 00000 n 0000340562 00000 n 0000340692 00000 n 0000340824 00000 n 0000340955 00000 n 0000341087 00000 n 0000341300 00000 n 0000341470 00000 n 0000341658 00000 n 0000341847 00000 n 0000341975 00000 n 0000342107 00000 n 0000342238 00000 n 0000342368 00000 n 0000342499 00000 n 0000342629 00000 n 0000342760 00000 n 0000342890 00000 n 0000343020 00000 n 0000343149 00000 n 0000343279 00000 n 0000343410 00000 n 0000343541 00000 n 0000343672 00000 n 0000343804 00000 n 0000343936 00000 n 0000344068 00000 n 0000344260 00000 n 0000344391 00000 n 0000344522 00000 n 0000344653 00000 n 0000344785 00000 n 0000344916 00000 n 0000345048 00000 n 0000345208 00000 n 0000345339 00000 n 0000345470 00000 n 0000345631 00000 n 0000345763 00000 n 0000345894 00000 n 0000346045 00000 n 0000346175 00000 n 0000346306 00000 n 0000346436 00000 n 0000346567 00000 n 0000346698 00000 n 0000346829 00000 n 0000346961 00000 n 0000347091 00000 n 0000347222 00000 n 0000347351 00000 n 0000347480 00000 n 0000347610 00000 n 0000347738 00000 n 0000347896 00000 n 0000348027 00000 n 0000348159 00000 n 0000348290 00000 n 0000348420 00000 n 0000348551 00000 n 0000348712 00000 n 0000348843 00000 n 0000348975 00000 n 0000349105 00000 n 0000349236 00000 n 0000349406 00000 n 0000349538 00000 n 0000349669 00000 n 0000349836 00000 n 0000349988 00000 n 0000350119 00000 n 0000350280 00000 n 0000350436 00000 n 0000350568 00000 n 0000350739 00000 n 0000350915 00000 n 0000351061 00000 n 0000351217 00000 n 0000351384 00000 n 0000351535 00000 n 0000351665 00000 n 0000351796 00000 n 0000351950 00000 n 0000352117 00000 n 0000352288 00000 n 0000352444 00000 n 0000352600 00000 n 0000352730 00000 n 0000352860 00000 n 0000352990 00000 n 0000353120 00000 n 0000353251 00000 n 0000353380 00000 n 0000353510 00000 n 0000353640 00000 n 0000353770 00000 n 0000353899 00000 n 0000354028 00000 n 0000354157 00000 n 0000354287 00000 n 0000354418 00000 n 0000354549 00000 n 0000354680 00000 n 0000354841 00000 n 0000354971 00000 n 0000355102 00000 n 0000355232 00000 n 0000355361 00000 n 0000355491 00000 n 0000355622 00000 n 0000355752 00000 n 0000355882 00000 n 0000356013 00000 n 0000356144 00000 n 0000356275 00000 n 0000356405 00000 n 0000356537 00000 n 0000356667 00000 n 0000356798 00000 n 0000356930 00000 n 0000357062 00000 n 0000357194 00000 n 0000357325 00000 n 0000357455 00000 n 0000357586 00000 n 0000357717 00000 n 0000357847 00000 n 0000357977 00000 n 0000358108 00000 n 0000358239 00000 n 0000358371 00000 n 0000358500 00000 n 0000358630 00000 n 0000358762 00000 n 0000358893 00000 n 0000359024 00000 n 0000359154 00000 n 0000359286 00000 n 0000359417 00000 n 0000359549 00000 n 0000359680 00000 n 0000359811 00000 n 0000359943 00000 n 0000360074 00000 n 0000360205 00000 n 0000360337 00000 n 0000360514 00000 n 0000360645 00000 n 0000360777 00000 n 0000360909 00000 n 0000361041 00000 n 0000361173 00000 n 0000361305 00000 n 0000361437 00000 n 0000361569 00000 n 0000361701 00000 n 0000361833 00000 n 0000361964 00000 n 0000362095 00000 n 0000362226 00000 n 0000362357 00000 n 0000362488 00000 n 0000362619 00000 n 0000362750 00000 n 0000362881 00000 n 0000363012 00000 n 0000363143 00000 n 0000363274 00000 n 0000363405 00000 n 0000363536 00000 n 0000363667 00000 n 0000363796 00000 n 0000363924 00000 n 0000364052 00000 n 0000364182 00000 n 0000364313 00000 n 0000364443 00000 n 0000364574 00000 n 0000364704 00000 n 0000364834 00000 n 0000364965 00000 n 0000365095 00000 n 0000365225 00000 n 0000365356 00000 n 0000365487 00000 n 0000365618 00000 n 0000365748 00000 n 0000365879 00000 n 0000366010 00000 n 0000366141 00000 n 0000366272 00000 n 0000366403 00000 n 0000366534 00000 n 0000366665 00000 n 0000366796 00000 n 0000366927 00000 n 0000367057 00000 n 0000367188 00000 n 0000367319 00000 n 0000367450 00000 n 0000367580 00000 n 0000367711 00000 n 0000367841 00000 n 0000367972 00000 n 0000368103 00000 n 0000368234 00000 n 0000368365 00000 n 0000368496 00000 n 0000368627 00000 n 0000368758 00000 n 0000368889 00000 n 0000369020 00000 n 0000334500 00000 n 0000225570 00000 n 0000227430 00000 n 0000227453 00000 n 0000227647 00000 n 0000227939 00000 n 0000228103 00000 n 0000247403 00000 n 0000247427 00000 n 0000247623 00000 n 0000248330 00000 n 0000248883 00000 n 0000254503 00000 n 0000254526 00000 n 0000254727 00000 n 0000255088 00000 n 0000255318 00000 n 0000266363 00000 n 0000266387 00000 n 0000266582 00000 n 0000267291 00000 n 0000267830 00000 n 0000274463 00000 n 0000274486 00000 n 0000274691 00000 n 0000275173 00000 n 0000275511 00000 n 0000285522 00000 n 0000285545 00000 n 0000285745 00000 n 0000286368 00000 n 0000286836 00000 n 0000291181 00000 n 0000291204 00000 n 0000291413 00000 n 0000291798 00000 n 0000292048 00000 n 0000297780 00000 n 0000297803 00000 n 0000298009 00000 n 0000298400 00000 n 0000298657 00000 n 0000302729 00000 n 0000302752 00000 n 0000302956 00000 n 0000303318 00000 n 0000303546 00000 n 0000303670 00000 n 0000315626 00000 n 0000315686 00000 n 0000315821 00000 n 0000315999 00000 n 0000316147 00000 n 0000316340 00000 n 0000316480 00000 n 0000316681 00000 n 0000316917 00000 n 0000317102 00000 n 0000317295 00000 n 0000317443 00000 n 0000317587 00000 n 0000317767 00000 n 0000317960 00000 n 0000318208 00000 n 0000318452 00000 n 0000318705 00000 n 0000318938 00000 n 0000319130 00000 n 0000319327 00000 n 0000319503 00000 n 0000319692 00000 n 0000319893 00000 n 0000320094 00000 n 0000320279 00000 n 0000320464 00000 n 0000320657 00000 n 0000320858 00000 n 0000321046 00000 n 0000321335 00000 n 0000321483 00000 n 0000321668 00000 n 0000321792 00000 n 0000321985 00000 n 0000322182 00000 n 0000322325 00000 n 0000322490 00000 n 0000322667 00000 n 0000322858 00000 n 0000322985 00000 n 0000323182 00000 n 0000323366 00000 n 0000323588 00000 n 0000323799 00000 n 0000323939 00000 n 0000324156 00000 n 0000324365 00000 n 0000324602 00000 n 0000324899 00000 n 0000325196 00000 n 0000325396 00000 n 0000325633 00000 n 0000325869 00000 n 0000326073 00000 n 0000326398 00000 n 0000326546 00000 n 0000326698 00000 n 0000327011 00000 n 0000327179 00000 n 0000327348 00000 n 0000327574 00000 n 0000327727 00000 n 0000328004 00000 n 0000328258 00000 n 0000328480 00000 n 0000328706 00000 n 0000328916 00000 n 0000329121 00000 n 0000329331 00000 n 0000329504 00000 n 0000329709 00000 n 0000329927 00000 n 0000330145 00000 n 0000330363 00000 n 0000330581 00000 n 0000330799 00000 n 0000331017 00000 n 0000331235 00000 n 0000331453 00000 n 0000331671 00000 n 0000331889 00000 n 0000332107 00000 n 0000332325 00000 n 0000332543 00000 n 0000332765 00000 n 0000332987 00000 n 0000333205 00000 n 0000333423 00000 n 0000333641 00000 n 0000333859 00000 n 0000334077 00000 n 0000334295 00000 n 0000369151 00000 n 0000369314 00000 n trailer < <4BE6631B8852001178F479DC6534D03F> ] /DocChecksum /C712C0D0D23BFFA99DF1BB89A1B63640 >> startxref 369994 %%EOF cb2bib-2.0.1/doc/PaxHeaders.5700/cb2bib_user_manual.md0000644000000000000000000000013214011522520017102 xustar0030 mtime=1613145424.318620349 30 atime=1613145424.818620334 30 ctime=1613145424.318620349 cb2bib-2.0.1/doc/cb2bib_user_manual.md0000644000175000001440000042216214011522520020510 0ustar00constansusers00000000000000--- author: Pere Constans description: 'cb2Bib: Bibliographic Reference Extracting and Managing Tool' keywords: | cb2bib, clipboard, bibtex, reference manager, bibliography, latex, PDF indexing, PDF searching title: cb2Bib User Manual --- Bibliographic Reference Extracting and Managing Tool \ \ © *2004-2021 Pere Constans. Last updated on 2021-02-12.*\ \ Contents -------- \ [Overview](#overview) [Description](#descrip) [Using cb2Bib](#usage) - [Procedure](#procedure) - [Buttons Functionality](#c2bbuttons) - [Additional Keyboard Functionality](#keyboard) [Advanced Features](#detail) [Requirements](#requirements) - [Compilation](#requirements_comp) - [Deployment](#requirements_run) [Credits and License](#credits) [Installation](#installation) - [Installing on Unix systems (tarball)](#linux-tar) - [Installing on Unix systems (RPM)](#linux-rpm) - [Installing on Debian systems (deb)](#linux-deb) - [Installing on Windows systems](#windows) - [Installing on Mac OS X](#mac) [Configuration](#configuration) - [Configuring Annote](#c2bconf_annote) - [Configuring BibTeX](#c2bconf_bibtex) - [Configuring Clipboard](#c2bconf_clipboard) - [Configuring Documents](#c2bconf_documents) - [Configuring Files](#c2bconf_files) - [Configuring Fonts](#c2bconf_fonts) - [Configuring Network](#c2bconf_network) - [Configuring Shortcuts](#c2bconf_shortcuts) - [Configuring Utilities](#c2bconf_utilities) [Search BibTeX and PDF Document Files](#bibsearch) - [Description](#descrip) - [Contextual Search](#contextsearch) - [Notes](#notes) [cb2Bib Command Line](#commandline) [cb2Bib Annote](#c2bannote) - [Annote Syntax](#c2bannote_syntax) [cb2Bib Citer](#c2bciter) [Examples](#examples) [Predefined Formats](#example_patterns) - [BibTeX](#ex_bibtex) - [ISI Reference Format](#ex_isi_format) - [RIS Reference Format](#ex_ris) [Additional Features](#toc-additional-features) [Embedded File Editor](#bibeditor) - [Bookmarks](#bookmarks) - [Update Documents Metadata](#update_metadata) - [Export Selected Entries](#export_entries) - [Right-Click Menu Functionality](#c2beditor_menu) - [Reference List Right-Click Menu Functionality](#references_menu) - [BibTeX Browser Right-Click Menu Functionality](#browser_menu) - [Additional Functionality](#c2beditor_qt) [Predefined Placeholders](#predefinedplaceholders) - [Cite and Document ID Placeholders](#idplaceholders) - [Cite Command Placeholders](#citeplaceholders) [BiBTeX Entry Types Available as cb2Bib Fields](#entrytype) - [Main Fields](#main-fields) - [Other Fields](#other-fields) [Reading and Writing Bibliographic Metadata](#metadata) - [Reading Metadata](#metadata_read) - [Writing Metadata](#metadata_write) [PDF Reference Import](#pdfimport) - [Introduction](#intro_automatic_extraction) - [Automatic Extraction: Questions and Answers](#faq_automatic_extraction) [Extracting Data from the Clipboard](#clipboard) [Processing of Author Names](#authorproc) [Processing of Journal Names](#journalproc) [Field Recognition Rules](#heuristics) [Regular Expression Editor](#regexpeditor) [Supplementary Notes](#toc-supplementary-notes) \ []{#overview}Overview ---------------------

cb2Bib is a free, open source, and multiplatform application for rapidly extracting unformatted, or unstandardized bibliographic references from email alerts, journal Web pages, and PDF files. cb2Bib facilitates the capture of single references from unformatted and non standard sources. Output references are written in BibTeX. Article files can be easily linked and renamed by dragging them onto the cb2Bib window. Additionally, it permits editing and browsing BibTeX files, citing references, searching references and the full contents of the referenced documents, inserting bibliographic metadata to documents, and writing short notes that interrelate several references. **Current version: cb2Bib 2.0.1**. See [Change Log File](https://www.molspaces.com/cb2bib/doc/changelog/) for a detailed list of changes and acknowledgments, and [Release Notes](#relnotes) for additional notes and information. See [Release Note cb2Bib 2.0.1](#relnotes201). ### []{#descrip} Description cb2Bib reads the clipboard text contents and process it against a set of predefined patterns. If this automatic detection is successful, cb2Bib formats the clipboard data according to the structured BibTeX reference syntax. Otherwise, if no predefined format pattern is found or if detection proves to be difficult, manual data extraction is greatly simplified by cb2Bib. In most cases, such manual data extraction will provide with a new, personalized pattern to be included within the predefined pattern set for future automatic extractions. Once the bibliographic reference is correctly extracted, it is added to a specified BibTeX database file. Optionally, document files are renamed to a DocumentID filename and moved to a desired directory as a personal article library, and their metadata is updated with the bibliographic reference. See [Reading and Writing Bibliographic Metadata](#metadata) section. cb2Bib facilitates writing short notes related to bibliographic collections. Notes are written using a minimalist markup on a plain text editor, and can latter be converted to HTML. Related references and links become easily accessible on any browser or by the embedded cb2Bib viewer. See [Release Note cb2Bib 1.1.0](#relnotes110). ### []{#usage} Using cb2Bib #### []{#procedure} Procedure - **Select the reference to import from the email or web browser**\ On Unix machines, cb2Bib automatically detects mouse selections and clipboard changes. On Windows machines, copy or Ctrl-C is necessary to activate cb2Bib automatic processing. - **cb2Bib automatic processing**\ Once text is selected cb2Bib initiates the automatic reference extraction. It uses the predefined patterns from file `regexp.txt` to attempt automatic extraction. See [Configuring Files](#c2bconf_files) section for setting the user predefined pattern matching expression file. After a successful detection bibliographic fields appear on the cb2Bib item line edits. Manual editing is possible at this stage. - **cb2Bib manual processing**\ If no predefined format pattern is found or if detection proves to be difficult, a manual data extraction must be performed. Select, either using mouse or Shift+arrow keys, the reference fields from the cb2Bib clipboard area. A popup menu will appear after selection is made. Choose the corresponding bibliographic field. See [BiBTeX Entry Types Available as cb2Bib Fields](#entrytype). If operating with the keyboard, first letter of the field is set as a menu shortcut. Then, typing 'A' sets selection to 'author', or '+A' to 'add authors'. Selection is postprocessed and added to the cb2Bib item line edit. cb2Bib field tags will show on the cb2Bib clipboard area. Once the manual processing is done, cb2Bib clipboard area will contain the matching pattern. The pattern can be further edited and stored to the `regexp.txt` file using **Insert Regular Expression**, Alt+I. See the [Extracting Data from the Clipboard](#clipboard) and [Regular Expression Editor](#regexpeditor) sections. - **Download reference to cb2Bib**\ cb2Bib has the built-in functionality to interact with publishers "Download reference to Citation Manager" service. Choose BibTeX format, or any other format that you can translate using **External Clipboard Preparsing Command**. See [Additional Keyboard Functionality](#keyboard), **Alt C**. Click "Download" from your browser. When asked "Open with..." select cb2Bib. cb2Bib will be launched if no running instance is found. If already running, it will place the downloaded reference to the clipboard, and it will start processing. Make sure your running instance is aware of clipboard changes. See [Buttons Functionality](#c2bbuttons). For convenience, the shell script `c2bimport`, and the desktop config file `c2bimport.desktop` are also provided. - **Adding documents**\ PDF and other documents can be added to the BibTeX reference by dragging the file icon and dropping it into the cb2Bib's panel. Optionally, document files, are renamed to a DocumentID filename and moved to a desired directory as a personal article library (See [Configuring Documents](#c2bconf_documents) section). Linked to a reference documents correspond to the BibTeX tag `file`. Usual reference manager software will permit to retrieve and visualize these files. Download, copy and/or moving is scheduled and performed once the reference is accepted, e.g., once it is saved by pressing **Save Reference** button. - **Multiple retrieving from PDF files**\ Multiple PDF or convertible to text files can be sequentially processed by dragging a set of files into cb2Bib's PDFImport dialog. By starting the processing button, files are sequentially converted to text and send to cb2Bib clipboard panel for reference extraction. See [PDF Reference Import](#pdfimport) for details. - **Journal-Volume-Page Queries**\ Takes input Journal, Volume, and first page from the corresponding edit lines and attempts to complete the reference. Additionally, queries consider `title`, `DOI`, and an `excerpt`, which is a simplified clipboard panel contents. See [Configuring Network](#c2bconf_network) section, the distribution file `netqinf.txt`, and [Release Note cb2Bib 0.3.5](#relnotes035) for customization and details. - **BibTeX Editor**\ cb2Bib includes a practical text editor suitable for corrections and additions. cb2Bib capabilities are readily available within the editor. E.g., the reference is first sent to cb2Bib by selecting it, and later retrieved from cb2Bib to the editor using 'right click' + 'Paste Current BibTeX'. Interconversions Unicode <-> LaTeX, long <-> abbreviated journal name, and adding/renaming PDF files are easily available. BibTeX Editor is also accessible through a shell command line. See [cb2Bib Command Line](#commandline) and [Embedded File Editor](#bibeditor). #### []{#c2bbuttons} Buttons Functionality - **About**\ About cb2Bib, bookmarks, and online help. - **Configure**\ Configure cb2Bib. See [Configuration](#configuration) section. - **Search references**\ Opens the cb2Bib's search dialog. The search is performed either on the current BibTeX file, or for all BibTeX files on the current directory. Optionally, the search is extended to reference's files. Hits are displayed on an editor window. See [Search BibTeX and PDF Document Files](#bibsearch). See also [Configuring Utilities](#c2bconf_utilities) section to configure the external to text converter. - **PDFImport**\ Launches cb2Bib's PDFImport window. Files dragged into PDFImport window are sequentially translated to text and sent to cb2Bib clipboard panel. cb2Bib automatic and manual capabilities are then easily available to extract and supervise reference extractions. See [PDF Reference Import](#pdfimport). - **Exit**\ Exits cb2Bib. - **Dis/Connect Clipboard**\ Toggles automatic cb2Bib and desktop clipboard connection. While the automatic cb2Bib-clipboard connection permits reducing keystrokes, the disconnected mode is needed in cases where multiple mouse selections or copies are required to complete a reference extraction. See also [Release Note cb2Bib 0.4.1](#relnotes041) and [Release Note cb2Bib 0.2.1](#relnotes021) if you experience problems with this feature. - **Network Reference Query**\ Starts Network Query. It usually takes input Journal, Volume, and first page from the corresponding edit lines and attempts to complete the reference. See [Configuring Network](#c2bconf_network) network section to customize querying. See the distribution file `netqinf.txt` and also [Release Note cb2Bib 0.3.5](#relnotes035) for the details. - **View BibTeX Reference**\ View current reference as will be output to the BibTeX file. Eventual manual changes should be done on the item line edit. - **Save Reference**\ Inserts the current bibliographic reference to the output BibTeX file. This action decides whether or not a reference is accepted. Scheduled actions such as PDF downloading, copying or renaming will be performed at this time. - **Open BibTeX File**\ Opens the current BibTeX output file. Right click within the BibTeX Editor window for its particular functionality. See also [Embedded File Editor](#bibeditor). #### []{#keyboard} Additional Keyboard Functionality Most keyboard shortcuts are customizable. See [Configuring Shortcuts](#c2bconf_shortcuts). In the following, default shortcuts are used to describe functionality. - **Alt A**\ Starts [cb2Bib Annote](#c2bannote). Specify the note's filename in the dialog. A new note is created if the file name does not exist. The cb2Bib Annote is opened as a separate program. Exiting cb2Bib will not exit the note's viewer. On the viewer, pressing key E launches the default text editor. The viewer will track the editor, and will update the note's display each time the editor saves it. The viewer's functionality is disabled if cb2Bib was not compiled and linked against WebKit. See [cb2Bib Command Line](#commandline) to use Annote in command line mode. - **Alt B**\ Edits the Bookmarks and Network Query Info file `netqinf.txt`. - **Alt C**\ Preparses cb2Bib's clipboard through a user specified external script or tool. Preparsing is necessary to catch formatted references that can not be easily extracted using recognition patterns, or that are written in ambiguous formats. Many available scripts or specific user-written tools can be incorporated to cb2Bib through this external preparsing capability. In addition, simple, one-line scripts can be used within PDFImport to provide, for instance, the journal name when missing from the PDF first page. The cb2Bib distribution contains the sample scripts `isi2bib` and `ris2bib` that convert ISI and RIS formatted strings to BibTeX. See [Configuring Clipboard](#c2bconf_clipboard) for details. - **Alt D**\ Deletes temporary BibTeX output file. This permits using cb2Bib output files as temporary media to transfer references to a preferred reference manager and preferred format. **Caution**: This feature is not intended for the users who actually store their references in one or several BibTeX files. Remember to import references prior to delete cb2Bib output file. - **Alt E**\ Edits the regular expression file. It permits an easy access and modification of stored extraction patterns. New patterns are conveniently added to to the regular expression file by using the **RegExp Editor** button functionality. - **Alt F**\ Launches a file dialog for selecting the source file name for the BibTeX entry `file`. Selected files are displayed either, as the actual source filename, or, as the target filename, depending on the file copy/rename/move settings. See [Configuring Documents](#c2bconf_documents). Alternatively to **Alt F**, documents can be easily linked to a reference by dragging the document file and dropping it to the cb2Bib panel. - **Alt I**\ Edits and optionally inserts the current regular expression pattern. See the [Extracting Data from the Clipboard](#clipboard) and [Regular Expression Editor](#regexpeditor) sections. - **Alt J**\ Edits the Journal Abbreviations file. - **Alt O**\ Opens the currently linked document for browsing. Documents can be easily linked to a reference by dragging the document file and dropping it to the cb2Bib panel, or with **Alt F**. Linked documents correspond to the BibTeX tag `file`. - **Alt P**\ Postprocess BibTeX output file. It launches a user specified script or program to postprocess the current BibTeX file. The cb2Bib distribution contains two sample scripts. One, `bib2pdf` is a shell script for running `latex` and `bibtex`; this permits to check the BibTeX file for possible errors, and to easily produce a suitable output for printing. The other one, `bib2end.bat` is a batch script for running `bib2xml` and `xml2end`, which converts references into Endnote format. See [Configuring BibTeX](#c2bconf_bibtex) for details. - **Alt R**\ Restarts cb2Bib automatic engine. Takes input data not from the system clipboard but from the cb2Bib clipboard panel. This permits editting the input stream from poorly translated PDF captions, correcting for author superscripts, or helps in debugging regular expressions. - **Alt W**\ Writes current reference to the source document file. This option is intended for writing and updating bibliographic metadata to document files without needing to use BibTeX files. Only local and writable files are considered. - **Alt X**\ Check Repeated looks for existing references in the BibTeX directory similar to the current one. The search is done for exact cite ID, and for title and author field values, or, if empty, for booktitle and editor,using the [approximate string](https://arxiv.org/abs/0705.0751) search pattern. See also [Configuring BibTeX](#c2bconf_bibtex). - **F4**\ Toggles between Main and Other Fields reference edit tabs. - **Esc**\ Quits cb2Bib popup menu. The cb2Bib menu pops up each time a selection in made in the clipboard panel. This saves keystrokes in a normal bibliographic extraction. Press **Esc** or **Right Click** mouse button if you need to gain access to the editor cut/copy/paste functionality instead. ### []{#detail} Advanced Features Advanced features, and processing and extraction details are described in the following sections: - [Automatic Extraction: Questions and Answers](#faq_automatic_extraction) - [Extracting Data from the Clipboard](#clipboard) - [Processing of Author Names](#authorproc) - [Processing of Journal Names](#journalproc) - [Field Recognition Rules](#heuristics) - [Regular Expression Editor](#regexpeditor) Configuration information is described in the following sections: - [Configuration](#configuration) - [Predefined Placeholders](#predefinedplaceholders) Utilities and modules are described in the following sections: - [Search BibTeX and PDF Document Files](#bibsearch) - [Embedded File Editor](#bibeditor) - [PDF Reference Import](#pdfimport) - [Reading and Writing Bibliographic Metadata](#metadata) - [cb2Bib Command Line](#commandline) - [cb2Bib Annote](#c2bannote) - [cb2Bib Citer](#c2bciter) ### []{#requirements} Requirements #### []{#requirements_comp} Compilation To compile cb2Bib, the following libraries must be present and accessible: - Qt 5.7.0 or later from [Qt Project](https://www.qt.io/download). On a Linux platform with Qt preinstalled, make sure that the `devel` packages and Qt tools are also present. - QtWebKit or QtWebEngine library (optional) to compile cb2Bib Annote viewer. No special action/flag is needed during compilation. - Compression libraries [LZ4](https://lz4.github.io/lz4/) or [LZO](https://www.oberhumer.com/opensource/lzo/) (optional). To chose a particular one, type `configure –enable-lz4` or `configure –enable-lzo`. On machines with SSE4 instruction set, the [LZSSE](https://github.com/ConorStokes/LZSSE/) compressor can be used in place of LZ4 and LZO, by typing `configure –enable-lzsse`. If none of the above compressors were appropiate on a particular platform, type `configure –enable-qt-zlib` before compiling. - X11 header files if compiling on Unix platforms. Concretely, headers `X11/Xlib.h` and `X11/Xatom.h` are needed. - The header files `fcntl.h` and `unistd.h` from `glibc-devel` package are also required. Otherwise compilation will fail with `` `::close' undeclared ``. #### []{#requirements_run} Deployment Although not needed for running cb2Bib, the following tools extend cb2Bib applicability: - `MathJax`, available at [https://www.mathjax.org](https://www.mathjax.org/), for displaying mathematical notation. Simply, download and unzip it in a desired directory. See [Configuring Annote](#c2bconf_annote). - `ExifTool`, version 7.31 or later, available at [https://exiftool.org](https://exiftool.org/), for metadata insertion. - `pdftotext`, found packaged as `xpdf`, and downloadable from . - The `bib2xml` and `xml2end` [BibUtils](http://bibutils.refbase.org/), for the postprocessing script `bib2end.bat` on Windows platforms. - LaTeX packages, for checking BibTeX files correctness and for references printing through the shell script `bib2pdf`. ### []{#credits} Credits and License The cb2Bib icons are taken from the *Oxygen*, *Crystal SVG*, and *Noia* icon sets, to be found at the [KDE Desktop Environment](https://kde.org/). Several people has contributed with suggestions, bug reports or patches. For a detailed list of acknowledgments see the [Change Log File](https://www.molspaces.com/cb2bib/doc/changelog/). The cb2Bib program is licensed under the terms of the [GNU General Public License](https://www.gnu.org/licenses/gpl-3.0.html) version 3. > ***Last updated on 2021-02-12.***\ > *First released version 0.1.0 on 2004-06-29.*\ > © *2004-2021 Pere Constans*\
[]{#installation}Installation -----------------------------
### []{#linux-tar} Installing on Unix systems (tarball) The following is the general, platform independent install procedure. - Unpack the distribution file:\ \ `tar -xzvf cb2bib-2.0.1.tar.gz`\ \ - Move to cb2Bib directory:\ \ `cd cb2bib-2.0.1`\ \ - Type the following commands:\ \ `./configure --prefix /usr/local`\ `make`\ `make install`\ \ Installation is now complete. **Note:** If the `./configure` step would fail while having the appropriate Qt libraries and utilities installed, try ` qmake` instead of `./configure`, and configure manually the required file directories once cb2Bib first starts. To uninstall type `make uninstall` from within the cb2Bib compilation directory. ### []{#linux-rpm} Installing on Unix systems (RPM) To build an appropriate RPM for your platform, type, e. g., `rpm –rebuild –target=i686 cb2bib-2.0.1-1.src.rpm` or a distro-dependend, equivalent command (perhaps `rpmbuild`). This will compile cb2Bib and build the required binary RPM (often placed at the `/usr/src/packages/RPMS/i686` directory). See also [Release Note cb2Bib 0.6.90](#relnotes0690) regarding `QTDIR` environment if having compilation problems. Once the binary RPM is build, installation is as follows. To install your RPM binary, simply type `rpm -Uhv cb2bib-2.0.1-1.i686.rpm` To uninstall, type `rpm -e cb2bib-2.0.1` ### []{#linux-deb} Installing on Debian systems (deb) To install cb2Bib, first make sure that you are actually using the packages for the proper Debian suite, as configured in the `/etc/apt/sources.list` file. Next, issue the following commands as root, `apt-get update` `apt-get install cb2bib` to resolve all required dependencies and install the program. ### []{#windows} Installing on Windows systems On Windows platforms installation is simple. Just launch the Windows Installer `cb2bib-2.0.1-install.exe` and follow the installation wizard indications. To uninstall, click the 'Unistall' icon. ### []{#mac} Installing on Mac OS X To install cb2Bib from its sources, make sure you have the following build tools on your system: - Qt toolkit version 5.7.0 or later (qt-mac-\*.dmg):\ \ \ \ - XCode from Apple:\ \ \ \ - bin-utils via darwinports\ \ \ - **Buiding with make/Makefile:**\ \ Type on a shell window:\ \ `tar -xzvf cb2bib-2.0.1.tar.gz`\ `cd cb2bib-2.0.1`\ `./configure --prefix /Applications/cb2Bib --qmakepath /Developer/Tools/Qt/qmake`\ `make`\ `make install`\ \ - **Buiding with make/Makefile (no configure and no external compression):**\ \ Type on a shell window if `configure` fails:\ \ `tar -xzvf cb2bib-2.0.1.tar.gz`\ `cd cb2bib-2.0.1`\ `/Developer/Tools/Qt/qmake -config use_qt_zlib`\ `make`\ \ - **Buiding with XCode:**\ \ Type on a shell window:\ \ `tar -xzvf cb2bib-2.0.1.tar.gz`\ `cd cb2bib-2.0.1`\ `/Developer/Tools/Qt/qmake cb2bib.pro -spec macx-xcode`\ \ Open `cb2bib.xcodeproj` with XCode and build from there.\ \ **Note:** It has been reported that qmake does not make usable XCode projects from subdir qmake projects. It is possible to produce one-single `.pro` file for the whole project, by typing `qmake -project -r` to create a base `.pro` file. An example and detailed instructions can be found at `./qmake/cb2bib-osx.pro`. See also [Configuration](#configuration).
[]{#configuration}Configuration -------------------------------
### []{#c2bconf_annote} Configuring Annote - **Annote Cascading Style Sheet (CSS)**\ This file contains the style sheet to personalize the appearance of the HTML notes generated by the cb2Bib. The cb2Bib distribution includes the `tex2html.css` file as a CSS template. - **MathJax Header File**\ The mathematical notation in the text notes is displayed by [MathJax](https://www.mathjax.org/), the successor of the [jsMath](http://www.math.union.edu/~dpvc/jsMath/) Java Script library. Its location and configuration must be specified inside the HTML files in order to be known by the browser. Check and eventually edit the distribution file `tex2html_local_mathjax_header.html`. Should web script be preferred set script source to `https://cdn.mathjax.org/mathjax/latest/MathJax.js`. - **Include CSS in HTML**\ Styles for the notes will be included, if checked, into the HTML file. In this way, all the information, text and layout, is contained in one single file. - **Use relative links**\ If checked, linked local files will be set relative to the current HTML document. - **Annote Viewer Fonts**\ Selects default and monospaced fonts for the Annote viewer. Changes in the fonts might need restarting the viewer unless using some of the latest QtWebKit libraries. The viewer is disabled if cb2Bib was not compiled and linked against WebKit. Note also that fonts specified in the CSS prevail over this selection. ### []{#c2bconf_bibtex} Configuring BibTeX - **Cite ID Pattern**\ Specifies the pattern for formatting cite's ID. Predefined placeholders are available as a context menu, by right-clicking this edit line. Placeholders will be substituted by the actual reference field values. See [Cite and Document ID Placeholders](#idplaceholders) for descriptions. - **Author and Editor Name Format**\ Sets Authors and Editor names in abbreviated or full form, if the latter is available. - **Journal Name Format**\ Sets output journal names in abbreviated or full form. Note that this feature only works if journal names are found in the `Journal Abbreviation List file`. See [Processing of Journal Names](#journalproc). - **Number Separator**\ Sets number separator, e.g., ' - ' or ' – '. Spaces count. It applies to `pages`, multiple `volume`, `number`, and `year` cases. - **Cite Command Pattern**\ Specifies the pattern for formatting cite command. Predefined command patterns for LaTeX and Markdown (see [Pandoc User's Guide](https://pandoc.org/MANUAL.html#citations)) are available in the line context menu. Other, customized command patterns are also available, see [Cite Command Placeholders](#citeplaceholders) for descriptions. - **Convert entry strings to LaTeX**\ If checked, cb2Bib converts special characters to LaTeX commands. Most BibTeX import filters do not process LaTeX escaped characters. Therefore, keeping this box unchecked can be appropriate when using cb2Bib as a temporary media to transfer references to non BibTeX reference managers. - **Set 'title' in double braces**\ If checked, it writes extra braces in title. This will keep capitalization as is, when processed by BibTeX. - **Postprocess 'month'**\ If checked, cb2Bib elaborates the 'month' string on a BibTeX fashion. E.g., 'April 1' becomes '"1\~" \# apr'. No processing is done if the input string is not written in English. - **Try Heuristic Guess if recognition fails**\ If checked, when automatic recognition fails, cb2Bib tries to catch some of the fields of the reference through an heuristic set of rules. See [Field Recognition Rules](#heuristics). - **Check Repeated On Save**\ If checked, cb2Bib looks for existing references in the BibTeX directory similar to the one being saved. The search is based on exact cite ID match, or on reference contents, by considering title and author field values, or, if empty, booktitle and editor, and using the [approximate string](https://arxiv.org/abs/0705.0751) search pattern. If similar references are found, the current reference is not saved, and the similar ones are displayed. Pressing the **save button one second time will proceed to actually saving the current reference**. Note that this feature is not applied in command line mode, when using `cb2bib –txt2bib` or `cb2bib –doc2bib`. See also [Additional Keyboard Functionality](#keyboard). - **External BibTeX Postprocessing**\ Use this box to select a BibTeX postprocessing external tool. The name of the executable, the command arguments and the output file extension are required fields. Arguments, any number, are passed to the executable. For the sake of generality, it is required to specify the `%finput` and `%foutput` placeholders. The first one is later substituted by the current BibTeX filename. The second one is substituted by the current filename with the specified output extension. **Caution:** Be careful if using the same file extension for input and output, e.g., using `bib` because you want to use a beautifier or a sorting script. cb2Bib has no control on external disk modifications. Therefore, if the script failed, the input data would possibly be lost. See also [Additional Keyboard Functionality](#keyboard). ### []{#c2bconf_clipboard} Configuring Clipboard - **Replace/Remove from Input Stream**\ If checked, input stream is preprocessed by performing a customizable set of string substitutions/removals. This option is mainly intended to remove image HTML `alt` tags. Although not visible, `alt` tags reach the clipboard when selecting and copying text. Author lists with email icons may contain `alt` strings that would interfere with the author names processing. In addition, this option is also appropriate to help translating special characters to Unicode and LaTeX. Use it carefully, as to avoid unwanted or unsuspected substitutions. See also [Extracting Data from the Clipboard](#clipboard). - **External Clipboard Preparsing Command**\ Preparses input stream through an external, user-defined tool. Use the box bellow to specify its name and path. cb2Bib executes the command `tool_name tmp_inputfile tmp_outputfile`. You might consider a wrapper shell script to fullfill this particular syntax requirement. Two examples, `isi2bib` and `ris2bib` are provided. To test them, make sure the [BibUtils Package](http://bibutils.refbase.org/) is available on your machine. Otherwise, modify these scripts according to your needs. See also [Additional Keyboard Functionality](#keyboard), [Extracting Data from the Clipboard](#clipboard), and the examples [ISI Reference Format](#ex_isi_format) and [RIS Reference Format](#ex_ris). - **Perform always, as part of an automatic extraction**\ Performs preparsing each time the recognition engine is invoked. **Caution:** cb2Bib, when not in disconnected mode, starts the recognition engine each time the clipboard changes. Therefore, it might send arbitrary data to the external parsing tool. The tool might not be prepared to handle **'any data'** and might fall into a sort of **'infinite loop'**. cb2Bib kills the external tool after a reasonable waiting. But, if the tool is called through a wrapper script, killing the script will not end the tool itself. Therefore, **check this box only when needed**. If you write your own preparser, design it as to write no data to output file whenever it can not process an input properly. When the preparser produces no data, cb2Bib sends instead the input stream to the recognition engine. In this way, preparsing and normal cb2Bib functioning will work harmoniously. - **Do not show log**\ If unchecked, the external process messages, and the input and output streams are shown in a log window. Showing output logs is useful for debugging purposes. - **Add document metadata to Input Stream**\ When checked, if the document linked to a reference contains relevant metadata, then metadata will be added to the current clipboard contents. The metadata is included at the time of adding the document to the current reference, e. g., when dropping a file into the cb2Bib panel. If the document has BibTeX information, cb2Bib will automatically set the corresponding fields. If it has not, but relevant bibliographic information is found, this data is only added to the clipboard panel. To insert it in the edit lines, activate the Heuristic Guess (Alt+G). The option **Prepend** or **Append** to the clipboard contents is provided for conveniently writing regular expressions considering metadata contents. File documents are linked to the references by the BibTeX tag 'file'. See also [Reading and Writing Bibliographic Metadata](#metadata). ### []{#c2bconf_documents} Configuring Documents - **Rename and Copy/Move document files to Directory**\ If selected, each file 'drag and dropped' onto the cb2Bib main window is renamed to `DocumentID.pdf` (or DocumentID.ps, DocumentID.dvi, etc.) and moved to the storage directory. If unselected, the file URL is written to the `file` BibTeX keyword, without any renaming or moving of the file. The actual copy/move action is scheduled and performed once the reference is accepted, e.g., once it is saved. - **Copy or Move document files**\ Choose whether copy or move Network Files dropped onto the cb2Bib main window. See also **Use External Network Client**. - **Set directory relative to the BibTeX File Directory**\ If checked, the document file is copied/moved to the current BibTeX file directory. If the Documents Directory box contains a **relative directory** it will be added to the file name. For example, if it contains `articles`, files will be copied to `/current_bibtex_path/articles/`. An absolute path in the Documents Directory box will be ignored in this context. Note that the file dialog returns here relative file addresses. Consequently, only the necessary portion of the full name, instead of the fullpath filename, is written to the BibTeX entry. File retrieving from within the cb2Bib browser will be relative to the BibTeX file absolute location.\ Use this option if you plan to store in a same or a related directory the BibTeX and document files. This option is appropriate for storing bibliographic collections in removal devices. Likewise, when cb2Bib is launched in USB mode, by means of the command line switch `–conf`, the alternate option is not available. See [Release Note cb2Bib 0.8.4](#relnotes084) and [Export Selected Entries](#export_entries). - **Insert BibTeX metadata to document files**\ If checked, cb2Bib will write bibliographic metadata to the linked document, once the current reference is accepted and saved. See also [Reading and Writing Bibliographic Metadata](#metadata). - **Document ID Pattern**\ Specifies the pattern for formatting the document's filenames. Predefined placeholders are available as a context menu, by right-clicking this edit line. Placeholders will be substituted by the actual reference field values. See [Cite and Document ID Placeholders](#idplaceholders) for descriptions. - **ExifTool Metadata writer**\ cb2Bib uses [ExifTool](https://exiftool.org/) for writing bibliographic metadata to the attached documents. Select here the ExifTool path name. On Windows, remember renaming `exiftool(-k).exe` to `exiftool.exe` for command line use. See also [Writing Metadata](#metadata_write). ### []{#c2bconf_files} Configuring Files - **Journal Abbreviation List File**\ This file contains a list of journal names equivalences: a capital-letter acronym, standard abbreviated form, and full name of the journal. If an input journal name is recognized, cb2Bib will use the standard abbreviated form for the `journal` bibkey. If your usual journal were not within the distributed, default `abbreviations.txt`, you could edit this file, or point to a personalized abbreviation file. **Note:** Changes in the abbreviation file only take place after reestarting cb2Bib. See [Processing of Journal Names](#journalproc). - **Regular Expression List File**\ The cb2Bib distribution includes the file `regexps.txt` with a few set of rules for reference extraction. This includes most of the scientific literature. Extracting from email alerts or publisher abstract pages is a *volatile* task. Information does not follow a standardized structure. Extraction pattern may then change as often as the web design needs to. Besides, such extraction from the clipboard is system dependent, in a way that produces different formatting of the text copies on different systems. You can use your personalized `regexps.txt` file, for testing, debugging -regular expressions are reloaded each time the automatic recognition engine executes-, and fullfiling your particular extraction needs. - **Bookmarks and Network Query Info File**\ The cb2Bib distribution includes the file `netqinf.txt` that contains bookmarks data, and server related information for bibliographic querying. Note that cb2Bib treats bibliographic queries as generalized net bookmarks. This allows accessing almost any online bibliographic resource. Check this file for implementations details and customization. - **Browser Cascading Style Sheet (CSS)**\ This file contains the style sheet to configure the appearance of the bibliographic references when viewed in browser mode. The cb2Bib distribution includes the `references.css` and `references-dark.css` file as a CSS examples. - **Part Of Speech (POS) Lexicon**\ This box must contain the address to the cb2Bib distribution file `lexicon.pos`. This file contains a set of patterns and related POS information required for indexing documents, i. e., to extract keywords from documents for the c2bCiter module. - **Search In Files Cache Directory**\ Directory containing internal data for Search In Files functionality. If an existing directory is selected cb2Bib will write all internal data on it. If otherwise, cache data will be written on the same directory from where BibTeX are searched. It might be, therefore, convenient to group all this files in a separate directory that does not need to be backup, and that can easily be deleted whenever desired. ### []{#c2bconf_fonts} Configuring Fonts - **Font Selector**\ Selects the main window and editor font family and size. - **Context Colors**\ Doubleclick on context color items to select syntax highlighter font color. Besides syntax highlighting, and to ease manual bibliographic extractions, cb2Bib has the following coloring convention. 'cb2Bib unrelevant text' colors non-word, non-digit, and cb2Bib's internal tags. 'cb2Bib relevant text' refers to the reference's year. 'cb2Bib highly relevant' attempts to guess text sectioning, highlighting 'abstract', 'introduction', and 'keywords'. ### []{#c2bconf_network} Configuring Network - **Use External Network Client**\ cb2Bib manages local and network files in an equivalent manner. Network file retrieving, however, requires sometimes password and/or cookies administration. The KDE desktop incorporates `kfmclient` utility. A command `kfmclient (copy|move|exec) source [destination]` permits copying or moving files, with `kfmclient` taking care of advanced browsing preferences. By checking this box, cb2Bib will use the specified file manger client. - **Use Proxy**\ If checked, cb2Bib will access the network through a proxy host. Set the Host name, the Port, and the proxy Type. A login dialog will appear if the proxy requires authentication. Login data is not stored, it must be entered at each session. - **Perform Network Queries after automatic reference extractions**\ Network queries can be used to complete a partial reference extraction. For instance, provided a reference 'J. Name, 25, 103' and an appropriate pattern to extract it, cb2Bib will attempt to complete the reference automatically. No query is performed if automatic reference extraction was tagged as BibTeX. - **Download document if available**\ If checked, cb2Bib downloads document files to the directory specified in **Rename and Copy/Move document files to Directory**. See also the file `netqinf.txt` for details. Download is scheduled and performed once the reference is accepted, e.g., once it is saved. Note that when document file is local, e.g., when PDFImport or switch `–doc2bib` is used, no document is downloaded. - **Keep Query temporary files (Debug Only)**\ cb2Bib may use up to three temporary files to perform a network query. If this box is checked, the temporary files are not deleted. This facilitates the testing and customization of the information file `netqinf.txt`. ### []{#c2bconf_shortcuts} Configuring Shortcuts - Customizes most key sequences for actions shortcuts. Concretely, cb2Bib specific actions are configurable, but not standard actions such as 'Open', 'Exit', 'Copy', or 'Paste', which are already predefined to the standard, specific key sequences for each platform. Shortcuts are customizable for the cb2Bib main panel, editor, and reference list actions. Single-key shortcuts, i.e., for manual reference extraction and shortcuts in c2bCiter, are non-configurable, since they they closely map non-translatable BibTeX keywords. ### []{#c2bconf_utilities} Configuring Utilities - **To plain text converter**\ Selects the external `some_format_to_text` tool that cb2Bib uses to convert document files prior to reference extraction and searching. cb2Bib executes the line command `converter [options] inputfile tmp_output.txt`, where `[options]` are user defined arguments. As a default, cb2Bib launches `pdf2cb`, a modified PDF to text utility found in the XPDF package. Modifications are available at xpdf/ directory in the cb2Bib sources. Default arguments are `-q -f 1 -l 1` to extract only the first, title page when used within PDFImport, and `-q`, to convert the complete document when used within Search in Files. Appropriate for PDFImport could also be a document metadata extractor. Often metadata contains structured information regarding document authors, title, and source. A simple shell script wrapper could be the following `any2text_search`: ``` {.fragment} #!/bin/csh # Convert documents to text according to filename extension # any2text_search input_fn.ext output_fn.txt set ext = $1:e if ( $ext == 'djvu' ) then /usr/bin/djvutxt "$1" "$2" if ($status) exit 1 else if ( $ext == 'chm' ) then (/usr/local/bin/archmage -c text "$1" "$2") >& /dev/null if ($status) exit 1 else # If using pdf2cb /path/to/pdf2cb -q "$1" "$2" # If using pdftotex # /usr/bin/pdftotext -enc UTF-8 "$1" "$2" if ($status) exit 1 endif ```
[]{#bibsearch}Search BibTeX and PDF Document Files --------------------------------------------------
### []{#descrip} Description {#description} - **Search pattern**\ Patterns and composite patterns can be either [approximate strings](https://arxiv.org/abs/0705.0751), strings, contexts, regular expressions, or wildcard filters. Patterns admit Unicode characters. The scope of each pattern can be the reference as a whole or be focused on a particular reference field. The fields `year`, `file`, and `journal` are treated specifically. The field `year` has the qualifiers `Exact`, `Newer`, and `Older`. The field `file` can optionally refer to either the filename or the contents of such a file. Finally, for `journal`, the input pattern is duplicated to the, if available, journal fullname, and they two are checked against the `journal` actual field contents and, if available, its expanded contents. For example, typing 'ijqc' retrieves all references with `journal` being 'Int. J. Quantum Chem.'. Or, typing 'chemistry' retrieves any of 'J. Math. Chem.', 'J. Phys. Chem.', etc. This expansion is not performed when the pattern scope is set to `all`. - **Search scope**\ By default, searches are performed on the current BibTeX output file. If **Scan all BibTeX files** is checked the search will extend to all BibTeX files, extension .bib, present in the current directory. It might be therefore convenient to group all reference files in one common directory, or have them linked to that directory. When **Scan linked documents** is checked, and one or more pattern scope is `all` or `file`, the contents of the file in `file` is converted to text and scanned for that given pattern. See [Configuring Utilities](#c2bconf_utilities) section to configure the external to text converter. - **Search modifier**\ cb2Bib converts TeX encoded characters to Unicode when parsing the references. This permits, for instance, for the pattern 'Møller' to retrieve either 'Møller' or 'M{\\o}ller', without regard to how the BibTeX reference is written. By checking **Simplify source**, the reference and the converted PDF files are simplified to plain ASCII. In this way, the pattern '\\bMoller\\b' will hit any of 'Møller', 'M{\\o}ller', or 'Moller'. Additionally, all non-word characters are removed, preserving only the ASCII, word structure of the source. Note that source simplification is only performed for the patterns whose scope is `all` or `file` contents, and that and so far, cb2Bib has only a subset of such conversions. Implemented TeX to Unicode conversions can be easily checked by entering a reference. The Unicode to ASCII letter-only conversion, on the other hand, is the one that cb2Bib also uses to write the reference IDs and, hence, the renaming of dropped files. cb2Bib can understand minor sub and superscript formatting. For instance, the pattern 'H2O' will retrieve 'H~2~O' from a BibTeX string `H$_{2}$O`. ### []{#contextsearch} Contextual Search A convenient way to retrieve documents is by matching a set of keywords appearing in a close proximity context, while disregarding the order in which the words might had been written. cb2Bib considers two types of contextual searches. One flexibilizes phrase matching only at the level of the constituting words. It is accessed by selecting `Fixed string: Context` in the pattern type box. The other one, in addition, stems the supplied keywords. It is accessed by selecting `Context`. By way of stemming, the keyword *analyze*, for example, will also match *analyse*, and *aluminum* will match *aluminium* too. The syntax for `Context` type patterns is summarized in the following table: ``` {.fragment} Operator Example Expansion space contextual search contextual AND search | contextual search|matching contextual AND (search|match) + contextual search|+matching contextual AND (search|\bmatching\b) _ contextual_search contextual.{0,25}search - non-parametric non.{0,1}parametr Diacritics and Greek letters: naïve search (naïve|naive) AND search kendall tau kendall AND (tau|τ) ``` In the above examples, operator space `AND` means match words in any order. Operator `_` preserves word order, and operator `+` prevents stemming and forces exact word match. Operator `-` considers cases of words that might had been written either united, hyphenated, or space separated. Diacritics are expanded if the diacritic mark is specified. This is, *naive* will not match *naïve*. On the other hand, Greek letters are expanded only when typed by name. ### []{#notes} Notes - cb2Bib uses an internal cache to speed up the search of linked files. By default data is stored as `current_file.bib.c2b`. It might be more convenient, however, to setup a temporary directory out of the user data backup directories. See **Search In Files Cache Directory** in [Configuring Files](#c2bconf_files). When a linked file is processed for the first time, cb2Bib does several string manipulations, such as removing end of line hyphenations. This process is time consuming for very large files. - The **approximate string** search is described in reference . It reduces the chance of missing a hit due to transcription and decoding errors in the document files. Approximate string is also a form of serendipitous information retrieval.
[]{#commandline}cb2Bib Command Line -----------------------------------
The complete listing of command line uses follows. ``` {style="font-size: xx-small;"} Usage: cb2bib cb2bib [action] [filename1 [filename2 ... ]] [--conf [filename.conf]] Actions: --configure [filename.conf] Edit configuration --bibedit [filename1.bib [filename2.bib ... ]] Edit/browse BibTeX files --citer [filename1.bib [filename2.bib ... ]] Start cb2Bib citer --import tmp_reference_filename Import reference, usually from ad hoc websites --doc2bib fn1.doc [fn2.doc ... ] reference.bib Extract reference from document file --txt2bib fn1.txt [fn2.txt ... ] reference.bib Extract reference from text file --index [bibdirname] Extract keywords from document files --html-annote filename.tex Convert annote file to HTML --view-annote filename.tex Convert and visualize annote file --view-annote filename.tex.html Visualize annote file Switches: --conf [filename.conf] Use configuration file --sloppy Accept guesses in automatic reference extraction Examples: cb2bib Start cb2Bib extraction panel cb2bib --import tmp_reference_filename Import reference cb2bib --bibedit filename.bib Edit BibTeX filename.bib cb2bib --conf Start cb2Bib in USB mode cb2bib --doc2bib *.pdf references.bib Extract references from PDF title pages Notes: -Use switch --conf to particularize specific settings for specific actions. -The file cb2bib.conf must be readable and writable. If it does not exist, cb2Bib will create one based on predefined defaults. -If starting cb2Bib from a removable media, use the command 'cb2bib --conf' without configuration filename. Settings will be read from and written to /cb2bib/full/path/cb2bib.conf, being therefore independent of the mounting address that the host computer will provide. -To import references from a browser select when asked c2bimport, which expands to 'cb2bib --import %f'. The browser will provide the temporary reference filename. -A number of factors influence the reliability of automatic extractions. Consider writing customized regular expressions and network queries, and use metadata when available. Important: -The commands --doc2bib and --txt2bib do not append the references to the references.bib. They create a new file, or silently overwrite it if already exists. ``` - **Note:** On Windows use `c2bconsole` instead of `cb2bib`. See [Release Note cb2Bib 1.3.0](#relnotes130). - **Note:** If using reference extraction command, see [Automatic Extraction: Questions and Answers](#faq_automatic_extraction).
[]{#c2bannote}cb2Bib Annote ---------------------------
The cb2Bib Annote module is named after the BibTeX key `annote`. Annote is not for a 'one reference annotation' though. Instead, Annote is for short notes that interrelate several references. Annote takes a plain text note, with minimal or no markup, inserts the bibliographic citations, and converts it to a HTML page with links to the referenced documents. From within cb2Bib, to write a note, type `Alt+A`, enter a filename, either new or existing, and once in Annote, type `E` to start the editor. Each time you save the document the viewer will be updated. For help on Annote's syntax type `F1`. If cb2Bib was compiled without Annote's Viewer, typing `Alt+A` will start the editor and HTML viewing will be committed to the default web browser. From the command line, typing ``` {.fragment} cb2bib --html-annote annote.tex ``` will produce the HTML file `annote.tex.html`. See also [Configuring Annote](#c2bconf_annote) and [cb2Bib Command Line](#commandline). ### []{#c2bannote_syntax} Annote Syntax The resulting HTML file `annote.tex.html` can be seen at [cb2Bib Annote](https://www.molspaces.com/cb2bib/doc/c2bannote/annote.tex.html). ``` {style="font-size: xx-small;"} % annote.tex %\c2b_bibtex_directory{/home/constans/Documents/BibReferences} %\c2b_makeindex \newcommand{\RR}{\mathbb{R}} \newcommand{\mnial}[3]{(#1 - #2)^#3} \title{cb2Bib Annote} \begin{abstract} This documents describes cb2Bib Annote. It succinctly lists Annote's minimalists syntax. \end{abstract} \section{cb2Bib Directives} \subsection{Make Index} \begin{verbatim} %\c2b_makeindex \end{verbatim} \subsection{BibTeX Directory} \begin{verbatim} %\c2b_bibtex_directory{/home/constans/Documents/BibReferences} \end{verbatim} \section{Simple Markup} \subsection{Uniform Resource Locator} \begin{verbatim} - URL: https://www.molspaces.com/cb2bib/doc/c2bannote/ - Named URL: https://www.molspaces.com/cb2bib/doc/c2bannote/[cb2Bib Annote] - On a blank window: _https://www.molspaces.com/cb2bib/doc/c2bannote/[cb2Bib Annote] \end{verbatim} \subsubsection{Example} - URL: https://www.molspaces.com/cb2bib/doc/c2bannote/ - Named URL: https://www.molspaces.com/cb2bib/doc/c2bannote/[cb2Bib Annote] - On a blank window: _https://www.molspaces.com/cb2bib/doc/c2bannote/[cb2Bib Annote] \subsection{Bibliographic Citations} \begin{verbatim} \cite {key} \end{verbatim} \subsubsection{Example} Citing cb2Bib \cite{cb2bib_key}. \section{LaTeX Markup} \subsection{Document Sections} \begin{verbatim} \title{Title string} \end{verbatim} \begin{verbatim} \section{Section string} \end{verbatim} \begin{verbatim} \subsection{Section string} \end{verbatim} \begin{verbatim} \subsubsection{Section string} \end{verbatim} \subsection{Document Environments} \begin{verbatim} % env = abstract, equation, itemize, and verbatim \begin{env} \end{env} \end{verbatim} - Note. equation rendering requires MathJax \cite{jsmath_key, mathjax_key} \subsubsection{Examples} \begin{verbatim} \begin{itemize} \item Description 1 \item Description 2 \end{itemize} \end{verbatim} \begin{itemize} \item Description 1 \item Description 2 \end{itemize} \begin{verbatim} \begin{equation} \int_D ({\nabla\cdot} F)dV=\int_{\partial D} F\cdot ndS \end{equation} \end{verbatim} \begin{equation} \int_D ({\nabla\cdot} F)dV=\int_{\partial D} F\cdot ndS \end{equation} \subsection{Mathematical Macros} \begin{verbatim} \newcommand{name}[number of arguments]{definition} \end{verbatim} \subsubsection{Example} \begin{verbatim} \newcommand{\RR}{\mathbb{R}} \newcommand{\mnial}[3]{(#1 - #2)^#3} ... a subset of $\RR$ values ... ... the monomial is $\mnial{a}{x}{2} > 0$ for $x \ne 0$, and $\mnial{a}{x}{3} \mnial{c}{x}{3}$ for $x < a \land x < c$ or $x > a \land x > c$ ... \end{verbatim} ... a subset of $\RR$ values ... ... the monomial is $\mnial{a}{x}{2} > 0$ for $x \ne 0$, and $\mnial{a}{x}{3} \mnial{c}{x}{3}$ for $x < a \land x < c$ or $x > a \land x > c$ ... \section{MathJax Example} \begin{verbatim} % Example from https://www.mathjax.org/#demo When $a \ne 0$, there are two solutions to \(ax^2 + bx + c = 0\) and they are $$x = {-b \pm \sqrt{b^2-4ac} \over 2a}.$$ \end{verbatim} When $a \ne 0$, there are two solutions to \(ax^2 + bx + c = 0\) and they are $$x = {-b \pm \sqrt{b^2-4ac} \over 2a}.$$ ```
[]{#c2bciter}cb2Bib Citer -------------------------
The cb2Bib Citer is a keyboard based module for inserting citation IDs into a working document. Conveniently, the command `c2bciter`, or its expansion `cb2bib –citer`, can be assigned to a global, desktop wide shortcut key. This will provide an easy access to the citer from within any text editor. Pressing the shortcut turns on and off the citer panel. Once appropriate references are selected, pressing key C sets the citations either to the clipboard or to a LyX pipe, closes the citer panel, and returns keyboard focus to the editor. By default, `c2bciter` loads all references from the current directory, specified in the cb2Bib main panel. On the desktop tray, the cb2Bib icon indicates that the citer is running. Its context menu offers the possibility to load other files or directories, or to toggle full screen mode. Search, filtering, navigation, and citation are keyword based. Pressing keys A, I, J, T, and Y sorts the references by author, included date, journal, title, and year, respectively. Key F initiates filtering, and Esc leaves filtering mode. References are selected when pressing enter. Key S toggles the current selection display, and Del clears the selection. The combination Shift + letter navigates through the rows starting by the letter. Advanced filtering capabilities are available after indexing the documents. Document indexing, or term or key sentence extraction, is performed by clicking the tray icon menu action Index Documents. Once indexing is done and after clicking Refresh, pressing K displays the document extracted keywords, and pressing G, the collection glossary of terms. On a keyword, pressing R display all documents indexed by the keyword. On a document, pressing R display related documents. Relatedness is set from keyword based similarity measures. Key sequence Alt+C toggles clipboard connection on and off. When connection is on, the clipboard contents is set, each time it changes, as the filter string. This provides a fast way to retrieve a given reference while browsing elsewhere. ``` {.fragment} Usage: cb2bib --citer [dirname1 [dirname2 ... ]] cb2bib --citer [filename1.bib [filename2.bib ... ]] ``` ``` {.fragment} Display Keys A author - journal - year - title I included date - title J journal - year - author T title Y year - author - journal - title ``` ``` {.fragment} Filter Keys D Delete last filter F Enter pattern filter mode G Toggle glossary of terms view K Toggle document keywords view R Display related documents Left Move to previous filtered view Right Move to next filtered view ``` ``` {.fragment} Action Keys C Cite selected citations and close citer window Del Unselect all citations E Edit current citation's source Enter Select current citation Esc Exit filter mode or close citer window O Open current citation's file S Display the set of selected citations V Display document excerpts in keywords view Shift+ Keyboard search naviagation U Open current citation's URL W Write notes using Annote ``` ``` {.fragment} Tray Icon Actions F1 Citer help Ctrl+O Open BibTeX directory Alt+O Open BibTeX files F5 Refresh Ctrl+F Search in files Alt+L Set Lyx pipe F2 Toggle cb2Bib Alt+C Toggle clipboard Alt+F Toggle full screen Index documents ``` See also [Release Note cb2Bib 1.3.0](#relnotes130), [Release Note cb2Bib 1.4.0](#relnotes140), [Release Note cb2Bib 1.4.7](#relnotes147), [cb2Bib Command Line](#commandline) and [cb2Bib Annote](#c2bannote).
[]{#examples}Examples ---------------------
This set of examples considers only simple cases of predifined bibliographic formats, which at present are most frequent on the Web. For complex cases that would require *ad hoc* regular expressions, see the cb2Bib's [Advanced Features](#detail). To test the examples, launch cb2Bib, and select the text within the boxes (type also Ctrl-C if running cb2Bib on a Windows machine). cb2Bib will extract the selected reference. ### []{#example_patterns} Predefined Formats - [BibTeX](#ex_bibtex) - [ISI Reference Format](#ex_isi_format) - [RIS Reference Format](#ex_ris) #### []{#ex_bibtex} BibTeX ``` {.fragment} @article{Efron, title = {{The Estimation of Prediction Error}}, author = {Bradley Efron}, journal = {Journal of the American Statistical Association}, pages = {619 - 632}, volume = {99}, number = {467}, year = {2004}, } ``` Nowadays most authors and publishers websites export references to BibTeX format. This is the safest way to retrieve a reference with cb2Bib. Select from `@article` to the last `}`. cb2Bib imports the reference. Once imported, cb2Bib permits adding the abstract, keywords or renaming and relocating the document file. #### []{#ex_isi_format} ISI Reference Format ``` {.fragment} PT Journal AU Kohn, W AU Becke, AD AU Parr, RG TI Density functional theory of electronic structure SO JOURNAL OF PHYSICAL CHEMISTRY BP 12974 EP 12980 PG 7 JI J. Phys. Chem. PY 1996 PD AUG 1 VL 100 IS 31 J9 J PHYS CHEM ER ``` Example provided for testing `isi2bib` external preparsing script. See [Configuring Clipboard](#c2bconf_clipboard) for the setup details. #### []{#ex_ris} RIS Reference Format ``` {.fragment} TY - JOUR AU - A. J. Coleman PY - 1963 TI - Structure of fermion density matrices JO - Rev. Mod. Phys. SP - 668 VL - 35 ER - ``` Example provided for testing `ris2bib` external preparsing script. See [Configuring Clipboard](#c2bconf_clipboard) for the setup details.
[]{#toc-additional-features}Additional Features ----------------------------------------------- ### []{#bibeditor}Embedded File Editor
cb2Bib contains a practical editor suitable to manipulate the files related to a cb2Bib session. Abbreviations, bookmarks, regular expressions, and BibTeX are readily available. On BibTeX mode, the editor contains a Reference List to ease file navigation, and to extend the editor functionality. The BibTeX editor can optionally be turned to a reference browser. #### []{#bookmarks} Bookmarks Bookmarks pointing to local or network files are available at the editor menu bar. They provide a fast access to external resources. Concretely, they are suitable for retrieving working documents, writing notes, or for accessing internet databases. The editor bookmark functionality had been introduced in the cb2Bib version 0.9.3. Currently, bookmarks are set manually in the `netqinf.txt` file, see [Configuring Files](#c2bconf_files). Each bookmark is an entry line with the form ``` {.fragment} editorbookmark=Description|Target file name|Shortcut|Icon file name ``` having four fields, description, target file name, shortcut, and icon file name, separated with three (required) vertical bars |. ``` {.fragment} # Bookmark Examples: # - A URL: editorbookmark=URL Description|https://www.molspaces.com/cb2bib/doc/bibeditor/|| # - A separator, which is a blank line: editorbookmark= # - A TeX document, which will be opened with its default application: editorbookmark=Document Description|/home/doc/chapter1.tex|| ``` #### []{#update_metadata} Update Documents Metadata The Update Documents Metadata functionality is available at the Edit and context menus on the BibTeX editor mode. Documents referred in the BibTeX file tags are scanned for metadata. If the BibTeX reference does not coincide with the bibliographic metadata, the document metadata is updated. In this way, metadata is synchronized with the BibTeX file contents. A log window appears, and possible errors are reported. Reported errors are, non-existence of a document file, read-only files, mismatches between BibTeX references and the actual metadata (often due to HTML tags or other illegal characters in BibTeX), or that the writing to the document format is not implemented. Note that this process will update all documents referenced in the BibTeX file. **While this process is safe, it implies writing into the documents.** Therefore take the usual measures and backup your data. See also [Writing Metadata](#metadata_write). #### []{#export_entries} Export Selected Entries Selected entries can be exported to a separate BibTeX document. Click on `File->Export Entries` menu option, and provide an export filename at the Export Dialog. Optionally, export will copy the document files attached to the citation. The copy of documents is similar to the cb2Bib 'rename/copy/move' general procedure. See [Configuring Documents](#c2bconf_documents), on **Set directory relative to the BibTeX File Directory**, for copying options. Documents will not be overwritten: copying of existing documents is skipped. Possible issues are reported in the new document, as LaTeX comments. #### []{#c2beditor_menu} Right-Click Menu Functionality Default Key Action ------------- ---------------------------------------- Ctrl+F Find in text Toggle word wrapping Selection to LaTeX Selection to Unicode Journals to full name Journals to alternate full name Journals to abbreviated name Journals to alternate abbreviated name Update documents metadata Shift+Ins Paste current BibTeX Alt+P Save and postprocess BibTeX file #### []{#references_menu} Reference List Right-Click Menu Functionality Default Key Action ------------- -------------------------- Alt+C Cite selected entries Open document file Browse by DOI Web search by Author Web search by Title Web search settings Clear entry selection Refresh list and browser #### []{#browser_menu} BibTeX Browser Right-Click Menu Functionality Default Key Action ------------- -------------------------------- Alt+C Cite selected entries Local search for selected text Web search for selected text Web search settings Clear entry selection Refresh list and browser #### []{#c2beditor_qt} Additional Functionality ----------------- ---------------------------------------------------------- Backspace Deletes the character to the left of the cursor Delete Deletes the character to the right of the cursor Ctrl+A Selects all text Ctrl+C Copy the selected text to the clipboard Ctrl+Insert Copy the selected text to the clipboard Ctrl+K Deletes to the end of the line Ctrl+V Pastes the clipboard text into text edit Shift+Insert Pastes the clipboard text into text edit Ctrl+X Deletes the selected text and copies it to the clipboard Shift+Delete Deletes the selected text and copies it to the clipboard Ctrl+Z Undoes the last operation Ctrl+Y Redoes the last operation LeftArrow Moves the cursor one character to the left Ctrl+LeftArrow Moves the cursor one word to the left RightArrow Moves the cursor one character to the right Ctrl+RightArrow Moves the cursor one word to the right UpArrow Moves the cursor one line up Ctrl+UpArrow Moves the cursor one word up DownArrow Moves the cursor one line down Ctrl+Down Arrow Moves the cursor one word down PageUp Moves the cursor one page up PageDown Moves the cursor one page down Home Moves the cursor to the beginning of the line Ctrl+Home Moves the cursor to the beginning of the text End Moves the cursor to the end of the line Ctrl+End Moves the cursor to the end of the text Alt+Wheel Scrolls the page horizontally Ctrl+Wheel Zooms the text ----------------- ----------------------------------------------------------
### []{#predefinedplaceholders}Predefined Placeholders
#### []{#idplaceholders} Cite and Document ID Placeholders - `<>` Takes first three letters of the last word of all authors's last name in cite, and converts to lowercase. - `<>` Takes capitalized initials of all authors in cite. - `<>` Takes first author last name. - `<>` Takes first author last name in lowercase. - `<>` This placeholder is meant to be used **alone, and only for document IDs**. It takes the pattern defined for the cite ID. If the cite ID is modified manually, the document ID is synchronized automatically. - `<>` Takes capitalized initials of journal name. - `<>` First page. - `<>` First page, written as, e. g., 'p125'. - `<>` Title. To truncate titles exceeding a maximum length `l` use `<<title_l>>`, where `l` stands for an integer value. - `<<title_underscored>>` Title with blanks set to underscores. To truncate title to `l` characters use `<<title_underscored_l>>`. - `<<title_first_word>>` First word in title, in lowercase. - `<<volume>>` Volume number. - `<<year_abbreviated>>` Last two digits from year. - `<<year_full>>` All digits from year. **Note:** If `author` is empty, `editor` will be considered instead. On conference proceedings or monographs this situation is usual. Similarly, if `title` is empty, `booktitle` is considered. **Note:** Only one placeholder of a given field, e. g. `<<author_first>>` or `<<author_all_initials>>`, should be used to compose the ID patterns. cb2Bib only performs one substitution per field placeholder. **Note:** cb2Bib performs a series of string manipulations, such as stripping diacritics and ligatures, aimed to provide ID values suitable for BibTeX keys and platform independent filenames. Currently only ASCII characters are considered. #### []{#citeplaceholders} Cite Command Placeholders - `<<citeid>>` The `citeid` placeholder replicates the pattern for each citation in the selected citation list. For example, the pattern `\citenum{<<citeid>>}` expands to `\citenum{cid1} \citenum{cid2} ... ` - `<<prefix|citeids|separator>>` The `citeids` placeholder replaces the selected citation list by prepending `prefix` and appending `separator` within the pattern. For example, the markdown pattern `[<<@|citeids|;>>]` expands to `[@cid1; @cid2; ...]`, and the LaTeX pattern `\citeauthor{<<|citeids|,>>}` expands to `\citeauthor{cid1, cid2, ...}`. **Note:** For additional information on cite commands see [LaTeX Bibliography Management](https://en.wikibooks.org/wiki/LaTeX/Bibliography_Management) and [Pandoc User's Guide](https://pandoc.org/MANUAL.html#citations). </div> </div> ### []{#entrytype}BiBTeX Entry Types Available as cb2Bib Fields <div class="contents"> <div class="textblock"> cb2Bib includes nearly all standard and extended BibTeX fields. The complete list is as follows. The field descriptions are taken from [The BibTeX Format](http://www.fb10.uni-bremen.de/anglistik/langpro/bibliographies/jacobsen-bibtex.html) written by Dana Jacobsen. #### []{#main-fields}Main Fields `abstract` An abstract of the work. `author` The name(s) of the author(s), in the format described in the LaTeX book. `file` Usually, the PDF filename of the work. `journal` A journal name. Abbreviations are provided for many journals. `keywords` Key words used for searching or possibly for annotation. `pages` One or more page numbers or range of numbers, such as `42--111` or `7,41,73--97` or `43+` (the \``+`' in this last example indicates pages following that don't form a simple range). To make it easier to maintain Scribe-compatible databases, the standard styles convert a single dash (as in `7-33`) to the double dash used in TeX to denote number ranges (as in `7--33`). `title` The work's title, typed as explained in the LaTeX book. `volume` The volume of a journal or multi-volume book. `number` The number of a journal, magazine, technical report, or of a work in a series. An issue of a journal or magazine is usually identified by its volume and number; the organization that issues a technical report usually gives it a number; and sometimes books are given numbers in a named series. `year` The year of publication or, for an unpublished work, the year it was written. Generally it should consist of four numerals, such as `1984`, although the standard styles can handle any `year` whose last four nonpunctuation characters are numerals, such as `\hbox{(about 1984)}`. #### []{#other-fields}Other Fields `address` Usually the address of the `publisher` or other type of institution. For major publishing houses, van Leunen recommends omitting the information entirely. For small publishers, on the other hand, you can help the reader by giving the complete address. `annote` An annotation. It is not used by the standard bibliography styles, but may be used by others that produce an annotated bibliography. `booktitle` Title of a book, part of which is being cited. See the LaTeX book for how to type titles. For book entries, use the `title` field instead. `chapter` A chapter (or section or whatever) number. `doi` The Digital Object Identifier is a unique string created to identify a piece of intellectual property in an online environment. `edition` The edition of a book---for example, \`\`Second''. This should be an ordinal, and should have the first letter capitalized, as shown here; the standard styles convert to lower case when necessary. `editor` Name(s) of editor(s), typed as indicated in the LaTeX book. If there is also an `author` field, then the `editor` field gives the editor of the book or collection in which the reference appears. `eprint` Electronic document file. `institution` The sponsoring institution of a technical report. `ISBN` The International Standard Book Number. `ISSN` The International Standard Serial Number. Used to identify a journal. `month` The month in which the work was published or, for an unpublished work, in which it was written. You should use the standard three-letter abbreviation, as described in Appendix B.1.3 of the LaTeX book. `note` Any additional information that can help the reader. The first word should be capitalized. `organization` The organization that sponsors a conference or that publishes a `manual`. `publisher` The publisher's name. `school` The name of the school where a thesis was written. `series` The name of a series or set of books. When citing an entire book, the the `title` field gives its title and an optional `series` field gives the name of a series or multi-volume set in which the book is published. `URL` The WWW Universal Resource Locator that points to the item being referenced. This often is used for technical reports to point to the ftp site where the postscript source of the report is located. </div> </div> ### []{#metadata}Reading and Writing Bibliographic Metadata <div class="contents"> <div class="textblock"> #### []{#metadata_read} Reading Metadata Metadata in scientific documents had been rarely appreciated and used for decades. For bibliographic metadata, no format specification had been widely accepted. cb2Bib adapted back in 2008 the PDF predefined metadata capabilities to set BibTeX bibliographic keys in document files. cb2Bib reads all XMP (a specific XML standard devised for metadata storage) packets found in the document. It then parses the XML strings looking for nodes and attributes with key names meaningful to bibliographic references. If a given bibliographic field is found in multiple packets, cb2Bib will take the last one, which most often, and according to the PDF specs, is the most updated one. The fields `file`, which would be the document itself, and `pages`, which is usually the actual number of pages, are skipped. The metadata is then summarized in cb2Bib clipboard panel as, for instance ``` {.fragment} [Bibliographic Metadata <title>arXiv:0705.0751v1 [cs.IR] 5 May 2007 /Bibliographic Metadata] ``` This data, whenever the user considers it to be correct, can be easily imported by the build-in 'Heuristic Guess' capability. On the other hand, if keys are found with the prefix `bibtex`, cb2Bib will assume the document does contain bibliographic metadata, and it will only consider the keys having this prefix. Assuming therefore that metadata is bibliographic, cb2Bib will automatically import the reference. This way, if using PDFImport, BibTeX-aware documents will be processed as successfully recognized, without requiring any user supplied regular expression. See also [Release Note cb2Bib 1.0.0](#relnotes100), [Configuring Clipboard](#c2bconf_clipboard), and [PDF Reference Import](#pdfimport). #### []{#metadata_write} Writing Metadata Once an extracted reference is saved and there is a document attached to it, cb2Bib will optionally insert the bibliographic metadata into the document itself. cb2Bib writes an XMP packet as, for instance ``` {.fragment} P. Constans arXiv 0705.0751 Approximate textual retrieval article 2007 ``` The BibTeX fields `file` and `id` are skip from writing. The former for the reason mentioned above, and the latter because it is easily generated by specialized BibTeX software according to each user preferences. LaTeX escaped characters for non ASCII letters are converted to UTF-8, as XMP already specifies this codec. The actual writing of the packet into the document is performed by ExifTool, an excellent Perl program written by Phil Harvey. See [https://exiftool.org](https://exiftool.org/). ExifTool supports several document formats for writing. The most relevant here are Postscript and PDF. For PDF documents, metadata is written as an incremental update of the document. This exactly preserves the binary structure of the document, and changes can be easily reversed or modified if so desired. Whenever ExifTool is unable to insert metadata, e.g., because the document format is not supported or it has structural errors, cb2Bib will issue an information message, and the document will remain untouched. See also [Configuring Documents](#c2bconf_documents) and [Update Documents Metadata](#update_metadata).
### []{#pdfimport}PDF Reference Import
#### []{#intro_automatic_extraction} Introduction Articles in PDF or other formats that can be converted to plain text can be processed and indexed by cb2Bib. Files can be selected using the Select Files button, or dragging them from the desktop or the file manager to the PDFImport dialog panel. Files are converted to plain text by using any external translation tool or script. This tool, and optionally its parameters, are set in the cb2Bib configure dialog. See the [Configuring Utilities](#c2bconf_utilities) section for details. Once the file is converted, the text, and optionally, the preparsed metadata, is sent to cb2Bib for reference recognition. This is the usual, two step process. First, text is optionally preprocessed, using a simple set of rules and/or any external script.or tool. See [Configuring Clipboard](#c2bconf_clipboard). Second, text is processed for reference extraction. cb2Bib so far uses two methods. One considers the text as a full pattern, which is checked against the user's set of regular expressions. The better designed are these rules, the best and most reliable will be the extraction. The second method, used when no regular expression matches the text, considers instead a set of predefined subpatterns. See [Field Recognition Rules](#heuristics). At this point users can interact and supervise their references, right before saving them. Allowing user intervention is and has been a design goal in cb2Bib. Therefore, at this point, cb2Bib helps users to check their references. Poorly translated characters, accented letters, 'forgotten' words, or some minor formatting in the titles might be worth considering. See [Glyph & Cog's Text Extraction](https://www.glyphandcog.com/textext.html) for a description on the intricacies of PDF to text conversions. In addition, if too few fields were extracted, one might perform a network query. Say, only the DOI was catch, then there are chances that such a query will fill the remaining fields. The references are saved from the cb2Bib main panel. Once Save is pressed, and depending on the configuration, see [Configuring Documents](#c2bconf_documents), the document file will be either renamed, copied, moved or simply linked onto the `file` field of the reference. If **Insert BibTeX metadata to document files** is checked, the current reference will also be inserted into the document itself. When several files are going to be indexed, the sequence can be as follows: - **Process next after saving**\ Once files are load and Process is pressed, the PDFImport dialog can be minimized (but not closed) for convenience. All required operations to completely fill the desired fields (e.g. dynamic bookmarks, open DOI, etc, which might be required if the data in document is not complete) are at this point accessible from the main panel. The link in the `file` field **will be permanent**, without regard to which operations (e.g. clipboard copying) are needed, until the reference is saved. The source file can be open at any time by right clicking the `file` line edit. Once the reference is saved, the next file will be automatically processed. To skip a given document file from saving its reference, press the Process button. - **Unsupervised processing**\ In this operation mode, all files will be sequentially processed, following the chosen steps and rules. **If the processes is successful**, the reference is automatically saved, and the next file is processed. **If it is not**, the file is skipped and no reference is saved. While processing, the clipboard is disabled for safety. Once finished, this box is unchecked, to avoid a possible accidental saving of a void reference. Network queries that require intervention, i.e., whose result is launching a given page, are skipped. The processes follows until all files are processed. However, it will stop to avoid a file being overwritten, as a result of a repeated key. In this case, it will resume after manual renaming and saving. See also [cb2Bib Command Line](#commandline), commands `–txt2bib` and `–doc2bib`. #### []{#faq_automatic_extraction} Automatic Extraction: Questions and Answers - **When does cb2Bib do automatic extractions?**\ cb2Bib is conceived as a lightweight tool to extract references and manage bibliographies in a simple, fast, and accurate way. Accuracy is better achieved in semi-automatic extractions. Such extractions are handy, and allow user intervention and verification. However, in cases where one has accumulated a large number of unindexed documents, automatic processing can be convenient. cb2Bib does automatic extraction when, in PDFImport mode, 'Unsupervised processing' is checked, or, in command line mode, when typing `cb2bib –doc2bib *.pdf tmp_references.bib`, or, on Windows, `c2bconsole.exe` instead of `cb2bib`. - **Are PDFImport and command line modes equivalent?**\ Yes. There are, however, two minor differences. First, PDFImport adds each reference to the current BibTeX file, as this behavior is the normal one in cb2Bib. On the other hand, command line mode will, instead, overwrite `tmp_references.bib` if it exists, as this is the expected behavior for almost all command line tools. Second, as for now, command line mode does not follow the configuration option 'Check Repeated On Save'. - **How do I do automatic extraction?**\ To test and learn about automatic extractions, the cb2Bib distribution includes a set of four PDF files that mimic a paper title page. For these files, distribution also includes a regular expression, in file `regexps.txt`, capable of extracting the reference fields, provided the `pdftotex` flags are set to their default values. Processing these files, should, therefore, be automatic, and four messages stating `Processed as 'PDF Import Example'` should be seen in the logs. Note that extractions are configurable. A reading of [Configuration](#configuration) will provide additional, useful information. - **Why some entries are not saved and files not renamed?**\ Once you move from the fabricated examples to real cases, you will realize that some of the files, while being processed, are not renamed and their corresponding BibTeX data is not written. For each document file, cb2Bib converts its first page to text, and from this text it attempts to extract the bibliographic reference. By design, when extraction fails, cb2Bib does nothing: no file is moved, no BibTeX is written. This way, you know that the remaining files in the origin directory need special, manual attention. **Extractions are seen as failed, unless reliable data is found in the text**. - **What is *reliable data*?**\ Note that computer processing of natural texts, as extracting the bibliographic data from a title page, is nowadays an approximated procedure. cb2Bib tries several strategies: **1)** allow for including user regular expressions very specific to the extraction at hand, **2)** use metadata if available, **3)** guess what is reasonable, and, based on this, make customized queries. Then, cb2Bib considers extracted **data is reliable if i)** data comes from a match to an user supplied regular expression **ii)** document contains BibTeX metadata, or **iii)** a guess is transformed through a query to formatted bibliographic data. As formatted bibliographic data, cb2Bib understands BibTeX, PubMed XML, arXiv XML, and CR JSON data. In addition, it allows external processing if needed. Other data, metadata, guesses, and guesses on query results are considered unreliable data. - **Is metadata reliable data?**\ No. Only author, title, and keywords in standard PDF metadata can be mapped to their corresponding bibliographic fields. Furthermore, publishers most often misuse these three keys, placing, for instance, DOI in title, or setting author to, perhaps, the document typesetter. Only BibTeX XMP metadata is considered reliable. If you consider that a set of PDF files does contain reliable data, you may force to accept it using the command line switch `–sloppy` together with `–doc2bib`. - **How successful is automatic extraction?**\ As it follows from the given definition of reliable data, running automatic extractions without adhoc `regexps.txt` and `netqinf.txt` files will certainly give a zero success ratio. In practice, scenario 3) often applies: cb2Bib guesses several fields, and, based on the out-of-the-box `netqinf.txt` file, it obtains from the web either BibTeX, PubMed XML, arXiv XML, or CR JSON data. - **What can I do to increase success ratio?**\ First, set your favorite journals in file `abbreviations.txt`. Besides increasing the chances of journal name recognition, it will provide consistency across your BibTeX database. In general, do not write regular expressions to extract directly from the PDF text. Conversion is often poor. Special characters often break lines, thus breaking your regular expressions too. Write customized queries instead. For instance, if your PDFs have DOI in title page, set the simple query ``` {.fragment} journal=The Journal of Everything| query=https://dx.doi.org/<> capture_from_query= referenceurl_prefix= referenceurl_sufix= pdfurl_prefix= pdfurl_sufix= action=htm2txt_query ``` then, if it is feasible to extract the reference from the document's web page using a regular expression, include it in file `regexps.txt`. Note that querying in cb2Bib had been designed having in mind minority fields of research, for which, established databases might not be available. If cb2Bib failed to make reasonable guesses, then, you might consider writing very simple regular expressions to extract directly from the PDF text. For instance, obtain title only. Then, the posterior query step can provide the remaining information. Note also, especially for old documents, journal name is often missing from the paper title page. If in need of processing a series of those papers, consider using a simple script, that, in the cb2Bib preprocessing step, adds this missing information. - **Does successful extraction mean accurate extraction?**\ No. An extraction is successful if reliable data, as defined above, is found in the text, in the metadata, or in the text returned by a query. Reference accuracy relies on whether or not user regular expressions are robust, BibTeX metadata is correct, a guess is appropriate, a set of queries can correct a partially incorrect guess, and the text returned by a query is accurate. In general, well designed sets of regular expressions are accurate. Publisher's abstract pages and PubMed are accurate. But, some publishers are still using images for non-ASCII characters, and PubMed algorithms may drop author middle names if a given author has 'too many names'. Expect convenience over accuracy on other sources. - **Can I use cb2Bib to extract comma separated value CSV references?**\ Yes. To automatically import multiple CSV references you will need one regular expression. If you can control CSV export, choose | as separator, since comma might be used, for instance, in titles. The regular expression for ``` {.fragment} AuthName1, AuthName2 | Title | 2010 ``` will simply be ``` {.fragment} author title year ^([^|]*)\|([^|]*)\|([^|]*)$ ``` The reference file `references.csv` can then be split to single-line files typing ``` {.fragment} split -l 1 references.csv slineref ``` and the command ``` {.fragment} cb2bib --txt2bib slineref* references.bib rm -f slineref* ``` will convert `references.csv` to BibTeX file `references.bib`
### []{#clipboard}Extracting Data from the Clipboard
Clipboard contents is processed according to the following rules: - Perform external, user-defined preparsing on input stream. See [Configuring Clipboard](#c2bconf_clipboard). - Perform user-defined substitutions on input stream. See [Configuring Clipboard](#c2bconf_clipboard). - Check if input stream is already a BibTeX entry. If so, process entry. - Check if input stream is, in this order of preference, a PubMed XML, arXiv XML, CR JSON, or Medline entry. If so, process entry. - Preprocess author names: PI JOAN III -> Pi III, J. (care of name prefixes, suffixes, and removal of ambiguities). If otherwise, - Extract DOI\ (DOI, URL and FILE/PDF are preprocessed, performed before the automatic recognition takes place.) - Extract URL - Remove leading and trailing white spaces, TABs and CRs. - "\\r\\n", "\\n" and/or "\\r" replaced by the line indicator tag ``. - Replace "\\t" and ten or more consecutive "\\s" by the tabular tag ``. - Simplify white spaces - Start the automatic recognition engine. If the automatic recognition engine fails, optionally, a heuristic guessing will be performed. See also [Field Recognition Rules](#heuristics) and [Reading and Writing Bibliographic Metadata](#metadata).
### []{#authorproc}Processing of Author Names
cb2Bib automatically processes the author names string. It uses a set of heuristic rules. First, the authors separator is identified. And second, it is decided whether or not author names are in natural or reverse order, or in the 'Abcd, E., F. Ghij, ...' mixed order. Cleanup author string: - Escape BibTeX to Unicode - Remove digits from authors string - Remove any character except `-',;&\.\s\w` - Simplify white spaces - Consider composing prefixes `(da|de|dal|del|der|di|do|du|dos|el|la|le|lo|van|vande|von|zur)` - Consider composing suffixes `(II|III|IV|Jr)` - Some publishers use superscripts to refer to multiple author affiliations. Text clipboard copying loses superscript formatting. Author strings are clean from 'orphan' lowcase, single letters in a preprocessing step. Everything following the pattern **\[a-z\]** is removed. Fortunately, abbreviated initials are most normally input as uppercase letters, thus permitting a correct superscript clean up.\ *Caution:* Lowcase, single, a to z letters are removed from author's string.\ *Caution:* Supperscripts **will be added to author Last Name** if no separation is provided. Users should care about it and correct these cases. Rules to identify separators: - Contains comma and semicolon -> ';' - Contains pattern `'^Abcd, E.-F.,'` -> ',' - Contains pattern `'^Abcd,'` -> 'and' - Contains comma -> ',' - Contains semicolon -> ';' - Any other -> 'and' Rules to identify ordering: - Contains comma and semicolon -> Reverse - Pattern `'^Abcd,'` -> Reverse - Pattern `'^Abcd EF Ghi'` -> Natural - Pattern `'^Abcd EF'` -> Reverse - Pattern `'^Abcd E.F.'` -> Reverse - Any other pattern -> Natural
### []{#journalproc}Processing of Journal Names
cb2Bib processes journal names according to its editable database, stored at `abbreviations.txt`. This file contains a list of journal names equivalences: a capital-letter acronym, the abbreviated form, and the title of the journal, all three on one single line. The `abbreviations.txt` file has the following structure: ``` {.fragment} JA|J. Abbrev.|Journal of Abbreviations AN|Am. Nat.=Amer. Naturalist|American Naturalist=The American Naturalist ``` The first field, the capital-letter acronym, is a user-defined shorthand to access a journal title by typing it at the extraction panel. The second field is the abbreviated form of the journal. To adapt to multiple abbreviations in use, cb2Bib allows one alternate version of the abbreviation, indicated with an equal sign `=`. In the above example, the ISO 4 abbreviation 'Am. Nat.' is the primary one and 'Amer. Naturalist' is the alternate one. Finally, the third field is the full title of the journal. As for the abbreviations, the full title also admits one alternate form. Abbreviated and full title alternates serve two purposes: journal recognition and citation styling. The former is performed internally by cb2Bib as part of a bibliographic reference extraction, and the latter is accomplished in the embedded BibTeX editor by replacing back and forth abbreviated-full forms, in order to set journals in accordance to the guidelines of a particular publication. Journal names processing is performed whenever a string is recognized as 'journal', and, additionally, when pressing `Intro Key` at the journal edit line. - Retrieves Journal name in **abbreviated form** if found. - If Journal name is not found in the database, returns input Journal name. - Search is case insensitive. - **Warning:** Journal codes can be duplicated. If duplicated, returns input Journal name. - Retrieves Journal name in **full form** if found. - If Journal name is not found in the database, returns input Journal name. - Search is case insensitive. - **Warning:** Journal codes can be duplicated. If duplicated, returns input Journal name. See [Configuring Files](#c2bconf_files), [Configuring BibTeX](#c2bconf_bibtex), and [Right-Click Menu Functionality](#c2beditor_menu).
### []{#heuristics}Field Recognition Rules
- **Abstract** - If `Abstract ` is found. - If `Summary ` is found. - **Author** - Check capitalization patterns. See [A Simple Extraction Procedure for Bibliographical Author Field](https://arxiv.org/abs/0902.0755). - **Keywords** - If `Key\s{0,1}words ` is found. - **Volume** - If `Volume:{0,1}` is found. - If `Vol.{0,1}` is found. - If `\b(\d+)[,:]\s*\d+\W+\d+` is found. - If `\b(\d+)\s*\(\d+\)` is found. - If `\b(\d+)[,:]\s*\d+\b` is found. - **Number** - If `Numbers{0,1}:{0,1}\s*([\d-]+)` is found. - If `No\.{0,1}\s*(\d+)` is found. - If `Issue\:{0,1}\s*(\d+)` is found. - If `\d\s*\((\d+)\)[^\.]` is found. - **Pages** - If `\bPages{0,1}[:\.]{0,1}([\d\s-]+)` is found. - If `\bp{1,2}\.{0,1}\s+(\d+)` is found. - If `\b(\d+)\s*-{1,2}\s*(\d+pp)\b` is found. - If `\b(\d+)\s*-{1,2}\s*(\d+)\b` is found. - **Year** - If `\b(19|20)(\d\d)\b` is found. - **Title** - If `\bTitle:{0,1}` is found. - **ISBN** - If `\bISBN\b(?:-\d+){0,1}:{0,1}(?:-\d+){0,1}\s*(\d+-[\d-]+-\d+)` is found. - If `\bISBN\b(?:-\d+){0,1}:{0,1}(?:-\d+){0,1}\s*(\d+)` is found. - **Journal** - Check cb2Bib internal database.
### []{#regexpeditor}Regular Expression Editor
Once a manual processing is done, cb2Bib clipboard area contains the extraction tags, plus, possibly, some other cb2Bib tags introduced during the preprocessing (see [Extracting Data from the Clipboard](#clipboard)). The **RegExp Editor** will generate a guess regular expression or matching pattern usable for automated extractions. The cb2Bib matching patterns consist of four lines: a brief description, the reference type, an ordered list of captured fields, and the regular expression itself. # cb2Bib 2.0.1 Pattern: American Chemical Society Publications article journal volume pages year title author abstract ^(.+), (\d+) \(.+\), ([\d|\-|\s]+),(\d\d\d\d)\..+(.+) (.+).+Abstract:(.+)$ The Regular Expression Editor provides the basic skeleton and a set of predefined suggestions. The regular expressions follow a Perl-like sintax. There are, however, some slight differences and minor limitations. Information about the basics on the editing and working with Regular Expressions as used by cb2Bib can be found at the Qt document file [Qt Documentation's QRegExp Class](https://doc.qt.io/archives/qt-5.6/QRegExp.html#introduction). **Remember when creating and editing regular expressions:** - Switch the clipboard mode to 'Tagged Clipboard Data', using the clipboard panel context menu. - Extract the bibliographic reference manually. On the clipboard panel will appear some cb2Bib tags that indicate which fields are being extracted. Once done, type Alt+I to enter to the regular expression editor. In the editor, there are the four line edits that define a cb2Bib pattern, one copy of the clipboard panel, and an information panel. The information panel displays possible issues, and, once everything is correct, the actual extracted fields. The clipboard panel highlights the captures for the current regular expression and current input text. - Patterns can be modified at any time by typing Alt+E to edit the regular expression file. Patterns are reloaded each time the automatic pattern recognition is started. This permits editing and testing. - cb2Bib processes sequentially the list of regular expressions as found in the regular expression file. It stops and picks the first match for the current input. **Therefore, the order of the regular expressions is important**. Consequently, to avoid possible clashing among similar patterns, consider sorting them from the most restrictive pattern to the less one. As a rule of thumb, the more captions it has the most restrictive a pattern is. - **The cb2Bib proposed patterns are general, and not necessarily the most appropriate for a particular capture**. E.g. tag `pages` becomes `([\d|\-|\s]+)`, which considers digits, hyphens, and spaces. It must be modified accordingly for reference sources with, e.g., `pages` written as Roman ordinals. - **Avoid whenever possible general patterns `(.+)`**. There is a risk that such a caption could include text intended for a posterior caption. This is why, sometimes, the cb2Bib proposed pattern is not hit by the input stream that originated it. **Use, whenever possible, cb2Bib anchors like `` instead of ``. They prevent `(.+)` captions to overextend**. - To debug a large regular expression it might be useful to break it to the first capturing parenthesis. For instance, the above pattern will be ``` {.fragment} # cb2Bib 2.0.1 Pattern: American Chemical Society Publications article journal ^(.+), ``` - Then, check if anything is captured and if this corresponds to `journal`. - Add on successive steps your set of captions and BibTeX fields.
[]{#toc-supplementary-notes}Supplementary Notes ----------------------------------------------- ### []{#relnotes}Release Notes
#### []{#relnotes201} Release Note cb2Bib 2.0.1 To optimize search on PDF's contents, cb2Bib keeps a cache with the extracted text streams, that are compressed to reduce disk space and reading overhead. Nowadays, compressors with extremely high decompression speed are available. Two of them are LZSSE, for SSE4 capable architectures, and LZ4, for a broader range of CPUs. These two compressors can now be used by cb2Bib, with the latter set as the default compression library in cb2Bib builds. When upgrading to version 2.0.1, the **first search** on the document collection will recreate the cache, and this step **will be noticeably slow**. Additionally, cb2Bib 2.0.1 includes original, optimized text matching code for AVX2 capable architectures that is used for search matching and BibTeX parsing. This code is **not set** in default builds and needs to be explicitly enabled at compilation time. Finally, it is important mentioning the inclusion in version 2.0.1 of stemmed context search, see [Contextual Search](#contextsearch) for details, and contributed feedback in handling citations and extending cite commands to markdown syntax, see [Predefined Placeholders](#predefinedplaceholders). #### []{#relnotes200} Release Note cb2Bib 2.0.0 Throughout the 1.9.x series, the cb2Bib sources were updated to the improved string processing capabilities of Qt5 and PCRE libraries. This update has brought a remarkable speedup for in-document searches and full search indexing. Alternate normalization of journal titles and abbreviations, upgrading jsMath to MathJax, extending network queries syntax, and a PDF user manual are the additional enhancements in cb2Bib 2.0.0. Back in version 0.3.3, cb2Bib introduced network queries to obtain the data for a citation. While convenient, queries to publishers' websites were difficult to setup and fragile. Nowadays, fortunately, arXiv, PubMed and Crossref offer structured APIs. These interfaces provide to the end user an easy setup for completing bibliographic citations. #### []{#relnotes190} Release Note cb2Bib 1.9.0 The cb2Bib sources have been ported to Qt5. To highlight this major update in library requirements the version number is set to 1.9.0. Later, once stabilized and new functionality related to Qt5 enhancements are applied, version number will be set to 2. At this point cb2Bib has exactly the same functionality as its preceding version 1.5.0. To build the program, however, only qmake and its related config procedure are available. The cmake scripts have not yet been ported. Qt5 brings important enhancements related to regular expressions and string processing. Some careful updates to the cb2Bib sources are needed to fully benefit from them. They will implemented through the 1.9.x series. We expect by then a performance boost on full text, regular expression based searches. #### []{#relnotes150} Release Note cb2Bib 1.5.0 Included in version 1.5.0 sources there is a patch for XPDF 3.0.4, the default tool to convert PDF documents to plain text. The modified code separates superscripts to avoid words being joined to reference numbers and author names joined to affiliations' glyphs. Interested users will need to download the package, apply the patch, and compile it. Additionally, this version improves converted text postprocessing. This step normalizes character codes, reverts ligatures, restores when possible orphan diacritics and broken words, and undoes text hyphenation. Conversion to text and postprocessing is important for reference extraction, and document indexing and searching. It is therefore recommended to delete cached document-to-text data to benefit from the present improvements. cb2Bib stores cached texts in \*c2b files in an user specified directory. After that, by performing a search or initiating indexing an updated cache will be created. #### []{#relnotes147} Release Note cb2Bib 1.4.7 Approximate and context searches effectively locate our references of interest. As collections grow in size, and low performance devices, netbooks and tablets, start being used, complete document searches become demanding. Besides, it is often not clear what to query for, and then a glossary of terms provides guidance. Often too, interest lies on subsetting documents by being similar to a given one. Version 1.4.7 adds a pragmatic term or keyword extraction from the document contents. Accepted keywords are set as the substrings appearing at least twice in one document, appearing at least in three documents, and conforming to predefined part-of-speech (POS) sequences. Keyword extraction is performed by either clicking on `Index Documents` at the `c2bciter` desktop tray menu, or, by typing `cb2bib –index [bibdirname]` on a shell. During extraction, the `Part Of Speech (POS) Lexicon` distribution file must be available and readable. On termination, indexing files are saved on the `Search In Files Cache Directory`. Simply copying this directory will synchronize keyword indexing to a second computer. After refreshing `c2bciter` module, pressing key G displays the glossary of terms. On a reference, pressing K displays its list of keywords. Pressing R on a keyword lists the references related to that keyword. Pressing R on a reference lists similarly related references. Similarity is assessed based on keyword occurrences. Left and Right keys provide previous and next navigation. Pressing V on either a reference keyword, or a keyword reference, visualizes the keyword excerpts from the reference's document. To close excerpt dialog press Esc or Left keys. See also [cb2Bib Citer](#c2bciter), [Configuring Files](#c2bconf_files), and [cb2Bib Command Line](#commandline). #### []{#relnotes140} Release Note cb2Bib 1.4.0 The `c2bciter` module was introduced in version 1.3.0. Its name, as it was described, states its purpose of being "aimed to ease inserting citation IDs into documents". In fact, it does have such functionality. And, it has also another, equally important one: it provides a very fast way to retrieve a given work from our personal collections. Retrieving is accomplished through pre-sorted views of the references and filtering. Both, views and filtering, scale on the (tens of) thousands references. Usually, we recall a work from its publication year, a few words from its title, or (some of the letters of) one of its authors names. Often, what we remember is when a reference was included into our collection. Therefore, having such a chronological view was desirable. The implementation of this sorted-by-inclusion-date view was not done during the 1.3.x series, but postponed to version 1.4.0; somehow, to indicate that some sort of 'proprietary' BibTeX tag might be required to specify inclusion timestamps. I have been reluctant through the cb2Bib's life span to introduce 'cb2Bib-only' tags in the BibTeX outputs. I believe that there is little gain, and it costs, possibly, breaking interoperability. In the end, the choice was to not write any 'timestamp' tag in references. Instead, `c2bciter` checks for the last modified date of the linked documents to build an approximated chronological view. The advantage is that all, not just 'version 1.4.0 or later', references are sorted. Furthermore, if a reference is later corrected, and the document metadata is updated too, the modification date is reflected in the view. The obvious inconvenience is that no such sorting can be done for references without an attached document. See also [cb2Bib Citer](#c2bciter). #### []{#relnotes130} Release Note cb2Bib 1.3.0 When version 0.2.7 came up, it was mentioned in [Release Note cb2Bib 0.2.7](#relnotes027) that cb2Bib 'doesn't have the means to automatically discern an author name from a department or street name'. I forgot mentioning, that I did not expect cb2Bib would have had such a feature. Since the last [Release Note cb2Bib 1.1.0](#relnotes110), the cb2Bib internals had changed significantly. Some changes, such heuristic recognition for interlaced authors and affiliations, get easily noticed. Other changes, however, do not, and need additional explanation. From version 1.2.3, the switches `–txt2bib` and `–doc2bib` set cb2Bib to work on console mode. The non-exact nature of the involved extractions makes logging necessary. On Windows, graphic or console modes must be decided not at run time, but when the application is built. So far, logging and globing were missing. This release adds the convenience wrapper `c2bconsole`. Typing `c2bconsole –txt2bib i*.txt out.bib`, for instance, will work as it does in the other platforms. Lists of references are now sorted case and diacritic insensitive. For some languages such a choice is not the expected one, and some operating systems offer local-aware collation. Due to usual inconsistencies and inaccuracies in references, this decision was taken to group together 'Density Matrix' with 'Density-matrix', and Møller with Moller, which, in a personal collection, most probably, refer to the same concept and to the same person. Additionally, document to text converted strings are now clean from extraneous, non-textual symbols. Therefore, recreating cache files is recommended. Finally, this release introduces a new module, named `c2bciter`, and aimed to ease inserting citation IDs into documents. The module should ideally stay idle at the system tray, and be recalled as needed by pressing a global, desktop shortcut. This functionality, while desirable, and usual in dictionaries, is platform and desktop dependent. On KDE there are currently known issues when switching among virtual desktops. See also [cb2Bib Citer](#c2bciter), and [cb2Bib Command Line](#commandline). #### []{#relnotes110} Release Note cb2Bib 1.1.0 A frequent request from cb2Bib users has been to expand the command line functionality. So far few progress has been seen in this regard. First, the addition of in-document searches and reading/inserting metadata were priorities. Second, cb2Bib is not the tool to interconvert among bibliographic formats. And third, cb2Bib is designed to involve the user in the search process, in the archiving and validation of the discovered works and references. For the latter reason, and for not knowing a priori how would such a tool be designed, the cb2Bib internals had been interlaced to its graphical interface. At the time of version 0.7.0, when the graphical libraries changed, and a major refactoring was required, the code started moving toward a better modularization and structure. The current release pushes code organization further. As a result, it adds two new command line switches: `–html-annote` and `–view-annote`. The new cb2Bib module is named after the BibTeX key 'annote'. Annote is not for a 'one reference annotation' though. Instead, Annote is for short notes that interrelate several references. Annote takes a plain text note, with minimal or no markup, inserts the bibliographic citations, and converts it to a HTML page with links to the referenced documents. From within cb2Bib, to write your notes, type Alt+A, enter a filename, either new or existing, and once in Annote, type E to launch your default text editor. For help, type F1. Each time you save the document the viewer will be updated. To display mathematical notations, install [jsMath](http://www.math.union.edu/~dpvc/jsMath/) locally. And, remember, code refactoring introduces bugs. See also [cb2Bib Annote](#c2bannote) and [cb2Bib Command Line](#commandline). #### []{#relnotes100} Release Note cb2Bib 1.0.0 Approximately four years ago the first cb2Bib was released. It included the possibility of easily linking a document to its bibliographic reference, in a handy way, by dragging the file to the main (at that time, single) panel. Now, in version 1.0.0, when a file is dropped, cb2Bib scans the document for metadata packets, and checks, in a rather experimental way, whether or not they contain relevant bibliographic information. Publishers metadata might or might not be accurate. Some, for instance, assign the DOI to the key Title. cb2Bib extracts possibly relevant key-value pairs and adds them to clipboard panel. Whenever key-value pairs are found accurate, just pressing Alt+G imports them to the line edits. If keys with the prefix `bibtex` are found, their values are automatically imported. The preparsed metadata that is added to the clipboard panel begins with `[Bibliographic Metadata` and ends with `/Bibliographic Metadata]`. Therefore, if you are using PDFImport together with a set of regular expressions, such that they contain the begin (\^) or end (\$) anchors, you can safely replace them by the above tags. In this manner, existing regular expressions remain useful with this minor change. And, with the advantage that, if recognition fails for a given document, metadata might give the hardest fields to extract from a PDF article, which are author and title. See also [Reading and Writing Bibliographic Metadata](#metadata). #### []{#relnotes084} Release Note cb2Bib 0.8.4 The previous cb2Bib release added the command line option `–conf [full_path]cb2bib.conf` to specify the settings location. This feature was intended, mainly, as a clean way to run the program on a host computer from a removable drive. The work done focused on arranging the command line and settings related code. It was left for a later release to solve some requirements regarding the managing of file pathnames and temporary files. This release addresses these two points. Now, when cb2Bib is launched as `cb2bib –conf` –without a configuration filename– it treats filenames as being relative to the cb2Bib actual location. Temporary files, if needed, will be placed at this location as well. Therefore, no data is being written on the host, and cb2Bib works independently of the actual address that the host assigns to the removable drive. The Windows' un/installer cleans/sets configuration data on the registry. Being aware of this particular, it might be better not to install the program directly to the USB drive. Just copy the cb2Bib base directory from a home/own computer to the removable drive, and then run it on the host computer as `cb2bib –conf`. #### []{#relnotes083} Release Note cb2Bib 0.8.3 cb2Bib accepts several arguments on its command line to access specific functionality. So far, the command `cb2bib tmp_ref` permits importing references from the browser, whenever a *download to reference manager* choice is available. In addition, the command `cb2bib –bibedit ref.bib` directly launches the BibTeX editor for file browsing and editing. This release adds the command line option `–conf [full_path]cb2bib.conf` to specifically set a file where all internal settings are being retrieved and stored. This has two interesting applications. On one hand, it easily permits switching from several sets of extraction rules, since the files `abbreviations.txt`, `regexps.txt`, and `netqinf.txt` are all stored in the cb2Bib's settings. And, on the other hand, it allows installing the program on a USB flash drive, and cleanly running it on any (e. g., library) computer. Settings can be stored and kept on the external device, and therefore, no data will be written on the registry or settings directory of the host computer. So far, however, this feature should be regarded as experimental. The Qt library to which cb2Bib is linked does read/write access to system settings in a few places (concretely, in file and color dialogs). On Unix and Mac OS systems this access can be modified by setting the environment variable DAG\_CONFIG\_HOME. No such workaround is presently available in Windows. See [cb2Bib Command Line](#commandline) for a detailed syntax description. #### []{#relnotes081} Release Note cb2Bib 0.8.1 Several changes in this release affect installation and deployment. First, the cb2Bib internals for settings management has been reorganized. Version 0.8.1 will not read previous settings, as user colors, file locations, etc. On Unix, settings are stored at `~/.config/MOLspaces/cb2Bib.conf`. This file can be removed, or renamed. On Windows, it is recommended to uninstall previous versions before upgrading. Second, cb2Bib tags are not shown by default. Instead, it is shown plain, raw clipboard data, as it is easier to identify with the original source. To write a regular expression, right click, on the menu, check 'View Tagged Clipboard Data', and perform the extraction from this view. And finally, cb2Bib adds the tag <<excerpt>> for network queries. It takes a simplified version of the clipboard contents and sends it to, e.g. Google Scholar. From there, one can easily import BibTeX references related to that contents. Therefore one should unchecked in most cases the 'Perform Network Queries after automatic reference extractions' box. #### []{#relnotes072} Release Note cb2Bib 0.7.2 cb2Bib reads the clipboard contents, processes it, and places it to the main cb2Bib's panel. If clipboard contents can be recognized as a reference, it writes the corresponding BibTeX entry. If not, the user can interact from the cb2Bib panel and complete or correct the reference. Additionally, this process permits to write down a regular expression matching the reference's pattern. To ease pattern writing, cb2Bib preprocesses the raw input data. This can consider format conversion by external tools and general substitutions, in addition to including some special tags. The resulting preprocessed data is usually less readable. A particularly illustrating case is when input data comes from a PDF article. cb2Bib now optionally presents input data, as raw, unprocessed data. This preserves the block text format of the source, and thus identifying the relevant bibliographic fields by visual inspection is more straightforward. In this raw mode view panel, interaction works in a similar manner. Except that, no conversions or substitutions are seen there, and that no regular expression tags are written. #### []{#relnotes070} Release Note cb2Bib 0.7.0 This release moves forward cb2Bib base requirement to Qt 4.2.0. Compilation errors related to rehighlight() library calls, kindly reported by Bongard, Seemann, and Luisser, should not appear anymore. File/URL opening is carried now by this library, in a desktop integrated manner. Additionally, Gnome users will enjoy better integration, as Cleanlooks widget style is available. All known regressions in 0.6.9x series have been fixed. Also, a few minor improvements have been included. In particular, file selection dialogs display navigation history, and BibTeX output file can be conveniently selected from the list of '\*.bib' files at the current directory. Such a feature will be specially useful to users that sort references in thematic files located at a given directory. #### []{#relnotes0691} Release Note cb2Bib 0.6.91 This release fixes a regression in the cb2Bib network capabilities. Network, and hence querying was erratic, both for the internal HTTP routines and for external clients. In addition to this fix, the `netqinf.txt` has been updated. PubMed is working again. Queries are also extended to include DOI's. A possible applicability will be for indexing a set of PDF articles with PDFImport. If the article contains its DOI number, and 'Perform Network Queries after automatic reference extractions' is checked, chances are that automatic extractions will work smooth. #### []{#relnotes0690} Release Note cb2Bib 0.6.90 cb2Bib has been ported from Qt3 to Qt4, a migration in its underlying system library. Qt experienced many changes and improvements in this major release upgrade. Relevant to cb2Bib, these changes will provide a better file management, word completion, faster searches, and better desktop integration. Upgrading to Qt4 it is not a "plug and recompile" game. Thorough refactoring and rewriting was required. The resulting cb2Bib code is cleaner and more suitable to further development. As one might expect, major upgrades introduce new bugs that must be fixed. The cb2Bib 0.6.90 is actually a preview version. It has approximately the same functionality than its predecessor. So, no additions were considered at this point. Its use, bug reporting, and feedback are encouraged. This will help to get sooner a stable cb2Bib 0.7. To compile it, type `./configure` as usual. The `configure` script calls the `qmake` tool to generate an appropriate `Makefile`. To make sure the right, Qt4 `qmake` is invocated, you can setup `QTDIR` environment variable prior to `./configure`. The `configure`'s call statement will then be `'$QTDIR/bin/qmake'`. E. g., type `'setenv QTDIR /usr'` if `qmake` happens to be at the directory`/usr/bin`. #### []{#relnotes060} Release Note cb2Bib 0.6.0 cb2Bib uses the internal tags `<>` and `<>` to ease the creation of regular expressions for reference extraction. New line and tabular codes from the input stream are substituted by these numbered tags. Numbering new lines and tabulars gives an extra safety when writing down a regular expression. E. g., suppose field title is 'anything' between '`<>` and `<>`'. We can then easily write 'anything' as '.+' without the risk of overextending the caption to several '\\n' codes. On the other hand, one still can use `<>` if not interested in a specific numbering. All these internal tags are later removed, once cb2Bib postprocesses the entry fields. The cb2Bib identified so far new lines by checking for '\\n' codes. I was unaware that this was a platform dependent, as well as a not completely accurate way of detecting new lines. McKay Euan reported that `<>` tags were not appearing as expected in the MacOSX version. I later learn that MacOSX uses '\\r' codes, and that Windows uses '\\r\\n', instead of '\\n' for new line encoding. This release addresses this issue. It is supposed now that the cb2Bib regular expressions will be more transferable among the different platforms. Extraction from plain text sources is expected to be completely platform independent. Extraction from web pages will still remain browser dependent. In fact, each browser adds its peculiar interpretation of a given HTML source. For example, in Wiley webpages we see the sectioning header 'Abstract' in its source and in several browsers, but we see, and get, 'ABSTRACT' if using Konqueror. What we pay for this more uniform approach is, however, a **break in compatibility** with previous versions of cb2Bib. Unix/Linux users should not expect many differences, though. Only one from the nine regular expressions in the examples needed to be modified, and the two contributed regular expressions work perfectly without any change. Windows users will not see a duplication of `<>` tags. To update previous expressions it should be enough just shifting the `<>` numbering. And, of course, any working regular expression that does not uses `<>` tags will still be working in this new version. Finally, just to mention that I do not have a MacOSX to test any of the cb2Bib releases in this particular platform. I am therefore assuming that these changes will fix the problem at hand. If otherwise, please, let me know. Also, let me know if release 0.6.0 'break' your own expressions. I consider this release a sort of experimental or beta version, and the previous version 0.5.3, will still be available during this testing period. #### []{#relnotes050} Release Note cb2Bib 0.5.0 Two issues had appeared regarding cb2Bib installation and deployment on MacOSX platforms. First, if you encounter a 'nothing to install'-error during installation on MacOSX 10.4.x using the cb2Bib binary installer available at naranja.umh.es/\~atg/, please delete the cb2bib-receipts from `/Library/Receipts` and then rerun the installer. See also M. Bongard's clarifying note 'MACOSX 10.4.X "NOTHING TO INSTALL"-ERROR' for details. Second, and also extensible to other cb2Bib platform versions, if PDFImport issues the error message 'Failed to call *some\_format\_to\_text*' tool, make sure such a tool is installed and available. Go to Configure->PDFImport, click at the 'Select External Convert Tool' button, and navigate to set its full path. Since version 0.5.0 the default full path for the MacOSX is already set, and pointing to `/usr/local/bin/pdftotext`. #### []{#relnotes041} Release Note cb2Bib 0.4.1 Qt/KDE applications emit notifications whenever they change the clipboard contents. cb2Bib uses these notifications to automatically start its 'clipboard to BibTeX' processing. Other applications, however, does not notify about them. Since version 0.2.1, see [Release Note cb2Bib 0.2.1](#relnotes021), cb2Bib started checking the clipboard periodically. This checking was later disabled as a default, needing a few lines of code to be uncomented to activate it. Without such a checking, cb2Bib appears unresponsive when selecting/copying from e.g., acroread or Mozilla. This release includes the class `clipboardpoll` written by L. Lunak for the KDE's Klipper. Checking is performed in a very optimized way. This checking is enabled by default. If you experience problems with this feature, or if the required X11 headers aren't available, consider disabling it by typing `./configure –disable-cbpoll` prior to compilation. This will disable checking completely. If the naive, old checking is preferred, uncomment the four usual lines, `./configure –disable-cbpoll`, and compile. #### []{#relnotes035} Release Note cb2Bib 0.3.5 Releases 0.3.3 and 0.3.4 brought querying functionality to cb2Bib. In essence, cb2Bib was rearranged to accommodate copying and opening of network files. Queries were then implemented as user customizable HTML posts to journal databases. In addition, these arrangements permitted defining convenience, dynamic bookmarks that were placed at the cb2Bib's 'About' panel. cb2Bib contains three viewing panels: 'About', 'Clipboard' and 'View BibTeX', being the 'Clipboard' panel the main working area. To keep cb2Bib simple, only two buttons, 'About' and 'View BibTeX', are set to navigate through the panels. The 'About' and 'View BibTeX' buttons are toggle buttons for momentarily displaying their corresponding panels. Guidance was so far provided by enabling/disabling the buttons. After the bookmark introduction, the 'About' panel has greatly increased its usefullness. Button functionality has been slightly redesigned now to avoid as many keystrokes and mouse clicks as possible. The buttons remain switchable, but they no longer disable the other buttons. User is guided by icon changes instead. Hopefully these changes will not be confusing or counterintuitive. Bookmarks and querying functionality are customizable through the `netqinf.txt` file, which is editable by pressing the `Alt+B` keys. Supported queries are of the form 'Journal-Volume-First Page'. cb2Bib parses `netqinf.txt` each time a query is performed. It looks for `journal=Full_Name|[code]` to obtain the required information for a specific journal. Empty, '`journal=`' entries have a meaning of 'any journal'. New in this release, cb2Bib will test all possible queries for a given journal instead of giving up at the first `No article found` message. The query process stops at the first successfull hit or, otherwise, once `netqinf.txt` is parsed completely (in an equivalent way as the automatic pattern recognition works). This permits querying multiple -and incomplete- journal databases. Users should order the `netqinf.txt` file in a way it is more convenient. E.g., put PubMed in front of JACS if desired an automatic extraction. Or JACS in front of PubMed and extract from the journal web page, if author accented characters are wanted. So far, this querying functionality is still tagged as *experimental*. Either the querying itself or its syntax seem quite successful. However, downloading of PDF files, on windows OS + T1 network, **was found to freeze** once progress reaches the 30-50%. Any feedback on this issue will be greatly appreciated. Also, information on `kfmclient` equivalent tools for non KDE desktops would be worth to be included in the cb2Bib documentation. #### []{#relnotes030} Release Note cb2Bib 0.3.0 cb2Bib considers the whole set of authors as an author-string pattern. This string is later postprocessed, without requirements on the actual number of authors it may contain, or on how the names are written. Once considered author-string patterns, the extraction of bibliographic references by means of regular expressions becomes relatively simple. There are situations, however, where several author-strings are required. The following box shows one of these cases. Authors are grouped according to their affiliations. Selecting from 'F. N. First' to 'F. N. Fifth' would include 'First Affiliation' within the author string. Cleaning up whatever wording 'First Affiliation' may contain is a rather ill-posed problem. Instead, cb2Bib includes an `Add Authors` option. The way of operation is then to select 'F. N. First, F. N. Second, F. N. Third' and chose `Authors` and right after, select 'F. N. Fourth and F. N. Fifth' and chose `Add Authors`. ``` {.fragment} Journal Name, 10, 1100-1105, 2004 AN EXAMPLE WITH MULTIPLE AUTHOR SETS F. N. First, F. N. Second, F. N. Third First Affiliation F. N. Fourth and F. N. Fifth Second Affiliation Abstract: Select from "Journal Name ..." to "... second author set.". The 'F. N. First, F. N. Second, F. N. Third' author string is automatically processed as one author set, while 'F. N. Fourth and F. N. Fifth' is processed as another, second author set. ``` At this point in the manual extraction, the user was faced with a red `<>` tag in the cb2Bib clipboard panel. The `<>` tag was intended to warn the user about the fact that cb2Bib would not be able to consider the resulting extraction pattern as a valid, general regular expression. Usual regular expressions are built up from an a priori known level of nesting. In these cases, however, the level of nesting is variable. It depends on the number of different affiliations occurring in a particular reference. So far the `<>` tag has become a true FAQ about cb2Bib and a source of many confusions. There is no real need, however, for such an user warning. The `<>` has therefore been removed and cb2Bib has taken an step further, to its 0.3.0 version. The cb2Bib 0.3.0 manual extraction works as usual. By clicking `Authors` the Authors edit line is reseted and selection contents moved there. Alternatively, if `Add Authors` is clicked, selection contents is added to the author field. On this version, however, both operations are tagged as `<>` (singular form, as it is the BibTeX keyword for Authors). The generated extraction pattern can now contain any number of `<>` fields. In automatic mode, cb2Bib now adds all `author` captions to Authors. In this way, cb2Bib can treat interlaced author-affiliation cases. Obviously, users needing such extractions will have to write particular regular expressions for cases with one set of authors, for two sets, and so on. Eventhough it is not rare a work having a hundred of authors, it would be quite umprobable that they were working on so many different institutions. Therefore, few regular expressions should actually be required in practice. Although not elegant, this breaks what was a cb2Bib limitation and broadens its use when extracting from PDF sources. Remember here to sort these regular expressions in decreasing order, since at present, cb2Bib stops at the first hit. Also, consider `Any Pattern` to get ride of the actual affiliation contents, as you might not want to extract authors addresses. #### []{#relnotes027} Release Note cb2Bib 0.2.7 The cb2Bib 0.2.7 release introduces multiple retrieving from PDF files. PDF documents are becoming more and more widely used, not only to transfer and printing articles, but also are substituting the personal paper files and classifiers for the electronic equivalents. cb2Bib is intended to help updating personal databases of papers. It is a tool focused on what is left behind in database retrieving. Cases such as email alerts, or inter colleague references and PDF sharing are example situations. Though in an electronic format, sources are not standardized or not globally used as to permit using habitual import filters in reference managers. cb2Bib is designed to consider a direct user intervention, either by creating its own useful filters or by a simple copy-paste assistance when handtyping. Hopefully someday cb2Bib will be able to take that old directory, with perhaps a few hundreds of papers, to automatically index the references and rename the files by author, in a consistent manner. The required mechanism is already there, in this version. But I guess that this new feature will manifest some present limitations in cb2Bib. For instance, most printed and PDF papers interlace author names and affiliations. cb2Bib doesn't have the means to automatically discern an author name from a department or street name. So far one needs to manually use the 'Add to Authors' feature to deal with these situations. Also, the managing of regular expressions needs developing, specially thinking in the spread variety of design patterns in publications. In summary, this current version is already useful in classifying and extracting the reference of that couple of papers that someone send right before submitting a work. A complete unsupervised extraction is still far away, however. #### []{#relnotes021} Release Note cb2Bib 0.2.1 The cb2Bib mechanism 'select-and-catch' failed in some cases. Acrobat and Mozilla selections were not always notified to cb2Bib. Indeed, this 'window manager - application' connection seems to be broken on a KDE 3.3.0 Qt 3.3.3 system. The cb2Bib 0.2.1 continues to listen to system clipboard change notifications, whenever they are received and whenever cb2Bib is on connected mode. Additionally, the cb2Bib 0.2.1 periodically checks for changes in the system clipboard. Checks are performed every second, approximately. This permits cb2Bib to work as usual, although one could experience 1-2 seconds delays in systems where the automatic notification is broken. If the 'select-and-catch' functionality appears 'sticky', possibly happening while using non KDE applications from where text is selected, check the source file `c2bclipboard``.cpp`, look for `'Setting timer'`, and set variable `interval` to 1000. This is the interval of time in ms that cb2Bib will use to check for clipboard changes.
cb2bib-2.0.1/PaxHeaders.5700/c2btools0000644000000000000000000000013014011522521013746 xustar0029 mtime=1613145425.31462032 30 atime=1613145424.814620334 29 ctime=1613145425.31462032 cb2bib-2.0.1/c2btools/0000755000175000001440000000000014011522521015424 5ustar00constansusers00000000000000cb2bib-2.0.1/c2btools/PaxHeaders.5700/med2bib0000644000000000000000000000007414011522151015260 xustar0030 atime=1613145424.814620334 30 ctime=1613145424.298620349 cb2bib-2.0.1/c2btools/med2bib0000755000175000001440000000507114011522151016660 0ustar00constansusers00000000000000#!/bin/sh #------------------------------------------------------------------------------- # med2bib -- Script to convert PUBMED format to BibTeX # cb2Bib Tools # # Copyright (C) 2009 by Filippo Rusconi # rusconi@mnhn.fr # # Based on previous work by # Pere Constans # constans@molspaces.com # # See LICENSE file that comes with this distribution # # Usage: med2bib input_med output_bib #------------------------------------------------------------------------------- # Using med2xml and xml2bib utilities from: # http://bibutils.refbase.org/ #------------------------------------------------------------------------------- #------------------------------------------------------------------------------- # Init variables #------------------------------------------------------------------------------- # Modify accordingly #med2xml=/usr/local/bin/med2xml #xml2bib=/usr/local/bin/xml2bib med2xml=med2xml xml2bib=xml2bib med2xml_flags="-u" xml2bib_flags="-sd -b" #------------------------------------------------------------------------------- # Immediately check that the needed programs are there: "${med2xml}" --version > /dev/null 2>&1 if [ "$?" != "0" ] then echo "Program med2xml (suite bibutils) is required." echo "Set it in your path, and/or modify $0 accordingly." echo "Ending processing." exit 1 fi "${xml2bib}" --version > /dev/null 2>&1 if [ "$?" != "0" ] then echo "Program xml2bib (suite bibutils) is required." echo "Set it in your path, and/or modify $0 accordingly." echo "Ending processing." exit 1 fi # Make sure we trap errors (we put that after the tests above because # we need the tests to fail, in case, without exiting immediately). set -e # Getting filenames from command line echo "cb2Bib Tools: Script to convert PUBMED-XML format to BibTeX" echo "" echo "It uses external package bibutils from" echo "http://bibutils.refbase.org/" echo "" if test "$#" != 2; then cat < c2b_tmp.xml "${xml2bib}" $xml2bib_flags c2b_tmp.xml | sed 's%^ISSUE=%NUMBER=%g' > c2b_tmp.bib # Clean up cd "${work_dir}" cp "${tmp_dir}"/c2b_tmp.bib "$bib" rm -rf "${tmp_dir}" echo "" echo "$0 ended." cb2bib-2.0.1/c2btools/PaxHeaders.5700/bib2pdf0000644000000000000000000000007414011522151015264 xustar0030 atime=1613145424.814620334 30 ctime=1613145424.298620349 cb2bib-2.0.1/c2btools/bib2pdf0000755000175000001440000000631614011522151016667 0ustar00constansusers00000000000000#!/bin/sh #------------------------------------------------------------------------------- # bib2pdf -- Script to convert BibTeX files to PDF # cb2Bib Tools # # Copyright (C) 2005-2021 by Pere Constans # constans@molspaces.com # # Improvements and modifications: # Copyright (C) 2009 by Filippo Rusconi # rusconi@mnhn.fr # # May/June 2009: # - Added checks to ensure that the used commands are available on # system. # - Make use of mktemp to create a temp directory. # # See LICENSE file that comes with this distribution # # Usage: bib2pdf input_bib output_pdf #------------------------------------------------------------------------------- #------------------------------------------------------------------------------- # Init variables #------------------------------------------------------------------------------- # Modify accordingly, by choosing either pdflatex or latex+dvipdfm #latexCmd=pdflatex latexCmd=latex ; dvi2pdfCmd=dvipdfm bibtexCmd=bibtex #------------------------------------------------------------------------------- # Immediately check that the needed programs are there: "${latexCmd}" --version > /dev/null 2>&1 if [ "$?" != "0" ] then echo "Program ${latexCmd} (LaTeX software) is required." echo "Ending processing." exit 1 fi "${bibtexCmd}" --version > /dev/null 2>&1 if [ "$?" != "0" ] then echo "Program ${bibtexCmd} (BibTeX software) is required." echo "Ending processing." exit 1 fi # Special case with dvi2pdf: if [ "x${dvi2pdfCmd}" != "x" ] then "${dvi2pdfCmd}" --version | head -n2 | grep dvipdfm > /dev/null 2>&1 if [ "$?" != "0" ] then echo "Program ${dvi2pdfCmd} (LaTeX software) is required." echo "Ending processing." exit 1 fi fi # Make sure we trap errors (we put that after the tests above because # we need the tests to fail, in case, without exiting immediately). set -e # Getting filenames from command line echo "cb2Bib Tools: Script to convert BibTeX to PDF" if test "$#" != 2; then cat < "${tmp_dir}"/c2b_tmp.tex < /dev/null 2>&1 "${bibtexCmd}" c2b_tmp "${latexCmd}" $latex_flags c2b_tmp > /dev/null 2>&1 "${latexCmd}" $latex_flags c2b_tmp if [ "x${dvi2pdfCmd}" != "x" ] then "${dvi2pdfCmd}" c2b_tmp > /dev/null 2>&1 fi # Make sure we trap errors. set -e # Clean up cd "${work_dir}" cp "${tmp_dir}"/c2b_tmp.pdf "$pdf" rm -rf "${tmp_dir}" echo "$0 ended." cb2bib-2.0.1/c2btools/PaxHeaders.5700/ris2bib0000644000000000000000000000007414011522151015310 xustar0030 atime=1613145424.814620334 30 ctime=1613145424.298620349 cb2bib-2.0.1/c2btools/ris2bib0000755000175000001440000000535114011522151016711 0ustar00constansusers00000000000000#!/bin/sh #------------------------------------------------------------------------------- # ris2bib -- Script to convert RIS format to BibTeX # cb2Bib Tools # # Copyright (C) 2005-2021 by Pere Constans # constans@molspaces.com # # Improvements and modifications: # Copyright (C) 2009 by Filippo Rusconi # rusconi@mnhn.fr # # May/June 2009: # - Added checks to ensure that the used commands are available on # system. # - Make use of mktemp to create a temp directory. # # See LICENSE file that comes with this distribution # # Usage: ris2bib input_ris output_bib #------------------------------------------------------------------------------- # Using ris2xml and xml2bib utilities from: # http://bibutils.refbase.org/ #------------------------------------------------------------------------------- #------------------------------------------------------------------------------- # Init variables #------------------------------------------------------------------------------- # Modify accordingly #ris2xml=/usr/local/bin/ris2xml #xml2bib=/usr/local/bin/xml2bib ris2xml=ris2xml xml2bib=xml2bib ris2xml_flags="-u" xml2bib_flags="-sd -b" #------------------------------------------------------------------------------- # Immediately check that the needed programs are there: "${ris2xml}" --version > /dev/null 2>&1 if [ "$?" != "0" ] then echo "Program ris2xml (suite bibutils) is required." echo "Set it in your path, and/or modify $0 accordingly." echo "Ending processing." exit 1 fi "${xml2bib}" --version > /dev/null 2>&1 if [ "$?" != "0" ] then echo "Program xml2bib (suite bibutils) is required." echo "Set it in your path, and/or modify $0 accordingly." echo "Ending processing." exit 1 fi # Make sure we trap errors (we put that after the tests above because # we need the tests to fail, in case, without exiting immediately). set -e # Getting filenames from command line echo "cb2Bib Tools: Script to convert RIS format to BibTeX" echo "" echo "It uses external package bibutils from" echo "http://bibutils.refbase.org/" echo "" if test "$#" != 2; then cat < c2b_tmp.xml "${xml2bib}" ${xml2bib_flags} c2b_tmp.xml | sed 's%^ISSUE=%NUMBER=%g' > c2b_tmp.bib # Clean up cd "${work_dir}" cp "${tmp_dir}"/c2b_tmp.bib "$bib" rm -rf "${tmp_dir}" echo "" echo "$0 ended." cb2bib-2.0.1/c2btools/PaxHeaders.5700/isi2bib0000644000000000000000000000007414011522151015277 xustar0030 atime=1613145424.814620334 30 ctime=1613145424.298620349 cb2bib-2.0.1/c2btools/isi2bib0000755000175000001440000000534514011522151016703 0ustar00constansusers00000000000000#!/bin/sh #------------------------------------------------------------------------------- # isi2bib -- Script to convert ISI format to BibTeX # cb2Bib Tools # # Copyright (C) 2005-2021 by Pere Constans # constans@molspaces.com # # Improvements and modifications: # Copyright (C) 2009 by Filippo Rusconi # rusconi@mnhn.fr # # May/June 2009: # - Added checks to ensure that the used commands are available on # system. # - Make use of mktemp to create a temp directory. # # See LICENSE file that comes with this distribution # # Usage: isi2bib input_isi output_bib #------------------------------------------------------------------------------- # Using isi2xml and xml2bib utilities from: # http://bibutils.refbase.org/ #------------------------------------------------------------------------------- #------------------------------------------------------------------------------- # Init variables #------------------------------------------------------------------------------- # Modify accordingly #isi2xml=/usr/local/bin/isi2xml #xml2bib=/usr/local/bin/xml2bib isi2xml=isi2xml xml2bib=xml2bib isi2xml_flags="-u" xml2bib_flags="-sd -b" #------------------------------------------------------------------------------- # Immediately check that the needed programs are there: "${isi2xml}" --version > /dev/null 2>&1 if [ "$?" != "0" ] then echo "Program ris2xml (suite bibutils) is required." echo "Set it in your path, and/or modify $0 accordingly." echo "Ending processing." exit 1 fi "${xml2bib}" --version > /dev/null 2>&1 if [ "$?" != "0" ] then echo "Program xml2bib (suite bibutils) is required." echo "Set it in your path, and/or modify $0 accordingly." echo "Ending processing." exit 1 fi # Make sure we trap errors (we put that after the tests above because # we need the tests to fail, in case, without exiting immediately). set -e # Getting filenames from command line echo "cb2Bib Tools: Script to convert ISI format to BibTeX" echo "" echo "It uses external package bibutils from" echo "http://bibutils.refbase.org/" echo "" if test "$#" != 2; then cat < c2b_tmp.xml "${xml2bib}" $xml2bib_flags c2b_tmp.xml | sed 's%^ISSUE=%NUMBER=%g' > c2b_tmp.bib # Clean up cd "${work_dir}" cp "${tmp_dir}"/c2b_tmp.bib "$bib" rm -rf "${tmp_dir}" echo "" echo "$0 ended." cb2bib-2.0.1/PaxHeaders.5700/c2bscripts0000644000000000000000000000007414011522151014303 xustar0030 atime=1613145424.814620334 30 ctime=1613145424.298620349 cb2bib-2.0.1/c2bscripts/0000755000175000001440000000000014011522151015752 5ustar00constansusers00000000000000cb2bib-2.0.1/c2bscripts/PaxHeaders.5700/c2bimport0000644000000000000000000000007414011522151016204 xustar0030 atime=1613145424.814620334 30 ctime=1613145424.298620349 cb2bib-2.0.1/c2bscripts/c2bimport0000755000175000001440000000147314011522151017606 0ustar00constansusers00000000000000#!/bin/sh #------------------------------------------------------------------------------- # c2bimport -- Script for calling cb2Bib in "Download Reference to cb2Bib" mode # cb2Bib Tools # Copyright (C) 2004-2021 by Pere Constans # constans@molspaces.com # # Copyright (C) 2009 by Filippo Rusconi # rusconi@mnhn.fr # # June 2009: # - Make use of quoted "$1" argument instead of $1. # # See the LICENSE file that comes with this distribution #------------------------------------------------------------------------------- # Usage: c2bimport tmp_imported_reference_file #------------------------------------------------------------------------------- if test "$#" != 1; then cat <
https://exiftool.org. \endhtmlonly ExifTool supports several document formats for writing. The most relevant here are Postscript and PDF. For PDF documents, metadata is written as an incremental update of the document. This exactly preserves the binary structure of the document, and changes can be easily reversed or modified if so desired. Whenever ExifTool is unable to insert metadata, e.g., because the document format is not supported or it has structural errors, cb2Bib will issue an information message, and the document will remain untouched. See also \ref c2bconf_documents and \ref update_metadata. */ metadataParser::metadataParser(QObject* parento) : QObject(parento) { _cbpP = new coreBibParser(this); init(); } metadataParser::metadataParser(coreBibParser* cbp, QObject* parento) : QObject(parento), _cbpP(cbp) { Q_ASSERT_X(_cbpP, "metadataParser", "coreBibParser was not instantiated"); init(); } void metadataParser::init() { _settingsP = settings::instance(); // Set bibliographic fields // Remove fields file (it is itself) and pages (usually number of pages) from list _fields = QRegExp("\\b(?:abstract|address|annote|author|authors|booktitle|chapter|" "doi|edition|editor|eprint|institution|isbn|issn|journal|" "keyword|keywords|key words|month|note|number|organization|" "pagerange|publicationname|publisher|school|series|title|url|volume|year)\\b"); _fields.setCaseSensitivity(Qt::CaseInsensitive); // Recognition from BibTeX entries _bibtex_fields = QRegExp("\\bbibtex:(?:abstract|address|annote|author|booktitle|chapter|" "doi|edition|editor|eprint|institution|isbn|issn|journal|" "keywords|month|note|number|organization|pages|publisher|" "school|series|title|url|volume|year)\\b"); _bibtex_fields.setCaseSensitivity(Qt::CaseInsensitive); // Set field keys equivalences const QStringList& bibliographicFields = _cbpP->bibliographicFields(); for (int i = 0; i < bibliographicFields.count(); ++i) _bibtex_key.insert(bibliographicFields.at(i), bibliographicFields.at(i)); _bibtex_key.insert("authors", "author"); _bibtex_key.insert("key words", "keywords"); _bibtex_key.insert("keyword", "keywords"); _bibtex_key.insert("pagerange", "pages"); _bibtex_key.insert("publicationname", "journal"); } const QString metadataParser::metadata(const QString& fn) { if (!_metadata(fn)) return QString(); QString data; if (_has_bibtex) data = _cbpP->referenceToBibTeX(_ref); else { const QStringList& bibliographicFields(_cbpP->bibliographicFields()); if (_ref.contains("type")) data += QString("%1\n").arg(_ref.value("type")); for (int i = 0; i < bibliographicFields.count(); ++i) { const QString key(bibliographicFields.at(i)); if (_ref.contains(key)) data += QString("<%1>%2\n").arg(key, _ref.value(key)); } } data = QString("[Bibliographic Metadata\n%1/Bibliographic Metadata]\n").arg(data); return data; } bool metadataParser::metadata(const QString& fn, bibReference* ref) { ref->clearReference(); bool has_reference(_metadata(fn)); has_reference = has_reference && _has_bibtex && _has_cb2bib; if (has_reference) (*ref) = _ref; return has_reference; } bool metadataParser::_metadata(const QString& fn) { QByteArray raw_contents; QFile f(fn); if (f.open(QIODevice::ReadOnly)) { raw_contents = f.readAll(); f.close(); } else return false; _ref.clearReference(); _ref.typeName = "article"; _has_bibtex = false; _has_cb2bib = false; _has_prism = false; QStringList xmls; _metadataXmp(fn, raw_contents, &xmls); // Last in list should be the most updated, parse it last for (int i = 0; i < xmls.count(); ++i) _fuzzyParser(xmls.at(i)); QMutableHashIterator it(_ref); while (it.hasNext()) { it.next(); it.value() = c2bUtils::fromQtXmlString(it.value()); } if (!_has_cb2bib) _miscellaneousData(fn, raw_contents); if (_ref.count() == 0) return false; if (_has_bibtex) if (_ref.contains("type")) _ref.typeName = _ref.value("type"); return true; } void metadataParser::_metadataXmp(const QString& fn, const QByteArray& raw_contents, QStringList* xmls) { xmls->clear(); int pos(0); while (pos > -1) { // Scan all packets, and do not trust "='' " etc, as producers encode differently pos = raw_contents.indexOf(" -1) { int posn(raw_contents.indexOf(" pos) { xmls->append(c2bUtils::toQtXmlString(QString::fromUtf8(raw_contents.mid(pos, posn - pos + 19)))); _has_bibtex = _has_bibtex || xmls->last().contains("bibtex:"); _has_cb2bib = _has_cb2bib || xmls->last().contains("www.molspaces.com/cb2bib"); _has_prism = _has_prism || xmls->last().contains("prismstandard.org/namespaces/basic/2.0"); pos = posn; } else pos = -1; } } if (xmls->count() == 0) _metadataXmpExifTool(fn, xmls); } void metadataParser::_miscellaneousData(const QString& fn, const QByteArray& raw_contents) { // Get title, author, and keywords from here whenever no cb2Bib BibTeX data is available QString data; QRegExp pdf_author_rx; QRegExp pdf_title_rx; QRegExp pdf_keywords_rx; const QString exiftool_bin(_settingsP->fileName("cb2Bib/ExifToolBin")); bool is_exiftool_available = !exiftool_bin.isEmpty(); if (is_exiftool_available) { QProcess exiftool; QStringList arglist; arglist.append(fn); exiftool.start(exiftool_bin, arglist); if (!exiftool.waitForFinished(90000)) exiftool.kill(); data = QString::fromUtf8(exiftool.readAllStandardOutput()); if (exiftool.error() == QProcess::UnknownError) // No error { pdf_author_rx.setPattern("Author\\s*:\\s+(.*)\\n"); pdf_title_rx.setPattern("Title\\s*:\\s+(.*)\\n"); pdf_keywords_rx.setPattern("Subject\\s*:\\s+(.*)\\n"); } else is_exiftool_available = false; } if (!is_exiftool_available) { if (!raw_contents.startsWith("%PDF")) return; data = _pdfDictionary(raw_contents); pdf_author_rx.setPattern("\\Author\\s*\\((.*)\\)"); pdf_title_rx.setPattern("\\Title\\s*\\((.*)\\)"); } pdf_author_rx.setMinimal(true); pdf_author_rx.setCaseSensitivity(Qt::CaseSensitive); if (pdf_author_rx.indexIn(data) > -1) if (!pdf_author_rx.cap(1).trimmed().isEmpty()) _ref["author"] = pdf_author_rx.cap(1); // Dublin Core Metadata keywords if exiftool is available if (_has_prism && is_exiftool_available) { pdf_keywords_rx.setMinimal(true); pdf_keywords_rx.setCaseSensitivity(Qt::CaseSensitive); if (pdf_keywords_rx.indexIn(data) > -1) if (!pdf_keywords_rx.cap(1).trimmed().isEmpty()) _ref["keywords"] = pdf_keywords_rx.cap(1); } // Done if BibTeX, otherwise try checking dictionary for title if (_has_bibtex) return; pdf_title_rx.setMinimal(true); pdf_title_rx.setCaseSensitivity(Qt::CaseSensitive); if (pdf_title_rx.indexIn(data) > -1) if (!pdf_title_rx.cap(1).trimmed().isEmpty()) _ref["title"] = pdf_title_rx.cap(1); } const QString metadataParser::_pdfDictionary(const QByteArray& rawpdf) { // Heuristic to locate the Pdf dictionary const int pos(rawpdf.lastIndexOf("/Producer")); if (pos > -1) { const int pos0(rawpdf.lastIndexOf("<<", pos)); if (pos0 > -1) { const int posn(rawpdf.indexOf(">>", pos)); if (posn > pos0) return QString::fromLatin1(rawpdf.mid(pos0, posn - pos0 + 2)); } } return QString(); } void metadataParser::_metadataXmpExifTool(const QString& fn, QStringList* xmls) { // Not actually needed, called for not directly visible XMP packages // It's slower than _metadataXmp() full scan. const QString exiftool_bin(_settingsP->fileName("cb2Bib/ExifToolBin")); if (exiftool_bin.isEmpty()) return; QProcess exiftool; QStringList arglist; arglist.append("-xmp"); arglist.append("-b"); arglist.append(fn); exiftool.start(exiftool_bin, arglist); if (!exiftool.waitForFinished(90000)) exiftool.kill(); QString xmp(c2bUtils::toQtXmlString(QString::fromUtf8(exiftool.readAllStandardOutput()))); if (xmp.startsWith("append(xmp); _has_bibtex = _has_bibtex || xmls->last().contains("bibtex:"); _has_cb2bib = _has_cb2bib || xmls->last().contains("www.molspaces.com/cb2bib"); _has_prism = _has_prism || xmls->last().contains("prismstandard.org/namespaces/basic/2.0"); } } void metadataParser::_fuzzyParser(const QString& data) { if (data.isEmpty()) return; QXmlStreamReader parser; parser.addData(data); QRegExp* fields; if (_has_bibtex) fields = &_bibtex_fields; else fields = &_fields; QString field; QString key; QString value; while (!parser.atEnd()) { parser.readNext(); if (parser.isStartElement()) { // Do attributes (seems poppler xml composing) QXmlStreamAttributes att = parser.attributes(); for (int i = 0; i < att.count(); ++i) { field = att.at(i).qualifiedName().toString(); key = att.at(i).name().toString().toLower(); value = att.at(i).value().toString(); if (value.isEmpty()) continue; if (field.contains(*fields)) _ref[_bibtex_key.value(key)] = value; else if (QString::compare(field, "summary", Qt::CaseInsensitive) == 0 || QString::compare(field, "subject", Qt::CaseInsensitive) == 0) { if (!_ref.contains("abstract")) // Prefer BibTeX field key if exists than synonyms _ref["abstract"] = value; } else if (QString::compare(field, "bibtex:type", Qt::CaseInsensitive) == 0 || QString::compare(field, "bibtex:entrytype", Qt::CaseInsensitive) == 0) _ref["type"] = value.toLower(); } // Do element (exiftool and exempi xml composing) field = parser.qualifiedName().toString(); key = parser.name().toString().toLower(); if (field.contains(*fields)) { parser.readNext(); value = parser.text().toString().trimmed(); if (!value.isEmpty()) _ref[_bibtex_key.value(key)] = value; } else if (!_has_bibtex && QString::compare(field, "prism:coverDate", Qt::CaseSensitive) == 0) { parser.readNext(); value = parser.text().toString().trimmed(); const QDate pdate(QDate::fromString(value, Qt::ISODate)); const QString pyear(pdate.toString("yyyy")); // Prefer BibTeX date over Prism if (!pyear.isEmpty() && !_ref.contains("year")) _ref["year"] = pyear; const QString pmonth(pdate.toString("d MMMM")); if (!pmonth.isEmpty() && !_ref.contains("month")) _ref["month"] = pmonth; } else if (QString::compare(field, "summary", Qt::CaseInsensitive) == 0 || QString::compare(field, "subject", Qt::CaseInsensitive) == 0) { parser.readNext(); value = parser.text().toString().trimmed(); if (!value.isEmpty() && !_ref.contains("abstract")) // Prefer BibTeX field key if exists than synonyms _ref["abstract"] = value; } else if (QString::compare(field, "bibtex:type", Qt::CaseInsensitive) == 0 || QString::compare(field, "bibtex:entrytype", Qt::CaseInsensitive) == 0) { parser.readNext(); value = parser.text().toString().trimmed(); if (!value.isEmpty()) _ref["type"] = value.toLower(); } } } if (parser.hasError()) c2bUtils::debug(tr("metadataParser: Error while parsing XML packets")); } bool metadataParser::insertMetadata(const bibReference& ref, const QString& fn, QString* error, const bool has_reference) { if (error) error->clear(); const QString exiftool_bin(_settingsP->fileName("cb2Bib/ExifToolBin")); if (exiftool_bin.isEmpty()) { if (error) *error = tr("Metadata writer: ExifTool location has not been specified."); else emit showMessage(tr("Warning - cb2Bib"), tr("Metadata writer: ExifTool location has not been specified.")); return false; } if (ref.count() == 0) return false; QString bibtags; QString key; QString value; const QString entry("%2\n"); bibtags += entry.arg("type", ref.typeName); const QStringList& bibliographicFields = _cbpP->bibliographicFields(); for (int i = 0; i < bibliographicFields.count(); ++i) { key = bibliographicFields.at(i); value = ref.value(key); if (key == "file") continue; else if (key == "id") continue; c2bUtils::fullBibToC2b(value); if (key == "title" || key == "booktitle") c2bUtils::cleanTitle(value); bibtags += entry.arg(key, value); } QString bibtags_xmp(c2bUtils::fileToString(":/xml/xml/cb2bib.xmp")); bibtags_xmp.replace("GET_BIBTEX_TAGS", bibtags); bibtags_xmp.replace("GET_FORMATTED_AUTHOR", formattedAuthor(ref.value("author"))); const QString workdir(QFileInfo(fn).absolutePath()); const QString bibtags_file(workdir + "/bibtags.xmp"); c2bUtils::stringToFile(bibtags_xmp, bibtags_file); QProcess exiftool; QStringList arglist; arglist.append("-overwrite_original"); arglist.append("-m"); if (has_reference) arglist.append("-P"); arglist.append("-TagsFromFile"); arglist.append(bibtags_file); arglist.append("-all:all"); arglist.append("-pdf:all>, (C) 2009 by Dayu Huang ***************************************************************************/ #ifndef IDMAKER_H #define IDMAKER_H #include "bibReference.h" #include /** @author Pere Constans */ class idMaker : public QObject { Q_OBJECT public: explicit idMaker(const QString& patternKey, QObject* parento = 0); inline ~idMaker() {} QString makeID(const bibReference& reference); private: QString _author; QString _id_pattern; QString _journal; QString _pages; QString _title; QString _title_pattern; QString _volume; QString _year; bool _is_title_underscored; const QString _pattern_key; int _title_max_length; void make_author_all_abbreviated(QString* id); void make_author_all_initials(QString* id); void make_author_first(QString* id); void make_author_first_lowercase(QString* id); void make_journal_initials(QString* id); void make_pages_first(QString* id); void make_ppages_first(QString* id); void make_title(QString* id); void make_title_first_word(QString* id); void make_volume(QString* id); void make_year_abbreviated(QString* id); void make_year_full(QString* id); private slots: void loadSettings(); }; #endif cb2bib-2.0.1/src/c2b/PaxHeaders.5700/network.cpp0000644000000000000000000000013214011522520015727 xustar0030 mtime=1613145424.642620339 30 atime=1613145424.834620334 30 ctime=1613145424.646620339 cb2bib-2.0.1/src/c2b/network.cpp0000644000175000001440000003145214011522520017333 0ustar00constansusers00000000000000/*************************************************************************** * Copyright (C) 2004-2021 by Pere Constans * constans@molspaces.com * cb2Bib version 2.0.1. Licensed under the GNU GPL version 3. * See the LICENSE file that comes with this distribution. ***************************************************************************/ #include "network.h" #include "cb2bib_utilities.h" #include "settings.h" #include #include #include #include #include network::network(QObject* parento) : QObject(parento), _max_redirections(15) { _is_fetching = false; _fetcher = new QNetworkAccessManager(this); connect(_fetcher, SIGNAL(proxyAuthenticationRequired(QNetworkProxy,QAuthenticator*)), this, SIGNAL(proxyAuthenticationRequired(QNetworkProxy,QAuthenticator*))); loadSettings(); connect(settings::instance(), SIGNAL(newSettings()), this, SLOT(loadSettings())); // Set predefined cookies QNetworkCookieJar* ncj = _fetcher->cookieJar(); QNetworkCookie nc("GSP", "ID=d093ce1ea042ad2b:IN=54afcd58e3b38df9:HIN=ff7e3a3ab3fbae0a+7e6cc990821af63:CF=4"); ncj->setCookiesFromUrl(QList() << nc, QUrl("https://scholar.google.com")); } /**************************************************************************** PUBLIC PART *****************************************************************************/ void network::getFile(const QString& source, const QString& destination, const Action action, QObject* receiver, const char* callback, const bool overwrite) { if (_is_fetching) { c2bUtils::warn(tr("network::getFile: Requesting network while still fetching previous request. Returned")); return; } setup(source, destination); disconnect(this, SIGNAL(requestFinished(bool)), 0, 0); if (receiver) connect(this, SIGNAL(requestFinished(bool)), receiver, callback); if (overwrite) if (QFileInfo::exists(destination)) QFile::remove(destination); getFilePrivate(action); } void network::headFile(const QString& source, QObject* receiver, const char* callback) { if (_is_fetching) { c2bUtils::warn(tr("network::headFile: Requesting network while still fetching previous request. Returned")); return; } setup(source); disconnect(this, SIGNAL(requestFinished(bool)), 0, 0); if (receiver) connect(this, SIGNAL(requestFinished(bool)), receiver, callback); headFilePrivate(); } void network::cancelDownload() { if (_is_fetching) _current_reply->abort(); } /**************************************************************************** PRIVATE PART *****************************************************************************/ void network::getFilePrivate(const Action action) { if (!checkDestination()) { _emit_request_finished(false); return; } if (_source_filename.startsWith("<>")) // cb2Bib keyword to use post http method { _source_filename.remove(QRegExp("^<>")); _fetch_c2b(action, QNetworkAccessManager::PostOperation); return; } if (FmClient) if ((action == Copy && !FmClientCopyBin.isEmpty()) || (action == Move && !FmClientMoveBin.isEmpty())) { _fetch_client(action); return; } _fetch_c2b(action); } void network::headFilePrivate() { const QUrl u(_source_filename, QUrl::TolerantMode); if (u.scheme() == "file" || QFileInfo::exists(_source_filename)) { // Local File const QString fn(u.scheme() == "file" ? u.toLocalFile() : _source_filename); const bool succeeded(QFileInfo::exists(fn)); if (!succeeded) _request_error_string = tr("File does not exist."); _emit_request_finished(succeeded); } else { // Network File _head(u); } } void network::_emit_request_finished(bool succeeded) { _request_succeeded = succeeded; // Give some time to cleanup events and to return all network functions // before passing the control to the callback routine QTimer::singleShot(50, this, SLOT(_emit_request_finished())); } void network::_emit_request_finished() { _is_fetching = false; // Assumed events are clean, all functions returned, then make the callback emit requestFinished(_request_succeeded); } bool network::checkDestination() { // Checks whether or not writing to destination is safe // Returns false if file exists if (QFileInfo::exists(_destination_filename)) { _request_error_string = tr("Destination file '%1' already exists.").arg(_destination_filename); return false; } else return true; } void network::loadSettings() { settings* s(settings::instance()); FmClient = s->value("cb2Bib/FmClient").toBool(); FmClientCopyBin = s->fileName("cb2Bib/FmClientCopyBin"); FmClientMoveBin = s->fileName("cb2Bib/FmClientMoveBin"); FmClientCopyArg = s->value("cb2Bib/FmClientCopyArg").toString(); FmClientMoveArg = s->value("cb2Bib/FmClientMoveArg").toString(); QNetworkProxy proxy; if (s->value("cb2Bib/UseProxy").toBool()) { const QString hn(s->value("cb2Bib/ProxyHostName", QString()).toString()); if (!hn.isEmpty()) { if (s->value("cb2Bib/ProxyType").toInt() == 0) proxy = QNetworkProxy::HttpProxy; else proxy = QNetworkProxy::Socks5Proxy; proxy.setHostName(hn); proxy.setPort(quint16(s->value("cb2Bib/ProxyPort").toInt())); } } _fetcher->setProxy(proxy); } /**************************************************************************** PRIVATE PART: FILEMANAGER CLIENT *****************************************************************************/ void network::_fetch_client(const Action action) { // Getting NetworkFile through kfmclient Action act(action); // Only move local files QUrl u(_source_filename); if (!(u.scheme() == "file" || QFileInfo::exists(_source_filename))) if (action == Move) act = Copy; // Copy network files QStringList arglist; QString fmclient_bin; if (act == Copy) { fmclient_bin = FmClientCopyBin; arglist = FmClientCopyArg.split(' ', QString::SkipEmptyParts); } else if (act == Move) { fmclient_bin = FmClientMoveBin; arglist = FmClientMoveArg.split(' ', QString::SkipEmptyParts); } arglist.append(_source_filename); arglist.append(_destination_filename); _fetcher_client = new QProcess(this); connect(_fetcher_client, SIGNAL(finished(int,QProcess::ExitStatus)), this, SLOT(_client_finished(int,QProcess::ExitStatus))); _fetcher_client->start(fmclient_bin, arglist); if (!_fetcher_client->waitForStarted()) { delete _fetcher_client; _request_error_string = tr("FM Client '%1' could not be launched.").arg(fmclient_bin); _emit_request_finished(false); } } void network::_client_finished(int exitCode, QProcess::ExitStatus exitStatus) { bool succeeded(false); if (exitStatus == QProcess::CrashExit) _request_error_string = tr("FM Client crashed."); else { if (QFileInfo::exists(_destination_filename)) succeeded = true; else _request_error_string = tr("File '%1' has not been written. Exit code '%2'.").arg(_source_filename).arg(exitCode); } delete _fetcher_client; _emit_request_finished(succeeded); } /**************************************************************************** PRIVATE PART: C2B FETCHER *****************************************************************************/ void network::_head(const QUrl& url) { QNetworkRequest request; request.setUrl(url); request.setRawHeader( "User-Agent", QString("cb2Bib/" + C2B_VERSION + " (https://www.molspaces.com/cb2bib/; mailto:cb2bib@molspaces.com; Bibliographic Browser Tool)") .toLatin1()); _current_reply = _fetcher->head(request); connect(_current_reply, SIGNAL(finished()), SLOT(_head_finished())); } void network::_head_finished() { if (_redirection_count++ < _max_redirections) { const QUrl redirection(_current_reply->attribute(QNetworkRequest::RedirectionTargetAttribute).toUrl()); if (redirection.isValid()) { const QUrl ru(_current_reply->url().resolved(redirection)); _source_filename = ru.toString(); _current_reply->deleteLater(); _head(ru); return; } } const bool succeeded(_current_reply->error() == QNetworkReply::NoError); if (succeeded) _file_mimetype_string = _current_reply->header(QNetworkRequest::ContentTypeHeader).toString(); else _request_error_string = _current_reply->errorString() + '.'; _current_reply->deleteLater(); _emit_request_finished(succeeded); } void network::_fetch_c2b(const Action action, const QNetworkAccessManager::Operation operation) { _fetch_operation = operation; _fetch_url_query.clear(); QString url_str; if (_fetch_operation == QNetworkAccessManager::PostOperation) { const int qmark(_source_filename.indexOf('?')); url_str = _source_filename.mid(0, qmark); if (qmark > -1) { url_str += '/'; _fetch_url_query = _source_filename.mid(qmark + 1).toUtf8(); } } else url_str = _source_filename; QUrl u(url_str, QUrl::TolerantMode); if (u.scheme() == "file" || QFileInfo::exists(_source_filename)) { // Local File QFile source(u.scheme() == "file" ? u.toLocalFile() : _source_filename); bool succeeded(false); if (action == Copy) succeeded = source.copy(_destination_filename); else if (action == Move) succeeded = source.rename(_destination_filename); if (!succeeded) _request_error_string = source.errorString(); _emit_request_finished(succeeded); } else { // Network File _fetch(u); } } void network::_fetch(const QUrl& url) { _destination_file.setFileName(_destination_filename); if (!_destination_file.open(QIODevice::WriteOnly)) { _request_error_string = tr("File '%1' cannot be written. %2").arg(_destination_filename, _destination_file.errorString()); _emit_request_finished(false); return; } QNetworkRequest request; request.setUrl(url); request.setRawHeader( "User-Agent", QString("cb2Bib/" + C2B_VERSION + " (https://www.molspaces.com/cb2bib/; mailto:cb2bib@molspaces.com; Bibliographic Browser Tool)") .toLatin1()); if (_fetch_operation == QNetworkAccessManager::PostOperation) { request.setHeader(QNetworkRequest::ContentTypeHeader, "application/x-www-form-urlencoded"); _current_reply = _fetcher->post(request, _fetch_url_query); } else _current_reply = _fetcher->get(request); connect(_current_reply, SIGNAL(readyRead()), this, SLOT(_fetch_ready_read())); connect(_current_reply, SIGNAL(finished()), SLOT(_fetch_finished())); connect(_current_reply, SIGNAL(error(QNetworkReply::NetworkError)), this, SLOT(logError())); connect(_current_reply, SIGNAL(downloadProgress(qint64,qint64)), this, SIGNAL(downloadProgress(qint64,qint64))); } void network::_fetch_finished() { _destination_file.close(); if (_current_reply->error() == QNetworkReply::OperationCanceledError) _destination_file.remove(); // Delete file else if (_redirection_count++ < _max_redirections) { const QUrl redirection(_current_reply->attribute(QNetworkRequest::RedirectionTargetAttribute).toUrl()); if (redirection.isValid()) { const QUrl ru(_current_reply->url().resolved(redirection)); _source_filename = ru.toString(); const int status(_current_reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt()); if ((status >= 301 && status <= 303) || status == 307) _fetch_operation = QNetworkAccessManager::GetOperation; _current_reply->deleteLater(); _fetch(ru); return; } } const bool succeeded(_current_reply->error() == QNetworkReply::NoError); if (succeeded) _file_mimetype_string = _current_reply->header(QNetworkRequest::ContentTypeHeader).toString(); else _request_error_string = _current_reply->errorString() + '.'; _current_reply->deleteLater(); _emit_request_finished(succeeded); } void network::_fetch_ready_read() { _destination_file.write(_current_reply->readAll()); } void network::logError() { c2bUtils::warn(tr("network::QNetworkReply log: %1").arg(_current_reply->errorString())); } cb2bib-2.0.1/src/c2b/PaxHeaders.5700/c2blib.pro0000644000000000000000000000007414011522151015416 xustar0030 atime=1613145424.834620334 30 ctime=1613145424.298620349 cb2bib-2.0.1/src/c2b/c2blib.pro0000644000175000001440000000164614011522151017017 0ustar00constansusers00000000000000LANGUAGE = C++ CONFIG += c++11 HEADERS += $$files(*.h) SOURCES += $$files(*.cpp) SOURCES -= $$files(moc_*.cpp) SOURCES -= $$files(qrc_*.cpp) RESOURCES += c2blib.qrc INCLUDEPATH += . QT = core network win32 { TARGET = ../../c2b } else { TARGET = ../c2b } CONFIG -= dll CONFIG += staticlib VERSION = 0.0.0 TEMPLATE = lib QMAKE_CXXFLAGS_DEBUG += -DC2B_DEBUG !use_lzsse : !use_lz4 : !use_lzo : !use_qt_zlib { CONFIG += use_lz4 } use_lzsse { message(cb2Bib will be linked against LZSSE library) DEFINES += C2B_USE_LZSSE SOURCES += ./lzsse4/lzsse4.cpp INCLUDEPATH += ./lzsse4 } use_lz4 { message(cb2Bib will be linked against LZ4 library) DEFINES += C2B_USE_LZ4 } use_lzo { message(cb2Bib will be linked against LZO library) DEFINES += C2B_USE_LZO } use_qt_zlib { message(cb2Bib will be linked against Qt ZLIB library) DEFINES += C2B_USE_ZLIB } use_avx2 { QMAKE_CXXFLAGS += -mavx2 } cb2bib-2.0.1/src/c2b/PaxHeaders.5700/document.h0000644000000000000000000000013214011522520015521 xustar0030 mtime=1613145424.718620337 30 atime=1613145424.834620334 30 ctime=1613145424.722620337 cb2bib-2.0.1/src/c2b/document.h0000644000175000001440000000242314011522520017121 0ustar00constansusers00000000000000/*************************************************************************** * Copyright (C) 2004-2021 by Pere Constans * constans@molspaces.com * cb2Bib version 2.0.1. Licensed under the GNU GPL version 3. * See the LICENSE file that comes with this distribution. ***************************************************************************/ #ifndef DOCUMENT_H #define DOCUMENT_H #include /** This class converts documents to unicode strings */ class document { public: enum Conversion { FirstPage, Complete }; document(const QString& fn, const Conversion mode); inline ~document() {} QString fileToString(const QString& fn); QString toString(); void setConverter(const Conversion mode); inline QString errorString() const { return _error_string.trimmed(); } inline QString logString() const { return _log_string.trimmed(); } static QString& normalize(QString& doc, const Conversion mode); private: Conversion _conversion_mode; QString _converter_arg; QString _converter_bin; QString _converter_output; QString _document_fn; QString _error_string; QString _log_string; void setConverter(const QString& bin, const QString& args); }; #endif cb2bib-2.0.1/src/c2b/PaxHeaders.5700/preprocess.h0000644000000000000000000000013214011522520016070 xustar0030 mtime=1613145424.742620336 30 atime=1613145424.834620334 30 ctime=1613145424.746620336 cb2bib-2.0.1/src/c2b/preprocess.h0000644000175000001440000000142314011522520017467 0ustar00constansusers00000000000000/*************************************************************************** * Copyright (C) 2004-2021 by Pere Constans * constans@molspaces.com * cb2Bib version 2.0.1. Licensed under the GNU GPL version 3. * See the LICENSE file that comes with this distribution. ***************************************************************************/ #ifndef PREPROCESS_H #define PREPROCESS_H #include #include /** @author Pere Constans */ class preprocess : public QObject { Q_OBJECT public: explicit preprocess(QObject* parento = 0); inline ~preprocess() {} public: void preprocessText(QString* text); public slots: void loadSettings(); private: bool FindReplaceInput; QStringList FindReplaceInputList; }; #endif cb2bib-2.0.1/src/c2b/PaxHeaders.5700/bibSearcher.cpp0000644000000000000000000000013214011522520016447 xustar0030 mtime=1613145424.598620341 30 atime=1613145424.830620334 30 ctime=1613145424.598620341 cb2bib-2.0.1/src/c2b/bibSearcher.cpp0000644000175000001440000006024614011522520020056 0ustar00constansusers00000000000000/*************************************************************************** * Copyright (C) 2004-2021 by Pere Constans * constans@molspaces.com * cb2Bib version 2.0.1. Licensed under the GNU GPL version 3. * See the LICENSE file that comes with this distribution. ***************************************************************************/ #include "bibSearcher.h" #include "bibParser.h" #include "settings.h" #include /** \page bibsearch Search BibTeX and PDF Document Files \section descrip Description - Search pattern \n Patterns and composite patterns can be either \htmlonly approximate strings, \endhtmlonly strings, contexts, regular expressions, or wildcard filters. Patterns admit Unicode characters. The scope of each pattern can be the reference as a whole or be focused on a particular reference field. The fields year, file, and journal are treated specifically. The field year has the qualifiers Exact, Newer, and Older. The field file can optionally refer to either the filename or the contents of such a file. Finally, for journal, the input pattern is duplicated to the, if available, journal fullname, and they two are checked against the journal actual field contents and, if available, its expanded contents. For example, typing 'ijqc' retrieves all references with journal being 'Int. J. Quantum Chem.'. Or, typing 'chemistry' retrieves any of 'J. Math. Chem.', 'J. Phys. Chem.', etc. This expansion is not performed when the pattern scope is set to all. - Search scope \n By default, searches are performed on the current BibTeX output file. If Scan all BibTeX files is checked the search will extend to all BibTeX files, extension .bib, present in the current directory. It might be therefore convenient to group all reference files in one common directory, or have them linked to that directory. When Scan linked documents is checked, and one or more pattern scope is all or file, the contents of the file in file is converted to text and scanned for that given pattern. See \ref c2bconf_utilities section to configure the external to text converter. - Search modifier \n \htmlonly cb2Bib converts TeX encoded characters to Unicode when parsing the references. This permits, for instance, for the pattern 'Møller' to retrieve either 'Møller' or 'M{\o}ller', without regard to how the BibTeX reference is written. By checking Simplify source, the reference and the converted PDF files are simplified to plain ASCII. In this way, the pattern '\bMoller\b' will hit any of 'Møller', 'M{\o}ller', or 'Moller'. Additionally, all non-word characters are removed, preserving only the ASCII, word structure of the source. Note that source simplification is only performed for the patterns whose scope is all or file contents, and that and so far, cb2Bib has only a subset of such conversions. Implemented TeX to Unicode conversions can be easily checked by entering a reference. The Unicode to ASCII letter-only conversion, on the other hand, is the one that cb2Bib also uses to write the reference IDs and, hence, the renaming of dropped files. cb2Bib can understand minor sub and superscript formatting. For instance, the pattern 'H2O' will retrieve 'H2O' from a BibTeX string H$_{2}$O. \endhtmlonly \section contextsearch Contextual Search A convenient way to retrieve documents is by matching a set of keywords appearing in a close proximity context, while disregarding the order in which the words might had been written. cb2Bib considers two types of contextual searches. One flexibilizes phrase matching only at the level of the constituting words. It is accessed by selecting Fixed string: Context in the pattern type box. The other one, in addition, stems the supplied keywords. It is accessed by selecting Context. By way of stemming, the keyword analyze, for example, will also match analyse, and aluminum will match aluminium too. The syntax for Context type patterns is summarized in the following table: \verbatim Operator Example Expansion space contextual search contextual AND search | contextual search|matching contextual AND (search|match) + contextual search|+matching contextual AND (search|\bmatching\b) _ contextual_search contextual.{0,25}search - non-parametric non.{0,1}parametr Diacritics and Greek letters: naïve search (naïve|naive) AND search kendall tau kendall AND (tau|τ) \endverbatim In the above examples, operator space AND means match words in any order. Operator _ preserves word order, and operator + prevents stemming and forces exact word match. Operator - considers cases of words that might had been written either united, hyphenated, or space separated. Diacritics are expanded if the diacritic mark is specified. This is, naive will not match naïve. On the other hand, Greek letters are expanded only when typed by name. \section notes Notes - cb2Bib uses an internal cache to speed up the search of linked files. By default data is stored as current_file.bib.c2b. It might be more convenient, however, to setup a temporary directory out of the user data backup directories. See Search In Files Cache Directory in \ref c2bconf_files. When a linked file is processed for the first time, cb2Bib does several string manipulations, such as removing end of line hyphenations. This process is time consuming for very large files. - The approximate string search is described in reference \htmlonly https://arxiv.org/abs/0705.0751. \endhtmlonly It reduces the chance of missing a hit due to transcription and decoding errors in the document files. Approximate string is also a form of serendipitous information retrieval. */ /** Top level driver for searching BibTeX files */ bibSearcher::bibSearcher(bibParser* bp, QObject* parento) : QObject(parento), _bpP(bp), _do_rank_results(true), _do_search_similar(false) { clear(); } /** Top level driver for searching BibTeX files. Specialized constructor for searching repeated or similar references. */ bibSearcher::bibSearcher(bibParser* bp, const QString& bib_dir, QObject* parento) : QObject(parento), _bpP(bp), _do_rank_results(false), _do_search_similar(true) { // Retrieve (any_author(context) AND any_title(approximate)) OR citeidName(exact) clear(); setSearchScope(bib_dir, bib_dir, true, false); setSimplifySource(false); setBoolean(true); addPattern(false, false, searchPattern::type(searchPattern::Context), QLatin1String("all"), QChar(), _bpP->currentReference().anyAuthor()); addPattern(false, false, searchPattern::type(searchPattern::ApproximateString), QLatin1String("all"), QChar(), _bpP->currentReference().anyTitle()); _do_search_similar_citeid = _bpP->currentReference().citeidName; if (_do_search_similar_citeid.isEmpty()) _do_search_similar_citeid = QLatin1Char('@'); } bibSearcher::bibSearcher() : _bpP(0), _do_rank_results(false), _do_search_similar(false) { clear(); } void bibSearcher::addPattern(bool Not, bool caseSensitive, const QString& patternType, const QString& scope, const QChar& yearScope, const QString& pattern) { if (pattern.trimmed().isEmpty()) return; _patterns.append(searchPattern(Not, caseSensitive, patternType, scope, yearScope, pattern)); if (!_scopes.contains(scope)) _scopes.append(scope); } void bibSearcher::exec() { if (_patterns.count() == 0 && !_do_search_similar) return; std::sort(_patterns.begin(), _patterns.end()); _include_documents = _include_documents && (_scopes.contains(QLatin1String("all")) || _scopes.contains(QLatin1String("file"))); if (_include_documents && !_scopes.contains(QLatin1String("file"))) _scopes.append(QLatin1String("file")); _scopes.removeAll(QLatin1String("all")); QString and_or; if (_boolean_and) and_or = QLatin1String(".AND."); else and_or = QLatin1String(".OR."); for (int i = 0; i < _patterns.count(); ++i) { const searchPattern& pattern = _patterns.at(i); _log_string += tr("% Pattern%1: %2%3\n").arg(i + 1).arg(and_or, pattern.toString()); } // Search In Files const QStringList flist(_all_bibtex_files ? c2bUtils::filesInDir(_bibtex_dir, QStringList() << "*.bib") : c2bUtils::filesInDir(_bibtex_file, QStringList() << "*.bib")); for (int i = 0; i < flist.count(); ++i) { search(flist.at(i)); if (_aborted) { clear(); _error_counter = -1; return; } } // Search Done _log_string += tr("% Scanned References: %1 BibTeX Files: %2 Linked Files: %3\n") .arg(_reference_counter) .arg(_bibtex_counter) .arg(_document_counter); if (_include_documents) _documents.unload(); if (_result_references.count() == 0) return; if (_do_rank_results) quadrupleSortDescending(&_result_scores, &_result_references, &_result_html_data, &_result_html_abstracts); _result_string = "\n\n" + _result_references.join("\n\n") + "\n\n"; _log_string += tr("% Total Unique Hits: %1\n").arg(_result_references.count()); #ifdef C2B_DEBUG_SEARCHING if (_result_scores.count() > 0) qDebug() << "Scores: " << _result_scores; #endif } QString bibSearcher::searchDocumentKeyword(const QString& bibtexfn, const QString& documentfn, const QString& keyword) { bibSearcher bs; QString exc; bs._documents.load(bibtexfn, documentContents::Complete); if (bs._documents.setCurrent(documentfn)) { QString p(keyword); p.replace(QRegExp("\\W"), ".{0,5}"); p.replace("s", ".?"); p = "\\b" + p + "\\w*\\b"; bs.addPattern(false, false, searchPattern::type(searchPattern::RegularExpression), QLatin1String("all"), QChar(), p); QString document(bs._documents.current().text()); c2bUtils::stripDiacritics(document); if (bs._patterns.at(0).matches(document)) { exc = c2bUtils::fileToString(":/htm/htm/excerpts.html"); exc.replace("GET_EXCERPTS_TITLE", keyword); exc.replace("GET_EXCERPTS", bs.excerpts(document).mid(20)); } } bs._documents.unload(); return exc; } void bibSearcher::abort() { _aborted = true; } void bibSearcher::clear() { _aborted = false; _all_bibtex_files = false; _bibtex_counter = 0; _bibtex_dir.clear(); _bibtex_file.clear(); _boolean_and = true; _do_search_similar_citeid.clear(); _document_counter = 0; _error_counter = 0; _include_documents = false; _log_string = "% cb2Bib " + C2B_VERSION + " / BibTeX Search Log\n"; _patterns.clear(); _reference_counter = 0; _reference_match_counter = 0; _reference_score = double(0); _result_html_abstracts.clear(); _result_html_data.clear(); _result_references.clear(); _result_scores.clear(); _result_string.clear(); _scopes.clear(); _simplify_source = false; } void bibSearcher::search(const QString& bib_file) { _bibtex_counter++; QString bib_file_contents; QFile file(bib_file); if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) { _error_counter++; _log_string += tr("% [cb2bib] Unable to open the file %1 for reading. Error: '%2'.\n").arg(bib_file, file.errorString()); return; } QTextStream stream(&file); stream.setCodec("UTF-8"); stream.setAutoDetectUnicode(true); bib_file_contents = stream.readAll(); _log_string += tr("% Scanning file %1\n").arg(bib_file.trimmed()); if (_include_documents) { if (_simplify_source) _documents.load(bib_file, documentContents::Simplified); else _documents.load(bib_file, documentContents::Complete); } const int hits(_result_references.count()); bibReference ref; _bpP->initReferenceParsing(bib_file, _scopes, &ref); while (_bpP->referencesIn(bib_file_contents, &ref)) { _reference_counter++; if (_do_search_similar) searchSimilarReferences(bib_file, ref); else searchReference(bib_file, ref); QCoreApplication::processEvents(); if (_aborted) return; } _log_string += tr("% File %1. Hits: %2\n").arg(bib_file.trimmed()).arg(_result_references.count() - hits); } void bibSearcher::searchReference(const QString& bib_file, const bibReference& ref) { const bool include_document( _include_documents && _documents.setCurrent(ref.value(QLatin1String("file")), &_document_counter, &_log_string, &_error_counter)); // Initialize composite search bool hit(_boolean_and); // Composite search for (int i = 0; i < _patterns.count(); ++i) { const searchPattern& pattern(_patterns.at(i)); const searchPattern::modifiers& modifier(pattern.modifier()); bool ihit(false); if (modifier.scope == QLatin1String("year")) { int istr(ref.value(modifier.scope).toInt()); int jstr(modifier.string.toInt()); if (modifier.yearScope == QLatin1Char('=')) ihit = istr == jstr; else if (modifier.yearScope == QLatin1Char('>')) ihit = istr >= jstr; else if (modifier.yearScope == QLatin1Char('<')) ihit = istr <= jstr; } else if (modifier.scope == QLatin1String("all")) { if (_simplify_source) ihit = pattern.matches(c2bUtils::toAscii(ref.unicodeReference, c2bUtils::FromBibTeX)); else ihit = pattern.matches(ref.unicodeReference); if (!ihit) if (include_document) ihit = pattern.matches(_documents.current()); } else if (modifier.scope == QLatin1String("journal")) { const QString pattern_full(_bpP->fullJournal(modifier.string)); const QString j_orig(ref.value(modifier.scope)); const QString j_full(_bpP->fullJournal(j_orig)); ihit = j_full == pattern_full || pattern.matches(j_orig) || pattern.matches(j_full); } else if (modifier.scope == QLatin1String("file") && include_document) ihit = pattern.matches(_documents.current()); else ihit = pattern.matches(ref.value(modifier.scope)); if (modifier.NOT) ihit = !ihit; if (_boolean_and) { hit = hit && ihit; if (!hit) break; } else { hit = hit || ihit; if (hit) break; } } if (hit) if (!_result_references.contains(ref.rawReference)) { _result_references.append(ref.rawReference); _reference_score = double(0); _reference_match_counter = 0; if (_scopes.contains(QLatin1String("title"))) setTitleRank(ref.value(QLatin1String("title"))); else if (_scopes.contains(QLatin1String("booktitle"))) setTitleRank(ref.value(QLatin1String("booktitle"))); if (_scopes.contains(QLatin1String("abstract"))) _result_html_abstracts.append(highlight(ref.value(QLatin1String("abstract")))); else _result_html_abstracts.append(highlight(_bpP->singleReferenceField(QLatin1String("abstract"), ref))); if (include_document) _result_html_data.append(location(bib_file, ref) + excerpts(_documents.current().text())); else _result_html_data.append(location(bib_file, ref)); _result_scores.append(_reference_score); #if C2B_DEBUG_SCORER _debug_scorer_scores.append(_reference_score); _debug_scorer_occurrences.append(_reference_match_counter); _debug_scorer_documents.append(_bpP->singleReferenceField(QLatin1String("title"), ref)); #endif } } void bibSearcher::searchSimilarReferences(const QString& bib_file, const bibReference& ref) { if (ref.citeidName == _do_search_similar_citeid) { if (!_result_references.contains(ref.rawReference)) { _result_references.append(ref.rawReference); _result_html_data.append(location(bib_file, ref)); } return; } if (_patterns.count() == 0) return; // Initialize composite search bool hit(_boolean_and); // Composite search for (int i = 0; i < _patterns.count(); ++i) { const searchPattern& pattern(_patterns.at(i)); hit = hit && pattern.matches(ref.unicodeReference); if (!hit) break; } if (hit) if (!_result_references.contains(ref.rawReference)) { _result_references.append(ref.rawReference); _result_html_data.append(location(bib_file, ref)); } } void bibSearcher::setTitleRank(const QString& title) { if (!_do_rank_results || title.isEmpty()) return; for (int i = 0; i < _patterns.count(); ++i) { const searchPattern& pattern(_patterns.at(i)); const searchPattern::modifiers& modifier(pattern.modifier()); pattern.initializeScores(); if (modifier.NOT) continue; if (modifier.scope != QLatin1String("title") && modifier.scope != QLatin1String("booktitle")) continue; int pos(0); while (pos >= 0) { pos = pattern.indexIn(title, pos); if (pos > -1) { pattern.updateScore(); pos += pattern.matchedLength(); } } _reference_score += 10 * pattern.matchedScore(); } } QString bibSearcher::excerpts(const QString& contents) { const int max_excerpts(25); const int max_unmerged_excerpts(max_excerpts + 100); QMap exc_endpos; for (int i = 0; i < _patterns.count(); ++i) { const searchPattern& pattern(_patterns.at(i)); const searchPattern::modifiers& modifier(pattern.modifier()); pattern.initializeScores(); if (modifier.NOT) continue; if (modifier.scope != QLatin1String("all") && modifier.scope != QLatin1String("file")) continue; int n_excerpts(0); int pos(0); while (pos >= 0) { pos = pattern.indexIn(contents, pos); if (pos > -1) { if (++n_excerpts > max_unmerged_excerpts) break; if (_do_rank_results) pattern.updateScore(); exc_endpos.insert(pos, std::max(pos + pattern.matchedLength(), exc_endpos.value(pos))); pos += pattern.matchedLength(); } } if (_do_rank_results) { _reference_score += pattern.matchedScore(); _reference_match_counter = pattern.matchedCounter(); } } if (exc_endpos.isEmpty()) return QString(); // Merge QList i_pos = exc_endpos.keys(); int pos0(i_pos.at(0)); for (int i = 1; i < i_pos.count(); ++i) { const int posi(i_pos.at(i)); if (exc_endpos.value(pos0) < posi) pos0 = posi; else { const int endposi(exc_endpos.value(posi)); exc_endpos.remove(posi); exc_endpos.insert(pos0, endposi); } } i_pos = exc_endpos.keys(); const int context_length(75); QString exc; QRegExp lead_truncated_words("^.*\\s(?=\\w)"); lead_truncated_words.setMinimal(true); QRegExp tail_truncated_words("\\W+\\w+\\W*$"); tail_truncated_words.setMinimal(true); bool item_begins(true); bool item_complete; const int items(std::min(i_pos.count(), max_excerpts)); for (int i = 0; i < items; ++i) { const int pos(i_pos.at(i)); const int length(exc_endpos.value(pos) - pos); const QString match(QLatin1String("") + c2bUtils::toHtmlString(contents.mid(pos, length)) + QLatin1String("")); if (item_begins) { QString pre_match(contents.mid(pos - context_length, context_length)); pre_match.remove(lead_truncated_words); pre_match = c2bUtils::toHtmlString(pre_match); exc += QLatin1String("• ...") + pre_match + match; } else exc += match; if (i + 1 == items) item_complete = true; else item_complete = exc_endpos.value(pos) + (2 * context_length) < i_pos.at(i + 1); if (item_complete) { QString post_match(contents.mid(pos + length, context_length)); post_match.remove(tail_truncated_words); post_match = c2bUtils::toHtmlString(post_match); exc += post_match + "... "; item_begins = true; } else { exc += contents.midRef(pos + length, i_pos.at(i + 1) - pos - length); item_begins = false; } } exc = QLatin1String("

") + exc; if (i_pos.count() >= max_excerpts) exc += tr("

Found more than %1 occurrences.").arg(max_excerpts); return exc; } QString bibSearcher::highlight(const QString& abstract) { if (abstract.isEmpty()) return abstract; QMap endpos; for (int i = 0; i < _patterns.count(); ++i) { const searchPattern& pattern(_patterns.at(i)); const searchPattern::modifiers& modifier(pattern.modifier()); pattern.initializeScores(); if (modifier.NOT) continue; if (modifier.scope != QLatin1String("all") && modifier.scope != QLatin1String("abstract")) continue; int pos(0); while (pos >= 0) { pos = pattern.indexIn(abstract, pos); if (pos > -1) { if (_do_rank_results) pattern.updateScore(); endpos.insert(pos, std::max(pos + pattern.matchedLength(), endpos.value(pos))); pos += pattern.matchedLength(); } } if (_do_rank_results) { _reference_score += pattern.matchedScore(); _reference_match_counter = pattern.matchedCounter(); } } if (endpos.isEmpty()) return c2bUtils::toHtmlString(abstract); // Merge QList i_pos = endpos.keys(); int pos0(i_pos.at(0)); for (int i = 1; i < i_pos.count(); ++i) { const int posi(i_pos.at(i)); if (endpos.value(pos0) < posi) pos0 = posi; else { const int endposi(endpos.value(posi)); endpos.remove(posi); endpos.insert(pos0, endposi); } } i_pos = endpos.keys(); QString hla; int npos(0); for (int i = 0; i < i_pos.count(); ++i) { const int pos(i_pos.at(i)); const int length(endpos.value(pos) - pos); hla += c2bUtils::toHtmlString(abstract.mid(npos, pos - npos)) + QLatin1String("") + c2bUtils::toHtmlString(abstract.mid(pos, length)) + QLatin1String(""); npos = endpos.value(pos); } hla += c2bUtils::toHtmlString(abstract.mid(npos, abstract.length() - npos)); return hla; } QString bibSearcher::location(const QString& fn, const bibReference& ref) const { const QString at("" "\"action\""); return at.arg(QDir::cleanPath(fn)).arg(ref.positionValue); } cb2bib-2.0.1/src/c2b/PaxHeaders.5700/triads.h0000644000000000000000000000013214011522520015171 xustar0030 mtime=1613145424.766620336 30 atime=1613145424.834620334 30 ctime=1613145424.770620336 cb2bib-2.0.1/src/c2b/triads.h0000644000175000001440000000162414011522520016573 0ustar00constansusers00000000000000/*************************************************************************** * Copyright (C) 2004-2021 by Pere Constans * constans@molspaces.com * cb2Bib version 2.0.1. Licensed under the GNU GPL version 3. * See the LICENSE file that comes with this distribution. ***************************************************************************/ #ifndef TRIADS_H #define TRIADS_H #include class triads { public: static const QString asciiTextSignature(const QString& str); static const QString textSignature(const QString& str); static const QVector textSignature(const QStringList& strs); static const QVector textFrequency(const QStringList& strs); static int textFrequency(const QString& str); private: inline triads() {} inline ~triads() {} static int _rank(const QString& str, const QString& sign, const QString& ranks); }; #endif cb2bib-2.0.1/src/c2b/PaxHeaders.5700/lzsse40000644000000000000000000000007414011522151014706 xustar0030 atime=1613145424.834620334 30 ctime=1613145424.302620349 cb2bib-2.0.1/src/c2b/lzsse4/0000755000175000001440000000000014011522151016355 5ustar00constansusers00000000000000cb2bib-2.0.1/src/c2b/lzsse4/PaxHeaders.5700/README.txt0000644000000000000000000000007414011522151016461 xustar0030 atime=1613145424.834620334 30 ctime=1613145424.302620349 cb2bib-2.0.1/src/c2b/lzsse4/README.txt0000644000175000001440000000030514011522151020051 0ustar00constansusers00000000000000 To use lzsse4 compressor download LZSSE/lzsse4 folder from https://github.com/ConorStokes/LZSSE/ and copy the the files LICENSE lzsse4_platform.h lzsse4.cpp lzsse4.h README.md in this folder. cb2bib-2.0.1/src/c2b/PaxHeaders.5700/texParser.h0000644000000000000000000000013214011522520015660 xustar0030 mtime=1613145424.762620336 30 atime=1613145424.834620334 30 ctime=1613145424.766620336 cb2bib-2.0.1/src/c2b/texParser.h0000644000175000001440000000367114011522520017266 0ustar00constansusers00000000000000/*************************************************************************** * Copyright (C) 2004-2021 by Pere Constans * constans@molspaces.com * cb2Bib version 2.0.1. Licensed under the GNU GPL version 3. * See the LICENSE file that comes with this distribution. ***************************************************************************/ #ifndef TEXPARSER_H #define TEXPARSER_H #include #include /** Minimalist TeX parser */ class texParser { public: inline texParser() : _stop_parsing(false) {} inline virtual ~texParser() {} protected: virtual void parseComment(const QString& /* p */) {} virtual void parseElement(const QString& /* p */, const QString& /* e */, const QString& /* v */) {} virtual void parseEmptyLine() {} virtual void parseLaTeXMarkup(const QString& /* p */, const QString& /* e */) {} virtual void parseTextParagraph(const QString& /* p */) {} void parse(QString tex); inline void stop() { _stop_parsing = true; } private: QString _element; QString _line; QString _paragraph; QTextStream _stream; bool _stop_parsing; void doElement(); void gotoEnd(const QString& e); void gotoEndBraces(const QString& e); void gotoEndMacro(const QString& e); inline const QString& readLine(const bool trim = false) { if (trim) _line = _stream.readLine().trimmed(); else _line = _stream.readLine(); return _line; } inline void flushElement(const QString& e, const QString& v) { flush(); parseElement(_element, e, v); } inline void flushLaTeXMarkup(const QString& e) { _element = _line; flush(); parseLaTeXMarkup(_element, e); } inline void flush() { if (_paragraph.isEmpty()) return; parseTextParagraph(_paragraph.mid(1)); _paragraph.clear(); } }; #endif cb2bib-2.0.1/src/c2b/PaxHeaders.5700/bibPreparser.cpp0000644000000000000000000000013214011522520016656 xustar0030 mtime=1613145424.594620341 30 atime=1613145424.830620334 30 ctime=1613145424.594620341 cb2bib-2.0.1/src/c2b/bibPreparser.cpp0000644000175000001440000000450614011522520020262 0ustar00constansusers00000000000000/*************************************************************************** * Copyright (C) 2004-2021 by Pere Constans * constans@molspaces.com * cb2Bib version 2.0.1. Licensed under the GNU GPL version 3. * See the LICENSE file that comes with this distribution. ***************************************************************************/ #include "bibPreparser.h" #include "cb2bib_utilities.h" #include "settings.h" #include bibPreparser::bibPreparser(QObject* parento) : QObject(parento) { settings* settingsP = settings::instance(); m_inp_file = settingsP->tempPath() + "/cb2bib_clipborad_inp.tmp_" + settingsP->applicationPid(); m_out_file = settingsP->tempPath() + "/cb2bib_clipborad_out.tmp_" + settingsP->applicationPid(); } void bibPreparser::preparse(const QString& text, QString* out_text) { out_text->clear(); if (!c2bUtils::stringToFile(text + '\n', m_inp_file)) { emit statusMessage(tr("Unable to open the file %1 for writing.").arg(m_inp_file)); return; } // External preparsing QStringList arguments; arguments.append(m_inp_file); arguments.append(m_out_file); QProcess preparser; preparser.start(settings::instance()->fileName("cb2Bib/PreparserBin"), arguments); if (!preparser.waitForFinished(2000)) { preparser.kill(); QFile ifile(m_inp_file); ifile.remove(); QFile ofile(m_out_file); ofile.remove(); emit statusMessage(tr("Failed to call %1.").arg(settings::instance()->fileName("cb2Bib/PreparserBin"))); return; } QFile ifile(m_inp_file); ifile.remove(); (*out_text) = c2bUtils::fileToString(m_out_file, true); if (out_text->isEmpty()) { emit statusMessage(tr("External Parsing ended. Input string remains unchanged.")); (*out_text) = text; } else emit statusMessage(tr("External Parsing ended.")); if (settings::instance()->value("cb2Bib/PreparserShowLog").toBool()) { QString log_string(QString::fromUtf8(preparser.readAllStandardOutput()) + '\n'); log_string += QString::fromUtf8(preparser.readAllStandardError()) + '\n'; log_string += QString("Input[\n%1\n]\n").arg(text); log_string += QString("Output[\n%1\n]\n").arg(*out_text); emit preparserLogAvailable(log_string); } } cb2bib-2.0.1/src/c2b/PaxHeaders.5700/heuristicBibParser.cpp0000644000000000000000000000013014011522520020025 xustar0029 mtime=1613145424.63062034 30 atime=1613145424.834620334 29 ctime=1613145424.63062034 cb2bib-2.0.1/src/c2b/heuristicBibParser.cpp0000644000175000001440000010506514011522520021435 0ustar00constansusers00000000000000/*************************************************************************** * Copyright (C) 2004-2021 by Pere Constans * constans@molspaces.com * cb2Bib version 2.0.1. Licensed under the GNU GPL version 3. * See the LICENSE file that comes with this distribution. ***************************************************************************/ #include "heuristicBibParser.h" #include "bibParser.h" #include "journalDB.h" #include #include heuristicBibParser::heuristicBibParser(bibParser* bp) : _bpP(bp), _current_reference(bp->_current_reference), _reliable_number(false), _reliable_pages(false), _reliable_volume(false), _abstract("abstract"), _addauthors("addauthors"), _author("author"), _isbn("isbn"), _keywords("keywords"), _number("number"), _pages("pages"), _title("title"), _volume("volume"), _year("year"), _bibliographic_fields(bp->_bibliographic_fields), _journal_db(*bp->_journal_dbP) { _leading_non_letters = QRegExp("^[^<\\w]+"); // Char 65533 appears many times in pdftotext outputs due to encoding errors _hyphens = QRegExp("\\s*[-" + QString(QChar(8211)) + QString(QChar(8722)) + QString(QChar(65533)) + "]+\\s*"); _hyphen_nums = "(?:\\d+|\\d+-\\d+)"; _hyphen_pages = "(?:\\d+|\\d+-\\d+p{0,2}|\\d+ \\d+pp)"; _max_year = 3 + QDate::currentDate().year(); // Setup author recognition // Implementation of author field extraction // P. Constans. A Simple Extraction Procedure for Bibliographical Author Field. // arXiv:0902.0755, 2009. _word_prefix_lexicon = c2bUtils::fileToString(":/txt/txt/word_prefix_lexicon.txt").split(c2bUtils::nonLetter, QString::SkipEmptyParts); for (int i = 0; i < _word_prefix_lexicon.count(); ++i) { _word_prefix_lexicon[i].replace('_', ' '); _word_prefix_lexicon[i].squeeze(); } const QString author_lc_t("(?:n%1n|n%1%1n|%1n|%1nn|%1%1n|%1%1%1n|n%1nn|nn%1n|%1%1nn|%1n%1n|nn|nnn)"); const QString author_uc_t( "(?:[nN]%1N|[nN]%1%1N|%1N|%1[nN]N|%1%1N|%1%1%1N|[nN]%1[nN]N|[nN]N%1N|%1%1[nN]N|%1[nN]%1N|[nN]N|[nN][nN]N)"); const QString author_initial("Ip{0,1}"); const QString author_line("L%1(?:[,;&L]+%1)*(?=L)"); const QString author_lc(author_line.arg(author_lc_t.arg(author_initial))); const QString author_uc(author_line.arg(author_uc_t.arg(author_initial))); const QString author_address("(?:L[^L]*)"); _author_sb = QRegExp(QString("L%1(?:[,;&]+L{0,2}%1)*[,;&L]*L").arg(author_lc_t.arg(author_initial)), Qt::CaseInsensitive, QRegExp::RegExp); _author_sb_lc = QRegExp(QString("L%1(?:[,;&L]+%1)*(?=L)").arg(author_lc_t.arg(author_initial)), Qt::CaseSensitive, QRegExp::RegExp); _author_sb_uc = QRegExp(QString("L%1(?:[,;&L]+%1)*(?=L)").arg(author_uc_t.arg(author_initial)), Qt::CaseSensitive, QRegExp::RegExp); _author_sb.setMinimal(false); _author_sb_lc.setMinimal(false); _author_sb_uc.setMinimal(false); // Note: Syntax must be RegExp and not RegExp2. // If not, in cases as 'LnnL ... Lnn,nn,Lnn,&nnL' it will overextend addresses to include Lnn,nn,L. // This is not related to minimal/greedy. // Note also that Lnn,nn,L will not be taken, unless it is followed by another author line. This is a feature. _author_b2_lc_rx = new QRegExp(QString("(%1)%2{0,7}(%1)").arg(author_lc, author_address), Qt::CaseSensitive, QRegExp::RegExp); _author_b2_uc_rx = new QRegExp(QString("(%1)%2{0,7}(%1)").arg(author_uc, author_address), Qt::CaseSensitive, QRegExp::RegExp); _author_b3_lc_rx = new QRegExp(QString("(%1)%2{0,7}(%1)%2{0,7}(%1)").arg(author_lc, author_address), Qt::CaseSensitive, QRegExp::RegExp); _author_b3_uc_rx = new QRegExp(QString("(%1)%2{0,7}(%1)%2{0,7}(%1)").arg(author_uc, author_address), Qt::CaseSensitive, QRegExp::RegExp); _author_b4_lc_rx = new QRegExp(QString("(%1)%2{0,7}(%1)%2{0,7}(%1)%2{0,7}(%1)").arg(author_lc, author_address), Qt::CaseSensitive, QRegExp::RegExp); _author_b4_uc_rx = new QRegExp(QString("(%1)%2{0,7}(%1)%2{0,7}(%1)%2{0,7}(%1)").arg(author_uc, author_address), Qt::CaseSensitive, QRegExp::RegExp); _author_b5_lc_rx = new QRegExp(QString("(%1)%2{0,7}(%1)%2{0,7}(%1)%2{0,7}(%1)%2{0,7}(%1)").arg(author_lc, author_address), Qt::CaseSensitive, QRegExp::RegExp); _author_b5_uc_rx = new QRegExp(QString("(%1)%2{0,7}(%1)%2{0,7}(%1)%2{0,7}(%1)%2{0,7}(%1)").arg(author_uc, author_address), Qt::CaseSensitive, QRegExp::RegExp); _author_b2_lc_rx->setMinimal(true); _author_b2_uc_rx->setMinimal(true); _author_b3_lc_rx->setMinimal(true); _author_b3_uc_rx->setMinimal(true); _author_b4_lc_rx->setMinimal(true); _author_b4_uc_rx->setMinimal(true); _author_b5_lc_rx->setMinimal(true); _author_b5_uc_rx->setMinimal(true); } heuristicBibParser::~heuristicBibParser() { delete _author_b2_lc_rx; delete _author_b2_uc_rx; delete _author_b3_lc_rx; delete _author_b3_uc_rx; delete _author_b4_lc_rx; delete _author_b4_uc_rx; delete _author_b5_lc_rx; delete _author_b5_uc_rx; } void heuristicBibParser::guessFields(const QString& clean_text, const QString& tagged_text) { QString clean_num(clean_text); clean_num.replace(_hyphens, "-"); // Order is important to increase the chances of a proper recognition guessJournal(clean_text); guessAbstract(tagged_text); guessAuthor(tagged_text); guessKeywords(tagged_text); guessYear(clean_num); _debug_guess("guessYear"); guessVolume(clean_num); _debug_guess("guessVolume"); guessNumber(clean_num); _debug_guess("guessNumber"); guessPages(clean_num); _debug_guess("guessPages"); guessTitle(tagged_text); guessISBN(clean_num); guessVolumeYearPages(clean_num); _debug_guess("guessVolumeYearPages"); guessYearVolumePages(clean_num); _debug_guess("guessYearVolumePages"); guessVolumePagesYear(clean_num); _debug_guess("guessVolumePagesYear"); guessFromMetadata(clean_text); } void heuristicBibParser::heuristicFields(const QString& text) { // Heuristics for reasonably secure extraction QRegExp rxdoi("(10\\.[\\d\\.]+/\\S+)"); if (rxdoi.indexIn(text) > -1) { QString cdoi(rxdoi.cap(1)); // This happens when publishers set doi to title in metadata: doi:10. ... if (cdoi.endsWith("")) cdoi.chop(8); cdoi.remove(QRegExp("[\\,\"\\}\\)]+$")); _current_reference["doi"] = _bpP->parse("doi", cdoi); } QRegExp rxarxiv("arXiv:([\\w\\./-]+)"); if (rxarxiv.indexIn(text) > -1) { // https://arxiv.org/hypertex/bibstyles/ QString aid(rxarxiv.cap(1)); aid.remove(QRegExp("v\\d{1,2}$")); _current_reference["eprint"] = _bpP->parse("eprint", aid); _current_reference["journal"] = _bpP->parse("journal", "arXiv:" + aid); _current_reference["url"] = _bpP->parse("url", c2bUtils::arxivUrl.arg(aid)); } QRegExp rxhtml("((http://|https://|ftp://|www\\.|ftp\\.)(www\\.|ftp\\.){0,1}\\S+)"); if (rxhtml.indexIn(text) > -1) _current_reference["url"] = _bpP->parse("url", rxhtml.cap(1)); } /** \page heuristics Field Recognition Rules - Abstract - If Abstract\b is found. - If Summary\b is found. */ void heuristicBibParser::guessAbstract(const QString& text) { // Check whether text might come from a web page or from a PDF with new lines // Set line length to 93 // Check first for abstract, check later for summary if (text.contains("Abstract", Qt::CaseInsensitive)) { const QString crl(QChar(169)); // Avoid abstract overextending to copyright line. QRegExp rxH("(?:|)\\s*Abstract[\\s\\.:]*(.+)(?:" + crl + "| -1) if (rxH.cap(1).length() > 93) { const QString val(rxH.cap(1).remove(_leading_non_letters)); _current_reference[_abstract] = _bpP->parse(_abstract, val); return; } rxH = QRegExp("(?:|)\\s*Abstract[\\s\\.:]*(.+)(?:" + crl + "|\\s* -1) { const QString val(rxH.cap(1).remove(_leading_non_letters)); _current_reference[_abstract] = _bpP->parse(_abstract, val); return; } rxH = QRegExp("(?:|)\\s*Abstract\\b(.+)(?:" + crl + "| -1) if (rxH.cap(1).length() > 93) { const QString val(rxH.cap(1).remove(_leading_non_letters)); _current_reference[_abstract] = _bpP->parse(_abstract, val); return; } rxH = QRegExp("(?:|)\\s*Abstract\\b(.+)(?:" + crl + "|\\s* -1) { const QString val(rxH.cap(1).remove(_leading_non_letters)); _current_reference[_abstract] = _bpP->parse(_abstract, val); return; } } if (text.contains("Summary", Qt::CaseInsensitive)) { QRegExp rxH("(?:|)\\s*Summary[\\s\\.:]*(.+)(?: -1) if (rxH.cap(1).length() > 93) { const QString val(rxH.cap(1).remove(_leading_non_letters)); _current_reference[_abstract] = _bpP->parse(_abstract, val); return; } rxH = QRegExp("(?:|)\\s*Summary[\\s\\.:]*(.+)(?:\\s* -1) { const QString val(rxH.cap(1).remove(_leading_non_letters)); _current_reference[_abstract] = _bpP->parse(_abstract, val); return; } rxH = QRegExp("(?:|)\\s*Summary\\b(.+)(?: -1) if (rxH.cap(1).length() > 93) { const QString val(rxH.cap(1).remove(_leading_non_letters)); _current_reference[_abstract] = _bpP->parse(_abstract, val); return; } rxH = QRegExp("(?:|)\\s*Summary\\b(.+)(?:\\s* -1) { const QString val(rxH.cap(1).remove(_leading_non_letters)); _current_reference[_abstract] = _bpP->parse(_abstract, val); return; } } } /** \page heuristics Field Recognition Rules - Author - Check capitalization patterns. See \htmlonly A Simple Extraction Procedure for Bibliographical Author Field. \endhtmlonly */ void heuristicBibParser::guessAuthor(const QString& tagged_text) { // Prepare input stream QString simplified_text("| " + tagged_text + " |"); simplified_text.replace('|', ' '); simplified_text = "| " + simplified_text + " |"; simplified_text.replace(QRegExp(""), " | "); simplified_text.replace(QRegExp("(\\w)(\\w)"), "\\1 , \\2"); simplified_text.replace(QRegExp(""), " "); simplified_text.remove(QRegExp("author.{0,3}:{0,1}", Qt::CaseInsensitive)); simplified_text.replace(QRegExp("(\\w{4,10})[a-z]\\)", Qt::CaseSensitive), "\\1 "); // Remove superscript, e. g. LASTNAMEa simplified_text.replace(QRegExp("([A-Z]{2,10})[a-z]\\b", Qt::CaseSensitive), "\\1 "); // Remove superscript, e. g. LASTNAMEa) simplified_text.replace(_hyphens, "-"); simplified_text.replace(QChar(183), ','); // Fancy author separator simplified_text.replace(' ' + QChar(198) + ' ', " , "); // Fancy author separator simplified_text.replace(QChar(8226), ','); // Fancy author separator simplified_text.replace(QChar(178), ' '); // Superscript dagger as sometimes translated by pdftotext _aencoder.aunifier.simplifyString(simplified_text); // Capitalize and encode for (int i = 0; i < _word_prefix_lexicon.count(); ++i) { const QString& wp = _word_prefix_lexicon.at(i); simplified_text.replace(wp, wp, Qt::CaseInsensitive); } simplified_text.replace(" by ", " "); _aencoder.encode(simplified_text); const QString sb_author(guessAuthor_single_block()); const int n_sb_author(authorCount(sb_author)); const QString mb_author(guessAuthor_multi_block()); const int n_mb_author(authorCount(mb_author)); if (n_mb_author > n_sb_author) _current_reference[_author] = mb_author; else _current_reference[_author] = sb_author; } QString heuristicBibParser::guessAuthor_single_block() { QString author; if (_author_sb_lc.indexIn(_aencoder.code) > -1) author = _bpP->parse(_author, _aencoder.decoded(_author_sb_lc.pos(0), _author_sb_lc.matchedLength())); else if (_author_sb_uc.indexIn(_aencoder.code) > -1) author = _bpP->parse(_author, _aencoder.decoded(_author_sb_uc.pos(0), _author_sb_uc.matchedLength())); else if (_author_sb.indexIn(_aencoder.code) > -1) // Few cases are extracted by _author_sb, keep it for cases 'A. Name,', with ',' usually coming // from a faulty plain text conversion. author = _bpP->parse(_author, _aencoder.decoded(_author_sb.pos(0), _author_sb.matchedLength())); return author; } QString heuristicBibParser::guessAuthor_multi_block() { QString author; if (_author_b5_uc_rx->indexIn(_aencoder.code) > -1) for (int i = 1; i < _author_b5_uc_rx->capturedTexts().count(); ++i) author = _bpP->parse( _addauthors, _aencoder.decoded(_author_b5_uc_rx->pos(i), _author_b5_uc_rx->cap(i).length()), author); else if (_author_b5_lc_rx->indexIn(_aencoder.code) > -1) for (int i = 1; i < _author_b5_lc_rx->capturedTexts().count(); ++i) author = _bpP->parse( _addauthors, _aencoder.decoded(_author_b5_lc_rx->pos(i), _author_b5_lc_rx->cap(i).length()), author); else if (_author_b4_uc_rx->indexIn(_aencoder.code) > -1) for (int i = 1; i < _author_b4_uc_rx->capturedTexts().count(); ++i) author = _bpP->parse( _addauthors, _aencoder.decoded(_author_b4_uc_rx->pos(i), _author_b4_uc_rx->cap(i).length()), author); else if (_author_b4_lc_rx->indexIn(_aencoder.code) > -1) for (int i = 1; i < _author_b4_lc_rx->capturedTexts().count(); ++i) author = _bpP->parse( _addauthors, _aencoder.decoded(_author_b4_lc_rx->pos(i), _author_b4_lc_rx->cap(i).length()), author); else if (_author_b3_uc_rx->indexIn(_aencoder.code) > -1) for (int i = 1; i < _author_b3_uc_rx->capturedTexts().count(); ++i) author = _bpP->parse( _addauthors, _aencoder.decoded(_author_b3_uc_rx->pos(i), _author_b3_uc_rx->cap(i).length()), author); else if (_author_b3_lc_rx->indexIn(_aencoder.code) > -1) for (int i = 1; i < _author_b3_lc_rx->capturedTexts().count(); ++i) author = _bpP->parse( _addauthors, _aencoder.decoded(_author_b3_lc_rx->pos(i), _author_b3_lc_rx->cap(i).length()), author); else if (_author_b2_uc_rx->indexIn(_aencoder.code) > -1) for (int i = 1; i < _author_b2_uc_rx->capturedTexts().count(); ++i) author = _bpP->parse( _addauthors, _aencoder.decoded(_author_b2_uc_rx->pos(i), _author_b2_uc_rx->cap(i).length()), author); else if (_author_b2_lc_rx->indexIn(_aencoder.code) > -1) for (int i = 1; i < _author_b2_lc_rx->capturedTexts().count(); ++i) author = _bpP->parse( _addauthors, _aencoder.decoded(_author_b2_lc_rx->pos(i), _author_b2_lc_rx->cap(i).length()), author); return author; } int heuristicBibParser::authorCount(const QString& authors) { if (authors.isEmpty()) return 0; return 1 + authors.count(" and "); } /** \page heuristics - Keywords - If Key\\s{0,1}words\b is found. */ void heuristicBibParser::guessKeywords(const QString& text) { QRegExp rxH("<(?:NewLine|Tab)\\d+>\\s*Key\\s{0,1}words and phrases[\\s\\.:]*(.+)( -1) { const QString val(rxH.cap(1).remove(_leading_non_letters)); _current_reference[_keywords] = _bpP->parse(_keywords, val); return; } rxH = QRegExp("<(?:NewLine|Tab)\\d+>\\s*Key\\s{0,1}words and phrases\\b(.+)( -1) { const QString val(rxH.cap(1).remove(_leading_non_letters)); _current_reference[_keywords] = _bpP->parse(_keywords, val); } rxH = QRegExp("<(?:NewLine|Tab)\\d+>\\s*Key\\s{0,1}words[\\s\\.:]*(.+)( -1) { const QString val(rxH.cap(1).remove(_leading_non_letters)); _current_reference[_keywords] = _bpP->parse(_keywords, val); return; } rxH = QRegExp("<(?:NewLine|Tab)\\d+>\\s*Key\\s{0,1}words\\b(.+)( -1) { const QString val(rxH.cap(1).remove(_leading_non_letters)); _current_reference[_keywords] = _bpP->parse(_keywords, val); } } /** \page heuristics - Volume - If Volume:{0,1} is found. - If Vol.{0,1} is found. - If \\b(\\d+)[,:]\\s*\\d+\\W+\\d+ is found. - If \\b(\\d+)\\s*\\(\\d+\\) is found. - If \\b(\\d+)[,:]\\s*\\d+\\b is found. */ void heuristicBibParser::guessVolume(const QString& text) { _reliable_volume = true; QRegExp rxH("Volumes{0,1}:{0,1}\\s*(" + _hyphen_nums + ')', Qt::CaseInsensitive); int nH(rxH.indexIn(text)); if (nH > -1) { _current_reference[_volume] = _bpP->parse(_volume, rxH.cap(1)); return; } rxH = QRegExp("Vols{0,1}\\.{0,1}\\s*(" + _hyphen_nums + ')', Qt::CaseInsensitive); nH = rxH.indexIn(text); if (nH > -1) { _current_reference[_volume] = _bpP->parse(_volume, rxH.cap(1)); return; } rxH = QRegExp("\\b(\\d+)\\s*\\(" + _hyphen_nums + "\\)[,:]\\s*pp\\.{0,1}\\s*\\d+", Qt::CaseInsensitive); nH = rxH.indexIn(text); if (nH > -1) { _current_reference[_volume] = _bpP->parse(_volume, rxH.cap(1)); return; } rxH = QRegExp("\\b(\\d+)[,:]\\s*pp\\.{0,1}\\s*\\d+", Qt::CaseInsensitive); nH = rxH.indexIn(text); if (nH > -1) { _current_reference[_volume] = _bpP->parse(_volume, rxH.cap(1)); return; } _reliable_volume = false; rxH = QRegExp("(\\d+)\\s*\\(" + _hyphen_nums + "\\)[,:]\\s*\\d+", Qt::CaseInsensitive); nH = rxH.indexIn(text); if (nH > -1) { _current_reference[_volume] = _bpP->parse(_volume, rxH.cap(1)); return; } rxH = QRegExp("\\b(\\d+)\\s*\\(\\d+\\)"); nH = rxH.indexIn(text); if (nH > -1) { _current_reference[_volume] = _bpP->parse(_volume, rxH.cap(1)); return; } rxH = QRegExp("\\b(\\d+)[,:]\\s*" + _hyphen_nums, Qt::CaseInsensitive); nH = rxH.indexIn(text); if (nH > -1) { _current_reference[_volume] = _bpP->parse(_volume, rxH.cap(1)); return; } rxH = QRegExp("\\b(\\d+)[,:]\\s*\\d+\\b"); nH = rxH.indexIn(text); if (nH > -1) _current_reference[_volume] = _bpP->parse(_volume, rxH.cap(1)); } /** \page heuristics - Number - If Numbers{0,1}:{0,1}\\s*([\\d-]+) is found. - If No\\.{0,1}\\s*(\\d+) is found. - If Issue\\:{0,1}\\s*(\\d+) is found. - If \\d\\s*\\((\\d+)\\)[^\\.] is found. */ void heuristicBibParser::guessNumber(const QString& text) { _reliable_number = true; QRegExp rxH("Numbers{0,1}\\:{0,1}\\s*(" + _hyphen_nums + ')', Qt::CaseInsensitive); int nH(rxH.indexIn(text)); if (nH > -1) { _current_reference[_number] = _bpP->parse(_number, rxH.cap(1)); return; } rxH = QRegExp("Nos{0,1}\\.{0,1}\\s*(" + _hyphen_nums + ')', Qt::CaseInsensitive); nH = rxH.indexIn(text); if (nH > -1) { _current_reference[_number] = _bpP->parse(_number, rxH.cap(1)); return; } rxH = QRegExp("Issues{0,1}\\:{0,1}\\s*(" + _hyphen_nums + ')', Qt::CaseInsensitive); nH = rxH.indexIn(text); if (nH > -1) { _current_reference[_number] = _bpP->parse(_number, rxH.cap(1)); return; } _reliable_number = false; rxH = QRegExp("\\d\\s*\\((" + _hyphen_nums + ")\\)[^\\.]"); nH = rxH.indexIn(text); if (nH > -1) if (rxH.cap(1) != _current_reference.value(_year)) // Avoid confusing (number) and (year) _current_reference[_number] = _bpP->parse(_number, rxH.cap(1)); } /** \page heuristics - Pages - If \\bPages{0,1}[:\\.]{0,1}([\\d\\s-]+) is found. - If \\bp{1,2}\\.{0,1}\\s+(\\d+) is found. - If \\b(\\d+)\\s*-{1,2}\\s*(\\d+pp)\\b is found. - If \\b(\\d+)\\s*-{1,2}\\s*(\\d+)\\b is found. */ void heuristicBibParser::guessPages(const QString& text) { _reliable_pages = true; QRegExp rxH("\\bPages{0,1}[:\\.]{0,1}\\s*((?!\\()" + _hyphen_nums + "(?!\\)))", Qt::CaseInsensitive); int nH(rxH.indexIn(text)); if (nH > -1) { _current_reference[_pages] = _bpP->parse(_pages, rxH.cap(1)); return; } rxH = QRegExp("(?!\\()(\\d+[\\s-]\\d+pp)(?!\\))", Qt::CaseInsensitive); nH = rxH.indexIn(text); if (nH > -1) { _current_reference[_pages] = _bpP->parse(_pages, rxH.cap(1)); return; } rxH = QRegExp("\\bpp\\.{0,1}\\s+(" + _hyphen_nums + ')', Qt::CaseInsensitive); nH = rxH.indexIn(text); if (nH > -1) { _current_reference[_pages] = _bpP->parse(_pages, rxH.cap(1)); return; } _reliable_pages = false; rxH = QRegExp("\\bp\\.{0,1}\\s+(" + _hyphen_nums + ')'); nH = rxH.indexIn(text); if (nH > -1) { _current_reference[_pages] = _bpP->parse(_pages, rxH.cap(1)); return; } rxH = QRegExp("\\d+\\s*\\(" + _hyphen_nums + "\\),{0,1}\\s*(" + _hyphen_nums + ')'); nH = rxH.indexIn(text); // 120 (1-3), 927 if (nH > -1) { _current_reference[_pages] = _bpP->parse(_pages, rxH.cap(1)); return; } rxH = QRegExp("(?!\\()(\\d+)\\s*-{1,2}\\s*(\\d+)\\b(?!\\))"); nH = 0; while (nH >= 0) { nH = rxH.indexIn(text, nH); if (nH > -1) { if (!rxH.cap(1).startsWith('0')) { const QString pp(_bpP->parse(_pages, QString("%1 %2").arg(rxH.cap(1), rxH.cap(2)))); const QStringList flpp(pp.split(QRegExp("\\D"), QString::SkipEmptyParts)); if (flpp.count() != 2) continue; const int fp(flpp.first().toInt()); const int lp(flpp.last().toInt()); if (fp < lp && lp - fp < 250) { _current_reference[_pages] = pp; return; } } nH += rxH.matchedLength(); } } } /** \page heuristics - Year - If \\b(19|20)(\\d\\d)\\b is found. */ void heuristicBibParser::guessYear(const QString& text) { QRegExp rxH("\\((19|20)(\\d\\d)\\)"); int nH(rxH.indexIn(text)); if (nH > -1) { const QString y(_bpP->parse(_year, rxH.cap(1) + rxH.cap(2))); if (y.toInt() < _max_year) { _current_reference[_year] = y; return; } } rxH = QRegExp("\\d+:" + _hyphen_nums + "[,\\s]+(19|20)(\\d\\d)\\b"); nH = rxH.indexIn(text); // 44:2077 – 2082, 2004. if (nH > -1) { const QString y(_bpP->parse(_year, rxH.cap(1) + rxH.cap(2))); if (y.toInt() < _max_year) { _current_reference[_year] = y; return; } } rxH = QRegExp("\\b(19|20)(\\d\\d)\\b"); nH = rxH.indexIn(text); if (nH > -1) { const QString y(_bpP->parse(_year, rxH.cap(1) + rxH.cap(2))); if (y.toInt() < _max_year) { _current_reference[_year] = y; return; } } } /** \page heuristics - Title - If \\bTitle:{0,1} is found. */ void heuristicBibParser::guessTitle(const QString& text) { QRegExp rxH("\\bTitle:{0,1}\\s*(.+)( -1) { QString val(rxH.cap(1).remove(_leading_non_letters)); _current_reference[_title] = _bpP->parse(_title, val); return; } rxH = QRegExp("\\bTitle:{0,1}(.+)( -1) { QString val(rxH.cap(1).remove(_leading_non_letters)); _current_reference[_title] = _bpP->parse(_title, val); } } /** \page heuristics - ISBN - If \\bISBN\\b(?:-\\d+){0,1}:{0,1}(?:-\\d+){0,1}\\s*(\\d+-[\\d-]+-\\d+) is found. - If \\bISBN\\b(?:-\\d+){0,1}:{0,1}(?:-\\d+){0,1}\\s*(\\d+) is found. */ void heuristicBibParser::guessISBN(const QString& text) { QRegExp rxH("\\bISBN\\b(?:[ -]\\d+){0,1}:{0,1}(?:-\\d+){0,1}\\s*(\\d+-[\\d-]+-\\d+)", Qt::CaseInsensitive); int nH(rxH.indexIn(text)); if (nH > -1) { _current_reference[_isbn] = _bpP->parse(_isbn, rxH.cap(1)); return; } rxH = QRegExp("\\bISBN\\b(?:[ -]\\d+){0,1}:{0,1}(?:-\\d+){0,1}\\s*(\\d+)", Qt::CaseInsensitive); nH = rxH.indexIn(text); if (nH > -1) { _current_reference[_isbn] = _bpP->parse(_isbn, rxH.cap(1)); return; } } /** \page heuristics - Journal - Check cb2Bib internal database. */ void heuristicBibParser::guessJournal(const QString& text) { QString stext(text.toLower()); stext.remove(c2bUtils::nonLetter); if (stext.length() < 3 || stext.length() > 10000) return; const int pheader(0); const int pfooter(stext.length()); double oscore(0); int oindex(-1); QStringMatcher blank(" "); for (int i = 0; i < _journal_db.count(); ++i) if (blank.indexIn(_journal_db.retrieveFull(i)) >= 0) { const int p(stext.indexOf(_journal_db.fullsimplifiedFull(i), 0, Qt::CaseSensitive)); if (p == -1) continue; const int jlength(_journal_db.fullsimplifiedFull(i).length()); const int d(1 + std::min(p - pheader, pfooter - p - jlength)); const double score(pow(double(jlength), 1.75) / double(d)); if (score > oscore) { oscore = score; oindex = i; } } for (int i = 0; i < _journal_db.count(); ++i) { const int p(stext.indexOf(_journal_db.fullsimplified(i), 0, Qt::CaseSensitive)); if (p == -1) continue; const int jlength(_journal_db.fullsimplified(i).length()); const int d(1 + std::min(p - pheader, pfooter - p - jlength)); const double score(pow(double(jlength), 1.75) / double(d)); if (score > oscore) { oscore = score; oindex = i; } } if (oscore > double(1) && oindex > -1) _current_reference["journal"] = _bpP->parse("journal", _journal_db.retrieve(oindex)); } void heuristicBibParser::guessFromMetadata(const QString& text) { if (!text.contains("[Bibliographic Metadata")) return; QRegExp bf; bf.setMinimal(true); bf.setCaseSensitivity(Qt::CaseSensitive); QString p("<%1>(.+)"); for (int i = 0; i < _bibliographic_fields.count(); ++i) { bf.setPattern(p.arg(_bibliographic_fields.at(i))); if (bf.indexIn(text) > -1) _current_reference[_bibliographic_fields.at(i)] = _bpP->parse(_bibliographic_fields.at(i), bf.cap(1)); } } void heuristicBibParser::guessVolumePagesYear(const QString& text) { // Does several volume pages year formats if (_reliable_pages && _reliable_volume && _reliable_number) return; // J. Sci., 108 (15), 3206, 2004 // J. Sci., 108 (15), 3206 2004 QRegExp rxH("(\\d+)\\s*\\((" + _hyphen_nums + ")\\)\\s*[,:]\\s*(" + _hyphen_pages + ")[,\\s]+(19|20)(\\d\\d)"); int nH(rxH.indexIn(text)); if (nH > -1) { _current_reference[_volume] = _bpP->parse(_volume, rxH.cap(1)); _current_reference[_number] = _bpP->parse(_number, rxH.cap(2)); _current_reference[_pages] = _bpP->parse(_pages, rxH.cap(3)); _current_reference[_year] = _bpP->parse(_year, rxH.cap(4) + rxH.cap(5)); return; } // J. Sci., 108 (15), 3206 (2004) rxH = QRegExp("(\\d+)\\s*\\((" + _hyphen_nums + ")\\)\\s*[,:]\\s*(" + _hyphen_pages + ")[,\\s]*\\((19|20)(\\d\\d)\\)"); nH = rxH.indexIn(text); if (nH > -1) { _current_reference[_volume] = _bpP->parse(_volume, rxH.cap(1)); _current_reference[_number] = _bpP->parse(_number, rxH.cap(2)); _current_reference[_pages] = _bpP->parse(_pages, rxH.cap(3)); _current_reference[_year] = _bpP->parse(_year, rxH.cap(4) + rxH.cap(5)); return; } if (_reliable_pages && _reliable_volume) return; // J. Sci. 124, 204109 2006 // J. Sci. 124, 204109, 2006 rxH = QRegExp("(\\d+)[,:]\\s*(" + _hyphen_pages + ")[,\\s]+(19|20)(\\d\\d)"); nH = rxH.indexIn(text); if (nH > -1) { _current_reference[_volume] = _bpP->parse(_volume, rxH.cap(1)); _current_reference[_pages] = _bpP->parse(_pages, rxH.cap(2)); _current_reference[_year] = _bpP->parse(_year, rxH.cap(3) + rxH.cap(4)); return; } // 120, 8425 - 8433 (2004) // J. Sci. 30, 2745 (1984) rxH = QRegExp("(\\d+)[,:]\\s*(" + _hyphen_pages + ")[,\\s]*\\((19|20)(\\d\\d)\\)"); nH = rxH.indexIn(text); if (nH > -1) { _current_reference[_volume] = _bpP->parse(_volume, rxH.cap(1)); _current_reference[_pages] = _bpP->parse(_pages, rxH.cap(2)); _current_reference[_year] = _bpP->parse(_year, rxH.cap(3) + rxH.cap(4)); return; } } void heuristicBibParser::guessVolumeYearPages(const QString& text) { // Does several volume year pages formats if (_reliable_number && _reliable_volume) return; // J. Sci. 203 (2003) 209. QRegExp rxH("(\\d+)\\s*\\(" + _current_reference.value(_year) + "\\)\\s*(" + _hyphen_pages + ')'); int nH(rxH.indexIn(text)); if (nH > -1) { _current_reference[_volume] = _bpP->parse(_volume, rxH.cap(1)); _current_reference[_pages] = _bpP->parse(_pages, rxH.cap(2)); return; } } void heuristicBibParser::guessYearVolumePages(const QString& text) { // Does several year volume pages formats if (_reliable_pages && _reliable_volume && _reliable_number) return; // J. Sci. 1995 January 25; 247(4):536-40. // J. Sci. 1995, 247(4):536-40. QRegExp rxH(_current_reference.value(_year) + "[\\w ]{0,15}[,:; ]\\s*(\\d+)\\s*\\((" + _hyphen_nums + ")\\)\\s*[,:;]\\s*(" + _hyphen_pages + ')'); int nH(rxH.indexIn(text)); if (nH > -1) { _current_reference[_volume] = _bpP->parse(_volume, rxH.cap(1)); _current_reference[_number] = _bpP->parse(_number, rxH.cap(2)); _current_reference[_pages] = _bpP->parse(_pages, rxH.cap(3)); _reliable_pages = true; _reliable_volume = true; return; } // J. Sci. (1999), 86, 3, pp. 635-648 rxH = QRegExp("\\(" + _current_reference.value(_year) + "\\)" + "\\s*[,:;]\\s*(\\d+)\\s*[,:;]\\s*(" + _hyphen_nums + ")\\s*[,:;]\\s*(?:pp)?\\.?\\s*(" + _hyphen_pages + ')'); nH = rxH.indexIn(text); if (nH > -1) { _current_reference[_volume] = _bpP->parse(_volume, rxH.cap(1)); _current_reference[_number] = _bpP->parse(_number, rxH.cap(2)); _current_reference[_pages] = _bpP->parse(_pages, rxH.cap(3)); _reliable_pages = true; _reliable_volume = true; return; } if (_reliable_volume) return; // J. Sci. 1995 January 25; 247:536-40. // J. Sci. 2005, 103, 818 // J. Sci. 2002;9:101–106.5. rxH = QRegExp(_current_reference.value(_year) + "\\s*[\\w ]{0,15}[,:;]\\s*(\\d+)\\s*[,:;]\\s*(" + _hyphen_pages + ')'); nH = rxH.indexIn(text); if (nH > -1) { _current_reference[_volume] = _bpP->parse(_volume, rxH.cap(1)); _current_reference[_pages] = _bpP->parse(_pages, rxH.cap(2)); _reliable_pages = true; _reliable_volume = true; return; } // J. Sci. 2005 103:818 rxH = QRegExp(_current_reference.value(_year) + "\\s+(\\d+)\\s*:\\s*(" + _hyphen_pages + ')'); nH = rxH.indexIn(text); if (nH > -1) { _current_reference[_volume] = _bpP->parse(_volume, rxH.cap(1)); _current_reference[_pages] = _bpP->parse(_pages, rxH.cap(2)); return; } // (2006) J. Sci. 39:3047 rxH = QRegExp("\\(" + _current_reference.value(_year) + "\\)\\D{5,30}(\\d+)\\s*[,:;]\\s*(" + _hyphen_pages + ')'); nH = rxH.indexIn(text); if (nH > -1) { _current_reference[_volume] = _bpP->parse(_volume, rxH.cap(1)); _current_reference[_pages] = _bpP->parse(_pages, rxH.cap(2)); return; } // 2006 J. Sci. 39 3047 rxH = QRegExp(_current_reference.value(_year) + "\\D{5,30}(\\d+)\\s*[,:; ]\\s*(" + _hyphen_pages + ')'); nH = rxH.indexIn(text); if (nH > -1) { _current_reference[_volume] = _bpP->parse(_volume, rxH.cap(1)); _current_reference[_pages] = _bpP->parse(_pages, rxH.cap(2)); return; } } cb2bib-2.0.1/src/c2b/PaxHeaders.5700/searchPattern.cpp0000644000000000000000000000013214011522520017041 xustar0030 mtime=1613145424.654620339 30 atime=1613145424.834620334 30 ctime=1613145424.658620339 cb2bib-2.0.1/src/c2b/searchPattern.cpp0000644000175000001440000002455114011522520020447 0ustar00constansusers00000000000000/*************************************************************************** * Copyright (C) 2004-2021 by Pere Constans * constans@molspaces.com * cb2Bib version 2.0.1. Licensed under the GNU GPL version 3. * See the LICENSE file that comes with this distribution. ***************************************************************************/ #include "searchPattern.h" #include "triads.h" #include #ifndef __has_cpp_attribute #define __has_cpp_attribute(name) 0 #endif #if __has_cpp_attribute(fallthrough) #define FALLTHROUGH [[fallthrough]] #else #define FALLTHROUGH #endif /** Top level driver for calling cb2Bib search types */ searchPattern::searchPattern(const QString& pattern, const QString& patternType) : _matcher(pattern, typemap().value(patternType), Qt::CaseInsensitive) { _modifier.NOT = false; _modifier.string = _matcher.typedpattern; _rank = 0; } searchPattern::searchPattern(const bool NOT, const bool caseSensitive, const QString& patternType, const QString& scope, const QChar& yearScope, const QString& pattern) : _matcher(pattern, typemap().value(patternType), qtcase(caseSensitive)) { _modifier.NOT = NOT; _modifier.string = _matcher.typedpattern; _modifier.scope = scope; _modifier.yearScope = yearScope; if (_modifier.NOT) _formatted_string += "NOT."; _formatted_string += QString(" [%1][%2|case=%3]").arg(_modifier.string, patternType).arg(caseSensitive); if (_modifier.scope == "year") _formatted_string += QString(" IN [%1(%2)]").arg(_modifier.scope).arg(_modifier.yearScope); else _formatted_string += QString(" IN [%1]").arg(_modifier.scope); // Set an approximate ranking to speed up composite searches _rank = 0; if (_modifier.scope == "file") _rank += 200; else if (_modifier.scope == "all") _rank += 100; else if (_modifier.scope == "year" || _modifier.scope == "volume" || _modifier.scope == "pages") _rank += 50; else _rank += 1; if (!caseSensitive) _rank *= 2; if (_matcher.type == FixedStringAllWords || _matcher.type == FixedStringAnyWord) _rank *= 5; else if (_matcher.type == ApproximateString) _rank *= 10; else if (_matcher.type == RegularExpression) _rank *= 20; } const QStringList searchPattern::types() { return typemap().keys(); } const QString searchPattern::type(const Type t) { return typemap().key(t); } const QMap searchPattern::typemap() { QMap tm; tm.insert(QObject::tr("Approximate string"), ApproximateString); tm.insert(QObject::tr("Context"), Context); tm.insert(QObject::tr("Fixed string: All Words"), FixedStringAllWords); tm.insert(QObject::tr("Fixed string: Any Word"), FixedStringAnyWord); tm.insert(QObject::tr("Fixed string: Context"), FixedStringContext); tm.insert(QObject::tr("Fixed string"), FixedString); tm.insert(QObject::tr("Regular expression"), RegularExpression); tm.insert(QObject::tr("Wildcard"), Wildcard); return tm; } searchPattern::matcher::matcher(const QString& pattern, const Type t, const Qt::CaseSensitivity cs) : csensitivity(cs), type(t), length(-1) { _set_typed_pattern(pattern); switch (t) { default: c2bUtils::warn(QObject::tr("Internal Error: Invalid search pattern type. Set to 'Approximate string'")); FALLTHROUGH; case ApproximateString: { appexp.setPattern(typedpattern, cs); if (appexp.isMultipattern()) { signature = triads::textSignature(typedpattern); subsignatures = triads::textSignature(appexp.substrings()); } else // Skip signatures for regular expression case { regexp = appexp.regexp(); type = RegularExpression; } } break; case Context: { cstemexp.setPattern(typedpattern, cs); signature = triads::textSignature(cstemexp.signatureString()); } break; case FixedStringAnyWord: { wordexp.setPattern(typedpattern, wordPattern::AnyWord, cs); signature = triads::textSignature(typedpattern); subsignatures = triads::textSignature(wordexp.substrings()); } break; case FixedStringAllWords: { wordexp.setPattern(typedpattern, wordPattern::AllWords, cs); signature = triads::textSignature(typedpattern); subsignatures.fill(signature, wordexp.subpatternCount()); } break; case FixedStringContext: { cwordexp.setPattern(typedpattern, cs); signature = triads::textSignature(typedpattern); } break; case FixedString: { strexp.setPattern(typedpattern); strexp.setCaseSensitivity(cs); signature = triads::textSignature(typedpattern); } break; case RegularExpression: { #if (QT_VERSION >= QT_VERSION_CHECK(5, 4, 0)) && (QT_VERSION < QT_VERSION_CHECK(5, 12, 0)) const QRegularExpression::PatternOptions po(QRegularExpression::DontCaptureOption | QRegularExpression::UseUnicodePropertiesOption | QRegularExpression::OptimizeOnFirstUsageOption); #else const QRegularExpression::PatternOptions po(QRegularExpression::DontCaptureOption | QRegularExpression::UseUnicodePropertiesOption); #endif regexp.setPattern(typedpattern); regexp.setPatternOptions(cs == Qt::CaseSensitive ? po : po | QRegularExpression::CaseInsensitiveOption); } break; case Wildcard: { #if (QT_VERSION >= QT_VERSION_CHECK(5, 4, 0)) && (QT_VERSION < QT_VERSION_CHECK(5, 12, 0)) const QRegularExpression::PatternOptions po( QRegularExpression::InvertedGreedinessOption | QRegularExpression::DontCaptureOption | QRegularExpression::UseUnicodePropertiesOption | QRegularExpression::OptimizeOnFirstUsageOption); #else const QRegularExpression::PatternOptions po(QRegularExpression::InvertedGreedinessOption | QRegularExpression::DontCaptureOption | QRegularExpression::UseUnicodePropertiesOption); #endif regexp.setPattern(_wildcard_escaped(typedpattern)); regexp.setPatternOptions(cs == Qt::CaseSensitive ? po : po | QRegularExpression::CaseInsensitiveOption); signature = triads::textSignature(typedpattern); } break; } } bool searchPattern::matcher::match(const QString& contents) const { length = -1; switch (type) { case ApproximateString: return appexp.matches(contents); case Context: return cstemexp.indexIn(contents) != -1; case FixedStringAnyWord: case FixedStringAllWords: return wordexp.matches(contents); case FixedStringContext: return cwordexp.indexIn(contents) != -1; case FixedString: return strexp.indexIn(contents) != -1; default: return regexp.match(contents).hasMatch(); } } bool searchPattern::matcher::match(const documentContents& contents) const { length = -1; switch (type) { case ApproximateString: return _match_any(appexp.subpatternCount(), appexp.submatchers(), contents); case Context: return _match(cstemexp, signature, contents); case FixedStringAnyWord: return _match_any(wordexp.subpatternCount(), wordexp.submatchers(), contents); case FixedStringAllWords: return _match_all(wordexp.subpatternCount(), wordexp.submatchers(), contents); case FixedStringContext: return _match(cwordexp, signature, contents); case FixedString: return _match(strexp, signature, contents); default: return _match(regexp, signature, contents); } } int searchPattern::matcher::index(const QString& contents, const int from) const { int i; switch (type) { case ApproximateString: i = appexp.indexIn(contents, from); length = appexp.matchedLength(); return i; case Context: i = cstemexp.indexIn(contents, from); length = cstemexp.matchedLength(); return i; case FixedStringAnyWord: case FixedStringAllWords: i = wordexp.indexIn(contents, from); length = wordexp.matchedLength(); return i; case FixedStringContext: i = cwordexp.indexIn(contents, from); length = cwordexp.matchedLength(); return i; case FixedString: i = strexp.indexIn(contents, from); length = strexp.pattern().length(); return i; default: regexp_match = regexp.match(contents, from); i = regexp_match.capturedStart(); length = regexp_match.capturedLength(); return i; } } void searchPattern::matcher::_set_typed_pattern(const QString& pattern) { const QRegExp rmors("\\|[^\\s]*"); const QRegExp rmnws("[\\W_]"); const QRegExp rmnls("[\\W\\d]"); QString stripped(pattern); switch (type) { case ApproximateString: case Context: case FixedStringAllWords: stripped.replace(rmors, " "); stripped.replace(rmnws, " "); break; case FixedStringAnyWord: stripped.replace(rmnws, " "); break; case FixedStringContext: stripped.replace(rmors, " "); break; case RegularExpression: stripped.replace(rmnls, " "); break; default: break; } stripped = stripped.simplified(); plength = type == FixedStringAllWords || type == FixedStringAnyWord ? 0 : stripped.length(); switch (type) { case Context: case FixedString: case RegularExpression: case Wildcard: typedpattern = pattern.simplified(); break; default: typedpattern = stripped; break; } #ifdef C2B_DEBUG_SEARCHING qDebug() << "searchPattern::matcher::_set_typed_pattern pattern " << pattern << pattern.length(); qDebug() << "searchPattern::matcher::_set_typed_pattern stripped " << stripped << stripped.length() << plength; qDebug() << "searchPattern::matcher::_set_typed_pattern typedpattern " << typedpattern << typedpattern.length(); #endif } QString searchPattern::matcher::_wildcard_escaped(const QString& pattern) { QString scaped; for (int i = 0; i < pattern.length(); ++i) if (pattern.at(i) == '*') scaped += ".*"; else if (pattern.at(i) == '?') scaped += '.'; else scaped += QRegularExpression::escape(pattern.at(i)); return scaped; } cb2bib-2.0.1/src/c2b/PaxHeaders.5700/searchPattern.h0000644000000000000000000000013214011522520016506 xustar0030 mtime=1613145424.750620336 30 atime=1613145424.834620334 30 ctime=1613145424.750620336 cb2bib-2.0.1/src/c2b/searchPattern.h0000644000175000001440000001422414011522520020110 0ustar00constansusers00000000000000/*************************************************************************** * Copyright (C) 2004-2021 by Pere Constans * constans@molspaces.com * cb2Bib version 2.0.1. Licensed under the GNU GPL version 3. * See the LICENSE file that comes with this distribution. ***************************************************************************/ #ifndef SEARCHPATTERN_H #define SEARCHPATTERN_H #include "approximatePattern.h" #include "documentContents.h" #include "scorer.h" #include "stemMatcher.h" #include "wordMatcher.h" #include "wordPattern.h" #include class searchPattern { public: searchPattern(const QString& pattern, const QString& patternType); searchPattern(const bool NOT, const bool caseSensitive, const QString& patternType, const QString& scope, const QChar& yearScope, const QString& pattern); inline ~searchPattern() {} enum Type { ApproximateString = 1, Context = 2, FixedStringAllWords = 3, FixedStringAnyWord = 4, FixedStringContext = 5, FixedString = 6, RegularExpression = 7, Wildcard = 8 }; static const QString type(const Type t); static const QStringList types(); struct modifiers { QChar yearScope; QString scope; QString string; bool NOT; }; inline const modifiers& modifier() const { return _modifier; } inline bool matches(const QString& contents) const { return _matcher.match(contents); } inline bool matches(const documentContents& contents) const { return _matcher.match(contents); } inline int indexIn(const QString& contents, const int from) const { return _matcher.index(contents, from); } inline int indexIn(const documentContents& contents, const int from) const { return _matcher.index(contents.text(), from); } inline int matchedLength() const { return _matcher.length; } inline void initializeScores() const { _scorer.initialize(); } inline void updateScore() const { _scorer.update(_matcher.plength, _matcher.length); } inline int matchedCounter() const { return _scorer.nscores; } inline double matchedScore() const { return _scorer.score(); } inline const QString toString() const { return _formatted_string; } inline bool operator<(const searchPattern& p) const { return (_rank < p._rank); } private: struct matcher { matcher(const QString& pattern, const Type t, const Qt::CaseSensitivity cs); QRegularExpression regexp; QString signature; QString typedpattern; QStringMatcher strexp; QVector subsignatures; Qt::CaseSensitivity csensitivity; Type type; approximatePattern appexp; int plength; mutable QRegularExpressionMatch regexp_match; mutable int length; stemMatcher cstemexp; wordMatcher cwordexp; wordPattern wordexp; bool match(const QString& contents) const; bool match(const documentContents& contents) const; int index(const QString& contents, const int from) const; static QString _wildcard_escaped(const QString& pattern); void _set_typed_pattern(const QString& pattern); static inline bool _match_signature(const QString& ps, const QString& cs) { const int pl(ps.length()); // Always pl > 0 const int cl(cs.length()); const ushort* ups(reinterpret_cast(ps.unicode())); const ushort* p(ups); const ushort* pn(ups + pl); const ushort* ucs(reinterpret_cast(cs.unicode())); const ushort* c(ucs - 1); const ushort* cn(ucs + cl); while (++c != cn) if (*c == *p) if (++p == pn) return true; return false; } static inline bool _match(const QRegularExpression& submatcher, const QString& psignature, const documentContents& contents) { #ifdef C2B_DEBUG_SEARCHING_SKIP_SIGNATURE return submatcher.match(contents.text()).hasMatch(); #else // Skip signature check for patterns that do not define it if (psignature.length() == 0 || _match_signature(psignature, contents.signature())) return submatcher.match(contents.text()).hasMatch(); else return false; #endif } template static inline bool _match(const T& submatcher, const QString& psignature, const documentContents& contents) { #ifdef C2B_DEBUG_SEARCHING_SKIP_SIGNATURE return submatcher.indexIn(contents.text()) != -1; #else // Skip signature check for patterns that do not define it if (psignature.length() == 0 || _match_signature(psignature, contents.signature())) return submatcher.indexIn(contents.text()) != -1; else return false; #endif } template inline bool _match_all(const int n, const T& submatchers, const documentContents& contents) const { for (int i = n - 1; i >= 0; --i) if (!_match(submatchers.at(i), subsignatures.at(i), contents)) return false; return true; } template inline bool _match_any(const int n, const T& submatchers, const documentContents& contents) const { for (int i = 0; i < n; ++i) if (_match(submatchers.at(i), subsignatures.at(i), contents)) return true; return false; } }; static const QMap typemap(); static inline Qt::CaseSensitivity qtcase(bool caseSensitive) { return caseSensitive ? Qt::CaseSensitive : Qt::CaseInsensitive; } QString _formatted_string; int _rank; matcher _matcher; modifiers _modifier; mutable scorer _scorer; }; #endif cb2bib-2.0.1/src/c2b/PaxHeaders.5700/coreBibParser.cpp0000644000000000000000000000013014011522520016756 xustar0029 mtime=1613145424.61062034 30 atime=1613145424.834620334 29 ctime=1613145424.61062034 cb2bib-2.0.1/src/c2b/coreBibParser.cpp0000644000175000001440000003743014011522520020366 0ustar00constansusers00000000000000/*************************************************************************** * Copyright (C) 2004-2021 by Pere Constans * constans@molspaces.com * cb2Bib version 2.0.1. Licensed under the GNU GPL version 3. * See the LICENSE file that comes with this distribution. ***************************************************************************/ #include "coreBibParser.h" coreBibParser::coreBibParser(QObject* parento) : QObject(parento), _at(QLatin1Char('@')), _close(QLatin1Char('}')), _colon(QLatin1Char(':')), _comma(QLatin1Char(',')), _cr(13), _hyphen(QLatin1Char('-')), _lca(QLatin1Char('a')), _lcz(QLatin1Char('z')), _nl(10), _open(QLatin1Char('{')), _period(QLatin1Char('.')), _pound(QLatin1Char('#')), _quote(QLatin1Char('"')), _space(QLatin1Char(' ')), _tilde(QLatin1Char('~')), _uca(QLatin1Char('A')), _ucz(QLatin1Char('Z')) { _settingsP = settings::instance(); // Setting bibliographic types setTypes(); // Setting bibliographic fields setFields(); // Setting regular expressions setRegularExpressions(); } bool coreBibParser::referencesIn(const QString& str, bibReference* ref) { // File parsing for given fields in ref ref->clearReference(); const int pos(referenceStarts(str, ref->pos)); if (pos < 0) return false; referenceContents(str, ref, pos); return true; } bool coreBibParser::referenceAtKey(const QString& key, const QString& str, bibReference* ref) { // File parsing for given fields in ref ref->clearReference(); const int pos(referenceStarts(key, str)); if (pos < 0) return false; referenceContents(str, ref, pos); return true; } QString coreBibParser::referenceToFomattedBibTeX(const bibReference& ref) const { // Writes a BibTeX string from struct bibReference QString BibString(QLatin1Char('@') + ref.typeName + QLatin1Char('{') + ref.citeidName); const bool ConvertReferenceToLaTeX(_settingsP->value("cb2Bib/ConvertReferenceToLaTeX").toBool()); const bool PostprocessMonth(_settingsP->value("cb2Bib/PostprocessMonth").toBool()); const bool UseDoubleBraces(_settingsP->value("cb2Bib/UseDoubleBraces").toBool()); QStringList::const_iterator it = _bibliographic_fields.begin(); while (it != _bibliographic_fields.end()) { QString fvalue(ref.value(*it)); if (!fvalue.isEmpty()) { if (ConvertReferenceToLaTeX) c2bUtils::c2bToBib(fvalue); const QString fd(*it); const QString padding(QString().fill(' ', 12 - fd.length())); if (fd == QLatin1String("title") || fd == QLatin1String("booktitle")) { if (UseDoubleBraces) if (!fvalue.contains(QRegExp("^\\{.+\\}$"))) fvalue = '{' + fvalue + '}'; fvalue = QLatin1Char('{') + fvalue + QLatin1Char('}'); } else if (fd == QLatin1String("month")) { if (!PostprocessMonth) fvalue = QLatin1Char('{') + fvalue + QLatin1Char('}'); } else fvalue = QLatin1Char('{') + fvalue + QLatin1Char('}'); BibString += QLatin1String(",\n") + fd + padding + QLatin1String(" = ") + fvalue; } ++it; } BibString += QLatin1String("\n}\n"); return BibString; } QString coreBibParser::referenceToBibTeX(const bibReference& ref) const { // Writes a BibTeX string from struct bibReference // No special formatting is done here QString BibString(QLatin1Char('@') + ref.typeName + QLatin1Char('{')); QStringList::const_iterator it(_bibliographic_fields.begin()); while (it != _bibliographic_fields.end()) { const QString fvalue(ref.value(*it)); if (!fvalue.isEmpty()) { const QString fd(*it); const QString padding(QString().fill(QLatin1Char(' '), 12 - fd.length())); BibString += QLatin1String(",\n") + fd + padding + QLatin1String(" = {") + fvalue + QLatin1Char('}'); } ++it; } BibString += QLatin1String("\n}\n"); return BibString; } QString coreBibParser::adjacentNumbers(const QString& numbers) const { // Originally for pages, used also for multiple volume, number and year QString anums(numbers); anums.replace(c2bUtils::nonLetter, QLatin1String(" ")); anums = c2bUtils::simplifyString(anums); if (anums.isEmpty() || anums == QLatin1String("0")) return QString(); anums.replace(' ', '-'); QRegExp rx1("^(\\d+)-(\\d+)-*pp$"); QRegExp rx2("^(\\d+)-(\\d+)$"); if (rx1.indexIn(anums) > -1) { anums = rx1.cap(1); int ilp(rx1.cap(2).toInt() - 1); if (ilp > 0) anums += QLatin1Char('-') + QString().setNum(rx1.cap(1).toInt() + ilp); // eg, 123-7pp -> 123 - 129 } else if (rx2.indexIn(anums) > -1) { QString fp(rx2.cap(1)); anums = fp + '-'; QString lp(rx2.cap(2)); uint lfp(fp.length()); uint llp(lp.length()); if (lfp > llp) lp = fp.remove(lfp - llp, llp) + lp; // eg, 123-7 -> 123 - 127 anums += lp; } const QString separator(_settingsP->value("cb2Bib/PageNumberSeparator").toString()); if (separator.isEmpty()) anums.replace('-', " - "); else anums.replace('-', separator); return anums; } void coreBibParser::setFields() { _bibliographic_fields << QLatin1String("title") << QLatin1String("author") << QLatin1String("journal") << QLatin1String("booktitle") << QLatin1String("series") << QLatin1String("chapter") << QLatin1String("pages") << QLatin1String("volume") << QLatin1String("number") << QLatin1String("edition") << QLatin1String("institution") << QLatin1String("organization") << QLatin1String("school") << QLatin1String("address") << QLatin1String("month") << QLatin1String("year") << QLatin1String("editor") << QLatin1String("publisher") << QLatin1String("abstract") << QLatin1String("keywords") << QLatin1String("isbn") << QLatin1String("issn") << QLatin1String("doi") << QLatin1String("eprint") << QLatin1String("file") << QLatin1String("url") << QLatin1String("note") << QLatin1String("annote"); _sorted_bibliographic_fields = _bibliographic_fields; std::sort(_sorted_bibliographic_fields.begin(), _sorted_bibliographic_fields.end()); } void coreBibParser::setTypes() { _bibliographic_types << QLatin1String("") << QLatin1String("article") << QLatin1String("book") << QLatin1String("booklet") << QLatin1String("conference") << QLatin1String("inbook") << QLatin1String("incollection") << QLatin1String("inproceedings") << QLatin1String("manual") << QLatin1String("mastersthesis") << QLatin1String("misc") << QLatin1String("periodical") << QLatin1String("phdthesis") << QLatin1String("proceedings") << QLatin1String("techreport") << QLatin1String("unpublished"); } void coreBibParser::setRegularExpressions() { _bib_begin0_re = QRegExp("^\\s*@\\w+\\s*\\{"); _bib_begin1_re = QRegExp("[\\r\\n]\\s*@\\w+\\s*\\{"); _bib_begin_at = txtmatcher("@", Qt::CaseSensitive, 0); _bib_begin_re = QRegExp("^@\\w+\\s*\\{"); _bib_field_delimiter = txtmatcher("=", Qt::CaseSensitive, 0); _field_re = QRegExp("\\b(" + _bibliographic_fields.join("|") + ")\\b"); } void coreBibParser::initReferenceParsing(const QString& dir, const QStringList& fields, bibReference* ref) { setReferenceParsingDir(dir); // Init file parsing for given fields ref->clearFields(); ref->clearReference(); _current_bibliographic_fields = fields; } bibReference coreBibParser::wholeReference(const QString& str) const { // Skip positionValue as it is not needed here bibReference ref; int pos(referenceStarts(str)); if (pos < 0) return ref; QString str_ref(referenceAt(str, &pos)); c2bUtils::fullBibToC2b(str_ref); c2bUtils::simplifyString(str_ref); setReferenceEnd(&str_ref); _parse_reference_fields(str_ref, _bibliographic_fields, &ref); return ref; } void coreBibParser::referenceContents(const QString& str, bibReference* ref, int pos) const { // File parsing for_current_bibliographic_fields in ref ref->positionValue = pos; QString str_ref(referenceAt(str, &pos)); ref->pos = pos; ref->rawReference = str_ref; c2bUtils::bibToC2b(str_ref); c2bUtils::simplifyString(str_ref); setReferenceEnd(&str_ref); ref->unicodeReference = str_ref; _parse_reference_fields(str_ref, _current_bibliographic_fields, ref); if (ref->contains(QLatin1String("file"))) if (!QDir::isAbsolutePath(ref->value(QLatin1String("file")))) (*ref)[QLatin1String("file")] = _bib_file_dir + ref->value(QLatin1String("file")); } QString coreBibParser::singleReferenceField(const QString& field, const bibReference& ref) const { // Simplified _parse_reference_fields function, excludes month and keywords peculiarities const QChar* const b(ref.unicodeReference.constData()); const int length(ref.unicodeReference.length()); if (length == 0 || b[0] != _at || field.isEmpty()) return QString(); const QChar lclc(field.at(field.length() - 1).toLower()), lcuc(field.at(field.length() - 1).toUpper()); int cursor(1); while (true) { const int cd(_bib_field_delimiter.indexIn(b, length, cursor)); if (cd < 1) break; const int fends(b[cd - 1] == _space ? cd - 2 : cd - 1); if (b[fends] != lclc && b[fends] != lcuc) { cursor = cd + 2; continue; } for (cursor = fends; cursor > 1; --cursor) if ((b[cursor] >= _lca && b[cursor] <= _lcz) || (b[cursor] >= _uca && b[cursor] <= _ucz)) continue; else break; if (field.compare(ref.unicodeReference.midRef(cursor + 1, fends - cursor), Qt::CaseInsensitive) != 0) { cursor = cd + 2; continue; } const int vstarts(b[cd + 1] == _space ? cd + 2 : cd + 1); const int vends(_in_braces_ends(b, vstarts, length)); if (vends > 0) { const int vs(b[vstarts + 1] == _space ? vstarts + 2 : vstarts + 1); return ref.unicodeReference.mid(vs, std::max(0, vends - vs + 1)); } for (cursor = vstarts; cursor < length; ++cursor) if (!b[cursor].isLetterOrNumber()) break; const int vnbends(cursor); if (b[cursor] == _space) ++cursor; if (b[cursor] == _comma) return ref.unicodeReference.mid(vstarts, std::max(0, vnbends - vstarts)); cursor = cd + 2; } return QString(); } static inline const QString* _ci_fields_index_of(const QStringList& fields, const ushort* const b, const int length) { for (QStringList::const_iterator i = fields.constBegin(); i != fields.constEnd(); ++i) { if (length != i->length() || (b[0] | 0x20) != i->at(0).unicode()) continue; for (int l = 1; l < length; ++l) if ((b[l] | 0x20) != i->at(l).unicode()) goto next; return &(*i); next: continue; } return nullptr; } void coreBibParser::_parse_reference_fields(const QString& bibstr, const QStringList& fields, bibReference* ref) const { const QChar* const b(bibstr.constData()); const int length(bibstr.length()); if (length == 0 || b[0] != _at) return; int cursor; for (cursor = 1; cursor < length; ++cursor) if (!b[cursor].isLetterOrNumber()) break; const int tends(cursor); if (b[cursor] == _space) ++cursor; if (b[cursor] == _open) { ref->typeName = bibstr.mid(1, tends - 1).toLower(); ++cursor; if (b[cursor] == _space) ++cursor; const int kstarts(cursor); for (; cursor < length; ++cursor) if (b[cursor].isLetterOrNumber() || b[cursor] == _colon || b[cursor] == _hyphen || b[cursor] == _period) continue; else break; const int kends(cursor); if (b[cursor] == _space) ++cursor; if (b[cursor] == _comma) ref->citeidName = bibstr.mid(kstarts, kends - kstarts); } if (fields.isEmpty()) return; while (true) { const int cd(_bib_field_delimiter.indexIn(b, length, cursor)); if (cd < 1) break; const int fends(b[cd - 1] == _space ? cd - 2 : cd - 1); for (cursor = fends; cursor > 1; --cursor) if ((b[cursor] >= _lca && b[cursor] <= _lcz) || (b[cursor] >= _uca && b[cursor] <= _ucz)) continue; else break; const QString* const fp( _ci_fields_index_of(fields, reinterpret_cast(b + cursor + 1), fends - cursor)); if (fp == nullptr) { cursor = cd + 2; continue; } const QString& field(*fp); const int vstarts(b[cd + 1] == _space ? cd + 2 : cd + 1); if (b[vstarts] != _open && field == QLatin1String("month")) { // Month macro for (cursor = vstarts; cursor < length; ++cursor) if (b[cursor].isLetterOrNumber() || b[cursor] == _space || b[cursor] == _tilde || b[cursor] == _pound || b[cursor] == _quote) continue; else break; if (b[cursor] == _comma && !ref->contains(field)) ref->insert(field, bibstr.mid(vstarts, cursor - vstarts).trimmed()); cursor = cd + 2; continue; } const int vends(_in_braces_ends(b, vstarts, length)); if (vends > 0) { const int vs(b[vstarts + 1] == _space ? vstarts + 2 : vstarts + 1); const int vl(vends - vs + 1); if (vl > 0) { if (!ref->contains(field)) ref->insert(field, bibstr.mid(vs, vl)); else if (field == QLatin1String("keywords")) ref->insert(field, ref->value(field) + QLatin1Char(';') + bibstr.mid(vs, vl)); } cursor = cd + 2; continue; } for (cursor = vstarts; cursor < length; ++cursor) if (!b[cursor].isLetterOrNumber()) break; const int vnbends(cursor); if (b[cursor] == _space) ++cursor; if (b[cursor] == _comma) { const int vl(vnbends - vstarts); if (vl > 0) { if (!ref->contains(field)) ref->insert(field, bibstr.mid(vstarts, vl)); else if (field == QLatin1String("keywords")) ref->insert(field, ref->value(field) + QLatin1Char(';') + bibstr.mid(vstarts, vl)); } } cursor = cd + 2; } } int coreBibParser::_in_braces_ends(const QChar* const b, const int p, const int length) const { if (b[p] == _open) for (int i = p + 1, open_braces = 1; i < length; ++i) { if (b[i] < _open) continue; if (b[i] == _open) ++open_braces; else if (b[i] == _close) --open_braces; if (open_braces == 0) return (b[i - 1] == _space) ? i - 2 : i - 1; } else if (b[p] == _quote) for (int i = p + 1; i < length; ++i) if (b[i] == _quote && b[i + 1] == _comma) return (b[i - 1] == _space) ? i - 2 : i - 1; return 0; } cb2bib-2.0.1/src/c2b/PaxHeaders.5700/monthDB.h0000644000000000000000000000013214011522520015236 xustar0030 mtime=1613145424.734620337 30 atime=1613145424.834620334 30 ctime=1613145424.738620337 cb2bib-2.0.1/src/c2b/monthDB.h0000644000175000001440000000153714011522520016643 0ustar00constansusers00000000000000/*************************************************************************** * Copyright (C) 2004-2021 by Pere Constans * constans@molspaces.com * cb2Bib version 2.0.1. Licensed under the GNU GPL version 3. * See the LICENSE file that comes with this distribution. ***************************************************************************/ #ifndef MONTHDB_H #define MONTHDB_H #include #include /** Post processing of tag 'month' @author Pere Constans */ class monthDB { public: monthDB(); inline ~monthDB() {} QString retrieve(const QString& month_query); private: QRegExp _day_rx; QRegExp _month_rx; QString abbreviated(const QString& month) const; QString full(const QString& month) const; const QStringList _month_abbreviated; const QStringList _month_full; }; #endif cb2bib-2.0.1/src/c2b/PaxHeaders.5700/collectionIndex.cpp0000644000000000000000000000013014011522520017357 xustar0029 mtime=1613145424.60662034 30 atime=1613145424.834620334 29 ctime=1613145424.60662034 cb2bib-2.0.1/src/c2b/collectionIndex.cpp0000644000175000001440000016044214011522520020767 0ustar00constansusers00000000000000/*************************************************************************** * Copyright (C) 2004-2021 by Pere Constans * constans@molspaces.com * cb2Bib version 2.0.1. Licensed under the GNU GPL version 3. * See the LICENSE file that comes with this distribution. ***************************************************************************/ #include "collectionIndex.h" #include "bibParser.h" #include "cb2bib_utilities.h" #include "documentCache.h" #include "documentParser.h" #include "posTagger.h" #include "settings.h" #include #include #include #define C2B_DEBUG_COLLECTIONINDEX 0 namespace { // Tunable parameters static const int _document_length_threshold(100000); static const int _in_long_document_sentence_repetition(3); static const int _in_short_document_sentence_repetition(2); static const int _inter_document_sentence_repetition(3); #if (QT_VERSION >= QT_VERSION_CHECK(5, 4, 0)) && (QT_VERSION < QT_VERSION_CHECK(5, 12, 0)) static const QRegularExpression::PatternOptions _qre_pattern_options(QRegularExpression::UseUnicodePropertiesOption | QRegularExpression::OptimizeOnFirstUsageOption); #else static const QRegularExpression::PatternOptions _qre_pattern_options(QRegularExpression::UseUnicodePropertiesOption); #endif class reversedsorting { public: inline reversedsorting() {} inline bool operator()(const QString& si, const QString& sj) const { const int li(si.length()); const int lj(sj.length()); const QChar* a = si.unicode() + li - 1; const QChar* b = sj.unicode() + lj - 1; int cl(std::min(li, lj)); while (cl-- > 0) { if (*a == *b) { --a; --b; } else return *a < *b; } return li < lj; } }; class ussorting { public: inline ussorting() : ss(' '), us('_') {} inline bool operator()(const QString& si, const QString& sj) { QString ssi(si); QString ssj(sj); return ssi.replace(us, ss) < ssj.replace(us, ss); } const QChar ss; const QChar us; }; } // namespace collectionIndex::collectionIndex(bibParser* bp) : _out(*(new QTextStream(stdout))), _bpP(bp), _space_char(QChar(' ')), _nerrors(0), _settingsP(settings::instance()) {} collectionIndex::~collectionIndex() { delete &_out; } int collectionIndex::index(const QString& dir) { const unsigned long start_time(clock()); _nerrors = 0; _keysentences.clear(); const QString bibtexdir(dir.isEmpty() ? QDir::toNativeSeparators(QFileInfo(_settingsP->fileName("cb2Bib/BibTeXFile")).path()) : QDir::toNativeSeparators(dir)); _out << QObject::tr("Indexing references from directory %1...").arg(bibtexdir) << endl; bibReference reference; documentCache dc; int documentid(0); QStringList documents; QStringList documentfns; const QStringList bibtexfns(c2bUtils::filesInDir(bibtexdir, QStringList() << "*.bib")); if (bibtexfns.count() == 0) { ++_nerrors; _out << QObject::tr("Error: No BibTeX files at %1").arg(bibtexdir) << endl; return _nerrors; } const QStringList fields(QStringList() << "file" << "journal" << "title" << "booktitle"); int nfailures(0); for (int i = 0; i < bibtexfns.count(); ++i) { const QString bibtexfn(bibtexfns.at(i)); _out << QObject::tr("Indexing %1...").arg(bibtexfn) << endl; const QString bibtex(c2bUtils::fileToString(bibtexfn)); dc.load(bibtexfn, documentContents::Complete); _bpP->initReferenceParsing(bibtexfn, fields, &reference); while (_bpP->referencesIn(bibtex, &reference)) { QString docfn(reference.value("file")); if (docfn.isEmpty()) continue; docfn = QDir::cleanPath(docfn); const QString journal(reference.value("journal")); QString title(reference.anyTitle()); c2bUtils::cleanTitle(title, true); if (dc.setCurrent(docfn)) setKeySentences(documentid, preprocessedText(journal, dc.current().text())); else ++nfailures; ++documentid; documents.append(title); documentfns.append(docfn); } dc.unload(); } if (nfailures > 0) { _out << QObject::tr("Warning: %1 documents could not be converted to text. Check search converter is set.") .arg(nfailures) << endl; _out << QObject::tr(" Refresh cache by running a prove search including document contents.") << endl; } _out << QObject::tr("done") << endl; digestKeySentences(); cleanupKeySentences(); analyzeKeySentences(); #if C2B_DEBUG_COLLECTIONINDEX for (int i = 0; i < documents.count(); ++i) { QStringList sentences(_document_sentences.values(i)); std::sort(sentences.begin(), sentences.end()); _out << i << " " << documents.at(i) << ':' << endl; for (int j = 0; j < sentences.count(); ++j) _out << " " << sentences.at(j) << endl; } #endif const QString cache_dir(_settingsP->fileName("cb2Bib/CacheDirectory")); const QString documentslfn(QDir::toNativeSeparators(cache_dir + "/documents.lc2b")); QFile documentslf(QDir::cleanPath(documentslfn)); if (documentslf.open(QIODevice::WriteOnly)) { _out << QObject::tr("Writing %1...").arg(documentslfn) << endl; QDataStream stream(&documentslf); stream << documentfns.count(); for (int i = 0; i < documentfns.count(); ++i) stream << documentfns.at(i); documentslf.close(); } else { ++_nerrors; _out << QObject::tr("Error: %1 can not be written").arg(documentslfn) << endl; } const QString documentsifn(QDir::toNativeSeparators(cache_dir + "/documents.ic2b")); QFile documentsif(documentsifn); if (documentsif.open(QIODevice::WriteOnly)) { _out << QObject::tr("Writing %1...").arg(documentsifn) << endl; QDataStream stream(&documentsif); for (int i = 0; i < documents.count(); ++i) { QList sentenceids(_document_sentenceids.values(i)); std::sort(sentenceids.begin(), sentenceids.end()); stream << sentenceids.count(); for (int j = 0; j < sentenceids.count(); ++j) stream << sentenceids.at(j); } documentsif.close(); } else { ++_nerrors; _out << QObject::tr("Error: %1 can not be written").arg(documentsifn) << endl; } _out << QObject::tr("done") << endl; const double time = double(clock() - start_time) / double(CLOCKS_PER_SEC); _out << QObject::tr("Indexing CPU time: %1s").arg(time) << endl; return _nerrors; } void collectionIndex::setKeySentences(const int documentid, const QString& text) { QHash docsentences; documentParser dp(text, 7); while (dp.parses()) { if (dp.nlength() < 4 * dp.nwords()) continue; const QStringRef s(dp.subsentence()); docsentences.insert(s, 1 + docsentences.value(s)); } const int dsr(text.length() < _document_length_threshold ? _in_short_document_sentence_repetition : _in_long_document_sentence_repetition); for (QHash::const_iterator si = docsentences.constBegin(); si != docsentences.constEnd(); ++si) { if (si.value() < dsr) continue; const QString ss(si.key().toString()); if (!isValidKeySentence(ss)) continue; if (_keysentences.contains(ss)) _keysentences[ss].update(documentid); else _keysentences.insert(ss, KeysentenceData(documentid)); } } void collectionIndex::analyzeKeySentences() { _out << QObject::tr("Analysing keyword sentences...") << endl; posTagger pt; if (!pt.loadLexicon()) { ++_nerrors; _out << QObject::tr("Error: cb2Bib POS lexicon could not be loaded; check Configure Files") << endl; return; } QStringList validlist; #if C2B_DEBUG_COLLECTIONINDEX QStringList taggedvalidlist; #endif for (QMap::const_iterator si = _keysentences.constBegin(); si != _keysentences.constEnd(); ++si) { const QString& s(si.key()); const KeysentenceData& sdata(si.value()); if (sdata.ndocuments < _inter_document_sentence_repetition) continue; const QString pts(pt.tagged(s)); if (pt.contains(pts)) { validlist.append(s); #if C2B_DEBUG_COLLECTIONINDEX taggedvalidlist.append(pts + " " + s); for (int j = 0; j < sdata.documents.count(); ++j) _document_sentences.insert(sdata.documents.at(j), s); #endif } } ussorting uss; std::sort(validlist.begin(), validlist.end(), uss); const QString cache_dir(_settingsP->fileName("cb2Bib/CacheDirectory")); const QString sentenceslfn(QDir::toNativeSeparators(QDir::cleanPath(cache_dir + "/sentences.lc2b"))); QFile sentenceslf(sentenceslfn); if (sentenceslf.open(QIODevice::WriteOnly)) { _out << QObject::tr("Writing %1...").arg(sentenceslfn) << endl; QDataStream stream(&sentenceslf); stream << validlist.count(); const QChar hs('-'); const QChar us('_'); const QString ss("\\1 "); QRegularExpression aprx(_bpP->authorPrefixes() + '_', _qre_pattern_options); for (int i = 0; i < validlist.count(); ++i) { QString v(validlist.at(i)); v.replace(aprx, ss); stream << v.replace(us, hs); } sentenceslf.close(); } else { ++_nerrors; _out << QObject::tr("Error: %1 can not be written").arg(sentenceslfn) << endl; } const QString sentencesifn(QDir::toNativeSeparators(QDir::cleanPath(cache_dir + "/sentences.ic2b"))); QFile sentencesif(sentencesifn); if (sentencesif.open(QIODevice::WriteOnly)) { _out << QObject::tr("Writing %1...").arg(sentencesifn) << endl; QDataStream stream(&sentencesif); for (int i = 0; i < validlist.count(); ++i) { const QString& s(validlist.at(i)); const KeysentenceData& sdata(_keysentences.value(s)); QList dl(sdata.documents); std::sort(dl.begin(), dl.end()); stream << dl.count(); for (int j = 0; j < dl.count(); ++j) stream << dl.at(j); } sentencesif.close(); } else { ++_nerrors; _out << QObject::tr("Error: %1 can not be written").arg(sentencesifn) << endl; } #ifdef C2B_TRACE_MEMORY qDebug() << "After writing sentencesifn:"; c2bUtils::print_maximum_resident_set_size(); #endif const QString documentsifn(QDir::toNativeSeparators(cache_dir + "/documents.ic2b.tmp")); QFile documentsif(documentsifn); int document_sentenceids_count(0); if (documentsif.open(QIODevice::WriteOnly)) { QDataStream stream(&documentsif); for (int i = 0; i < validlist.count(); ++i) { const QString& s(validlist.at(i)); const KeysentenceData& sdata(_keysentences.value(s)); document_sentenceids_count += sdata.documents.count(); for (int j = 0; j < sdata.documents.count(); ++j) stream << sdata.documents.at(j) << i; } documentsif.close(); } else { ++_nerrors; _out << QObject::tr("Error: %1 can not be written").arg(documentsifn) << endl; } _out << QObject::tr("Raw keyword sentences: ") << _keysentences.size() << endl; _out << QObject::tr("Keyword sentences: ") << validlist.count() << endl; _out << QObject::tr("done") << endl; #if !C2B_DEBUG_COLLECTIONINDEX _out << QObject::tr("Clearing arrays...") << endl; _keysentences.clear(); _document_sentences.clear(); _out << QObject::tr("done") << endl; #endif #ifdef C2B_TRACE_MEMORY qDebug() << "After clearing arrays:"; c2bUtils::print_maximum_resident_set_size(); #endif if (documentsif.open(QIODevice::ReadOnly)) { QDataStream stream(&documentsif); for (int l = 0, d, i; l < document_sentenceids_count; ++l) { stream >> d >> i; _document_sentenceids.insert(d, i); } documentsif.close(); documentsif.remove(); } else { ++_nerrors; _out << QObject::tr("Error: %1 can not be read").arg(documentsifn) << endl; } #ifdef C2B_TRACE_MEMORY qDebug() << "After inserting _document_sentenceids:"; c2bUtils::print_maximum_resident_set_size(); #endif #if C2B_DEBUG_COLLECTIONINDEX std::sort(taggedvalidlist.begin(), taggedvalidlist.end()); for (int i = 0; i < taggedvalidlist.count(); ++i) _out << taggedvalidlist.at(i) << endl; #endif } void collectionIndex::cleanupKeySentences() { _out << QObject::tr("Cleaning keyword sentences...") << endl; QStringList keysentenceskeys; for (QMap::const_iterator si = _keysentences.constBegin(); si != _keysentences.constEnd(); ++si) { if (si.value().ndocuments < _inter_document_sentence_repetition) continue; keysentenceskeys.append(si.key()); } const int nkeysentenceskeys(keysentenceskeys.count()); std::sort(keysentenceskeys.begin(), keysentenceskeys.end()); for (int i = 0; i < nkeysentenceskeys - 1; ++i) { const QString& si(keysentenceskeys.at(i)); const QString& sj(keysentenceskeys.at(i + 1)); if (sj.startsWith(si) && _keysentences.value(si).ndocuments == _keysentences.value(sj).ndocuments) _keysentences[si].ndocuments = 0; } reversedsorting rs; std::sort(keysentenceskeys.begin(), keysentenceskeys.end(), rs); for (int i = 0; i < nkeysentenceskeys - 1; ++i) { const QString& si(keysentenceskeys.at(i)); const QString& sj(keysentenceskeys.at(i + 1)); if (sj.endsWith(si) && _keysentences.value(si).ndocuments == _keysentences.value(sj).ndocuments) _keysentences[si].ndocuments = 0; } _out << QObject::tr("done") << endl; } void collectionIndex::digestKeySentences() { _out << QObject::tr("Digesting keyword sentences...") << endl; const QChar hyphen('_'); const QString coordination_and(" and "); const QString coordination_in(" in "); const QString coordination_of(" of "); const QString coordination_on(" on "); const QString coordination_or(" or "); const QRegularExpression trailing_ae("ae\\b", _qre_pattern_options); const QRegularExpression trailing_ches("ches\\b", _qre_pattern_options); const QRegularExpression trailing_dices("dices\\b", _qre_pattern_options); const QRegularExpression trailing_ices("ices\\b", _qre_pattern_options); const QRegularExpression trailing_ies("ies\\b", _qre_pattern_options); const QRegularExpression trailing_is("is\\b", _qre_pattern_options); const QRegularExpression trailing_us("us\\b", _qre_pattern_options); const QRegularExpression trailing_s("s\\b", _qre_pattern_options); const QRegularExpression trailing_ss("ss\\b", _qre_pattern_options); const QRegularExpression trailing_sses("sses\\b", _qre_pattern_options); const QRegularExpression trailing_ap("'\\b", _qre_pattern_options); const QRegularExpression trailing_aps("'s\\b", _qre_pattern_options); for (QMap::iterator si = _keysentences.begin(); si != _keysentences.end(); ++si) { if (si.value().ndocuments == 0) continue; const QString& s(si.key()); KeysentenceData* ksdndmax(&si.value()); int ndmax(ksdndmax->ndocuments); // Unify hyphenation if (s.contains(hyphen)) { QString sp(s); sp.remove(hyphen); if (_keysentences.contains(sp)) ksdndmax = _digest_sentence(&_keysentences[sp], ksdndmax, &ndmax); sp = s; sp.replace(hyphen, _space_char); if (_keysentences.contains(sp)) ksdndmax = _digest_sentence(&_keysentences[sp], ksdndmax, &ndmax); } // Unify simple coordinations if (s.count(coordination_and) == 1) { const QStringList p(s.split(coordination_and, QString::SkipEmptyParts)); const QString sp(p.at(1) + coordination_and + p.at(0)); if (_keysentences.contains(sp)) ksdndmax = _digest_sentence(&_keysentences[sp], ksdndmax, &ndmax); } else if (s.count(coordination_or) == 1) { const QStringList p(s.split(coordination_or, QString::SkipEmptyParts)); const QString sp(p.at(1) + coordination_or + p.at(0)); if (_keysentences.contains(sp)) ksdndmax = _digest_sentence(&_keysentences[sp], ksdndmax, &ndmax); } else if (s.count(coordination_of) == 1) { const QStringList p(s.split(coordination_of, QString::SkipEmptyParts)); const QString sp(p.at(1) + _space_char + p.at(0)); if (_keysentences.contains(sp)) ksdndmax = _digest_sentence(&_keysentences[sp], ksdndmax, &ndmax); } else if (s.count(coordination_on) == 1) { const QStringList p(s.split(coordination_on, QString::SkipEmptyParts)); const QString sp(p.at(1) + _space_char + p.at(0)); if (_keysentences.contains(sp)) ksdndmax = _digest_sentence(&_keysentences[sp], ksdndmax, &ndmax); } else if (s.count(coordination_in) == 1) { const QStringList p(s.split(coordination_in, QString::SkipEmptyParts)); const QString sp(p.at(1) + _space_char + p.at(0)); if (_keysentences.contains(sp)) ksdndmax = _digest_sentence(&_keysentences[sp], ksdndmax, &ndmax); } // Unify genitives if (s.contains(trailing_aps) || s.contains(trailing_ap)) { QString sp(s); sp.remove(trailing_aps); sp.remove(trailing_ap); if (s.length() != sp.length() && _keysentences.contains(sp)) ksdndmax = _digest_sentence(&_keysentences[sp], ksdndmax, &ndmax); } // Unify number if (s.contains(trailing_s) || s.contains(trailing_ae)) { QString sp(s); sp.replace(trailing_dices, "dex"); sp.replace(trailing_ices, "ix"); sp.replace(trailing_ae, "a"); sp.replace(trailing_ies, "y"); sp.replace(trailing_ches, "ch"); sp.replace(trailing_ss, "sss"); sp.replace(trailing_us, "uss"); sp.replace(trailing_aps, "'ss"); sp.replace(trailing_sses, "sss"); sp.replace(trailing_is, "iss"); sp.remove(trailing_s); if (s.length() != sp.length() && _keysentences.contains(sp)) ksdndmax = _digest_sentence(&_keysentences[sp], ksdndmax, &ndmax); } ksdndmax->ndocuments = ksdndmax->documents.count(); } _out << QObject::tr("done") << endl; } collectionIndex::KeysentenceData* collectionIndex::_digest_sentence(KeysentenceData* ksd, KeysentenceData* ksdndmax, int* ndmax) const { if (ksd->ndocuments > *ndmax) { // Transfer from ksdndmax *ndmax = ksd->ndocuments; const int nd(ksdndmax->documents.count()); for (int i = 0; i < nd; ++i) { const int did(ksdndmax->documents.at(i)); if (!ksd->documents.contains(did)) ksd->documents.append(did); } ksdndmax->ndocuments = 0; return ksd; } else { // Transfer to ksdndmax const int nd(ksd->documents.count()); for (int i = 0; i < nd; ++i) { const int did(ksd->documents.at(i)); if (!ksdndmax->documents.contains(did)) ksdndmax->documents.append(did); } ksd->ndocuments = 0; return ksdndmax; } } bool collectionIndex::isValidKeySentence(const QString& text) const { const ushort fc(text.at(0).unicode()); if (fc == 39) return false; if (fc == 95) return false; if (fc == 97) { if (text.startsWith(QLatin1String("a "))) return false; if (text.startsWith(QLatin1String("ability "))) return false; if (text.startsWith(QLatin1String("able "))) return false; if (text.startsWith(QLatin1String("about "))) return false; if (text.startsWith(QLatin1String("above "))) return false; if (text.startsWith(QLatin1String("academy of "))) return false; if (text.startsWith(QLatin1String("according "))) return false; if (text.startsWith(QLatin1String("acknowledgment "))) return false; if (text.startsWith(QLatin1String("across "))) return false; if (text.startsWith(QLatin1String("added "))) return false; if (text.startsWith(QLatin1String("advances in "))) return false; if (text.startsWith(QLatin1String("after "))) return false; if (text.startsWith(QLatin1String("agreement "))) return false; if (text.startsWith(QLatin1String("all ")) && text.count(_space_char) < 3) return false; if (text.startsWith(QLatin1String("along "))) return false; if (text.startsWith(QLatin1String("also "))) return false; if (text.startsWith(QLatin1String("although "))) return false; if (text.startsWith(QLatin1String("among "))) return false; if (text.startsWith(QLatin1String("an "))) return false; if (text.startsWith(QLatin1String("and "))) return false; if (text.startsWith(QLatin1String("annals of "))) return false; if (text.startsWith(QLatin1String("any ")) && text.count(_space_char) < 3) return false; if (text.startsWith(QLatin1String("are "))) return false; if (text.startsWith(QLatin1String("as "))) return false; if (text.startsWith(QLatin1String("at "))) return false; if (text.startsWith(QLatin1String("author "))) return false; if (text.startsWith(QLatin1String("author's "))) return false; if (text.startsWith(QLatin1String("authors "))) return false; } else if (fc == 98) { if (text.startsWith(QLatin1String("based on "))) return false; if (text.startsWith(QLatin1String("be "))) return false; if (text.startsWith(QLatin1String("been "))) return false; if (text.startsWith(QLatin1String("before "))) return false; if (text.startsWith(QLatin1String("between "))) return false; if (text.startsWith(QLatin1String("both "))) return false; if (text.startsWith(QLatin1String("but "))) return false; if (text.startsWith(QLatin1String("by "))) return false; } else if (fc == 99) { if (text.startsWith(QLatin1String("calculated ")) && text.count(_space_char) < 3) return false; if (text.startsWith(QLatin1String("calculations "))) return false; if (text.startsWith(QLatin1String("can "))) return false; if (text.startsWith(QLatin1String("cannot "))) return false; if (text.startsWith(QLatin1String("capable "))) return false; if (text.startsWith(QLatin1String("carried "))) return false; if (text.startsWith(QLatin1String("case "))) return false; if (text.startsWith(QLatin1String("chapter "))) return false; if (text.startsWith(QLatin1String("chapters "))) return false; if (text.startsWith(QLatin1String("college of "))) return false; if (text.startsWith(QLatin1String("come "))) return false; if (text.startsWith(QLatin1String("conference on "))) return false; if (text.startsWith(QLatin1String("contribution from "))) return false; if (text.startsWith(QLatin1String("corresponding "))) return false; if (text.startsWith(QLatin1String("could "))) return false; if (text.startsWith(QLatin1String("current "))) return false; if (text.startsWith(QLatin1String("currently "))) return false; } else if (fc == 100) { if (text.startsWith(QLatin1String("data "))) return false; if (text.startsWith(QLatin1String("de "))) return false; if (text.startsWith(QLatin1String("department "))) return false; if (text.startsWith(QLatin1String("depicted "))) return false; if (text.startsWith(QLatin1String("depicts "))) return false; if (text.startsWith(QLatin1String("der "))) return false; if (text.startsWith(QLatin1String("described "))) return false; if (text.startsWith(QLatin1String("detailed "))) return false; if (text.startsWith(QLatin1String("details "))) return false; if (text.startsWith(QLatin1String("determined "))) return false; if (text.startsWith(QLatin1String("did not "))) return false; if (text.startsWith(QLatin1String("different ")) && text.count(_space_char) < 3) return false; if (text.startsWith(QLatin1String("difficult "))) return false; if (text.startsWith(QLatin1String("discussed "))) return false; if (text.startsWith(QLatin1String("dissolved "))) return false; if (text.startsWith(QLatin1String("do "))) return false; if (text.startsWith(QLatin1String("does "))) return false; if (text.startsWith(QLatin1String("due ")) && text.count(_space_char) < 3) return false; if (text.startsWith(QLatin1String("during "))) return false; } else if (fc == 101) { if (text.startsWith(QLatin1String("each "))) return false; if (text.startsWith(QLatin1String("easily "))) return false; if (text.startsWith(QLatin1String("easy "))) return false; if (text.startsWith(QLatin1String("edited "))) return false; if (text.startsWith(QLatin1String("effect ")) && text.count(_space_char) < 3) return false; if (text.startsWith(QLatin1String("effects ")) && text.count(_space_char) < 3) return false; if (text.startsWith(QLatin1String("either "))) return false; if (text.startsWith(QLatin1String("elsevier "))) return false; } else if (fc == 102) { if (text.startsWith(QLatin1String("faculty of "))) return false; if (text.startsWith(QLatin1String("figure "))) return false; if (text.startsWith(QLatin1String("figures "))) return false; if (text.startsWith(QLatin1String("find "))) return false; if (text.startsWith(QLatin1String("finding "))) return false; if (text.startsWith(QLatin1String("findings "))) return false; if (text.startsWith(QLatin1String("first ")) && text.count(_space_char) < 3) return false; if (text.startsWith(QLatin1String("followed "))) return false; if (text.startsWith(QLatin1String("following "))) return false; if (text.startsWith(QLatin1String("footnote "))) return false; if (text.startsWith(QLatin1String("for "))) return false; if (text.startsWith(QLatin1String("form "))) return false; if (text.startsWith(QLatin1String("found "))) return false; if (text.startsWith(QLatin1String("foundation "))) return false; if (text.startsWith(QLatin1String("free of charge "))) return false; if (text.startsWith(QLatin1String("from "))) return false; if (text.startsWith(QLatin1String("fur "))) return false; if (text.startsWith(QLatin1String("further "))) return false; } else if (fc == 103) { if (text.startsWith(QLatin1String("gave "))) return false; if (text.startsWith(QLatin1String("give "))) return false; if (text.startsWith(QLatin1String("given "))) return false; if (text.startsWith(QLatin1String("gives "))) return false; if (text.startsWith(QLatin1String("go "))) return false; if (text.startsWith(QLatin1String("goes "))) return false; if (text.startsWith(QLatin1String("going "))) return false; if (text.startsWith(QLatin1String("groups "))) return false; } else if (fc == 104) { if (text.startsWith(QLatin1String("has "))) return false; if (text.startsWith(QLatin1String("have "))) return false; if (text.startsWith(QLatin1String("he "))) return false; if (text.startsWith(QLatin1String("highlighted "))) return false; if (text.startsWith(QLatin1String("his "))) return false; if (text.startsWith(QLatin1String("how "))) return false; } else if (fc == 105) { if (text.startsWith(QLatin1String("i "))) return false; if (text.startsWith(QLatin1String("if "))) return false; if (text.startsWith(QLatin1String("ii "))) return false; if (text.startsWith(QLatin1String("iii "))) return false; if (text.startsWith(QLatin1String("in "))) return false; if (text.startsWith(QLatin1String("initially "))) return false; if (text.startsWith(QLatin1String("int j "))) return false; if (text.startsWith(QLatin1String("international conference on "))) return false; if (text.startsWith(QLatin1String("international journal "))) return false; if (text.startsWith(QLatin1String("into "))) return false; if (text.startsWith(QLatin1String("is "))) return false; if (text.startsWith(QLatin1String("it "))) return false; if (text.startsWith(QLatin1String("its "))) return false; } else if (fc == 106) { if (text.startsWith(QLatin1String("j "))) return false; if (text.startsWith(QLatin1String("journal of "))) return false; if (text.startsWith(QLatin1String("journal on "))) return false; if (text.startsWith(QLatin1String("just "))) return false; } else if (fc == 107) { if (text.startsWith(QLatin1String("kept "))) return false; } else if (fc == 108) { if (text.startsWith(QLatin1String("laboratory for "))) return false; if (text.startsWith(QLatin1String("laboratory of "))) return false; if (text.startsWith(QLatin1String("larger "))) return false; if (text.startsWith(QLatin1String("less "))) return false; if (text.startsWith(QLatin1String("let "))) return false; if (text.startsWith(QLatin1String("lower "))) return false; } else if (fc == 109) { if (text.startsWith(QLatin1String("may "))) return false; if (text.startsWith(QLatin1String("mol "))) return false; if (text.startsWith(QLatin1String("more "))) return false; if (text.startsWith(QLatin1String("most ")) && text.count(_space_char) < 3) return false; if (text.startsWith(QLatin1String("much ")) && text.count(_space_char) < 3) return false; if (text.startsWith(QLatin1String("my "))) return false; } else if (fc == 110) { if (text.startsWith(QLatin1String("national academy of "))) return false; if (text.startsWith(QLatin1String("need "))) return false; if (text.startsWith(QLatin1String("new "))) return false; if (text.startsWith(QLatin1String("not ")) && text.count(_space_char) < 3) return false; } else if (fc == 111) { if (text.startsWith(QLatin1String("observed "))) return false; if (text.startsWith(QLatin1String("obtained "))) return false; if (text.startsWith(QLatin1String("occur "))) return false; if (text.startsWith(QLatin1String("occurs "))) return false; if (text.startsWith(QLatin1String("of "))) return false; if (text.startsWith(QLatin1String("office "))) return false; if (text.startsWith(QLatin1String("on "))) return false; if (text.startsWith(QLatin1String("only "))) return false; if (text.startsWith(QLatin1String("onto "))) return false; if (text.startsWith(QLatin1String("or "))) return false; if (text.startsWith(QLatin1String("other "))) return false; if (text.startsWith(QLatin1String("otherwise "))) return false; if (text.startsWith(QLatin1String("our "))) return false; if (text.startsWith(QLatin1String("over "))) return false; } else if (fc == 112) { if (text.startsWith(QLatin1String("per "))) return false; if (text.startsWith(QLatin1String("permission of "))) return false; if (text.startsWith(QLatin1String("play "))) return false; if (text.startsWith(QLatin1String("played "))) return false; if (text.startsWith(QLatin1String("please "))) return false; if (text.startsWith(QLatin1String("possible "))) return false; if (text.startsWith(QLatin1String("present"))) return false; if (text.startsWith(QLatin1String("previous "))) return false; if (text.startsWith(QLatin1String("proceedings "))) return false; if (text.startsWith(QLatin1String("proof "))) return false; } else if (fc == 113) { if (text.startsWith(QLatin1String("quite "))) return false; } else if (fc == 114) { if (text.startsWith(QLatin1String("rather "))) return false; if (text.startsWith(QLatin1String("rest of "))) return false; if (text.startsWith(QLatin1String("result of "))) return false; if (text.startsWith(QLatin1String("reviews in "))) return false; if (text.startsWith(QLatin1String("run "))) return false; } else if (fc == 115) { if (text.startsWith(QLatin1String("same "))) return false; if (text.startsWith(QLatin1String("see "))) return false; if (text.startsWith(QLatin1String("several "))) return false; if (text.startsWith(QLatin1String("shall "))) return false; if (text.startsWith(QLatin1String("show "))) return false; if (text.startsWith(QLatin1String("shown "))) return false; if (text.startsWith(QLatin1String("since "))) return false; if (text.startsWith(QLatin1String("so "))) return false; if (text.startsWith(QLatin1String("some "))) return false; if (text.startsWith(QLatin1String("strongly "))) return false; if (text.startsWith(QLatin1String("studied "))) return false; if (text.startsWith(QLatin1String("studies "))) return false; if (text.startsWith(QLatin1String("study "))) return false; if (text.startsWith(QLatin1String("such "))) return false; if (text.startsWith(QLatin1String("supporting "))) return false; if (text.startsWith(QLatin1String("suppose "))) return false; if (text.startsWith(QLatin1String("symposium on "))) return false; } else if (fc == 116) { if (text.startsWith(QLatin1String("than "))) return false; if (text.startsWith(QLatin1String("thank "))) return false; if (text.startsWith(QLatin1String("that "))) return false; if (text.startsWith(QLatin1String("the "))) return false; if (text.startsWith(QLatin1String("their "))) return false; if (text.startsWith(QLatin1String("then "))) return false; if (text.startsWith(QLatin1String("there "))) return false; if (text.startsWith(QLatin1String("these "))) return false; if (text.startsWith(QLatin1String("they "))) return false; if (text.startsWith(QLatin1String("this "))) return false; if (text.startsWith(QLatin1String("those "))) return false; if (text.startsWith(QLatin1String("thus "))) return false; if (text.startsWith(QLatin1String("title "))) return false; if (text.startsWith(QLatin1String("to "))) return false; if (text.startsWith(QLatin1String("too "))) return false; if (text.startsWith(QLatin1String("top "))) return false; if (text.startsWith(QLatin1String("transactions on "))) return false; } else if (fc == 117) { if (text.startsWith(QLatin1String("under "))) return false; if (text.startsWith(QLatin1String("us "))) return false; if (text.startsWith(QLatin1String("use "))) return false; if (text.startsWith(QLatin1String("used "))) return false; if (text.startsWith(QLatin1String("uses "))) return false; if (text.startsWith(QLatin1String("using "))) return false; } else if (fc == 118) { if (text.startsWith(QLatin1String("very ")) && text.count(_space_char) < 3) return false; } else if (fc == 119) { if (text.startsWith(QLatin1String("was "))) return false; if (text.startsWith(QLatin1String("we "))) return false; if (text.startsWith(QLatin1String("were "))) return false; if (text.startsWith(QLatin1String("were "))) return false; if (text.startsWith(QLatin1String("what "))) return false; if (text.startsWith(QLatin1String("when "))) return false; if (text.startsWith(QLatin1String("whenever "))) return false; if (text.startsWith(QLatin1String("where "))) return false; if (text.startsWith(QLatin1String("whether "))) return false; if (text.startsWith(QLatin1String("which "))) return false; if (text.startsWith(QLatin1String("while "))) return false; if (text.startsWith(QLatin1String("whose "))) return false; if (text.startsWith(QLatin1String("wiley "))) return false; if (text.startsWith(QLatin1String("will "))) return false; if (text.startsWith(QLatin1String("with "))) return false; if (text.startsWith(QLatin1String("within "))) return false; if (text.startsWith(QLatin1String("without "))) return false; if (text.startsWith(QLatin1String("work "))) return false; if (text.startsWith(QLatin1String("workshop on "))) return false; if (text.startsWith(QLatin1String("worth "))) return false; if (text.startsWith(QLatin1String("would "))) return false; } else if (fc == 120) { if (text.startsWith(QLatin1String("x "))) return false; } else if (fc == 121) { if (text.startsWith(QLatin1String("yes "))) return false; if (text.startsWith(QLatin1String("you "))) return false; if (text.startsWith(QLatin1String("your "))) return false; } const ushort lc(text.at(text.length() - 1).unicode()); if (lc == 95) return false; if (lc == 97) { if (text.endsWith(QLatin1String(" a"))) return false; if (text.endsWith(QLatin1String(" via"))) return false; } else if (lc == 100) { if (text.endsWith(QLatin1String(" and"))) return false; if (text.endsWith(QLatin1String(" applied"))) return false; if (text.endsWith(QLatin1String(" carried"))) return false; if (text.endsWith(QLatin1String(" could"))) return false; if (text.endsWith(QLatin1String(" performed"))) return false; if (text.endsWith(QLatin1String(" second"))) return false; if (text.endsWith(QLatin1String(" should"))) return false; if (text.endsWith(QLatin1String(" showed"))) return false; if (text.endsWith(QLatin1String(" third"))) return false; if (text.endsWith(QLatin1String(" used"))) return false; if (text.endsWith(QLatin1String(" would"))) return false; } else if (lc == 101) { if (text.endsWith(QLatin1String(" above"))) return false; if (text.endsWith(QLatin1String(" are"))) return false; if (text.endsWith(QLatin1String(" available"))) return false; if (text.endsWith(QLatin1String(" be"))) return false; if (text.endsWith(QLatin1String(" because"))) return false; if (text.endsWith(QLatin1String(" due"))) return false; if (text.endsWith(QLatin1String(" gave"))) return false; if (text.endsWith(QLatin1String(" have"))) return false; if (text.endsWith(QLatin1String(" he"))) return false; if (text.endsWith(QLatin1String(" here"))) return false; if (text.endsWith(QLatin1String(" importance"))) return false; if (text.endsWith(QLatin1String(" indicate"))) return false; if (text.endsWith(QLatin1String(" like"))) return false; if (text.endsWith(QLatin1String(" made"))) return false; if (text.endsWith(QLatin1String(" more"))) return false; if (text.endsWith(QLatin1String(" same"))) return false; if (text.endsWith(QLatin1String(" since"))) return false; if (text.endsWith(QLatin1String(" the"))) return false; if (text.endsWith(QLatin1String(" there"))) return false; if (text.endsWith(QLatin1String(" these"))) return false; if (text.endsWith(QLatin1String(" we"))) return false; if (text.endsWith(QLatin1String(" were"))) return false; if (text.endsWith(QLatin1String(" where"))) return false; if (text.endsWith(QLatin1String(" where"))) return false; if (text.endsWith(QLatin1String(" while"))) return false; if (text.endsWith(QLatin1String(" whose"))) return false; } else if (lc == 102) { if (text.endsWith(QLatin1String(" if"))) return false; if (text.endsWith(QLatin1String(" of"))) return false; } else if (lc == 103) { if (text.endsWith(QLatin1String(" according"))) return false; if (text.endsWith(QLatin1String(" along"))) return false; if (text.endsWith(QLatin1String(" belonging"))) return false; if (text.endsWith(QLatin1String(" containing"))) return false; if (text.endsWith(QLatin1String(" corresponding"))) return false; if (text.endsWith(QLatin1String(" during"))) return false; if (text.endsWith(QLatin1String(" fig"))) return false; if (text.endsWith(QLatin1String(" having"))) return false; if (text.endsWith(QLatin1String(" involving"))) return false; if (text.endsWith(QLatin1String(" using"))) return false; } else if (lc == 104) { if (text.endsWith(QLatin1String(" although"))) return false; if (text.endsWith(QLatin1String(" both"))) return false; if (text.endsWith(QLatin1String(" much"))) return false; if (text.endsWith(QLatin1String(" such"))) return false; if (text.endsWith(QLatin1String(" through"))) return false; if (text.endsWith(QLatin1String(" which"))) return false; if (text.endsWith(QLatin1String(" with"))) return false; } else if (lc == 105) { if (text.endsWith(QLatin1String(" i"))) return false; } else if (lc == 108) { if (text.endsWith(QLatin1String(" all"))) return false; if (text.endsWith(QLatin1String(" several"))) return false; if (text.endsWith(QLatin1String(" will"))) return false; } else if (lc == 109) { if (text.endsWith(QLatin1String(" from"))) return false; if (text.endsWith(QLatin1String(" them"))) return false; } else if (lc == 110) { if (text.endsWith(QLatin1String(" an"))) return false; if (text.endsWith(QLatin1String(" been"))) return false; if (text.endsWith(QLatin1String(" between"))) return false; if (text.endsWith(QLatin1String(" can"))) return false; if (text.endsWith(QLatin1String(" in"))) return false; if (text.endsWith(QLatin1String(" known"))) return false; if (text.endsWith(QLatin1String(" on"))) return false; if (text.endsWith(QLatin1String(" shown"))) return false; if (text.endsWith(QLatin1String(" shown"))) return false; if (text.endsWith(QLatin1String(" supporting information"))) return false; if (text.endsWith(QLatin1String(" taken"))) return false; if (text.endsWith(QLatin1String(" than"))) return false; if (text.endsWith(QLatin1String(" then"))) return false; if (text.endsWith(QLatin1String(" upon"))) return false; if (text.endsWith(QLatin1String(" when"))) return false; if (text.endsWith(QLatin1String(" within"))) return false; } else if (lc == 111) { if (text.endsWith(QLatin1String(" also"))) return false; if (text.endsWith(QLatin1String(" do"))) return false; if (text.endsWith(QLatin1String(" into"))) return false; if (text.endsWith(QLatin1String(" to"))) return false; if (text.endsWith(QLatin1String(" two"))) return false; if (text.endsWith(QLatin1String(" who"))) return false; } else if (lc == 114) { if (text.endsWith(QLatin1String(" after"))) return false; if (text.endsWith(QLatin1String(" chapter"))) return false; if (text.endsWith(QLatin1String(" elsevier"))) return false; if (text.endsWith(QLatin1String(" for"))) return false; if (text.endsWith(QLatin1String(" or"))) return false; if (text.endsWith(QLatin1String(" our"))) return false; if (text.endsWith(QLatin1String(" over"))) return false; if (text.endsWith(QLatin1String(" per"))) return false; if (text.endsWith(QLatin1String(" their"))) return false; if (text.endsWith(QLatin1String(" under"))) return false; if (text.endsWith(QLatin1String(" whether"))) return false; if (text.endsWith(QLatin1String(" your"))) return false; } else if (lc == 115) { if (text.endsWith(QLatin1String(" across"))) return false; if (text.endsWith(QLatin1String(" as"))) return false; if (text.endsWith(QLatin1String(" does"))) return false; if (text.endsWith(QLatin1String(" does"))) return false; if (text.endsWith(QLatin1String(" figs"))) return false; if (text.endsWith(QLatin1String(" follows"))) return false; if (text.endsWith(QLatin1String(" gives"))) return false; if (text.endsWith(QLatin1String(" has"))) return false; if (text.endsWith(QLatin1String(" his"))) return false; if (text.endsWith(QLatin1String(" is"))) return false; if (text.endsWith(QLatin1String(" its"))) return false; if (text.endsWith(QLatin1String(" ones"))) return false; if (text.endsWith(QLatin1String(" shows"))) return false; if (text.endsWith(QLatin1String(" this"))) return false; if (text.endsWith(QLatin1String(" us"))) return false; if (text.endsWith(QLatin1String(" was"))) return false; if (text.endsWith(QLatin1String(" yes"))) return false; if (text.endsWith(QLatin1String("acids res"))) return false; } else if (lc == 116) { if (text.endsWith(QLatin1String(" about"))) return false; if (text.endsWith(QLatin1String(" at"))) return false; if (text.endsWith(QLatin1String(" department"))) return false; if (text.endsWith(QLatin1String(" et"))) return false; if (text.endsWith(QLatin1String(" first"))) return false; if (text.endsWith(QLatin1String(" important"))) return false; if (text.endsWith(QLatin1String(" it"))) return false; if (text.endsWith(QLatin1String(" let"))) return false; if (text.endsWith(QLatin1String(" most"))) return false; if (text.endsWith(QLatin1String(" must"))) return false; if (text.endsWith(QLatin1String(" not"))) return false; if (text.endsWith(QLatin1String(" out"))) return false; if (text.endsWith(QLatin1String(" suggest"))) return false; if (text.endsWith(QLatin1String(" that"))) return false; if (text.endsWith(QLatin1String(" without"))) return false; } else if (lc == 117) { if (text.endsWith(QLatin1String(" you"))) return false; } else if (lc == 119) { if (text.endsWith(QLatin1String(" how"))) return false; if (text.endsWith(QLatin1String(" new"))) return false; if (text.endsWith(QLatin1String(" show"))) return false; } else if (lc == 121) { if (text.endsWith(QLatin1String(" any"))) return false; if (text.endsWith(QLatin1String(" by"))) return false; if (text.endsWith(QLatin1String(" may"))) return false; if (text.endsWith(QLatin1String(" my"))) return false; if (text.endsWith(QLatin1String(" only"))) return false; if (text.endsWith(QLatin1String(" society"))) return false; if (text.endsWith(QLatin1String(" they"))) return false; if (text.endsWith(QLatin1String(" wiley"))) return false; } if (text.contains(QLatin1String("_ "))) return false; if (text.contains(QLatin1String(" _"))) return false; if (_last_equals_first(text)) return false; return true; } QString collectionIndex::preprocessedText(const QString& journal, const QString& text) const { QString pt(text.toLower()); if (journal.contains(_space_char)) { QStringList jns; jns.append(journal.toLower()); jns.append(_bpP->fullJournal(journal).toLower()); jns.append(_bpP->abbreviatedJournal(journal).toLower()); jns.append(QString(jns.at(0)).remove('.')); jns.append(QString(jns.at(1)).remove('.')); jns.append(QString(jns.at(2)).remove('.')); jns.removeDuplicates(); for (int i = 0; i < jns.count(); ++i) c2bUtils::fillString(pt, QStringMatcher(jns.at(i), Qt::CaseSensitive), '.'); } c2bUtils::fillString(pt, txtmatcher("\"", Qt::CaseSensitive, 0), ' '); c2bUtils::fillString(pt, txtmatcher("-", Qt::CaseSensitive, 0), '_'); pt.replace(QRegularExpression("_{2,}", _qre_pattern_options), "_"); pt.replace(QRegularExpression("\\bin *situ\\b", _qre_pattern_options), " in_situ "); pt.replace(QRegularExpression("\\bin *vivo\\b", _qre_pattern_options), " in_vivo "); pt.replace(QRegularExpression("\\bin *vitro\\b", _qre_pattern_options), " in_vitro "); pt.replace(QRegularExpression("\\bex *situ\\b", _qre_pattern_options), " ex_situ "); pt.replace(QRegularExpression("\\bex *vivo\\b", _qre_pattern_options), " ex_vivo "); pt.replace(QRegularExpression("\\bex *vitro\\b", _qre_pattern_options), " ex_vitro "); // Clear some strings c2bUtils::fillString(pt, QRegularExpression("\\bbased (?=on\\b)", _qre_pattern_options), ' '); c2bUtils::fillString(pt, QRegularExpression("\\bin order (?=to\\b)", _qre_pattern_options), ' '); c2bUtils::fillString(pt, txtmatcher(" a ", Qt::CaseSensitive, 0), ' '); c2bUtils::fillString(pt, txtmatcher(" an ", Qt::CaseSensitive, 2), ' '); c2bUtils::fillString(pt, txtmatcher(" its ", Qt::CaseSensitive, 3), ' '); c2bUtils::fillString(pt, txtmatcher(" the ", Qt::CaseSensitive, 2), ' '); c2bUtils::fillString(pt, txtmatcher(" their ", Qt::CaseSensitive, 2), ' '); c2bUtils::fillString(pt, txtmatcher(" '", Qt::CaseSensitive, 1), ' '); c2bUtils::fillString(pt, txtmatcher("' ", Qt::CaseSensitive, 0), ' '); // Set additional breakpoints c2bUtils::fillString(pt, txtmatcher(" are ", Qt::CaseSensitive, 2), '.'); c2bUtils::fillString(pt, txtmatcher(" be ", Qt::CaseSensitive, 1), '.'); c2bUtils::fillString(pt, txtmatcher(" is ", Qt::CaseSensitive, 2), '.'); c2bUtils::fillString(pt, txtmatcher(" was ", Qt::CaseSensitive, 1), '.'); c2bUtils::fillString(pt, txtmatcher(" were ", Qt::CaseSensitive, 1), '.'); c2bUtils::fillString(pt, QRegularExpression("\\binstitut\\w*", _qre_pattern_options), '.'); c2bUtils::fillString(pt, QRegularExpression("\\buniversi\\w*", _qre_pattern_options), '.'); c2bUtils::fillString(pt, QRegularExpression("\\bdoi\\w*", _qre_pattern_options), '.'); c2bUtils::fillString(pt, QRegularExpression("\\bet al\\w*", _qre_pattern_options), '.'); // Normalize proper names c2bUtils::fillString(pt, QRegularExpression("\\bdo not\\b", _qre_pattern_options), '.'); pt.replace(QRegularExpression("\\b" + _bpP->authorPrefixes() + "\\s", _qre_pattern_options), QString("\\1%1").arg(QChar(127))); replace(pt, QChar(127), '_'); // Remove noisy elements from PDF articles c2bUtils::fillString(pt, QStringMatcher("page intentionally left", Qt::CaseSensitive), '.'); c2bUtils::fillString(pt, QStringMatcher("journal article", Qt::CaseSensitive), '.'); c2bUtils::fillString(pt, QRegularExpression(" \\w \\w \\w ", _qre_pattern_options), '.'); c2bUtils::stripDiacritics(pt); c2bUtils::simplifyString(pt); return pt; } QString& collectionIndex::replace(QString& str, const QChar& a, const QChar& b) const { const int length(str.length()); QChar* const s(str.data()); int i(0); while (i < length) { QChar& c(s[i]); if (c == a) c = b; ++i; } return str; } cb2bib-2.0.1/src/c2b/PaxHeaders.5700/wordMatcher.h0000644000000000000000000000013214011522520016162 xustar0030 mtime=1613145424.778620335 30 atime=1613145424.834620334 30 ctime=1613145424.782620335 cb2bib-2.0.1/src/c2b/wordMatcher.h0000644000175000001440000000470314011522520017565 0ustar00constansusers00000000000000/*************************************************************************** * Copyright (C) 2004-2021 by Pere Constans * constans@molspaces.com * cb2Bib version 2.0.1. Licensed under the GNU GPL version 3. * See the LICENSE file that comes with this distribution. ***************************************************************************/ #ifndef WORDMATCHER_H #define WORDMATCHER_H #include "txtmatcher.h" #include #include class wordMatcher { public: wordMatcher(); explicit wordMatcher(const QString& pattern, const Qt::CaseSensitivity cs = Qt::CaseSensitive); inline ~wordMatcher() {} int indexIn(const QString& text, const int from = 0) const; void setPattern(const QString& pattern, const Qt::CaseSensitivity cs); inline int matchedLength() const { return _matched_length; } inline const QStringList& subpatternStrings() const { return _subpatterns; } private: inline int _index_in(const int s, const QString& text, const int p0) const { return _substrings.at(s).indexIn(text, p0); } inline int _index_in(const int s, const QString& text, const int p0, const int pn) const { return _substrings.at(s).indexIn(text.unicode(), std::min(_pn, pn), p0); } inline int _index_around(const QString& text, const int phook) const { for (int i = 0; i < _substring_count; ++i) _sp0[i] = -1; _sp0[_hook] = phook; const int bp0 = std::max(_p0, phook - _stretch); const int bpn = std::min(_pn, phook + _stretch); for (int i = 0; i < _substring_count; ++i) if (_sp0.at(i) == -1) { const int p0(_index_in(i, text, bp0, bpn)); if (p0 == -1) return -1; _sp0[i] = p0; } int bp(_pn); int fp(_p0); for (int i = 0; i < _substring_count; ++i) { const int p0(_sp0.at(i)); if (bp > p0) bp = p0; const int pn(p0 + _lengths.at(i)); if (fp < pn) fp = pn; } _matched_length = fp - bp; return bp; } QStringList _subpatterns; QVector _lengths; QVector _substrings; int _hook; int _stretch; int _substring_count; mutable QVector _sp0; mutable int _matched_length; mutable int _p0; mutable int _pn; }; #endif cb2bib-2.0.1/src/c2b/PaxHeaders.5700/document.cpp0000644000000000000000000000013014011522520016052 xustar0029 mtime=1613145424.61462034 30 atime=1613145424.834620334 29 ctime=1613145424.62262034 cb2bib-2.0.1/src/c2b/document.cpp0000644000175000001440000004110414011522520017453 0ustar00constansusers00000000000000/*************************************************************************** * Copyright (C) 2004-2021 by Pere Constans * constans@molspaces.com * cb2Bib version 2.0.1. Licensed under the GNU GPL version 3. * See the LICENSE file that comes with this distribution. ***************************************************************************/ #include "document.h" #include "cb2bib_utilities.h" #include "settings.h" #include document::document(const QString& fn, const Conversion mode) { _document_fn = fn.trimmed(); settings* settingsP = settings::instance(); _converter_output = settingsP->tempPath() + "/cb2bib_document_conversion_tmp_" + settingsP->applicationPid(); setConverter(mode); } QString document::fileToString(const QString& fn) { _document_fn = fn.trimmed(); return toString(); } QString document::toString() { _error_string.clear(); _log_string.clear(); if (_document_fn.isEmpty()) return QString(); QFileInfo fbin(_converter_bin); if (fbin.isAbsolute()) if (!fbin.exists() || !fbin.isFile()) { _error_string = QObject::tr("Converter %1 does not exist\n").arg(_converter_bin); return QString(); } QFileInfo fi(_document_fn); if (!fi.exists() || !fi.isFile()) { _error_string = QObject::tr("File %1 does not exist\n").arg(_document_fn); return QString(); } QProcess converter; QStringList args(_converter_arg.split(' ', QString::SkipEmptyParts)); args.append(_document_fn); args.append(_converter_output); converter.start(_converter_bin, args); if (!converter.waitForStarted()) { _error_string += QObject::tr("Converter '%1 %2' could not be started. Check file permissions and path\n") .arg(_converter_bin, _converter_arg); return QString(); } if (!converter.waitForFinished(_conversion_mode == Complete ? -1 : 150000)) { converter.kill(); c2bUtils::warn(QObject::tr("Error: Document conversion timeout for file '%1'").arg(_document_fn)); } QString doc(c2bUtils::fileToString(_converter_output, true)); _log_string = QString::fromUtf8(converter.readAllStandardOutput().trimmed()); _log_string += '\n' + QString::fromUtf8(converter.readAllStandardError().trimmed()); if (converter.exitStatus() != QProcess::NormalExit || doc.isEmpty()) { _error_string += QObject::tr("[%1 %2] Conversion failed for file %3\n").arg(_converter_bin, _converter_arg, _document_fn); c2bUtils::warn(QObject::tr("Warning: Text conversion for file '%1' is empty").arg(_document_fn)); return QString(); } normalize(doc, _conversion_mode); // Recheck in case normalize reveals badly encoded PDFs if (doc.isEmpty()) c2bUtils::warn(QObject::tr("Warning: Text conversion for file '%1' is empty").arg(_document_fn)); return doc; } QString& document::normalize(QString& doc, const Conversion mode) { if (doc.length() == 0) return doc; const ushort unull(0); const ushort unl(10); const ushort uspace(32); const ushort uhyp(45); bool hgrave(false); bool hdieresis(false); bool haccute(false); bool hcedilla(false); bool hcircumflex(false); bool hcaron(false); bool hring(false); bool htilde(false); bool hreg(false); bool hligatures(false); ushort* const c0((ushort*)doc.data()); const ushort* const cn(c0 + doc.length()); ushort* c(c0 - 1); while (c < cn) { ++c; ushort& uc(*c); if (uc > 96 && uc < 127) continue; if (uc > 31 && uc < 94) continue; const QChar::Category ct(QChar::category(uc)); if (ct == QChar::Mark_NonSpacing) uc = unull; else if (ct == QChar::Mark_SpacingCombining) uc = uspace; else if (ct == QChar::Mark_Enclosing) uc = uspace; else if (ct == QChar::Separator_Space) uc = uspace; else if (ct == QChar::Separator_Paragraph) uc = unl; else if (ct == QChar::Other_Control) { if (uc == 10 || uc == 13) uc = unl; else uc = uspace; } else if (ct == QChar::Other_Format) uc = uc == 173 ? uhyp : unull; else if (ct == QChar::Other_PrivateUse) uc = uspace; else if (ct == QChar::Other_NotAssigned) uc = uspace; else if (uc == QChar::ReplacementCharacter) uc = uspace; else if (uc == 96) hgrave = true; else if (uc == 168) hdieresis = true; else if (uc == 180) haccute = true; else if (uc == 184) hcedilla = true; else if (uc == 710) hcircumflex = true; else if (uc == 711) hcaron = true; else if (uc == 730) hring = true; else if (uc == 732) htilde = true; // Normalize apostrophe else if (uc == 8216 || uc == 8217) uc = 39; // Normalize comma else if (uc == 65292) uc = 44; // Normalize quotation else if (uc == 8220 || uc == 8221 || uc == 65282) uc = 34; // Normalize separator else if ((uc > 8207 && uc < 8213) || uc == 8722) uc = uhyp; // Corrections else if (uc == 174) hreg = true; else if (uc == 305) uc = 105; else if (uc == 1001) uc = 43; else if (uc == 1002 || uc == 1003) uc = 45; else if (uc == 306 || uc == 307 || uc == 455 || uc == 460 || uc == 498 || uc == 64256 || uc == 64257 || uc == 64258 || uc == 64259 || uc == 64260) hligatures = true; } // Diacritics from legacy PDFs are set to text in several manners: // - an orphan diacritic is set either before or after the letter // - an orphan diacritic might be followed by one or more spaces, resulting in broken words // These deficiencies impact on indexing and searching // In the following // - an orphan diacritic is re-set to the most probably accented letters // - extra spaces are removed whenever the risk of joining two independent words is low if (haccute) { const ushort uaccute(180); c = c0 + 1; const ushort* const cm(cn - 2); while (c < cm) { if (*c == uaccute && *(c + 1) == uspace) { const QChar r(*(c - 1)); const QChar s(*(c + 2)); if (r.isLetter()) if ((r.isUpper() && s.isLetter()) || s.category() == QChar::Punctuation_Dash || s.category() == QChar::Punctuation_Other || s.isSpace()) *(c + 1) = unull; } ++c; } } // Revert hyphenation (skip for FirstPage mode to preserve layout) if (mode == Complete) { c = c0 + 1; const ushort* const cm(cn - 2); while (c < cm) { if (*c == uhyp) { const QChar r(*(c - 1)); if (r.isLetter()) { ushort* cs(c); bool h(false); while (cs < cn) if (QChar(*(++cs)).isLetter()) break; else if (*cs == unl) h = true; else if (*cs != uspace) { h = false; break; } if (h && cs < cn) { QString testw; for (ushort* cw = c - 1; cw > c0; --cw) if (QChar(*cw).isLetter()) testw.prepend(QChar(*cw)); else break; testw.append(QChar(uhyp)); for (ushort* cw = cs; cw < cn; ++cw) if (QChar(*cw).isLetter()) testw.append(QChar(*cw)); else break; const QChar s(*cs); // Avoid de-hyphenating 'divide-and-conquer' like cases by checking the word in document if (doc.contains(testw)) ++c; // Avoid de-hyphenating 'Hartree-Fock' like cases; replace hyphen by space else if ((r.isLower() && s.isUpper()) || (r.isUpper() && s.isLower())) *(c++) = uspace; for (ushort* z = c; z < cs; ++z) *z = unull; c = cs + 1; } } } ++c; } } // Clear extra spaces on enclosing marks { c = c0; while (c < cn) { ++c; ushort& uc(*c); if (uc < 40) continue; if (uc > 41 && uc < 91) continue; if (uc > 93 && uc < 123) continue; const QChar::Category ct(QChar::category(uc)); if (ct == QChar::Punctuation_Open) { for (ushort* co = c + 1; co < cn; ++co) if (*co == uspace || *co == unl || *co == unull) *co = unull; else break; } else if (ct == QChar::Punctuation_Close) { for (ushort* cc = c - 1; cc > c0; --cc) if (*cc == uspace || *cc == unl || *cc == unull) *cc = unull; else break; } } } // Remove null characters (djvutxt end of page, and other control characters) doc.remove(QChar(unull)); if (hreg) { // Correct frequent misencoding of "fi" as circle R in PDFs (Adobe Standard Encoding) doc.replace(QRegExp(QString("%1([a-z])").arg(QChar(174))), "fi\\1"); } if (hligatures) { // Revert Latin ligatures doc.replace(QChar(306), "IJ"); doc.replace(QChar(307), "ij"); doc.replace(QChar(455), "LJ"); doc.replace(QChar(460), "nj"); doc.replace(QChar(498), "Dz"); doc.replace(QChar(64256), "ff"); doc.replace(QChar(64257), "fi"); doc.replace(QChar(64258), "fl"); doc.replace(QChar(64259), "ffi"); doc.replace(QChar(64260), "ffl"); } if (hgrave) { const QChar grave(96); doc.replace('a' + grave, QChar(224)); doc.replace(grave + 'a', QChar(224)); doc.replace('e' + grave, QChar(232)); doc.replace(grave + 'e', QChar(232)); doc.replace('o' + grave, QChar(242)); doc.replace('u' + grave, QChar(249)); doc.replace('y' + grave, QChar(7923)); doc.replace('A' + grave, QChar(192)); doc.replace('E' + grave, QChar(200)); doc.replace('O' + grave, QChar(210)); } if (hdieresis) { const QChar dieresis(168); doc.replace(QRegExp(dieresis + ' ' + '+'), dieresis); doc.replace(dieresis + ' ', dieresis); doc.replace('a' + dieresis, QChar(228)); doc.replace('e' + dieresis, QChar(235)); doc.replace('i' + dieresis, QChar(239)); doc.replace('o' + dieresis, QChar(246)); doc.replace('u' + dieresis, QChar(252)); doc.replace('A' + dieresis, QChar(196)); doc.replace('E' + dieresis, QChar(203)); doc.replace('I' + dieresis, QChar(207)); doc.replace('O' + dieresis, QChar(214)); doc.replace('U' + dieresis, QChar(220)); doc.replace(dieresis + 'a', QChar(228)); doc.replace(dieresis + 'e', QChar(235)); doc.replace(dieresis + 'i', QChar(239)); doc.replace(dieresis + 'o', QChar(246)); doc.replace(dieresis + 'u', QChar(252)); doc.replace(dieresis + 'A', QChar(196)); doc.replace(dieresis + 'E', QChar(203)); doc.replace(dieresis + 'I', QChar(207)); doc.replace(dieresis + 'O', QChar(214)); doc.replace(dieresis + 'U', QChar(220)); } if (haccute) { const QChar accute(180); doc.replace('e' + accute, QChar(233)); doc.replace(accute + 'e', QChar(233)); doc.replace('A' + accute, QChar(193)); doc.replace(accute + 'A', QChar(193)); doc.replace('a' + accute, QChar(225)); doc.replace(accute + 'a', QChar(225)); doc.replace('o' + accute, QChar(243)); doc.replace(accute + 'o', QChar(243)); doc.replace('i' + accute, QChar(237)); doc.replace(accute + 'i', QChar(237)); doc.replace('E' + accute, QChar(201)); doc.replace(accute + 'E', QChar(201)); doc.replace('u' + accute, QChar(250)); doc.replace(accute + 'u', QChar(250)); doc.replace('O' + accute, QChar(211)); doc.replace(accute + 'O', QChar(211)); doc.replace('I' + accute, QChar(205)); doc.replace(accute + 'I', QChar(205)); doc.replace('U' + accute, QChar(218)); doc.replace(accute + 'U', QChar(218)); doc.replace('c' + accute, QChar(263)); doc.replace('C' + accute, QChar(262)); doc.replace('y' + accute, QChar(253)); doc.replace('Y' + accute, QChar(221)); } if (hcedilla) { const QChar cedilla(184); doc.replace('c' + cedilla, QChar(231)); doc.replace(cedilla + 'c', QChar(231)); doc.replace('C' + cedilla, QChar(199)); doc.replace(cedilla + 'C', QChar(199)); doc.replace('s' + cedilla, QChar(351)); doc.replace(cedilla + 's', QChar(351)); doc.replace('S' + cedilla, QChar(350)); doc.replace(cedilla + 'S', QChar(350)); doc.replace('e' + cedilla, QChar(553)); doc.replace(cedilla + 'e', QChar(553)); doc.replace('E' + cedilla, QChar(552)); doc.replace(cedilla + 'E', QChar(552)); } if (hcircumflex) { const QChar circumflex(710); doc.replace('a' + circumflex, QChar(226)); doc.replace(circumflex + 'a', QChar(226)); doc.replace('e' + circumflex, QChar(234)); doc.replace(circumflex + 'e', QChar(234)); doc.replace('i' + circumflex, QChar(238)); doc.replace(circumflex + 'i', QChar(238)); doc.replace('o' + circumflex, QChar(244)); doc.replace(circumflex + 'o', QChar(244)); } if (hcaron) { const QChar caron(711); doc.replace('c' + caron, QChar(269)); doc.replace(caron + 'c', QChar(269)); doc.replace('C' + caron, QChar(268)); doc.replace(caron + 'C', QChar(268)); doc.replace('z' + caron, QChar(382)); doc.replace(caron + 'z', QChar(382)); doc.replace('Z' + caron, QChar(381)); doc.replace(caron + 'Z', QChar(381)); doc.replace('s' + caron, QChar(353)); doc.replace(caron + 's', QChar(353)); doc.replace('S' + caron, QChar(352)); doc.replace(caron + 'S', QChar(352)); doc.replace('r' + caron, QChar(345)); doc.replace(caron + 'r', QChar(345)); doc.replace('R' + caron, QChar(344)); doc.replace(caron + 'R', QChar(344)); } if (hring) { const QChar ring(730); doc.replace('a' + ring, QChar(229)); doc.replace('A' + ring, QChar(197)); doc.replace(ring + 'a', QChar(229)); doc.replace(ring + 'A', QChar(197)); } if (htilde) { const QChar tilde(732); doc.replace('n' + tilde, QChar(241)); doc.replace('N' + tilde, QChar(209)); doc.replace('a' + tilde, QChar(227)); doc.replace('A' + tilde, QChar(195)); } // Simplify (skip for FirstPage mode to preserve layout) if (mode == Complete) c2bUtils::simplifyString(doc); return doc; } void document::setConverter(const Conversion mode) { _conversion_mode = mode; settings* s(settings::instance()); switch (_conversion_mode) { case Complete: setConverter(s->fileName("c2bBibSearcher/Pdf2TextBin"), s->value("c2bBibSearcher/Pdf2TextArg").toString()); break; case FirstPage: default: setConverter(s->fileName("c2bPdfImport/Pdf2TextBin"), s->value("c2bPdfImport/Pdf2TextArg").toString()); break; } } void document::setConverter(const QString& bin, const QString& args) { _converter_bin = bin.trimmed(); _converter_arg = args.simplified(); } cb2bib-2.0.1/src/c2b/PaxHeaders.5700/substringMatcher.h0000644000000000000000000000013214011522520017227 xustar0030 mtime=1613145424.758620336 30 atime=1613145424.834620334 30 ctime=1613145424.762620336 cb2bib-2.0.1/src/c2b/substringMatcher.h0000644000175000001440000000666014011522520020636 0ustar00constansusers00000000000000/*************************************************************************** * Copyright (C) 2004-2021 by Pere Constans * constans@molspaces.com * cb2Bib version 2.0.1. Licensed under the GNU GPL version 3. * See the LICENSE file that comes with this distribution. ***************************************************************************/ #ifndef SUBSTRINGMATCHER_H #define SUBSTRINGMATCHER_H #include "txtmatcher.h" #include #define C2B_DEBUG_SUBSTRINGMATCHER 0 class substringMatcher { public: substringMatcher(); explicit substringMatcher(const QString& pattern, const Qt::CaseSensitivity cs = Qt::CaseSensitive); inline ~substringMatcher() {} int indexIn(const QString& str, const int from = 0) const; inline int matchedLength() const { return _matched_length; } private: inline int _index_in(const int s, const QString& str, const int p0) const { return _substrings.at(s).indexIn(str, p0); } inline int _index_in(const int s, const QString& str, const int p0, const int pn) const { #if C2B_DEBUG_SUBSTRINGMATCHER qDebug() << "Search for substring:" << _substrings.at(s).pattern() << "in interval" << p0 << pn; int i; if (p0 >= pn) i = -1; else i = _substrings.at(s).indexIn(str.unicode(), std::min(_pn, pn), p0); qDebug() << "substringMatcher: returned index:" << i; return i; #else return _substrings.at(s).indexIn(str.unicode(), std::min(_pn, pn), p0); #endif } inline int _p_back(const int s, const int p0) const { return std::max(_p0 + _acc_lengths.at(s), p0 - _stretches.at(s + 1) - _lengths.at(s)); } inline int _p_forth(const int s, const int p0) const { return std::min(_pn, p0 + _stretches.at(s) + _lengths.at(s)); } inline int _index_back(const int s, const QString& str, int p0, const int pn) const { while ((p0 = _index_in(s, str, p0, pn)) != -1) { if (s == 0) return p0; const int i(_index_back(s - 1, str, _p_back(s - 1, p0), p0)); if (i != -1) return i; p0 += _lengths.at(s); } return -1; } inline int _index_forth(const int s, const QString& str, int p0, const int pn) const { while ((p0 = _index_in(s, str, p0, pn)) != -1) { p0 += _lengths.at(s); if (s + 1 == _substring_count) return p0; const int i(_index_forth(s + 1, str, p0, _p_forth(s + 1, p0))); if (i != -1) return i; } return -1; } inline int _index_around(const QString& str, const int phook) const { int bp(phook); if (_hook > 0) { bp = _index_back(_hook - 1, str, _p_back(_hook - 1, bp), bp); if (bp == -1) return -1; } int fp(phook + _lengths.at(_hook)); if (_hook + 1 < _substring_count) { fp = _index_forth(_hook + 1, str, fp, _p_forth(_hook + 1, fp)); if (fp == -1) return -1; } _matched_length = fp - bp; return bp; } QVector _substrings; QVector _acc_lengths; QVector _lengths; QVector _stretches; int _hook; int _substring_count; mutable int _matched_length; mutable int _p0; mutable int _pn; }; #endif cb2bib-2.0.1/src/c2b/PaxHeaders.5700/networkQuery.cpp0000644000000000000000000000013214011522520016755 xustar0030 mtime=1613145424.646620339 30 atime=1613145424.834620334 30 ctime=1613145424.650620339 cb2bib-2.0.1/src/c2b/networkQuery.cpp0000644000175000001440000004071014011522520020356 0ustar00constansusers00000000000000/*************************************************************************** * Copyright (C) 2004-2021 by Pere Constans * constans@molspaces.com * cb2Bib version 2.0.1. Licensed under the GNU GPL version 3. * See the LICENSE file that comes with this distribution. ***************************************************************************/ #include "networkQuery.h" #include "bibParser.h" #include "cb2bib_utilities.h" #include "network.h" #include "settings.h" #include networkQuery::networkQuery(bibParser* bp, QObject* parento) : QObject(parento), _bpP(bp) { Q_ASSERT_X(_bpP, "networkQuery", "bibParser was not instantiated"); _networkP = new network(this); init(); } networkQuery::networkQuery(bibParser* bp, network* net, QObject* parento) : QObject(parento), _bpP(bp), _networkP(net) { Q_ASSERT_X(_bpP, "networkQuery", "bibParser was not instantiated"); Q_ASSERT_X(_networkP, "networkQuery", "network was not instantiated"); init(); } void networkQuery::init() { _settingsP = settings::instance(); _settingsP->setValue("networkQuery/isSupervised", true); _networkquery_tmp_fn1 = _settingsP->tempPath() + "/cb2bib_query_tmp_html1_" + _settingsP->applicationPid(); _networkquery_tmp_fn2 = _settingsP->tempPath() + "/cb2bib_query_tmp_html2_" + _settingsP->applicationPid(); _timing = QDateTime::currentDateTime(); } void networkQuery::submitQuery(const bibReference& reference, const QString& raw_reference, const bool check_document) { // Submission Initialization _error_string.clear(); _query_parameter_count.clear(); _is_end_of_file = false; _pdfurl_is_captured = false; _check_document = check_document && _settingsP->value("cb2Bib/AutomaticPdfDownload").toBool(); // Query data _Qtitle = reference.value("title"); _Qjournal = _bpP->fullJournal(reference.value("journal")); _Qvolume = reference.value("volume"); _Qpage = c2bUtils::firstPage(reference.value("pages")); _Qdoi = reference.value("doi").trimmed(); if (!_Qdoi.isEmpty() && !_Qdoi.contains(QRegExp("^10\\.[\\d\\.]+/\\S+$"))) { _Qdoi.clear(); c2bUtils::warn(tr("Warning: DOI skipped: '%1' is not a valid DOI").arg(_Qdoi)); } _Qauthor = reference.value("author"); _Qauthor.replace(QRegExp("(?:\\b\\w\\b|\\band\\b|\\W)"), " "); _Qauthor = c2bUtils::simplifyString(_Qauthor); _Qexcerpt = _bpP->excerpt(raw_reference, QStringList() << _Qdoi << _Qauthor << _Qtitle); _Qeprint = reference.value("eprint").trimmed(); _raw_reference = raw_reference; // Remove raw metadata in case user repeats the network query _raw_reference.remove(QRegExp("\\n\\[Raw Metadata.+$")); if (_timing.msecsTo(QDateTime::currentDateTime()) < 550) QTimer::singleShot(550, this, SLOT(submitQuery1())); else submitQuery1(); } void networkQuery::submitQuery1() { _raw_metadata.clear(); // Submission, first step, setting journal codes if (!setQueryParameters()) { _error_string = tr("No data for query."); emit queryEnded(false, _targetQ, _networkquery_tmp_fn1); return; } if (_is_end_of_file) { _error_string = tr("Performed %1 queries: No reference found.").arg(_query_parameter_count.count()); emit queryEnded(false, _targetQ, _networkquery_tmp_fn1); return; } c2bUtils::debug(tr("Query Number = %1").arg(_query_parameter_count.count())); c2bUtils::debug(tr("targetQ[%1]").arg(_targetQ)); c2bUtils::debug(tr("captionQ[%1]").arg(_captionQ)); c2bUtils::debug(tr("referenceurl_prefix[%1]").arg(_referenceurl_prefix)); c2bUtils::debug(tr("referenceurl_sufix[%1]").arg(_referenceurl_sufix)); c2bUtils::debug(tr("pdfurl_prefix[%1]").arg(_pdfurl_prefix)); c2bUtils::debug(tr("pdfurl_sufix[%1]").arg(_pdfurl_sufix)); c2bUtils::debug(tr("action[%1]").arg(_action)); c2bUtils::debug(tr("POST1[%1]").arg(_targetQ)); if (_action == "browse_query") { if (openFile(encodeUrl(_targetQ))) { _error_string = tr("Browsing query."); emit queryEnded(true, QString(), QString()); } else { _error_string = tr("Could not open URL '%1'.").arg(encodeUrl(_targetQ)); emit queryEnded(false, QString(), QString()); } return; } _timing = QDateTime::currentDateTime(); if (_action == "htm2txt_query") emit statusMessage(tr("Importing: %1.").arg(_targetQ)); else emit statusMessage(tr("Query: %1.").arg(_targetQ)); _networkP->getFile(_targetQ, _networkquery_tmp_fn1, network::Copy, this, SLOT(submitQuery2(bool)), !_settingsP->value("cb2Bib/KeepTmpNQFiles").toBool()); } void networkQuery::submitQuery2(bool succeeded) { // Submission, second part: check query replay and PDF existence if (!succeeded) { _error_string = _networkP->errorString(); emit statusMessage(tr("Query failed with %1.").arg(_error_string)); QTimer::singleShot(10, this, SLOT(submitQuery1())); return; } QString lines(c2bUtils::fileToString(_networkquery_tmp_fn1, !_settingsP->value("cb2Bib/KeepTmpNQFiles").toBool())); // For the single query cases with no htm2txt_query and referenceurl_prefix use // non empty capture_from_query to check for result availability QString captured; if (!_captionQ.isEmpty()) { QRegExp rx(_captionQ); rx.setMinimal(true); if (!rx.isValid()) c2bUtils::warn(tr("Warning: RegExp '%1' is not valid").arg(_captionQ)); const int ncap(rx.indexIn(lines)); if (ncap == -1) { QTimer::singleShot(10, this, SLOT(submitQuery1())); return; } captured = fromHtmlString(rx.cap(1)); c2bUtils::debug(tr("CAPTURED[%1]").arg(captured)); } if (_action == "htm2txt_query") { _error_string = tr("Importing query URL."); emit queryEnded(true, QString(), fromHtmlString(lines, true)); return; } if (_action == "merge_all_metadata") _raw_metadata = _raw_reference + c2bUtils::metadatasection.arg(lines.trimmed()); else if (_action == "merge_referenceurl_metadata") _raw_metadata = _raw_reference; else _raw_metadata = c2bUtils::metadatasection.arg(lines.trimmed()); if (_referenceurl_prefix.isEmpty() && _pdfurl_prefix.isEmpty()) { _error_string = tr("Importing query URL."); emit queryEnded(true, QString(), _raw_metadata); return; } if (captured.isEmpty()) { QTimer::singleShot(10, this, SLOT(submitQuery1())); return; } if (_referenceurl_prefix.isEmpty()) _targetBib.clear(); else _targetBib = _referenceurl_prefix + captured + _referenceurl_sufix; if (_check_document && !_pdfurl_prefix.isEmpty()) { if (_pdfurl_is_captured) _targetPDF = _pdfurl_prefix + _pdfurl_sufix; else _targetPDF = _pdfurl_prefix + captured + _pdfurl_sufix; emit statusMessage(tr("Checking: %1").arg(_targetPDF)); _networkP->headFile(_targetPDF, this, SLOT(submitQuery3(bool))); } else submitQuery3(false); } void networkQuery::submitQuery3(bool succeeded) { // Submission, third part: extracting reference location if (!succeeded || !_networkP->mimetypeString().contains(QRegExp("\\b(chm|djvu|pdf|ps)\\b"))) _targetPDF.clear(); else _targetPDF = _networkP->sourceFilename(); if (_referenceurl_prefix.isEmpty()) { emit queryEnded(true, _targetPDF, _raw_metadata); return; } c2bUtils::debug(tr("POST2[%1]").arg(_targetBib)); c2bUtils::debug(tr("POST3[%1]").arg(_targetPDF)); if (_action == "browse_referenceurl") { if (openFile(encodeUrl(_targetBib))) { _error_string = tr("Browsing reference."); emit queryEnded(true, QString(), QString()); } else { _error_string = tr("Could not open URL '%1'.").arg(encodeUrl(_targetBib)); emit queryEnded(false, QString(), QString()); } return; } if (_action == "htm2txt_referenceurl") emit statusMessage(tr("Importing: %1.").arg(_targetBib)); else emit statusMessage(tr("Retrieving: %1.").arg(_targetBib)); _networkP->getFile(_targetBib, _networkquery_tmp_fn2, network::Copy, this, SLOT(queryDone(bool)), !_settingsP->value("cb2Bib/KeepTmpNQFiles").toBool()); } void networkQuery::queryDone(bool succeeded) { // Submission Done if (!succeeded) { QTimer::singleShot(10, this, SLOT(submitQuery1())); return; } QString lines(c2bUtils::fileToString(_networkquery_tmp_fn2, !_settingsP->value("cb2Bib/KeepTmpNQFiles").toBool())); if (_action == "htm2txt_referenceurl") { _error_string = tr("Importing reference URL."); emit queryEnded(true, _targetPDF, fromHtmlString(lines, true)); return; } if (_action == "merge_all_metadata" || _action == "merge_referenceurl_metadata") _raw_metadata += c2bUtils::metadatasection.arg(lines.trimmed()); else _raw_metadata = c2bUtils::metadatasection.arg(lines.trimmed()); emit queryEnded(true, _targetPDF, _raw_metadata); } bool networkQuery::setQueryParameters() { if (!checkQueryFile(_settingsP->fileName("cb2Bib/NetworkFile"))) return false; QFile file(_settingsP->fileName("cb2Bib/NetworkFile")); file.open(QIODevice::ReadOnly | QIODevice::Text); QTextStream stream(&file); stream.setCodec("UTF-8"); stream.setAutoDetectUnicode(true); QRegExp Journal("journal=" + _Qjournal + "\\|"); QRegExp AnyJournal("journal=\\s*$"); uint readQueryParams(0); _is_end_of_file = false; QString line; while (!stream.atEnd()) { line = stream.readLine(); if (line.startsWith("%c2b_stop_parsing")) break; // Skip comments and blanks if (!(line.isEmpty() || line.contains(QRegExp("^#")))) { if (line.contains(Journal)) { const QStringList lc(line.split('|')); if (lc.count() > 1) _QjournalCode = lc.at(1); else _QjournalCode.clear(); } else if (line.contains(AnyJournal)) { _QjournalCode = _Qjournal; _QjournalCode.replace(" & ", " and "); // Avoid sending '&' to confuse URLs _QjournalCode.replace(QRegExp("\\W"), " "); _QjournalCode = _QjournalCode.simplified(); _QjournalCode.replace(" ", "+"); } // Get appropiate parameters for Journal or AnyJournal if (line.contains(Journal) || line.contains(AnyJournal)) { // Skip if already performed if (!_query_parameter_count.contains(++readQueryParams)) { while (line.contains(QRegExp("^journal="))) line = stream.readLine(); _targetQ = line.remove(QRegExp("^query=")); line = stream.readLine(); _captionQ = line.remove(QRegExp("^capture_from_query=")); line = stream.readLine(); _referenceurl_prefix = line.remove(QRegExp("^referenceurl_prefix=")); line = stream.readLine(); _referenceurl_sufix = line.remove(QRegExp("^referenceurl_sufix=")); line = stream.readLine(); _pdfurl_prefix = line.remove(QRegExp("^pdfurl_prefix=")); line = stream.readLine(); _pdfurl_sufix = line.remove(QRegExp("^pdfurl_sufix=")); line = stream.readLine(); _action = line.remove(QRegExp("^action=")); // Setting Query Parameters updateQueryPlaceholders(); // Finally, check for unresolved cb2Bib tags if (areQueryParametersValid()) { _query_parameter_count.append(readQueryParams); return true; } } } } } file.close(); _is_end_of_file = true; return (!_query_parameter_count.isEmpty()); } void networkQuery::updateQueryPlaceholders() { const QString pdfurl_prefix(_pdfurl_prefix); if (!_Qtitle.isEmpty()) { _targetQ.replace("<>", _Qtitle); _captionQ.replace("<<title>>", _Qtitle); _referenceurl_prefix.replace("<<title>>", _Qtitle); _referenceurl_sufix.replace("<<title>>", _Qtitle); _pdfurl_prefix.replace("<<title>>", _Qtitle); _pdfurl_sufix.replace("<<title>>", _Qtitle); } if (!_QjournalCode.isEmpty()) { _targetQ.replace("<<journal>>", _QjournalCode); _captionQ.replace("<<journal>>", _QjournalCode); _referenceurl_prefix.replace("<<journal>>", _QjournalCode); _referenceurl_sufix.replace("<<journal>>", _QjournalCode); _pdfurl_prefix.replace("<<journal>>", _QjournalCode); _pdfurl_sufix.replace("<<journal>>", _QjournalCode); } if (!_Qpage.isEmpty()) { _targetQ.replace("<<pages>>", _Qpage); _captionQ.replace("<<pages>>", _Qpage); _referenceurl_prefix.replace("<<pages>>", _Qpage); _referenceurl_sufix.replace("<<pages>>", _Qpage); _pdfurl_prefix.replace("<<pages>>", _Qpage); _pdfurl_sufix.replace("<<pages>>", _Qpage); } if (!_Qvolume.isEmpty()) { _targetQ.replace("<<volume>>", _Qvolume); _captionQ.replace("<<volume>>", _Qvolume); _referenceurl_prefix.replace("<<volume>>", _Qvolume); _referenceurl_sufix.replace("<<volume>>", _Qvolume); _pdfurl_prefix.replace("<<volume>>", _Qvolume); _pdfurl_sufix.replace("<<volume>>", _Qvolume); } if (!_Qdoi.isEmpty()) { _targetQ.replace("<<doi>>", _Qdoi); _captionQ.replace("<<doi>>", _Qdoi); _referenceurl_prefix.replace("<<doi>>", _Qdoi); _referenceurl_sufix.replace("<<doi>>", _Qdoi); _pdfurl_prefix.replace("<<doi>>", _Qdoi); _pdfurl_sufix.replace("<<doi>>", _Qdoi); } if (!_Qexcerpt.isEmpty()) { _targetQ.replace("<<excerpt>>", _Qexcerpt); _captionQ.replace("<<excerpt>>", _Qexcerpt); _referenceurl_prefix.replace("<<excerpt>>", _Qexcerpt); _referenceurl_sufix.replace("<<excerpt>>", _Qexcerpt); _pdfurl_prefix.replace("<<excerpt>>", _Qexcerpt); _pdfurl_sufix.replace("<<excerpt>>", _Qexcerpt); } if (!_Qeprint.isEmpty()) { _targetQ.replace("<<eprint>>", _Qeprint); _captionQ.replace("<<eprint>>", QRegExp::escape(_Qeprint)); _referenceurl_prefix.replace("<<eprint>>", _Qeprint); _referenceurl_sufix.replace("<<eprint>>", _Qeprint); _pdfurl_prefix.replace("<<eprint>>", _Qeprint); _pdfurl_sufix.replace("<<eprint>>", _Qeprint); } _pdfurl_is_captured = (pdfurl_prefix != _pdfurl_prefix); } bool networkQuery::areQueryParametersValid() { if (!_action.isEmpty()) { if (_action == "browse_query" || _action == "browse_referenceurl") { if (!_settingsP->value("networkQuery/isSupervised").toBool()) return false; } else if (!(_action == "htm2txt_query" || _action == "htm2txt_referenceurl" || _action == "merge_all_metadata" || _action == "merge_referenceurl_metadata")) return false; } const QString allParams(_targetQ + _captionQ + _referenceurl_prefix + _referenceurl_sufix + _pdfurl_prefix + _pdfurl_sufix); return !( allParams.contains(QRegExp("(?:<<title>>|<<journal>>|<<pages>>|<<volume>>|<<doi>>|<<excerpt>>|<<eprint>>)"))); } const QString networkQuery::encodeUrl(const QString& url) const { // Removes <<post>> tag if present and encodes URL to percent encoding QString encoded_url(url); encoded_url.remove(QRegExp("^<<post>>")); encoded_url = QUrl::toPercentEncoding(encoded_url, "+:/?=&\\"); return encoded_url; } bool networkQuery::checkQueryFile(const QString& fn) const { if (fn.isEmpty()) { c2bUtils::warn(tr("No network query file especified")); return false; } QFileInfo fi(fn); if (!fi.exists() || !fi.isReadable()) { c2bUtils::warn(tr("Could not open network query file %1 for reading").arg(fn)); return false; } return true; } ��������������������������������������������������������cb2bib-2.0.1/src/c2b/PaxHeaders.5700/collectionAnalyzer.cpp�����������������������������������������0000644�0000000�0000000�00000000130�14011522520�020075� x����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������29 mtime=1613145424.60262034 30 atime=1613145424.834620334 29 ctime=1613145424.60262034 ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������cb2bib-2.0.1/src/c2b/collectionAnalyzer.cpp���������������������������������������������������������0000644�0001750�0000144�00000022107�14011522520�021500� 0����������������������������������������������������������������������������������������������������ustar�00constans������������������������users���������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*************************************************************************** * Copyright (C) 2004-2021 by Pere Constans * constans@molspaces.com * cb2Bib version 2.0.1. Licensed under the GNU GPL version 3. * See the LICENSE file that comes with this distribution. ***************************************************************************/ #include "collectionAnalyzer.h" #include "settings.h" #include <QDataStream> #include <QVector> #include <cmath> namespace { template <typename T> class lengthsorting { public: explicit lengthsorting(const T& data) : _data(data) {} inline bool operator()(const int i, const int j) { const int ni(_data[i].length()); const int nj(_data[j].length()); if (ni == nj) return _data[i] < _data[j]; else return ni < nj; } private: const T& _data; }; // Template double_sort was adapted from qSortHelper by Pere Constans. // qSortHelper is copyrighted by // (C) 2011 Nokia Corporation and/or its subsidiary(-ies), // and released under GLP/LGPL license. template <typename T1, typename T2> void double_sort(int start, int end, T1* v1, T2* v2) { top: int span = end - start; if (span < 2) return; --end; int low = start; int high = end - 1; int pivot = start + span / 2; if ((*v1)[end] > (*v1)[start]) { std::swap((*v1)[end], (*v1)[start]); std::swap((*v2)[end], (*v2)[start]); } if (span == 2) return; if ((*v1)[pivot] > (*v1)[start]) { std::swap((*v1)[pivot], (*v1)[start]); std::swap((*v2)[pivot], (*v2)[start]); } if ((*v1)[end] > (*v1)[pivot]) { std::swap((*v1)[end], (*v1)[pivot]); std::swap((*v2)[end], (*v2)[pivot]); } if (span == 3) return; std::swap((*v1)[pivot], (*v1)[end]); std::swap((*v2)[pivot], (*v2)[end]); while (low < high) { while (low < high && (*v1)[low] > (*v1)[end]) ++low; while (high > low && (*v1)[end] > (*v1)[high]) --high; if (low < high) { std::swap((*v1)[low], (*v1)[high]); std::swap((*v2)[low], (*v2)[high]); ++low; --high; } else break; } if ((*v1)[low] > (*v1)[end]) ++low; std::swap((*v1)[end], (*v1)[low]); std::swap((*v2)[end], (*v2)[low]); double_sort(start, low, v1, v2); start = low + 1; ++end; goto top; } } // namespace collectionAnalyzer::collectionAnalyzer() : _ndocuments(0), _nsentences(0), _nsimilar(0), _settingsP(settings::instance()) {} void collectionAnalyzer::reload() { _ndocuments = 0; _nsentences = 0; _nsimilar = 0; _document_keyword.clear(); _keyword_document_fn.clear(); _similar_document_fn.clear(); const QString cache_dir(_settingsP->fileName("cb2Bib/CacheDirectory")); _documentslf_fn = QDir::cleanPath(cache_dir + "/documents.lc2b"); QFile documentslf(_documentslf_fn); if (documentslf.open(QIODevice::ReadOnly)) { QDataStream stream(&documentslf); stream >> _ndocuments; _documents.resize(_ndocuments); for (int i = 0; i < _ndocuments; ++i) stream >> _documents[i]; documentslf.close(); } _similar.resize(_ndocuments); _similarity.resize(_ndocuments); _sentenceslf_fn = QDir::cleanPath(cache_dir + "/sentences.lc2b"); QFile sentenceslf(_sentenceslf_fn); if (sentenceslf.open(QIODevice::ReadOnly)) { QDataStream stream(&sentenceslf); stream >> _nsentences; _sentences.resize(_nsentences); for (int i = 0; i < _nsentences; ++i) stream >> _sentences[i]; sentenceslf.close(); } _documentsif_fn = QDir::cleanPath(cache_dir + "/documents.ic2b"); QFile documentsif(_documentsif_fn); if (documentsif.open(QIODevice::ReadOnly)) { QDataStream stream(&documentsif); _document_norms.resize(_ndocuments); int ns; int ss; for (int d = 0; d < _ndocuments; ++d) { stream >> ns; _document_norms[d] = ns; for (int s = 0; s < ns; ++s) stream >> ss; } documentsif.close(); } _sentencesif_fn = QDir::cleanPath(cache_dir + "/sentences.ic2b"); } void collectionAnalyzer::setDocumentKeywords(const QString& documentfn) { if (documentfn == _keyword_document_fn) return; _keyword_document_fn = documentfn; _document_keyword_ids.clear(); QVector<int> dsentences; grepDocuments(documentfn, &dsentences); const int ndsentences(dsentences.size()); if (ndsentences == 0) return; lengthsorting<QVarLengthArray<QString>> ls(_sentences); std::sort(dsentences.begin(), dsentences.end(), ls); for (int i = 0; i < ndsentences; ++i) { const QString& si(_sentences[dsentences.at(i)]); bool redundant(false); for (int j = i + 1; j < ndsentences; ++j) if (_sentences[dsentences.at(j)].contains(si)) { redundant = true; break; } if (!redundant) _document_keyword_ids.append(dsentences.at(i)); } std::sort(_document_keyword_ids.begin(), _document_keyword_ids.end()); } void collectionAnalyzer::setKeywordDocuments(const QString& keyword) { if (keyword == _document_keyword) return; _document_keyword = keyword; grepSentences(keyword, &_sdocuments); } void collectionAnalyzer::setSimilarDocuments(const QString& documentfn) { if (documentfn == _similar_document_fn) return; _similar_document_fn = documentfn; _nsimilar = 0; QVector<int> dsentences; grepDocuments(documentfn, &dsentences); const int ndsentences(dsentences.size()); if (ndsentences == 0) return; QVarLengthArray<int> overlaps(_ndocuments); for (int i = 0; i < _ndocuments; ++i) overlaps[i] = 0; QFile sentencesif(_sentencesif_fn); if (sentencesif.open(QIODevice::ReadOnly)) { QDataStream stream(&sentencesif); int nd; int dd; int s0(0); for (int i = 0; i < ndsentences; ++i) { const int sentenceid(dsentences[i]); for (int s = s0; s < sentenceid; ++s) { stream >> nd; for (int d = 0; d < nd; ++d) stream >> dd; } stream >> nd; for (int d = 0; d < nd; ++d) { stream >> dd; overlaps[dd] += 1; } s0 = sentenceid + 1; } sentencesif.close(); } const int documentid(_document_id(documentfn)); for (int i = 0; i < _ndocuments; ++i) { const int o(overlaps[i]); if (o == 0) continue; const double s(double(o) / sqrt(double(_document_norms[documentid] * _document_norms[i]))); if (s < 0.051) continue; _similarity[_nsimilar] = s; _similar[_nsimilar++] = i; } double_sort(0, _nsimilar, &_similarity, &_similar); } void collectionAnalyzer::skipSimilarDocument(const int i) { --_nsimilar; for (int j = i; j < _nsimilar; ++j) _similarity[j] = _similarity[j + 1]; for (int j = i; j < _nsimilar; ++j) _similarity[j] = _similarity[j + 1]; } void collectionAnalyzer::grepDocuments(const QString& documentfn, QVector<int>* dsentences) const { dsentences->clear(); const int documentid(_document_id(documentfn)); if (documentid == -1) return; QFile documentsif(_documentsif_fn); if (documentsif.open(QIODevice::ReadOnly)) { QDataStream stream(&documentsif); int ns; int ss; for (int d = 0; d < documentid; ++d) { stream >> ns; for (int s = 0; s < ns; ++s) stream >> ss; } stream >> ns; dsentences->resize(ns); for (int s = 0; s < ns; ++s) stream >> (*dsentences)[s]; documentsif.close(); } } void collectionAnalyzer::grepSentences(const QString& keyword, QVarLengthArray<int>* sdocuments) const { sdocuments->clear(); const int sentenceid(_sentence_id(keyword)); if (sentenceid == -1) return; QFile sentencesif(_sentencesif_fn); if (sentencesif.open(QIODevice::ReadOnly)) { QDataStream stream(&sentencesif); int nd; int dd; for (int s = 0; s < sentenceid; ++s) { stream >> nd; for (int d = 0; d < nd; ++d) stream >> dd; } stream >> nd; sdocuments->resize(nd); for (int d = 0; d < nd; ++d) stream >> (*sdocuments)[d]; sentencesif.close(); } } int collectionAnalyzer::_document_id(const QString& documentfn) const { for (int i = 0; i < _ndocuments; ++i) if (_documents[i] == documentfn) return i; return -1; } int collectionAnalyzer::_sentence_id(const QString& keyword) const { for (int i = 0; i < _nsentences; ++i) if (_sentences[i] == keyword) return i; return -1; } ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������cb2bib-2.0.1/src/c2b/PaxHeaders.5700/bibSearcher.h��������������������������������������������������0000644�0000000�0000000�00000000132�14011522520�016114� x����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������30 mtime=1613145424.702620338 30 atime=1613145424.834620334 30 ctime=1613145424.702620338 ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������cb2bib-2.0.1/src/c2b/bibSearcher.h������������������������������������������������������������������0000644�0001750�0000144�00000014751�14011522520�017523� 0����������������������������������������������������������������������������������������������������ustar�00constans������������������������users���������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*************************************************************************** * Copyright (C) 2004-2021 by Pere Constans * constans@molspaces.com * cb2Bib version 2.0.1. Licensed under the GNU GPL version 3. * See the LICENSE file that comes with this distribution. ***************************************************************************/ #ifndef BIBSEARCHER_H #define BIBSEARCHER_H #include "documentCache.h" #include "searchPattern.h" #include <QObject> #include <QStringList> class bibParser; class bibReference; class bibSearcher : public QObject { Q_OBJECT public: explicit bibSearcher(bibParser* bp, QObject* parento = 0); bibSearcher(bibParser* bp, const QString& bib_dir, QObject* parento = 0); inline ~bibSearcher() {} static QString searchDocumentKeyword(const QString& bibtexfn, const QString& documentfn, const QString& keyword); void addPattern(bool Not, bool caseSensitive, const QString& patternType, const QString& scope, const QChar& yearScope, const QString& pattern); void clear(); void exec(); inline void setBoolean(bool AND) { _boolean_and = AND; } inline void setSearchScope(const QString& file, const QString& dir, bool all, bool documents) { _bibtex_file = file; _bibtex_dir = dir; _all_bibtex_files = all; _include_documents = documents; } inline void setSimplifySource(bool simplify) { _simplify_source = simplify; } inline int errorsCount() const { return _error_counter; } inline int hitsCount() const { return _result_references.count(); } inline QString hitsString() const { return _result_string; } inline QString hitHtmlDatum(const int index) const { return index < _result_html_data.count() ? _result_html_data.at(index) : QString(); } inline QString hitHtmlAbstract(const int index) const { return index < _result_html_abstracts.count() ? _result_html_abstracts.at(index) : QString(); } inline int patternsCount() const { return _patterns.count(); } inline int referencesCount() const { return _reference_counter; } inline QString logString() const { return _log_string; } inline bool isSearchSimilar() const { return _do_search_similar; } public slots: void abort(); private: bibSearcher(); QString excerpts(const QString& contents); QString highlight(const QString& abstract); QString location(const QString& fn, const bibReference& ref) const; void search(const QString& bib_file); void searchReference(const QString& bib_file, const bibReference& ref); void searchSimilarReferences(const QString& bib_file, const bibReference& ref); void setTitleRank(const QString& title); template <typename T1, typename T2, typename T3, typename T4> void quadrupleSortDescending(int start, int end, T1* v1, T2* v2, T3* v3, T4* v4) { // Template quadrupleSortDescending was adapted from qSortHelper by Pere Constans. // qSortHelper is copyrighted by // (C) 2011 Nokia Corporation and/or its subsidiary(-ies), // and released under GLP/LGPL license. top: int span = end - start; if (span < 2) return; --end; int low = start; int high = end - 1; int pivot = start + span / 2; if (v1->at(end) > v1->at(start)) { std::swap((*v1)[end], (*v1)[start]); std::swap((*v2)[end], (*v2)[start]); std::swap((*v3)[end], (*v3)[start]); std::swap((*v4)[end], (*v4)[start]); } if (span == 2) return; if (v1->at(pivot) > v1->at(start)) { std::swap((*v1)[pivot], (*v1)[start]); std::swap((*v2)[pivot], (*v2)[start]); std::swap((*v3)[pivot], (*v3)[start]); std::swap((*v4)[pivot], (*v4)[start]); } if (v1->at(end) > v1->at(pivot)) { std::swap((*v1)[end], (*v1)[pivot]); std::swap((*v2)[end], (*v2)[pivot]); std::swap((*v3)[end], (*v3)[pivot]); std::swap((*v4)[end], (*v4)[pivot]); } if (span == 3) return; std::swap((*v1)[pivot], (*v1)[end]); std::swap((*v2)[pivot], (*v2)[end]); std::swap((*v3)[pivot], (*v3)[end]); std::swap((*v4)[pivot], (*v4)[end]); while (low < high) { while (low < high && v1->at(low) > v1->at(end)) ++low; while (high > low && v1->at(end) > v1->at(high)) --high; if (low < high) { std::swap((*v1)[low], (*v1)[high]); std::swap((*v2)[low], (*v2)[high]); std::swap((*v3)[low], (*v3)[high]); std::swap((*v4)[low], (*v4)[high]); ++low; --high; } else break; } if (v1->at(low) > v1->at(end)) ++low; std::swap((*v1)[end], (*v1)[low]); std::swap((*v2)[end], (*v2)[low]); std::swap((*v3)[end], (*v3)[low]); std::swap((*v4)[end], (*v4)[low]); quadrupleSortDescending(start, low, v1, v2, v3, v4); start = low + 1; ++end; goto top; } template <typename T1, typename T2, typename T3, typename T4> void quadrupleSortDescending(T1* v1, T2* v2, T3* v3, T4* v4) { const int n(v1->size()); if (n != v2->size() && n != v3->size() && n != v4->size()) c2bUtils::warn(tr("Invalid array dimensions at quadrupleSortDescending")); else quadrupleSortDescending(0, n, v1, v2, v3, v4); } QList<double> _result_scores; QString _result_string; QStringList _result_html_abstracts; QStringList _result_html_data; QStringList _result_references; QList<searchPattern> _patterns; QString _bibtex_dir; QString _bibtex_file; QString _do_search_similar_citeid; QString _log_string; QStringList _scopes; bibParser* _bpP; bool _aborted; bool _all_bibtex_files; bool _boolean_and; bool _include_documents; bool _simplify_source; documentCache _documents; double _reference_score; int _bibtex_counter; int _document_counter; int _error_counter; int _reference_counter; int _reference_match_counter; const bool _do_rank_results; const bool _do_search_similar; }; #endif �����������������������cb2bib-2.0.1/src/c2b/PaxHeaders.5700/idMaker.cpp����������������������������������������������������0000644�0000000�0000000�00000000130�14011522520�015610� x����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������29 mtime=1613145424.63062034 30 atime=1613145424.834620334 29 ctime=1613145424.63462034 ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������cb2bib-2.0.1/src/c2b/idMaker.cpp��������������������������������������������������������������������0000644�0001750�0000144�00000024050�14011522520�017212� 0����������������������������������������������������������������������������������������������������ustar�00constans������������������������users���������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*************************************************************************** * Copyright (C) 2004-2021 by Pere Constans * constans@molspaces.com * cb2Bib version 2.0.1. Licensed under the GNU GPL version 3. * See the LICENSE file that comes with this distribution. * * Improvements and modifications: * July 2009 - Added <<author_all_abbreviated>>, (C) 2009 by Dayu Huang ***************************************************************************/ #include "idMaker.h" #include "settings.h" idMaker::idMaker(const QString& patternKey, QObject* parento) : QObject(parento), _pattern_key(patternKey) { loadSettings(); connect(settings::instance(), SIGNAL(newSettings()), this, SLOT(loadSettings())); } /** \page predefinedplaceholders Predefined Placeholders \section idplaceholders Cite and Document ID Placeholders - <tt><<author_all_abbreviated>></tt> Takes first three letters of the last word of all authors's last name in cite, and converts to lowercase. - <tt><<author_all_initials>></tt> Takes capitalized initials of all authors in cite. - <tt><<author_first>></tt> Takes first author last name. - <tt><<author_first_lowercase>></tt> Takes first author last name in lowercase. - <tt><<citeid>></tt> This placeholder is meant to be used <b>alone, and only for document IDs</b>. It takes the pattern defined for the cite ID. If the cite ID is modified manually, the document ID is synchronized automatically. - <tt><<journal_initials>></tt> Takes capitalized initials of journal name. - <tt><<pages_first>></tt> First page. - <tt><<ppages_first>></tt> First page, written as, e. g., 'p125'. - <tt><<title>></tt> Title. To truncate titles exceeding a maximum length <tt>l</tt> use <tt><<title_l>></tt>, where <tt>l</tt> stands for an integer value. - <tt><<title_underscored>></tt> Title with blanks set to underscores. To truncate title to <tt>l</tt> characters use <tt><<title_underscored_l>></tt>. - <tt><<title_first_word>></tt> First word in title, in lowercase. - <tt><<volume>></tt> Volume number. - <tt><<year_abbreviated>></tt> Last two digits from year. - <tt><<year_full>></tt> All digits from year. <b>Note:</b> If <tt>author</tt> is empty, <tt>editor</tt> will be considered instead. On conference proceedings or monographs this situation is usual. Similarly, if <tt>title</tt> is empty, <tt>booktitle</tt> is considered. <b>Note:</b> Only one placeholder of a given field, e. g. <tt><<author_first>></tt> or <tt><<author_all_initials>></tt>, should be used to compose the ID patterns. cb2Bib only performs one substitution per field placeholder. <b>Note:</b> cb2Bib performs a series of string manipulations, such as stripping diacritics and ligatures, aimed to provide ID values suitable for BibTeX keys and platform independent filenames. Currently only ASCII characters are considered. \section citeplaceholders Cite Command Placeholders - <tt><<citeid>></tt> The <tt>citeid</tt> placeholder replicates the pattern for each citation in the selected citation list. For example, the pattern <tt>\\citenum{<<citeid>>}</tt> expands to <tt>\\citenum{cid1} \\citenum{cid2} ... </tt> - <tt><<prefix|citeids|separator>></tt> The <tt>citeids</tt> placeholder replaces the selected citation list by prepending <tt>prefix</tt> and appending <tt>separator</tt> within the pattern. For example, the markdown pattern <tt>[<<\@|citeids|;>>]</tt> expands to <tt>[\@cid1; \@cid2; ...]</tt>, and the LaTeX pattern <tt>\\citeauthor{<<|citeids|,>>}</tt> expands to <tt>\\citeauthor{cid1, cid2, ...}</tt>. <b>Note:</b> For additional information on cite commands see \htmlonly <a href="https://en.wikibooks.org/wiki/LaTeX/Bibliography_Management" target="_blank">LaTeX Bibliography Management</a> \endhtmlonly and \htmlonly <a href="https://pandoc.org/MANUAL.html#citations" target="_blank">Pandoc User's Guide</a>. \endhtmlonly */ QString idMaker::makeID(const bibReference& reference) { if (_id_pattern.isEmpty()) return QString(); if (_id_pattern.contains(QLatin1String("<<citeid>>"))) return reference.citeidName; // Initialize fields _author = reference.anyAuthor(); _journal = reference.value(QLatin1String("journal")); _pages = reference.value(QLatin1String("pages")); _title = reference.anyTitle(); _volume = reference.value(QLatin1String("volume")); _year = reference.value(QLatin1String("year")); // Set cite ID QString id(_id_pattern); if (_id_pattern.contains(QLatin1String("<<author_first>>"))) make_author_first(&id); else if (_id_pattern.contains(QLatin1String("<<author_first_lowercase>>"))) make_author_first_lowercase(&id); else if (_id_pattern.contains(QLatin1String("<<author_all_abbreviated>>"))) make_author_all_abbreviated(&id); else if (_id_pattern.contains(QLatin1String("<<author_all_initials>>"))) make_author_all_initials(&id); if (_id_pattern.contains(QLatin1String("<<journal_initials>>"))) make_journal_initials(&id); if (_id_pattern.contains(QLatin1String("<<pages_first>>"))) make_pages_first(&id); else if (_id_pattern.contains(QLatin1String("<<ppages_first>>"))) make_ppages_first(&id); if (!_title_pattern.isEmpty()) if (_id_pattern.contains(_title_pattern)) make_title(&id); if (_id_pattern.contains(QLatin1String("<<title_first_word>>"))) make_title_first_word(&id); if (_id_pattern.contains(QLatin1String("<<volume>>"))) make_volume(&id); if (_id_pattern.contains(QLatin1String("<<year_abbreviated>>"))) make_year_abbreviated(&id); else if (_id_pattern.contains(QLatin1String("<<year_full>>"))) make_year_full(&id); return id; } void idMaker::make_author_first(QString* id) { QRegExp rx("([-'\\s\\w]+)(?:\\sand|$)"); rx.setMinimal(true); rx.indexIn(_author); _author = rx.cap(1); if (_author.contains(c2bUtils::nonAsciiLetter)) _author = c2bUtils::toAscii(_author, c2bUtils::Cleanup); id->replace(QLatin1String("<<author_first>>"), _author); } void idMaker::make_author_first_lowercase(QString* id) { QRegExp rx("([-'\\s\\w]+)(?:\\sand|$)"); rx.setMinimal(true); rx.indexIn(_author); _author = rx.cap(1).toLower(); if (_author.contains(c2bUtils::nonAsciiLetter)) _author = c2bUtils::toAscii(_author, c2bUtils::Cleanup); id->replace(QLatin1String("<<author_first_lowercase>>"), _author); } void idMaker::make_author_all_abbreviated(QString* id) { // If there is less than 3 letters in their last name's last word, // then use all the letters in the last name's last word QString temp_author; QRegExp rx("([-'\\w]{1,3})(?:[-'\\w]*)(?:\\sand|$)"); rx.setMinimal(true); rx.indexIn(_author); int pos(0); while ((pos = rx.indexIn(_author, pos)) != -1) { temp_author += rx.cap(1); pos += rx.matchedLength(); } _author = temp_author.toLower(); if (_author.contains(c2bUtils::nonAsciiLetter)) _author = c2bUtils::toAscii(_author, c2bUtils::Cleanup); id->replace(QLatin1String("<<author_all_abbreviated>>"), _author); } void idMaker::make_author_all_initials(QString* id) { _author.remove(QRegExp("\\b\\w\\b")); _author.remove(" and "); if (_author.contains(c2bUtils::nonAsciiLetter)) _author = c2bUtils::toAscii(_author, c2bUtils::Cleanup); _author.remove(QRegExp("[a-z]")); id->replace(QLatin1String("<<author_all_initials>>"), _author); } void idMaker::make_journal_initials(QString* id) { _journal.remove(QRegExp("[^A-Z]")); id->replace(QLatin1String("<<journal_initials>>"), _journal); } void idMaker::make_pages_first(QString* id) { _pages = c2bUtils::firstPage(_pages); id->replace(QLatin1String("<<pages_first>>"), _pages); } void idMaker::make_ppages_first(QString* id) { _pages = c2bUtils::firstPage(_pages); if (!_pages.isEmpty()) if (_pages.at(0).isDigit()) _pages = 'p' + _pages; id->replace(QLatin1String("<<ppages_first>>"), _pages); } void idMaker::make_title(QString* id) { if (_title.contains(c2bUtils::nonAsciiLetter)) _title = c2bUtils::toAscii(_title, c2bUtils::FromBibTeX); _title = _title.left(_title_max_length).trimmed(); // Avoid possible trailing blank if (_is_title_underscored) _title.replace(QLatin1Char(' '), QLatin1Char('_')); id->replace(_title_pattern, _title); } void idMaker::make_title_first_word(QString* id) { if (_title.contains(c2bUtils::nonAsciiLetter)) _title = c2bUtils::toAscii(_title, c2bUtils::FromBibTeX); const QStringList ws(_title.toLower().split(c2bUtils::nonAsciiLetter, QString::SkipEmptyParts)); _title.resize(0); for (int w = 0; w < ws.count(); ++w) if (ws.at(w).length() > 2 && ws.at(w) != QLatin1String("are") && ws.at(w) != QLatin1String("the")) { _title = ws.at(w); break; } id->replace(QLatin1String("<<title_first_word>>"), _title); } void idMaker::make_volume(QString* id) { _volume.remove(' '); id->replace(QLatin1String("<<volume>>"), _volume); } void idMaker::make_year_abbreviated(QString* id) { _year = _year.right(2); id->replace(QLatin1String("<<year_abbreviated>>"), _year); } void idMaker::make_year_full(QString* id) { id->replace(QLatin1String("<<year_full>>"), _year); } void idMaker::loadSettings() { _id_pattern = settings::instance()->value(_pattern_key).toString(); QRegExp title_pattern("(<<title(?:_underscored)?(?:_\\d+)?>>)"); if (title_pattern.indexIn(_id_pattern) > -1) { _title_pattern = title_pattern.cap(1); _title_pattern.remove(QRegExp("\\D")); _title_max_length = _title_pattern.toInt(); if (_title_max_length == 0) _title_max_length = -1; _title_pattern = title_pattern.cap(1); _is_title_underscored = _title_pattern.contains(QRegExp("_underscored(?:_\\d+)?>>")); } else _title_pattern.clear(); } ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������cb2bib-2.0.1/src/c2b/PaxHeaders.5700/texToHtml.cpp��������������������������������������������������0000644�0000000�0000000�00000000132�14011522520�016166� x����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������30 mtime=1613145424.666620339 30 atime=1613145424.834620334 30 ctime=1613145424.666620339 ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������cb2bib-2.0.1/src/c2b/texToHtml.cpp������������������������������������������������������������������0000644�0001750�0000144�00000033262�14011522520�017573� 0����������������������������������������������������������������������������������������������������ustar�00constans������������������������users���������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*************************************************************************** * Copyright (C) 2004-2021 by Pere Constans * constans@molspaces.com * cb2Bib version 2.0.1. Licensed under the GNU GPL version 3. * See the LICENSE file that comes with this distribution. ***************************************************************************/ #include "texToHtml.h" #include "cb2bib_parameters.h" #include "settings.h" #include <QUrl> texToHtml::texToHtml() : texParser() { _macro_arguments_rx = QRegExp("\\}\\s*\\[\\s*(\\d+)\\s*\\]\\s*\\{"); _named_extern_url_rx = QRegExp("_((?:file|http|https|ftp)://(?:[^\\s\\n\\r\\[]+))\\[([^\\]]*)\\]"); _named_url_rx = QRegExp("\\b((?:file|http|https|ftp)://(?:[^\\s\\n\\r\\[]+))\\[([^\\]]*)\\]"); _extern_url_rx = QRegExp("_((?:file|http|https|ftp)(?!.+\">)://(?:[^\\s\\n\\r\\[]+))(\\.[\\s\\n\\r]){0,1}"); _url_rx = QRegExp("\\b((?:file|http|https|ftp)(?!.+\">)://(?:[^\\s\\n\\r\\[]+))(\\.[\\s\\n\\r]){0,1}"); _close_subsection = false; _close_subsubsection = false; _make_index = false; _use_mathjax_rendering = false; _use_relative_links = false; _index_anchors = 0; _settingsP = settings::instance(); } void texToHtml::toHtml(const QString& tex, const QString& fn) { _html_filename = fn; c2bUtils::stringToFile(toHtml(tex), fn); } QString texToHtml::toHtml(const QString& tex) { _bibtex_directory.clear(); _cites.clear(); _close_subsection = false; _close_subsubsection = false; _html.clear(); _index = "<ul>\n"; _index_anchors = 0; _make_index = false; _use_mathjax_rendering = false; _references.clear(); _tex_macro_names_rx.clear(); _tex_macros.clear(); _title.clear(); _use_relative_links = _settingsP->value("c2bAnnote/UseRelativeLinks").toBool(); if (_html_filename.isEmpty()) _use_relative_links = false; else _current_dir = QDir(QFileInfo(_html_filename).absolutePath()); QString tex2html(c2bUtils::fileToString(":/htm/htm/tex2html.html")); QString mathjax_head(c2bUtils::fileToString(_settingsP->fileName("c2bAnnote/MathJaxHeaderFile")).trimmed()); if (!mathjax_head.isEmpty()) _use_mathjax_rendering = true; parse(tex); if (_close_subsubsection) _index += "</ul></li>\n"; if (_close_subsection) _index += "</ul></li>\n"; _index += "</ul>"; if (_use_mathjax_rendering) { if (!_tex_macros.isEmpty()) { QString t("\n\n<script type=\"text/x-mathjax-config\">\n MathJax.Hub.Config({\n TeX: {\n Macros: " "{%1\n }\n }\n });\n</script>\n"); mathjax_head += t.arg(_tex_macros); } tex2html.replace("GET_MATHJAX_HEAD", mathjax_head); } else tex2html.remove("GET_MATHJAX_HEAD"); if (_settingsP->value("c2bAnnote/IncludeCSS").toBool()) { QString css(c2bUtils::fileToString(_settingsP->fileName("c2bAnnote/AnnoteCssFile")).trimmed()); if (css.isEmpty()) css = c2bUtils::fileToString(":/htm/htm/tex2html.css"); tex2html.replace("GET_CSS", "<style type=\"text/css\">\n" + css.trimmed() + "\n</style>\n"); } else { QString cssfn(_settingsP->fileName("c2bAnnote/AnnoteCssFile")); if (cssfn.isEmpty()) tex2html.remove("GET_CSS"); else { if (_use_relative_links) cssfn = _current_dir.relativeFilePath(cssfn); tex2html.replace("GET_CSS", "\n <link href=\"" + cssfn + "\" rel=\"stylesheet\" type=\"text/css\"/>\n"); } } tex2html.replace("GET_TITLE", _title); retrieveReferences(); QString reference_list_html; referencesToHtml(&reference_list_html); tex2html.replace("GET_REFERENCES", reference_list_html); citesToHtml(&_html); if (_make_index && _index_anchors > 1) { _index = c2bUtils::fileToString(":/htm/htm/tex2html_index.html").arg(_index); tex2html.replace("GET_INDEX", _index); } else tex2html.remove("GET_INDEX"); tex2html.replace("GET_HTML", _html); tex2html.replace("GET_CB2BIB_VERSION_NUMBER", C2B_VERSION); _html_filename.clear(); return tex2html; } void texToHtml::parseElement(const QString& p, const QString& e, const QString& v) { if (e == "section") { const QString sv(toHtmlString(v)); ++_index_anchors; _html += QString("\n<h1><a id=\"sect%1\"></a>%2</h1>\n\n").arg(_index_anchors).arg(sv); if (_close_subsubsection) _index += "</ul></li>\n"; if (_close_subsection) _index += "</ul></li>\n"; _index += QString("<li><a href=\"#sect%1\">%2</a></li>\n").arg(_index_anchors).arg(sv); _close_subsubsection = false; _close_subsection = false; } else if (e == "subsection") { const QString sv(toHtmlString(v)); ++_index_anchors; _html += QString("\n<h2><a id=\"sect%1\"></a>%2</h2>\n\n").arg(_index_anchors).arg(sv); if (_close_subsubsection) _index += "</ul></li>\n"; if (!_close_subsection) _index += "<li style=\"list-style: none\"><ul>\n"; _index += QString("<li><a href=\"#sect%1\">%2</a></li>\n").arg(_index_anchors).arg(sv); _close_subsubsection = false; _close_subsection = true; } else if (e == "subsubsection") { const QString sv(toHtmlString(v)); ++_index_anchors; _html += QString("\n<h3><a id=\"sect%1\"></a>%2</h3>\n\n").arg(_index_anchors).arg(sv); if (!_close_subsubsection) _index += "<li style=\"list-style: none\"><ul>\n"; _index += QString("<li><a href=\"#sect%1\">%2</a></li>\n").arg(_index_anchors).arg(sv); _close_subsubsection = true; } else if (e == "title") _title = toHtmlString(v); else if (e == "itemize") { const QStringList items(v.trimmed().split("\\item ", QString::SkipEmptyParts)); for (int i = 0; i < items.count(); ++i) parseTextParagraph("- " + items.at(i).simplified()); } else if (e == "abstract") _html += QString("\n<div id=\"abstract\" class=\"abstract\">\n%1\n</div><br /><hr />\n\n") .arg(toHtmlString(v.trimmed(), false)); else if (e == "verbatim") _html += QString("\n<pre>%1</pre>\n\n").arg(v); else if (e == "newcommand") extractMacro(v); else _html += QString("\n<div>\n%1\n</div>\n\n").arg(p); } void texToHtml::parseComment(const QString& p) { if (p.startsWith("%\\c2b_bibtex_directory{")) c2bUtils::inBraces(p.indexOf('{') + 1, p, &_bibtex_directory); else if (p == "%\\c2b_makeindex") _make_index = true; } void texToHtml::parseTextParagraph(const QString& p) { extractCites(p); QString pstr(toHtmlString(p, false)); urlToHtml(&pstr); if (p.startsWith("- ")) _html += QString("\n<ul><li>%1</li></ul>\n\n").arg(pstr.mid(2)); else _html += QString("\n<p>%1</p>\n\n").arg(pstr); } void texToHtml::extractMacro(const QString& v) { QString name; if (!c2bUtils::inBraces(1, v, &name)) return; // Substitution '\macro' -> '$\macro[args]$'. MathJax will not process macros outside equation environments. _tex_macro_names_rx.append(QRegExp("(\\" + name + "\\S*)")); // To minimize clashes, the replacement must be performed from longest to shortest names. // Sort now, even if this needs multiple sortings. This way, substitutions can be done while parsing. std::sort(_tex_macro_names_rx.begin(), _tex_macro_names_rx.end(), c2bUtils::patternLengthMoreThan); QString definition; for (int i = name.length() + 2; i < v.length(); ++i) if (v.at(i) == '{') { if (c2bUtils::inBraces(i + 1, v, &definition)) break; else return; } if (definition.isEmpty()) return; name.remove("\\"); definition.remove("\\ensuremath"); definition.replace("\\", "\\\\"); if (_macro_arguments_rx.indexIn(v) > -1) _tex_macros += QString("\n %1: ['%2',%3],").arg(name, definition, _macro_arguments_rx.cap(1)); else _tex_macros += QString("\n %1: '%2',").arg(name, definition); } void texToHtml::extractCites(const QString& p) { int pos(p.indexOf("\\cite{", 0)); while (pos >= 0) { QString cites; if (c2bUtils::inBraces(pos + 6, p, &cites)) { const QStringList cite(cites.split(',', QString::SkipEmptyParts)); for (int i = 0; i < cite.count(); ++i) { const QString c(cite.at(i).trimmed()); if (!_cites.contains(c)) _cites.insert(c, -(1 + _cites.count())); } } pos = p.indexOf("\\cite{", pos + 6); } } void texToHtml::citesToHtml(QString* html) { QString key("\\b%1\\b"); QHash<QString, bibReference>::const_iterator i = _references.constBegin(); while (i != _references.constEnd()) { const QString k(i.key()); html->replace(QRegExp(key.arg(k)), QString("<a href=\"#%1\">%2</a>").arg(k).arg(_cites.value(k))); ++i; } html->replace(QRegExp("\\\\cite\\{([^\\{]+)\\}"), "<span class=\"citations\">[\\1]</span>"); } /** Retrieve references from BibTeX files directory */ void texToHtml::retrieveReferences() { if (_bibtex_directory.isEmpty()) _bibtex_directory = QFileInfo(_settingsP->fileName("cb2Bib/BibTeXFile")).path(); const QStringList flist(c2bUtils::filesInDir(_bibtex_directory, QStringList() << "*.bib")); const QStringList keys(_cites.keys()); QStringList fields; fields.append("author"); fields.append("booktitle"); fields.append("doi"); fields.append("editor"); fields.append("file"); fields.append("journal"); fields.append("pages"); fields.append("title"); fields.append("url"); fields.append("volume"); fields.append("year"); bibReference ref; _cbp.initReferenceParsing(_bibtex_directory + '/', fields, &ref); bool done(false); for (int i = 0; i < flist.count(); ++i) { if (done) return; const QString bib_contents(c2bUtils::fileToString(flist.at(i))); done = true; for (int j = 0; j < keys.count(); ++j) { if (_cites.value(keys.at(j)) > 0) continue; done = false; const QString key(keys.at(j)); if (_cbp.referenceAtKey(key, bib_contents, &ref)) { _references.insert(key, ref); _cites[key] = -_cites[key]; } } } } void texToHtml::referencesToHtml(QString* reference_list_html) { reference_list_html->clear(); if (_references.count() == 0) return; QStringList keys(_references.keys()); QMap<int, QString> ordering; for (int i = 0; i < keys.count(); ++i) ordering.insert(_cites.value(keys.at(i)), keys.at(i)); keys = ordering.values(); const QString reference_item_html(c2bUtils::fileToString(":/htm/htm/reference_item.html")); const QRegExp nonletters("[^\\w\\s-]"); QString references; for (int i = 0; i < keys.count(); ++i) { const bibReference& ref = _references.value(keys.at(i)); QString author(ref.anyAuthor()); if (!author.isEmpty()) { author = _cbp.authorFromBibTeX(author); author.remove(nonletters); author.replace(" and ", ", "); c2bUtils::simplifyString(author); author += '.'; } QString title(ref.anyTitle()); c2bUtils::cleanTitle(title, true); // Do not percent encode file (some browsers dont like encoded local files) and url // (it might already be, if needed, decode prior to encode) const QString doi(ref.value("doi")); const QString file(ref.value("file")); const QString url(ref.value("url")); QString link; if (!file.isEmpty()) { if (_use_relative_links) link = QDir::cleanPath(_current_dir.relativeFilePath(file)); else link = QDir::cleanPath(file); } else if (!url.isEmpty()) link = url; else if (!doi.isEmpty()) { if (doi.startsWith("http")) link = doi; else link = "https://dx.doi.org/" + QUrl::toPercentEncoding(doi); } const QString journal(ref.anyJournal()); const QString volume(ref.value("volume")); QString pages(ref.value("pages")); if (!pages.isEmpty()) { if (!volume.isEmpty()) pages = ", " + pages.remove(' '); else pages = ' ' + pages.remove(' '); } QString year(ref.value("year")); if (!year.isEmpty()) year = '(' + year + ")."; QString item(reference_item_html); item.replace("GET_REFERENCE_ANCHOR_ID", ref.citeidName); item.replace("GET_REFERENCE_ANCHOR_NAME", ref.citeidName); item.replace("GET_REFERENCE_AUTHOR", author); if (link.isEmpty()) item.remove("href=\"GET_REFERENCE_LINK\""); else item.replace("GET_REFERENCE_LINK", link); item.replace("GET_REFERENCE_PAGES", pages); item.replace("GET_REFERENCE_SOURCE", journal); item.replace("GET_REFERENCE_TITLE", c2bUtils::toHtmlString(title)); item.replace("GET_REFERENCE_VOLUME", volume); item.replace("GET_REFERENCE_YEAR", year); references += item; // Update _cites values according to this list _cites[keys.at(i)] = i + 1; } *reference_list_html = c2bUtils::fileToString(":/htm/htm/reference_list.html"); reference_list_html->replace("GET_REFERENCES", references); } ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������cb2bib-2.0.1/src/c2b/PaxHeaders.5700/journalDB.cpp��������������������������������������������������0000644�0000000�0000000�00000000131�14011522520�016115� x����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������29 mtime=1613145424.63462034 30 atime=1613145424.834620334 30 ctime=1613145424.638620339 ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������cb2bib-2.0.1/src/c2b/journalDB.cpp������������������������������������������������������������������0000644�0001750�0000144�00000022275�14011522520�017525� 0����������������������������������������������������������������������������������������������������ustar�00constans������������������������users���������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*************************************************************************** * Copyright (C) 2004-2021 by Pere Constans * constans@molspaces.com * cb2Bib version 2.0.1. Licensed under the GNU GPL version 3. * See the LICENSE file that comes with this distribution. ***************************************************************************/ #include "journalDB.h" #include "cb2bib_utilities.h" #include <QFile> #include <QObject> #include <QTextStream> journalDB::journalDB(const QString& dbfile) { if (dbfile.isEmpty()) { c2bUtils::warn(QObject::tr("No journal file especified")); return; } _nitems = 0; QFile file(dbfile); if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) { c2bUtils::warn(QObject::tr("Could not open journal file %1 for reading").arg(dbfile)); return; } QTextStream stream(&file); stream.setCodec("UTF-8"); stream.setAutoDetectUnicode(true); QString line; int line_number(0); while (!stream.atEnd()) { line = stream.readLine(); ++line_number; if (line.isEmpty() || line.startsWith('#')) continue; const QStringList spLine(line.split('|', QString::SkipEmptyParts)); if (spLine.count() != 3) { c2bUtils::warn(QObject::tr("Syntax error in journal file at line %1").arg(line_number)); continue; } const QStringList spAbbreviated(spLine.at(1).split('=', QString::SkipEmptyParts)); const int na(spAbbreviated.count()); if (na < 1 || na > 2) { c2bUtils::warn(QObject::tr("Syntax error in journal file at line %1").arg(line_number)); continue; } const QStringList spExtended(spLine.at(2).split('=', QString::SkipEmptyParts)); const int ne(spExtended.count()); if (ne < 1 || ne > 2) { c2bUtils::warn(QObject::tr("Syntax error in journal file at line %1").arg(line_number)); continue; } for (int e = 0, c = 0; e < ne; ++e) for (int a = 0; a < na; ++a) { _nitems++; JCode += (c++ == 0) ? spLine.at(0).toLower() : QString(); JAbbrev += spAbbreviated.at(a); JExtended += spExtended.at(e); } } file.close(); JAbbrev_simp.resize(_nitems); JExtended_simp.resize(_nitems); for (int i = 0; i < _nitems; ++i) { JAbbrev_simp[i] = JAbbrev.at(i).toLower(); JAbbrev_simp[i].remove(c2bUtils::nonLetter); JExtended_simp[i] = JExtended.at(i).toLower(); JExtended_simp[i].remove(c2bUtils::nonLetter); } } /** \page journalproc Processing of Journal Names cb2Bib processes journal names according to its editable database, stored at <tt>abbreviations.txt</tt>. This file contains a list of journal names equivalences: a capital-letter acronym, the abbreviated form, and the title of the journal, all three on one single line. The <tt>abbreviations.txt</tt> file has the following structure: \verbatim JA|J. Abbrev.|Journal of Abbreviations AN|Am. Nat.=Amer. Naturalist|American Naturalist=The American Naturalist \endverbatim The first field, the capital-letter acronym, is a user-defined shorthand to access a journal title by typing it at the extraction panel. The second field is the abbreviated form of the journal. To adapt to multiple abbreviations in use, cb2Bib allows one alternate version of the abbreviation, indicated with an equal sign <tt>=</tt>. In the above example, the ISO 4 abbreviation 'Am. Nat.' is the primary one and 'Amer. Naturalist' is the alternate one. Finally, the third field is the full title of the journal. As for the abbreviations, the full title also admits one alternate form. Abbreviated and full title alternates serve two purposes: journal recognition and citation styling. The former is performed internally by cb2Bib as part of a bibliographic reference extraction, and the latter is accomplished in the embedded BibTeX editor by replacing back and forth abbreviated-full forms, in order to set journals in accordance to the guidelines of a particular publication. <p> </p> Journal names processing is performed whenever a string is recognized as 'journal', and, additionally, when pressing <tt>Intro Key</tt> at the journal edit line. <p> </p> - Retrieves Journal name in <b>abbreviated form</b> if found. - If Journal name is not found in the database, returns input Journal name. - Search is case insensitive. - **Warning:** Journal codes can be duplicated. If duplicated, returns input Journal name. <p> </p> - Retrieves Journal name in <b>full form</b> if found. - If Journal name is not found in the database, returns input Journal name. - Search is case insensitive. - **Warning:** Journal codes can be duplicated. If duplicated, returns input Journal name. <p> </p> See \ref c2bconf_files, \ref c2bconf_bibtex, and \ref c2beditor_menu. */ QString journalDB::retrieve(const QString& JQuery) const { const QString query(JQuery.toLower().remove(c2bUtils::nonLetter)); if (query.isEmpty()) return QString(); for (int i = 0; i < _nitems; ++i) { if (JAbbrev_simp.at(i) == query) { if (i > 0 && JExtended_simp.at(i) == JExtended_simp.at(i - 1)) return JAbbrev.at(i - 1); else return JAbbrev.at(i); } if (JExtended_simp.at(i) == query) return JAbbrev.at(i); } int journal_found(0); int journal_found_at(-1); for (int i = 0; i < _nitems; ++i) if (JCode.at(i) == query) { journal_found++; journal_found_at = i; } if (journal_found == 1) return JAbbrev.at(journal_found_at); else return JQuery; } QString journalDB::retrieveFull(const QString& JQuery) const { const QString query(JQuery.toLower().remove(c2bUtils::nonLetter)); if (query.isEmpty()) return QString(); for (int i = 0; i < _nitems; ++i) { if (JAbbrev_simp.at(i) == query) return JExtended.at(i); if (JExtended_simp.at(i) == query) { if (i > 0 && JAbbrev_simp.at(i) == JAbbrev_simp.at(i - 1)) return JExtended.at(i - 1); else if (i > 1 && JAbbrev_simp.at(i) == JAbbrev_simp.at(i - 2)) return JExtended.at(i - 2); else return JExtended.at(i); } } int journal_found(0); int journal_found_at(-1); for (int i = 0; i < _nitems; ++i) if (JCode.at(i) == query) { journal_found++; journal_found_at = i; } if (journal_found == 1) return JExtended.at(journal_found_at); else return JQuery; } QString journalDB::retrieveAlternate(const QString& JQuery) const { const QString query(JQuery.toLower().remove(c2bUtils::nonLetter)); if (query.isEmpty()) return QString(); for (int i = _nitems - 1; i >= 0; --i) { if (JAbbrev_simp.at(i) == query) { if (i + 1 < _nitems && JExtended_simp.at(i) == JExtended_simp.at(i + 1)) return JAbbrev.at(i + 1); else return JAbbrev.at(i); } if (JExtended_simp.at(i) == query) return JAbbrev.at(i); } int journal_found(0); int journal_found_at(-1); for (int i = 0; i < _nitems; i++) if (JCode.at(i) == query) { journal_found++; journal_found_at = i; } if (journal_found == 1) { if (journal_found_at + 1 < _nitems && JCode.at(journal_found_at + 1).isEmpty()) return JAbbrev.at(journal_found_at + 1); else return JAbbrev.at(journal_found_at); } else return JQuery; } QString journalDB::retrieveAlternateFull(const QString& JQuery) const { const QString query(JQuery.toLower().remove(c2bUtils::nonLetter)); if (query.isEmpty()) return QString(); for (int i = _nitems - 1; i >= 0; --i) { if (JAbbrev_simp.at(i) == query) return JExtended.at(i); if (JExtended_simp.at(i) == query) { if (i + 2 < _nitems && JAbbrev_simp.at(i) == JAbbrev_simp.at(i + 2)) return JExtended.at(i + 2); else if (i + 1 < _nitems && JAbbrev_simp.at(i) == JAbbrev_simp.at(i + 1)) return JExtended.at(i + 1); else return JExtended.at(i); } } int journal_found(0); int journal_found_at(-1); for (int i = 0; i < _nitems; ++i) if (JCode.at(i) == query) { journal_found++; journal_found_at = i; } if (journal_found == 1) { if (journal_found_at + 2 < _nitems && JCode.at(journal_found_at + 1).isEmpty() && JCode.at(journal_found_at + 2).isEmpty()) return JExtended.at(journal_found_at + 2); else if (journal_found_at + 1 < _nitems && JCode.at(journal_found_at + 1).isEmpty()) return JExtended.at(journal_found_at + 1); else return JExtended.at(journal_found_at); } else return JQuery; } �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������cb2bib-2.0.1/src/c2b/PaxHeaders.5700/txt������������������������������������������������������������0000644�0000000�0000000�00000000074�14011522151�014301� x����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������30 atime=1613145424.834620334 30 ctime=1613145424.302620349 ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������cb2bib-2.0.1/src/c2b/txt/���������������������������������������������������������������������������0000755�0001750�0000144�00000000000�14011522151�015750� 5����������������������������������������������������������������������������������������������������ustar�00constans������������������������users���������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������cb2bib-2.0.1/src/c2b/txt/PaxHeaders.5700/suffixes.txt�����������������������������������������������0000644�0000000�0000000�00000000074�14011522151�016753� x����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������30 atime=1613145424.838620334 30 ctime=1613145424.302620349 ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������cb2bib-2.0.1/src/c2b/txt/suffixes.txt���������������������������������������������������������������0000644�0001750�0000144�00000015732�14011522151�020355� 0����������������������������������������������������������������������������������������������������ustar�00constans������������������������users���������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������a abilities ability able abled ablely ableness ablenesses ables abling ably ac acea aceae acean acene aceous acousia acoustic acy ad ada addy ade adenia adic adiene adiyne adol ads aemia aesthesia aesthetic against age agnosia agog agogue agra al ales algesia algia aling alis alism alisms alities alitis ality alization alizations alize alized alizer alizers alizes alizing alli allied allies allis ally allying alness als amide amidine amidyl amine aminyl an ana ance ances ancies ancy ane angle ans ant anted anthema anting antness ants ar arch arche archy ard aria arian aries arion arit arity arities arium ary as ase asis ast aster asthenia ata ate ated ateful atefulness ately ateness ates ating atings ation ational ationals ations ative atively ativeness atives ativity ato ator atored atoring ators atory atresia atriene atriyne atrophia atum atus auxe basia bility biosis biotic biotics blast ble bleness blepharia blepsia blepsy bly boom bound bounds brachia bund bus cace caine calities cality cally calness capnia cara carbaldehyde carbonitrile carbonyl carboxamide carboximidamide carboxylate carboxylic carcinoma cardia cardiac carp catharic cele cene centesis centric cephalia cephalus cephaly cera cerca cerebral chesia chezia chirurgia chondria chorea chroia chromasia chromatic chrome chylia cidal cide clasia clasis clasm clast clastic cle cleisis clinous clonia clysm cnemia coccus coele cole comma cracy crania crasia crat cratia crine crotic cular cule culum culus current cusis cy cycle cyst cystic cyte cythemia d dactylia demic dendron dermia dermic desis desma diene diide diium diol dione dipsia diyl diylidene diylylidene dom donita dorsal drome duct dynamia dynamy dynia e eabilities eability eable eableness eables eably eae eal ealed ealing ealism eality ealization ealize ealized ealizing eally ealness eals ecane echia ecin ecine ecoia ectasia ectasis ectasy ectomy ectopia ed edema edly edness ee eement eements een eence eer eered eering eers ees eg egasia ein el ella elle ellum ema eme ement emented emently ementness ements emetic emia empyema en ence enceful encephalia encephaly enchyma ency ene ened ener eness enesses ent entative entatively entativeness entatives entativity ented entful entfulness enting ently entness ents eous eously eousness epane epin epine er erative eratively erativeness ered erful erfulness ergetic ergic ergy eries ering erings erness erotic ers ery es escence escense escent ese esis esp esque ess est esthesia et etane etc ete etene eth etic etidine etine ette etum eus facient faction fast febrile fer ferent ferous fibroma fic fication fid field fields fish fishes flect flex fluent fold food foot form forme found founds fuge ful fullness fully fulness fulnesses fuls fuse fy fying gamy gen gene genesia genesis genia genic gerous geusia geustia gine glossia glycaemia gnathia gnomy gnosia gnosis gon gony gram graph grapher graphia graphy gyne h hale hedron helminth herbicide hood hound hounds hydria hydride i ia iac ial ian iasis iatric iatrician iatry ible iblely ibleness ibles iblies ibly ic ical icalism icalities icality ically icals ice iced ician icing icities icitis icity ics icus id ida idae idan ide idea ides idin idine idines idium ido idyl ie ied ier ies iest iform iforme ify il ile iliac ility illa illus ily imidamide imide imine iminyl in ina inae inane ine ineae iness inesses ing ingly ings ingy ini initio io ion ional ioned ionful ioning ionings ions ior ious irane irene iridine irine iscus ise ised ish ishly ishness ishy ising isk isks ism isms ismus ist istic ists ite ited ites iti itiative itic ities itious itis itium itol ity ium iumyl ive ivelies ively iveness ives ivities ivitis ivity ization izations ize ized izer izers izes izing kijn kin kind kinds kinesia kinesis l labe labial labile lability lable labled lablely lableness lables lably lagnia lagny lalia land lapse lateral lates lating lation lational lations lative latively lativeness lator lators latry le leability leable leableness leal led lemma leness leous lepsy leptic ler lered lering lers les less lesses lessly lessness let lexia like likes lines ling lings lipsis lite lith lithiasis lithotomy lity lobe log logia logical logist logue logy long lucent lunar ly lying lymph lyse lysin lysis lyst lyte lytic lyze ma malacia man mancy mania maniac manic manship mark marks mastia masty mazia megaly melia men ment mentative mentatively mentativeness mented mentia menting mently ments mer mere meria meric merics meter metr metria metric metries metry mimesis mixis mnesia mo moria most motor mrs myelia neonatology nephric ness nessed nesses nessing neural neure neuria neuron nik nitrile node noia noid nom noma nome nomia nomy o oate ocane ocin ocine ock ode odonita oedema of ogen oic oid oidal oidea oin ol ola olane olate ole olene olic olics olidine oline ology ols olum olus oma ome on onane one ones onia onic onin onine onio onite onites onium oniumyl ons ont ope opia opsia opsy opy or orexia organic orial ories orium ors ory os oscopy ose oside osis osmia osteon osteum ostomy ote otia otic otomy ous oused ousing ously ousness oxemia oxia oyl pachy paedic paenia pagus pancreatic para partite path pathetic pathia pathic pathy ped pede penia pennate pepsia peptic pert petal pexia pexis pexy phagia phane phasia phemia phil phile philia philias philic phily phobe phobia phone phones phonia phonic phore phoresis phoria phragm phrasia phrenia phrenic phthongia phyll phyma physical physics physis phyte picrin plakia plania plasia plasm plast plastia plastic plasty plegia plegic plex plexia plexus plexy ploid pnea pnoea pod podia poetic poiesis poo pore post potent pragia praxia praxis privia proctia proof proofs prosopia prost pselaphesia psychic psychosis pterygium ptosis ptysis pubic pulsion pyrexia renal rhachia rhage rhagia rhaphy rhea rhexis rhoea room rooms rrh rrhachia rrhage rrhagia rrhaphy rrhea rrhexis rrhoea ry s scelia schisis sclerosis scope scopy scribe script se sect sector selenal selenoic selenol selone sepsis septic ship sia sion sis site sitia solve soma somatic some someness somenesses somia spasm spermia sphere sphygmia spire spore stabile stage stalsis stasis stat state staxis stenia stenosis ster sthenuria stichia stole stoma stome stomy stone stophy strongyle sts studies style sulfenic sulfinic sulfonate sulfonic sultam sultone surgery sy synthesis t tactic taxia technics technology ted tela tellurol tension tention tetrayl th thecium thelium therapeutic therapy therm thermia thermy thetic thioic thiol thiolate thione thymia thyrea tic tically tics tion tode tome tomic tomy tonia tonic tony topia topy toxin trauma trema tresia tribe trichia triene triide trione tripsis tripsy trix triyl tron trope trophia trophic trophy tropic tropics tropos tropy tude tumescence tuse ty typia uida uide uidyl ula ular ulation ule ulent ulose ulous ulum ulus um ums ura ure urgia urgy uria uris us uses valve venous ventral verge verse vert vertebral ville volute vore vorous ward wards way ways with wood worm y yl ylene ylia ylidene ylidyne ylium yliumyl ylylidene ylylidyne yne zoa zoite zoon zyme ��������������������������������������cb2bib-2.0.1/src/c2b/txt/PaxHeaders.5700/word_prefix_lexicon.txt������������������������������������0000644�0000000�0000000�00000000074�14011522151�021170� x����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������30 atime=1613145424.838620334 30 ctime=1613145424.302620349 ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������cb2bib-2.0.1/src/c2b/txt/word_prefix_lexicon.txt����������������������������������������������������0000644�0001750�0000144�00000006703�14011522151�022570� 0����������������������������������������������������������������������������������������������������ustar�00constans������������������������users���������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������_about_ _abso _abstra _acces _accu _acety _acid _acta _actin _activ _adapt _adso _advanc _afte _agen _alert _algor _align _analys _and_ _anion _antib _antige _applic _appr _arabid _archiv _articl _assemb _asses _assoc _at_ _atom_ _atomic _atp _autom _bacil _bact _based _basis _behav _betw _bibli _bindi _bioc _bioi _biolog _biom _biosy _blood _bound _bovine _but_ _by_ _calci _calcul _campus_ _cataly _catio _ccs _cdn _cell_ _cells _cellul _center_ _centra _cereb _cerev _changes _channe _charac _chem_ _chemi _chlor _chrom _cien _citat _classi _clini _cloni _clust _collect _colleg _communic _compara _comparis _compl _compon _composi _compou _compu _conform _conse _consis _constr _contac _contai _continu _control _conversi _coord _copy _core_ _corpo _correla _couple _crystall _cubat _cult _cyc _cyt _data_ _datab _dehy _densi _depart _depen _deriv _descri _design _deskt _detai _detec _determi _devel _dft _differ _digg_ _digit _dimensi _direc _disea _dissoc _distanc _distr _diverg _divers _dna _doctora _domains _downl _droso _dyna _edite _editi _edito _effec _effi _eigenv _elec _elemen _emai _embry _enco _endot _energ _enh _enzy _epid _epit _equa _errat _escheri _estim _eval _evidenc _evol _exam _exch _exci _experi _expr _extra _facul _false_ _family _featu _federa _fibr _fluo _for_ _formal _format _formu _fract _fragm _from_ _funct _gaussi _generali _generat _geneti _genom _geolo _geom _gluco _gluta _glyc _granul _group _growt _hamiltoni _hepa _heter _highly _hist _homolo _hormon _htm _hybr _hydr _hyper _iden _image _imagi _immu _impl _improv _inc_ _index _indu _infe _infl _info _inhi _init _inst _integ _intera _interf _interm _inters _intro_ _introd _inves _invo _isolat _issu _items _journal _kinase _kinet _labora _lact _librarie _library _licens _ligan _linea _lipid _lipop _localiz _lymph _magnet _mammal _manusc _mappi _matchi _mathem _matric _matrix _measure_ _measurem _mechanis _mediat _medica _membe _membra _metab _metad _method _methy _metri _micr _mitoc _model_ _modeli _models _modif _modu _molec _morph _multi _muscl _mutant _mutati _myco _nanop _nanos _nanot _natu _nerve _netw _neural _neuron _new_ _nitr _nmr _nonp _normal _notes_ _novel_ _nucl _numer _obj _obse _of_ _on_ _onl _oper _optical _optim _orbi _organiz _origi _oxi _oxy _paper_ _papers _parall _paramet _partia _partic _patho _pathw _patients _pattern _pdf _peak_ _pept _perfo _permis _perox _pertur _phas _phos _phot _phylo _phys _plasm _polymer_ _polymera _popu _postin _potent _pract _predict _prepr _presen _primar _principl _probab _probl _proces _produ _profes _profi _progr _promo _prope _proteas _protei _proteo _proton _pseu _pub _purificat _putat _quadra _quantit _quantu _radical _reac _recep _recog _recom _recon _reduc _refere _regio _regr _regulat _relat _repl _report_ _reports _represe _requi _resea _resis _reso _resp _revea _review _ribos _rna _rotat _saccha _scale_ _scalin _scheme_ _school_ _scienc _scient _search _second _secret _segm _selec _sensit _sequen _series _sets_ _shell_ _signa _simila _simula _singu _sites _soft _solut _south_ _space_ _speci _spectr _sph _spin_ _stabili _standard_ _stati _stimu _strep _struct _studies _study _subject _subm _subsp _subst _subun _sulf _surf _syna _synth _syst _technic _techniq _techno _tempera _termina _tetr _the_ _theorem _theoreti _theori _theory _thermo _thesis _three _throu _tissu _to_ _tox _transc _transf _transi _transm _transp _treatm _tumo _type _ultr _unit _univ _usa_ _usi _variab _vesic _vibrat _virtua _visua _vitro _with_ _within _yeas �������������������������������������������������������������cb2bib-2.0.1/src/c2b/txt/PaxHeaders.5700/triads.txt�������������������������������������������������0000644�0000000�0000000�00000000074�14011522151�016405� x����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������30 atime=1613145424.838620334 30 ctime=1613145424.302620349 ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������cb2bib-2.0.1/src/c2b/txt/triads.txt�����������������������������������������������������������������0000644�0001750�0000144�00000005411�14011522151�020000� 0����������������������������������������������������������������������������������������������������ustar�00constans������������������������users���������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������aeiloty ¦§³»¼ÀÂÉÍÑÛÜÝáþāĎďģıIJĵĶķĹļľĿŃńŅʼnƂƐƑƕƦƶǀdžǍǑǓǔǕǟǠǧǫǯǴǵȝȟȲȳȷȹȽɁɃɆɇɈɏɑɓɛɜɝɠɢɤɩɭɻɼ˙̪͍̒Ϳ΀΂ϛжџӜӫӳӷӾԁԐֱֶֻּ֭֩֯؈ؙؓؕؖآأؤحٹٽٿځچڌۋۘۙۚۛ۟ۡ۩۬ۮۯ۵ۻۿ܃܆܉܌܎܏ܘܙܧܳݣݥݧݫݰݱݵށޅދޏޚޥޱ޵޹޼߄ߜࡑࡕ࡛ࢄࢉࢍ࢓࢔࣓ࣜथ঍঒ণধফলৠਉਊਜਡਧਲਵ੉ੌੲ੺૱૵ૹૼ૾૿଀ଃ଄ଅଜଥ଩ଭଷୂୌ୙୛ଡ଼ଢ଼ୟୡ୥୧୪୫୬ୱ୵஄஑ஔச஠பயழஸு௅ே௉ௌ௎௓௔௕఑జశ఼౎ౖౠౡ౥౷౹౻಄ಅಈಭಯಲಳಶಷಸ಼ಽಾೃೈ೐೒೓ೖ೗೘೟ೡೢೣ೤೧೪೫೬೭೰ೲ೴೷೹೽ഄആഊഌഖഞതറാ෍෗ෛො฀กฐฑโ๭ແ໪໺ཏནབཛྷརལྠွ၀၁။ၓႳႴ폐ᅾᆋᆏᆖᆜᆩᆴሆቨጹᐍᐗᐠᐧᐨᐳᑍᑏᑡᑧᒙᒛᒜᒥᒳᓨᓬᔮᖅᖉᖌᖓᖔᖙᖟᖹᗇᗉᗑᗜᗞᗦᗩᗭᗱᗺᗻᗼᗾᘁᘔᘡᘪᘮᙄᙈᙉᙑᙔᙕᙗᙙᙜᙞᙢᙣᙥᙩᚱᚷᛖᛗᛞᛤᛥᛱᜋᜏ᜘᜚ᝌ᝙᝱ᝲ᝵᝷᝼᝽កជញឍទបលវឮ឴ᡡ᱂ᵱᵵᵿᶀᶒᶩᶬᶲᶴᷦᷨḋḖṃṈẲẸếểịốỒỡừἫἺὅὉὓ὞ὟὩὬὰήᾚᾶῺ ’‣‥⁅⁐₊₋ℱℳℷ℻⅀⅁⅂ⅆ⅖ⅣⅧⅫⅯⅰⅵⅶↁↅ←⇍⇒⇶∁∃∇∍∐−∗∙∝∡≳⊮⊸⊹⊽⋂⋉⋍⋭⌝⌟⌡⌣⌥〉⌬⌮⌯⌰⌲⍈⍤⎅⎉⎋⎍⎐⎒⎘⎙⎝⏖⏥⏦⏫⏭⏯⏱⏾␋␏␙␭␳␶⑙⑯⑲⑷⑺⒂⒇⒣⒥⒦⒧⒰⒱⒴⒵ⒶⒷⒽⓨ╝╡╤╦▀▆▜▞▴▸►◁◅◈◉◎◒◓◔◕◣◬☠☩☭☯☰☱☴☶☻☼♅⚃⚄⚍⚔⚜⚞⚤⚫⚭⚯⚽⛉⛍⛓⛗⛝⛣⛧⛬⛰⛱⛲✓✕✗✛✞✟✥✭✮✰✵✾✿❇❊❏❓❔❕❥❩❴➈➌⟗⠁⠱⠵⠶⠹⡂⡩⡭⡶⡷⣍⣏⣐⣑⣓⣕⣚⣟⣠⤝⤟⤨⤬⤮⥓⥗⥜⥩⥫⥭⥮⥱⥴⥷⥺⥼⥽⦷⦻⦿⧂⧃⧅⧉⧊⧋⧎⧙⧤⧯⧸⧼⧾⩵⪥⪩⪴⬋⬜⭱⭵ⵇⵉⵌⵍⵐⵓⵗⵘⵠⵢⵣ⵲⵼⵽ⶁⶄⶆⶋⶍⶕ⶗ⶭ⶯ⶱⶵⶼ⶿ⷀⷘⷡⷥⷮⷯⷴ⸌⸕⸙⸛⸝⸠⸢⸦⸧⸨⸩⸱⹶⺅⺊⺐⺙⺛⺜⺟⺢⺥⺩⺵⺹⺽⻃⻋⻏⻓⻜⻝⻩⻭⼙⼜⼝⼡⼤⼦⼧⼪⼵⼶⼷⼻⼿⽀⽁⽄⽆⽍⽐⽑⽔⽪⽺⾧⿫⿬⿭⿱⿴⿼〇〖〝〥〨〪えごすっつらろグスタチツテニネㄉㄋㄏㄙㄚㄥㄬㄴㄻㄿㅃㅆㅕㅘㅙㅝㅠㅡㅢㅧㅨㅽㆀㆍㆣㆤㆥㆧㆫㆰㆲㆶ㇁㇥㇩㇬ㇵㇹ㈂㈃㊑㊕㊘㊚㊟㊠㊫㋅㋌㋎㋵㋹㋽㌁㌂㌆㌇㌈㌩㌺㍡㍣㍥㍯㍰㍱㎞㏇㏐㏗㏘㏞㏟㏣㏧㏭㏱㏹㏽㏿㐁㐇㐋㐌㐍㑇㑉㑋㑏㑒㑔㑕㑙㑚㑛㑩㑽㒆㒉㒍㒎㒨㒺㓁㓂㔵㔹㕜㕭㖐㖡㖬㖵㘅㘇㘎㙢㙧㚇㚋㚎㚗㛈㛉㛸㛽㜅㜍㜟㜢㜣㜬㜭㜮㜰㝄㠗㣳㣷㤀㤂㥓㦏㦓㦕㦗㦚㧑㫥㭍㭐㱅㲄㲬㶍㶘㹠㹨㻩㿉䂑䄌䄵䆻䑡�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������cb2bib-2.0.1/src/c2b/txt/PaxHeaders.5700/prefixes.txt�����������������������������������������������0000644�0000000�0000000�00000000074�14011522151�016744� x����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������30 atime=1613145424.834620334 30 ctime=1613145424.302620349 ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������cb2bib-2.0.1/src/c2b/txt/prefixes.txt���������������������������������������������������������������0000644�0001750�0000144�00000022160�14011522151�020337� 0����������������������������������������������������������������������������������������������������ustar�00constans������������������������users���������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������a ab abdomin abs ac acanth acantho acar acet acetab aceto acou acous acouso acr acro actin acu ad add aden adeno adenoid adip adipo adren adreno aemia aer aero aesthesi aesthesio aeti af after ag agri al ala alb albi alg alge algesi algio algo ali aliment alkyl all allo alto alveol am amb ambi ambly ambyl ameb ametr amic amidino amino amm amni amnio amph amphi amphibi ampho amyl an ana ancylo andr andro anemo ang angi angio anis ankyl ankyle ankylo ano anomalo ant ante anter antero anth antho anthra anthro anthrop anthropo anti antr ap aph api apo aqu aqua aqui aquo ar arch archa archaeo arche archi argyr aristo arrhen arsa arshae arter arteri arterio arteriol arth arthr arthro arthron articul articulo as asco aster asthen astr at ate atel ather atm atmo atom atreto atri atrium atto audi aur auri auricul aut auto aux axi axilla aza azido azo azot bacill back bacter bacteri bacterio bactr balan bar barb baro bary basi baso bath be ben bene benzo ber bi bibli biblio bicyclo bin bio bis bisma blast blasto blenn bleph blephar blepharo bon bora brachi brachia brachio brachy brady branchi breph brev brevi brom bronch bronchi bry bryo bucc bucco cac caco caen calc calor cancer cancr canth capill capit caps caput carb carbamimidoyl carbamoyl carbox carboxy carboxylate carboxylato carcin carcino cardi cardio carn carnis carp carpal cary case cat cata cath cato cau caud caul caus cav cel cell cen cente centi centr centri cephal cephalo cer cerat cerebell cerebr cerebro cervic chalc chancr cheil cheir chel chele chem chemi chemico chemio chemo chil chir chlor chloro chloroformyl chol cholangi choledoch chondr chondrio chondro chord chori chrom chroma chromato chrome chromo chron chrono chyle chym cili cilia cine circa circum cirrho cirru cis citra clas clast cleid cleist clin clist co cocc coccyg coel coen col cole coll colo colono colp com con coni contra cor core corp corpus cort cortic cosmo cost cotyl counter crani cranio cresc cret cric crin crur cry cryo crypt cteno cucmul cumul cusp cut cuti cyan cyano cyber cyci cycl cyclo cymbo cyn cyrt cyst cysti cysto cyt cyte cytis cyto da dacrio dacry dacty dactyl dactylo de dea dec deca deci deka deliquesc dem demi demo dendr dent der derm dermato dermis des desm deuter deutero dextr dextro di dia diaza dicta dif differ digit diicosa dilia din dipl diplo dis dodec dodeca doheptaconta dohexaconta doicosa dolich dolicho dont dorm dors drom du duo duoden duodeno dur dy dynam dynamo dys e ec echin eco ect ecto ectro ef eka el ele electr electro elytr em embry emet emnea en encephal encephalo end endo ennea enneaconta ent enter entero ento entom eole ep eph epi episi equi erg ergy erot erythr erythro eso esthesio ethno ethoxy eu eury ev ex exa exo extra extro faci fasci febri femto ferr ferro feto fibr fibro fil fila fis fiss flagell flav flor flu fluct fluor foet foli for fore formyl fract front fus galact galacto gam gamet gangli gastr gastro ge gelat gemin gemm gen gene geni genu geny geo ger germa geront gibi giga giganto glia glob gloss glossa glosso glott glotto gluc gluco glut glyc glyco gn gnath gnatho gon goni gono gony granul graph grav gravid gravis gymno gyn gynae gynaeco gyne gyneco gyno gyr haem haema haemat haemato hal hallux halo halocarbonyl hapl haplo hapto hect hecta hecto hel helc heli helic hem hema hemat hemato hemi hemo hen hendeca hepar hepat hepatico hepato hept hepta heptacta heptadeca heptalia herb heter hetero hex hexa hexacta hexaicosa hexalia hibern hidr hidro hier hipp hist histio histo holo hom homeo homo horm hort hyal hybrid hydr hydro hydroperoxy hydrox hydroxy hygr hyl hymen hyp hyper hyph hypho hypno hypo hyps hypsi hyster hystero iatr ic ichthy icon icosa icosidi icosiocta icositri icter ide idea ideo idi idio ign il ile ileo ili ill im imino immuno in incret incud infero infra infro inguin ini insul inter intra intro intus iodo ir irid irido isch ischi ischio iso ite ithy ixodi jec jejun jug jugu juxta kak kali kaps kary karyo kat kata kel ken ker kerat kerato keraun kibi kilia kilo kin kine kinesi kinesio kino klept koilo kolp koly kon krym kym kyn kyph kypho kysth labi lac lachry lacri lacrim lacrimo lact lacti lacto laevo lal lamina lampro lan lapar lapis laryng laryngo lat later latero lecith lei leio lem lepid lepr lepto leuc leuco leuk leuko levo lex lien liga lign lim lin lingu linguo lio lip lipo liqu lith litho loc log loga logo longus loph loxo luc lue lumb lumi lumin lun lute ly lyc lymph lympho lys lyso lyss macr macro mag magn magna maj makro mal malac malar male malle mamm man mania marg mast masto maxilla maz mc meat mebi mechan mechano mecon med medi meg mega megal megalo meio mel mela melan melano meli men mening meningo menisc ment mer mercura mes mesa meso mesos met meta meteor meter meth metop metr metro micr micro mid migr mill mille milli mini minumus mio mis mit mito mnem mole moll mon mono mont morph morpho mort mot mov muc multi muscul musculo mut my myc mycel mycet myco myel myelo myl myo myria myring myringo myx myxo nano narc naris nas natr ne neco necr necro nem nema nemat neo neph nephr nephro ner nerv nesidi neur neuri neuro neutr niga noci noct nod nodus nomen non nona nonaconta nonacta nonadeca nonalia normo nos not novi nox nuc nucha nutri nyct nymph o oari oate ob oc occipit occlus oct octa octaconta octacta octadeca octaicosa octi octo octodeci ocul oculo odont odonto odyn odyno oedem oesophageal oesophago of oik ole olf olfact olig oligo om omni omphal onc oncho onco one oneir ont onych onycho onyx oo oophor oophoro oothec op ophidia ophthalm ophthalmo opistho ops opt opthal opthalm optic or ora orb orch orchi orchid orchido orchio organ organo ornith orrh orth ortho os osche oscu osm oss osseo ossi ost oste osteo ot oto ous out ov ovari ovario over ovi ovo oxa oxido oxo oxy pachy paed palat paleo pali palin palm palpebra palpit pan pant panto papilla par para part parvi path patho pebi pect pector ped pel pell pelv pelvi pelvo pene pent penta pentacta pentadeca pep per peri permea pero pes peta petal petr phac phaco phaeo phag phage phago phak phalan phall phan phaner phao pharmac pharmaco pharyng pharyngo phas phen pheno pheo pher phil philo phleb phlebo phleg phlogo phob phobo phon phono phor phos phospha phot photo phrag phren phreni phrenico phreno phthi phyc phyl phyll phylo phys physi phyt phyto pi pico picro piez pil pimel pinni pino pituit plan plankto plas plasm plasma plast plat platy pleo pleur pleura pleuro plex plic plumba pluri pne pneum pneuma pneumat pneumato pneumo pod podo poikilo poli polio pollex polples poly pom pon pont por porphyro port post postero prae pre presby presbyo prim primordis pro proct procto pronto pronus proprio pros prosop prot proto prox psamm pselaph pseud pseudo psor psych psyche psycho pter pterido ptoma ptyal pub puer pulm pulmo puls pur purpur py pyel pyelo pyg pyle pylor pyo pyon pyr pyret pyro quad quadr quadra quadri quarter quarti quasi quater quatr quin quinque quint r rachi radi radicul radio rami re rect recto red ren renes reno reptilis ret reticul reticulo retro revo rhabd rhabdo rhachi rhag rhe rhig rhin rhino rhiptid rhiz rhizo rhod rhodo rhyp rost rot roto rub rubr sacchar saccharo sacr salping salpingo sangui sanita sap sapr sapro sapros sarc sarco saturn saur scaph scat scel schis schist schisto schiz schizo sci scia scirrho scler sclero scolec scoli scolio scop scot scribe scrit scyt se sect secund sed selanyl selena selenocarboxy semei semi sens seps sept septa septe septi septic ser sesqui sess set sex sexdeci sexi sial sialo sicc sider sigmoid sigmoido sila sin sinap sinistr sinistro sit sito skia sol solv som soma somat somatico somato some somn son sonus sover spacel spano spasm spasmo spec spectr spectro sperm sperma spermato spermo sphaer sphen spher sphygm spic spin spinth spir spiro splanchn splanchni splanchno splen spleno spod spondyl spondylo spongi spor squam stann stanna staphyl stas stat steap stear steat stell sten steno sterc stere stereo stern steth sthen stheno stiba stom stoma stomat stomato strab strat strati strept stri strict stroph strum styl sub subter suc succ sud suf sug sulfanyl sulfeno sulfido sulfino sulfo sulfonato sum sup super supinus supra sur sursum sy syl sym syn syndesm syring sys system syto tabe tach tachy tact taenia tal talip taph tars tarso taut tax tebi techn tect teg tel tela tele tellanyl tellura telo temp tend tenia teno tenont tension tephr ter tera terat terr terti test tetan tetart tetr tetra tetraconta tetracta tetralia thall thanat thec their thel thelo thely thenar theo therap therm thermo thia thigm thio thiocarboxy thix thorac thoracico thoraco threp thrix thromb thrombo thym thyr thyro tibi toc toco ton tono top topo tors tox toxi toxico toxo tra trache trachel tracheo trachy trans tre tredo tri trich trichi trichia tricho tricta trideca triginta trigon trigono triicosa trilia tris trit trocho trop troph tub turb tuss twi tyman tympan tympano typ typhl tyr ul ula ultra un una undeci under ungu uni untriginta ur uran ureter urethro uri uric urico uro uron uter vagin valvul varic varico vas vascul vasculo vaso vect ven vent venter ventr ventricul verd vermi vertebr vesic vesico vice vig viginti vir viscer vit vita viv vivi volv vor vulv xanth xanthin xantho xen xeno xero xiph xyl yocto yotta zepto zetta zo zoa zoo zyg zygon zym zymo ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������cb2bib-2.0.1/src/c2b/PaxHeaders.5700/wordMatcher.cpp������������������������������������������������0000644�0000000�0000000�00000000132�14011522520�016515� x����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������30 mtime=1613145424.678620338 30 atime=1613145424.834620334 30 ctime=1613145424.678620338 ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������cb2bib-2.0.1/src/c2b/wordMatcher.cpp����������������������������������������������������������������0000644�0001750�0000144�00000005117�14011522520�020120� 0����������������������������������������������������������������������������������������������������ustar�00constans������������������������users���������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*************************************************************************** * Copyright (C) 2004-2021 by Pere Constans * constans@molspaces.com * cb2Bib version 2.0.1. Licensed under the GNU GPL version 3. * See the LICENSE file that comes with this distribution. ***************************************************************************/ #include "wordMatcher.h" #include "cb2bib_utilities.h" #include "triads.h" #include <limits> wordMatcher::wordMatcher() : _hook(-1), _stretch(0), _substring_count(0), _matched_length(-1), _p0(0), _pn(0) {} wordMatcher::wordMatcher(const QString& pattern, const Qt::CaseSensitivity cs) : _p0(0), _pn(0) { setPattern(pattern, cs); } void wordMatcher::setPattern(const QString& pattern, const Qt::CaseSensitivity cs) { _hook = -1; _matched_length = -1; _stretch = 0; _subpatterns = pattern.split(c2bUtils::nonLetter, QString::SkipEmptyParts); if (_subpatterns.count() == 0) return; _substring_count = _subpatterns.count(); for (int i = 0; i < _substring_count; ++i) _subpatterns[i].replace('_', ' '); _substrings.resize(_substring_count); _lengths.resize(_substring_count); _sp0.resize(_substring_count); for (int i = 0; i < _substring_count; ++i) { _substrings[i] = txtmatcher(_subpatterns.at(i), cs); _lengths[i] = _subpatterns.at(i).length(); if (_lengths.at(i) > 4) _stretch += 50; else _stretch += 10; } for (int i = 0, lf = std::numeric_limits<int>::max(); i < _substring_count; ++i) { const int f(_substrings.at(i).frequency() * triads::textFrequency(_substrings.at(i).pattern())); if (f < lf) { lf = f; _hook = i; } } #ifdef C2B_DEBUG_SEARCHING for (int i = 0; i < _substring_count; ++i) qDebug() << "subpattern " << _substrings.at(i).pattern(); qDebug() << "hook " << _substrings.at(_hook).pattern() << _hook; qDebug() << "_stretch " << _stretch; qDebug() << "subpatternstrings " << subpatternStrings(); #endif } int wordMatcher::indexIn(const QString& text, const int from) const { _matched_length = -1; if (_hook == -1) // Uninitialized return -1; _p0 = from; if (_p0 < 0) _p0 = 0; _pn = text.length(); if (_pn == 0) return -1; int hp(_p0); int p(-1); while (p == -1) { hp = _index_in(_hook, text, hp); if (hp == -1) return -1; p = _index_around(text, hp); hp += _lengths.at(_hook); } return p; } �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������cb2bib-2.0.1/src/c2b/PaxHeaders.5700/txtmatcher.h���������������������������������������������������0000644�0000000�0000000�00000000132�14011522520�016066� x����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������30 mtime=1613145424.770620336 30 atime=1613145424.834620334 30 ctime=1613145424.774620336 ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������cb2bib-2.0.1/src/c2b/txtmatcher.h�������������������������������������������������������������������0000644�0001750�0000144�00000004245�14011522520�017472� 0����������������������������������������������������������������������������������������������������ustar�00constans������������������������users���������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*************************************************************************** * Copyright (C) 2004-2021 by Pere Constans * constans@molspaces.com * cb2Bib version 2.0.1. Licensed under the GNU GPL version 3. * See the LICENSE file that comes with this distribution. ***************************************************************************/ #ifndef TXTMATCHER_H #define TXTMATCHER_H #if defined(__AVX2__) #define C2B_USE_TXTMATCHER_AVX2 1 #elif defined(__SSE2__) #define C2B_USE_TXTMATCHER_SSE2 1 #else #define C2B_USE_TXTMATCHER_SCALAR 1 #endif #include <QString> class txtmatcher { public: txtmatcher(); explicit txtmatcher(const QString& spattern, const Qt::CaseSensitivity cs = Qt::CaseSensitive, const int chook = -1); inline ~txtmatcher() {} void setPattern(const QString& spattern, const Qt::CaseSensitivity cs = Qt::CaseSensitive, const int chook = -1); inline const QString& pattern() const { return _pattern; } inline int frequency() const { return _frequency; } inline int indexIn(const QString& text, const int from = 0) const { return indexIn(text.unicode(), text.size(), from); } int indexIn(const QChar* const text, const int length, const int from) const; private: int _find_case_insensitive(const ushort* const t, const int length, const int from) const; int _find_case_sensitive(const ushort* const t, const int length, const int from) const; #ifdef C2B_USE_TXTMATCHER_SSE2 int _find_case_insensitive_sse2(const ushort* const t, const int length, const int from) const; int _find_case_sensitive_sse2(const ushort* const t, const int length, const int from) const; #endif #ifdef C2B_USE_TXTMATCHER_AVX2 int _find_case_insensitive_avx2(const ushort* const t, const int length, const int from) const; int _find_case_sensitive_avx2(const ushort* const t, const int length, const int from) const; #endif void _set_lowest_frequency_character(const QString& spattern, const bool cs); QString _padded_pattern; QString _pattern; QString _lcp; QString _ucp; bool _case_sensitive; int _chook; int _frequency; }; #endif �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������cb2bib-2.0.1/src/c2b/PaxHeaders.5700/wordPattern.cpp������������������������������������������������0000644�0000000�0000000�00000000132�14011522520�016547� x����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������30 mtime=1613145424.678620338 30 atime=1613145424.834620334 30 ctime=1613145424.686620338 ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������cb2bib-2.0.1/src/c2b/wordPattern.cpp����������������������������������������������������������������0000644�0001750�0000144�00000004110�14011522520�020142� 0����������������������������������������������������������������������������������������������������ustar�00constans������������������������users���������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*************************************************************************** * Copyright (C) 2004-2021 by Pere Constans * constans@molspaces.com * cb2Bib version 2.0.1. Licensed under the GNU GPL version 3. * See the LICENSE file that comes with this distribution. ***************************************************************************/ #include "wordPattern.h" #include "cb2bib_utilities.h" #include "triads.h" wordPattern::wordPattern() : compositePattern(), _type(AllWords) {} wordPattern::wordPattern(const QString& pattern, const Type type, const Qt::CaseSensitivity cs) : compositePattern(pattern, cs), _type(type) { setPattern(pattern, type, cs); } void wordPattern::setPattern(const QString& pattern, const Type type, const Qt::CaseSensitivity cs) { _string = pattern; _type = type; _case_sensitivity = cs; _is_multipattern = false; _matched_length = -1; const QStringList words(_string.split(c2bUtils::nonLetter, QString::SkipEmptyParts)); _subpattern_count = words.count(); if (_subpattern_count == 0) return; _ranks.clear(); QStringList subpattern; QStringList substring; for (int i = 0; i < words.count(); ++i) { const QString& wi = words.at(i); const QString sp(escape(wi, _case_sensitivity)); subpattern.append(sp); substring.append(wi); _ranks.append(triads::textFrequency(wi)); // Rank according expectation (arXiv:0705.0751, Eq. 6) } set_sort_index(); if (_subpattern_count == 1) _regexp.setPattern(escape(_string, _case_sensitivity)); else _regexp.setPattern(QString("(?:%1)").arg(subpattern.join("|"))); _submatchers.resize(_subpattern_count); _subregexps.resize(_subpattern_count); _substrings.clear(); for (int i = 0; i < _subpattern_count; ++i) { const int ii(_index.at(i)); _submatchers[i] = txtmatcher(substring.at(ii), _case_sensitivity); _subregexps[i].setPattern(subpattern.at(ii)); _substrings.append(substring.at(ii)); } _is_multipattern = _subpattern_count > 1; } ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������cb2bib-2.0.1/src/c2b/PaxHeaders.5700/settings.cpp���������������������������������������������������0000644�0000000�0000000�00000000132�14011522520�016076� x����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������30 mtime=1613145424.658620339 30 atime=1613145424.834620334 30 ctime=1613145424.658620339 ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������cb2bib-2.0.1/src/c2b/settings.cpp�������������������������������������������������������������������0000644�0001750�0000144�00000065336�14011522520�017512� 0����������������������������������������������������������������������������������������������������ustar�00constans������������������������users���������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*************************************************************************** * Copyright (C) 2004-2021 by Pere Constans * constans@molspaces.com * cb2Bib version 2.0.1. Licensed under the GNU GPL version 3. * See the LICENSE file that comes with this distribution. ***************************************************************************/ #include "settings.h" #include "cb2bib_utilities.h" #include <QCoreApplication> #include <QDir> /** Global settings for cb2Bib */ settings::settings(const QString& organization, const QString& application, QObject* parento) : QSettings(organization, application, parento) { _init(); } settings::settings(const QString& fn, QObject* parento) : QSettings(fn, QSettings::IniFormat, parento) { _init(); } settings::settings(QObject* parento) : QSettings(C2B_ORGANIZATION, C2B_APPLICATION, parento) { _init(); init(false); } settings::~settings() { _c2b_global_settings = 0; } void settings::init(bool command_line) { if (command_line) readCommandLine(); if (cl_user_configured) _is_usb_configured_mode = QDir::toNativeSeparators(QDir::cleanPath(QSettings::fileName())) == QDir::toNativeSeparators(QDir::cleanPath(_c2bApp->applicationDirPath() + '/' + "cb2bib.conf")); else _is_usb_configured_mode = false; if (_is_usb_configured_mode) { _c2bAppDir = QDir(_c2bApp->applicationDirPath()); _tmp_dir_path = _c2bApp->applicationDirPath(); } else { // Use user's home as tmp_dir since tmp files are more accessible if they are needed, // for instance, for debugging netqinf // Using cb2bib remotely causes tmp_dir not being writable, fallback to machine's tmp const QFileInfo hpi(QDir::homePath()); if (hpi.exists() && hpi.isWritable()) _tmp_dir_path = QDir::homePath(); else _tmp_dir_path = QDir::tempPath(); } setDefaults(); // Set relative to BibTeX file in USB mode, overriding defaults. if (_is_usb_configured_mode) setValue("cb2Bib/RelativePdfDirectory", true); } void settings::_init() { _c2bApp = QCoreApplication::instance(); Q_ASSERT_X(_c2bApp, "settings", "application was not instantiated"); Q_ASSERT_X(!_c2b_global_settings, "settings", "settings already instantiated"); settings::_c2b_global_settings = this; _application_pid = QString::number(_c2bApp->applicationPid()); _is_loaded = true; cl_bibedit = false; cl_cb2bib_import_mode = false; cl_cb2bib_information = false; cl_cb2bib_tests = false; cl_citer = false; cl_configure = false; cl_doc2bib = false; cl_html_annote = false; cl_import = false; cl_index = false; cl_sloppy = false; cl_txt2bib = false; cl_user_configured = false; cl_view_annote = false; } void settings::setDefaultValue(const QString& key, const QVariant& defaulValue) { // Makes sure a key is initialized setValue(key, value(key, defaulValue)); } void settings::setDefaults() { QHash<QString, QVariant> defaults; const QString dsep(QDir::separator()); // Files defaults["cb2Bib/BibTeXFile"] = QDir::cleanPath(QDir::homePath() + dsep + "references.bib"); defaults["cb2Bib/CacheDirectory"] = QDir::cleanPath(QDir::homePath() + dsep + "PdfDocuments" + dsep + "c2b.tmp"); defaults["cb2Bib/PdfDirectory"] = QDir::cleanPath(QDir::homePath() + dsep + "PdfDocuments"); #if defined(Q_OS_WIN) const QString C2B_APP_DIR(_c2bApp->applicationDirPath() + dsep); defaults["c2bAnnote/AnnoteCssFile"] = C2B_APP_DIR + "data\\tex2html.css"; defaults["c2bAnnote/MathJaxHeaderFile"] = C2B_APP_DIR + "data\\tex2html_mathjax_header.html"; defaults["c2bBibSearcher/Pdf2TextBin"] = C2B_APP_DIR + "externtools\\xpdf\\pdf2cb.exe"; defaults["c2bPdfImport/LastFile"] = C2B_APP_DIR + "testPDFImport\\nomeaning1.pdf"; defaults["c2bPdfImport/Pdf2TextBin"] = C2B_APP_DIR + "externtools\\xpdf\\pdf2cb.exe"; defaults["cb2Bib/BrowserCssFile"] = C2B_APP_DIR + "data\\references.css"; defaults["cb2Bib/JournalFile"] = C2B_APP_DIR + "data\\abbreviations.txt"; defaults["cb2Bib/NetworkFile"] = C2B_APP_DIR + "data\\netqinf.txt"; defaults["cb2Bib/PosLexiconFile"] = C2B_APP_DIR + "data\\lexicon.pos"; defaults["cb2Bib/PostprocessBibTeXBin"] = C2B_APP_DIR + C2B_POSTPROCESS_BIBTEX_BIN; defaults["cb2Bib/PreparserBin"] = C2B_APP_DIR + "c2btools\\ris2bib.bat"; defaults["cb2Bib/RegularExpressionFile"] = C2B_APP_DIR + "data\\regexps.txt"; #elif defined(Q_OS_MACOS) QString C2B_DATA_DIR_MAC(C2B_DATA_DIR); if (QDir(C2B_DATA_DIR + "/data/").exists()) C2B_DATA_DIR_MAC = QDir::cleanPath(C2B_DATA_DIR + '/'); else if (QDir(_c2bApp->applicationDirPath() + "/../Resources/data/").exists()) C2B_DATA_DIR_MAC = QDir::cleanPath(_c2bApp->applicationDirPath() + "/../Resources/"); defaults["c2bAnnote/AnnoteCssFile"] = QDir::cleanPath(C2B_DATA_DIR_MAC + "/data/tex2html.css"); defaults["c2bAnnote/MathJaxHeaderFile"] = QDir::cleanPath(C2B_DATA_DIR_MAC + "/data/tex2html_local_mathjax_header.html"); defaults["c2bBibSearcher/Pdf2TextBin"] = QDir::cleanPath(C2B_BIBSEARCHER_PDF2TXT_BIN); defaults["c2bPdfImport/LastFile"] = QDir::cleanPath(C2B_DATA_DIR_MAC + "/testPDFImport/nomeaning1.pdf"); defaults["c2bPdfImport/Pdf2TextBin"] = QDir::cleanPath(C2B_PDFIMPORT_PDF2TXT_BIN); defaults["cb2Bib/BrowserCssFile"] = QDir::cleanPath(C2B_DATA_DIR_MAC + "/data/references.css"); defaults["cb2Bib/ExifToolBin"] = QDir::cleanPath(C2B_METADATAPARSER_EXIFTOOL_BIN); defaults["cb2Bib/JournalFile"] = QDir::cleanPath(C2B_DATA_DIR_MAC + "/data/abbreviations.txt"); defaults["cb2Bib/NetworkFile"] = QDir::cleanPath(C2B_DATA_DIR_MAC + "/data/netqinf.txt"); defaults["cb2Bib/PosLexiconFile"] = QDir::cleanPath(C2B_DATA_DIR_MAC + dsep + "data/lexicon.pos"); defaults["cb2Bib/PostprocessBibTeXBin"] = QDir::cleanPath(C2B_DATA_DIR_MAC + C2B_POSTPROCESS_BIBTEX_BIN); defaults["cb2Bib/PreparserBin"] = QDir::cleanPath(C2B_DATA_DIR_MAC + "/c2btools/ris2bib"); defaults["cb2Bib/RegularExpressionFile"] = QDir::cleanPath(C2B_DATA_DIR_MAC + "/data/regexps.txt"); #else // Q_OS_UNIX defaults["c2bAnnote/AnnoteCssFile"] = QDir::cleanPath(C2B_DATA_DIR + dsep + "data/tex2html.css"); defaults["c2bAnnote/MathJaxHeaderFile"] = QDir::cleanPath(C2B_DATA_DIR + dsep + "data/tex2html_local_mathjax_header.html"); defaults["c2bBibSearcher/Pdf2TextBin"] = QDir::cleanPath(C2B_BIBSEARCHER_PDF2TXT_BIN); defaults["c2bPdfImport/LastFile"] = QDir::cleanPath(C2B_DATA_DIR + dsep + "testPDFImport/nomeaning1.pdf"); defaults["c2bPdfImport/Pdf2TextBin"] = QDir::cleanPath(C2B_PDFIMPORT_PDF2TXT_BIN); defaults["cb2Bib/BrowserCssFile"] = QDir::cleanPath(C2B_DATA_DIR + dsep + "data/references.css"); defaults["cb2Bib/ExifToolBin"] = QDir::cleanPath(C2B_METADATAPARSER_EXIFTOOL_BIN); defaults["cb2Bib/JournalFile"] = QDir::cleanPath(C2B_DATA_DIR + dsep + "data/abbreviations.txt"); defaults["cb2Bib/NetworkFile"] = QDir::cleanPath(C2B_DATA_DIR + dsep + "data/netqinf.txt"); defaults["cb2Bib/PosLexiconFile"] = QDir::cleanPath(C2B_DATA_DIR + dsep + "data/lexicon.pos"); defaults["cb2Bib/PostprocessBibTeXBin"] = QDir::cleanPath(C2B_DATA_DIR + dsep + C2B_POSTPROCESS_BIBTEX_BIN); defaults["cb2Bib/PreparserBin"] = QDir::cleanPath(C2B_DATA_DIR + dsep + "c2btools/ris2bib"); defaults["cb2Bib/RegularExpressionFile"] = QDir::cleanPath(C2B_DATA_DIR + dsep + "data/regexps.txt"); #endif // External file manager defaults["cb2Bib/FmClient"] = false; defaults["cb2Bib/FmClientCopyArg"] = C2B_FM_CLIENT_COPY_ARG; defaults["cb2Bib/FmClientCopyBin"] = QDir::cleanPath(C2B_FM_CLIENT_COPY_BIN); defaults["cb2Bib/FmClientMoveArg"] = C2B_FM_CLIENT_MOVE_ARG; defaults["cb2Bib/FmClientMoveBin"] = QDir::cleanPath(C2B_FM_CLIENT_MOVE_BIN); // Proxy defaults["cb2Bib/UseProxy"] = false; defaults["cb2Bib/ProxyPort"] = 8080; defaults["cb2Bib/ProxyType"] = 0; // Postprocess BibTeX defaults["cb2Bib/PostprocessBibTeXArg"] = C2B_POSTPROCESS_BIBTEX_ARG; defaults["cb2Bib/PostprocessBibTeXExt"] = C2B_POSTPROCESS_BIBTEX_EXT; // Misc defaults["c2bAnnote/IncludeCSS"] = true; defaults["c2bAnnote/UseRelativeLinks"] = false; defaults["cb2Bib/AddMetadata"] = true; defaults["cb2Bib/AutomaticPdfDownload"] = false; defaults["cb2Bib/AutomaticQuery"] = false; defaults["cb2Bib/CheckRepeatedOnSave"] = false; defaults["cb2Bib/CiteCommandPattern"] = C2B_CITE_COMMAND_PATTERN; defaults["cb2Bib/CiteIdPattern"] = C2B_CITE_ID_PATTERN; defaults["cb2Bib/ConvertReferenceToLaTeX"] = true; defaults["cb2Bib/CopyMovePdf"] = "copy"; defaults["cb2Bib/DoHeuristicGuess"] = true; defaults["cb2Bib/DocumentIdPattern"] = C2B_DOCUMENT_ID_PATTERN; defaults["cb2Bib/FindReplaceInput"] = true; defaults["cb2Bib/FindReplaceInputList"] = QString(C2B_FIND_REPLACE_LIST).split("^e"); defaults["cb2Bib/InsertMetadata"] = false; defaults["cb2Bib/KeepTmpNQFiles"] = false; defaults["cb2Bib/MovePdf"] = false; defaults["cb2Bib/PageNumberSeparator"] = " - "; defaults["cb2Bib/PostprocessMonth"] = false; defaults["cb2Bib/PreAppendMetadata"] = "prepend"; defaults["cb2Bib/PreparserAutomatic"] = false; defaults["cb2Bib/PreparserShowLog"] = true; defaults["cb2Bib/RelativePdfDirectory"] = false; defaults["cb2Bib/SetJournalsToFullname"] = false; defaults["cb2Bib/UseDoubleBraces"] = true; defaults["cb2Bib/UseFullNames"] = false; // Pdf2Text arguments defaults["c2bBibSearcher/Pdf2TextArg"] = "-q"; defaults["c2bPdfImport/Pdf2TextArg"] = "-q -f 1 -l 1"; // Construct current settings const QStringList keys(defaults.keys()); for (int i = 0; i < keys.count(); ++i) setValue(keys.at(i), value(keys.at(i), defaults.value(keys.at(i)))); } QString settings::applicationDataDir() const { // Base application data dir containing ./data/ ./doc/ ./c2btools/ #if defined(Q_OS_WIN) const QString app_data_dir(_c2bApp->applicationDirPath()); #elif defined(Q_OS_MACOS) QString app_data_dir(C2B_DATA_DIR); if (!QDir(app_data_dir).exists()) app_data_dir = _c2bApp->applicationDirPath() + "/../Resources/"; #else // Q_OS_UNIX const QString app_data_dir(C2B_DATA_DIR); #endif if (QDir(app_data_dir + "/data/").exists()) return QDir::cleanPath(app_data_dir); else return QString(); } settings* settings::_c2b_global_settings = 0; /*************************************************************************** * Command line processing ***************************************************************************/ /** \page commandline cb2Bib Command Line The complete listing of command line uses follows. \htmlonly <pre style="font-size: xx-small;"> Usage: cb2bib cb2bib [action] [filename1 [filename2 ... ]] [--conf [filename.conf]] Actions: --configure [filename.conf] Edit configuration --bibedit [filename1.bib [filename2.bib ... ]] Edit/browse BibTeX files --citer [filename1.bib [filename2.bib ... ]] Start cb2Bib citer --import tmp_reference_filename Import reference, usually from ad hoc websites --doc2bib fn1.doc [fn2.doc ... ] reference.bib Extract reference from document file --txt2bib fn1.txt [fn2.txt ... ] reference.bib Extract reference from text file --index [bibdirname] Extract keywords from document files --html-annote filename.tex Convert annote file to HTML --view-annote filename.tex Convert and visualize annote file --view-annote filename.tex.html Visualize annote file Switches: --conf [filename.conf] Use configuration file --sloppy Accept guesses in automatic reference extraction Examples: cb2bib Start cb2Bib extraction panel cb2bib --import tmp_reference_filename Import reference cb2bib --bibedit filename.bib Edit BibTeX filename.bib cb2bib --conf Start cb2Bib in USB mode cb2bib --doc2bib *.pdf references.bib Extract references from PDF title pages Notes: -Use switch --conf to particularize specific settings for specific actions. -The file cb2bib.conf must be readable and writable. If it does not exist, cb2Bib will create one based on predefined defaults. -If starting cb2Bib from a removable media, use the command 'cb2bib --conf' without configuration filename. Settings will be read from and written to /cb2bib/full/path/cb2bib.conf, being therefore independent of the mounting address that the host computer will provide. -To import references from a browser select when asked c2bimport, which expands to 'cb2bib --import %f'. The browser will provide the temporary reference filename. -A number of factors influence the reliability of automatic extractions. Consider writing customized regular expressions and network queries, and use metadata when available. Important: -The commands --doc2bib and --txt2bib do not append the references to the references.bib. They create a new file, or silently overwrite it if already exists. </pre> \endhtmlonly - <b>Note:</b> On Windows use <tt>c2bconsole</tt> instead of <tt>cb2bib</tt>. See \ref relnotes130. - <b>Note:</b> If using reference extraction command, see \ref faq_automatic_extraction. */ bool settings::isConsoleMode(const int argc, char** argv) { for (int i = 0; i < argc; ++i) if (strcmp(argv[i], "--html-annote") == 0 || strcmp(argv[i], "--doc2bib") == 0 || strcmp(argv[i], "--txt2bib") == 0 || strcmp(argv[i], "--index") == 0 || strcmp(argv[i], "--c2binfo") == 0 || strcmp(argv[i], "--test") == 0) return true; return false; } bool settings::isSingleApplicationMode(const int argc, char** argv) { for (int i = 0; i < argc; ++i) if (strcmp(argv[i], "--citer") == 0) return true; return false; } bool settings::isConfiguredMode() { const QCoreApplication* capp = QCoreApplication::instance(); const QStringList argv(capp->arguments()); const int argc(argv.count()); if (argc > 1) { for (int i = 1; i < argc; ++i) if (argv.at(i) == "--conf") return true; for (int i = 1; i < argc; ++i) if (argv.at(i) == "--configure") { const int j(i + 1); if (j < argc) if (!argv.at(j).startsWith('-')) return true; return false; } } return false; } const QString settings::configuredFilename() { const QCoreApplication* capp = QCoreApplication::instance(); QStringList arguments(capp->arguments()); arguments.removeAll(QString()); const int argc(arguments.count()); QString filename; for (int i = 1; i < argc - 1; ++i) if (arguments.at(i) == "--conf" || arguments.at(i) == "--configure") { const int j(i + 1); if (!arguments.at(j).startsWith('-')) filename = QFile::decodeName(arguments.at(j).toLocal8Bit()); break; } if (filename.isEmpty()) filename = capp->applicationDirPath() + QDir::separator() + "cb2bib.conf"; QFileInfo fi(filename); if (fi.isDir()) { c2bUtils::warn(QObject::tr("Error: Could not open %1 configuration file for reading/writing").arg(filename)); c2bUtils::warn(QObject::tr("Error: Filename is a directory")); exit(1); } QFile file(filename); if (!file.open(QIODevice::ReadWrite | QIODevice::Text)) { c2bUtils::warn(QObject::tr("Error: Could not open %1 configuration file for reading/writing").arg(filename)); c2bUtils::warn(QObject::tr("Error: %1.").arg(file.errorString())); exit(1); } return filename; } void settings::readCommandLine() { QStringList arguments(_c2bApp->arguments()); arguments.removeAll(QString()); int actions(0); for (int i = 1; i < arguments.count(); ++i) if (arguments.at(i).startsWith('-')) { // switches if (arguments.at(i) == "--conf") { checkCommand(&cl_user_configured, &actions); _conf_command_flags.append("--conf"); const int j(i + 1); if (j < arguments.count() && !arguments.at(j).startsWith('-')) _conf_command_flags.append(arguments.at(j)); --actions; } else if (arguments.at(i) == "--sloppy") { checkCommand(&cl_sloppy, &actions); --actions; } // actions else if (arguments.at(i) == "--configure") checkCommand(&cl_configure, &actions); else if (arguments.at(i) == "--bibedit") checkCommand(&cl_bibedit, &actions); else if (arguments.at(i) == "--citer") checkCommand(&cl_citer, &actions); else if (arguments.at(i) == "--import") checkCommand(&cl_import, &actions); else if (arguments.at(i) == "--html-annote") checkCommand(&cl_html_annote, &actions); else if (arguments.at(i) == "--view-annote") checkCommand(&cl_view_annote, &actions); else if (arguments.at(i) == "--doc2bib") checkCommand(&cl_doc2bib, &actions); else if (arguments.at(i) == "--txt2bib") checkCommand(&cl_txt2bib, &actions); else if (arguments.at(i) == "--index") checkCommand(&cl_index, &actions); else if (arguments.at(i) == "--c2binfo") cl_cb2bib_information = true; else if (arguments.at(i).startsWith("--test")) cl_cb2bib_tests = true; else _is_loaded = false; } if (actions > 1) _is_loaded = false; if (cl_user_configured && cl_configure) _is_loaded = false; if (cl_sloppy && !(cl_doc2bib || cl_txt2bib)) _is_loaded = false; if (cl_index && (cl_bibedit || cl_citer || cl_import || cl_html_annote || cl_view_annote || cl_doc2bib || cl_txt2bib)) _is_loaded = false; if (!_is_loaded) { printUsage(); return; } cl_console_mode = cl_html_annote || cl_cb2bib_information || cl_cb2bib_tests || cl_doc2bib || cl_txt2bib || cl_index; cl_cb2bib_mode = !(cl_console_mode || cl_configure || cl_view_annote); // Check for cl_user_configured if (cl_configure) for (int i = 1; i < arguments.count() - 1; ++i) if (arguments.at(i) == "--configure") { if (!arguments.at(i + 1).startsWith('-')) cl_user_configured = true; break; } // Check for --bibedit files if (cl_bibedit) { for (int i = 1; i < arguments.count(); ++i) if (arguments.at(i) == "--bibedit") { for (int j = i + 1; j < arguments.count(); ++j) if (arguments.at(j).startsWith('-')) break; else cl_bibedit_filenames.append(decodeFilename(arguments.at(j))); break; } if (cl_bibedit_filenames.count() == 0) cl_bibedit = false; else setValue("cb2Bib/BibTeXFile", cl_bibedit_filenames.first()); } // Check for --citer files else if (cl_citer) { for (int i = 1; i < arguments.count(); ++i) if (arguments.at(i) == "--citer") { for (int j = i + 1; j < arguments.count(); ++j) if (arguments.at(j).startsWith('-')) break; else cl_citer_filenames.append(decodeFilename(arguments.at(j))); break; } } // Check for --index BibTeX dirname else if (cl_index) { for (int i = 1; i < arguments.count(); ++i) if (arguments.at(i) == "--index") { const int j(i + 1); if (j < arguments.count() && !arguments.at(j).startsWith('-')) cl_index_dirname.append(decodeFilename(arguments.at(j))); break; } } // Check for annote file else if (cl_html_annote || cl_view_annote) { for (int i = 1; i < arguments.count(); ++i) if (arguments.at(i) == "--html-annote" || arguments.at(i) == "--view-annote") { const int j(i + 1); if (j < arguments.count()) if (!arguments.at(j).startsWith('-')) cl_annote_filename = decodeFilename(arguments.at(j)); if (cl_annote_filename.isEmpty()) _is_loaded = false; } } // Check for extraction files else if (cl_doc2bib || cl_txt2bib) { for (int i = 1; i < arguments.count(); ++i) if (arguments.at(i) == "--doc2bib" || arguments.at(i) == "--txt2bib") { for (int j = i + 1; j < arguments.count(); ++j) if (arguments.at(j).startsWith('-')) break; else cl_extract_input_filenames.append(decodeFilename(arguments.at(j))); break; } if (cl_extract_input_filenames.count() < 2) _is_loaded = false; else cl_extract_output_filename = cl_extract_input_filenames.takeLast(); } // Check for import reference file else if (cl_import) { if (arguments.count() > 2) if (!arguments.at(2).startsWith('-')) { cl_import_filename = QFileInfo(QFile::decodeName(arguments.at(2).toLocal8Bit())).absoluteFilePath(); return; } cl_import = false; _is_loaded = false; } // Accept also 'cb2bib filename' as '--import' to ease import on Windows else if (arguments.count() > 1) if (!arguments.at(1).startsWith('-')) { cl_import_filename = QFileInfo(QFile::decodeName(arguments.at(1).toLocal8Bit())).absoluteFilePath(); cl_import = true; return; } if (!_is_loaded) printUsage(); } void settings::checkCommand(bool* action, int* actions) { if (*action) _is_loaded = false; *action = true; *actions += 1; } QString settings::decodeFilename(const QString& fn) const { // This function is meant for fn given by the command shell and that will end up being visible return QDir::toNativeSeparators(QFileInfo(QFile::decodeName(fn.toLocal8Bit())).absoluteFilePath()); } void settings::printUsage() { fprintf(stdout, "Usage: cb2bib\n"); fprintf(stdout, " cb2bib [action] [filename1 [filename2 ... ]] [--conf [filename.conf]]\n"); fprintf(stdout, "\n"); fprintf(stdout, "Actions:\n"); fprintf(stdout, " --configure [filename.conf] Edit configuration\n"); fprintf(stdout, "\n"); fprintf(stdout, " --bibedit [filename1.bib [filename2.bib ... ]] Edit/browse BibTeX files\n"); fprintf(stdout, " --citer [filename1.bib [filename2.bib ... ]] Start cb2Bib citer\n"); fprintf( stdout, " --import tmp_reference_filename Import reference, usually from ad hoc websites\n"); fprintf(stdout, "\n"); fprintf(stdout, " --doc2bib fn1.doc [fn2.doc ... ] reference.bib Extract reference from document file\n"); fprintf(stdout, " --txt2bib fn1.txt [fn2.txt ... ] reference.bib Extract reference from text file\n"); fprintf(stdout, "\n"); fprintf(stdout, " --index [bibdirname] Extract keywords from document files\n"); fprintf(stdout, "\n"); fprintf(stdout, " --html-annote filename.tex Convert annote file to HTML\n"); fprintf(stdout, " --view-annote filename.tex Convert and visualize annote file\n"); fprintf(stdout, " --view-annote filename.tex.html Visualize annote file\n"); fprintf(stdout, "\n"); fprintf(stdout, "Switches:\n"); fprintf(stdout, " --conf [filename.conf] Use configuration file\n"); fprintf( stdout, " --sloppy Accept guesses in automatic reference extraction\n"); fprintf(stdout, "\n"); fprintf(stdout, "Examples:\n"); fprintf(stdout, " cb2bib Start cb2Bib extraction panel\n"); fprintf(stdout, " cb2bib --import tmp_reference_filename Import reference\n"); fprintf(stdout, " cb2bib --bibedit filename.bib Edit BibTeX filename.bib\n"); fprintf(stdout, " cb2bib --conf Start cb2Bib in USB mode\n"); fprintf(stdout, " cb2bib --doc2bib *.pdf references.bib Extract references from PDF title pages\n"); fprintf(stdout, "\n"); fprintf(stdout, "Notes:\n"); fprintf(stdout, " -Use switch --conf to particularize specific settings for specific actions.\n"); fprintf(stdout, " -The file cb2bib.conf must be readable and writable. If it does not exist, cb2Bib will create one\n"); fprintf(stdout, " based on predefined defaults.\n"); fprintf(stdout, " -If starting cb2Bib from a removable media use, the command 'cb2bib --conf' without configuration\n"); fprintf(stdout, " filename. Settings will be read from and written to /cb2bib/full/path/cb2bib.conf, being therefore\n"); fprintf(stdout, " independent of the mounting address that the host computer will provide.\n"); fprintf( stdout, " -To import references from a browser select when asked c2bimport, which expands to 'cb2bib --import %%f'.\n"); fprintf(stdout, " The browser will provide the temporary reference filename.\n"); fprintf(stdout, " -A number of factors influence the reliability of automatic extractions. Consider writing customized\n"); fprintf(stdout, " regular expressions and network queries, and use metadata when available.\n"); fprintf(stdout, "\n"); fprintf(stdout, "Important:\n"); fprintf(stdout, " -The commands --doc2bib and --txt2bib do not append the references to the references.bib. They create\n"); fprintf(stdout, " a new file, or silently overwrite it if already exists.\n"); fprintf(stdout, "\n"); } ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������cb2bib-2.0.1/src/c2b/PaxHeaders.5700/htm������������������������������������������������������������0000644�0000000�0000000�00000000074�14011522151�014252� x����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������30 atime=1613145424.834620334 30 ctime=1613145424.302620349 ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������cb2bib-2.0.1/src/c2b/htm/���������������������������������������������������������������������������0000755�0001750�0000144�00000000000�14011522151�015721� 5����������������������������������������������������������������������������������������������������ustar�00constans������������������������users���������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������cb2bib-2.0.1/src/c2b/htm/PaxHeaders.5700/tex2html.css�����������������������������������������������0000644�0000000�0000000�00000000074�14011522151�016610� x����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������30 atime=1613145424.366620347 30 ctime=1613145424.298620349 ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������cb2bib-2.0.1/src/c2b/htm/tex2html.css���������������������������������������������������������������0000644�0001750�0000144�00000005534�14011522151�020211� 0����������������������������������������������������������������������������������������������������ustar�00constans������������������������users���������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* cb2Bib Annote CSS */ /* general */ body { background-color: #E7E7E7; border-color: #72726A; border-style: solid; border-width: 1px; color: black; margin: 1px; padding-left: 25px; padding-right: 25px; padding-top: 25px; } h1 { background-color: #010141; border-color: black; border-style: solid; border-width: 1px; color: #E3E3E3; font-family: sans-serif; font-size: 120%; padding-left: 10px; } h2 { color: #010141; font-family: sans-serif; font-size: 110%; padding-left: 10px; } h3 { color: #010141; font-family: sans-serif; font-size: 100%; font-style: italic; padding-left: 10px; } a { color: #293747; font-size: 100%; text-decoration: underline; } p { padding-right: 20px; text-indent: 20px; } pre { background-color: #DBDBDB; border-color: #72726A; border-style: solid; border-width: 1px; font-family: monospace; font-size: 80%; padding: 10px; } ul li { list-style-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAsAAAAJCAYAAADkZNYtAAAABGdBTUEAANbY1E9YMgAAAAZiS0dEAP8A/wD/oL2nkwAAAAlwSFlzAAALEwAACxMBAJqcGAAAAAd0SU1FB9gMCBQ5B7ky4rkAAAFHSURBVBjTTcoxasJQAIDhPy8JlfCKGpe+LIUuQhAnN0FEikcodOvSnqCLV+lYEA/QCi4GnERyhE5FsGoCDgZ9oMnr0pZ+8G+/xQ+lVLXVaj31+/378/lsOY5jJpPJaDabvWRZtuMfv9PpjKIoMkmSmDRNzXa7NdPp1LTb7RHgA9iACILgcTAYPFerVbTWaK3Z7XbkeU69Xm/M5/OvLMtiAbjNZvPO8zy01uz3+7+01nieR6PRuANcB3CVUje1Wg0pJa7rYts2eZ5zOp0olUoEQXDzO4skSVa+719JKXPLsizbtjHGACCEEJvNZgUIARSLxWK8Xq+RUtrlcllIKUWlUhFSSrFcLonjeAwUABdA2O12J3Ecm8PhYLTW5ng8miiKTBiGb0AIXFiAAC6VUqHv+w+9Xu/WcZzroig+h8Phe5qmr8AHkH0DzH6Pqv7Vyi4AAAAASUVORK5CYII=); padding-right: 100px; text-indent: 15px; } /* header */ .header { vertical-align: middle; } /* footer */ .footer { color: black; font-family: arial, sans-serif; font-size: 50%; } .footer td { padding: 10px; padding-left: 5px; padding-right: 5px; } .footer a { color: #293747; font-weight: bold; text-decoration: underline; } /* index */ .index { background-color: #DBDBDB; border-color: #72726A; border-style: solid; border-width: 1px; font-family: sans-serif; font-size: 80%; } .index a { color: #293747; font-weight: bold; text-decoration: none; } .index a:hover { color: #010141; font-weight: bold; text-decoration: none; } .index ul li { list-style-image: none; } /* abstract */ #abstract { background-color: #DBDBDB; border-color: #72726A; border-style: solid; border-width: 1px; font-size: 95%; font-style: italic; padding-bottom: 10px; padding-left: 50px; padding-right: 70px; padding-top: 10px; text-indent: 20px; } /* citations */ .citations { font-size: 80%; } .citations a { text-decoration: none; } .citations a:active { color: #010141; text-decoration: none; } /* references */ .references { font-size: 80%; font-family: sans-serif; padding-right: 50px; } .references a { color: black; text-decoration: none; } .references a:link { color: #293747; font-weight: bold; text-decoration: none; } .references a:visited { color: #293747; font-weight: bold; text-decoration: none; }��������������������������������������������������������������������������������������������������������������������������������������������������������������������cb2bib-2.0.1/src/c2b/htm/PaxHeaders.5700/tex2html.html����������������������������������������������0000644�0000000�0000000�00000000074�14011522151�016764� x����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������30 atime=1613145424.834620334 30 ctime=1613145424.302620349 ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������cb2bib-2.0.1/src/c2b/htm/tex2html.html��������������������������������������������������������������0000644�0001750�0000144�00000002143�14011522151�020356� 0����������������������������������������������������������������������������������������������������ustar�00constans������������������������users���������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html;charset=UTF-8"/> GET_CSS GET_MATHJAX_HEAD <title>GET_TITLE

GET_TITLE



GET_INDEX GET_HTML GET_REFERENCES
cb2bib-2.0.1/src/c2b/htm/PaxHeaders.5700/tex2html_index.html0000644000000000000000000000007414011522151020153 xustar0030 atime=1613145424.834620334 30 ctime=1613145424.302620349 cb2bib-2.0.1/src/c2b/htm/tex2html_index.html0000644000175000001440000000005714011522151021547 0ustar00constansusers00000000000000
%1

cb2bib-2.0.1/src/c2b/htm/PaxHeaders.5700/reference_item.html0000644000000000000000000000007414011522151020171 xustar0030 atime=1613145424.834620334 30 ctime=1613145424.298620349 cb2bib-2.0.1/src/c2b/htm/reference_item.html0000644000175000001440000000037314011522151021566 0ustar00constansusers00000000000000
  • GET_REFERENCE_AUTHOR GET_REFERENCE_TITLE. GET_REFERENCE_SOURCE GET_REFERENCE_VOLUMEGET_REFERENCE_PAGES GET_REFERENCE_YEAR
  • cb2bib-2.0.1/src/c2b/htm/PaxHeaders.5700/reference_list.html0000644000000000000000000000007414011522151020206 xustar0030 atime=1613145424.834620334 30 ctime=1613145424.298620349 cb2bib-2.0.1/src/c2b/htm/reference_list.html0000644000175000001440000000011014011522151021570 0ustar00constansusers00000000000000

      GET_REFERENCES
    cb2bib-2.0.1/src/c2b/PaxHeaders.5700/network.h0000644000000000000000000000013214011522520015374 xustar0030 mtime=1613145424.738620337 30 atime=1613145424.834620334 30 ctime=1613145424.738620337 cb2bib-2.0.1/src/c2b/network.h0000644000175000001440000000652314011522520017001 0ustar00constansusers00000000000000/*************************************************************************** * Copyright (C) 2004-2021 by Pere Constans * constans@molspaces.com * cb2Bib version 2.0.1. Licensed under the GNU GPL version 3. * See the LICENSE file that comes with this distribution. ***************************************************************************/ #ifndef NETWORK_H #define NETWORK_H #include #include #include #include #include /** cb2Bib Network file copy/move @author Pere Constans */ class network : public QObject { Q_OBJECT public: explicit network(QObject* parento = 0); inline ~network() {} enum Action { Copy, Move }; void getFile(const QString& source, const QString& destination, const Action action = Copy, QObject* receiver = 0, const char* callback = 0, const bool overwrite = false); void headFile(const QString& source, QObject* receiver = 0, const char* callback = 0); inline const QString destinationFilename() const { return _destination_filename; } inline const QString sourceFilename() const { return _source_filename; } inline const QString errorString() const { return _request_error_string; } inline const QString mimetypeString() const { return _file_mimetype_string; } static inline Action actionType(const QString& action) { return action == "move" ? Move : Copy; } signals: void downloadProgress(qint64 bytesReceived, qint64 bytesTotal); void proxyAuthenticationRequired(const QNetworkProxy& proxy, QAuthenticator* auth); void requestFinished(bool succeeded); public slots: void cancelDownload(); private: QByteArray _fetch_url_query; QFile _destination_file; QNetworkAccessManager* _fetcher; QNetworkAccessManager::Operation _fetch_operation; QNetworkReply* _current_reply; QProcess* _fetcher_client; QString FmClientCopyArg; QString FmClientCopyBin; QString FmClientMoveArg; QString FmClientMoveBin; QString _destination_filename; QString _file_mimetype_string; QString _request_error_string; QString _source_filename; bool FmClient; bool _is_fetching; bool _request_succeeded; bool checkDestination(); const int _max_redirections; int _redirection_count; void _emit_request_finished(bool succeeded); void _fetch(const QUrl& url); void _fetch_c2b(const Action action, const QNetworkAccessManager::Operation operation = QNetworkAccessManager::GetOperation); void _fetch_client(const Action action); void _head(const QUrl& url); void getFilePrivate(const Action action); void headFilePrivate(); inline void setup(const QString& source, const QString& destination = QString()) { _destination_filename = destination; _source_filename = source; _file_mimetype_string.clear(); _request_error_string.clear(); _is_fetching = true; _redirection_count = 0; } private slots: void _client_finished(int exitCode, QProcess::ExitStatus exitStatus); void _emit_request_finished(); void _fetch_finished(); void _fetch_ready_read(); void _head_finished(); void loadSettings(); void logError(); }; #endif cb2bib-2.0.1/src/c2b/PaxHeaders.5700/bibParser.cpp0000644000000000000000000000013214011522520016147 xustar0030 mtime=1613145424.590620341 30 atime=1613145424.830620334 30 ctime=1613145424.590620341 cb2bib-2.0.1/src/c2b/bibParser.cpp0000644000175000001440000006246414011522520017562 0ustar00constansusers00000000000000/*************************************************************************** * Copyright (C) 2004-2021 by Pere Constans * constans@molspaces.com * cb2Bib version 2.0.1. Licensed under the GNU GPL version 3. * See the LICENSE file that comes with this distribution. ***************************************************************************/ #include "bibParser.h" #include "arxivXml.h" #include "bibPreparser.h" #include "crJson.h" #include "document.h" #include "heuristicBibParser.h" #include "idMaker.h" #include "preprocess.h" #include "pubmedXml.h" #include "settings.h" #include #include bibParser::bibParser(QObject* parento) : coreBibParser(parento) { // Creating journal name database _journal_dbP = new journalDB(_settingsP->fileName("cb2Bib/JournalFile")); // Creating month list _month_dbP = new monthDB(); // Creating cite and document ID makers _cite_idmP = new idMaker("cb2Bib/CiteIdPattern", this); _file_idmP = new idMaker("cb2Bib/DocumentIdPattern", this); // Creating (external) reference preparser _preparserP = new bibPreparser(this); connect(_preparserP, SIGNAL(statusMessage(QString)), this, SIGNAL(statusMessage(QString))); // Creating stream preprocess object _preprocessP = new preprocess(this); // Creating heuristic bibliographic parser _heuristic_parserP = new heuristicBibParser(this); } bibParser::~bibParser() { delete _journal_dbP; delete _month_dbP; delete _heuristic_parserP; } /** Process each field and set its final format */ QString bibParser::parse(const QString& field, const QString& value, const QString& init_value) { QString v(value); if (field == QLatin1String("file")) return v.trimmed(); if (field == "abstract") document::normalize(v, document::Complete); v = removeTags(v); if (v.isEmpty()) return v; c2bUtils::fullBibToC2b(v); if (field == QLatin1String("author")) { c2bUtils::debug(v); v = _authorString.toBibTeX(v, _settingsP->value("cb2Bib/UseFullNames").toBool()); } else if (field == QLatin1String("addauthors")) { c2bUtils::debug(v); if (init_value.isEmpty()) v = _authorString.toBibTeX(v, _settingsP->value("cb2Bib/UseFullNames").toBool()); else v = init_value + " and " + _authorString.toBibTeX(v, _settingsP->value("cb2Bib/UseFullNames").toBool()); } else if (field == QLatin1String("editor")) { c2bUtils::debug(v); v.remove(QRegExp("\\((Editor|Editors|Ed|Eds)\\.{0,1}\\)", Qt::CaseInsensitive)); v = _authorString.toBibTeX(v, _settingsP->value("cb2Bib/UseFullNames").toBool()); } else if (field == QLatin1String("addeditors")) { c2bUtils::debug(v); v.remove(QRegExp("\\((Editor|Editors|Ed|Eds)\\.{0,1}\\)", Qt::CaseInsensitive)); if (init_value.isEmpty()) v = _authorString.toBibTeX(v, _settingsP->value("cb2Bib/UseFullNames").toBool()); else v = init_value + " and " + _authorString.toBibTeX(v, _settingsP->value("cb2Bib/UseFullNames").toBool()); } else if (field == QLatin1String("doi")) { v.remove(QRegExp("^.+(?=10\\.[\\d\\.]+/\\S+)")); if (v.endsWith(QLatin1Char('.')) || v.endsWith(QLatin1Char(',')) || v.endsWith(QLatin1Char(';'))) v.chop(1); } else if (field == QLatin1String("url")) { // Remove redundant DOI URLs if (v.contains("doi.org/10.")) v.clear(); } else if (field == QLatin1String("isbn")) v.remove(' '); else if (field == QLatin1String("journal")) { if (_settingsP->value("cb2Bib/SetJournalsToFullname").toBool()) v = fullJournal(v); else v = abbreviatedJournal(v); } else if (field == QLatin1String("keywords")) { v.replace(" - ", ","); QStringList kl(v.split(QRegExp("[^\\w\\s-']"), QString::SkipEmptyParts)); kl.removeAll(" "); kl.removeDuplicates(); v = kl.join(", "); v.replace(QRegExp("\\s+,"), ","); v = v.toLower(); } else if (field == QLatin1String("month")) v = _month_dbP->retrieve(v); // Fields edition and note require first letter capitalization else if (field == QLatin1String("edition")) v = c2bUtils::setCapitalization(v); else if (field == QLatin1String("note")) v = c2bUtils::setCapitalization(v); // Process pages, volume, number, and year to set hyphenation else if (field == QLatin1String("pages")) v = adjacentNumbers(v); else if (field == QLatin1String("volume")) v = adjacentNumbers(v); else if (field == QLatin1String("number")) v = adjacentNumbers(v); else if (field == QLatin1String("year")) v = adjacentNumbers(v); else if (field == QLatin1String("title") || field == QLatin1String("booktitle")) v = c2bUtils::setCapitalization(v); else if (field == QLatin1String("addtitle")) { if (!init_value.isEmpty()) v = init_value + QLatin1String(": ") + v; v = c2bUtils::setCapitalization(v); } return c2bUtils::simplifyString(v); } /** Process each field and set its final format for a complete reference */ bibReference& bibParser::parse(bibReference& reference) { QMutableHashIterator i(reference); while (i.hasNext()) { i.next(); const QString v(parse(i.key(), i.value())); i.setValue(v); } return reference; } QString bibParser::setJournalsToFull(const QString& text, const bool alternate) { const bool ConvertReferenceToLaTeX(_settingsP->value("cb2Bib/ConvertReferenceToLaTeX").toBool()); QString substituted_text(text); QRegExp jnre("\\bjournal\\s*=\\s*[\\{\"]", Qt::CaseInsensitive); QString jn; int pos(0); uint nj(0); while (pos >= 0) { pos = jnre.indexIn(substituted_text, pos); if (pos > 0 && c2bUtils::inBraces(pos + jnre.matchedLength(), substituted_text, &jn)) { const int jnlength(jn.length()); c2bUtils::bibToC2b(jn); jn = alternate ? alternateFullJournal(jn) : fullJournal(jn); if (ConvertReferenceToLaTeX) c2bUtils::c2bToBib(jn); pos += jnre.matchedLength(); substituted_text.replace(pos, jnlength, jn); nj++; } else if (pos >= 0) ++pos; } emit statusMessage(tr("Processed %1 journal names.").arg(nj)); return substituted_text; } QString bibParser::setJournalsToAbbreviated(const QString& text, const bool alternate) { const bool ConvertReferenceToLaTeX(_settingsP->value("cb2Bib/ConvertReferenceToLaTeX").toBool()); QString substituted_text(text); QRegExp jnre("\\bjournal\\s*=\\s*[\\{\"]", Qt::CaseInsensitive); QString jn; int pos(0); uint nj(0); while (pos >= 0) { pos = jnre.indexIn(substituted_text, pos); if (pos > 0 && c2bUtils::inBraces(pos + jnre.matchedLength(), substituted_text, &jn)) { const int jnlength(jn.length()); c2bUtils::bibToC2b(jn); jn = alternate ? alternateAbbreviatedJournal(jn) : abbreviatedJournal(jn); if (ConvertReferenceToLaTeX) c2bUtils::c2bToBib(jn); pos += jnre.matchedLength(); substituted_text.replace(pos, jnlength, jn); nj++; } else if (pos >= 0) ++pos; } emit statusMessage(tr("Processed %1 journal names.").arg(nj)); return substituted_text; } QString bibParser::excerpt(const QString& text, const QStringList& hints) const { QString txt(removeTags(text)); txt.replace(QRegExp("\\[Bibliographic Metadata.+/Bibliographic Metadata\\]"), " "); txt.replace(QRegExp("(http://|https://|ftp://|www\\.|ftp\\.)(www\\.|ftp\\.){0,1}\\S+"), " "); txt.replace(QRegExp("\\b[A-Z]+\\b"), " "); txt.replace(QRegExp("\\d"), " "); txt.replace(c2bUtils::nonLetter, " "); txt.replace(QRegExp("\\b\\w{1,2}\\b"), " "); txt.replace( QRegExp("\\b(about|and|are|com|for|from|how|into|that|the|their|this|where|with|www)\\b", Qt::CaseInsensitive), " "); txt.replace(QRegExp("\\b(january|february|march|april|may|june|july|august|september|october|november|december)\\b", Qt::CaseInsensitive), " "); txt = hints.join(" ") + ' ' + txt; txt = c2bUtils::simplifyString(txt); const QStringList txtlist(txt.split(' ', QString::SkipEmptyParts)); QStringList txtlistSimp; for (int i = 0; i < std::min(15, txtlist.count()); ++i) txtlistSimp.append(txtlist.at(i)); return txtlistSimp.join(" "); } void bibParser::setField(const QString& name, const QString& value) { _current_reference[name] = parse(name, value); } void bibParser::setReferenceType(const QString& type) { _current_reference.typeName = type; } void bibParser::setCiteID() { _current_reference.citeidName = _cite_idmP->makeID(_current_reference); } QString bibParser::documentFilename(const QString& base_fn, const QString& bibtex_fn) { if (base_fn.isEmpty()) return base_fn; if (!_settingsP->value("cb2Bib/MovePdf").toBool()) { const QUrl u(base_fn); const QString scheme(u.scheme()); if (scheme == "file") return parse("file", u.toLocalFile()); else return parse("file", base_fn); } QString filename(_file_idmP->makeID(_current_reference)); if (filename.isEmpty()) filename = "no_cite_id"; QFileInfo fi(base_fn); QString docExtension('.' + fi.suffix().toLower()); // Possible document extensions if (!docExtension.contains(QRegExp("^\\.\\w{2,4}$"))) docExtension = ".pdf"; // Default if (docExtension == ".gz") if (fi.completeSuffix().toLower() == ".ps.gz") docExtension = ".ps.gz"; // Composite extension filename = c2bUtils::documentFilename(_settingsP->value("cb2Bib/RelativePdfDirectory").toBool(), bibtex_fn, _settingsP->fileName("cb2Bib/PdfDirectory"), filename + docExtension); return parse("file", filename); } /**************************************************************************** AUTOMATIC BIB CAPTION *****************************************************************************/ void bibParser::preparse(const QString& text, QString* out_text) { _preparserP->preparse(text, out_text); } /** \page clipboard Extracting Data from the Clipboard Clipboard contents is processed according to the following rules: - Perform external, user-defined preparsing on input stream. See \ref c2bconf_clipboard. - Perform user-defined substitutions on input stream. See \ref c2bconf_clipboard. - Check if input stream is already a BibTeX entry. If so, process entry. - Check if input stream is, in this order of preference, a PubMed XML, arXiv XML, CR JSON, or Medline entry. If so, process entry. - Preprocess author names: PI JOAN III -> Pi III, J. (care of name prefixes, suffixes, and removal of ambiguities). If otherwise, - Extract DOI \n (DOI, URL and FILE/PDF are preprocessed, performed before the automatic recognition takes place.) - Extract URL - Remove leading and trailing white spaces, TABs and CRs. - "\r\n", "\n" and/or "\r" replaced by the line indicator tag . - Replace "\t" and ten or more consecutive "\s" by the tabular tag . - Simplify white spaces - Start the automatic recognition engine. If the automatic recognition engine fails, optionally, a heuristic guessing will be performed. See also \ref heuristics and \ref metadata. */ void bibParser::parse(const QString& text, QString* out_text, QString* out_tagtext) { QString& otext = *out_text; otext = text; QString& ottext = *out_tagtext; ottext.clear(); _preprocessP->preprocessText(out_text); if (hasBibTeX(otext)) { _current_reference = wholeReference(otext); parse(_current_reference); currentReferenceUpdated(); _auto_recognized_string = tr("Processed as 'BibTeX'."); _auto_recognized = true; emit statusMessage(_auto_recognized_string); return; } const QString pubmed_identifier(""); if (otext.contains(pubmed_identifier)) { pubmedXml pxml(metadataSection(otext, pubmed_identifier)); if (pxml.hasError()) { _auto_recognized_string = tr("Error parsing 'PubMed XML': %1.").arg(pxml.errorString()); _auto_recognized = false; } else { _current_reference = pxml.reference(); parse(_current_reference); currentReferenceUpdated(); _auto_recognized_string = tr("Processed as 'PubMed XML'."); _auto_recognized = true; } emit statusMessage(_auto_recognized_string); return; } const QString arxiv_identifier("arxiv.org/api/"); const QString cr_identifier("{\"status\":\"ok\",\"message-type\":\"work\""); if (otext.contains(arxiv_identifier) || otext.contains(cr_identifier)) { if (otext.contains(cr_identifier)) { crJson crjson(metadataSection(otext, cr_identifier)); if (crjson.hasError()) { _auto_recognized_string = tr("Error parsing 'CR JSON': %1.").arg(crjson.errorString()); _auto_recognized = false; emit statusMessage(_auto_recognized_string); return; } else { _current_reference = crjson.reference(); _auto_recognized_string = tr("Processed as 'CR JSON'."); } } if (otext.contains(arxiv_identifier)) { arxivXml axml(metadataSection(otext, arxiv_identifier)); if (axml.hasError()) { _auto_recognized_string = tr("Error parsing 'arXiv XML': %1.").arg(axml.errorString()); _auto_recognized = false; if (_current_reference.size() > 0) _current_reference.clearReference(); emit statusMessage(_auto_recognized_string); return; } else { if (_current_reference.size() == 0) { _current_reference = axml.reference(); _auto_recognized_string = tr("Processed as 'arXiv XML'."); } else { // Merging arXiv and CR metadata const bibReference& areference(axml.reference()); if (!areference.value("abstract").isEmpty()) _current_reference["abstract"] = areference.value("abstract"); if (!areference.value("title").isEmpty()) _current_reference["title"] = areference.value("title"); if (!areference.value("eprint").isEmpty()) _current_reference["eprint"] = areference.value("eprint"); if (!areference.value("url").isEmpty()) _current_reference["url"] = areference.value("url"); _auto_recognized_string = tr("Processed as merged 'arXiv XML' and 'CR JSON'."); } } } parse(_current_reference); currentReferenceUpdated(); _auto_recognized = true; emit statusMessage(_auto_recognized_string); return; } if (otext.contains(QRegExp("^\\s*PMID\\s*-"))) { _current_reference.typeName = "article"; otext = ' ' + otext; ottext = otext; // http://www.nlm.nih.gov/bsd/mms/medlineelements.html ottext.replace(QRegExp("[\\n\\r]\\s*([A-Z]{2,4}\\s*-)"), "][\\1"); // Two to four capital letter in field tags ottext = c2bUtils::simplifyString(ottext); if (!ottext.contains(QRegExp("\\[FAU\\s+-"))) ottext.replace(QRegExp("\\[(AU\\s*-\\s*[-'\\w]+)"), "[F\\1 "); QStringList fList(ottext.split("][")); QString kw; QRegExp fld("^([A-Z]{2,4})\\s{0,1}-\\s*(.+)$"); fld.setPatternSyntax(QRegExp::RegExp2); for (QStringList::Iterator it = fList.begin(); it != fList.end(); ++it) { if (fld.indexIn(*it) == -1) continue; const QString tag(fld.cap(1)); QString value(fld.cap(2)); if (tag == "AB") _current_reference["abstract"] = parse("abstract", value); else if (tag == "FAU") _current_reference["author"] = parse("addauthors", authorFromMedline(value), _current_reference.value("author")); else if (tag == "TA") _current_reference["journal"] = parse("journal", value); else if (tag == "IP") _current_reference["number"] = parse("number", value); else if (tag == "PG") _current_reference["pages"] = parse("pages", value); else if (tag == "TI") _current_reference["title"] = parse("title", value); else if (tag == "PMID") _current_reference["url"] = parse("url", c2bUtils::pubmedUrl.arg(value)); else if (tag == "VI") _current_reference["volume"] = parse("volume", value); else if (tag == "AID") { if (value.contains("[doi]")) _current_reference["doi"] = parse("doi", value.remove("[doi]")); } else if (tag == "DP") _current_reference["year"] = parse("year", value.replace(QRegExp("^([\\d\\s]+).*$"), "\\1")); else if (tag == "MH") kw += "; " + value.trimmed(); } if (!kw.isEmpty()) _current_reference["keywords"] = parse("keywords", kw.remove(0, 2)); currentReferenceUpdated(); _auto_recognized_string = tr("Processed as 'PubMed - Medline Journals'."); _auto_recognized = true; emit statusMessage(_auto_recognized_string); return; } _heuristic_parserP->heuristicFields(otext); // Set tags and start regular expression extraction ottext = setTags(otext); QString regular_expression_f(_settingsP->fileName("cb2Bib/RegularExpressionFile")); checkRegExpFile(regular_expression_f); QFile file(regular_expression_f); file.open(QIODevice::ReadOnly | QIODevice::Text); QString ItemX; QString line; QString reftype; QString fieldset; QTextStream stream(&file); stream.setCodec("UTF-8"); stream.setAutoDetectUnicode(true); int nfilters(0); while (!stream.atEnd()) { line = stream.readLine(); if (!(line.isEmpty() || line.contains(QRegExp("^#")))) { reftype = stream.readLine(); fieldset = stream.readLine(); ItemX = stream.readLine(); c2bUtils::debug(tr("The RegExp file contains1: |%1|").arg(line)); c2bUtils::debug(tr("The RegExp file contains2: |%1|").arg(reftype)); c2bUtils::debug(tr("The RegExp file contains3: |%1|").arg(fieldset)); c2bUtils::debug(tr("The RegExp file contains4: |%1|").arg(ItemX)); QRegExp rx(ItemX); rx.setMinimal(true); if (!rx.isValid()) c2bUtils::warn(tr("RegExp |%1| is not valid").arg(ItemX)); const QStringList list(fieldset.split(' ', QString::SkipEmptyParts)); const int efields(list.count()); const int cfields(rx.captureCount()); int npos(rx.indexIn(ottext)); c2bUtils::debug(tr("Expected Fields: |%1|").arg(efields)); c2bUtils::debug(tr("Captured Fields: |%1|").arg(cfields)); c2bUtils::debug(tr("Position: |%1|").arg(npos)); if (efields != cfields) { c2bUtils::warn( tr("RegExp |%1| is not valid. Mismatch between expected and actual captures").arg(ItemX)); npos = -1; } nfilters++; if (npos > -1) { for (int i = 0; i < cfields; i++) { const QString& listi = list.at(i); int ii(i + 1); c2bUtils::debug(QString("Fields in Template %1: |%2|").arg(i).arg(rx.cap(ii))); if (_field_re.indexIn(listi) > -1) { if (listi == "author") // Reminder: "addauthors" requires to init _current_reference["author"] _current_reference[listi] = parse("addauthors", rx.cap(ii), _current_reference.value(listi)); else if (listi == "editor") // Reminder: "addeditors" requires to init _current_reference["editor"] _current_reference[listi] = parse("addeditors", rx.cap(ii), _current_reference.value(listi)); else if (listi == "title") // Reminder: "addtitle" requires to init _current_reference["title"] _current_reference[listi] = parse("addtitle", rx.cap(ii), _current_reference.value(listi)); else _current_reference[listi] = parse(listi, rx.cap(ii)); } } _current_reference.typeName = reftype; currentReferenceUpdated(); _auto_recognized_string = tr("Processed as '%1'.").arg(line); _auto_recognized = true; emit statusMessage(_auto_recognized_string); file.close(); return; } } } file.close(); // Heuristic Bib Parsing if (_settingsP->value("cb2Bib/DoHeuristicGuess").toBool()) { // Sometimes (if user is on tag mode) tag could be on otext. Revert tags here, just in case. const QString clean_text(removeTags(ottext)); _heuristic_parserP->guessFields(clean_text, ottext); currentReferenceUpdated(); _auto_recognized_string = tr("Applied %1 filters: No automatic format detection. %2 fields guessed.").arg(nfilters).arg(fieldCount()); } else _auto_recognized_string = tr("Applied %1 filters: No automatic format detection.").arg(nfilters); emit statusMessage(_auto_recognized_string); } void bibParser::checkRegExpFile(const QString& fn) { if (fn.isEmpty()) { c2bUtils::warn(tr("No regular expression file especified")); return; } QFileInfo fi(fn); if (!fi.exists() || !fi.isReadable()) { c2bUtils::warn(tr("Could not open regular expression file %1 for reading").arg(fn)); return; } } void bibParser::guessFields(const QString& text) { const QString clean_text(text.simplified()); const QString tagged_text(setTags(text)); _heuristic_parserP->heuristicFields(clean_text); _heuristic_parserP->guessFields(clean_text, tagged_text); currentReferenceUpdated(); _auto_recognized_string = tr("%1 fields guessed.").arg(fieldCount()); emit statusMessage(_auto_recognized_string); } QString bibParser::setTags(const QString& text) const { QString tagged_text(text.trimmed()); tagged_text.replace(QRegExp("\\r\\n"), ""); // Windows new line tagged_text.replace(QRegExp("\\n"), ""); // Linux new line, LF tagged_text.replace(QRegExp("\\r"), ""); // OSX new line, CR QStringList spText(tagged_text.split("")); int n(spText.count()); tagged_text.clear(); for (int i = 0; i < n - 1; i++) tagged_text += spText.at(i) + QString("").arg(i + 1); tagged_text += spText[n - 1]; spText = tagged_text.split(QRegExp("(\\s{10,}|\\t)")); n = spText.count(); tagged_text.clear(); for (int i = 0; i < n - 1; i++) tagged_text += spText.at(i) + QString("").arg(i + 1); tagged_text += spText[n - 1]; tagged_text = c2bUtils::simplifyString(tagged_text); return tagged_text; } QString bibParser::removeTags(const QString& text) const { QString clean(text); clean.remove("[["); clean.remove("]]"); clean.replace(QRegExp(""), " "); clean.replace(QRegExp(""), " "); clean = c2bUtils::simplifyString(clean); return clean; } QString bibParser::metadataSection(const QString& text, const QString& identifier) const { const QStringList lines(text.split(QRegExp("[\\r\\n]"), QString::KeepEmptyParts)); const int nl(lines.count()); int il(-1); int sl(0); int el(0); for (int l = 0; l < nl; ++l) if (lines.at(l).contains(identifier)) { il = l; break; } if (il == -1) return QString(); for (int l = il + 1; l < nl; ++l) if (lines.at(l) == "/Raw Metadata]") { el = l; break; } for (int l = il; l >= 0; --l) if (lines.at(l) == "[Raw Metadata") { sl = l; break; } if (sl == 0 && el == 0) return text.trimmed(); if (sl == 0 || el == 0) return QString(); QString section; for (int l = sl + 1; l < el; ++l) section += '\n' + lines.at(l); return section.trimmed(); } cb2bib-2.0.1/src/c2b/PaxHeaders.5700/wordPattern.h0000644000000000000000000000013214011522520016214 xustar0030 mtime=1613145424.782620335 30 atime=1613145424.834620334 30 ctime=1613145424.782620335 cb2bib-2.0.1/src/c2b/wordPattern.h0000644000175000001440000000345614011522520017623 0ustar00constansusers00000000000000/*************************************************************************** * Copyright (C) 2004-2021 by Pere Constans * constans@molspaces.com * cb2Bib version 2.0.1. Licensed under the GNU GPL version 3. * See the LICENSE file that comes with this distribution. ***************************************************************************/ #ifndef WORDPATTERN_H #define WORDPATTERN_H #include "compositePattern.h" #include "txtmatcher.h" class wordPattern : public compositePattern { public: enum Type { AllWords, AnyWord }; wordPattern(); wordPattern(const QString& pattern, const Type type, const Qt::CaseSensitivity cs); inline ~wordPattern() {} void setPattern(const QString& pattern, const Type type, const Qt::CaseSensitivity cs = Qt::CaseSensitive); inline bool matches(const QString& str) const override { _matched_length = -1; if (str.length() == 0) return false; if (_type == AllWords) { for (int i = _subpattern_count - 1; i >= 0; --i) if (_submatchers.at(i).indexIn(str) == -1) return false; return true; } else { for (int i = 0; i < _subpattern_count; ++i) if (_submatchers.at(i).indexIn(str) != -1) return true; return false; } } inline int indexIn(const QString& str, const int from = 0) const override { const QRegularExpressionMatch rem(_regexp.match(str, from)); _matched_length = rem.capturedLength(); return rem.capturedStart(); } inline const QVector& submatchers() const { return _submatchers; } private: QVector _submatchers; Type _type; }; #endif cb2bib-2.0.1/src/c2b/PaxHeaders.5700/crJson.cpp0000644000000000000000000000013014011522520015472 xustar0029 mtime=1613145424.61062034 30 atime=1613145424.834620334 29 ctime=1613145424.61462034 cb2bib-2.0.1/src/c2b/crJson.cpp0000644000175000001440000002146414011522520017102 0ustar00constansusers00000000000000/*************************************************************************** * Copyright (C) 2004-2021 by Pere Constans * constans@molspaces.com * cb2Bib version 2.0.1. Licensed under the GNU GPL version 3. * See the LICENSE file that comes with this distribution. ***************************************************************************/ #include "crJson.h" #include "cb2bib_utilities.h" #include #include #include #include crJson::crJson(const QString& json) { _reference.clearReference(); readReference(json); } void crJson::readReference(const QString& json) { _has_error = true; _error_string.clear(); QJsonParseError jerr; QJsonDocument jdoc(QJsonDocument::fromJson(json.toUtf8(), &jerr)); if (jdoc.isNull() || jdoc.isEmpty()) { _error_string = QObject::tr("Invalid data%1").arg(jerr.errorString().isEmpty() ? QString() : ": " + jerr.errorString()); return; } QJsonObject jobj(jdoc.object().value("message").toObject()); if (jobj.isEmpty()) { _error_string = QObject::tr("Invalid reference data"); return; } #ifdef C2B_DEBUG for (QJsonObject::const_iterator i = jobj.constBegin(); i != jobj.constEnd(); ++i) qDebug() << "[crjson] " << i.key() << i.value(); #endif if (jobj.value("DOI").isUndefined()) { _error_string = QObject::tr("Invalid reference data: no DOI parsed"); return; } _reference["doi"] = jobj.value("DOI").toString(); if (!jobj.value("published-print").isUndefined()) { const QJsonValue jyear( jobj.value("published-print").toObject().value("date-parts").toArray().first().toArray().first()); if (!jyear.isUndefined()) _reference["year"] = QString::number(jyear.toDouble()); } else if (!jobj.value("published-online").isUndefined()) { // For articles no longer published in print const QJsonValue jyear( jobj.value("published-online").toObject().value("date-parts").toArray().first().toArray().first()); if (!jyear.isUndefined()) _reference["year"] = QString::number(jyear.toDouble()); } _reference["volume"] = jobj.value("volume").toString(); _reference["number"] = jobj.value("issue").toString(); _reference["pages"] = jobj.value("page").toString(); QStringList authors; const QJsonArray jauthors(jobj.value("author").toArray()); for (QJsonArray::const_iterator i = jauthors.constBegin(); i != jauthors.constEnd(); ++i) { const QJsonObject ja((*i).toObject()); authors.append(ja.value("given").toString() + ' ' + ja.value("family").toString()); } _reference["author"] = authors.join(", "); QStringList editors; const QJsonArray jeditors(jobj.value("editor").toArray()); for (QJsonArray::const_iterator i = jeditors.constBegin(); i != jeditors.constEnd(); ++i) { const QJsonObject je((*i).toObject()); editors.append(je.value("given").toString() + ' ' + je.value("family").toString()); } _reference["editor"] = editors.join(", "); QStringList titles; const QJsonArray jtitles(jobj.value("title").toArray()); for (QJsonArray::const_iterator i = jtitles.constBegin(); i != jtitles.constEnd(); ++i) titles.append((*i).toString()); _normalize_jtitles(&titles); QStringList subtitles; const QJsonArray jsubtitles(jobj.value("subtitle").toArray()); for (QJsonArray::const_iterator i = jsubtitles.constBegin(); i != jsubtitles.constEnd(); ++i) subtitles.append((*i).toString()); _normalize_jtitles(&subtitles); QStringList containertitles; const QJsonArray jcontainertitles(jobj.value("container-title").toArray()); for (QJsonArray::const_iterator i = jcontainertitles.constBegin(); i != jcontainertitles.constEnd(); ++i) containertitles.append((*i).toString()); _normalize_jtitles(&containertitles); const QString jisbn(jobj.value("ISBN").toArray().first().toString()); const QString jpublisher(jobj.value("publisher").toString()); const QString jabstract(jobj.value("abstract").toString()); _reference["abstract"] = _normalize_jabstract(jabstract); _reference["title"] = _bibtex_title(titles, subtitles); const QString jtype(jobj.value("type").toString()); if (jtype == "journal-article") { _reference.typeName = "article"; _reference["journal"] = containertitles.count() > 0 ? containertitles.first() : QString(); } else if (jtype == "proceedings-article") { _reference.typeName = "inproceedings"; _reference["booktitle"] = _bibtex_booktitle(containertitles); _reference["series"] = _bibtex_series(containertitles); _reference["isbn"] = jisbn; _reference["publisher"] = jpublisher; } else if (jtype == "book") { _reference.typeName = "book"; _reference["series"] = containertitles.count() > 0 ? containertitles.first() : QString(); _reference["isbn"] = jisbn; _reference["publisher"] = jpublisher; } else if (jtype == "book-chapter") { _reference.typeName = "inbook"; _reference["booktitle"] = _bibtex_booktitle(containertitles); _reference["series"] = _bibtex_series(containertitles); _reference["isbn"] = jisbn; _reference["publisher"] = jpublisher; } else { // jtype == "other" _reference.typeName = "misc"; _reference["booktitle"] = _bibtex_booktitle(containertitles); _reference["series"] = _bibtex_series(containertitles); _reference["isbn"] = jisbn; _reference["publisher"] = jpublisher; } if (_reference.value("series") == _reference.value("booktitle")) _reference["series"] = QString(); if (jtype == "book-chapter" && !_reference.value("series").isEmpty()) _reference.typeName = "incollection"; #ifdef C2B_DEBUG qDebug() << "[crjson] TITLES" << titles; qDebug() << "[crjson] SUBTITLES" << subtitles; qDebug() << "[crjson] CONTAINERTITLES" << containertitles; qDebug() << "[crjson] BIBTEX"; qDebug() << "[crjson] type " << _reference.typeName; qDebug() << "[crjson] title " << _reference.value("title"); qDebug() << "[crjson] booktitle " << _reference.value("booktitle"); qDebug() << "[crjson] series " << _reference.value("series"); qDebug() << "[crjson] publisher " << _reference.value("publisher"); qDebug() << "[crjson] isbn " << _reference.value("isbn"); qDebug() << "[crjson] year " << _reference.value("year"); #endif _has_error = false; } void crJson::_normalize_jtitles(QStringList* titles) { if (titles->count() == 0) return; titles->removeDuplicates(); for (int i = 0; i < titles->count(); ++i) { QString t(titles->at(i).simplified()); for (int j = 0; j < t.length(); ++j) if (t.at(j).category() == QChar::Punctuation_Dash) t[j] = '-'; t.replace(" - ", ": "); t.replace(" : ", ": "); (*titles)[i] = t; } } QString crJson::_normalize_jabstract(const QString& abstract) { if (abstract.isEmpty()) return abstract; QString na(abstract); na.replace("<", "<"); na.replace(">", ">"); na.replace(QRegExp("<[^>]+>"), " "); na.remove(QRegExp("^\\W*(abstract|synopsis|summary)\\.*", Qt::CaseInsensitive)); return na.simplified(); } QString crJson::_bibtex_title(const QStringList& titles, const QStringList& subtitles) { if (titles.count() > 0 && subtitles.count() > 0 && !titles.first().contains(": ")) { const int wt(_words(titles.first())); const int ws(_words(subtitles.first())); const int wu(_words(titles.first() + ' ' + subtitles.first())); const int s(100 * (wt + ws - wu) / sqrt(double(wt * ws))); if (s < 30) return titles.first() + ": " + subtitles.first(); } return titles.count() > 0 ? titles.first() : QString(); } QString crJson::_bibtex_booktitle(const QStringList& titles) { if (titles.count() == 0) return QString(); if (titles.count() == 2) return (!titles.at(1).contains( QRegExp("(advances|series|lecture notes|studies in|topics in)", Qt::CaseInsensitive))) ? titles.at(1) : titles.at(0); return titles.first(); } QString crJson::_bibtex_series(const QStringList& titles) { if (titles.count() == 2) return (titles.at(1).contains( QRegExp("(advances|series|lecture notes|studies in|topics in)", Qt::CaseInsensitive))) ? titles.at(1) : titles.at(0); return QString(); } int crJson::_words(const QString& s) { QStringList wl(s.split(QRegExp("\\W"), QString::SkipEmptyParts)); wl.removeDuplicates(); return wl.count(); } cb2bib-2.0.1/src/c2b/PaxHeaders.5700/scorer.h0000644000000000000000000000013214011522520015200 xustar0030 mtime=1613145424.746620336 30 atime=1613145424.834620334 30 ctime=1613145424.750620336 cb2bib-2.0.1/src/c2b/scorer.h0000644000175000001440000000176614011522520016611 0ustar00constansusers00000000000000/*************************************************************************** * Copyright (C) 2004-2021 by Pere Constans * constans@molspaces.com * cb2Bib version 2.0.1. Licensed under the GNU GPL version 3. * See the LICENSE file that comes with this distribution. ***************************************************************************/ #ifndef SCORER_H #define SCORER_H #include #ifdef C2B_DEBUG_SEARCHING #include #endif struct scorer { scorer() : tscore(0), nscores(0) {} void initialize() { tscore = double(0); nscores = 0; } void update(const int plength, const int length) { const double s(plength == 0 ? double(1) : double(1) / (double(1) + std::abs(length - plength))); tscore += s; ++nscores; } double score() const { #ifdef C2B_DEBUG_SEARCHING qDebug() << "scorer: n score" << nscores << tscore; #endif return tscore; } double tscore; int nscores; }; #endif cb2bib-2.0.1/src/c2b/PaxHeaders.5700/stemmer.h0000644000000000000000000000013214011522520015357 xustar0030 mtime=1613145424.754620336 30 atime=1613145424.834620334 30 ctime=1613145424.758620336 cb2bib-2.0.1/src/c2b/stemmer.h0000644000175000001440000002113514011522520016760 0ustar00constansusers00000000000000/*************************************************************************** * Copyright (C) 2004-2021 by Pere Constans * constans@molspaces.com * cb2Bib version 2.0.1. Licensed under the GNU GPL version 3. * See the LICENSE file that comes with this distribution. ***************************************************************************/ #ifndef STEMMER_H #define STEMMER_H #include #include struct stemmer { stemmer() : digits("\\d"), suffix_1_letter("(:?a|e|f|i|o|r|s|t|x|y)$", Qt::CaseInsensitive), suffix_2_letter("(:?as|ce|er|es|fs|ic|id|ie|is|on|os|se|sm|st|um|us|ys)$", Qt::CaseInsensitive), suffix_2_letter_inflected("(:?ed|en|er)$", Qt::CaseInsensitive), suffix_2_letter_length_5("(:?ed|er)$", Qt::CaseInsensitive), suffix_3_letter("(:?ers|ics|ies|ion|ish|ism|ist|ium|oes|ons|ora|sms|sts|ums|ves|xes)$", Qt::CaseInsensitive), suffix_3_letter_length_7("(:?ers|ies|ish|ora|sms|ums|ves|xes)$", Qt::CaseInsensitive), suffix_4_letter("(:?ical|ions|isms|ists)$", Qt::CaseInsensitive), suffix_double_esses("(:?sses|ssis|ssus)$", Qt::CaseInsensitive), suffix_isz("(:?ise|ised|iser|isers|ises|ising|isis|ize|ized|izer|izers|izes|izing)$", Qt::CaseInsensitive), suffix_man("(:?man|men)$", Qt::CaseInsensitive), suffix_misc("(:?mme|mmes|lty|lties|lity|lities)$", Qt::CaseInsensitive), suffix_ogues("(:?ogue|ogues)$", Qt::CaseInsensitive), suffix_ours("(:?or|ors|our|ours)$", Qt::CaseInsensitive), suffix_reer("(:?tre|tres|bre|bres)$", Qt::CaseInsensitive), suffix_sz("(:?isation|ization|ysation|yzation|isations|izations|ysations|yzations)$", Qt::CaseInsensitive), suffix_ysz("(:?yse|ysed|yser|ysers|yses|ysing|ysis|yze|yzed|yzer|yzers|yzes|yzing)$", Qt::CaseInsensitive) { dictionary.insert("alpha", QChar(913)); dictionary.insert("beta", QChar(914)); dictionary.insert("gamma", QChar(915)); dictionary.insert("delta", QChar(916)); dictionary.insert("epsilon", QChar(917)); dictionary.insert("zeta", QChar(918)); dictionary.insert("eta", QChar(919)); dictionary.insert("theta", QChar(920)); dictionary.insert("iota", QChar(921)); dictionary.insert("kappa", QChar(922)); dictionary.insert("lambda", QChar(923)); dictionary.insert("mu", QChar(924)); dictionary.insert("nu", QChar(925)); dictionary.insert("xi", QChar(926)); dictionary.insert("omicron", QChar(927)); dictionary.insert("pi", QChar(928)); dictionary.insert("rho", QChar(929)); dictionary.insert("sigma", QChar(931)); dictionary.insert("tau", QChar(932)); dictionary.insert("upsilon", QChar(933)); dictionary.insert("phi", QChar(934)); dictionary.insert("chi", QChar(935)); dictionary.insert("psi", QChar(936)); dictionary.insert("omega", QChar(937)); dictionary.insert("axes", "axis"); dictionary.insert("axis", "axes"); dictionary.insert("bases", "basis"); dictionary.insert("basis", "bases"); dictionary.insert("data", "datum"); dictionary.insert("datum", "data"); dictionary.insert("liked", "like"); dictionary.insert("infinity", QChar(8734)); } QString stem(const QString& word) const { const Qt::CaseSensitivity ci(Qt::CaseInsensitive); const int nl(word.length()); if (nl < 4) return word; if (digits.indexIn(word) >= 0) return word; if (nl == 4) { if (word.endsWith(QLatin1Char('s'), ci)) return word.left(3); return word; } if (suffix_man.indexIn(word) >= 0) return word.left(nl - 2); if (suffix_reer.indexIn(word) >= 0) return word.left(nl - suffix_reer.matchedLength() + 1); if (nl == 5) { if (suffix_2_letter_length_5.indexIn(word) >= 0) return word.left(3); if (suffix_1_letter.indexIn(word) >= 0) return word.left(4); return word; } if (suffix_isz.indexIn(word) >= 0) return word.left(nl - suffix_isz.matchedLength() + 1); if (suffix_ysz.indexIn(word) >= 0) return word.left(nl - suffix_ysz.matchedLength() + 1); if (suffix_2_letter_inflected.indexIn(word) >= 0) return word.at(nl - 3) == word.at(nl - 4) || word.at(nl - 3).toLower() == QLatin1Char('i') ? word.left(nl - 3) : word.left(nl - 2); if (suffix_ours.indexIn(word) >= 0) return word.left(nl - suffix_ours.matchedLength() + 1); if (suffix_misc.indexIn(word) >= 0) return word.left(nl - suffix_misc.matchedLength() + 1); if (nl == 6) { if (word.endsWith(QLatin1String("ing"), ci)) return word.left(3); if (suffix_2_letter.indexIn(word) >= 0) return word.left(4); if (suffix_1_letter.indexIn(word) >= 0) return word.left(5); return word; } if (word.endsWith(QLatin1String("est"), ci)) return word.at(nl - 4) == word.at(nl - 5) || word.at(nl - 4).toLower() == QLatin1Char('i') ? word.left(nl - 4) : word.left(nl - 3); if (word.endsWith(QLatin1String("ing"), ci)) return word.at(nl - 4) == word.at(nl - 5) || word.at(nl - 4).toLower() == QLatin1Char('y') ? word.left(nl - 4) : word.left(nl - 3); if (word.endsWith(QLatin1String("ices"), ci)) return word.left(nl - 3); if (word.endsWith(QLatin1String("uses"), ci)) return word.at(nl - 5).toLower() == QLatin1Char('f') ? word.left(nl - 2) : word.left(nl - 4); if (suffix_ogues.indexIn(word) >= 0) return word.left(nl - suffix_ogues.matchedLength() + 2); if (nl == 7) { if (suffix_3_letter_length_7.indexIn(word) >= 0) return word.left(4); if (suffix_2_letter.indexIn(word) >= 0) return word.left(5); if (suffix_1_letter.indexIn(word) >= 0) return word.left(6); return word; } if (word.endsWith(QLatin1String("ings"), ci)) return word.at(nl - 5) == word.at(nl - 6) || word.at(nl - 5).toLower() == QLatin1Char('y') ? word.left(nl - 5) : word.left(nl - 4); if (nl > 9 && suffix_sz.indexIn(word) >= 0) return word.left(nl - suffix_sz.matchedLength() + 1); if (nl > 8 && suffix_4_letter.indexIn(word) >= 0) return word.left(nl - 4); if (suffix_3_letter.indexIn(word) >= 0) return word.left(nl - 3); if (suffix_double_esses.indexIn(word) >= 0) return word.left(nl - 3); if (suffix_2_letter.indexIn(word) >= 0) return word.left(nl - 2); if (suffix_1_letter.indexIn(word) >= 0) return word.left(nl - 1); return word; } QStringList stems(const QString& word) const { QStringList sts; { QString stripped(word); c2bUtils::stripDiacritics(stripped); if (stripped != word) { sts.append(word); sts.append(stripped); return sts; } } { const QString lower(word.toLower()); if (dictionary.contains(lower)) { sts.append(word); sts.append(cased(word, dictionary.value(lower))); return sts; } } sts.append(stem(word)); return sts; } static QString cased(const QString& word, const QString& other) { const int n(std::min(word.length(), other.length())); QString wc(other); for (int i = 0; i < n; ++i) wc[i] = word.at(i).isUpper() ? wc.at(i).toUpper() : wc.at(i).toLower(); return wc; } QHash dictionary; QRegExp digits; QRegExp suffix_1_letter; QRegExp suffix_2_letter; QRegExp suffix_2_letter_inflected; QRegExp suffix_2_letter_length_5; QRegExp suffix_3_letter; QRegExp suffix_3_letter_length_7; QRegExp suffix_4_letter; QRegExp suffix_double_esses; QRegExp suffix_isz; QRegExp suffix_man; QRegExp suffix_misc; QRegExp suffix_ogues; QRegExp suffix_ours; QRegExp suffix_reer; QRegExp suffix_sz; QRegExp suffix_ysz; }; #endif cb2bib-2.0.1/src/c2b/PaxHeaders.5700/metadataParser.h0000644000000000000000000000013214011522520016640 xustar0030 mtime=1613145424.734620337 30 atime=1613145424.834620334 30 ctime=1613145424.734620337 cb2bib-2.0.1/src/c2b/metadataParser.h0000644000175000001440000000411614011522520020241 0ustar00constansusers00000000000000/*************************************************************************** * Copyright (C) 2004-2021 by Pere Constans * constans@molspaces.com * cb2Bib version 2.0.1. Licensed under the GNU GPL version 3. * See the LICENSE file that comes with this distribution. ***************************************************************************/ #ifndef METADATAPARSER_H #define METADATAPARSER_H #include #include class coreBibParser; class settings; class metadataParser : public QObject { Q_OBJECT public: explicit metadataParser(QObject* parento = 0); explicit metadataParser(coreBibParser* cbp, QObject* parento = 0); inline ~metadataParser() {} bool insertMetadata(const bibReference& ref, const QString& fn, QString* error = 0, const bool has_reference = false); bool metadata(const QString& fn, bibReference* ref); const QString metadata(const QString& fn); signals: void showMessage(const QString& title, const QString& ms); private: QHash _bibtex_key; QRegExp _bibtex_fields; QRegExp _fields; bibReference _ref; bool _has_bibtex; bool _has_cb2bib; bool _has_prism; bool _metadata(const QString& fn); const QString _pdfDictionary(const QByteArray& rawpdf); coreBibParser* _cbpP; settings* _settingsP; void _fuzzyParser(const QString& data); void _metadataXmp(const QString& fn, const QByteArray& raw_contents, QStringList* xmls); void _metadataXmpExifTool(const QString& fn, QStringList* xmls); void _miscellaneousData(const QString& fn, const QByteArray& raw_contents); void init(); inline QString formattedAuthor(const QString& author) const { const QStringList alist(author.split(" and ", QString::SkipEmptyParts)); int na(alist.count()); if (na <= 2) return author; QString formatted(alist.first()); for (int i = 1; i < na - 1; ++i) formatted += ", " + alist.at(i); formatted += ", and " + alist.last(); return formatted; } }; #endif cb2bib-2.0.1/src/c2b/PaxHeaders.5700/cb2bib_parameters.h0000644000000000000000000000013214011522520017251 xustar0030 mtime=1613145424.702620338 30 atime=1613145424.834620334 30 ctime=1613145424.706620337 cb2bib-2.0.1/src/c2b/cb2bib_parameters.h0000644000175000001440000000741614011522520020660 0ustar00constansusers00000000000000/*************************************************************************** * Copyright (C) 2004-2021 by Pere Constans * constans@molspaces.com * cb2Bib version 2.0.1. Licensed under the GNU GPL version 3. * See the LICENSE file that comes with this distribution. ***************************************************************************/ #ifndef CB2BIB_PARAMETERS_H #define CB2BIB_PARAMETERS_H #include const int C2B_MESSAGE_TIME(6000); const QLatin1String C2B_APPLICATION("cb2Bib"); const QLatin1String C2B_CITE_COMMAND_PATTERN("\\cite{<<|citeids|,>>}"); const QLatin1String C2B_CITE_ID_PATTERN("<><><>"); const QLatin1String C2B_DOCUMENT_ID_PATTERN("<>"); const QLatin1String C2B_FIND_REPLACE_LIST("Corresponding Author Contact Information||ScienceDirect alt tag^e" "E-mail The Corresponding Author||ScienceDirect alt tag^e" "small pi, Greek|$\\pi$|ScienceDirect alt tag^e" "{sect}||PNAS - Author String^e" "{dagger}||PNAS - Author String"); const QLatin1String C2B_ICON_ABOUT_B_BACK("back_cb2bib_32.png"); const QLatin1String C2B_ICON_ABOUT_B("cb2bib.png"); const QLatin1String C2B_ICON_CONNECT_B("connect_established.png"); const QLatin1String C2B_ICON_DIR(":/icons/icons/"); const QLatin1String C2B_ICON_DISCONNECT_B("connect_no.png"); const QLatin1String C2B_ICON_VIEWBIB_B("viewbib.png"); const QLatin1String C2B_ICON_VIEWC2B_B("viewcb.png"); const QLatin1String C2B_ORGANIZATION("MOLspaces"); const QLatin1String C2B_VERSION("2.0.1"); #if defined(Q_OS_WIN) const QLatin1String C2B_DATA_DIR("C:/Documents and Settings"); #else const QLatin1String C2B_DATA_DIR("/usr/share/cb2bib"); #endif // File Manager Client #if defined(Q_OS_WIN) const QLatin1String C2B_FM_CLIENT_COPY_ARG(""); const QLatin1String C2B_FM_CLIENT_COPY_BIN(""); const QLatin1String C2B_FM_CLIENT_MOVE_ARG(""); const QLatin1String C2B_FM_CLIENT_MOVE_BIN(""); #elif defined(Q_OS_MACOS) const QLatin1String C2B_FM_CLIENT_COPY_ARG(""); const QLatin1String C2B_FM_CLIENT_COPY_BIN(""); const QLatin1String C2B_FM_CLIENT_MOVE_ARG(""); const QLatin1String C2B_FM_CLIENT_MOVE_BIN(""); #else // Q_OS_UNIX const QLatin1String C2B_FM_CLIENT_COPY_ARG("copy"); const QLatin1String C2B_FM_CLIENT_COPY_BIN("kfmclient"); const QLatin1String C2B_FM_CLIENT_MOVE_ARG("move"); const QLatin1String C2B_FM_CLIENT_MOVE_BIN("kfmclient"); #endif // To text converter #if defined(Q_OS_WIN) const QLatin1String C2B_METADATAPARSER_EXIFTOOL_BIN("C:\\Windows\\exiftool.exe"); const QLatin1String C2B_PDFIMPORT_PDF2TXT_BIN("C:\\Program Files\\xpdf-3.04-win32\\pdf2cb.exe"); const QLatin1String C2B_BIBSEARCHER_PDF2TXT_BIN("C:\\Program Files\\xpdf-3.04-win32\\pdf2cb.exe"); #elif defined(Q_OS_MACOS) const QLatin1String C2B_METADATAPARSER_EXIFTOOL_BIN("exiftool"); const QLatin1String C2B_BIBSEARCHER_PDF2TXT_BIN("pdftotext"); const QLatin1String C2B_PDFIMPORT_PDF2TXT_BIN("pdftotext"); #else // Q_OS_UNIX const QLatin1String C2B_METADATAPARSER_EXIFTOOL_BIN("exiftool"); const QLatin1String C2B_BIBSEARCHER_PDF2TXT_BIN("pdftotext"); const QLatin1String C2B_PDFIMPORT_PDF2TXT_BIN("pdftotext"); #endif // BibTeX postprocessing #if defined(Q_OS_WIN) const QLatin1String C2B_POSTPROCESS_BIBTEX_BIN("c2btools\\bib2end.bat"); const QLatin1String C2B_POSTPROCESS_BIBTEX_ARG("%finput %foutput"); const QLatin1String C2B_POSTPROCESS_BIBTEX_EXT("end"); #elif defined(Q_OS_MACOS) const QLatin1String C2B_POSTPROCESS_BIBTEX_BIN("c2btools/bib2pdf"); const QLatin1String C2B_POSTPROCESS_BIBTEX_ARG("%finput %foutput"); const QLatin1String C2B_POSTPROCESS_BIBTEX_EXT("bib.pdf"); #else // Q_OS_UNIX const QLatin1String C2B_POSTPROCESS_BIBTEX_BIN("c2btools/bib2pdf"); const QLatin1String C2B_POSTPROCESS_BIBTEX_ARG("%finput %foutput"); const QLatin1String C2B_POSTPROCESS_BIBTEX_EXT("bib.pdf"); #endif #endif cb2bib-2.0.1/src/c2b/PaxHeaders.5700/txtmatcher.cpp0000644000000000000000000000013214011522520016421 xustar0030 mtime=1613145424.670620338 30 atime=1613145424.834620334 30 ctime=1613145424.674620338 cb2bib-2.0.1/src/c2b/txtmatcher.cpp0000644000175000001440000003620414011522520020025 0ustar00constansusers00000000000000/*************************************************************************** * Copyright (C) 2004-2021 by Pere Constans * constans@molspaces.com * cb2Bib version 2.0.1. Licensed under the GNU GPL version 3. * See the LICENSE file that comes with this distribution. ***************************************************************************/ #include "txtmatcher.h" #ifdef C2B_USE_TXTMATCHER_AVX2 #include #endif #ifdef C2B_USE_TXTMATCHER_SSE2 #include #endif static const double _upper_case_letter_frequency[] = { // A B C D E F G H I 0.0461215, 0.0219791, 0.0542205, 0.0247118, 0.0243137, 0.0249272, 0.0155418, 0.0318637, 0.0319445, // J K L M N O P Q R 0.0185178, 0.0110203, 0.0211695, 0.0345829, 0.0251332, 0.0222969, 0.0335058, 0.0034723, 0.0278396, // S T U V W X Y Z 0.0433791, 0.0483445, 0.0070459, 0.0108463, 0.0114125, 0.0053894, 0.0057301, 0.0039877 }; static const double _lower_case_letter_frequency[] = { // a b c d e f g h i 0.6139480, 0.1124940, 0.3052070, 0.2845240, 0.9756860, 0.1816290, 0.1361380, 0.3223960, 0.6192860, // j k l m n o p q r 0.0084664, 0.0315632, 0.3386540, 0.2145900, 0.5768830, 0.5937770, 0.1803630, 0.0162243, 0.5046140, // s t u v w x y z 0.4905200, 0.6968060, 0.2104950, 0.0785456, 0.0858753, 0.0380061, 0.1229070, 0.0193867 }; /** Specialized substring search for English texts */ txtmatcher::txtmatcher() : _case_sensitive(true), _chook(-1), _frequency(10000) {} txtmatcher::txtmatcher(const QString& spattern, const Qt::CaseSensitivity cs, const int chook) { setPattern(spattern, cs, chook); } void txtmatcher::setPattern(const QString& spattern, const Qt::CaseSensitivity cs, const int chook) { _pattern = spattern; _case_sensitive = cs == Qt::CaseSensitive; const int m(_pattern.size()); #ifdef C2B_USE_TXTMATCHER_SCALAR _padded_pattern = _pattern; #else #ifdef C2B_USE_TXTMATCHER_SSE2 _padded_pattern.fill(QChar(65535), std::max(m, 8)); #endif #ifdef C2B_USE_TXTMATCHER_AVX2 _padded_pattern.fill(QChar(65535), std::max(m, 16)); #endif for (int i = 0; i < m; ++i) _padded_pattern[i] = _pattern.at(i); #endif if (_case_sensitive) { _lcp.clear(); _ucp.clear(); } else { // Safe character case folding _lcp = _padded_pattern; for (int i = 0; i < m; ++i) _lcp[i] = _padded_pattern.at(i).toLower(); _ucp = _padded_pattern; for (int i = 0; i < m; ++i) _ucp[i] = _padded_pattern.at(i).toUpper(); } if (chook < 0 || chook >= m) _set_lowest_frequency_character(_pattern, _case_sensitive); else { _chook = chook; _frequency = 0; } } int txtmatcher::indexIn(const QChar* const text, const int length, const int from) const { if (from + _pattern.size() > length) return -1; if (_pattern.size() == 0) // Convention return from; #ifdef C2B_USE_TXTMATCHER_SCALAR if (_case_sensitive) return _find_case_sensitive(reinterpret_cast(text), length, from); else return _find_case_insensitive(reinterpret_cast(text), length, from); #endif #ifdef C2B_USE_TXTMATCHER_SSE2 if (_pattern.size() > 8 || length - from < 5 * 8) { if (_case_sensitive) return _find_case_sensitive(reinterpret_cast(text), length, from); else return _find_case_insensitive(reinterpret_cast(text), length, from); } else { if (_case_sensitive) return _find_case_sensitive_sse2(reinterpret_cast(text), length, from); else return _find_case_insensitive_sse2(reinterpret_cast(text), length, from); } #endif #ifdef C2B_USE_TXTMATCHER_AVX2 if (_pattern.size() > 16 || length - from < 5 * 16) { if (_case_sensitive) return _find_case_sensitive(reinterpret_cast(text), length, from); else return _find_case_insensitive(reinterpret_cast(text), length, from); } else { if (_case_sensitive) return _find_case_sensitive_avx2(reinterpret_cast(text), length, from); else return _find_case_insensitive_avx2(reinterpret_cast(text), length, from); } #endif } void txtmatcher::_set_lowest_frequency_character(const QString& spattern, const bool cs) { const int n(spattern.length()); int lfc(-1); double lf(2); if (cs) for (int l = 0; l < n; ++l) { const ushort lcs(spattern.at(l).unicode()); double cf(0); if (lcs > 96 && lcs < 123) cf = _lower_case_letter_frequency[lcs - 97]; else if (lcs > 64 && lcs < 91) cf = _upper_case_letter_frequency[lcs - 65]; if (cf < lf) { lf = cf; lfc = l; } } else for (int l = 0; l < n; ++l) { const ushort lcu(spattern.at(l).toLower().unicode()); double cf(0); if (lcu > 96 && lcu < 123) cf = _lower_case_letter_frequency[lcu - 97] + _upper_case_letter_frequency[lcu - 97]; if (cf < lf) { lf = cf; lfc = l; } } _chook = lfc; _frequency = 1 + int(1000 * lf); } int txtmatcher::_find_case_sensitive(const ushort* const t, const int length, const int from) const { const int sp(_pattern.size()); const int ch(_chook); const ushort* const p(reinterpret_cast(_pattern.unicode())); const ushort pch(p[ch]); const int a(from + ch), b(length - sp + ch + 1); for (int i = a; i < b; ++i) if (t[i] == pch) { for (int j = 0; j < sp; ++j) if (t[i - ch + j] != p[j]) goto next; return i - ch; next: continue; } return -1; } int txtmatcher::_find_case_insensitive(const ushort* const t, const int length, const int from) const { const int sp(_pattern.size()); const int ch(_chook); const ushort* const lp(reinterpret_cast(_lcp.unicode())); const ushort* const up(reinterpret_cast(_ucp.unicode())); const ushort lpch(lp[ch]); const ushort upch(up[ch]); const int a(from + ch), b(length - sp + ch + 1); for (int i = a; i < b; ++i) if (t[i] == lpch || t[i] == upch) { for (int j = 0; j < sp; ++j) if (t[i - ch + j] != lp[j] && t[i - ch + j] != up[j]) goto next; return i - ch; next: continue; } return -1; } /* SIMD implementations for _find_case_sensitive and _find_case_insensitive Optimizes short substring pattern matching (words and stemmed words) required in context and approximate searches The _find_case_sensitive and _find_case_insensitive routines use effective skipping provided by lowest frequency letters See B Smyth, Computing Patterns in Strings (2003), chapter 8, for a review on search techniques and letter frequency specialization See W Muła, SIMD-friendly algorithms for substring searching (2016), for generic SIMD implementations */ #ifdef C2B_USE_TXTMATCHER_SSE2 static const uint16_t _zpattern_sse2[] = { 0x0, 0x3, 0xf, 0x3f, 0xff, 0x3ff, 0xfff, 0x3fff, 0xffff }; int txtmatcher::_find_case_sensitive_sse2(const ushort* const t, const int length, const int from) const { const int sp(_pattern.size()); const int ch(_chook); const ushort* const p(reinterpret_cast(_padded_pattern.unicode())); const ushort pch(p[ch]); const uint16_t zpattern(_zpattern_sse2[sp]); const __m128i ppattern(_mm_loadu_si128(reinterpret_cast(p))); const __m128i spattern(_mm_set1_epi16(pch)); const int tposition(length - 8 - 7 + 1); int cposition(from + ch); while (cposition < tposition) { __m128i text(_mm_loadu_si128(reinterpret_cast(t + cposition))); const uint16_t zsp(_mm_movemask_epi8(_mm_cmpeq_epi16(text, spattern))); if (zsp == uint16_t(0)) cposition += 8; else { const int ctz(__builtin_ctz(zsp) / 2); cposition += ctz; text = _mm_loadu_si128(reinterpret_cast(t + cposition - ch)); const uint16_t zp(_mm_movemask_epi8(_mm_cmpeq_epi16(text, ppattern))); if (zp == zpattern) return cposition - ch; ++cposition; } } for (int i = cposition; i < length - sp + ch + 1; ++i) if (t[i] == pch) { for (int j = 0; j < sp; ++j) if (t[i - ch + j] != p[j]) goto next; return i - ch; next: continue; } return -1; } int txtmatcher::_find_case_insensitive_sse2(const ushort* const t, const int length, const int from) const { const int sp(_pattern.size()); const int ch(_chook); const ushort* const lp(reinterpret_cast(_lcp.unicode())); const ushort* const up(reinterpret_cast(_ucp.unicode())); const ushort lpch(lp[ch]); const ushort upch(up[ch]); const uint16_t zpattern(_zpattern_sse2[sp]); const __m128i lcpattern(_mm_loadu_si128(reinterpret_cast(lp))); const __m128i ucpattern(_mm_loadu_si128(reinterpret_cast(up))); const __m128i lspattern(_mm_set1_epi16(lpch)); const __m128i uspattern(_mm_set1_epi16(upch)); const int tposition(length - 8 - 7 + 1); int cposition(from + ch); while (cposition < tposition) { __m128i text(_mm_loadu_si128(reinterpret_cast(t + cposition))); const uint16_t zlsp(_mm_movemask_epi8(_mm_cmpeq_epi16(text, lspattern))); const uint16_t zusp(_mm_movemask_epi8(_mm_cmpeq_epi16(text, uspattern))); const uint16_t zsp(zlsp | zusp); if (zsp == uint16_t(0)) cposition += 8; else { const int ctz(__builtin_ctz(zsp) / 2); cposition += ctz; text = _mm_loadu_si128(reinterpret_cast(t + cposition - ch)); const uint16_t zlp(_mm_movemask_epi8(_mm_cmpeq_epi16(text, lcpattern))); const uint16_t zup(_mm_movemask_epi8(_mm_cmpeq_epi16(text, ucpattern))); const uint16_t zp(zlp | zup); if (zp == zpattern) return cposition - ch; ++cposition; } } for (int i = cposition; i < length - sp + ch + 1; ++i) if (t[i] == lpch || t[i] == upch) { for (int j = 0; j < sp; ++j) if (t[i - ch + j] != lp[j] && t[i - ch + j] != up[j]) goto next; return i - ch; next: continue; } return -1; } #endif #ifdef C2B_USE_TXTMATCHER_AVX2 static const uint32_t _zpattern_avx2[] = { 0x0, 0x3, 0xf, 0x3f, 0xff, 0x3ff, 0xfff, 0x3fff, 0xffff, 0x3ffff, 0xfffff, 0x3fffff, 0xffffff, 0x3ffffff, 0xfffffff, 0x3fffffff, 0xffffffff }; int txtmatcher::_find_case_sensitive_avx2(const ushort* const t, const int length, const int from) const { const int sp(_pattern.size()); const int ch(_chook); const ushort* const p(reinterpret_cast(_padded_pattern.unicode())); const ushort pch(p[ch]); const uint32_t zpattern(_zpattern_avx2[sp]); const __m256i ppattern(_mm256_loadu_si256(reinterpret_cast(p))); const __m256i spattern(_mm256_set1_epi16(pch)); const int tposition(length - 16 - 15 + 1); int cposition(from + ch); while (cposition < tposition) { __m256i text(_mm256_loadu_si256(reinterpret_cast(t + cposition))); const uint32_t zsp(_mm256_movemask_epi8(_mm256_cmpeq_epi16(text, spattern))); if (zsp == uint32_t(0)) cposition += 16; else { const int ctz(__builtin_ctz(zsp) / 2); cposition += ctz; text = _mm256_loadu_si256(reinterpret_cast(t + cposition - ch)); const uint32_t zp(_mm256_movemask_epi8(_mm256_cmpeq_epi16(text, ppattern))); if (zp == zpattern) return cposition - ch; ++cposition; } } for (int i = cposition; i < length - sp + ch + 1; ++i) if (t[i] == pch) { for (int j = 0; j < sp; ++j) if (t[i - ch + j] != p[j]) goto next; return i - ch; next: continue; } return -1; } int txtmatcher::_find_case_insensitive_avx2(const ushort* const t, const int length, const int from) const { const int sp(_pattern.size()); const int ch(_chook); const ushort* const lp(reinterpret_cast(_lcp.unicode())); const ushort* const up(reinterpret_cast(_ucp.unicode())); const ushort lpch(lp[ch]); const ushort upch(up[ch]); const uint32_t zpattern(_zpattern_avx2[sp]); const __m256i lcpattern(_mm256_loadu_si256(reinterpret_cast(lp))); const __m256i ucpattern(_mm256_loadu_si256(reinterpret_cast(up))); const __m256i lspattern(_mm256_set1_epi16(lpch)); const __m256i uspattern(_mm256_set1_epi16(upch)); const int tposition(length - 16 - 15 + 1); int cposition(from + ch); while (cposition < tposition) { __m256i text(_mm256_loadu_si256(reinterpret_cast(t + cposition))); const uint32_t zlsp(_mm256_movemask_epi8(_mm256_cmpeq_epi16(text, lspattern))); const uint32_t zusp(_mm256_movemask_epi8(_mm256_cmpeq_epi16(text, uspattern))); const uint32_t zsp(zlsp | zusp); if (zsp == uint32_t(0)) cposition += 16; else { const int ctz(__builtin_ctz(zsp) / 2); cposition += ctz; text = _mm256_loadu_si256(reinterpret_cast(t + cposition - ch)); const uint32_t zlp(_mm256_movemask_epi8(_mm256_cmpeq_epi16(text, lcpattern))); const uint32_t zup(_mm256_movemask_epi8(_mm256_cmpeq_epi16(text, ucpattern))); const uint32_t zp(zlp | zup); if (zp == zpattern) return cposition - ch; ++cposition; } } for (int i = cposition; i < length - sp + ch + 1; ++i) if (t[i] == lpch || t[i] == upch) { for (int j = 0; j < sp; ++j) if (t[i - ch + j] != lp[j] && t[i - ch + j] != up[j]) goto next; return i - ch; next: continue; } return -1; } #endif cb2bib-2.0.1/src/c2b/PaxHeaders.5700/bibParser.h0000644000000000000000000000013214011522520015614 xustar0030 mtime=1613145424.698620338 30 atime=1613145424.830620334 30 ctime=1613145424.698620338 cb2bib-2.0.1/src/c2b/bibParser.h0000644000175000001440000000775414011522520017230 0ustar00constansusers00000000000000/*************************************************************************** * Copyright (C) 2004-2021 by Pere Constans * constans@molspaces.com * cb2Bib version 2.0.1. Licensed under the GNU GPL version 3. * See the LICENSE file that comes with this distribution. ***************************************************************************/ #ifndef BIBPARSER_H #define BIBPARSER_H #include "cb2bib_parameters.h" #include "coreBibParser.h" #include "journalDB.h" #include "monthDB.h" class bibPreparser; class heuristicBibParser; class idMaker; class preprocess; /** Class for bibliographic reference parsing and manipulation @author Pere Constans */ class bibParser : public coreBibParser { Q_OBJECT public: explicit bibParser(QObject* parento = 0); virtual ~bibParser(); QString documentFilename(const QString& base_fn, const QString& bibtex_fn); QString excerpt(const QString& text, const QStringList& hints) const; QString parse(const QString& field, const QString& value, const QString& init_value = QString()); QString setJournalsToAbbreviated(const QString& text, const bool alternate); QString setJournalsToFull(const QString& text, const bool alternate); QString setTags(const QString& text) const; bibReference& parse(bibReference& reference); virtual void setCiteID(); virtual void setField(const QString& name, const QString& value); virtual void setReferenceType(const QString& type); void guessFields(const QString& text); void parse(const QString& text, QString* out_text, QString* out_tagtext); void preparse(const QString& text, QString* out_text); inline QString abbreviatedJournal(const QString& name) const { return _journal_dbP->retrieve(name); } inline QString fullJournal(const QString& name) const { return _journal_dbP->retrieveFull(name); } inline QString alternateAbbreviatedJournal(const QString& name) const { return _journal_dbP->retrieveAlternate(name); } inline QString alternateFullJournal(const QString& name) const { return _journal_dbP->retrieveAlternateFull(name); } inline const QStringList& abbreviatedJournalList() const { return _journal_dbP->abbreviatedList(); } inline bool isAutoRecognized() const { return _auto_recognized; } inline QString autoRecognizedString() const { return _auto_recognized_string; } inline QString toBibTeX(bool sig = true) const { if (sig) return "% cb2Bib " + C2B_VERSION + '\n' + referenceToFomattedBibTeX(_current_reference) + '\n'; else return referenceToFomattedBibTeX(_current_reference); } inline QString toBibTeX(const bibReference& ref, bool sig = true) const { if (sig) return "% cb2Bib " + C2B_VERSION + '\n' + referenceToFomattedBibTeX(ref) + '\n'; else return referenceToFomattedBibTeX(ref); } inline const bibReference& currentReference() const { return _current_reference; } inline void clearCurrentReference() { _current_reference.clearReference(); _auto_recognized = false; _auto_recognized_string.clear(); } inline int fieldCount() const { return coreBibParser::fieldCount(_current_reference); } signals: void statusMessage(const QString& ms); protected: bibPreparser* _preparserP; bibReference _current_reference; idMaker* _cite_idmP; idMaker* _file_idmP; inline virtual void currentReferenceUpdated() {} virtual void checkRegExpFile(const QString& fn); private: QString _auto_recognized_string; QString metadataSection(const QString& text, const QString& identifier) const; QString removeTags(const QString& text) const; bool _auto_recognized; heuristicBibParser* _heuristic_parserP; journalDB* _journal_dbP; monthDB* _month_dbP; preprocess* _preprocessP; friend class heuristicBibParser; }; #endif cb2bib-2.0.1/src/c2b/PaxHeaders.5700/documentContents.h0000644000000000000000000000013214011522520017237 xustar0030 mtime=1613145424.722620337 30 atime=1613145424.834620334 30 ctime=1613145424.722620337 cb2bib-2.0.1/src/c2b/documentContents.h0000644000175000001440000000417214011522520020642 0ustar00constansusers00000000000000/*************************************************************************** * Copyright (C) 2004-2021 by Pere Constans * constans@molspaces.com * cb2Bib version 2.0.1. Licensed under the GNU GPL version 3. * See the LICENSE file that comes with this distribution. ***************************************************************************/ #ifndef DOCUMENTCONTENTS_H #define DOCUMENTCONTENTS_H #include "cb2bib_utilities.h" #include #include class documentContents { public: enum Type { Simplified, Complete }; inline const QString& signature() const { if (!_is_signature_loaded) { _signature = c2bUtils::byteArrayToString(_cache.value(_signature_key)); _is_signature_loaded = true; } return _signature; } inline const QString& text() const { if (!_is_text_loaded) { if (_type == Simplified) _text = c2bUtils::toAscii(c2bUtils::decompressString(_cache.value(_text_key)), c2bUtils::KeepWords); else _text = c2bUtils::decompressString(_cache.value(_text_key)); _is_text_loaded = true; } return _text; } private: inline explicit documentContents(const QHash& cache) : _type(Complete), _cache(cache), _is_signature_loaded(false), _is_text_loaded(false) {} inline ~documentContents() {} inline void clear() { _is_signature_loaded = false; _is_text_loaded = false; _signature.clear(); _signature_key.clear(); _text.clear(); _text_key.clear(); } inline void preload(const QString& skey, const QString& tkey, const Type type) { clear(); _signature_key = skey; _text_key = tkey; _type = type; } QString _signature_key; QString _text_key; Type _type; const QHash& _cache; mutable QString _signature; mutable QString _text; mutable bool _is_signature_loaded; mutable bool _is_text_loaded; friend class documentCache; }; #endif cb2bib-2.0.1/src/c2b/PaxHeaders.5700/arxivXml.cpp0000644000000000000000000000013214011522520016050 xustar0030 mtime=1613145424.578620341 30 atime=1613145424.830620334 30 ctime=1613145424.582620341 cb2bib-2.0.1/src/c2b/arxivXml.cpp0000644000175000001440000000446214011522520017455 0ustar00constansusers00000000000000/*************************************************************************** * Copyright (C) 2004-2021 by Pere Constans * constans@molspaces.com * cb2Bib version 2.0.1. Licensed under the GNU GPL version 3. * See the LICENSE file that comes with this distribution. ***************************************************************************/ #include "arxivXml.h" arxivXml::arxivXml(const QString& xml) : QXmlStreamReader() { _reference.clearReference(); addData(xml); readReference(); } void arxivXml::readReference() { if (hasError()) return; QStringList authors; while (reading("entry")) if (name() == "author") appendAuthor(&authors); else if (name() == "journal_ref") readField("note"); else if (name() == "title") readField("title"); else if (name() == "summary") readField("abstract"); else if (name() == "doi") readField("doi"); else if (name() == "id") processId(); else if (name() == "published") processDate(); _reference["author"] = authors.join(", "); } void arxivXml::readField(const QString& field) { readNext(); _reference[field] = text().toString(); } void arxivXml::processId() { readNext(); QRegExp rxarxiv("abs/(.+)$"); if (text().toString().contains(rxarxiv)) { QString aid(rxarxiv.cap(1)); aid.remove(QRegExp("v\\d{1,2}$")); _reference["eprint"] = aid; _reference["journal"] = "arXiv:" + aid; _reference["url"] = c2bUtils::arxivUrl.arg(aid); } } void arxivXml::processDate() { readNext(); _reference["year"] = text().toString().left(4); } void arxivXml::appendAuthor(QStringList* authors) { while (reading("name")) if (name() == "name") { readNext(); authors->append(text().toString()); } } bool arxivXml::reading(const QString& tag) { if (tokenType() == NoToken) while (!atEnd()) if (readNext() == StartElement && name() == tag) return true; while (!atEnd()) { TokenType t = readNext(); if (t == StartElement) return true; else if (t == EndElement && name() == tag) return false; } return false; } cb2bib-2.0.1/src/PaxHeaders.5700/bookmarkPlugin.h0000644000000000000000000000013214011522520016221 xustar0030 mtime=1613145424.474620344 30 atime=1613145424.830620334 30 ctime=1613145424.478620344 cb2bib-2.0.1/src/bookmarkPlugin.h0000644000175000001440000000160614011522520017623 0ustar00constansusers00000000000000/*************************************************************************** * Copyright (C) 2004-2021 by Pere Constans * constans@molspaces.com * cb2Bib version 2.0.1. Licensed under the GNU GPL version 3. * See the LICENSE file that comes with this distribution. ***************************************************************************/ #ifndef BOOKMARKPLUGIN_H #define BOOKMARKPLUGIN_H #include class c2bFileSystemWatcher; class bookmarkPlugin : public QMenu { Q_OBJECT public: explicit bookmarkPlugin(QWidget* parentw = 0); ~bookmarkPlugin(); signals: void editBookmarks(); void openFile(const QString& fn); private: c2bFileSystemWatcher* _fsw; QString _bookmark_file; QString iconProvider(const QString& fn, const QString& iconFile); private slots: void init(); void openBookmark(); void parseBookmarks(); }; #endif cb2bib-2.0.1/src/PaxHeaders.5700/c2bConfigure.h0000644000000000000000000000013214011522520015545 xustar0030 mtime=1613145424.514620343 30 atime=1613145424.830620334 30 ctime=1613145424.514620343 cb2bib-2.0.1/src/c2bConfigure.h0000644000175000001440000000370214011522520017146 0ustar00constansusers00000000000000/*************************************************************************** * Copyright (C) 2004-2021 by Pere Constans * constans@molspaces.com * cb2Bib version 2.0.1. Licensed under the GNU GPL version 3. * See the LICENSE file that comes with this distribution. ***************************************************************************/ #ifndef C2BCONFIGURE_H #define C2BCONFIGURE_H #include "c2bColors.h" #include "ui_c2bConfigure.h" #include #include class c2bSettings; class c2bConfigure : public QDialog { Q_OBJECT public: explicit c2bConfigure(QWidget* parentw = 0); ~c2bConfigure(); void setPage(int index); protected slots: void FindReplaceDialog_Delete(); void FindReplaceDialog_Edit(); void FindReplaceDialog_New(); void accept(); void apply(); void changeContextColor(QTreeWidgetItem* item); void changePage(QListWidgetItem* current, QListWidgetItem* previous); void comboFamilyChanged(const QString& family); void comboSizeChanged(const QString& pt); void getAnnoteCssFile(); void getBibSearcherPdf2TextBin(); void getBrowserCssFile(); void getCacheDirectory(); void getExifToolBin(); void getFmClientCopyBin(); void getFmClientMoveBin(); void getJournalFile(); void getMathJaxHeaderFile(); void getNetworkFile(); void getPdfDirectory(); void getPdfImportPdf2TextBin(); void getPosLexiconFile(); void getPostprocessBibTeXBin(); void getPreparserBin(); void getRegularExpressionFile(); void help(); void showMessage(const QString& ms); void updateFindReplaceInputButtons(); private: QFont c2bMonoFont; QFont selectedFont(QFontComboBox* fc, QComboBox* sc) const; Ui::c2bConfigure ui; bool event(QEvent* qevent); c2bColors colors; c2bSettings* settings; void fontSelection(const QFont& f, QFontComboBox* fc, QComboBox* sc); void populateFontCombos(); }; #endif cb2bib-2.0.1/src/PaxHeaders.5700/c2bPdfImport.ui0000644000000000000000000000007414011522151015723 xustar0030 atime=1613145424.830620334 30 ctime=1613145424.302620349 cb2bib-2.0.1/src/c2bPdfImport.ui0000644000175000001440000001375514011522151017330 0ustar00constansusers00000000000000 Pere Constans c2bPdfImport 0 0 869 414 true PDFImport - cb2Bib 6 6 Qt::Vertical QFrame::Raised QFrame::StyledPanel QFrame::Raised true 0 0 false Qt::Horizontal QDialogButtonBox::Abort|QDialogButtonBox::Close|QDialogButtonBox::Help Qt::Horizontal QFrame::HLine QFrame::Sunken Qt::Horizontal Miscellaneous 9 6 Qt::Horizontal 40 20 Perform network queries after automatic reference extractions Perform network queries Open document files Open document files Sequence 9 6 Qt::Horizontal 40 20 Process next after saving Process next after saving Unsupervised processing Unsupervised processing PDFlist Log OpenFiles DoNextAfterSaving buttonBox buttonBox rejected() c2bPdfImport reject() 759 428 822 323 cb2bib-2.0.1/src/PaxHeaders.5700/c2bSearchInFilesPatternEdit.ui0000644000000000000000000000007414011522151020642 xustar0030 atime=1613145424.830620334 30 ctime=1613145424.302620349 cb2bib-2.0.1/src/c2bSearchInFilesPatternEdit.ui0000644000175000001440000000446714011522151022247 0ustar00constansusers00000000000000 Pere Constans c2bSearchInFilesPatternEdit 0 0 594 85 Edit Pattern - cb2Bib 6 6 6 6 6 Qt::Horizontal Qt::Horizontal QDialogButtonBox::Cancel|QDialogButtonBox::Ok c2bSearchInFilesPattern QWidget
    c2bSearchInFilesPattern.h
    buttonBox accepted() c2bSearchInFilesPatternEdit accept() 248 254 157 274 buttonBox rejected() c2bSearchInFilesPatternEdit reject() 316 260 286 274
    cb2bib-2.0.1/src/PaxHeaders.5700/c2bCiterView.h0000644000000000000000000000013214011522520015525 xustar0030 mtime=1613145424.502620343 30 atime=1613145424.826620334 30 ctime=1613145424.502620343 cb2bib-2.0.1/src/c2bCiterView.h0000644000175000001440000000335614011522520017133 0ustar00constansusers00000000000000/*************************************************************************** * Copyright (C) 2004-2021 by Pere Constans * constans@molspaces.com * cb2Bib version 2.0.1. Licensed under the GNU GPL version 3. * See the LICENSE file that comes with this distribution. ***************************************************************************/ #ifndef C2BCITERVIEW_H #define C2BCITERVIEW_H #include "c2bCiterModel.h" #include class c2bCiterView : public QTableView { Q_OBJECT public: explicit c2bCiterView(QWidget* parentw = 0); inline ~c2bCiterView() {} c2bCiter::State currentState() const; void reloadModel(QAbstractItemModel* citations, const QStringList& bibtex_files, const c2bCiter::State& s); void setPatternFilter(const QString& pattern); signals: void citeReferences(); void editReference(); void hideCiter(); void openAnnote(); void openFile(); void openUrl(); void patternFilterChanged(const bool mode, const QString& pattern); void statusMessage(const QString& message); protected: void keyPressEvent(QKeyEvent* qevent); void keyboardSearch(const QString& search); void resizeEvent(QResizeEvent* qevent); public slots: void updatePatternFilter(const QString& pattern); private: void clearCurrentFilter(); void keywordDocumentSearch(); void setRelatedFilter(); void showNextState(); void showPreviousState(); void toggleGlossaryView(); void toggleKeywordView(); void toggleSelectedFilter(); void updateCurrentIndex(const QModelIndex& i); void updateFormat(const c2bCiter::Format& format); void updateViewport(); QString _filter_string; bool _filter_mode; c2bCiterModel* _citationsP; }; #endif cb2bib-2.0.1/src/PaxHeaders.5700/c2bCiterHistory.cpp0000644000000000000000000000013214011522520016607 xustar0030 mtime=1613145424.386620347 30 atime=1613145424.826620334 30 ctime=1613145424.386620347 cb2bib-2.0.1/src/c2bCiterHistory.cpp0000644000175000001440000000353614011522520020215 0ustar00constansusers00000000000000/*************************************************************************** * Copyright (C) 2004-2021 by Pere Constans * constans@molspaces.com * cb2Bib version 2.0.1. Licensed under the GNU GPL version 3. * See the LICENSE file that comes with this distribution. ***************************************************************************/ #include "c2bCiterHistory.h" static const int _maximum_history_states(35); c2bCiterHistory::c2bCiterHistory() { _last_citation_format = c2bCiter::AJYT; _index.resize(_maximum_history_states); _states.resize(_maximum_history_states); clear(); } void c2bCiterHistory::clear() { _last_citation = 0; _last_keyword = 0; _last_selection_citation = 0; _last_nonkeyword_state = c2bCiter::State(); _last_nonselected_state = c2bCiter::State(); _cstate = -1; _nstates = -1; for (int i = 0; i < _maximum_history_states; ++i) _index[i] = i; } void c2bCiterHistory::saveCurrentState(const c2bCiter::Format format, const c2bCiter::Filter filter, const int iindex, const int vindex, const QString fstring) { if (_cstate != -1) _nstates = _cstate - 1; _cstate = -1; const c2bCiter::State s(format, filter, vindex, fstring); if (_nstates > -1 && s == _states[_index[_nstates]]) return; if (++_nstates >= _maximum_history_states) { // Move, e.g., 0 1 2 3 4 to 1 2 3 4 0 const int oldest(_index[0]); for (int i = 0; i < _maximum_history_states - 1; ++i) _index[i] = _index[i + 1]; _index[--_nstates] = oldest; } _states[_index[_nstates]] = s; if (format != c2bCiter::K) { _last_nonkeyword_state = s; if (filter != c2bCiter::Selected) _last_nonselected_state = s; } saveCurrentItemIndex(format, filter, iindex); } cb2bib-2.0.1/src/PaxHeaders.5700/c2bClipEdit.cpp0000644000000000000000000000013214011522520015654 xustar0030 mtime=1613145424.398620346 30 atime=1613145424.826620334 30 ctime=1613145424.398620346 cb2bib-2.0.1/src/c2bClipEdit.cpp0000644000175000001440000000754314011522520017264 0ustar00constansusers00000000000000/*************************************************************************** * Copyright (C) 2004-2021 by Pere Constans * constans@molspaces.com * cb2Bib version 2.0.1. Licensed under the GNU GPL version 3. * See the LICENSE file that comes with this distribution. ***************************************************************************/ #include "c2bClipEdit.h" #include "c2b.h" #include "c2bBibHighlighter.h" #include "c2bHighlighter.h" #include #include #include #include #include c2bClipEdit::c2bClipEdit(const Mode mode, QWidget* parentw) : QPlainTextEdit(parentw) { setFrameShape(QPlainTextEdit::StyledPanel); setFrameShadow(QPlainTextEdit::Raised); viewport()->setAcceptDrops(false); _has_selecting_ended = false; _is_tagged_view = false; if (mode == Editor) { new c2bHighlighter(document()); setReadOnly(false); connect(this, SIGNAL(selectionChanged()), this, SLOT(selectionHasChanged())); } else if (mode == Browser) { new c2bBibHighlighter(document()); setReadOnly(true); } } c2bClipEdit::~c2bClipEdit() {} void c2bClipEdit::setText(const QString& text, const QString& tagged_text) { _text = text; if (tagged_text.isEmpty()) _tagged_text = text; else _tagged_text = tagged_text; if (_is_tagged_view) setPlainText(_tagged_text); else setPlainText(_text); } void c2bClipEdit::insertTag(const QString& tag) { if (_is_tagged_view) insertPlainText(tag); else insertPlainText("[[" + textCursor().selectedText() + "]]"); } void c2bClipEdit::setTaggedViewMode(bool tagged_view) { _is_tagged_view = tagged_view; if (_is_tagged_view) { _text = toPlainText(); setPlainText(_tagged_text); } else { _tagged_text = toPlainText(); setPlainText(_text); } } void c2bClipEdit::updatePlainText(const QString& text) { const int scrollPosition(verticalScrollBar()->value()); setPlainText(text); verticalScrollBar()->setValue(scrollPosition); } void c2bClipEdit::keyPressEvent(QKeyEvent* qevent) { _has_selecting_ended = false; QPlainTextEdit::keyPressEvent(qevent); } void c2bClipEdit::keyReleaseEvent(QKeyEvent* qevent) { QPlainTextEdit::keyReleaseEvent(qevent); if (_has_selecting_ended && qevent->key() == Qt::Key_Shift) if (textCursor().hasSelection()) { _has_selecting_ended = false; emit userEndedSelection(mapToGlobal(cursorRect().topLeft())); } } void c2bClipEdit::mouseReleaseEvent(QMouseEvent* qevent) { QPlainTextEdit::mouseReleaseEvent(qevent); if (qevent->button() == Qt::LeftButton) if (textCursor().hasSelection()) emit userEndedSelection(QCursor::pos()); _has_selecting_ended = false; } void c2bClipEdit::selectionHasChanged() { _has_selecting_ended = textCursor().hasSelection(); } void c2bClipEdit::contextMenuEvent(QContextMenuEvent* qevent) { QMenu* edit_menu = createStandardContextMenu(); edit_menu->setTitle(tr("Edit...")); QList acts = edit_menu->actions(); if (!isReadOnly()) { QAction* act; act = new QAction(tr("Clear"), edit_menu); act->setEnabled(acts.last()->isEnabled()); // As is Select All connect(act, SIGNAL(triggered()), this, SLOT(clear())); edit_menu->insertAction(acts.at(7), act); } QMenu* menu = new QMenu(this); menu->addMenu(edit_menu); menu->addSeparator(); acts = c2b::netqinf()->bookmarkActions(textCursor().selectedText()); for (int i = 0; i < acts.count(); ++i) menu->addAction(acts.at(i)); acts = actions(); for (int i = 0; i < acts.count(); ++i) menu->addAction(acts.at(i)); menu->exec(qevent->globalPos()); delete edit_menu; delete menu; } cb2bib-2.0.1/src/PaxHeaders.5700/c2bPostprocess.cpp0000644000000000000000000000013214011522520016503 xustar0030 mtime=1613145424.434620345 30 atime=1613145424.826620334 30 ctime=1613145424.438620345 cb2bib-2.0.1/src/c2bPostprocess.cpp0000644000175000001440000001120414011522520020100 0ustar00constansusers00000000000000/*************************************************************************** * Copyright (C) 2004-2021 by Pere Constans * constans@molspaces.com * cb2Bib version 2.0.1. Licensed under the GNU GPL version 3. * See the LICENSE file that comes with this distribution. ***************************************************************************/ #include "c2bPostprocess.h" #include "c2b.h" #include "c2bSettings.h" #include "c2bUtils.h" #include #include #include #include c2bPostprocess::c2bPostprocess(const QString& fn, QWidget* parentw) : QDialog(parentw) { ui.setupUi(this); setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint); setWindowTitle(tr("BibTeX Postprocessing Log - cb2Bib")); setAttribute(Qt::WA_DeleteOnClose); _buttonOpenFile = new QPushButton(tr("&Open File")); ui.buttonBox->addButton(_buttonOpenFile, QDialogButtonBox::ActionRole); _buttonOpenFile->setAutoDefault(true); _buttonOpenFile->setDefault(true); _buttonOpenFile->setEnabled(false); ui.buttonBox->button(QDialogButtonBox::Close)->setEnabled(false); connect(ui.buttonBox, SIGNAL(helpRequested()), this, SLOT(help())); connect(_buttonOpenFile, SIGNAL(clicked()), this, SLOT(openFile())); c2bSettings* settings(c2bSettingsP); resize(settings->value("c2bLogWidget/size", size()).toSize()); PPBIBTEX_BIN = settings->fileName("cb2Bib/PostprocessBibTeXBin"); PPBIBTEX_ARG = settings->value("cb2Bib/PostprocessBibTeXArg").toString(); PPBIBTEX_EXT = settings->value("cb2Bib/PostprocessBibTeXExt").toString(); QFile f(fn); if (!f.open(QIODevice::ReadOnly | QIODevice::Text)) { QMessageBox::warning(parentw, tr("Warning - cb2Bib"), tr("Unable to open the file %1 for reading.\nError: '%2'.").arg(fn, f.errorString()), QMessageBox::Ok); ui.buttonBox->button(QDialogButtonBox::Close)->setEnabled(true); ui.buttonBox->button(QDialogButtonBox::Close)->setFocus(); ui.Log->appendPlainText(tr("BibTeX Post Processing: Erroneous termination.\n")); } else { f.close(); _bib = fn; QFileInfo fi(fn); _out = QDir::toNativeSeparators(fi.absolutePath() + '/' + fi.baseName() + '.' + PPBIBTEX_EXT); QString cargs(PPBIBTEX_ARG); cargs.replace("%finput", _bib); cargs.replace("%foutput", _out); ui.Log->appendPlainText(tr("BibTeX Post Processing Command:\n%1 %2\n").arg(PPBIBTEX_BIN, cargs)); PProcessFile(); } } c2bPostprocess::~c2bPostprocess() { c2bSettingsP->setValue("c2bLogWidget/size", size()); } void c2bPostprocess::PProcessFile() { // Postprocessing BibTeX const QStringList arglist(PPBIBTEX_ARG.split(' ', QString::SkipEmptyParts)); QStringList args; for (int i = 0; i < arglist.count(); i++) { if (arglist.at(i) == "%finput") args.append(_bib); else if (arglist.at(i) == "%foutput") args.append(_out); else args.append(arglist.at(i)); } _ppBibTeX = new QProcess(this); connect(_ppBibTeX, SIGNAL(finished(int,QProcess::ExitStatus)), this, SLOT(conversionEnded())); _ppBibTeX->start(PPBIBTEX_BIN, args); if (!_ppBibTeX->waitForStarted()) { ui.Log->appendPlainText(tr("Failed to call %1.").arg(PPBIBTEX_BIN)); ui.buttonBox->button(QDialogButtonBox::Close)->setEnabled(true); ui.buttonBox->button(QDialogButtonBox::Close)->setFocus(); delete _ppBibTeX; } } void c2bPostprocess::conversionEnded() { addToLog(); ui.buttonBox->button(QDialogButtonBox::Close)->setEnabled(true); if (QFileInfo(_out).isReadable()) { _buttonOpenFile->setEnabled(true); _buttonOpenFile->setFocus(); } else { ui.buttonBox->button(QDialogButtonBox::Close)->setAutoDefault(true); ui.buttonBox->button(QDialogButtonBox::Close)->setDefault(true); ui.buttonBox->button(QDialogButtonBox::Close)->setFocus(); } ui.Log->appendPlainText(tr("\n\nBibTeX Post Processing Command Ended.")); delete _ppBibTeX; } void c2bPostprocess::addToLog() { QString log(QString::fromUtf8(_ppBibTeX->readAllStandardOutput().trimmed())); if (!log.isEmpty()) ui.Log->appendPlainText(log); log = QString::fromUtf8(_ppBibTeX->readAllStandardError().trimmed()); if (!log.isEmpty()) ui.Log->appendPlainText(log); } void c2bPostprocess::openFile() { c2bUtils::openFile(_out, this); close(); } void c2bPostprocess::help() { c2bUtils::displayHelp("https://www.molspaces.com/cb2bib/doc/overview/#additional-keyboard-functionality"); } cb2bib-2.0.1/src/PaxHeaders.5700/c2bCiterView.cpp0000644000000000000000000000013214011522520016060 xustar0030 mtime=1613145424.390620346 30 atime=1613145424.826620334 30 ctime=1613145424.390620346 cb2bib-2.0.1/src/c2bCiterView.cpp0000644000175000001440000002705514011522520017470 0ustar00constansusers00000000000000/*************************************************************************** * Copyright (C) 2004-2021 by Pere Constans * constans@molspaces.com * cb2Bib version 2.0.1. Licensed under the GNU GPL version 3. * See the LICENSE file that comes with this distribution. ***************************************************************************/ #include "c2bCiterView.h" #include "c2bCiterExcerptView.h" #include #include #include #include c2bCiterView::c2bCiterView(QWidget* parentw) : QTableView(parentw) { setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); setShowGrid(false); setTabKeyNavigation(true); setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); setVerticalScrollMode(QAbstractItemView::ScrollPerPixel); horizontalHeader()->setSectionResizeMode(QHeaderView::Fixed); horizontalHeader()->setVisible(false); verticalHeader()->setDefaultSectionSize(fontMetrics().height() + 5); verticalHeader()->setSectionResizeMode(QHeaderView::Fixed); verticalHeader()->setVisible(false); _citationsP = 0; _filter_mode = false; } void c2bCiterView::reloadModel(QAbstractItemModel* citations, const QStringList& bibtex_files, const c2bCiter::State& s) { _filter_mode = false; _filter_string.clear(); if (!citations) return; if (_citationsP != citations) { _citationsP = static_cast(citations); QTableView::setModel(_citationsP); connect(_citationsP, SIGNAL(patternFilterChanged(QString)), this, SLOT(updatePatternFilter(QString))); } QModelIndex i(currentIndex()); _citationsP->reloadCitations(bibtex_files, s, &i); updateViewport(); updateCurrentIndex(i); } c2bCiter::State c2bCiterView::currentState() const { if (_citationsP) return _citationsP->currentState(currentIndex()); else return c2bCiter::State(); } void c2bCiterView::showPreviousState() { QModelIndex i(currentIndex()); _citationsP->restorePreviousState(&i); updateViewport(); updateCurrentIndex(i); } void c2bCiterView::showNextState() { QModelIndex i(currentIndex()); _citationsP->restoreNextState(&i); updateViewport(); updateCurrentIndex(i); } void c2bCiterView::clearCurrentFilter() { QModelIndex i(currentIndex()); _citationsP->clearCurrentFilter(&i); updateViewport(); updateCurrentIndex(i); } void c2bCiterView::setPatternFilter(const QString& pattern) { QModelIndex i(currentIndex()); _filter_string = pattern; _citationsP->setPatternFilter(_filter_string, &i, _citationsP->currentFormat()); updateViewport(); updateCurrentIndex(i); } void c2bCiterView::updatePatternFilter(const QString& pattern) { _filter_string = pattern; emit patternFilterChanged(false, _filter_string); } void c2bCiterView::setRelatedFilter() { if (_citationsP->count() == 0) return; QModelIndex i(currentIndex()); if (_citationsP->currentFormat() == c2bCiter::K) { const QString k(_citationsP->dataKeyword(i)); _citationsP->setKeywordFilter(k, &i); updateViewport(); updateCurrentIndex(i); } else { const QString f(_citationsP->dataFile(i)); if (f.isEmpty()) emit statusMessage(tr("No File contents in this reference.")); else { _citationsP->setRelatedFilter(f, &i); updateViewport(); updateCurrentIndex(i); } } } void c2bCiterView::toggleSelectedFilter() { QModelIndex i(currentIndex()); if (_citationsP->currentFilter() == c2bCiter::Selected) _citationsP->restoreLastNonSelectedState(&i); else _citationsP->setSelectedFilter(&i); updateViewport(); updateCurrentIndex(i); } void c2bCiterView::toggleKeywordView() { if (_citationsP->count() == 0) return; QModelIndex i(currentIndex()); if (_citationsP->currentFormat() == c2bCiter::K) { _citationsP->restoreLastNonKeywordState(&i); updateViewport(); updateCurrentIndex(i); } else { const QString f(_citationsP->dataFile(i)); if (f.isEmpty()) emit statusMessage(tr("No File contents in this reference.")); else { _citationsP->setDocumentFilter(f, &i); updateViewport(); updateCurrentIndex(i); } } } void c2bCiterView::toggleGlossaryView() { QModelIndex i(currentIndex()); if (_citationsP->currentFormat() == c2bCiter::K && (_citationsP->currentFilter() == c2bCiter::None || _citationsP->currentFilter() == c2bCiter::Pattern)) _citationsP->restoreLastNonKeywordState(&i); else _citationsP->setGlossaryView(&i); updateViewport(); updateCurrentIndex(i); } void c2bCiterView::keywordDocumentSearch() { const c2bCiter::KeywordData kd(_citationsP->keywordData(currentIndex())); if (!kd.valid) return; QApplication::setOverrideCursor(QCursor(Qt::WaitCursor)); const QString excerpt(bibSearcher::searchDocumentKeyword(kd.bibtexfn, kd.documentfn, kd.keyword)); QApplication::restoreOverrideCursor(); if (excerpt.isEmpty()) { emit statusMessage(tr("Keyword variation '%1' not available in this reference.").arg(kd.keyword)); return; } c2bCiterExcerptView cev(excerpt, this); cev.exec(); } void c2bCiterView::updateCurrentIndex(const QModelIndex& i) { setCurrentIndex(i); scrollTo(i, PositionAtCenter); } void c2bCiterView::updateFormat(const c2bCiter::Format& format) { if (!_citationsP) return; QModelIndex i(currentIndex()); _citationsP->updateFormat(format, &i); updateViewport(); updateCurrentIndex(i); } void c2bCiterView::updateViewport() { if (!_citationsP) return; const int nc(_citationsP->columnCount()); if (nc < 1) return; const int vp_w(viewport()->size().width()); if (nc == 1) { setColumnWidth(0, vp_w); return; } QList w = _citationsP->sizeHintForColumns(); #if QT_VERSION >= QT_VERSION_CHECK(5, 11, 0) const int char_w(fontMetrics().horizontalAdvance(QLatin1Char('N'))); #else const int char_w(fontMetrics().width(QLatin1Char('N'))); #endif for (int i = 0; i < nc; ++i) w[i] *= char_w; int required_w(w.at(0)); if (required_w >= vp_w) { setColumnWidth(0, vp_w); for (int i = 1; i < nc; ++i) setColumnWidth(i, 0); return; } for (int i = 1; i < nc; ++i) required_w += w.at(i); if (required_w > vp_w) { int available_w(vp_w - w.at(0)); int div[] = { 0, 0, 0, 0 }; while (available_w > 0) for (int i = 1; i < nc; ++i) if (div[i] < w.at(i)) { div[i] += 1; --available_w; } for (int i = 1; i < nc; ++i) w[i] = div[i]; } else w[nc - 1] += vp_w - required_w; for (int i = 0; i < nc; ++i) setColumnWidth(i, w.at(i)); } void c2bCiterView::keyPressEvent(QKeyEvent* qevent) { if (_filter_mode) { switch (qevent->key()) { case Qt::Key_Enter: case Qt::Key_Return: case Qt::Key_Down: case Qt::Key_Escape: case Qt::Key_Up: case Qt::Key_Tab: _filter_mode = false; emit patternFilterChanged(_filter_mode, _filter_string); qevent->accept(); return; } switch (qevent->key()) { case Qt::Key_Backspace: _filter_string.chop(1); break; default: _filter_string += c2bUtils::toAscii(qevent->text(), c2bUtils::Collation); } emit patternFilterChanged(_filter_mode, _filter_string); setPatternFilter(_filter_string); qevent->ignore(); return; } if (qevent->modifiers() & Qt::ShiftModifier) { if (!qevent->text().isEmpty()) QTableView::keyboardSearch(qevent->text()); qevent->accept(); return; } switch (qevent->key()) { // Formats case Qt::Key_A: updateFormat(c2bCiter::AJYT); qevent->accept(); return; case Qt::Key_I: updateFormat(c2bCiter::IT); qevent->accept(); return; case Qt::Key_J: updateFormat(c2bCiter::JYA); qevent->accept(); return; case Qt::Key_T: updateFormat(c2bCiter::T); qevent->accept(); return; case Qt::Key_Y: updateFormat(c2bCiter::YAJT); qevent->accept(); return; // Filters case Qt::Key_Delete: _citationsP->clearSelection(); qevent->accept(); return; case Qt::Key_D: clearCurrentFilter(); qevent->accept(); return; case Qt::Key_F: _filter_mode = true; emit patternFilterChanged(_filter_mode, _filter_string); qevent->accept(); return; case Qt::Key_G: toggleGlossaryView(); qevent->accept(); return; case Qt::Key_K: toggleKeywordView(); qevent->accept(); return; case Qt::Key_R: setRelatedFilter(); qevent->accept(); return; case Qt::Key_S: toggleSelectedFilter(); qevent->accept(); return; // Actions case Qt::Key_Left: showPreviousState(); qevent->accept(); return; case Qt::Key_Right: showNextState(); qevent->accept(); return; case Qt::Key_C: emit citeReferences(); qevent->accept(); return; case Qt::Key_E: emit editReference(); qevent->accept(); return; case Qt::Key_O: emit openFile(); qevent->accept(); return; case Qt::Key_U: emit openUrl(); qevent->accept(); return; case Qt::Key_V: keywordDocumentSearch(); qevent->accept(); return; case Qt::Key_W: emit openAnnote(); qevent->accept(); return; case Qt::Key_Escape: emit hideCiter(); qevent->accept(); return; // Navigation case Qt::Key_Tab: { QKeyEvent ke(QEvent::KeyPress, Qt::Key_Down, Qt::NoModifier); QTableView::keyPressEvent(&ke); qevent->accept(); return; } case Qt::Key_Backspace: { QKeyEvent ke(QEvent::KeyPress, Qt::Key_Up, Qt::NoModifier); QTableView::keyPressEvent(&ke); qevent->accept(); return; } case Qt::Key_Home: { QKeyEvent ke(QEvent::KeyPress, Qt::Key_Home, Qt::ControlModifier); QTableView::keyPressEvent(&ke); qevent->accept(); return; } case Qt::Key_End: { QKeyEvent ke(QEvent::KeyPress, Qt::Key_End, Qt::ControlModifier); QTableView::keyPressEvent(&ke); qevent->accept(); return; } case Qt::Key_Space: { QKeyEvent ke(QEvent::KeyPress, Qt::Key_PageDown, Qt::NoModifier); QTableView::keyPressEvent(&ke); qevent->accept(); return; } case Qt::Key_Enter: case Qt::Key_Return: { QTableView::keyPressEvent(qevent); QKeyEvent ke(QEvent::KeyPress, Qt::Key_Down, Qt::NoModifier); QTableView::keyPressEvent(&ke); qevent->accept(); return; } default: QTableView::keyPressEvent(qevent); qevent->ignore(); } } void c2bCiterView::resizeEvent(QResizeEvent* qevent) { updateViewport(); QTableView::resizeEvent(qevent); } void c2bCiterView::keyboardSearch(const QString& /* search */) {} cb2bib-2.0.1/src/PaxHeaders.5700/c2bBibPreparserLog.cpp0000644000000000000000000000013214011522520017201 xustar0030 mtime=1613145424.382620347 30 atime=1613145424.818620334 30 ctime=1613145424.382620347 cb2bib-2.0.1/src/c2bBibPreparserLog.cpp0000644000175000001440000000372314011522520020605 0ustar00constansusers00000000000000/*************************************************************************** * Copyright (C) 2004-2021 by Pere Constans * constans@molspaces.com * cb2Bib version 2.0.1. Licensed under the GNU GPL version 3. * See the LICENSE file that comes with this distribution. ***************************************************************************/ #include "c2bBibPreparserLog.h" #include "c2b.h" #include "c2bSettings.h" #include "c2bUtils.h" #include #include c2bBibPreparserLog::c2bBibPreparserLog(QWidget* parentw) : QDialog(parentw) { ui.setupUi(this); setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint); setWindowTitle(tr("Clipboard Preparsing Log - cb2Bib")); PreparserShowLog = new QCheckBox(); PreparserShowLog->setObjectName(QString::fromUtf8("PreparserShowLog")); PreparserShowLog->setLayoutDirection(Qt::RightToLeft); PreparserShowLog->setText(QApplication::translate("c2bBibPreparserLog", "Do not show log", 0)); ui.buttonBox->addButton(PreparserShowLog, QDialogButtonBox::ActionRole); connect(ui.buttonBox, SIGNAL(helpRequested()), this, SLOT(help())); connect(this, SIGNAL(finished(int)), this, SLOT(close())); } c2bBibPreparserLog::~c2bBibPreparserLog() {} void c2bBibPreparserLog::append(const QString& ms) { ui.Log->appendPlainText(ms); } void c2bBibPreparserLog::show() { resize(c2bSettingsP->value("c2bLogWidget/size", size()).toSize()); ui.buttonBox->button(QDialogButtonBox::Close)->setFocus(); QDialog::show(); } void c2bBibPreparserLog::closeEvent(QCloseEvent* qevent) { ui.Log->clear(); if (PreparserShowLog->isChecked()) c2bSettingsP->setValue("cb2Bib/PreparserShowLog", false); PreparserShowLog->setChecked(false); c2bSettingsP->setValue("c2bLogWidget/size", size()); qevent->accept(); } void c2bBibPreparserLog::help() { c2bUtils::displayHelp("https://www.molspaces.com/cb2bib/doc/overview/#additional-keyboard-functionality"); } cb2bib-2.0.1/src/PaxHeaders.5700/c2bExportDialog.cpp0000644000000000000000000000013214011522520016560 xustar0030 mtime=1613145424.418620346 30 atime=1613145424.826620334 30 ctime=1613145424.418620346 cb2bib-2.0.1/src/c2bExportDialog.cpp0000644000175000001440000001133414011522520020161 0ustar00constansusers00000000000000/*************************************************************************** * Copyright (C) 2004-2021 by Pere Constans * constans@molspaces.com * cb2Bib version 2.0.1. Licensed under the GNU GPL version 3. * See the LICENSE file that comes with this distribution. ***************************************************************************/ #include "c2bExportDialog.h" #include "c2b.h" #include "c2bFileDialog.h" #include "c2bSettings.h" #include "c2bUtils.h" #include #include c2bExportDialog::c2bExportDialog(const QString& fn, const QString& contents, const QStringList& keys, QWidget* parentw) : QDialog(parentw) { setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint); _ed.bibtex_fn = fn; if (contents.isEmpty()) _ed.bibtex_contents = c2bUtils::fileToString(fn); else _ed.bibtex_contents = contents; _ed.bibtex_keys = keys; ui.setupUi(this); setWindowTitle(tr("Export Entries - cb2Bib")); QPushButton* buttonExport = new QPushButton(tr("Export")); ui.buttonBox->addButton(buttonExport, QDialogButtonBox::ActionRole); buttonExport->setAutoDefault(true); buttonExport->setDefault(true); connect(buttonExport, SIGNAL(clicked()), this, SLOT(_export())); settings = c2bSettingsP; ui.ExportFile->setText(settings->value("c2bExportDialog/ExportFile", QString()).toString()); ui.DocumentsDirectory->setText(settings->value("c2bExportDialog/DocumentsDirectory", QString()).toString()); ui.CopyDocuments->setChecked(settings->value("c2bExportDialog/CopyDocuments").toBool()); ui.RelativeDocumentDirectory->setChecked(settings->value("c2bExportDialog/RelativeDocumentDirectory").toBool()); ui.DocumentsDirectoryBox->setEnabled(ui.CopyDocuments->isChecked()); connect(ui.ExportFileDir, SIGNAL(clicked()), this, SLOT(getExportFile())); connect(ui.DocumentsDirectoryDir, SIGNAL(clicked()), this, SLOT(getDocumentsDirectory())); connect(ui.buttonBox, SIGNAL(helpRequested()), this, SLOT(help())); } c2bExportDialog::~c2bExportDialog() { if (result() == QDialog::Accepted) { settings->setValue("c2bExportDialog/CopyDocuments", ui.CopyDocuments->isChecked()); settings->setValue("c2bExportDialog/DocumentsDirectory", ui.DocumentsDirectory->text()); settings->setValue("c2bExportDialog/ExportFile", ui.ExportFile->text()); settings->setValue("c2bExportDialog/RelativeDocumentDirectory", ui.RelativeDocumentDirectory->isChecked()); } } void c2bExportDialog::_export() { _ed.copy_documents = ui.CopyDocuments->isChecked(); _ed.documents_dir = ui.DocumentsDirectory->text(); _ed.export_fn = ui.ExportFile->text(); _ed.relative_dir = ui.RelativeDocumentDirectory->isChecked(); // Check files if (QFileInfo::exists(_ed.export_fn)) { const int button(QMessageBox::warning( this, tr("Warning - cb2Bib"), tr("File %1 already exists.\nDo you want to replace it?").arg(_ed.export_fn), QMessageBox::Yes | QMessageBox::No)); if (button == QMessageBox::No) return; } if (_ed.copy_documents) { const QString ddname( c2bUtils::documentAbsoluteName(_ed.relative_dir, _ed.export_fn, _ed.documents_dir, QString()) + QDir::separator()); QDir doc_dir(ddname); if (!doc_dir.exists()) if (!doc_dir.mkpath(ddname)) { QMessageBox::warning(this, tr("Warning - cb2Bib"), tr("Unable to create directory %1.").arg(ddname), QMessageBox::Ok); return; } } QApplication::setOverrideCursor(QCursor(Qt::WaitCursor)); c2bExport e(this); e.exportEntries(_ed); QApplication::restoreOverrideCursor(); accept(); } void c2bExportDialog::getExportFile() { const QString fn(ui.ExportFile->text()); const QString new_fn(c2bFileDialog::getFilename(this, tr("Select export filename"), fn, "BibTeX (*.bib)")); if (!new_fn.isEmpty()) ui.ExportFile->setText(new_fn); } void c2bExportDialog::getDocumentsDirectory() { const QString dir(c2bUtils::documentAbsoluteName(ui.RelativeDocumentDirectory->isChecked(), ui.ExportFile->text(), ui.DocumentsDirectory->text(), QString())); QString new_dir(c2bFileDialog::getExistingDirectory(this, tr("Select documents directory"), dir)); if (!new_dir.isEmpty()) { new_dir = c2bUtils::documentDirName(ui.RelativeDocumentDirectory->isChecked(), ui.ExportFile->text(), new_dir); ui.DocumentsDirectory->setText(new_dir); } } void c2bExportDialog::help() { c2bUtils::displayHelp("https://www.molspaces.com/cb2bib/doc/bibeditor/#export-selected-entries"); } cb2bib-2.0.1/src/PaxHeaders.5700/c2bCiterWidget.cpp0000644000000000000000000000013214011522520016371 xustar0030 mtime=1613145424.394620346 30 atime=1613145424.826620334 30 ctime=1613145424.394620346 cb2bib-2.0.1/src/c2bCiterWidget.cpp0000644000175000001440000002712114011522520017773 0ustar00constansusers00000000000000/*************************************************************************** * Copyright (C) 2004-2021 by Pere Constans * constans@molspaces.com * cb2Bib version 2.0.1. Licensed under the GNU GPL version 3. * See the LICENSE file that comes with this distribution. ***************************************************************************/ #include "c2bCiterWidget.h" #include "c2b.h" #include "c2bCiterModel.h" #include "c2bClipboard.h" #include "c2bCollectionIndex.h" #include "c2bCoreCiter.h" #include "c2bFileDialog.h" #include "c2bSettings.h" #include "c2bUtils.h" #include #include #include c2bCiterWidget::c2bCiterWidget(QWidget* parentw) : QWidget(parentw) { ui.setupUi(this); ui.clipboardIcon->setVisible(true); ui.filterIcon->setVisible(false); _citerP = new c2bCoreCiter(this); _tray_icon = 0; setActions(); _settingsP = c2bSettingsP; resize(_settingsP->value("c2bCiter/size", size()).toSize()); move(_settingsP->value("c2bCiter/position", pos()).toPoint()); _clipboard_connected = true; _citations = new c2bCiterModel(this); connect(_citations, SIGNAL(statusLabel(QString)), this, SLOT(showLabel(QString))); connect(_citations, SIGNAL(statusMessage(QString)), this, SLOT(showMessage(QString))); connect(c2b::clipboard(), SIGNAL(cbDataChanged(QString)), this, SLOT(filterDataChanged(QString))); connect(ui.citationsView, SIGNAL(activated(QModelIndex)), _citations, SLOT(selectCitation(QModelIndex))); connect(ui.citationsView, SIGNAL(citeReferences()), this, SLOT(citeReferences())); connect(ui.citationsView, SIGNAL(editReference()), this, SLOT(editReference())); connect(ui.citationsView, SIGNAL(hideCiter()), this, SLOT(hide())); connect(ui.citationsView, SIGNAL(openAnnote()), this, SIGNAL(openAnnote())); connect(ui.citationsView, SIGNAL(openFile()), this, SLOT(openFile())); connect(ui.citationsView, SIGNAL(openUrl()), this, SLOT(openUrl())); connect(ui.citationsView, SIGNAL(patternFilterChanged(bool,QString)), this, SLOT(updatePatternFilter(bool,QString))); connect(ui.citationsView, SIGNAL(statusMessage(QString)), this, SLOT(showMessage(QString))); } c2bCiterWidget::~c2bCiterWidget() { if (!isFullScreen()) { _settingsP->setValue("c2bCiter/position", pos()); _settingsP->setValue("c2bCiter/size", size()); } _settingsP->setValue("c2bCiter/format", static_cast(_citations->lastCitationFormat())); } void c2bCiterWidget::load() { _bibtex_files.clear(); if (_settingsP->cl_citer_filenames.count() == 0) _bibtex_files = c2bUtils::filesInDir(QFileInfo(_settingsP->fileName("cb2Bib/BibTeXFile")).absolutePath(), QStringList() << "*.bib"); else for (int i = 0; i < _settingsP->cl_citer_filenames.count(); ++i) _bibtex_files += c2bUtils::filesInDir(_settingsP->cl_citer_filenames.at(i), QStringList() << "*.bib"); c2bCiter::State state; state.format = static_cast(_settingsP->value("c2bCiter/format", state.format).toInt()); reload(state); } void c2bCiterWidget::reload() { const c2bCiter::State state(ui.citationsView->currentState()); reload(state); } void c2bCiterWidget::reload(const c2bCiter::State& state) { QApplication::setOverrideCursor(QCursor(Qt::WaitCursor)); updatePatternFilter(false, QString()); if (_bibtex_files.count() == 1) setWindowTitle( tr("%1 - cb2Bib").arg(QDir::toNativeSeparators(QFileInfo(_bibtex_files.at(0)).absoluteFilePath()))); else if (_bibtex_files.count() > 1) setWindowTitle(tr("%1 - cb2Bib").arg(QDir::toNativeSeparators(QFileInfo(_bibtex_files.at(0)).absolutePath()))); else setWindowTitle(tr("Citer - cb2Bib")); ui.citationsView->reloadModel(_citations, _bibtex_files, state); QApplication::restoreOverrideCursor(); } void c2bCiterWidget::toggleVisible() { if (isVisible()) hide(); else show(); } void c2bCiterWidget::show() { if (isHidden()) QWidget::show(); raise(); activateWindow(); ui.citationsView->setFocus(); } void c2bCiterWidget::setTrayIcon() { _tray_icon = new QSystemTrayIcon(this); _tray_icon->setIcon(QIcon(":/icons/icons/cb2bib.ico")); _tray_icon->setToolTip("c2bBib Citer"); QMenu* tray_icon_menu = new QMenu(this); foreach (QAction* a, actions()) { tray_icon_menu->addAction(a); } _tray_icon->setContextMenu(tray_icon_menu); _tray_icon->show(); connect(_tray_icon, SIGNAL(activated(QSystemTrayIcon::ActivationReason)), this, SLOT(trayIconActivated(QSystemTrayIcon::ActivationReason))); } void c2bCiterWidget::trayIconActivated(QSystemTrayIcon::ActivationReason r) { if (r == QSystemTrayIcon::Context) return; show(); } void c2bCiterWidget::setActions() { QAction* a; a = new QAction(this); a->setText(tr("Citer Help")); a->setShortcut(QKeySequence(QKeySequence::HelpContents)); addAction(a); connect(a, SIGNAL(triggered()), this, SLOT(help())); c2bUtils::addSeparator(this); a = new QAction(this); a->setText(tr("Open Directory")); a->setShortcut(QKeySequence(QKeySequence::Open)); addAction(a); connect(a, SIGNAL(triggered()), this, SLOT(openDirectory())); a = new QAction(this); a->setText(tr("Open Files")); a->setShortcut(QKeySequence(Qt::ALT + Qt::Key_O)); addAction(a); connect(a, SIGNAL(triggered()), this, SLOT(openFiles())); c2bUtils::addSeparator(this); a = new QAction(this); a->setText(tr("Refresh")); a->setShortcut(QKeySequence(QKeySequence::Refresh)); addAction(a); connect(a, SIGNAL(triggered()), this, SLOT(reload())); c2bUtils::addSeparator(this); a = new QAction(this); a->setText(tr("Search In Files")); a->setShortcut(QKeySequence(QKeySequence::Find)); addAction(a); connect(a, SIGNAL(triggered()), this, SLOT(doSearchInFiles())); c2bUtils::addSeparator(this); a = new QAction(this); a->setText(tr("Set LyX Pipe")); a->setShortcut(QKeySequence(Qt::ALT + Qt::Key_L)); addAction(a); connect(a, SIGNAL(triggered()), _citerP, SLOT(setLyXPipe())); c2bUtils::addSeparator(this); a = new QAction(this); a->setText(tr("Toggle cb2Bib")); a->setShortcut(QKeySequence(Qt::Key_F2)); addAction(a); connect(a, SIGNAL(triggered()), this, SLOT(toggleCb2Bib())); a = new QAction(this); a->setText(tr("Toggle Clipboard")); a->setShortcut(QKeySequence(Qt::ALT + Qt::Key_C)); addAction(a); connect(a, SIGNAL(triggered()), this, SLOT(toggleClipboard())); a = new QAction(this); a->setText(tr("Toggle Full Screen")); a->setShortcut(QKeySequence(Qt::ALT + Qt::Key_F)); addAction(a); connect(a, SIGNAL(triggered()), this, SLOT(toggleFullScreen())); c2bUtils::addSeparator(this); a = new QAction(this); a->setText(tr("Index Documents")); addAction(a); connect(a, SIGNAL(triggered()), this, SLOT(indexDocuments())); c2bUtils::addSeparator(this); a = new QAction(this); a->setText(tr("Exit")); a->setShortcut(QKeySequence(QKeySequence::Quit)); addAction(a); connect(a, SIGNAL(triggered()), c2b::instance(), SLOT(exitRequested())); } void c2bCiterWidget::openDirectory() { QString dir; if (_bibtex_files.count() > 0) dir = _bibtex_files.at(0); dir = c2bFileDialog::getExistingDirectory(this, tr("Select BibTeX directory"), dir); if (dir.isEmpty()) return; _bibtex_files = c2bUtils::filesInDir(dir, QStringList() << "*.bib"); reload(); } void c2bCiterWidget::openFiles() { QString dir; if (_bibtex_files.count() > 0) dir = _bibtex_files.at(0); const QStringList fns( c2bFileDialog::getOpenFilenames(this, "Select BibTeX filenames", dir, "BibTeX (*.bib);;All (*)")); if (fns.count() > 0) { _bibtex_files = fns; reload(); } } void c2bCiterWidget::doSearchInFiles() { const QString fn(_citations->isKeywordView() ? QString() : _citations->dataBibTeXFile(ui.citationsView->currentIndex())); if (fn.isEmpty()) showMessage(tr("No active reference.")); else c2b::doSearchInFiles(QString(), fn); } void c2bCiterWidget::toggleCb2Bib() { if (c2b::mainWidget()->isVisible()) c2b::mainWidget()->hide(); else c2bUtils::setWidgetOnTop(c2b::mainWidget()); } void c2bCiterWidget::toggleClipboard() { _clipboard_connected = !_clipboard_connected; ui.clipboardIcon->setVisible(_clipboard_connected); if (_clipboard_connected) showMessage(tr("Filter set to clipboard contents.")); } void c2bCiterWidget::toggleFullScreen() { if (isFullScreen()) showNormal(); else showFullScreen(); } void c2bCiterWidget::indexDocuments() { c2bCollectionIndex* ci(new c2bCollectionIndex(0)); ci->setAttribute(Qt::WA_DeleteOnClose); ci->show(); ci->index(); } void c2bCiterWidget::filterDataChanged(const QString& filter) { if (_clipboard_connected && isVisible()) { const QString p(c2bUtils::toAscii(filter, c2bUtils::Collation).simplified()); updatePatternFilter(false, p); ui.citationsView->setPatternFilter(p); } } void c2bCiterWidget::updatePatternFilter(const bool mode, const QString& pattern) { ui.filterIcon->setVisible(mode); if (mode) showLabel(tr("Filter: %1_").arg(pattern)); else { if (pattern.isEmpty()) showLabel(_citations->isKeywordView() ? tr("Glossary of terms") : pattern); else showLabel(tr("Filter: %1").arg(pattern)); } } void c2bCiterWidget::citeReferences() { const QStringList k(_citations->dataSelectedCiteIds()); if (k.count() > 0) { hide(); _citerP->cite(k); } else showMessage(tr("No selected references.")); } void c2bCiterWidget::editReference() { if (_citations->isKeywordView()) { showMessage(tr("No active reference.")); return; } const QString r(_citations->dataBibTeXPosition(ui.citationsView->currentIndex())); if (r.isEmpty()) showMessage(tr("No active reference.")); else emit openFile(r); } void c2bCiterWidget::openFile() { if (_citations->count() == 0) return; if (_citations->isKeywordView()) { showMessage(tr("No active reference.")); return; } const QString f(_citations->dataFile(ui.citationsView->currentIndex())); if (f.isEmpty()) showMessage(tr("No File entry in this reference.")); else { showMessage(tr("Opening %1").arg(f)); c2bUtils::openFile(f, parentWidget()); } } void c2bCiterWidget::openUrl() { if (_citations->count() == 0) return; if (_citations->isKeywordView()) { showMessage(tr("No active reference.")); return; } const QString u(_citations->dataUrl(ui.citationsView->currentIndex())); if (u.isEmpty()) showMessage(tr("No URL entry in this reference.")); else { showMessage(tr("Opening %1").arg(QUrl::fromPercentEncoding(u.toUtf8()))); c2bUtils::openFile(u, parentWidget()); } } void c2bCiterWidget::showLabel() { ui.statusBar->showMessage(_status_label, 0); } void c2bCiterWidget::showLabel(const QString& label) { _status_label = label; ui.statusBar->showMessage(_status_label, 0); } void c2bCiterWidget::showMessage(const QString& message) { QTimer::singleShot(C2B_MESSAGE_TIME, this, SLOT(showLabel())); ui.statusBar->showMessage(message, 0); } void c2bCiterWidget::help() { c2bUtils::displayHelp("https://www.molspaces.com/cb2bib/doc/c2bciter/"); } cb2bib-2.0.1/src/PaxHeaders.5700/c2bClipboard.cpp0000644000000000000000000000013214011522520016056 xustar0030 mtime=1613145424.394620346 30 atime=1613145424.826620334 30 ctime=1613145424.394620346 cb2bib-2.0.1/src/c2bClipboard.cpp0000644000175000001440000000562314011522520017463 0ustar00constansusers00000000000000/*************************************************************************** * Copyright (C) 2004-2021 by Pere Constans * constans@molspaces.com * cb2Bib version 2.0.1. Licensed under the GNU GPL version 3. * See the LICENSE file that comes with this distribution. ***************************************************************************/ #include "c2bClipboard.h" #ifdef C2B_USE_CBPOLL #include "clipboardPoll.h" #endif #include c2bClipboard::c2bClipboard(QObject* parento) : QObject(parento) { // Connecting clipboard _cb = QApplication::clipboard(); _supports_selection = _cb->supportsSelection(); _is_connected = false; _cb_text = _cb->text(QClipboard::Clipboard); if (_supports_selection) _cbs_text = _cb->text(QClipboard::Selection); // Set polling _interval = 1000; #ifdef C2B_USE_CBPOLL _poll = new clipboardPoll(); connect(_poll, SIGNAL(clipboardChanged(bool)), this, SLOT(newClipboardData(bool))); #else _timer = new QTimer(this); connect(_timer, SIGNAL(timeout()), this, SLOT(checkData())); #endif } c2bClipboard::~c2bClipboard() { #ifdef C2B_USE_CBPOLL delete _poll; #endif } void c2bClipboard::checkData() { if (_cb_text != _cb->text(QClipboard::Clipboard)) { _cb_text = _cb->text(QClipboard::Clipboard); emit cbDataChanged(_cb_text); } if (_supports_selection && _cbs_text != _cb->text(QClipboard::Selection)) { _cbs_text = _cb->text(QClipboard::Selection); emit cbDataChanged(_cbs_text); } } void c2bClipboard::dataChanged() { if (_cb_text != _cb->text(QClipboard::Clipboard)) { _cb_text = _cb->text(QClipboard::Clipboard); emit cbDataChanged(_cb_text); } } void c2bClipboard::selectionChanged() { if (_supports_selection && _cbs_text != _cb->text(QClipboard::Selection)) { _cbs_text = _cb->text(QClipboard::Selection); emit cbDataChanged(_cbs_text); } } void c2bClipboard::setConnected(bool zconn) { _is_connected = zconn; if (_is_connected) { _cb_text = _cb->text(QClipboard::Clipboard); connect(_cb, SIGNAL(dataChanged()), this, SLOT(dataChanged())); if (_supports_selection) { _cbs_text = _cb->text(QClipboard::Selection); connect(_cb, SIGNAL(selectionChanged()), this, SLOT(selectionChanged())); } #ifdef C2B_USE_CBPOLL _poll->startT(_interval); #else _timer->start(_interval); #endif } else { #ifdef C2B_USE_CBPOLL _poll->stopT(); #else _timer->stop(); #endif disconnect(_cb, SIGNAL(dataChanged()), this, SLOT(dataChanged())); if (_supports_selection) disconnect(_cb, SIGNAL(selectionChanged()), this, SLOT(selectionChanged())); } } void c2bClipboard::newClipboardData(bool selectionMode) { if (selectionMode) selectionChanged(); else dataChanged(); } cb2bib-2.0.1/src/PaxHeaders.5700/c2bCiterHistory.h0000644000000000000000000000013214011522520016254 xustar0030 mtime=1613145424.494620343 30 atime=1613145424.826620334 30 ctime=1613145424.494620343 cb2bib-2.0.1/src/c2bCiterHistory.h0000644000175000001440000000606614011522520017663 0ustar00constansusers00000000000000/*************************************************************************** * Copyright (C) 2004-2021 by Pere Constans * constans@molspaces.com * cb2Bib version 2.0.1. Licensed under the GNU GPL version 3. * See the LICENSE file that comes with this distribution. ***************************************************************************/ #ifndef C2BCITERHISTORY_H #define C2BCITERHISTORY_H #include "c2bCiter.h" #include #include class c2bCiterHistory { public: c2bCiterHistory(); inline ~c2bCiterHistory() {} void clear(); void saveCurrentState(const c2bCiter::Format format, const c2bCiter::Filter filter, const int iindex, const int vindex, const QString fstring); inline void saveCurrentState(const c2bCiter::Format format, const c2bCiter::Filter filter, const int iindex, const QModelIndex* const index, const QString fstring) { if (index) saveCurrentState(format, filter, iindex, index->row(), fstring); } inline void saveCurrentItemIndex(const c2bCiter::Format format, const c2bCiter::Filter filter, const int iindex) { if (format == c2bCiter::K) _last_keyword = iindex; else if (filter == c2bCiter::Selected) _last_selection_citation = iindex; else _last_citation = iindex; } inline const c2bCiter::State& lastState() const { return _states[_index[_nstates]]; } inline const c2bCiter::State& previousState() { if (_cstate == -1) _cstate = _nstates; else if (_cstate == 0) _cstate = 1; return _states[_index[--_cstate]]; } inline const c2bCiter::State& nextState() { if (_cstate == _nstates) _cstate = _nstates - 1; return _states[_index[++_cstate]]; } inline int currentState() const { return _cstate; } inline const c2bCiter::State& lastNonKeywordState() const { return _last_nonkeyword_state; } inline const c2bCiter::State& lastNonSelectedState() const { return _last_nonselected_state; } inline void saveCurrentCitationFormat(const c2bCiter::Format format) { _last_citation_format = (format == c2bCiter::R || format == c2bCiter::K) ? _last_citation_format : format; } inline c2bCiter::Format lastCitationFormat() const { return _last_citation_format; } inline int lastCitation() const { return _last_citation; } inline int lastSelectionCitation() const { return _last_selection_citation; } inline int lastKeyword() const { return _last_keyword; } private: c2bCiter::Format _last_citation_format; int _cstate; int _last_citation; int _last_keyword; int _last_selection_citation; int _nstates; c2bCiter::State _last_nonkeyword_state; c2bCiter::State _last_nonselected_state; QVarLengthArray _states; QVarLengthArray _index; }; #endif cb2bib-2.0.1/src/PaxHeaders.5700/c2bHighlighter.cpp0000644000000000000000000000013214011522520016415 xustar0030 mtime=1613145424.422620346 30 atime=1613145424.826620334 30 ctime=1613145424.426620345 cb2bib-2.0.1/src/c2bHighlighter.cpp0000644000175000001440000001163414011522520020021 0ustar00constansusers00000000000000/*************************************************************************** * Copyright (C) 2004-2021 by Pere Constans * constans@molspaces.com * cb2Bib version 2.0.1. Licensed under the GNU GPL version 3. * See the LICENSE file that comes with this distribution. ***************************************************************************/ #include "c2bHighlighter.h" #include "c2bSettings.h" #include #include c2bHighlighter::c2bHighlighter(QTextDocument* doc) : QSyntaxHighlighter(doc) { QPalette p; text_color = p.text().color(); c2bSettings* settings(c2bSettingsP); c = &settings->colors; connect(settings, SIGNAL(newSettings()), this, SLOT(rehighlight())); rx0 = QRegExp("\\d+"); rx0.setMinimal(true); rx1 = QRegExp("[^\\w\\d]+"); rx1.setMinimal(true); rx2 = QRegExp("<(?:NewLine|Tab)\\d+>"); rx2.setMinimal(true); rx3 = QRegExp("\\b(?:19|20)\\d\\d\\b"); rx3.setMinimal(true); rx4 = QRegExp("\\b(?:abstract|authors{0,1}|introduction|issue|keywords|key words|title|volume|vol)\\b", Qt::CaseInsensitive); rx4.setMinimal(true); rx5 = QRegExp("<<(?:abstract|address|annote|author|booktitle|chapter|" "doi|edition|editor|eprint|file|institution|isbn|issn|journal|" "keywords|month|note|number|organization|pages|publisher|" "school|series|title|url|volume|year)>>"); rx5.setMinimal(true); rx6 = QRegExp(""); rx6.setMinimal(true); rx_extracted_starts = QRegExp("\\[\\["); rx_extracted_ends = QRegExp("\\]\\]"); rx_metadata_starts = QRegExp("\\[(Bibliographic|Raw) Metadata"); rx_metadata_ends = QRegExp("/(Bibliographic|Raw) Metadata\\]"); } c2bHighlighter::~c2bHighlighter() {} void c2bHighlighter::highlightBlock(const QString& text) { const int len(text.length()); setFormat(0, len - 1, text_color); int pos(0); while (pos >= 0) { pos = rx0.indexIn(text, pos); if (pos > -1) { setFormat(pos, rx0.matchedLength(), c->cb2bib_digit_color); pos += rx0.matchedLength(); } } pos = 0; while (pos >= 0) { pos = rx1.indexIn(text, pos); if (pos > -1) { setFormat(pos, rx1.matchedLength(), c->cb2bib_unrelevant_color); pos += rx1.matchedLength(); } } pos = 0; while (pos >= 0) { pos = rx2.indexIn(text, pos); if (pos > -1) { setFormat(pos, rx2.matchedLength(), c->cb2bib_unrelevant_color); pos += rx2.matchedLength(); } } pos = 0; while (pos >= 0) { pos = rx3.indexIn(text, pos); if (pos > -1) { setFormat(pos, rx3.matchedLength(), c->cb2bib_relevant_color); pos += rx3.matchedLength(); } } pos = 0; while (pos >= 0) { pos = rx4.indexIn(text, pos); if (pos > -1) { setFormat(pos, rx4.matchedLength(), c->cb2bib_highly_relevant_color); pos += rx4.matchedLength(); } } pos = 0; while (pos >= 0) { pos = rx5.indexIn(text, pos); if (pos > -1) { setFormat(pos, rx5.matchedLength(), c->cb2bib_tag_color); pos += rx5.matchedLength(); } } pos = 0; while (pos >= 0) { pos = rx6.indexIn(text, pos); if (pos > -1) { setFormat(pos, rx6.matchedLength(), c->cb2bib_unrelevant_color); pos += rx6.matchedLength(); } } setCurrentBlockState(0); int startIndexMD(0); if (previousBlockState() != 1) startIndexMD = rx_metadata_starts.indexIn(text); while (startIndexMD >= 0) { const int endIndex(rx_metadata_ends.indexIn(text, startIndexMD)); int extractedLength; if (endIndex == -1) { setCurrentBlockState(1); extractedLength = text.length() - startIndexMD; } else extractedLength = endIndex - startIndexMD + rx_metadata_ends.matchedLength(); setFormat(startIndexMD, extractedLength, c->cb2bib_metadata_color); startIndexMD = rx_metadata_starts.indexIn(text, startIndexMD + extractedLength); } int startIndexEx(0); if (previousBlockState() != 2) startIndexEx = rx_extracted_starts.indexIn(text); while (startIndexEx >= 0) { const int endIndex(rx_extracted_ends.indexIn(text, startIndexEx)); int extractedLength; if (endIndex == -1) { setCurrentBlockState(2); extractedLength = text.length() - startIndexEx; } else extractedLength = endIndex - startIndexEx + rx_extracted_ends.matchedLength(); setFormat(startIndexEx, extractedLength, c->cb2bib_unrelevant_color); startIndexEx = rx_extracted_starts.indexIn(text, startIndexEx + extractedLength); } } cb2bib-2.0.1/src/PaxHeaders.5700/c2bNetworkQueryInfo.h0000644000000000000000000000013214011522520017117 xustar0030 mtime=1613145424.538620342 30 atime=1613145424.830620334 30 ctime=1613145424.538620342 cb2bib-2.0.1/src/c2bNetworkQueryInfo.h0000644000175000001440000000224314011522520020517 0ustar00constansusers00000000000000/*************************************************************************** * Copyright (C) 2004-2021 by Pere Constans * constans@molspaces.com * cb2Bib version 2.0.1. Licensed under the GNU GPL version 3. * See the LICENSE file that comes with this distribution. ***************************************************************************/ #ifndef C2BNETWORKQUERYINFO_H #define C2BNETWORKQUERYINFO_H #include #include class QAction; class c2bBibParser; class c2bFileSystemWatcher; /** Manage Network Query Information */ class c2bNetworkQueryInfo : public QObject { Q_OBJECT public: explicit c2bNetworkQueryInfo(QObject* parento = 0); ~c2bNetworkQueryInfo(); QList bookmarkActions(const QString& selection); const QString bookmarksToHtml() const; const QString encodeLink(const QString& ln) const; private: QList BookmarkActionList; QString NetworkFile; QString _current_selection; QStringList BookmarkList; c2bFileSystemWatcher* _fsw; const c2bBibParser* _bpP; private slots: void loadSettings(); void openBookmark(); void parseBookmarks(); }; #endif cb2bib-2.0.1/src/PaxHeaders.5700/c2bComboBox.cpp0000644000000000000000000000013214011522520015667 xustar0030 mtime=1613145424.402620346 30 atime=1613145424.826620334 30 ctime=1613145424.402620346 cb2bib-2.0.1/src/c2bComboBox.cpp0000644000175000001440000000214414011522520017267 0ustar00constansusers00000000000000/*************************************************************************** * Copyright (C) 2004-2021 by Pere Constans * constans@molspaces.com * cb2Bib version 2.0.1. Licensed under the GNU GPL version 3. * See the LICENSE file that comes with this distribution. ***************************************************************************/ #include "c2bComboBox.h" #include #include #include #include c2bComboBox::c2bComboBox(QWidget* parentw) : QComboBox(parentw) {} c2bComboBox::~c2bComboBox() {} void c2bComboBox::contextMenuEvent(QContextMenuEvent* e) { QMenu* menu = QComboBox::lineEdit()->createStandardContextMenu(); QList acts = menu->actions(); QAction* act; act = new QAction("Clear", menu); act->setEnabled(!QComboBox::lineEdit()->text().isEmpty()); connect(act, SIGNAL(triggered()), this, SLOT(clearEditText())); menu->insertAction(acts.at(7), act); acts = actions(); for (int i = 0; i < acts.count(); ++i) menu->addAction(acts.at(i)); menu->exec(e->globalPos()); delete menu; } cb2bib-2.0.1/src/PaxHeaders.5700/c2bColors.cpp0000644000000000000000000000013214011522520015420 xustar0030 mtime=1613145424.398620346 30 atime=1613145424.826620334 30 ctime=1613145424.402620346 cb2bib-2.0.1/src/c2bColors.cpp0000644000175000001440000000743414011522520017027 0ustar00constansusers00000000000000/*************************************************************************** * Copyright (C) 2004-2021 by Pere Constans * constans@molspaces.com * cb2Bib version 2.0.1. Licensed under the GNU GPL version 3. * See the LICENSE file that comes with this distribution. ***************************************************************************/ #include "c2bColors.h" #include "c2bSettings.h" c2bColors::c2bColors() { colorList.insert("BibTeX delimiters", &bib_delimiter_color); colorList.insert("BibTeX reference field", &bib_reference_field_color); colorList.insert("BibTeX reference type", &bib_reference_type_color); colorList.insert("Comments and line numbers", &comment_color); colorList.insert("NetQInf command contents", &netqinf_command_content_color); colorList.insert("NetQInf command keys", &netqinf_command_key_color); colorList.insert("RegExp and NetQInf cb2Bib tags", &cb2bib_tag_color); colorList.insert("cb2Bib digits", &cb2bib_digit_color); colorList.insert("cb2Bib highly relevant text", &cb2bib_highly_relevant_color); colorList.insert("cb2Bib metadata", &cb2bib_metadata_color); colorList.insert("cb2Bib relevant text", &cb2bib_relevant_color); colorList.insert("cb2Bib unrelevant text", &cb2bib_unrelevant_color); } c2bColors::~c2bColors() {} void c2bColors::updateColor(const QColor& color, const QString& colorName) { *colorList[colorName] = color; } void c2bColors::saveColors(c2bSettings* settings) { settings->setValue("c2bColors/bib_delimiter_color", bib_delimiter_color); settings->setValue("c2bColors/bib_reference_field_color", bib_reference_field_color); settings->setValue("c2bColors/bib_reference_type_color", bib_reference_type_color); settings->setValue("c2bColors/cb2bib_digit_color", cb2bib_digit_color); settings->setValue("c2bColors/cb2bib_highly_relevant_color", cb2bib_highly_relevant_color); settings->setValue("c2bColors/cb2bib_metadata_color", cb2bib_metadata_color); settings->setValue("c2bColors/cb2bib_relevant_color", cb2bib_relevant_color); settings->setValue("c2bColors/cb2bib_tag_color", cb2bib_tag_color); settings->setValue("c2bColors/cb2bib_unrelevant_color", cb2bib_unrelevant_color); settings->setValue("c2bColors/comment_color", comment_color); settings->setValue("c2bColors/netqinf_command_content_color", netqinf_command_content_color); settings->setValue("c2bColors/netqinf_command_key_color", netqinf_command_key_color); } void c2bColors::loadColors(c2bSettings* settings) { bib_delimiter_color = settings->value("c2bColors/bib_delimiter_color", "#555555").value(); bib_reference_field_color = settings->value("c2bColors/bib_reference_field_color", "#00007f").value(); bib_reference_type_color = settings->value("c2bColors/bib_reference_type_color", "#00007f").value(); cb2bib_digit_color = settings->value("c2bColors/cb2bib_digit_color", "#005500").value(); cb2bib_highly_relevant_color = settings->value("c2bColors/cb2bib_highly_relevant_color", "#0000ff").value(); cb2bib_metadata_color = settings->value("c2bColors/cb2bib_metadata_color", "#595942").value(); cb2bib_relevant_color = settings->value("c2bColors/cb2bib_relevant_color", "#005500").value(); cb2bib_tag_color = settings->value("c2bColors/cb2bib_tag_color", "#550000").value(); cb2bib_unrelevant_color = settings->value("c2bColors/cb2bib_unrelevant_color", "#595942").value(); comment_color = settings->value("c2bColors/comment_color", "#595942").value(); netqinf_command_content_color = settings->value("c2bColors/netqinf_command_content_color", "#000000").value(); netqinf_command_key_color = settings->value("c2bColors/netqinf_command_key_color", "#00007f").value(); } cb2bib-2.0.1/src/PaxHeaders.5700/c2bCoreCiter.cpp0000644000000000000000000000013214011522520016036 xustar0030 mtime=1613145424.410620346 30 atime=1613145424.826620334 30 ctime=1613145424.414620346 cb2bib-2.0.1/src/c2bCoreCiter.cpp0000644000175000001440000000757514011522520017453 0ustar00constansusers00000000000000/*************************************************************************** * Copyright (C) 2004-2021 by Pere Constans * constans@molspaces.com * cb2Bib version 2.0.1. Licensed under the GNU GPL version 3. * See the LICENSE file that comes with this distribution. * * The LyX pipe procedure in citeToLyXPipe has been adapted from Tellico * (Tellico (C) 2003-2005 by Robby Stephenson) ***************************************************************************/ #include "c2bCoreCiter.h" #include "c2bFileDialog.h" #include #include #include #include #include // fifo to lyx #include #include c2bCoreCiter::c2bCoreCiter(QWidget* parentw) : QObject(parentw) { _parentWP = parentw; _settingsP = settings::instance(); _settingsP->setDefaultValue("c2bCoreCiter/LyXPipe", QDir::cleanPath(QDir::homePath() + QDir::separator() + ".lyx/lyxpipe.in")); _lyxpipe = _settingsP->value("c2bCoreCiter/LyXPipe").toString(); _citeids = QRegExp("^([^<]*)<<([^\\|]*)\\|citeids\\|([^>]*)>>(.*)$"); } c2bCoreCiter::~c2bCoreCiter() {} void c2bCoreCiter::cite(const QStringList& keys) { if (keys.count() == 0) return; _command = _settingsP->value("cb2Bib/CiteCommandPattern").toString(); const QByteArray pipe(QFile::encodeName(_lyxpipe)); if (QFile::exists(pipe) && _command == C2B_CITE_COMMAND_PATTERN) _cite_to_lyx_pipe(keys); else _cite_to_clipboard(keys); } void c2bCoreCiter::_cite_to_clipboard(const QStringList& keys) const { QString c; if (_command.isEmpty() || _command == C2B_CITE_COMMAND_PATTERN) c = QLatin1String("\\cite{") + keys.join(QLatin1String(", ")).trimmed() + QLatin1Char('}'); else if (_command.contains(QLatin1String("<>"))) for (int i = 0; i < keys.count(); ++i) c += QString(_command).replace(QLatin1String("<>"), keys.at(i)) + QLatin1Char(' '); else if (_citeids.indexIn(_command) >= 0) { c = _citeids.cap(2) + keys.at(0); // Note keys.count() > 0 for (int i = 1; i < keys.count(); ++i) c += _citeids.cap(3) + QLatin1Char(' ') + _citeids.cap(2) + keys.at(i); c = _citeids.cap(1) + c.trimmed() + _citeids.cap(4); } if (c.isEmpty()) { QMessageBox::warning(_parentWP, tr("Warning - cb2Bib"), tr("Cite Command Pattern is misspecified"), QMessageBox::Ok); return; } QClipboard* cb(QApplication::clipboard()); cb->setText(c.trimmed(), QClipboard::Clipboard); } void c2bCoreCiter::_cite_to_lyx_pipe(const QStringList& keys) const { // This procedure was adapted from Tellico // Tellico (C) 2003-2005 by Robby Stephenson const QByteArray pipe(QFile::encodeName(_lyxpipe)); const QString errorStr(tr("Unable to write to the server pipe at '%1'.").arg(QString(pipe))); if (!QFile::exists(pipe)) { QMessageBox::warning(_parentWP, tr("Warning - cb2Bib"), errorStr, QMessageBox::Ok); return; } int pipeFd = ::open(pipe, O_WRONLY); QFile file(QString::fromUtf8(pipe)); if (file.open(pipeFd, QIODevice::WriteOnly)) { // pybliographer uses comma-space, and pyblink expects the space there const QString c(keys.join(", ").trimmed()); QTextStream st(&file); st << QString::fromLatin1("LYXCMD:cb2bib:citation-insert:%1\n").arg(c).toLatin1(); file.flush(); file.close(); } else QMessageBox::warning(_parentWP, tr("Warning - cb2Bib"), errorStr, QMessageBox::Ok); ::close(pipeFd); } void c2bCoreCiter::setLyXPipe() { const QString new_pn(c2bFileDialog::getSystemFilename(_parentWP, "Select LyX pipe", _lyxpipe, "All (*)")); if (!new_pn.isEmpty()) { _lyxpipe = new_pn; _settingsP->setValue("c2bCoreCiter/LyXPipe", _lyxpipe); } } cb2bib-2.0.1/src/PaxHeaders.5700/qweb0000644000000000000000000000007414011522151013752 xustar0030 atime=1613145424.838620334 30 ctime=1613145424.306620349 cb2bib-2.0.1/src/qweb/0000755000175000001440000000000014011522151015421 5ustar00constansusers00000000000000cb2bib-2.0.1/src/qweb/PaxHeaders.5700/engine0000644000000000000000000000007414011522151015217 xustar0030 atime=1613145424.838620334 30 ctime=1613145424.306620349 cb2bib-2.0.1/src/qweb/engine/0000755000175000001440000000000014011522151016666 5ustar00constansusers00000000000000cb2bib-2.0.1/src/qweb/engine/PaxHeaders.5700/c2bWebBrowser.cpp0000644000000000000000000000007414011522151020450 xustar0030 atime=1613145424.838620334 30 ctime=1613145424.306620349 cb2bib-2.0.1/src/qweb/engine/c2bWebBrowser.cpp0000644000175000001440000001312614011522151022045 0ustar00constansusers00000000000000/*************************************************************************** * Copyright (C) 2004-2021 by Pere Constans * constans@molspaces.com * * See the LICENSE file that comes with this distribution. ***************************************************************************/ #include "c2bWebBrowser.h" #include "c2bUtils.h" #include #include #include #include #include #include c2bWebBrowser::c2bWebBrowser(QWidget* parentw) : QWebEngineView(parentw) { // Set default background to application #if QT_VERSION >= QT_VERSION_CHECK(5, 6, 0) page()->setBackgroundColor(qApp->palette().color(QPalette::Window)); #endif // Actions setContextMenuPolicy(Qt::ActionsContextMenu); viewBackwardAction = new QAction(QIcon(QString::fromUtf8(":/icons/icons/viewBackward.png")), tr("Backward"), this); viewBackwardAction->setShortcut(QKeySequence("Left")); viewBackwardAction->setStatusTip(tr("Backward")); addAction(viewBackwardAction); viewForwardAction = new QAction(QIcon(QString::fromUtf8(":/icons/icons/viewForward.png")), tr("Forward"), this); viewForwardAction->setShortcut(QKeySequence("Right")); viewForwardAction->setStatusTip(tr("Forward")); addAction(viewForwardAction); c2bUtils::addSeparator(this); viewHomeAction = new QAction(QIcon(QString::fromUtf8(":/icons/icons/viewHome.png")), tr("Home"), this); viewHomeAction->setShortcut(QKeySequence("Esc")); viewHomeAction->setStatusTip(tr("Home page")); addAction(viewHomeAction); c2bUtils::addSeparator(this); viewReloadAction = new QAction(QIcon(QString::fromUtf8(":/icons/icons/viewReload.png")), tr("Reload"), this); viewReloadAction->setShortcut(QKeySequence("R")); viewReloadAction->setStatusTip(tr("Reload current page")); addAction(viewReloadAction); c2bUtils::addSeparator(this); viewZoomInAction = new QAction(QIcon(QString::fromUtf8(":/icons/icons/viewZoomIn.png")), tr("Zoom In"), this); viewZoomInAction->setShortcut(QKeySequence(QKeySequence::ZoomIn)); viewZoomInAction->setStatusTip(tr("Zoom in")); addAction(viewZoomInAction); viewZoomOutAction = new QAction(QIcon(QString::fromUtf8(":/icons/icons/viewZoomOut.png")), tr("Zoom Out"), this); viewZoomOutAction->setShortcut(QKeySequence(QKeySequence::ZoomOut)); viewZoomOutAction->setStatusTip(tr("Zoom out")); addAction(viewZoomOutAction); connect(viewForwardAction, SIGNAL(triggered()), this, SLOT(forward())); connect(viewBackwardAction, SIGNAL(triggered()), this, SLOT(back())); connect(viewHomeAction, SIGNAL(triggered()), this, SLOT(home())); connect(viewReloadAction, SIGNAL(triggered()), this, SLOT(reload())); connect(viewZoomInAction, SIGNAL(triggered()), this, SLOT(zoomIn())); connect(viewZoomOutAction, SIGNAL(triggered()), this, SLOT(zoomOut())); QShortcut* copy_shortcut = new QShortcut(QKeySequence(QKeySequence::Copy), this); connect(copy_shortcut, SIGNAL(activated()), this, SLOT(copy())); connect(page(), SIGNAL(linkHovered(QString)), this, SLOT(linkHovered(QString))); connect(this, SIGNAL(titleChanged(QString)), this, SLOT(setWindowTitle(QString))); } c2bWebBrowser::~c2bWebBrowser() {} void c2bWebBrowser::setHomePage(const QString& hp_url) { _home_page = hp_url; home(); } void c2bWebBrowser::setFont(const QFont& qfont) { QWebEngineSettings* wsettings = settings(); wsettings->setFontFamily(QWebEngineSettings::StandardFont, qfont.family()); wsettings->setFontSize(QWebEngineSettings::DefaultFontSize, qfont.pointSize()); } void c2bWebBrowser::setFixedFont(const QFont& qfont) { QWebEngineSettings* wsettings = settings(); wsettings->setFontFamily(QWebEngineSettings::FixedFont, qfont.family()); wsettings->setFontSize(QWebEngineSettings::DefaultFixedFontSize, qfont.pointSize()); } void c2bWebBrowser::copy() { page()->triggerAction(QWebEnginePage::Copy); } void c2bWebBrowser::home() { if (!_home_page.isEmpty()) load(c2bUtils::stringToUrl(_home_page)); } void c2bWebBrowser::loadPage(const QString& p_url) { if (!p_url.isEmpty()) load(c2bUtils::stringToUrl(p_url)); } void c2bWebBrowser::zoomIn() { setZoomFactor(zoomFactor() + 0.1); } void c2bWebBrowser::zoomOut() { setZoomFactor(zoomFactor() - 0.1); } QWebEngineView* c2bWebBrowser::createWindow(QWebEnginePage::WebWindowType /* type */) { if (!_hovered_link.isEmpty()) c2bUtils::openFile(_hovered_link, this); return 0; } template struct InvokeWrapper { R* receiver; void (C::*memberFun)(Arg); void operator()(Arg result) { (receiver->*memberFun)(result); } }; template InvokeWrapper invoke(R* receiver, void (C::*memberFun)(Arg)) { InvokeWrapper wrapper = { receiver, memberFun }; return wrapper; } void c2bWebBrowser::showTitle(const QVariant& v) { if (!v.isValid()) emit statusMessage(QString()); else emit statusMessage(v.toString()); } void c2bWebBrowser::linkHovered(const QString& link) { _hovered_link = link; if (_hovered_link.isEmpty()) emit statusMessage(QString()); else if (_hovered_link.contains(".tex.html#")) { const QString q(QFileInfo(link).fileName().split('#').last()); page()->runJavaScript("document.querySelector('a[id*=\"" + q + "\"]').text", invoke(this, &c2bWebBrowser::showTitle)); } else { QString vlink(link); emit statusMessage(vlink.remove("file://")); } } cb2bib-2.0.1/src/qweb/engine/PaxHeaders.5700/c2bWebBrowser.h0000644000000000000000000000007414011522151020115 xustar0030 atime=1613145424.838620334 30 ctime=1613145424.306620349 cb2bib-2.0.1/src/qweb/engine/c2bWebBrowser.h0000644000175000001440000000244414011522151021513 0ustar00constansusers00000000000000/*************************************************************************** * Copyright (C) 2004-2021 by Pere Constans * constans@molspaces.com * * See the LICENSE file that comes with this distribution. ***************************************************************************/ #ifndef C2BWEBBROWSER_H #define C2BWEBBROWSER_H #include #include class c2bWebBrowser : public QWebEngineView { Q_OBJECT public: explicit c2bWebBrowser(QWidget* parentw = 0); virtual ~c2bWebBrowser(); QAction* viewBackwardAction; QAction* viewForwardAction; QAction* viewHomeAction; QAction* viewReloadAction; QAction* viewZoomInAction; QAction* viewZoomOutAction; signals: void statusMessage(const QString ms); public slots: void loadPage(const QString& p_url); void setFixedFont(const QFont& qfont); void setFont(const QFont& qfont); void setHomePage(const QString& hp_url); protected: virtual QWebEngineView* createWindow(QWebEnginePage::WebWindowType type); protected slots: void copy(); void home(); void zoomIn(); void zoomOut(); private: QString _home_page; QString _hovered_link; void showTitle(const QVariant& v); private slots: void linkHovered(const QString& link); }; #endif cb2bib-2.0.1/src/qweb/PaxHeaders.5700/kit0000644000000000000000000000007414011522151014541 xustar0030 atime=1613145424.838620334 30 ctime=1613145424.306620349 cb2bib-2.0.1/src/qweb/kit/0000755000175000001440000000000014011522151016210 5ustar00constansusers00000000000000cb2bib-2.0.1/src/qweb/kit/PaxHeaders.5700/c2bWebBrowser.cpp0000644000000000000000000000007414011522151017772 xustar0030 atime=1613145424.838620334 30 ctime=1613145424.306620349 cb2bib-2.0.1/src/qweb/kit/c2bWebBrowser.cpp0000644000175000001440000001325114011522151021366 0ustar00constansusers00000000000000/*************************************************************************** * Copyright (C) 2004-2021 by Pere Constans * constans@molspaces.com * * See the LICENSE file that comes with this distribution. ***************************************************************************/ #include "c2bWebBrowser.h" #include "c2bUtils.h" #include #include #include #include #include #include c2bWebBrowser::c2bWebBrowser(QWidget* parentw) : QWebView(parentw) { // Avoid flickering (Qt 4.3) setAttribute(Qt::WA_NoSystemBackground, true); setAttribute(Qt::WA_OpaquePaintEvent, true); // Set default background to application page()->setPalette(qApp->palette()); // Actions setContextMenuPolicy(Qt::ActionsContextMenu); viewBackwardAction = new QAction(QIcon(QString::fromUtf8(":/icons/icons/viewBackward.png")), tr("Backward"), this); viewBackwardAction->setShortcut(QKeySequence("Left")); viewBackwardAction->setStatusTip(tr("Backward")); addAction(viewBackwardAction); viewForwardAction = new QAction(QIcon(QString::fromUtf8(":/icons/icons/viewForward.png")), tr("Forward"), this); viewForwardAction->setShortcut(QKeySequence("Right")); viewForwardAction->setStatusTip(tr("Forward")); addAction(viewForwardAction); c2bUtils::addSeparator(this); viewHomeAction = new QAction(QIcon(QString::fromUtf8(":/icons/icons/viewHome.png")), tr("Home"), this); viewHomeAction->setShortcut(QKeySequence("Esc")); viewHomeAction->setStatusTip(tr("Home page")); addAction(viewHomeAction); c2bUtils::addSeparator(this); viewReloadAction = new QAction(QIcon(QString::fromUtf8(":/icons/icons/viewReload.png")), tr("Reload"), this); viewReloadAction->setShortcut(QKeySequence("R")); viewReloadAction->setStatusTip(tr("Reload current page")); addAction(viewReloadAction); c2bUtils::addSeparator(this); viewZoomInAction = new QAction(QIcon(QString::fromUtf8(":/icons/icons/viewZoomIn.png")), tr("Zoom In"), this); viewZoomInAction->setShortcut(QKeySequence(QKeySequence::ZoomIn)); viewZoomInAction->setStatusTip(tr("Zoom in")); addAction(viewZoomInAction); viewZoomOutAction = new QAction(QIcon(QString::fromUtf8(":/icons/icons/viewZoomOut.png")), tr("Zoom Out"), this); viewZoomOutAction->setShortcut(QKeySequence(QKeySequence::ZoomOut)); viewZoomOutAction->setStatusTip(tr("Zoom out")); addAction(viewZoomOutAction); connect(viewForwardAction, SIGNAL(triggered()), this, SLOT(forward())); connect(viewBackwardAction, SIGNAL(triggered()), this, SLOT(back())); connect(viewHomeAction, SIGNAL(triggered()), this, SLOT(home())); connect(viewReloadAction, SIGNAL(triggered()), this, SLOT(reload())); connect(viewZoomInAction, SIGNAL(triggered()), this, SLOT(zoomIn())); connect(viewZoomOutAction, SIGNAL(triggered()), this, SLOT(zoomOut())); QShortcut* copy_shortcut = new QShortcut(QKeySequence(QKeySequence::Copy), this); connect(copy_shortcut, SIGNAL(activated()), this, SLOT(copy())); connect(page(), SIGNAL(linkHovered(QString,QString,QString)), this, SLOT(linkHovered(QString))); connect(page(), SIGNAL(statusBarMessage(QString)), this, SIGNAL(statusMessage(QString))); connect(this, SIGNAL(titleChanged(QString)), this, SLOT(_set_window_title(QString))); } c2bWebBrowser::~c2bWebBrowser() {} void c2bWebBrowser::setHomePage(const QString& hp_url) { _home_page = hp_url; home(); } void c2bWebBrowser::setFont(const QFont& qfont) { QWebSettings* wsettings = settings(); wsettings->setFontFamily(QWebSettings::StandardFont, qfont.family()); wsettings->setFontSize(QWebSettings::DefaultFontSize, qfont.pointSize()); } void c2bWebBrowser::setFixedFont(const QFont& qfont) { QWebSettings* wsettings = settings(); wsettings->setFontFamily(QWebSettings::FixedFont, qfont.family()); wsettings->setFontSize(QWebSettings::DefaultFixedFontSize, qfont.pointSize()); } void c2bWebBrowser::copy() { page()->triggerAction(QWebPage::Copy); } void c2bWebBrowser::home() { if (!_home_page.isEmpty()) load(c2bUtils::stringToUrl(_home_page)); } void c2bWebBrowser::loadPage(const QString& p_url) { if (!p_url.isEmpty()) load(c2bUtils::stringToUrl(p_url)); } void c2bWebBrowser::zoomIn() { setTextSizeMultiplier(textSizeMultiplier() + 0.1); } void c2bWebBrowser::zoomOut() { setTextSizeMultiplier(textSizeMultiplier() - 0.1); } QWebView* c2bWebBrowser::createWindow(QWebPage::WebWindowType /* type */) { if (!_hovered_link.isEmpty()) c2bUtils::openFile(_hovered_link, this); return 0; } void c2bWebBrowser::mousePressEvent(QMouseEvent* qevent) { if (qevent->button() == Qt::BackButton) { back(); qevent->accept(); } QWebView::mousePressEvent(qevent); } void c2bWebBrowser::_set_window_title(const QString& pagetitle) { // This fixes anchor clicked cases where titleChanged signal emits an empty document title if (!pagetitle.isEmpty()) setWindowTitle(pagetitle); } void c2bWebBrowser::linkHovered(const QString& link) { _hovered_link = link; if (_hovered_link.isEmpty()) emit statusMessage(QString()); else if (_hovered_link.contains(".tex.html#")) { const QString q(QFileInfo(link).fileName().split('#').last()); const QVariant v( page()->mainFrame()->evaluateJavaScript("document.querySelector('a[id*=\"" + q + "\"]').text")); if (!v.isValid()) emit statusMessage(QString()); else emit statusMessage(v.toString()); } else { QString vlink(link); emit statusMessage(vlink.remove("file://")); } } cb2bib-2.0.1/src/qweb/kit/PaxHeaders.5700/c2bWebBrowser.h0000644000000000000000000000007414011522151017437 xustar0030 atime=1613145424.838620334 30 ctime=1613145424.306620349 cb2bib-2.0.1/src/qweb/kit/c2bWebBrowser.h0000644000175000001440000000252414011522151021034 0ustar00constansusers00000000000000/*************************************************************************** * Copyright (C) 2004-2021 by Pere Constans * constans@molspaces.com * * See the LICENSE file that comes with this distribution. ***************************************************************************/ #ifndef C2BWEBBROWSER_H #define C2BWEBBROWSER_H #include #include class c2bWebBrowser : public QWebView { Q_OBJECT public: explicit c2bWebBrowser(QWidget* parentw = 0); virtual ~c2bWebBrowser(); QAction* viewBackwardAction; QAction* viewForwardAction; QAction* viewHomeAction; QAction* viewReloadAction; QAction* viewZoomInAction; QAction* viewZoomOutAction; signals: void statusMessage(const QString ms); public slots: void loadPage(const QString& p_url); void setFixedFont(const QFont& qfont); void setFont(const QFont& qfont); void setHomePage(const QString& hp_url); protected: virtual QWebView* createWindow(QWebPage::WebWindowType type); virtual void mousePressEvent(QMouseEvent* qevent); protected slots: void copy(); void home(); void zoomIn(); void zoomOut(); private: QString _home_page; QString _hovered_link; private slots: void _set_window_title(const QString& pagetitle); void linkHovered(const QString& link); }; #endif cb2bib-2.0.1/src/PaxHeaders.5700/c2bBibParser.h0000644000000000000000000000013214011522520015475 xustar0030 mtime=1613145424.486620344 30 atime=1613145424.826620334 30 ctime=1613145424.486620344 cb2bib-2.0.1/src/c2bBibParser.h0000644000175000001440000000434614011522520017103 0ustar00constansusers00000000000000/*************************************************************************** * Copyright (C) 2004-2021 by Pere Constans * constans@molspaces.com * cb2Bib version 2.0.1. Licensed under the GNU GPL version 3. * See the LICENSE file that comes with this distribution. ***************************************************************************/ #ifndef C2BBIBPARSER_H #define C2BBIBPARSER_H #include "c2bBibPreparserLog.h" #include "c2bLineEdit.h" #include #include #include class QComboBox; /** cb2Bib interface to bibParser This class groups Bib Parser functionality related to GUI @author Pere Constans */ class c2bBibParser : public bibParser { Q_OBJECT public: explicit c2bBibParser(QObject* parento = 0); ~c2bBibParser(); void clearCurrentReference(); void setWidgetMapping(); inline void addField(const QString& name, c2bLineEdit* editor) { _field_editors.insert(name, editor); } inline void addTypes(QComboBox* types) { _type_editor = types; } inline QString field(const QString& name) const { return _field_editors.value(name)->text(); } inline void setField(const QString& name, const QString& value) override { _field_editors[name]->setText(parse(name, value)); } inline void setField(const QString& name, const QString& value, const QString& init_value) { if (name == "addauthors") _field_editors["author"]->setText(parse(name, value, init_value)); else if (name == "addeditors") _field_editors["editor"]->setText(parse(name, value, init_value)); } signals: void bibModified(bool modified); void setDocumentFilename(); private: QComboBox* _type_editor; QHash _field_editors; QPointer _preparser_logP; QWidget* _c2b_mainP; bool _bp_updates_gui; void checkRegExpFile(const QString& fn) override; void currentReferenceUpdated() override; void setCiteID() override; void setReferenceType(const QString& type) override; private slots: void referenceEdited(const QString& value); void setField(); void showLog(const QString& log); }; #endif cb2bib-2.0.1/src/PaxHeaders.5700/c2bPostprocess.h0000644000000000000000000000013214011522520016150 xustar0030 mtime=1613145424.542620342 30 atime=1613145424.830620334 30 ctime=1613145424.542620342 cb2bib-2.0.1/src/c2bPostprocess.h0000644000175000001440000000174214011522520017553 0ustar00constansusers00000000000000/*************************************************************************** * Copyright (C) 2004-2021 by Pere Constans * constans@molspaces.com * cb2Bib version 2.0.1. Licensed under the GNU GPL version 3. * See the LICENSE file that comes with this distribution. ***************************************************************************/ #ifndef C2BPOSTPROCESS_H #define C2BPOSTPROCESS_H #include "ui_c2bLogWidget.h" #include class QProcess; class c2bPostprocess : public QDialog { Q_OBJECT public: explicit c2bPostprocess(const QString& fn, QWidget* parentw = 0); ~c2bPostprocess(); protected: void PProcessFile(); void addToLog(); protected slots: void conversionEnded(); void help(); void openFile(); private: QProcess* _ppBibTeX; QPushButton* _buttonOpenFile; QString PPBIBTEX_ARG; QString PPBIBTEX_BIN; QString PPBIBTEX_EXT; QString _bib; QString _out; Ui::c2bLogWidget ui; }; #endif cb2bib-2.0.1/src/PaxHeaders.5700/c2bCitePatternLineEedit.h0000644000000000000000000000013214011522520017631 xustar0030 mtime=1613145424.486620344 30 atime=1613145424.826620334 30 ctime=1613145424.490620344 cb2bib-2.0.1/src/c2bCitePatternLineEedit.h0000644000175000001440000000203514011522520021230 0ustar00constansusers00000000000000/*************************************************************************** * Copyright (C) 2004-2021 by Pere Constans * constans@molspaces.com * cb2Bib version 2.0.1. Licensed under the GNU GPL version 3. * See the LICENSE file that comes with this distribution. ***************************************************************************/ #ifndef C2BCITEPATTERNLINEEEDIT_H #define C2BCITEPATTERNLINEEEDIT_H #include "c2bLineEdit.h" class QAction; class c2bCitePatternLineEedit : public c2bLineEdit { Q_OBJECT public: explicit c2bCitePatternLineEedit(QWidget* parentw = 0); ~c2bCitePatternLineEedit(); signals: void statusMessage(const QString& ms); protected: QAction* a_citeid; QAction* a_citeids_comma; QAction* a_citeids_semicolon; QAction* a_latex; QAction* a_markdown; protected slots: void check(const QString& pattern); void citeid(); void citeids_comma(); void citeids_semicolon(); void latex(); void markdown(); private: QRegExp _citeids; }; #endif cb2bib-2.0.1/src/PaxHeaders.5700/c2bSaveREHighlighter.h0000644000000000000000000000013214011522520017130 xustar0030 mtime=1613145424.550620342 30 atime=1613145424.830620334 30 ctime=1613145424.550620342 cb2bib-2.0.1/src/c2bSaveREHighlighter.h0000644000175000001440000000151714011522520020533 0ustar00constansusers00000000000000/*************************************************************************** * Copyright (C) 2004-2021 by Pere Constans * constans@molspaces.com * cb2Bib version 2.0.1. Licensed under the GNU GPL version 3. * See the LICENSE file that comes with this distribution. ***************************************************************************/ #ifndef C2BSAVEREHIGHLIGHTER_H #define C2BSAVEREHIGHLIGHTER_H #include /** Save RegExp SyntaxHighLighter @author Pere Constans */ class c2bColors; class c2bSaveREHighlighter : public QSyntaxHighlighter { public: c2bSaveREHighlighter(QRegExp& rx, QTextDocument* doc); ~c2bSaveREHighlighter(); protected: virtual void highlightBlock(const QString& text); private: QColor text_color; QRegExp& _current_rx; c2bColors* c; }; #endif cb2bib-2.0.1/src/PaxHeaders.5700/c2bTextEdit.cpp0000644000000000000000000000013214011522520015711 xustar0030 mtime=1613145424.462620344 30 atime=1613145424.830620334 30 ctime=1613145424.462620344 cb2bib-2.0.1/src/c2bTextEdit.cpp0000644000175000001440000002311414011522520017311 0ustar00constansusers00000000000000/*************************************************************************** * Copyright (C) 2004-2021 by Pere Constans * constans@molspaces.com * cb2Bib version 2.0.1. Licensed under the GNU GPL version 3. * See the LICENSE file that comes with this distribution. ***************************************************************************/ #include "c2bTextEdit.h" #include "c2bSettings.h" #include "c2bUtils.h" #include #include #include #include c2bTextEdit::c2bTextEdit(QWidget* parentw) : QPlainTextEdit(parentw) { setFrameShape(QPlainTextEdit::StyledPanel); setFrameShadow(QPlainTextEdit::Raised); _settingsP = c2bSettingsP; connect(_settingsP, SIGNAL(newSettings()), this, SLOT(loadSettings())); _line_number_area = new LineNumberArea(this); _line_number_area_color = palette().color(QPalette::Active, QPalette::Base).darker(110); _line_number_color_p = &_settingsP->colors.comment_color; connect(this, SIGNAL(blockCountChanged(int)), this, SLOT(updateLineNumberAreaWidth())); connect(this, SIGNAL(updateRequest(QRect,int)), this, SLOT(updateLineNumberArea(QRect,int))); updateLineNumberAreaWidth(); c2bUtils::addSeparator(this); toggleWordWrappingAction = new QAction(this); addAction(toggleWordWrappingAction); toggleWordWrappingAction->setText(tr("Toggle Word Wrapping")); toggleWordWrappingAction->setStatusTip(tr("Toggle word wrapping")); _settingsP->setKeysequence("Shortcuts/Editor/", toggleWordWrappingAction); connect(toggleWordWrappingAction, SIGNAL(triggered()), this, SLOT(toggleWordWrapping())); if (_settingsP->value("c2bTextEdit/WrapMode", false).toBool()) setLineWrapMode(QPlainTextEdit::WidgetWidth); else setLineWrapMode(QPlainTextEdit::NoWrap); } c2bTextEdit::~c2bTextEdit() { _settingsP->setValue("c2bTextEdit/WrapMode", lineWrapMode() == QPlainTextEdit::WidgetWidth); } void c2bTextEdit::setBibTeXActions() { c2bUtils::addSeparator(this); pasteCurrentBibTeXAction = new QAction(this); addAction(pasteCurrentBibTeXAction); pasteCurrentBibTeXAction->setText(tr("Paste Current BibTeX")); pasteCurrentBibTeXAction->setStatusTip(tr("Paste current BibTeX")); _settingsP->setKeysequence("Shortcuts/Editor/", pasteCurrentBibTeXAction); setLaTeXActions(); c2bUtils::addSeparator(this); journalsToFullAction = new QAction(this); addAction(journalsToFullAction); journalsToFullAction->setText(tr("Set Journals to Full Name")); journalsToFullAction->setStatusTip(tr("Set journals to full name")); _settingsP->setKeysequence("Shortcuts/Editor/", journalsToFullAction); journalsToAlternateFullAction = new QAction(this); addAction(journalsToAlternateFullAction); journalsToAlternateFullAction->setText(tr("Set Journals to Alternate Full Name")); journalsToAlternateFullAction->setStatusTip(tr("Set journals to alternate full name")); journalsToAbbreviatedAction = new QAction(this); addAction(journalsToAbbreviatedAction); journalsToAbbreviatedAction->setText(tr("Set Journals to Abbreviated Name")); journalsToAbbreviatedAction->setStatusTip(tr("Set journals to abbreviated name")); _settingsP->setKeysequence("Shortcuts/Editor/", journalsToAbbreviatedAction); journalsToAlternateAbbreviatedAction = new QAction(this); addAction(journalsToAlternateAbbreviatedAction); journalsToAlternateAbbreviatedAction->setText(tr("Set Journals to Alternate Abbreviated Name")); journalsToAlternateAbbreviatedAction->setStatusTip(tr("Set journals to alternate abbreviated name")); c2bUtils::addSeparator(this); updateMetadataAction = new QAction(this); addAction(updateMetadataAction); updateMetadataAction->setText(tr("Update Documents Metadata")); updateMetadataAction->setStatusTip(tr("Update document files metadata")); _settingsP->setKeysequence("Shortcuts/Editor/", updateMetadataAction); } void c2bTextEdit::setLaTeXActions() { c2bUtils::addSeparator(this); convertSelection2LaTeXAction = new QAction(this); addAction(convertSelection2LaTeXAction); convertSelection2LaTeXAction->setText(tr("Selection to LaTeX")); convertSelection2LaTeXAction->setStatusTip(tr("Convert selection to LaTeX")); _settingsP->setKeysequence("Shortcuts/Editor/", convertSelection2LaTeXAction); connect(convertSelection2LaTeXAction, SIGNAL(triggered()), this, SLOT(convert2LaTeX())); convertSelection2LaTeXAction->setEnabled(false); connect(this, SIGNAL(copyAvailable(bool)), convertSelection2LaTeXAction, SLOT(setEnabled(bool))); convertSelection2UnicodeAction = new QAction(this); addAction(convertSelection2UnicodeAction); convertSelection2UnicodeAction->setText(tr("Selection to Unicode")); convertSelection2UnicodeAction->setStatusTip(tr("Convert selection to Unicode")); _settingsP->setKeysequence("Shortcuts/Editor/", convertSelection2UnicodeAction); connect(convertSelection2UnicodeAction, SIGNAL(triggered()), this, SLOT(convert2Unicode())); convertSelection2UnicodeAction->setEnabled(false); connect(this, SIGNAL(copyAvailable(bool)), convertSelection2UnicodeAction, SLOT(setEnabled(bool))); } void c2bTextEdit::contextMenuEvent(QContextMenuEvent* qevent) { QMenu* menu = createStandardContextMenu(); QList acts = actions(); for (int i = 0; i < acts.count(); ++i) menu->addAction(acts.at(i)); menu->exec(qevent->globalPos()); delete menu; } void c2bTextEdit::keyPressEvent(QKeyEvent* qevent) { QPlainTextEdit::keyPressEvent(qevent); if (qevent->key() == Qt::Key_Insert) { setOverwriteMode(!overwriteMode()); emit overwriteModeChanged(); } } void c2bTextEdit::toggleWordWrapping() { if (lineWrapMode() == QPlainTextEdit::WidgetWidth) setLineWrapMode(QPlainTextEdit::NoWrap); else setLineWrapMode(QPlainTextEdit::WidgetWidth); } void c2bTextEdit::updatePlainText(const QString& text) { const int scrollPosition(verticalScrollBar()->value()); const int cursorBlock(textCursor().blockNumber()); const int cursorColumn(textCursor().columnNumber()); setPlainText(text); const int lposition(document()->findBlockByNumber(cursorBlock).position()); QTextCursor tcursor(textCursor()); tcursor.setPosition(lposition + cursorColumn, QTextCursor::MoveAnchor); setTextCursor(tcursor); verticalScrollBar()->setValue(scrollPosition); } void c2bTextEdit::cursorPosition(int* line_number, int* line_position) const { *line_number = textCursor().blockNumber() + 1; *line_position = textCursor().positionInBlock() + 1; } void c2bTextEdit::convert2LaTeX() { QString txt(textCursor().selectedText()); // Better do the long way: Convert anything to c2b, and then // translate to TeX c2bUtils::fullBibToC2b(txt); insertPlainText(c2bUtils::c2bToBib(txt)); } void c2bTextEdit::convert2Unicode() { QString txt(textCursor().selectedText()); // Strictly, this should be bibToC2b; but convert also // possible PNAS like, and, for consistency, HTML sub // and superscripts to TeX insertPlainText(c2bUtils::fullBibToC2b(txt)); } void c2bTextEdit::loadSettings() { if (font() != _settingsP->c2bMonoFont) { setFont(_settingsP->c2bMonoFont); updateLineNumberAreaWidth(); } _line_number_area->update(); // Update, otherwise number colors might not follow apply button } /*************************************************************************** * Line number area (From CodeEditor Qt's example) ***************************************************************************/ int c2bTextEdit::lineNumberAreaWidth() { int digits(1); int dmax(std::max(1, blockCount())); while (dmax >= 10) { dmax /= 10; ++digits; } #if QT_VERSION >= QT_VERSION_CHECK(5, 11, 0) const int space(5 + fontMetrics().horizontalAdvance(QLatin1Char('9')) * digits); #else const int space(5 + fontMetrics().width(QLatin1Char('9')) * digits); #endif return space; } void c2bTextEdit::updateLineNumberAreaWidth() { setViewportMargins(lineNumberAreaWidth(), 0, 0, 0); } void c2bTextEdit::updateLineNumberArea(const QRect& qrect, int dy) { if (dy) _line_number_area->scroll(0, dy); else _line_number_area->update(0, qrect.y(), _line_number_area->width(), qrect.height()); if (qrect.contains(viewport()->rect())) updateLineNumberAreaWidth(); } void c2bTextEdit::resizeEvent(QResizeEvent* qevent) { QPlainTextEdit::resizeEvent(qevent); QRect cr = contentsRect(); _line_number_area->setGeometry(QRect(cr.left(), cr.top(), lineNumberAreaWidth(), cr.height())); } void c2bTextEdit::lineNumberAreaPaintEvent(QPaintEvent* qevent) { QPainter painter(_line_number_area); painter.fillRect(qevent->rect(), _line_number_area_color); painter.setPen(*_line_number_color_p); QFont f = font(); f.setPointSize(std::max(0, f.pointSize() - 3)); painter.setFont(f); QTextBlock block = firstVisibleBlock(); int blockNumber(block.blockNumber()); int top(int(blockBoundingGeometry(block).translated(contentOffset()).top())); int bottom(top + int(blockBoundingRect(block).height())); while (block.isValid() && top <= qevent->rect().bottom()) { if (block.isVisible() && bottom >= qevent->rect().top()) { const QString number(QString::number(blockNumber + 1)); painter.drawText(5, top + 2, _line_number_area->width(), fontMetrics().height(), Qt::AlignLeft, number); } block = block.next(); top = bottom; bottom = top + (int)blockBoundingRect(block).height(); ++blockNumber; } } cb2bib-2.0.1/src/PaxHeaders.5700/c2bClipboard.h0000644000000000000000000000013214011522520015523 xustar0030 mtime=1613145424.502620343 30 atime=1613145424.830620334 30 ctime=1613145424.506620343 cb2bib-2.0.1/src/c2bClipboard.h0000644000175000001440000000242114011522520017121 0ustar00constansusers00000000000000/*************************************************************************** * Copyright (C) 2004-2021 by Pere Constans * constans@molspaces.com * cb2Bib version 2.0.1. Licensed under the GNU GPL version 3. * See the LICENSE file that comes with this distribution. ***************************************************************************/ #ifndef C2BCLIPBOARD_H #define C2BCLIPBOARD_H #include #include #include /** cb2Bib Clipboard Implements clipboard functionality as required by cb2Bib This should fix acrobat, mozilla, qt 3.3.3 issues Using clipboardPoll STATUS: DEPRECATED */ #ifdef C2B_USE_CBPOLL class clipboardPoll; #endif class c2bClipboard : public QObject { Q_OBJECT public: explicit c2bClipboard(QObject* parento = 0); ~c2bClipboard(); void setConnected(bool); signals: void cbDataChanged(const QString&); private: QClipboard* _cb; QString _cb_text; QString _cbs_text; bool _is_connected; bool _supports_selection; uint _interval; #ifdef C2B_USE_CBPOLL clipboardPoll* _poll; #else QTimer* _timer; #endif private slots: void checkData(); void dataChanged(); void newClipboardData(bool selectionMode); void selectionChanged(); }; #endif cb2bib-2.0.1/src/PaxHeaders.5700/c2bTextEdit.h0000644000000000000000000000013214011522520015356 xustar0030 mtime=1613145424.566620341 30 atime=1613145424.830620334 30 ctime=1613145424.566620341 cb2bib-2.0.1/src/c2bTextEdit.h0000644000175000001440000000523714011522520016764 0ustar00constansusers00000000000000/*************************************************************************** * Copyright (C) 2004-2021 by Pere Constans * constans@molspaces.com * cb2Bib version 2.0.1. Licensed under the GNU GPL version 3. * See the LICENSE file that comes with this distribution. ***************************************************************************/ #ifndef C2BTEXTEDIT_H #define C2BTEXTEDIT_H #include class c2bSettings; class c2bTextEdit : public QPlainTextEdit { Q_OBJECT public: explicit c2bTextEdit(QWidget* parentw = 0); ~c2bTextEdit(); QAction* convertSelection2LaTeXAction; QAction* convertSelection2UnicodeAction; QAction* journalsToAbbreviatedAction; QAction* journalsToAlternateAbbreviatedAction; QAction* journalsToAlternateFullAction; QAction* journalsToFullAction; QAction* pasteCurrentBibTeXAction; QAction* toggleWordWrappingAction; QAction* updateMetadataAction; void cursorPosition(int* line_number, int* line_position) const; void setBibTeXActions(); void setLaTeXActions(); void updatePlainText(const QString& text); inline const QString editorFilename() const { return _editor_filename; } void setEditorFilename(const QString& fn) { _editor_filename = fn; } signals: void overwriteModeChanged(); public slots: void toggleWordWrapping(); protected slots: void convert2LaTeX(); void convert2Unicode(); protected: void contextMenuEvent(QContextMenuEvent* qevent); void keyPressEvent(QKeyEvent* qevent); void resizeEvent(QResizeEvent* qevent); private: QColor _line_number_area_color; QColor* _line_number_color_p; QString _editor_filename; QWidget* _line_number_area; c2bSettings* _settingsP; int lineNumberAreaWidth(); void lineNumberAreaPaintEvent(QPaintEvent* qevent); private slots: void loadSettings(); void updateLineNumberAreaWidth(); void updateLineNumberArea(const QRect& qrect, int dy); friend class LineNumberArea; }; /*************************************************************************** * Line number area (From CodeEditor Qt's example) ***************************************************************************/ class LineNumberArea : public QWidget { public: explicit LineNumberArea(c2bTextEdit* editor) : QWidget(editor) { _editor = editor; } ~LineNumberArea() {} QSize sizeHint() const { return QSize(_editor->lineNumberAreaWidth(), 0); } protected: void paintEvent(QPaintEvent* qevent) { _editor->lineNumberAreaPaintEvent(qevent); } private: c2bTextEdit* _editor; }; #endif cb2bib-2.0.1/src/PaxHeaders.5700/c2bCiterModel.cpp0000644000000000000000000000013214011522520016206 xustar0030 mtime=1613145424.390620346 30 atime=1613145424.826620334 30 ctime=1613145424.390620346 cb2bib-2.0.1/src/c2bCiterModel.cpp0000644000175000001440000006745214011522520017623 0ustar00constansusers00000000000000/*************************************************************************** * Copyright (C) 2004-2021 by Pere Constans * constans@molspaces.com * cb2Bib version 2.0.1. Licensed under the GNU GPL version 3. * See the LICENSE file that comes with this distribution. ***************************************************************************/ #include "c2bCiterModel.h" #include #include "c2b.h" #include #include namespace { template class ascending { public: explicit ascending(const T& data) : _data(data) {} inline bool operator()(const int i, const int j) { return _data.at(i) < _data.at(j); } private: const T& _data; }; } // namespace c2bCiterModel::c2bCiterModel(QObject* parento) : QAbstractTableModel(parento) { _first_column_color = QApplication::palette().color(QPalette::Active, QPalette::Base).darker(110); _clear(); } void c2bCiterModel::loadCitations(const QStringList& fns) { emit layoutAboutToBeChanged(); _clear(); _analyzer.reload(); for (int i = 0; i < fns.count(); ++i) _add_citations(fns.at(i)); _set_table_data(); _set_sort_indices(); _update_format(); emit layoutChanged(); emit statusMessage(tr("Loaded %1 references from %2 files.").arg(_citation_count).arg(fns.count())); } void c2bCiterModel::loadCitations(const QString& fn) { emit layoutAboutToBeChanged(); _clear(); _analyzer.reload(); _add_citations(fn); _set_table_data(); _set_sort_indices(); _update_format(); emit layoutChanged(); emit statusMessage(tr("Loaded %1 references.").arg(_citation_count)); } void c2bCiterModel::reloadCitations(const QStringList& fns, const c2bCiter::State& state, QModelIndex* current_index) { emit layoutAboutToBeChanged(); _clear(); _analyzer.reload(); for (int i = 0; i < fns.count(); ++i) _add_citations(fns.at(i)); _set_table_data(); _set_sort_indices(); _update_format(state.format); const int current_item(_current_item(state.index_data)); _update_current_index(current_item, current_index); _history.saveCurrentState(_format, _filter, current_item, current_index, _fstring); emit layoutChanged(); emit statusMessage(tr("Loaded %1 references from %2 files.").arg(_citation_count).arg(fns.count())); } QVariant c2bCiterModel::data(const QModelIndex& i, int role) const { if (role == Qt::DisplayRole) return (this->*_display_ptr)(i.row(), i.column()); else if (role == Qt::DecorationRole) { if (_format == c2bCiter::K && i.column() == 0) return QVariant(QIcon(":/icons/icons/bullet.png")); if (i.column() == 0) { if (_is_selected.at(_offset(i.row()))) return QVariant(QIcon(":/icons/icons/citer_citation_checked.png")); else return QVariant(QIcon(":/icons/icons/citer_citation.png")); } return QVariant(); } else if (role == Qt::BackgroundRole) { if (i.column() == 0 && _column_count > 1 && _format != c2bCiter::K) return _first_column_color; else return QVariant(); } else return QVariant(); } QStringList c2bCiterModel::dataSelectedCiteIds() const { QStringList ids; for (int i = 0; i < _citation_count; ++i) if (_is_selected.at(_map_yajt.at(i))) ids.append(_citeId.at(_map_yajt.at(i))); return ids; } void c2bCiterModel::setPatternFilter(const QString& pattern, QModelIndex* current_index, const c2bCiter::Format format) { _history.saveCurrentState(_format, _filter, _current_item(current_index), current_index, _fstring); emit layoutAboutToBeChanged(); const QStringList word(pattern.split(c2bUtils::nonLetter, QString::SkipEmptyParts)); _filter = word.count() > 0 ? c2bCiter::Pattern : c2bCiter::None; _format = format; if (_filter == c2bCiter::Pattern) { _fstring = pattern; if (_format == c2bCiter::K) { int j(0); for (int i = 0; i < _keyword_count; ++i) { const QString& str = _analyzer.sentence(i); bool mf(true); for (int w = 0; w < word.count(); ++w) if (!str.contains(word.at(w), Qt::CaseSensitive)) { mf = false; break; } if (mf) _map_filter[j++] = i; } _row_count = j; } else { for (int i = 0; i < _citation_count; ++i) { _matches_filter[i] = true; const QString& str = _search_string.at(i); for (int w = 0; w < word.count(); ++w) if (!str.contains(word.at(w), Qt::CaseSensitive)) { _matches_filter[i] = false; break; } } } } else _fstring.clear(); _update_format(_format == c2bCiter::R ? _history.lastCitationFormat() : _format); _update_current_index(_format == c2bCiter::K ? _history.lastKeyword() : _history.lastCitation(), current_index); emit layoutChanged(); } void c2bCiterModel::setSelectedFilter(QModelIndex* current_index) { emit statusLabel(tr("Selected")); _history.saveCurrentState(_format, _filter, _current_item(current_index), current_index, _fstring); emit layoutAboutToBeChanged(); for (int i = 0; i < _citation_count; ++i) _matches_filter[i] = _is_selected.at(i); _filter = c2bCiter::Selected; _fstring.clear(); _update_format(_history.lastCitationFormat()); _update_current_index(_history.lastSelectionCitation(), current_index); emit layoutChanged(); } void c2bCiterModel::setRelatedFilter(const QString& documentfn, QModelIndex* current_index, const c2bCiter::Format format) { _analyzer.setSimilarDocuments(documentfn); if (_analyzer.similarCount() == 0) { emit statusMessage(tr("No related references.")); return; } emit statusLabel(tr("Related to '%1'").arg(_title.at(_file.value(documentfn)))); _history.saveCurrentState(_format, _filter, _current_item(current_index), current_index, _fstring); emit layoutAboutToBeChanged(); for (int i = 0; i < _citation_count; ++i) _matches_filter[i] = false; const int sc(_analyzer.similarCount()); _related_count = 0; for (int i = 0; i < sc; ++i) { // Note that data in collectionAnalyzer index might not match // BibTeX files data (outdated index or users browsing // particular BibTeX file sets). Use full path document // filenames to set a mapping. const int j(_file.value(_analyzer.similar(i), -1)); if (j == -1) { _analyzer.skipSimilarDocument(i); continue; } _matches_filter[j] = true; _map_filter[i] = j; ++_related_count; } _filter = c2bCiter::Related; _fstring = documentfn; _update_format(format); _update_current_index(_history.lastCitation(), current_index); emit layoutChanged(); } void c2bCiterModel::setKeywordFilter(const QString& keyword, QModelIndex* current_index) { _analyzer.setKeywordDocuments(keyword); if (_analyzer.documentCount() == 0) { emit statusMessage(tr("No related references.")); return; } emit statusLabel(tr("Related to '%1'").arg(keyword)); _history.saveCurrentState(_format, _filter, _current_item(current_index), current_index, _fstring); emit layoutAboutToBeChanged(); for (int i = 0; i < _citation_count; ++i) _matches_filter[i] = false; const int dc(_analyzer.documentCount()); for (int i = 0; i < dc; ++i) { // See comment at c2bCiterModel::setRelatedFilter const int j(_file.value(_analyzer.document(i), -1)); if (j == -1) continue; _matches_filter[j] = true; } _filter = c2bCiter::Keyword; _fstring = keyword; _update_format(_history.lastCitationFormat()); _update_current_index(_history.lastKeyword(), current_index); emit layoutChanged(); } void c2bCiterModel::setDocumentFilter(const QString& documentfn, QModelIndex* current_index) { _analyzer.setDocumentKeywords(documentfn); const int nk(_analyzer.keywordCount()); if (nk == 0) { emit statusMessage(tr("No keywords from this reference.")); return; } emit statusLabel(tr("Keywords from '%1'").arg(_title.at(_file.value(documentfn)))); _history.saveCurrentState(_format, _filter, _current_item(current_index), current_index, _fstring); emit layoutAboutToBeChanged(); int j(0); for (int i = 0; i < nk; ++i) _map_filter[j++] = _analyzer.keywordid(i); _row_count = j; _filter = c2bCiter::Document; _fstring = documentfn; _update_format(c2bCiter::K); _update_current_index(_history.lastKeyword(), current_index); emit layoutChanged(); } void c2bCiterModel::setGlossaryView(QModelIndex* current_index) { _history.saveCurrentState(_format, _filter, _current_item(current_index), current_index, _fstring); emit layoutAboutToBeChanged(); _filter = c2bCiter::None; _fstring.clear(); _update_format(c2bCiter::K); _update_current_index(_history.lastKeyword(), current_index); emit patternFilterChanged(_fstring); emit layoutChanged(); } void c2bCiterModel::selectCitation(const QModelIndex& i) { if (_format == c2bCiter::K) return; _is_selected[_offset(i.row())] = !_is_selected.at(_offset(i.row())); emit layoutChanged(); } QList c2bCiterModel::sizeHintForColumns() const { QList sizes; switch (_format) { case c2bCiter::AJYT: sizes.append(std::min(20, _author_max_length + 2)); sizes.append(20); sizes.append(6); sizes.append(100); break; case c2bCiter::IT: sizes.append(12); sizes.append(100); break; case c2bCiter::JYA: sizes.append(std::min(25, _journal_max_length)); sizes.append(6); sizes.append(100); break; case c2bCiter::K: sizes.append(100); break; case c2bCiter::R: sizes.append(9); sizes.append(100); break; case c2bCiter::T: sizes.append(100); break; case c2bCiter::YAJT: default: sizes.append(8); sizes.append(75); sizes.append(25); sizes.append(100); break; } return sizes; } void c2bCiterModel::clearSelection() { emit layoutAboutToBeChanged(); for (int i = 0; i < _citation_count; ++i) _is_selected[i] = false; emit layoutChanged(); } void c2bCiterModel::clearCurrentFilter(QModelIndex* current_index) { if (_filter == c2bCiter::None) return; if (_filter != c2bCiter::Pattern && _history.lastState().filter == c2bCiter::Pattern) { const c2bCiter::State& s(_history.lastState()); setPatternFilter(s.filter_string, current_index, s.format); emit patternFilterChanged(s.filter_string); } else { _history.saveCurrentState(_format, _filter, _current_item(current_index), current_index, _fstring); emit layoutAboutToBeChanged(); _filter = c2bCiter::None; _fstring.clear(); _update_format(_format == c2bCiter::R ? _history.lastCitationFormat() : _format); _update_current_index(_format == c2bCiter::K ? _history.lastKeyword() : _history.lastCitation(), current_index); emit patternFilterChanged(_fstring); emit layoutChanged(); } } c2bCiter::State c2bCiterModel::currentState(const QModelIndex& current_index) const { const int current_item(_current_item(current_index)); c2bCiter::State s(_format == c2bCiter::R ? _history.lastCitationFormat() : _format, _filter, current_index.row(), _fstring); if (current_item > -1) s.index_data = (_format == c2bCiter::K) ? _analyzer.sentence(current_item) : _search_string.at(current_item); return s; } void c2bCiterModel::restoreState(const c2bCiter::State& s, QModelIndex* current_index) { if (current_index) _history.saveCurrentItemIndex(_format, _filter, _current_item(current_index)); switch (s.filter) { case c2bCiter::None: emit layoutAboutToBeChanged(); _filter = c2bCiter::None; _fstring.clear(); _update_format(s.format); emit patternFilterChanged(_fstring); emit layoutChanged(); break; case c2bCiter::Document: if (_file.contains(s.filter_string)) emit statusLabel(tr("Keywords from '%1'").arg(_title.at(_file.value(s.filter_string)))); setDocumentFilter(s.filter_string, 0); break; case c2bCiter::Keyword: setKeywordFilter(s.filter_string, 0); break; case c2bCiter::Pattern: setPatternFilter(s.filter_string, 0, s.format); emit patternFilterChanged(s.filter_string); break; case c2bCiter::Related: setRelatedFilter(s.filter_string, 0, s.format); break; case c2bCiter::Selected: emit statusLabel(tr("Selected")); setSelectedFilter(0); break; default: break; } if (current_index) *current_index = index(s.viewer_index, 0); } void c2bCiterModel::restorePreviousState(QModelIndex* current_index) { if (_history.currentState() == -1) _history.saveCurrentState(_format, _filter, _current_item(current_index), current_index, _fstring); const c2bCiter::State& s(_history.previousState()); restoreState(s, 0); if (current_index) *current_index = index(s.viewer_index, 0); } void c2bCiterModel::restoreNextState(QModelIndex* current_index) { if (_history.currentState() == -1) return; const c2bCiter::State& s(_history.nextState()); restoreState(s, 0); if (current_index) *current_index = index(s.viewer_index, 0); } void c2bCiterModel::updateFormat(const c2bCiter::Format format, QModelIndex* current_index) { if (_format == c2bCiter::K) { c2bCiter::State s(_history.lastNonKeywordState()); s.format = format; restoreState(s, current_index); } else { emit layoutAboutToBeChanged(); const int current_item(_current_item(current_index)); _update_format(format); _update_current_index(current_item, current_index); emit layoutChanged(); } } void c2bCiterModel::_update_format(const c2bCiter::Format format) { _format = format; _history.saveCurrentCitationFormat(_format); switch (_format) { case c2bCiter::AJYT: _column_count = 4; _display_ptr = &c2bCiterModel::_display_ajyt; break; case c2bCiter::IT: _column_count = 2; _display_ptr = &c2bCiterModel::_display_it; break; case c2bCiter::JYA: _column_count = 3; _display_ptr = &c2bCiterModel::_display_jya; break; case c2bCiter::K: _column_count = 1; _display_ptr = &c2bCiterModel::_display_k; break; case c2bCiter::R: _column_count = 2; _display_ptr = &c2bCiterModel::_display_r; break; case c2bCiter::T: _column_count = 1; _display_ptr = &c2bCiterModel::_display_t; break; case c2bCiter::YAJT: default: _column_count = 4; _display_ptr = &c2bCiterModel::_display_yajt; break; } _set_mapping(); } int c2bCiterModel::_current_item(const QString& index_data) const { int current_item(-1); if (!index_data.isEmpty()) { if (_format == c2bCiter::K) { for (int i = 0; i < _keyword_count; ++i) if (index_data == _analyzer.sentence(i)) { current_item = i; break; } } else { for (int i = 0; i < _citation_count; ++i) if (index_data == _search_string.at(i)) { current_item = i; break; } } } return current_item; } void c2bCiterModel::_update_current_index(const int current_item, QModelIndex* current_index) const { if (!current_index) return; if (current_item >= 0) for (int i = 0; i < _row_count; ++i) if (_offset(i) == current_item) { *current_index = index(i, 0); return; } *current_index = index(0, 0); } void c2bCiterModel::_add_citations(const QString& fn) { bibParser* bpP = c2b::bibParser(); const QString tag_author("author"); const QString tag_booktitle("booktitle"); const QString tag_doi("doi"); const QString tag_editor("editor"); const QString tag_file("file"); const QString tag_journal("journal"); const QString tag_title("title"); const QString tag_url("url"); const QString tag_year("year"); const QString template_position("%1:%2"); QStringList fields; fields.append(tag_author); fields.append(tag_booktitle); fields.append(tag_doi); fields.append(tag_editor); fields.append(tag_file); fields.append(tag_journal); fields.append(tag_title); fields.append(tag_url); fields.append(tag_year); bibReference ref; bpP->initReferenceParsing(fn, fields, &ref); const QRegExp initials1("\\b\\w\\b"); const QRegExp initials2("[^\\w\\s]"); const QString bibtex(c2bUtils::fileToString(fn)); while (bpP->referencesIn(bibtex, &ref)) { QString author(ref.anyAuthor()); if (!author.isEmpty()) { author = bpP->authorFromBibTeX(author); author.remove(initials1); author.remove(initials2); author.replace(" and ", ", "); c2bUtils::simplifyString(author); } QString title(ref.anyTitle()); c2bUtils::cleanTitle(title, true); QString url(ref.value(tag_url)); if (url.isEmpty()) { const QString doi(ref.value(tag_doi)); if (!doi.isEmpty()) { if (doi.startsWith("http")) url = QUrl::toPercentEncoding(doi); else url = "https://dx.doi.org/" + QUrl::toPercentEncoding(doi); } } QString file(ref.value(tag_file)); if (!file.isEmpty()) file = QDir::cleanPath(file); uint included_date; const QFileInfo finf(file); if (finf.exists()) included_date = QDateTime(finf.lastModified().date()).toTime_t(); else included_date = 0; _author_string.append(author); _bibtex_position.append(template_position.arg(fn).arg(ref.positionValue)); _citeId.append(ref.citeidName); _included_date.append(included_date); _journal.append(ref.anyJournal()); _title.append(title); _url.append(url); _year.append(ref.value(tag_year)); if (!file.isEmpty()) _file.insert(file, _citation_count); _citation_count++; } } void c2bCiterModel::_clear() { _filter = c2bCiter::None; _format = c2bCiter::AJYT; _author.clear(); _author_string.clear(); _bibtex_position.clear(); _citeId.clear(); _file.clear(); _fstring.clear(); _history.clear(); _included_date.clear(); _is_selected.clear(); _journal.clear(); _map_ajyt.clear(); _map_author.clear(); _map_filter.clear(); _map_it.clear(); _map_jya.clear(); _map_t.clear(); _map_yajt.clear(); _matches_filter.clear(); _search_string.clear(); _title.clear(); _url.clear(); _year.clear(); _author_count = 0; _author_max_length = 0; _citation_count = 0; _column_count = 0; _journal_max_length = 0; _keyword_count = 0; _mapping = 0; _related_count = 0; _row_count = 0; } /**************************************************************************** SETTING DATA POINTERS *****************************************************************************/ void c2bCiterModel::_set_table_data() { const QString sep(", "); const QChar dot('.'); for (int i = 0; i < _citation_count; ++i) _author_count += _author_string.at(i).count(sep) + 1; _author.resize(_author_count); _map_author.resize(_author_count); int ij(0); for (int i = 0; i < _citation_count; ++i) { const QStringList authors(_author_string.at(i).split(sep, QString::KeepEmptyParts)); for (int j = 0; j < authors.count(); ++j) { _author[ij] = authors.at(j).trimmed(); _map_author[ij] = i; _author_max_length = std::max(_author_max_length, _author.at(ij).length()); ++ij; } } if (_author_count != ij) qFatal("c2bCiterModel::_set_table_data: Mismatch author mapping"); bibParser* bpP = c2b::bibParser(); for (int i = 0; i < _citation_count; ++i) { _journal[i] = bpP->abbreviatedJournal(_journal.at(i)); _journal[i].remove(dot); _journal_max_length = std::max(_journal_max_length, _journal.at(i).length()); } _is_selected.resize(_citation_count); for (int i = 0; i < _citation_count; ++i) _is_selected[i] = false; _keyword_count = _analyzer.sentenceCount(); const int mca(std::max(_citation_count, _author_count)); const int mcas(std::max(mca, _keyword_count)); _matches_filter.resize(mca); _map_filter.resize(mcas); } void c2bCiterModel::_set_sort_indices() { const QChar sp(' '); // AJYT // Use _search_string as temporary for sorting _search_string.resize(_author_count); for (int i = 0; i < _author_count; ++i) { const int j(_map_author.at(i)); _search_string[i] = c2bUtils::toAscii( _author.at(i) + sp + _journal.at(j) + sp + _year.at(j) + sp + _title.at(j), c2bUtils::Collation); } _map_ajyt.resize(_author_count); for (int i = 0; i < _author_count; ++i) _map_ajyt[i] = i; ascending> ajyt(_search_string); std::sort(_map_ajyt.begin(), _map_ajyt.end(), ajyt); // IT _search_string.resize(_citation_count); const int current_dtt(QDateTime::currentDateTime().toTime_t()); const QString dtt("%1"); const QChar padding('0'); for (int i = 0; i < _citation_count; ++i) _search_string[i] = c2bUtils::toAscii( dtt.arg(current_dtt - _included_date.at(i), 10, 10, padding) + sp + _title.at(i), c2bUtils::Collation); _map_it.resize(_citation_count); for (int i = 0; i < _citation_count; ++i) _map_it[i] = i; ascending> it(_search_string); std::sort(_map_it.begin(), _map_it.end(), it); // JYA for (int i = 0; i < _citation_count; ++i) _search_string[i] = c2bUtils::toAscii(_journal.at(i) + sp + _year.at(i) + sp + _author_string.at(i), c2bUtils::Collation); _map_jya.resize(_citation_count); for (int i = 0; i < _citation_count; ++i) _map_jya[i] = i; ascending> jya(_search_string); std::sort(_map_jya.begin(), _map_jya.end(), jya); // T for (int i = 0; i < _citation_count; ++i) _search_string[i] = c2bUtils::toAscii(_title.at(i), c2bUtils::Collation); _map_t.resize(_citation_count); for (int i = 0; i < _citation_count; ++i) _map_t[i] = i; ascending> t(_search_string); std::sort(_map_t.begin(), _map_t.end(), t); // YAJT for (int i = 0; i < _citation_count; ++i) _search_string[i] = c2bUtils::toAscii( _year.at(i) + sp + _author_string.at(i) + sp + _journal.at(i) + sp + _title.at(i), c2bUtils::Collation); _map_yajt.resize(_citation_count); for (int i = 0; i < _citation_count; ++i) _map_yajt[i] = i; ascending> yajt(_search_string); std::sort(_map_yajt.begin(), _map_yajt.end(), yajt); // Keep _search_string for filtering } void c2bCiterModel::_set_mapping() { switch (_format) { case c2bCiter::AJYT: _row_count = _author_count; _mapping = &_map_ajyt; break; case c2bCiter::IT: _row_count = _citation_count; _mapping = &_map_it; break; case c2bCiter::JYA: _row_count = _citation_count; _mapping = &_map_jya; break; case c2bCiter::K: _row_count = _filter == c2bCiter::None ? _keyword_count : _row_count; break; case c2bCiter::R: _row_count = _related_count; _mapping = &_map_filter; break; case c2bCiter::T: _row_count = _citation_count; _mapping = &_map_t; break; case c2bCiter::YAJT: default: _row_count = _citation_count; _mapping = &_map_yajt; break; } if (_filter == c2bCiter::None) return; if (_format == c2bCiter::K) { _mapping = &_map_filter; return; } if (_format == c2bCiter::R) // _map_filter is already set in setRelatedFilter return; int r(0); if (_format == c2bCiter::AJYT) { for (int i = 0; i < _row_count; ++i) if (_matches_filter.at(_map_author.at(_mapping->at(i)))) _map_filter[r++] = _mapping->at(i); } else { for (int i = 0; i < _row_count; ++i) if (_matches_filter.at(_mapping->at(i))) _map_filter[r++] = _mapping->at(i); } _row_count = r; _mapping = &_map_filter; } QString c2bCiterModel::_display_ajyt(const int row, const int column) const { switch (column) { case 0: return _author.at(_mapping->at(row)); case 1: return _journal.at(_map_author.at(_mapping->at(row))); case 2: return _year.at(_map_author.at(_mapping->at(row))); case 3: return _title.at(_map_author.at(_mapping->at(row))); default: return QString(); } } QString c2bCiterModel::_display_it(const int row, const int column) const { switch (column) { case 0: return _included_date.at(_offset(row)) > 0 ? QDateTime::fromTime_t(_included_date.at(_offset(row))).date().toString(Qt::ISODate) : QString(); case 1: return _title.at(_offset(row)); default: return QString(); } } QString c2bCiterModel::_display_jya(const int row, const int column) const { switch (column) { case 0: return _journal.at(_offset(row)); case 1: return _year.at(_offset(row)); case 2: return _author_string.at(_offset(row)); default: return QString(); } } QString c2bCiterModel::_display_k(const int row, const int column) const { switch (column) { case 0: return _analyzer.sentence(_offset(row)); default: return QString(); } } QString c2bCiterModel::_display_r(const int row, const int column) const { switch (column) { case 0: return QString("%1%").arg(100 * _analyzer.similarity(row), 3, 'f', 0); case 1: return _title.at(_offset(row)); default: return QString(); } } QString c2bCiterModel::_display_t(const int row, const int column) const { switch (column) { case 0: return _title.at(_offset(row)); default: return QString(); } } QString c2bCiterModel::_display_yajt(const int row, const int column) const { switch (column) { case 0: return _year.at(_offset(row)); case 1: return _author_string.at(_offset(row)); case 2: return _journal.at(_offset(row)); case 3: return _title.at(_offset(row)); default: return QString(); } } int c2bCiterModel::_offset(const int i) const { if (_format == c2bCiter::AJYT) return _map_author.at(_mapping->at(i)); else if (_format == c2bCiter::K && _filter == c2bCiter::None) return i; else return _mapping->at(i); } cb2bib-2.0.1/src/PaxHeaders.5700/c2bConfigure.ui0000644000000000000000000000007414011522151015740 xustar0030 atime=1613145424.830620334 30 ctime=1613145424.302620349 cb2bib-2.0.1/src/c2bConfigure.ui0000644000175000001440000017533714011522151017352 0ustar00constansusers00000000000000 Pere Constans c2bConfigure 0 0 1184 775 Configure - cb2Bib Qt::Horizontal 0 0 200 16777215 PointingHandCursor true QFrame::Raised QAbstractItemView::NoSelection QAbstractItemView::SelectColumns 32 32 QListView::Static 5 QListView::ListMode 0 true Annote :/icons/icons/annote.png:/icons/icons/annote.png BibTeX :/icons/icons/configure_bibtex.png:/icons/icons/configure_bibtex.png Clipboard :/icons/icons/configure_clipboard.png:/icons/icons/configure_clipboard.png Documents :/icons/icons/configure_documents.png:/icons/icons/configure_documents.png Files :/icons/icons/configure_files.png:/icons/icons/configure_files.png Fonts :/icons/icons/configure_fonts.png:/icons/icons/configure_fonts.png Network :/icons/icons/configure_network.png:/icons/icons/configure_network.png Shortcuts :/icons/icons/configure_shortcuts.png:/icons/icons/configure_shortcuts.png Utilities :/icons/icons/configure_utilities.png:/icons/icons/configure_utilities.png Qt::Vertical 0 1 Annote Cascading Style Sheet (CSS) Select Annote CSS file :/icons/icons/mimeFolder.png:/icons/icons/mimeFolder.png MathJax Header Select MathJax header file :/icons/icons/mimeFolder.png:/icons/icons/mimeFolder.png HTML Output Include CSS in HTML Use relative links Qt::Horizontal 40 20 Annote Viewer Font Family false Size 0 0 true false Annote Viewer Fixed Font Family false QFontComboBox::MonospacedFonts Size 0 0 true false Qt::Vertical 20 41 1 Cite ID Pattern 9 6 Right click to edit pattern placeholders Author and Editor Format 9 6 Qt::Horizontal 40 20 F&ull Name Abbrevia&ted Journal Format 9 6 Full Name Abbreviated Qt::Horizontal QSizePolicy::Expanding 95 31 Number Separator 9 6 Keep empty for default dash. Blank spaces count Cite Command Pattern 9 6 LaTeX Conversions 9 6 Qt::Horizontal QSizePolicy::Expanding 182 20 Postprocess 'month' Set 'title' in double braces Convert entry strings to LaTe&X Reference Extraction 9 6 Tr&y Heuristic Guess if recognition fails Reference Check 9 6 Check Repeated On Save External BibTeX Postprocessing 9 6 Aguments: Select external postprocess tool :/icons/icons/mimeFolder.png:/icons/icons/mimeFolder.png Command: Output Extension: Qt::Vertical 20 20 1 Clipboard Preprocessing 9 6 Replace/Remove from Input Stream 0 6 &Edit Alt+E Qt::Vertical 20 40 &Delete Alt+D QFrame::Raised QAbstractItemView::DoubleClicked|QAbstractItemView::EditKeyPressed|QAbstractItemView::SelectedClicked true QAbstractItemView::SingleSelection false true true 3 Find Replace Description &New Alt+N External Clipboard Preparsing Command 9 6 6 0 Select external parser tool :/icons/icons/mimeFolder.png:/icons/icons/mimeFolder.png Perform always, as part of an automatic extraction Do not show log Qt::Horizontal 40 20 Add document metadata to Input Stream 9 6 Qt::Horizontal 40 20 Append Prepend 1 Rename and Copy/Move document files Document Options 9 6 Documents Directory: Insert BibTeX metadata to document files Set directory relative to the BibTeX File Directory 6 0 Select PDF directory :/icons/icons/mimeFolder.png:/icons/icons/mimeFolder.png 9 6 Qt::Horizontal 40 20 Move (local so&urce files) Copy Document ID Pattern 9 6 Right click to edit pattern placeholders ExifTool Metadata writer 9 6 Select ExifTool executable :/icons/icons/mimeFolder.png:/icons/icons/mimeFolder.png Command: Qt::Vertical 20 16 1 Journal Abbreviation List File Select journal abbreviation file :/icons/icons/mimeFolder.png:/icons/icons/mimeFolder.png Regular Expression List File Select regular expression file :/icons/icons/mimeFolder.png:/icons/icons/mimeFolder.png Bookmarks and Network Query Info File Select network informantion file :/icons/icons/mimeFolder.png:/icons/icons/mimeFolder.png Browser Cascading Style Sheet (CSS) Select CSS file :/icons/icons/mimeFolder.png:/icons/icons/mimeFolder.png Qt::Vertical 31 20 Part Of Speech (POS) Lexicon Select POS lexicon file :/icons/icons/mimeFolder.png:/icons/icons/mimeFolder.png Search In Files Cache Directory Select cache directory :/icons/icons/mimeFolder.png:/icons/icons/mimeFolder.png 1 Family false Size 0 0 true false 0 0 Sample Text Qt::AlignHCenter QFrame::Raised true false true true 1 Context Colors 1 Use E&xternal Network Client Copy: kfmclient Select external copy executable :/icons/icons/mimeFolder.png:/icons/icons/mimeFolder.png Copy Aguments: Move: kfmclient Select external move executable :/icons/icons/mimeFolder.png:/icons/icons/mimeFolder.png Move Aguments: Use Proxy false false Host: Port: 0 0 Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter Type: Http Socks5 Queries 9 6 Download document if available &Keep Query temporary files (Debug Only) Perform Network Queries after automatic reference extractions Alt+Q Qt::Vertical 20 16 1 Main panel Editor and reference list Qt::Vertical 20 398 1 PDF Import: To plain text converter 9 6 Select external convert tool :/icons/icons/mimeFolder.png:/icons/icons/mimeFolder.png Aguments: Command: BibTeX search: To plain text converter 9 6 Select external convert tool :/icons/icons/mimeFolder.png:/icons/icons/mimeFolder.png Aguments: Command: Qt::Vertical 20 40 Qt::Horizontal 0 0 false Qt::Horizontal Qt::Horizontal QDialogButtonBox::Apply|QDialogButtonBox::Cancel|QDialogButtonBox::Help|QDialogButtonBox::Save c2bLineEdit QLineEdit
    c2bLineEdit.h
    c2bIdPatternLineEdit QLineEdit
    c2bIdPatternLineEdit.h
    c2bCitePatternLineEedit QLineEdit
    c2bCitePatternLineEedit.h
    c2bShortcutWidget QWidget
    c2bShortcutWidget.h
    1
    buttonBox buttonBox accepted() c2bConfigure accept() 427 578 612 561 buttonBox rejected() c2bConfigure reject() 385 578 342 524 FmClient toggled(bool) clientGroupBox setEnabled(bool) 549 46 549 106 UseProxy toggled(bool) proxyGroupBox setEnabled(bool) 235 162 276 190
    cb2bib-2.0.1/src/PaxHeaders.5700/c2bAnnote.cpp0000644000000000000000000000013214011522520015403 xustar0030 mtime=1613145424.374620347 30 atime=1613145424.818620334 30 ctime=1613145424.374620347 cb2bib-2.0.1/src/c2bAnnote.cpp0000644000175000001440000001460614011522520017011 0ustar00constansusers00000000000000/*************************************************************************** * Copyright (C) 2004-2021 by Pere Constans * constans@molspaces.com * cb2Bib version 2.0.1. Licensed under the GNU GPL version 3. * See the LICENSE file that comes with this distribution. ***************************************************************************/ #include "c2bAnnote.h" #include "c2b.h" #include "c2bFileSystemWatcher.h" #include "c2bSettings.h" #include "c2bUtils.h" #include "c2bWebBrowser.h" #include #include #include #include #include /** \page c2bannote cb2Bib Annote The cb2Bib Annote module is named after the BibTeX key annote. Annote is not for a 'one reference annotation' though. Instead, Annote is for short notes that interrelate several references. Annote takes a plain text note, with minimal or no markup, inserts the bibliographic citations, and converts it to a HTML page with links to the referenced documents. From within cb2Bib, to write a note, type Alt+A, enter a filename, either new or existing, and once in Annote, type E to start the editor. Each time you save the document the viewer will be updated. For help on Annote's syntax type F1. If cb2Bib was compiled without Annote's Viewer, typing Alt+A will start the editor and HTML viewing will be committed to the default web browser. From the command line, typing \verbatim cb2bib --html-annote annote.tex \endverbatim will produce the HTML file annote.tex.html. See also \ref c2bconf_annote and \ref commandline. \section c2bannote_syntax Annote Syntax The resulting HTML file annote.tex.html can be seen at \htmlonly cb2Bib Annote. \endhtmlonly \htmlonly
    % annote.tex
    
    GET_C2BANNOTE_TEX_DOC
    \endhtmlonly
    
    */
    c2bAnnote::c2bAnnote(QWidget* parentw) : QMainWindow(parentw)
    {
        _view_port = new c2bWebBrowser(this);
        setCentralWidget(_view_port);
        QLabel* informationLabel = new QLabel(this);
        statusBar()->addWidget(informationLabel, 1);
        connect(_view_port, SIGNAL(windowTitleChanged(QString)), this, SLOT(setWindowTitle(QString)));
        connect(_view_port, SIGNAL(statusMessage(QString)), this, SLOT(showMessage(QString)));
    
        // Creating cb2Bib global resources
        c2b* c2b_resources = new c2b(this, this);
        connect(c2b_resources, SIGNAL(statusMessage(QString)), this, SLOT(showMessage(QString)));
    
        QAction* act = new QAction(QIcon(QString::fromUtf8(":/icons/icons/edit.png")), tr("Edit Note"), this);
        act->setShortcut(QKeySequence(Qt::Key_E));
        act->setStatusTip(tr("Edit TeX note"));
        c2bUtils::addSeparator(_view_port);
        _view_port->addAction(act);
        connect(act, SIGNAL(triggered()), this, SLOT(edit()));
    
        act = new QAction(QIcon(QString::fromUtf8(":/icons/icons/configure.png")), tr("Configure"), this);
        act->setShortcut(QKeySequence(Qt::Key_C));
        act->setStatusTip(tr("Configure cb2Bib Annote"));
        c2bUtils::addSeparator(_view_port);
        _view_port->addAction(act);
        connect(act, SIGNAL(triggered()), this, SLOT(configure()));
    
        _settingsP = c2bSettingsP;
        resize(_settingsP->value("c2bAnnote/size", size()).toSize());
        move(_settingsP->value("c2bAnnote/position", pos()).toPoint());
        loadSettings();
        connect(_settingsP, SIGNAL(newSettings()), this, SLOT(loadSettings()));
    
        _t2h = new texToHtml;
        _fsw = new c2bFileSystemWatcher(this);
        connect(_fsw, SIGNAL(fileChanged(QString)), this, SLOT(annote()));
        disconnect(_view_port->viewReloadAction, 0, 0, 0);
        connect(_view_port->viewReloadAction, SIGNAL(triggered()), this, SLOT(update()));
    
        QShortcut* help_shortcut = new QShortcut(QKeySequence(QKeySequence::HelpContents), this);
        connect(help_shortcut, SIGNAL(activated()), this, SLOT(help()));
    }
    
    c2bAnnote::~c2bAnnote()
    {
        delete _t2h;
        _settingsP->setValue("c2bAnnote/position", pos());
        _settingsP->setValue("c2bAnnote/size", size());
    }
    
    
    bool c2bAnnote::show()
    {
        _annote_filename = QDir::cleanPath(_settingsP->cl_annote_filename);
        const bool is_html = _annote_filename.endsWith(".html");
        if (is_html)
            _annote_filename.remove(QRegExp("\\.html$"));
        if (!QFileInfo::exists(_annote_filename))
        {
            QMessageBox::warning(this, tr("Warning - cb2Bib"),
                                 tr("Unable to open the file %1 for reading.\nError: '%2'.")
                                 .arg(QDir::toNativeSeparators(_annote_filename), "File does not exist"),
                                 QMessageBox::Ok);
            return false;
        }
        _html_filename = _annote_filename + ".html";
        if (!is_html || !QFileInfo::exists(_html_filename))
            _t2h->toHtml(c2bUtils::fileToString(_annote_filename), _html_filename);
        _view_port->setHomePage(_html_filename);
        _fsw->addPath(_annote_filename);
        QMainWindow::show();
        return true;
    }
    
    void c2bAnnote::annote()
    {
        QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
        _t2h->toHtml(c2bUtils::fileToString(_annote_filename), _html_filename);
        if (_html_filename == QDir::cleanPath(_view_port->url().toLocalFile()))
            _view_port->reload();
        QApplication::restoreOverrideCursor();
    }
    
    void c2bAnnote::update()
    {
        if (_html_filename == QDir::cleanPath(_view_port->url().toLocalFile()))
            annote();
        else
            _view_port->reload();
    }
    
    void c2bAnnote::edit()
    {
        c2bUtils::openFile(_annote_filename, this);
    }
    
    void c2bAnnote::configure()
    {
        // Attention: Currently c2bAnnote is page 0. Update here if c2bConfigure changes page ordering.
        c2b::configure(0);
    }
    
    void c2bAnnote::setWindowTitle(const QString& title)
    {
        if (title.isEmpty())
            QMainWindow::setWindowTitle("Annote - cb2Bib");
        else
            QMainWindow::setWindowTitle(title + " - cb2Bib");
        if (title == "New Note")
            showMessage(tr("Press E to Edit and %1 for Help.").arg(QKeySequence(QKeySequence::HelpContents).toString()));
    }
    
    void c2bAnnote::showMessage(const QString& ms)
    {
        statusBar()->showMessage(ms, C2B_MESSAGE_TIME);
    }
    
    void c2bAnnote::loadSettings()
    {
        _view_port->setFont(_settingsP->value("c2bAnnote/Font").value());
        _view_port->setFixedFont(_settingsP->value("c2bAnnote/FixedFont").value());
    }
    
    void c2bAnnote::help()
    {
        c2bUtils::displayHelp("https://www.molspaces.com/cb2bib/doc/c2bannote/");
    }
    cb2bib-2.0.1/src/PaxHeaders.5700/c2bCiter.h0000644000000000000000000000013214011522520014672 xustar0030 mtime=1613145424.490620344
    30 atime=1613145424.826620334
    30 ctime=1613145424.490620344
    cb2bib-2.0.1/src/c2bCiter.h0000644000175000001440000001223414011522520016273 0ustar00constansusers00000000000000/***************************************************************************
     *   Copyright (C) 2004-2021 by Pere Constans
     *   constans@molspaces.com
     *   cb2Bib version 2.0.1. Licensed under the GNU GPL version 3.
     *   See the LICENSE file that comes with this distribution.
     ***************************************************************************/
    #ifndef C2BCITER_H
    #define C2BCITER_H
    
    #include 
    
    
    /** \page c2bciter cb2Bib Citer
    
        The cb2Bib Citer is a keyboard based module for inserting citation IDs into
        a working document. Conveniently, the command c2bciter, or its
        expansion cb2bib --citer, can be assigned to a global, desktop
        wide shortcut key. This will provide an easy access to the citer from
        within any text editor. Pressing the shortcut turns on and off the citer
        panel. Once appropriate references are selected, pressing key C sets the
        citations either to the clipboard or to a LyX pipe, closes the citer panel,
        and returns keyboard focus to the editor.
    
        By default, c2bciter loads all references from the current
        directory, specified in the cb2Bib main panel. On the desktop tray, the
        cb2Bib icon indicates that the citer is running. Its context menu offers
        the possibility to load other files or directories, or to toggle full
        screen mode.
    
        Search, filtering, navigation, and citation are keyword based. Pressing
        keys A, I, J, T, and Y sorts the references by author, included date,
        journal, title, and year, respectively. Key F initiates filtering, and Esc
        leaves filtering mode. References are selected when pressing enter. Key S
        toggles the current selection display, and Del clears the selection. The
        combination Shift + letter navigates through the rows starting by the
        letter.
    
        Advanced filtering capabilities are available after indexing the documents.
        Document indexing, or term or key sentence extraction, is performed by
        clicking the tray icon menu action Index Documents. Once indexing is done
        and after clicking Refresh, pressing K displays the document extracted
        keywords, and pressing G, the collection glossary of terms. On a keyword,
        pressing R display all documents indexed by the keyword. On a document,
        pressing R display related documents. Relatedness is set from keyword based
        similarity measures.
    
        Key sequence Alt+C toggles clipboard connection on and off. When connection
        is on, the clipboard contents is set, each time it changes, as the filter
        string. This provides a fast way to retrieve a given reference while
        browsing elsewhere.
    
    
    
    \verbatim
       Usage:      cb2bib --citer [dirname1 [dirname2 ... ]]
                   cb2bib --citer [filename1.bib [filename2.bib ... ]]
    
    \endverbatim
    
    \verbatim
       Display Keys
          A        author - journal - year - title
          I        included date - title
          J        journal - year - author
          T        title
          Y        year - author - journal - title
    
    \endverbatim
    
    \verbatim
       Filter Keys
          D        Delete last filter
          F        Enter pattern filter mode
          G        Toggle glossary of terms view
          K        Toggle document keywords view
          R        Display related documents
    
          Left     Move to previous filtered view
          Right    Move to next filtered view
    
    \endverbatim
    
    \verbatim
       Action Keys
          C        Cite selected citations and close citer window
          Del      Unselect all citations
          E        Edit current citation's source
          Enter    Select current citation
          Esc      Exit filter mode or close citer window
          O        Open current citation's file
          S        Display the set of selected citations
          V        Display document excerpts in keywords view
          Shift+   Keyboard search naviagation
          U        Open current citation's URL
          W        Write notes using Annote
    
    \endverbatim
    
    \verbatim
       Tray Icon Actions
          F1       Citer help
          Ctrl+O   Open BibTeX directory
          Alt+O    Open BibTeX files
          F5       Refresh
          Ctrl+F   Search in files
          Alt+L    Set Lyx pipe
          F2       Toggle cb2Bib
          Alt+C    Toggle clipboard
          Alt+F    Toggle full screen
                   Index documents
    
    \endverbatim
    
    
    
      See also \ref relnotes130, \ref relnotes140, \ref relnotes147, \ref
      commandline and \ref c2bannote.
    
    */
    
    
    namespace c2bCiter
    {
    
    enum Format
    {
        AJYT,
        IT,
        JYA,
        T,
        YAJT,
        R,
        K
    };
    enum Filter
    {
        None,
        Document,
        Keyword,
        Pattern,
        Related,
        Selected
    };
    
    struct State
    {
        inline State() : format(AJYT), filter(None), viewer_index(0) {}
        inline State(const Format fo, const Filter fi, const int vi, const QString fs)
            : format(fo), filter(fi), viewer_index(vi), filter_string(fs) {}
    
        inline bool operator==(const State& s) const
        {
            return format == s.format && filter == s.filter && viewer_index == s.viewer_index &&
                   filter_string == s.filter_string;
        }
    
        Format format;
        Filter filter;
        int viewer_index;
        QString filter_string;
        QString index_data;
    };
    
    struct KeywordData
    {
        bool valid;
        QString bibtexfn;
        QString documentfn;
        QString keyword;
    };
    
    } // namespace c2bCiter
    
    #endif
    cb2bib-2.0.1/src/PaxHeaders.5700/c2bShortcutPushButton.cpp0000644000000000000000000000013214011522520020026 xustar0030 mtime=1613145424.454620345
    30 atime=1613145424.830620334
    30 ctime=1613145424.454620345
    cb2bib-2.0.1/src/c2bShortcutPushButton.cpp0000644000175000001440000000267714011522520021441 0ustar00constansusers00000000000000/***************************************************************************
     *   Copyright (C) 2004-2021 by Pere Constans
     *   constans@molspaces.com
     *   cb2Bib version 2.0.1. Licensed under the GNU GPL version 3.
     *   See the LICENSE file that comes with this distribution.
     ***************************************************************************/
    #include "c2bShortcutPushButton.h"
    
    #include 
    
    
    void c2bShortcutPushButton::setKeysequence(const QKeySequence& ks)
    {
        _keysequence = ks;
        const QString bt(_keysequence.toString(QKeySequence::NativeText));
        setText(bt.isEmpty() ? tr("None") : bt);
        setChecked(false);
    }
    
    void c2bShortcutPushButton::clear()
    {
        _set_keysequence(QKeySequence());
    }
    
    void c2bShortcutPushButton::reset()
    {
        _set_keysequence(_default_keysequence);
    }
    
    void c2bShortcutPushButton::keyPressEvent(QKeyEvent* qevent)
    {
        const int k(qevent->key());
        // This function is based on GPL configdialog.cpp
        // Copyright (C) 2003-2007 by Pascal Brachet, http://www.xm1math.net/texmaker/
        if ((qevent->modifiers() != 0 && k != Qt::Key_Enter && k != Qt::Key_Alt && k != Qt::Key_Shift &&
             k != Qt::Key_Control && k != Qt::Key_AltGr && k != Qt::Key_Meta && k != 0 && k != Qt::Key_Super_L &&
             k != Qt::Key_Super_R) ||
            (k >= Qt::Key_F1 && k <= Qt::Key_F35))
        {
            _set_keysequence(QKeySequence(qevent->modifiers() | k));
            return;
        }
        QPushButton::keyPressEvent(qevent);
    }
    cb2bib-2.0.1/src/PaxHeaders.5700/c2bShortcutWidget.cpp0000644000000000000000000000013214011522520017136 xustar0030 mtime=1613145424.454620345
    30 atime=1613145424.830620334
    30 ctime=1613145424.458620345
    cb2bib-2.0.1/src/c2bShortcutWidget.cpp0000644000175000001440000001074514011522520020544 0ustar00constansusers00000000000000/***************************************************************************
     *   Copyright (C) 2004-2021 by Pere Constans
     *   constans@molspaces.com
     *   cb2Bib version 2.0.1. Licensed under the GNU GPL version 3.
     *   See the LICENSE file that comes with this distribution.
     ***************************************************************************/
    #include "c2bShortcutWidget.h"
    
    #include "c2bSettings.h"
    
    
    c2bShortcutWidget::c2bShortcutWidget(QWidget* parentw) : QWidget(parentw)
    {
        ui.setupUi(this);
        _settingsP = c2bSettingsP;
        _standard_keysequences.append(QKeySequence::Close);
        _standard_keysequences.append(QKeySequence::Copy);
        _standard_keysequences.append(QKeySequence::Cut);
        _standard_keysequences.append(QKeySequence::Find);
        _standard_keysequences.append(QKeySequence::FindNext);
        _standard_keysequences.append(QKeySequence::FindPrevious);
        _standard_keysequences.append(QKeySequence::HelpContents);
        _standard_keysequences.append(QKeySequence::Open);
        _standard_keysequences.append(QKeySequence::Paste);
        _standard_keysequences.append(QKeySequence::Redo);
        _standard_keysequences.append(QKeySequence::Refresh);
        _standard_keysequences.append(QKeySequence::Save);
        _standard_keysequences.append(QKeySequence::SelectAll);
        _standard_keysequences.append(QKeySequence::Undo);
        _standard_keysequences.append(QKeySequence::ZoomIn);
        _standard_keysequences.append(QKeySequence::ZoomOut);
        _standard_keysequences.append(Qt::Key_F2);
        _standard_keysequences.append(QKeySequence::Quit);
        _standard_keysequences.append(QKeySequence::SaveAs);
    
        connect(ui.Clear, SIGNAL(clicked()), ui.Shortcut, SLOT(clear()));
        connect(ui.Reset, SIGNAL(clicked()), ui.Shortcut, SLOT(reset()));
    }
    
    
    void c2bShortcutWidget::setShortcutNames(const QString& path, const QStringList& fullnames)
    {
        disconnect(ui.Shortcut, SIGNAL(shortcutChanged(QKeySequence,QKeySequence)), this,
                   SLOT(shortcutChanged(QKeySequence,QKeySequence)));
        disconnect(ui.Description, SIGNAL(currentIndexChanged(QString)), this, SLOT(currentIndexChanged(QString)));
        _modified_keysequences.clear();
    
        _shortcut_path = path;
        _fullnames = fullnames.filter(path);
        const int n(_fullnames.count());
        const int p(path.length());
        for (int i = 0; i < n; ++i)
            if (_fullnames.at(i).startsWith(path))
                ui.Description->addItem(_fullnames.at(i).mid(p));
    
        ui.Shortcut->setKeysequence(_settingsP->keysequence(_shortcut_path + ui.Description->currentText()));
        ui.Shortcut->setDefaultKeysequence(_settingsP->defaultKeysequence(_shortcut_path + ui.Description->currentText()));
    
        connect(ui.Shortcut, SIGNAL(shortcutChanged(QKeySequence,QKeySequence)), this,
                SLOT(shortcutChanged(QKeySequence,QKeySequence)));
        connect(ui.Description, SIGNAL(currentIndexChanged(QString)), this, SLOT(currentIndexChanged(QString)));
    }
    
    void c2bShortcutWidget::currentIndexChanged(const QString& name)
    {
        const QString fullname(_shortcut_path + name);
        if (_modified_keysequences.contains(fullname))
            ui.Shortcut->setKeysequence(_modified_keysequences.value(fullname));
        else
            ui.Shortcut->setKeysequence(_settingsP->keysequence(fullname));
        ui.Shortcut->setDefaultKeysequence(_settingsP->defaultKeysequence(fullname));
    }
    
    void c2bShortcutWidget::shortcutChanged(const QKeySequence& oldks, const QKeySequence& newks)
    {
        const QString fullname(_shortcut_path + ui.Description->currentText());
        if (!newks.isEmpty())
        {
            if (_standard_keysequences.contains(newks))
            {
                ui.Shortcut->setKeysequence(oldks);
                ui.Shortcut->setChecked(true);
                emit statusMessage(
                    tr("Key sequence %1 is used by standard shortcuts").arg(newks.toString(QKeySequence::NativeText)));
                return;
            }
            if (_modified_keysequences.size() == 0)
            {
                const int n(_fullnames.count());
                for (int i = 0; i < n; ++i)
                    _modified_keysequences.insert(_fullnames.at(i), _settingsP->keysequence(_fullnames.at(i)));
            }
            if (_modified_keysequences.values().contains(newks) && _modified_keysequences.value(fullname) != newks)
            {
                ui.Shortcut->setKeysequence(oldks);
                ui.Shortcut->setChecked(true);
                emit statusMessage(tr("Key sequence %1 is already assigned").arg(newks.toString(QKeySequence::NativeText)));
                return;
            }
        }
        _modified_keysequences[fullname] = newks;
        emit statusMessage(QString());
    }
    cb2bib-2.0.1/src/PaxHeaders.5700/c2bLogWidget.ui0000644000000000000000000000007414011522151015704 xustar0030 atime=1613145424.830620334
    30 ctime=1613145424.302620349
    cb2bib-2.0.1/src/c2bLogWidget.ui0000644000175000001440000000400014011522151017270 0ustar00constansusers00000000000000
     Pere Constans
     c2bLogWidget
     
      
       
        0
        0
        827
        347
       
      
      
       Process Log - cb2Bib
      
      
       
        6
       
       
        6
       
       
        
         
          QFrame::StyledPanel
         
         
          QFrame::Raised
         
         
          true
         
        
       
       
        
         
          QFrame::HLine
         
         
          QFrame::Sunken
         
         
          Qt::Horizontal
         
        
       
       
        
         
          Qt::Horizontal
         
         
          QDialogButtonBox::Close|QDialogButtonBox::Help
         
        
       
      
     
     
     
      Log
     
     
     
      
       buttonBox
       rejected()
       c2bLogWidget
       reject()
       
        
         797
         330
        
        
         830
         305
        
       
      
     
    
    cb2bib-2.0.1/src/PaxHeaders.5700/c2bShortcutWidget.h0000644000000000000000000000013214011522520016603 xustar0030 mtime=1613145424.558620342
    30 atime=1613145424.830620334
    30 ctime=1613145424.562620342
    cb2bib-2.0.1/src/c2bShortcutWidget.h0000644000175000001440000000244014011522520020202 0ustar00constansusers00000000000000/***************************************************************************
     *   Copyright (C) 2004-2021 by Pere Constans
     *   constans@molspaces.com
     *   cb2Bib version 2.0.1. Licensed under the GNU GPL version 3.
     *   See the LICENSE file that comes with this distribution.
     ***************************************************************************/
    #ifndef C2BSHORTCUTWIDGET_H
    #define C2BSHORTCUTWIDGET_H
    
    #include "ui_c2bShortcutWidget.h"
    
    
    #include 
    #include 
    
    
    class c2bSettings;
    
    
    class c2bShortcutWidget : public QWidget
    {
    
        Q_OBJECT
    
    public:
        explicit c2bShortcutWidget(QWidget* parentw = 0);
        inline ~c2bShortcutWidget() {}
    
        void setShortcutNames(const QString& path, const QStringList& fullnames);
        inline const QHash& modifiedKeysequences() const
        {
            return _modified_keysequences;
        }
    
    
    signals:
        void statusMessage(const QString& ms);
    
    
    private slots:
        void currentIndexChanged(const QString& name);
        void shortcutChanged(const QKeySequence& oldks, const QKeySequence& newks);
    
    
    private:
        QHash _modified_keysequences;
        QList _standard_keysequences;
        QString _shortcut_path;
        QStringList _fullnames;
        Ui::c2bShortcutWidget ui;
        c2bSettings* _settingsP;
    };
    
    #endif
    cb2bib-2.0.1/src/PaxHeaders.5700/c2bShortcutWidget.ui0000644000000000000000000000007414011522151016776 xustar0030 atime=1613145424.830620334
    30 ctime=1613145424.302620349
    cb2bib-2.0.1/src/c2bShortcutWidget.ui0000644000175000001440000000431014011522151020366 0ustar00constansusers00000000000000
    
     c2bShortcutWidget
     
      
       
        0
        0
        551
        29
       
      
      
       Form
      
      
       
        -1
       
       
        0
       
       
        0
       
       
        
       
       
        
         
          
         
         
          true
         
         
          false
         
        
       
       
        
         
          Qt::NoFocus
         
         
          Clear key sequence
         
         
          
           :/icons/icons/clear_left.png:/icons/icons/clear_left.png
         
        
       
       
        
         
          Qt::NoFocus
         
         
          Reset key sequence to default value
         
         
          
           :/icons/icons/edit-undo.png:/icons/icons/edit-undo.png
         
        
       
      
     
     
      
       c2bShortcutPushButton
       QPushButton
       
    c2bShortcutPushButton.h
    cb2bib-2.0.1/src/PaxHeaders.5700/c2bTests.cpp0000644000000000000000000000013214011522520015261 xustar0030 mtime=1613145424.458620345 30 atime=1613145424.830620334 30 ctime=1613145424.458620345 cb2bib-2.0.1/src/c2bTests.cpp0000644000175000001440000015153514011522520016672 0ustar00constansusers00000000000000/*************************************************************************** * Copyright (C) 2004-2021 by Pere Constans * constans@molspaces.com * cb2Bib version 2.0.1. Licensed under the GNU GPL version 3. * See the LICENSE file that comes with this distribution. ***************************************************************************/ #define C2B_CHECK_CAPITALIZATION 0 #define C2B_CHECK_CODE_DECOMPOSITION 0 #define C2B_CHECK_JOURNALS 0 #define C2B_CHECK_PATTERNS 0 #define C2B_CHECK_PDF_AUTHORS 0 #define C2B_CHECK_PDF_CODES 0 #include "c2bTests.h" #include #include #include #include #include #include #include #include c2bTests::c2bTests() : cout(*(new QTextStream(stdout))), _failed_test_count(0), _test_count(0) { cout.setCodec("UTF-8"); cout << "============" << endl; cout << "cb2Bib tests" << endl; cout << "============" << endl; _bibliographic_dir = QFileInfo(settings::instance()->fileName("cb2Bib/BibTeXFile")).absolutePath(); } c2bTests::~c2bTests() { cout << endl; cout << "=================" << endl; cout << "cb2Bib tests done" << endl; cout << "=================" << endl << endl; delete &cout; } int c2bTests::allTests() { _test_count = 0; _failed_test_count = 0; #if C2B_CHECK_PATTERNS heuristic_check_patterns(); return 0; #endif #if C2B_CHECK_JOURNALS check_abbreviations_txt(); heuristic_journal(); #else author_parser(); heuristic_pvny(); heuristic_misc(); heuristic_author(); heuristic_check_patterns(); compression_check(); write_information(); #endif cout << endl << endl; cout << "Tests done. Tests: " << _test_count << " Failed: " << _failed_test_count << endl; return 0; } int c2bTests::writeInformation() { write_information(); return 0; } void c2bTests::compression_check() { QString test; test += QChar(100); test += QChar(200); test += QChar(8700); test += QChar(56200); test += QChar(57000); test += QChar(10); test += QChar(100); test += QChar(200); test += QChar(8700); test += QChar(56200); test += QChar(57000); test += QChar(10); QByteArray ba = test.toUtf8(); bool passed(c2bUtils::fromUtf8(ba) == QString::fromUtf8(ba)); cout << endl; if (passed) { cout << "-----------------------------------------------------------------" << endl; cout << "Check for c2b utf8: passed" << endl; cout << "-----------------------------------------------------------------" << endl; } else { cout << "-----------------------------------------------------------------" << endl; cout << "WARNING: Check for c2b utf8 FAILED! Please report it as a bug" << endl; cout << "-----------------------------------------------------------------" << endl; ++_failed_test_count; } ++_test_count; test += "-----------------------------------------------------------------"; test += "================================================================="; QByteArray cba(c2bUtils::compressString(test)); QString dcs(c2bUtils::decompressString(cba)); passed = (dcs == test) && (test.toUtf8().length() > cba.length()) && (dcs.utf16()[dcs.size()] == 0); if (passed) { cout << "-----------------------------------------------------------------" << endl; cout << "Check for compression: passed" << endl; cout << "-----------------------------------------------------------------" << endl; } else { cout << "-----------------------------------------------------------------" << endl; cout << "WARNING: Check for compression FAILED! Please report it as a bug" << endl; cout << "-----------------------------------------------------------------" << endl; ++_failed_test_count; } ++_test_count; } void c2bTests::write_information() { cout << endl; cout << "-------------------------" << endl; cout << "Miscellaneous information" << endl; cout << "-------------------------" << endl; cout << endl; cout << "Version: cb2bib " << C2B_VERSION << endl; #if defined(C2B_USE_LZSSE) cout << "Compression: lzsse" << endl; #elif defined(C2B_USE_LZ4) cout << "Compression: lz4" << endl; #elif defined(C2B_USE_LZO) cout << "Compression: lzo2" << endl; #else cout << "Compression: zlib" << endl; #endif #if QT_VERSION >= QT_VERSION_CHECK(5, 4, 0) cout << "Optimized PCRE: yes" << endl; #else cout << "Optimized PCRE: no" << endl; #endif #ifdef C2B_USE_TXTMATCHER_AVX2 cout << "Optimized txtmatcher: AVX2" << endl; #endif #ifdef C2B_USE_TXTMATCHER_SSE2 cout << "Optimized txtmatcher: SSE2" << endl; #endif #ifdef C2B_USE_TXTMATCHER_SCALAR cout << "Optimized txtmatcher: no" << endl; #endif #ifdef C2B_USE_QWEBKIT cout << "Compiled against QtWebKit: yes" << endl; #else cout << "Compiled against QtWebKit: no" << endl; #endif #ifdef C2B_USE_QWEBENGINE cout << "Compiled against QtWebEngine: yes" << endl; #else cout << "Compiled against QtWebEngine: no" << endl; #endif #ifdef C2B_USE_CBPOLL cout << "Clipboard polling: yes" << endl; #else cout << "Clipboard polling: no" << endl; #endif cout << "Application binary path: " << QCoreApplication::instance()->applicationDirPath() << endl; cout << "Application hardcoded data path: " << C2B_DATA_DIR << endl; #ifdef Q_OS_MACOS QString C2B_DATA_DIR_MAC(C2B_DATA_DIR); if (QDir(C2B_DATA_DIR + "/data/").exists()) C2B_DATA_DIR_MAC = QDir::cleanPath(C2B_DATA_DIR + '/'); else if (QDir(QCoreApplication::instance()->applicationDirPath() + "/../Resources/data/").exists()) C2B_DATA_DIR_MAC = QDir::cleanPath(QCoreApplication::instance()->applicationDirPath() + "/../Resources/"); cout << "Application macosx data path: " << C2B_DATA_DIR_MAC << endl; #endif cout << "\n-------------------------" << endl; cout << "OS:" << endl; cout << "Build CPU: " << QSysInfo::buildCpuArchitecture() << endl; cout << "CPU: " << QSysInfo::currentCpuArchitecture() << endl; cout << "Kernel Type: " << QSysInfo::kernelType() << endl; cout << "Kernel Version: " << QSysInfo::kernelVersion() << endl; cout << "Product Type: " << QSysInfo::productType() << endl; cout << "Product Version: " << QSysInfo::productVersion() << '|' << int(QSysInfo::productVersion().toDouble()) << endl; cout << "Name: " << QSysInfo::prettyProductName() << endl; cout << "-------------------------" << endl; cout << endl; } void c2bTests::heuristic_author() { cout << endl; cout << "---------------------------------" << endl; cout << "Test heuristic author recognition" << endl; cout << "---------------------------------" << endl; QFileInfoList flist = QDir(_bibliographic_dir).entryInfoList(QStringList() << "*.bib"); bibParser bp; bibReference reference; QStringList fields; fields.append("author"); fields.append("editor"); bp.initReferenceParsing(_bibliographic_dir, fields, &reference); #if C2B_CHECK_CAPITALIZATION for (int f = 0; f < flist.count(); ++f) { const QString bib_file(flist.at(f).absoluteFilePath()); bp.initReferenceParsing(_bibliographic_dir, fields, &reference); cout << "File: " << bib_file << endl; while (bp.referencesIn(c2bUtils::fileToString(bib_file), &reference)) { const QString author(reference.value("author")); if (author.isEmpty()) continue; bp.clearCurrentReference(); bp.guessFields(author); const QString guess(bp.currentReference().value("author")); const bool passed(guess == author); ++_test_count; if (!passed) ++_failed_test_count; cout << QString("[%1]\t'%2'\n").arg(boolToStr(passed)).arg(author); if (!passed) cout << QString("\t'%1'\n").arg(guess); } } return; #endif #if C2B_CHECK_CODE_DECOMPOSITION for (int u = 1; u < 78790; ++u) { const QChar c(u); if (!c.isLetter()) continue; if (c.decompositionTag() == QChar::NoDecomposition) continue; const QString dc(c.decomposition()); if (dc.length() != 2) continue; if (dc.at(0).isLetter() && dc.at(1).isLetter()) cout << '[' << c << ']' << " u: " << u << " decompose: " << decomposition(c) << " category: " << c.category() << endl; } return; #endif #if C2B_CHECK_PDF_CODES QMap charfreq; long long char_count = 0; for (int f = 0; f < flist.count(); ++f) { const QString bib_file(flist.at(f).absoluteFilePath()); fields.append("file"); bp.initReferenceParsing(_bibliographic_dir, fields, &reference); cout << "File: " << bib_file << endl; while (bp.referencesIn(c2bUtils::fileToString(bib_file), &reference)) { const QString file(reference.value("file")); document d(file, document::Raw); const QString doc(d.toString()); for (int i = 0; i < doc.length(); ++i) { if (doc.at(i).unicode() > 800 && doc.at(i).unicode() < 900) { cout << "At file: " << file << endl; cout << '[' << doc.at(i) << "] " << doc.mid(i - 10, 20) << endl; } charfreq.insert(doc.at(i), 1 + charfreq.value(doc.at(i), 0)); } char_count += doc.length(); } } QList cl = charfreq.keys(); for (int i = 0; i < cl.count(); ++i) cout << '[' << cl.at(i) << ']' << " u: " << cl.at(i).unicode() << " letter: " << cl.at(i).isLetter() << " decompose: " << decomposition(cl.at(i)) << " category: " << cl.at(i).category() << " f: " << charfreq.value(cl.at(i)) << endl; cout << "\nTotal characters: " << char_count << endl; return; #endif #if C2B_CHECK_PDF_AUTHORS cout << endl; cout << "----------------------------------------" << endl; cout << "Test heuristic author recognition on PDF" << endl; cout << "----------------------------------------" << endl; cout << endl; cout << "Checking files at: " << _bibliographic_dir << endl; const QStringList excluded(c2bUtils::fileToString(_bibliographic_dir + "/c2b_test_exclude.txt") .split(QRegExp("[\\n\\r]"), QString::SkipEmptyParts)); QHash doc_cache; const QString doc_cache_fn(_bibliographic_dir + "/c2b_test.cache"); if (QFileInfo::exists(doc_cache_fn)) { cout << "Reading from cache" << endl; QFile file(doc_cache_fn); file.open(QIODevice::ReadOnly); QDataStream ds(&file); ds >> doc_cache; } else { for (int f = 0; f < flist.count(); ++f) { const QString bib_file(flist.at(f).absoluteFilePath()); fields.append("file"); bp.initReferenceParsing(_bibliographic_dir, fields, &reference); cout << "File: " << bib_file << endl; while (bp.referencesIn(c2bUtils::fileToString(bib_file), &reference)) { const QString file(reference.value("file")); if (excluded.contains(file) || file.contains("/stacks/")) continue; document d(file, document::FirstPage); const QString doc(d.toString()); doc_cache.insert(reference.value("file"), doc); } } if (doc_cache.size() > 0) { QFile file(doc_cache_fn); file.open(QIODevice::WriteOnly); QDataStream ds(&file); ds << doc_cache; cout << "Writing cache " << doc_cache_fn << endl; cout << "Delete cache when done" << endl; } } cout << "Check authors" << endl; int n_pdf(0); int n_failed_pdf(0); for (int f = 0; f < flist.count(); ++f) { const QString bib_file(flist.at(f).absoluteFilePath()); fields.append("file"); bp.initReferenceParsing(_bibliographic_dir, fields, &reference); cout << "File: " << bib_file << endl; while (bp.referencesIn(c2bUtils::fileToString(bib_file), &reference)) { const QString file(reference.value("file")); if (file.isEmpty()) continue; if (excluded.contains(file) || file.contains("/stacks/")) continue; const QString doc(doc_cache.value(reference.value("file"))); QString check_doc(doc); check_doc.remove(c2bUtils::nonAsciiLetter); if (check_doc.isEmpty()) continue; const QString author(reference.value("author")); bp.clearCurrentReference(); bp.guessFields(doc); const QString guess(bp.currentReference().value("author")); bool passed(guess == author); if (!passed) { QString author_ascii(c2bUtils::toAscii(author, c2bUtils::Cleanup)); QString guess_ascii(c2bUtils::toAscii(guess, c2bUtils::Cleanup)); passed = guess_ascii == author_ascii; if (passed) cout << QString("[%1*] '%2'\n").arg(boolToStr(passed), author); else cout << QString("[%1] '%2'\n").arg(boolToStr(passed), author); if (!passed) { qDebug() << author; qDebug() << guess; qDebug() << reference.value("file"); qDebug() << "DOCUMENT: \n" << doc << endl << endl; // for (int i = 0; i < doc.count(); ++i) // cout << '[' << doc.at(i) << ']' << " u: " << doc.at(i).unicode() << " // letter: " << // doc.at(i).isLetter() << endl; } cout << QString(" '%1'\n").arg(guess); } else cout << QString("[%1] '%2'\n").arg(boolToStr(passed), author); ++n_pdf; if (!passed) ++n_failed_pdf; } } cout << "PDF Tests: " << n_pdf << endl; cout << "Succeded: " << n_pdf - n_failed_pdf << endl; _test_count += n_pdf; _failed_test_count += n_failed_pdf; #endif } void c2bTests::check_abbreviations_txt() { #if C2B_CHECK_JOURNALS cout << endl; cout << "--------------------------------" << endl; cout << "Check journal abbreviations file" << endl; cout << "--------------------------------" << endl; cout << endl; const QString dbfile(settings::instance()->fileName("cb2Bib/JournalFile")); cout << dbfile << endl; journalDB jdb(dbfile); QStringList abbr1, abbr2, full1, full2, code; { QFile file(dbfile); if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) return; QTextStream stream(&file); stream.setCodec("UTF-8"); stream.setAutoDetectUnicode(true); QString line; int line_number(0); while (!stream.atEnd()) { line = stream.readLine(); ++line_number; if (line.isEmpty() || line.startsWith('#')) continue; const QStringList spLine(line.split('|', QString::SkipEmptyParts)); if (spLine.count() != 3) { cout << "Syntax error in journal file at line " << line_number << endl; continue; } const QStringList spAbbreviated(spLine.at(1).split('=', QString::SkipEmptyParts)); const int na(spAbbreviated.count()); if (na < 1 || na > 2) { cout << "Syntax error in journal file at line " << line_number << endl; continue; } const QStringList spExtended(spLine.at(2).split('=', QString::SkipEmptyParts)); const int ne(spExtended.count()); if (ne < 1 || ne > 2) { cout << "Syntax error in journal file at line " << line_number << endl; continue; } code += spLine.at(0); abbr1 += spAbbreviated.at(0); full1 += spExtended.at(0); abbr2 += (na == 2) ? spAbbreviated.at(1) : spAbbreviated.at(0); full2 += (ne == 2) ? spExtended.at(1) : spExtended.at(0); } file.close(); const int njournals(code.count()); QStringList counter; for (int i = 0; i < njournals; ++i) counter += code.at(i).toLower().remove(c2bUtils::nonLetter); counter.removeDuplicates(); cout << "code total: " << njournals << " unique: " << counter.count() << endl; counter.clear(); for (int i = 0; i < njournals; ++i) counter += abbr1.at(i).toLower().remove(c2bUtils::nonLetter); counter.removeDuplicates(); cout << "abbr1 total: " << njournals << " unique: " << counter.count() << endl; counter.clear(); for (int i = 0; i < njournals; ++i) counter += full1.at(i).toLower().remove(c2bUtils::nonLetter); counter.removeDuplicates(); cout << "full1 total: " << njournals << " unique: " << counter.count() << endl; counter.clear(); for (int i = 0; i < njournals; ++i) counter += abbr2.at(i).toLower().remove(c2bUtils::nonLetter); counter.removeDuplicates(); cout << "abbr2 total: " << njournals << " unique: " << counter.count() << endl; counter.clear(); for (int i = 0; i < njournals; ++i) counter += full2.at(i).toLower().remove(c2bUtils::nonLetter); counter.removeDuplicates(); cout << "full2 total: " << njournals << " unique: " << counter.count() << endl; } const int njournals(code.count()); cout << endl; for (int i = 0; i < njournals; ++i) if (jdb.retrieve(code.at(i)) != abbr1.at(i)) cout << "failed code to abbr1 " << code.at(i) << " | " << abbr1.at(i) << " | " << jdb.retrieve(code.at(i)) << endl; for (int i = 0; i < njournals; ++i) if (jdb.retrieveAlternate(code.at(i)) != abbr2.at(i)) cout << "failed code to abbr2 " << code.at(i) << " | " << abbr2.at(i) << " | " << jdb.retrieveAlternate(code.at(i)) << endl; for (int i = 0; i < njournals; ++i) if (jdb.retrieveFull(code.at(i)) != full1.at(i)) cout << "failed code to full1 " << code.at(i) << " | " << full1.at(i) << " | " << jdb.retrieveFull(code.at(i)) << endl; for (int i = 0; i < njournals; ++i) if (jdb.retrieveAlternateFull(code.at(i)) != full2.at(i)) cout << "failed code to full2 " << code.at(i) << " | " << full2.at(i) << " | " << jdb.retrieveAlternateFull(code.at(i)) << endl; cout << endl; for (int i = 0; i < njournals; ++i) if (jdb.retrieve(abbr1.at(i)) != abbr1.at(i)) cout << "failed abbr1 to abbr1 " << abbr1.at(i) << " | " << abbr1.at(i) << " | " << jdb.retrieve(abbr1.at(i)) << endl; for (int i = 0; i < njournals; ++i) if (jdb.retrieveAlternate(abbr1.at(i)) != abbr2.at(i)) cout << "failed abbr1 to abbr2 " << abbr1.at(i) << " | " << abbr2.at(i) << " | " << jdb.retrieveAlternate(abbr1.at(i)) << endl; for (int i = 0; i < njournals; ++i) if (jdb.retrieveFull(abbr1.at(i)) != full1.at(i)) cout << "failed abbr1 to full1 " << abbr1.at(i) << " | " << full1.at(i) << " | " << jdb.retrieveFull(abbr1.at(i)) << endl; for (int i = 0; i < njournals; ++i) if (jdb.retrieveAlternateFull(abbr1.at(i)) != full2.at(i)) cout << "failed abbr1 to full2 " << abbr1.at(i) << " | " << full2.at(i) << " | " << jdb.retrieveAlternateFull(abbr1.at(i)) << endl; cout << endl; for (int i = 0; i < njournals; ++i) if (jdb.retrieve(abbr2.at(i)) != abbr1.at(i)) cout << "failed abbr2 to abbr1 " << abbr2.at(i) << " | " << abbr1.at(i) << " | " << jdb.retrieve(abbr2.at(i)) << endl; for (int i = 0; i < njournals; ++i) if (jdb.retrieveAlternate(abbr2.at(i)) != abbr2.at(i)) cout << "failed abbr2 to abbr2 " << abbr2.at(i) << " | " << abbr2.at(i) << " | " << jdb.retrieveAlternate(abbr2.at(i)) << endl; for (int i = 0; i < njournals; ++i) if (jdb.retrieveFull(abbr2.at(i)) != full1.at(i)) cout << "failed abbr2 to full1 " << abbr2.at(i) << " | " << full1.at(i) << " | " << jdb.retrieveFull(abbr2.at(i)) << endl; for (int i = 0; i < njournals; ++i) if (jdb.retrieveAlternateFull(abbr2.at(i)) != full2.at(i)) cout << "failed abbr2 to full2 " << abbr2.at(i) << " | " << full2.at(i) << " | " << jdb.retrieveAlternateFull(abbr2.at(i)) << endl; cout << endl; for (int i = 0; i < njournals; ++i) if (jdb.retrieve(full1.at(i)) != abbr1.at(i)) cout << "failed full1 to abbr1 " << full1.at(i) << " | " << abbr1.at(i) << " | " << jdb.retrieve(full1.at(i)) << endl; for (int i = 0; i < njournals; ++i) if (jdb.retrieveAlternate(full1.at(i)) != abbr2.at(i)) cout << "failed full1 to abbr2 " << full1.at(i) << " | " << abbr2.at(i) << " | " << jdb.retrieveAlternate(full1.at(i)) << endl; for (int i = 0; i < njournals; ++i) if (jdb.retrieveFull(full1.at(i)) != full1.at(i)) cout << "failed full1 to full1 " << full1.at(i) << " | " << full1.at(i) << " | " << jdb.retrieveFull(full1.at(i)) << endl; for (int i = 0; i < njournals; ++i) if (jdb.retrieveAlternateFull(full1.at(i)) != full2.at(i)) cout << "failed full1 to full2 " << full1.at(i) << " | " << full2.at(i) << " | " << jdb.retrieveAlternateFull(full1.at(i)) << endl; cout << endl; for (int i = 0; i < njournals; ++i) if (jdb.retrieve(full2.at(i)) != abbr1.at(i)) cout << "failed full2 to abbr1 " << full2.at(i) << " | " << abbr1.at(i) << " | " << jdb.retrieve(full2.at(i)) << endl; for (int i = 0; i < njournals; ++i) if (jdb.retrieveAlternate(full2.at(i)) != abbr2.at(i)) cout << "failed full2 to abbr2 " << full2.at(i) << " | " << abbr2.at(i) << " | " << jdb.retrieveAlternate(full2.at(i)) << endl; for (int i = 0; i < njournals; ++i) if (jdb.retrieveFull(full2.at(i)) != full1.at(i)) cout << "failed full2 to full1 " << full2.at(i) << " | " << full1.at(i) << " | " << jdb.retrieveFull(full2.at(i)) << endl; for (int i = 0; i < njournals; ++i) if (jdb.retrieveAlternateFull(full2.at(i)) != full2.at(i)) cout << "failed full2 to full2 " << full2.at(i) << " | " << full2.at(i) << " | " << jdb.retrieveAlternateFull(full2.at(i)) << endl; #endif } void c2bTests::heuristic_journal() { #if C2B_CHECK_JOURNALS cout << endl; cout << "-----------------------------------------" << endl; cout << "Test heuristic journal recognition on PDF" << endl; cout << "-----------------------------------------" << endl; cout << endl; cout << "Checking files at: " << _bibliographic_dir << endl; QFileInfoList flist = QDir(_bibliographic_dir).entryInfoList(QStringList() << "*.bib"); bibParser bp; bibReference reference; QStringList fields; fields.append("journal"); fields.append("file"); const QStringList excluded(c2bUtils::fileToString(_bibliographic_dir + "/c2b_test_exclude.txt") .split(QRegExp("[\\n\\r]"), QString::SkipEmptyParts)); QHash doc_cache; const QString doc_cache_fn(_bibliographic_dir + "/c2b_test.cache"); if (QFileInfo(doc_cache_fn).exists()) { cout << "Reading from cache" << endl; QFile file(doc_cache_fn); file.open(QIODevice::ReadOnly); QDataStream ds(&file); ds >> doc_cache; } else { cout << "No cache. Return" << doc_cache_fn << endl; return; } cout << "Check journals" << endl; int n_pdf(0); int n_failed_pdf(0); QList doclengths; for (int f = 0; f < flist.count(); ++f) { const QString bib_file(flist.at(f).absoluteFilePath()); bp.initReferenceParsing(_bibliographic_dir, fields, &reference); cout << "File: " << bib_file << endl; while (bp.referencesIn(c2bUtils::fileToString(bib_file), &reference)) { const QString file(reference.value("file")); if (file.isEmpty()) continue; if (excluded.contains(file) || file.contains("/stacks/")) continue; const QString doc(doc_cache.value(file)); QString check_doc(doc); check_doc.remove(c2bUtils::nonAsciiLetter); if (check_doc.isEmpty()) continue; doclengths.append(check_doc.length()); const QString ajournal(bp.abbreviatedJournal(reference.value("journal"))); const QString fjournal(bp.fullJournal(reference.value("journal"))); if (fjournal.isEmpty()) continue; if (ajournal == fjournal && (ajournal.count('.') > 0 || ajournal.count(' ') > 0)) { qDebug() << "not in db:" << fjournal; continue; } bp.clearCurrentReference(); bp.guessFields(doc); // const QString guess(bp.abbreviatedJournal(bp.currentReference().value("journal"))); const QString guess(bp.fullJournal(bp.currentReference().value("journal"))); if (guess.isEmpty()) continue; bool passed(guess == fjournal); if (!passed) { cout << QString("[%1] '%2'\n").arg(boolToStr(passed)).arg(fjournal); cout << QString(" '%1'\n").arg(guess); qDebug() << "jn:" << fjournal; qDebug() << "gn:" << guess; qDebug() << reference.value("file"); qDebug() << "DOCUMENT: \n" << doc << endl << endl; } else cout << QString("[%1] '%2'\n").arg(boolToStr(passed)).arg(fjournal); ++n_pdf; if (!passed) ++n_failed_pdf; } } cout << "PDF Tests: " << n_pdf << endl; cout << "Succeded: " << n_pdf - n_failed_pdf << endl; cout << "Ratio: " << double(n_pdf) / double(n_failed_pdf) << endl; _test_count += n_pdf; _failed_test_count += n_failed_pdf; std::sort(doclengths.begin(), doclengths.end()); cout << "doclengths min max median: " << doclengths.first() << ' ' << doclengths.last() << ' ' << doclengths.at(doclengths.count() / 2) << endl; #endif } void c2bTests::author_parser() { cout << endl; cout << "------------------" << endl; cout << "Test author parser" << endl; cout << "------------------" << endl; bibParser bp; QString author; QString input; author = "J.-L. Smith and R. Jones and K. McGibbons"; input = "SMITH, J.-L., R. JONES, AND K. MCGIBBONS"; check_test(author == bp.parse("author", input), input, author); input = "Smith, J.-L., Jones, R., and McGibbons, K."; check_test(author == bp.parse("author", input), input, author); input = "Smith, J.-L., Jones, R., McGibbons, K."; check_test(author == bp.parse("author", input), input, author); author = "J. L. Brooks Jr"; input = "Brooks Jr, John L"; check_test(author == bp.parse("author", input), input, author); author = "E. B. Melissa and W. F. Tohnson Jr and C. Z. Ortiz and S. J. van der Burgh"; input = "Melissa, Elizabeth Baines; Tohnson, Walter F., Jr.; Zapa Ortiz, Carlos; van der Burgh, S. J."; check_test(author == bp.parse("author", input), input, author); input = "Melissa, E.B., Tohnson Jr, Walter F., Zapa Ortiz, C., van der Burgh, S. J."; check_test(author == bp.parse("author", input), input, author); input = "Melissa, E.B., Tohnson Jr, Walter F., Zapa Ortiz, C., and van der Burgh, S. J."; check_test(author == bp.parse("author", input), input, author); author = "B. B. Aaaaaaa"; input = "Aaaaaaa, BB"; check_test(author == bp.parse("author", input), input, author); // author = "J. R. Aaaaaaa"; // input = "Aaaaaaa, JR"; // Gives wrong processing of the initials JR (set to Jr) // check_test(author == bp.parse("author", input), input, author); author = "J. Pi"; input = "Joan Pi"; check_test(author == bp.parse("author", input), input, author); input = "JOAN PI"; check_test(author == bp.parse("author", input), input, author); author = "P. I. Joan"; input = "Joan PI"; check_test(author == bp.parse("author", input), input, author); author = "C. V. Pi"; input = "Carles Vidal Pi"; check_test(author == bp.parse("author", input), input, author); input = "Carles VIDAL PI"; check_test(author == bp.parse("author", input), input, author); input = "Vidal Pi, Carles"; check_test(author == bp.parse("author", input), input, author); input = "Pi, Carles Vidal"; check_test(author == bp.parse("author", input), input, author); input = "PI, CARLES VIDAL"; check_test(author == bp.parse("author", input), input, author); author = "C. V. Pi and M. R. Catala"; input = "Carles Vidal Pi, Maria Rosa Catala"; check_test(author == bp.parse("author", input), input, author); input = "Vidal Pi, Carles and Catala, Maria Rosa"; check_test(author == bp.parse("author", input), input, author); input = "Vidal Pi, Carles and Catala, MR"; check_test(author == bp.parse("author", input), input, author); input = "VIDAL PI, Carles and CATALA, MR"; check_test(author == bp.parse("author", input), input, author); input = "Vidal Pi, Carles and Catala, M.R."; check_test(author == bp.parse("author", input), input, author); author = "C. V. Pi and M. R. Catala"; input = "Carles Vidal Pi, Maria Ros Catala"; check_test(author == bp.parse("author", input), input, author); input = "Carles VIDAL PI, Maria ROS CATALA"; check_test(author == bp.parse("author", input), input, author); input = "Vidal Pi, Carles and Ros Catala, Maria"; check_test(author == bp.parse("author", input), input, author); author = "M. R. R. Catala"; input = "Maria Rosa Ros Catala"; check_test(author == bp.parse("author", input), input, author); input = "Ros Catala, MR"; check_test(author == bp.parse("author", input), input, author); input = "Ros Catala, M R"; check_test(author == bp.parse("author", input), input, author); input = "Ros Catala, M. R."; check_test(author == bp.parse("author", input), input, author); author = "M. d'Errico"; input = "Monica d'Errico"; check_test(author == bp.parse("author", input), input, author); author = "J. V. Mael Jr"; input = "JAMES V. MAEL, Jr."; check_test(author == bp.parse("author", input), input, author); author = "J. V. Mael III"; input = "JAMES V. MAEL, III"; check_test(author == bp.parse("author", input), input, author); author = "V. Yu. Dmitri and A. Karpoff"; input = "VICTOR Yu. DMITRI,3 ANDRIY KARPOFF"; check_test(author == bp.parse("author", input), input, author); author = "Yu. Dmitri and A. Karpoff"; input = "Yu. Dmitri,3 Andriy Karpoff"; check_test(author == bp.parse("author", input), input, author); input = "Yu. DMITRI,3 ANDRIY KARPOFF"; check_test(author == bp.parse("author", input), input, author); input = "YU. DMITRI,3 ANDRIY KARPOFF"; check_test(author == bp.parse("author", input), input, author); cout << "From medline:" << endl; author = "C. L. Maggi III"; input = "Maggi, Carla L., III"; check_test(author == bp.parse("author", input), input, author); input = "Maggi III CL"; check_test(author == bp.parse("author", input), input, author); check_test(author == bp.parse("author", bp.authorFromMedline(input)), input, author); input = "Maggi, Carla L 3rd"; check_test(author == bp.parse("author", bp.authorFromMedline(input)), input, author); input = "Maggi CL 3rd"; check_test(author == bp.parse("author", bp.authorFromMedline(input)), input, author); author = "A. M. C. Lourtau"; input = "Carr Lourtau, A M"; check_test(author == bp.parse("author", input), input, author); check_test(author == bp.parse("author", bp.authorFromMedline(input)), input, author); input = "Carr Lourtau, AM"; check_test(author == bp.parse("author", input), input, author); // input = "Carr Lourtau AM"; // Gives 'L. A. Carr' (rare AU formatting) // check_test(author == bp.parse("author", author::fromMedline(input)), input, author); author = "B. de Rivas"; input = "de Rivas, Beatriz"; check_test(author == bp.parse("author", bp.authorFromMedline(input)), input, author); input = "de Rivas B"; check_test(author == bp.parse("author", bp.authorFromMedline(input)), input, author); author = "B. De Baets"; input = " De Baets, B "; check_test(author == bp.parse("author", bp.authorFromMedline(input)), input, author); } void c2bTests::heuristic_pvny() { cout << endl; cout << "---------------------------------------------------------" << endl; cout << "Test heuristic pages - volume - number - year recognition" << endl; cout << "---------------------------------------------------------" << endl; bibParser bp; bibReference reference; /**************************************************************** journal-pages-volume ****************************************************************/ reference.clearReference(); reference.insert("journal", bp.parse("journal", "Science")); reference.insert("pages", bp.parse("pages", "927")); reference.insert("volume", bp.parse("volume", "120")); write(bp, reference); heuristic(bp, reference, "Science. 120: 927"); heuristic(bp, reference, "Science. 120, 927"); heuristic(bp, reference, "Science 120, 927"); heuristic(bp, reference, "Science 120, pp. 927"); reference.clearReference(); reference.insert("journal", bp.parse("journal", "Science")); reference.insert("pages", bp.parse("pages", "927 - 993")); reference.insert("volume", bp.parse("volume", "120")); write(bp, reference); heuristic(bp, reference, "Science. 120: 927 - 993"); heuristic(bp, reference, "Science. 120, 927 - 93"); heuristic(bp, reference, "Science 120, 927 - 993"); heuristic(bp, reference, "Science 120, pp. 927 - 993"); /**************************************************************** journal-pages-volume-number ****************************************************************/ reference.clearReference(); reference.insert("journal", bp.parse("journal", "Science")); reference.insert("pages", bp.parse("pages", "927")); reference.insert("volume", bp.parse("volume", "120")); reference.insert("number", bp.parse("number", "1 - 3")); write(bp, reference); heuristic(bp, reference, "Science 120(1 - 3), 927"); heuristic(bp, reference, "Science 120(1 - 3), pp. 927"); reference.clearReference(); reference.insert("journal", bp.parse("journal", "Science")); reference.insert("pages", bp.parse("pages", "927 - 993")); reference.insert("volume", bp.parse("volume", "120")); reference.insert("number", bp.parse("number", "1 - 3")); write(bp, reference); heuristic(bp, reference, "Science 120(1 - 3), 927 - 993"); heuristic(bp, reference, "Science 120(1 - 3), pp. 927 - 993"); reference.clearReference(); reference.insert("journal", bp.parse("journal", "Science")); reference.insert("pages", bp.parse("pages", "927 - 993")); reference.insert("volume", bp.parse("volume", "120")); reference.insert("number", bp.parse("number", "1")); write(bp, reference); heuristic(bp, reference, "Science, Volume 120, Number 1, 927 - 993"); /**************************************************************** journal-pages-volume-year ****************************************************************/ reference.clearReference(); reference.insert("journal", bp.parse("journal", "Science")); reference.insert("pages", bp.parse("pages", "1922")); reference.insert("volume", bp.parse("volume", "120")); reference.insert("year", bp.parse("year", "2007")); write(bp, reference); heuristic(bp, reference, "Science 2007, 120, 1922"); heuristic(bp, reference, "Science 2007 120: 1922"); heuristic(bp, reference, "Science. 120: 1922, 2007"); heuristic(bp, reference, "(2007) Science 120: 1922"); heuristic(bp, reference, "Science 120, 1922 2007"); heuristic(bp, reference, "Science 120, 1922(2007)"); heuristic(bp, reference, "Science 120(2007) 1922"); heuristic(bp, reference, "Science 2007;120:1922."); heuristic(bp, reference, "Science 2007 May 2;120:1922"); reference.clearReference(); reference.insert("journal", bp.parse("journal", "Science")); reference.insert("pages", bp.parse("pages", "22")); reference.insert("volume", bp.parse("volume", "120")); reference.insert("year", bp.parse("year", "2007")); write(bp, reference); heuristic(bp, reference, "Science 2007, 120, 22"); heuristic(bp, reference, "Science 2007 120: 22"); heuristic(bp, reference, "Science 2007 May 2, 120: 22"); heuristic(bp, reference, "Science. 120: 22, 2007"); heuristic(bp, reference, "(2007) Science 120: 22"); heuristic(bp, reference, "Science 120, 22 2007"); heuristic(bp, reference, "Science 120, 22(2007)"); heuristic(bp, reference, "Science 120(2007) 22"); // Usual pages reference.clearReference(); reference.insert("journal", bp.parse("journal", "Science")); reference.insert("pages", bp.parse("pages", "3 - 7")); reference.insert("volume", bp.parse("volume", "120")); reference.insert("year", bp.parse("year", "2007")); write(bp, reference); heuristic(bp, reference, "Science. 120, 3 - 7(2007)"); heuristic(bp, reference, "Science. 120: 3 - 7, 2007"); heuristic(bp, reference, "Science, 120(2007), pp. 3 - 7"); heuristic(bp, reference, "Science 120(2007) 3 - 7"); heuristic(bp, reference, "2007 Science 120 3 - 7"); heuristic(bp, reference, "Science. 2007, 120, 3 - 7"); heuristic(bp, reference, "Science. 2007 120: 3 - 7"); heuristic(bp, reference, "Science. 2007 May 2, 120: 3 - 7"); heuristic(bp, reference, "Science. 2007, 120, 3 - 5pp"); heuristic(bp, reference, "Science 2007;120: 3 - 7"); // Pages susceptible to be confused by years reference.clearReference(); reference.insert("journal", bp.parse("journal", "Science")); reference.insert("pages", bp.parse("pages", "1997 - 2001")); reference.insert("volume", bp.parse("volume", "120")); reference.insert("year", bp.parse("year", "2007")); write(bp, reference); heuristic(bp, reference, "Science. 120, 1997 - 2001(2007)"); heuristic(bp, reference, "Science. 120, 1997 - 2001, 2007"); heuristic(bp, reference, "Science. 120: 1997 - 2001, 2007"); heuristic(bp, reference, "Science, 120(2007), pp. 1997 - 2001"); heuristic(bp, reference, "Science 120(2007) 1997 - 2001"); heuristic(bp, reference, "2007 Science 120 1997 - 2001"); heuristic(bp, reference, "Science. 2007, 120, 1997 - 2001"); heuristic(bp, reference, "Science. 2007 May 2, 120, 1997 - 2001"); heuristic(bp, reference, "Science. 2007 120: 1997 - 2001"); heuristic(bp, reference, "Science. 2007, 120, 1997 - 5pp"); heuristic(bp, reference, "Science 2007;120: 1997 - 2001"); // Pages starting by zero reference.clearReference(); reference.insert("journal", bp.parse("journal", "Science")); reference.insert("pages", bp.parse("pages", "044103 - 044110")); reference.insert("volume", bp.parse("volume", "120")); reference.insert("year", bp.parse("year", "2007")); write(bp, reference); heuristic(bp, reference, "Science. 120, 044103 - 044110(2007)"); heuristic(bp, reference, "Science. 120: 044103 - 044110, 2007"); heuristic(bp, reference, "Science, 120(2007), pp. 044103 - 044110"); heuristic(bp, reference, "Science 120(2007) 044103 - 044110"); heuristic(bp, reference, "2007 Science 120 044103 - 044110"); heuristic(bp, reference, "Science. 2007, 120, 044103 - 044110"); heuristic(bp, reference, "Science. 2007 May 2; 120, 044103 - 044110"); heuristic(bp, reference, "Science. 2007 120: 044103 - 044110"); heuristic(bp, reference, "Science 2007;120: 044103 - 044110"); /**************************************************************** journal-pages-volume-number-year ****************************************************************/ // Usual pages reference.clearReference(); reference.insert("journal", bp.parse("journal", "Science")); reference.insert("pages", bp.parse("pages", "117")); reference.insert("volume", bp.parse("volume", "120")); reference.insert("number", bp.parse("number", "1")); reference.insert("year", bp.parse("year", "2007")); write(bp, reference); heuristic(bp, reference, "Science 120(1), 117(2007)"); heuristic(bp, reference, "Science 120(1), 117(2007)"); heuristic(bp, reference, "Science 120(1): 117, 2007"); heuristic(bp, reference, "Science 2007, 120(1): 117"); heuristic(bp, reference, "Science 2007 120(1): 117"); heuristic(bp, reference, "Science 2007, 120(1), 117"); heuristic(bp, reference, "Science, 2007, 120 (1), p 117"); heuristic(bp, reference, "Science 2007 January 25; 120(1), 117"); heuristic(bp, reference, "Science 2007 January 25 120(1), 117"); heuristic(bp, reference, "Science 2007 May 25 120(1), 117"); heuristic(bp, reference, "Science (2007), 120, 1, 117"); heuristic(bp, reference, "Science, Vol. 120, No. 1 (2007) 117"); reference.clearReference(); reference.insert("journal", bp.parse("journal", "Science")); reference.insert("pages", bp.parse("pages", "10 - 17")); reference.insert("volume", bp.parse("volume", "120")); reference.insert("number", bp.parse("number", "1")); reference.insert("year", bp.parse("year", "2007")); write(bp, reference); heuristic(bp, reference, "Science 120(1), 10 - 17(2007)"); heuristic(bp, reference, "Science 120(1), 10 - 17(2007)"); heuristic(bp, reference, "Science 120(1): 10 - 17, 2007"); heuristic(bp, reference, "Science 2007, 120(1): 10 - 17"); heuristic(bp, reference, "Science. 2007, 120(1): 10 - 7"); heuristic(bp, reference, "Science. 2007 120(1): 10 - 7"); heuristic(bp, reference, "Science. 2007, 120(1): 10 8pp"); heuristic(bp, reference, "Science. 2007, 120(1), 10 - 17"); heuristic(bp, reference, "Science. 2007, 120(1), pp 10 - 17"); heuristic(bp, reference, "Science. 2007 January 25, 120(1), pp 10 - 17"); heuristic(bp, reference, "Science (2007), 120, 1, pp. 10-17"); reference.clearReference(); reference.insert("journal", bp.parse("journal", "Science")); reference.insert("pages", bp.parse("pages", "117")); reference.insert("volume", bp.parse("volume", "120")); reference.insert("number", bp.parse("number", "1 - 6")); reference.insert("year", bp.parse("year", "2007")); write(bp, reference); heuristic(bp, reference, "Science 120(1 - 6), 117(2007)"); heuristic(bp, reference, "Science 120(1 - 6), 117(2007)"); heuristic(bp, reference, "Science 120(1 - 6): 117, 2007"); heuristic(bp, reference, "Science 2007, 120(1 - 6): 117"); heuristic(bp, reference, "Science 2007 120(1 - 6): 117"); heuristic(bp, reference, "Science 2007 May 25 120(1 - 6): 117"); reference.clearReference(); reference.insert("journal", bp.parse("journal", "Science")); reference.insert("pages", bp.parse("pages", "10 - 17")); reference.insert("volume", bp.parse("volume", "120")); reference.insert("number", bp.parse("number", "1 - 6")); reference.insert("year", bp.parse("year", "2007")); write(bp, reference); heuristic(bp, reference, "Science 120(1 - 6), 10 - 17(2007)"); heuristic(bp, reference, "Science 120(1 - 6), 10 - 17(2007)"); heuristic(bp, reference, "Science 120(1 - 6): 10 - 17, 2007"); heuristic(bp, reference, "Science 2007, 120(1 - 6): 10 - 17"); heuristic(bp, reference, "Science. 2007, 120(1 - 6): 10 - 7"); heuristic(bp, reference, "Science. 2007, 120(1 - 6): 10 8pp"); heuristic(bp, reference, "Science 2007 120(1 - 6): 10 8pp"); heuristic(bp, reference, "Science 2007 May 25 120(1 - 6): 10 8pp"); // Pages susceptible to be confused by years reference.clearReference(); reference.insert("journal", bp.parse("journal", "Science")); reference.insert("pages", bp.parse("pages", "1922")); reference.insert("volume", bp.parse("volume", "120")); reference.insert("number", bp.parse("number", "1")); reference.insert("year", bp.parse("year", "2007")); write(bp, reference); heuristic(bp, reference, "Science 120(1), 1922(2007)"); heuristic(bp, reference, "Science 120(1), 1922(2007)"); heuristic(bp, reference, "Science 120(1): 1922, 2007"); heuristic(bp, reference, "Science 2007, 120(1): 1922"); heuristic(bp, reference, "Science 2007, 120(1), 1922"); heuristic(bp, reference, "Science 2007 120(1): 1922"); heuristic(bp, reference, "Science 2007 May 25 120(1): 1922"); heuristic(bp, reference, "Science, Vol. 120, No. 1 (2007) 1922"); reference.clearReference(); reference.insert("journal", bp.parse("journal", "Science")); reference.insert("pages", bp.parse("pages", "1922 - 1927")); reference.insert("volume", bp.parse("volume", "120")); reference.insert("number", bp.parse("number", "1")); reference.insert("year", bp.parse("year", "2007")); write(bp, reference); heuristic(bp, reference, "Science 120(1), 1922 - 1927(2007)"); heuristic(bp, reference, "Science 120(1), 1922 - 1927(2007)"); heuristic(bp, reference, "Science 120(1): 1922 - 1927, 2007"); heuristic(bp, reference, "Science 2007, 120(1): 1922 - 1927"); heuristic(bp, reference, "Science. 2007, 120(1): 1922 - 1927"); heuristic(bp, reference, "Science. 2007, 120(1): 1922 6pp"); heuristic(bp, reference, "Science. 2007 120(1): 1922 6pp"); heuristic(bp, reference, "Science. 2007, 120(1), 1922 - 1927"); heuristic(bp, reference, "Science. 2007, 120(1), pp 1922 - 1927"); heuristic(bp, reference, "Science. 2007 May 25, 120(1), pp 1922 - 1927"); heuristic(bp, reference, "Science (2007), 120, 1, pp. 1922-1927"); heuristic(bp, reference, "Science, Vol. 120, No. 1 (2007) 1922 - 1927"); reference.clearReference(); reference.insert("journal", bp.parse("journal", "Science")); reference.insert("pages", bp.parse("pages", "1922")); reference.insert("volume", bp.parse("volume", "120")); reference.insert("number", bp.parse("number", "1 - 6")); reference.insert("year", bp.parse("year", "2007")); write(bp, reference); heuristic(bp, reference, "Science 120(1 - 6), 1922(2007)"); heuristic(bp, reference, "Science 120(1 - 6), 1922(2007)"); heuristic(bp, reference, "Science 120(1 - 6): 1922, 2007"); heuristic(bp, reference, "Science 2007, 120(1 - 6): 1922"); heuristic(bp, reference, "Science 2007 120(1 - 6): 1922"); heuristic(bp, reference, "Science 2007 May 25 120(1 - 6): 1922"); reference.clearReference(); reference.insert("journal", bp.parse("journal", "Science")); reference.insert("pages", bp.parse("pages", "1922 - 1927")); reference.insert("volume", bp.parse("volume", "120")); reference.insert("number", bp.parse("number", "1 - 6")); reference.insert("year", bp.parse("year", "2007")); write(bp, reference); heuristic(bp, reference, "Science 120(1 - 6), 1922 - 1927(2007)"); heuristic(bp, reference, "Science 120(1 - 6), 1922 - 1927(2007)"); heuristic(bp, reference, "Science 120(1 - 6): 1922 - 1927, 2007"); heuristic(bp, reference, "Science 2007, 120(1 - 6): 1922 - 1927"); heuristic(bp, reference, "Science 2007 120(1 - 6): 1922 - 1927"); heuristic(bp, reference, "Science. 2007, 120(1 - 6): 1922 - 7"); heuristic(bp, reference, "Science. 2007, 120(1 - 6): 1922 6pp"); heuristic(bp, reference, "Science. 2007 May 25, 120(1 - 6): 1922 6pp"); } void c2bTests::heuristic_misc() { cout << endl; cout << "-----------------------------" << endl; cout << "Test miscellaneous heuristics" << endl; cout << "-----------------------------" << endl; bibParser bp; bibReference reference; // abstract reference.clearReference(); reference.insert("abstract", bp.parse("abstract", "Some text.")); write(bp, reference); heuristic(bp, reference, "...\n\nAbstract. Some text.\n"); heuristic(bp, reference, "...\n\nAbstract.\n Some text.\n"); heuristic(bp, reference, "...\n\nAbstract:\n Some text.\n"); heuristic(bp, reference, "...\n\nAbstract\n Some text.\n"); heuristic(bp, reference, "...\n\nSummary. Some text.\n"); heuristic(bp, reference, "...\n\nSummary:\n Some text.\n"); heuristic(bp, reference, "...\n\nSummary\n Some text.\n"); // keywords reference.clearReference(); reference.insert("keywords", bp.parse("keywords", "Some text.")); write(bp, reference); heuristic(bp, reference, "...\n\nKeywords:\n Some text.\n"); heuristic(bp, reference, "...\n\nKeywords. Some text.\n"); // title reference.clearReference(); reference.insert("title", bp.parse("title", "Some text.")); write(bp, reference); heuristic(bp, reference, "...\n\nTitle: Some text.\n"); heuristic(bp, reference, "...\n\nTitle:\n Some text.\n"); } void c2bTests::heuristic(bibParser& bp, const bibReference& reference, const QString& text) { bp.clearCurrentReference(); bp.guessFields(text); const bool passed(bp.toBibTeX() == bp.toBibTeX(reference)); ++_test_count; if (!passed) ++_failed_test_count; cout << QString("[%1]\t'%2'\n").arg(boolToStr(passed), text); if (!passed) qDebug() << "Guessed:\n" << bp.toBibTeX(); } void c2bTests::check_test(const bool passed, const QString& input, const QString& output) { ++_test_count; if (!passed) ++_failed_test_count; cout << QString("[%1]\t'%2'\n").arg(boolToStr(passed), input); if (!passed) qDebug() << output; } void c2bTests::write(const bibParser& bp, const bibReference& reference) { cout << endl; const QStringList& bibliographicFields = bp.bibliographicFields(); for (int i = 0; i < bibliographicFields.count(); ++i) { const QString fvalue(reference.value(bibliographicFields.at(i))); if (!fvalue.isEmpty()) { const QString& fd = bibliographicFields.at(i); const QString padding(QString().fill(' ', 12 - fd.length())); cout << (fd + padding + " = {" + fvalue + '}') << endl; } } } #if C2B_CHECK_PATTERNS #include "frequentPatterns.h" #endif void c2bTests::heuristic_check_patterns() { #if C2B_CHECK_PATTERNS frequentPatterns fp; fp.process(); return; #endif cout << endl; cout << "-----------------------------------------------------" << endl; cout << "Check pattern clashes in heuristic author recognition" << endl; cout << "-----------------------------------------------------" << endl; cout << endl; QFileInfoList flist = QDir(_bibliographic_dir).entryInfoList(QStringList() << "*.bib"); bibParser bp; bibReference reference; QStringList fields; fields.append("author"); QHash adictionary; for (int f = 0; f < flist.count(); ++f) { const QString bib_file(flist.at(f).absoluteFilePath()); bp.initReferenceParsing(_bibliographic_dir, fields, &reference); while (bp.referencesIn(c2bUtils::fileToString(bib_file), &reference)) { const QString a(c2bUtils::toAscii(reference.value("author"), c2bUtils::Collation)); const QStringList as(a.split(c2bUtils::nonLetter)); for (int i = 0; i < as.count(); ++i) adictionary.insert(as.at(i), 1 + adictionary.value(as.at(i), 0)); } } QStringList word_prefix_lexicon( c2bUtils::fileToString(":/txt/txt/word_prefix_lexicon.txt").split(c2bUtils::nonLetter, QString::SkipEmptyParts)); for (int i = 0; i < word_prefix_lexicon.count(); ++i) word_prefix_lexicon[i].replace('_', "\\b"); QStringList anames(adictionary.keys()); QRegExp wre; for (int i = 0; i < word_prefix_lexicon.count(); ++i) for (int j = 0; j < anames.count(); ++j) { const QString& wp = word_prefix_lexicon.at(i); const QString& a = anames.at(j); wre.setPattern(wp); if (a.contains(wre)) cout << "LEXICON CLASH: " << wp << ' ' << a << endl; } } QString c2bTests::decomposition(const QChar& c) { // Write char decomposition const QString d(c.decomposition()); QString wd; for (int i = 0; i < d.length(); ++i) wd += '[' + d.at(i) + ']'; return wd; } cb2bib-2.0.1/src/PaxHeaders.5700/c2bREHighlighter.h0000644000000000000000000000013214011522520016311 xustar0030 mtime=1613145424.546620342 30 atime=1613145424.830620334 30 ctime=1613145424.546620342 cb2bib-2.0.1/src/c2bREHighlighter.h0000644000175000001440000000157614011522520017721 0ustar00constansusers00000000000000/*************************************************************************** * Copyright (C) 2004-2021 by Pere Constans * constans@molspaces.com * cb2Bib version 2.0.1. Licensed under the GNU GPL version 3. * See the LICENSE file that comes with this distribution. ***************************************************************************/ #ifndef C2BREHIGHLIGHTER_H #define C2BREHIGHLIGHTER_H #include /** RegExp SyntaxHighLighter @author Pere Constans */ class c2bColors; class c2bREHighlighter : public QSyntaxHighlighter { public: explicit c2bREHighlighter(QTextDocument* doc); ~c2bREHighlighter(); protected: virtual void highlightBlock(const QString& text); private: QColor text_color; QRegExp rx0; QRegExp rx1; QRegExp rx2; QRegExp rx3; QRegExp rx4; QRegExp rx5; c2bColors* c; }; #endif cb2bib-2.0.1/src/PaxHeaders.5700/icons0000644000000000000000000000007414011522151014127 xustar0030 atime=1613145424.838620334 30 ctime=1613145424.306620349 cb2bib-2.0.1/src/icons/0000755000175000001440000000000014011522151015576 5ustar00constansusers00000000000000cb2bib-2.0.1/src/icons/PaxHeaders.5700/annote.png0000644000000000000000000000007414011522151016176 xustar0030 atime=1613145424.838620334 30 ctime=1613145424.306620349 cb2bib-2.0.1/src/icons/annote.png0000644000175000001440000000675014011522151017600 0ustar00constansusers00000000000000PNG  IHDR00WsRGBbKGD pHYs11(RtIME ) hIDATh޵K]y}^fh@/(K Ĥ TJ*H&8Y{E{ERJ٤ 6a?,E0` R =<:>ݝŌ.34T{;Wp ٳg/J)[9vO۷ns$o !ra|3?|-8qO ! n?8FkMEg5EQ_{&o_Oq<B۷k^6?R:[?~baal[o}t瞇077׸87,/'| 5 ƷsS5QatJN|)*T8cY %8 !ѯ% kQ6 .$DSi  ; `E8K6ж7 8صgKATQ)ﻛlH`zNT 41TRX8q%9AS;FT򣟿ι:G"m RA&vHe<4L+#Mwd0ʣ5Waǎ ` 88$}4,SBgDR;d x嵏m$Zgs=J ʕ6LL9Y'5$}s{R+V#=M_[dGb,6#)_w3v6[aTO# J23['mqkjs> y%~p|i42Co'R)gd2ٌiK: NI0h NXY^IXZ]VV@=TI6`ed]r3R'\ (CzR +D) y+N!<#mɇ9RI|n*[I@)!(iNR@ H{-8 biKgT @>3achVM9oڌ%Ԋz@/t R:R\xVs`wHsqf%@+8VvkCBkPk#.[ec1Q!ZFŽ \\N(^@ՐjY:!r%bJ'8)2Ep8k$gwbzC*Ѫz4 !1fZeyj8.Ư)pq-7j~·xAj'/@Ŋ_2?S#b~F2ř_H"%8|4r0<ɲv{K틌FCњE/ک= ߰:KI6ĆaN똨 |iJ+XIOE =R%CEs:J0,q9V/ I dRbds5`L(%Ip8d7wGWy쩧Z=]ujP{TʾQ ;s;+ZF\oirT}6<bgJ5~6QQDj$u}X),YQ╗\ꀀ-})SX X 9/&&!A|vvW*hڄ,, ?uu򫫹@Bw? .0003306 K20~ Q1 A a܁Ă6 w20ܼt!É 7n00 hAakPhClT-@ A|b >,(I?P,z? u$::VPrr@^Q`߿ Q]f!aA   d(9.ᏸ   `Qd ,wJ3ß't})B ZF@L $! W#|bH0C-Dr ӋgJP?@?`{ &).\ rq3f`D%0rĄj%@{X*b`Wf$p#/3 9tѾD1>.?VLB,=bPG@ 9ZzY ? d9bl &B A6?#Т}S]&2HȾrt1AR2 u/ 98v1|{ @LD% \ | R+޾``ᯚ_K`p * T2$Xvm`!"™T0?B W1pD1Te`333io  ϱrOV {2pKj 2jx޿fZ $7u}(E'a X XZ 98ȴs 8{ mإ _:F L1|o?$0..g=q,;>[3|+b`6Xv?C+.ArÁ# *(2) @8X0?< _?321_`nE/X  91) Xs"W@+` ̙3g̘@Le& X~`xR0Y>زg[GӧO*R@!o\Z؁q*R1@?;2@3Լ6m-PL@]x0ز$ፅ;CR18-LT)J2˗ȖF BT:?#>X12@$ Kpȡ8OPwvv,A9 fgf` 4V !l/|>a„ ll$,۷o&OpZJPTTT4Bo߾1>}dz׶v??2=z䤸7og9z&IENDB`cb2bib-2.0.1/src/icons/PaxHeaders.5700/configure_files.png0000644000000000000000000000007414011522151020055 xustar0030 atime=1613145424.838620334 30 ctime=1613145424.306620349 cb2bib-2.0.1/src/icons/configure_files.png0000644000175000001440000000202414011522151021445 0ustar00constansusers00000000000000PNG  IHDR00WsBIT|d pHYs11(RtEXtSoftwarewww.inkscape.org<IDAThYkG7RtѩPr2O ]eb|5%/uNL.bpIVֲzDZ3ff͘ iI@x6G////DQdm8e=:3Ƽ> "[qf7:Ԓ uĦ)91_nCuƦR 墭G^U^!Bwq 0ԺoGhd$s3(Mmk1(QMU]W(~v ӈ4M_Qv4NʈUa(FGUzwwwzp8W՛ ?58p8U Oŏs[axU1[q6IJ.|(9 " ðXkP1u&0tG__а ߙ瓓_}%JA0#_WUqp΍(nxpf'hn ֎3}/$0ƌ}Jᜳm'r+"i̺7 ëZ@QWU&AðZ`0Xn#v  Y[HLi dhrq6Ƙ x]T `@H$A rdWD|&Z;"{B$#9CdϚĕަmzF^I^__Ϝs/*,Twۜs=3yI$L$t唨jS\5kw9 A,&I9/^ n&}X",oUeH,Vr- 2u\lwVwY[]eSm (`߱;7I@x[O RIENDB`cb2bib-2.0.1/src/icons/PaxHeaders.5700/configure_shortcuts.png0000644000000000000000000000007414011522151021011 xustar0030 atime=1613145424.838620334 30 ctime=1613145424.306620349 cb2bib-2.0.1/src/icons/configure_shortcuts.png0000644000175000001440000000260614011522151022407 0ustar00constansusers00000000000000PNG  IHDR00 1 sBITUF pHYs11(RtEXtSoftwarewww.inkscape.org<IDATxWKoEz^cƏXرy)!H!@nKC$wH$B  !86_`֏]kvOիfr@ pq<3_u}]w!MJAᾋ `!{hg vpbg/)J]1i$X*ָ$ }cH؍%dM FvoVR#LGj'5c NnL!'%Z:ixq0y$4UA2!'c@ Vō㣅l__z v2V1уV0lW/lt"[D^tz~UhՎCC;SJ *""V ;jq,fFJ(el!G͓.KX*,5xTY̡)1,Nڙ۰sw75NvTOo[B"yacv>J k*`pLr &^ lqf>R݋eNE/is!9yhxD' ?S 'S??י'勚-G0EEm9: ~l{iX][ҏ3|Vre pu[u@k40t!틀vq(2X-EkV3r-H(qEȹҾ~;GZG-2XB1UܣB*Jh(z*A$YObEg6P`tH~SX%m! 7c^XxgMu` }c  1QIENDB`cb2bib-2.0.1/src/icons/PaxHeaders.5700/viewReload.png0000644000000000000000000000007414011522151017013 xustar0030 atime=1613145424.838620334 30 ctime=1613145424.306620349 cb2bib-2.0.1/src/icons/viewReload.png0000644000175000001440000000075114011522151020410 0ustar00constansusers00000000000000PNG  IHDR&N:sRGBbKGD pHYs  tIME "-FXMiIDAT(}ӽkUA}|rZ ̻(2TZ~X?TQ| cJs g:-%F)}>:qg2] ߑ}:`[:'Tkl2tC)hXk Pڕ|gr|sY&O Z"P_, uJinsO˩=5<FZ7ȶzcu#FL7 5\lАR4(n 6W560v$t# 0 oŠ^pJ=(dDF`E2g" wWT| 5ï?;S0 V$`!'nMBtf͆QG(\eY^lw1Z ou"fتghꭼ<}D0#WM;JW/pj]{8tg{8xK/qTyIENDB`cb2bib-2.0.1/src/icons/PaxHeaders.5700/viewHome.png0000644000000000000000000000007414011522151016475 xustar0030 atime=1613145424.838620334 30 ctime=1613145424.306620349 cb2bib-2.0.1/src/icons/viewHome.png0000644000175000001440000000063214011522151020070 0ustar00constansusers00000000000000PNG  IHDRabKGD@ pHYs  tIME  P2tEXtCommentCreated with The GIMPd%nIDAT8͑m0OAST@8}\9PE1x)Dlj xH/+8љGsH$ 䔂$,A(rR"LzC@9L.T׆i}rN!K)eH.vYlZro]XHmRX&"QARS 6kem=o\nD"ijr ˠڦ9מ<}p}5s-K` AKI[z6.IENDB`cb2bib-2.0.1/src/icons/PaxHeaders.5700/package_network.png0000644000000000000000000000007414011522151020056 xustar0030 atime=1613145424.838620334 30 ctime=1613145424.306620349 cb2bib-2.0.1/src/icons/package_network.png0000644000175000001440000000511514011522151021452 0ustar00constansusers00000000000000PNG  IHDR szzgAMA7 IDATxklucg7i-"UÖUñEl#mmAO i"mC/ ȇARJrWmzТdo.].1;3sY2q6np0`9gFAmcg=ՙ9ґL伌'%a^_U6f͗)ȱ>3~nfjWyh>8]ضֆr-rKyҵ~xL@NΓO%S(ՍcJii iEIٵV͏.}:p" >;{C|ά|1 6jh6(fub6)WCS[LJ545eHfWu~=/u۝>qC FD+Ak1iI$AJiDhD0?{7ǶMGN1$\]US-:sRhmڮQ:$w#3]o,$`ė~ч?_;цfbPdi%ORR h4aD=h hgo!4JiaH74;? @<~c_gh0z% -aDibe%a,19> כ8eY()mPZ#-$ĉ&J=Y7Ëֈ o$=tg?KKA@@KgTV"hFzg~W6XX#$E~Hhz{Q*)/6d&ϯA __Da> 9"łV4#g"0tucl)%@o/}`H 2MQf`aU«ǟ>05 U abiVhE103ˇO BiY!p~Hrpс6׸4WPTIoR\N6R ±-l[ Eb6 +@UÞ{mMwvvr1ό>묮ut"xl[O=@_Of+xUsQo$?zJdh9>=fd[;2Ӕ*ey%tt bLϽpr%`zz}C j&2J)lV#"DZ6񉢘oS 4-0mik~̵5&$(NwGƵYo.:z7涸pmrF/ͪ_Cf l&Q+}BN08ıBiApcWy ߯!'оarTXZ4(*J'..^'нnNnBlrcf3&6.sy.m;-L9M+5 ;/MutO7tM ;qm|o.!$5^H:H!˒R.4f%@~ jgϞca'A cRؖk[Ms-~-Fw__}z{a"`SA"I oԢ¢/&~ᡛ\NK&Tql\2MƵy|Yνz#- r^61z V7\z?`wj۬*I_ɱVj:8Qv4l& ,2(m\!1FPHip*mݴ6 $?nnTQNNϜy凼};lꝀ_Λ>;J%.(Y\dqe`nRY\it\b1H,(٦(nJQaȝ©g*ߩDD|;?urKw1J q'JO酭)ʲ vCDk8`VҊ 2t{ ϞvaN}t  yrG˟U6zD1L =6P<b QSǠ+|//۠t%"/s %&4ѣ^DQ1~4+n]^ûLoI{}f -Y(-S.јY8y&׮;j=nL|z5~--q=G9ڊV&rq S[w["ӛ?@ϜiVU,ya$ܼ6Gi=Dq@wSk!ˇvi86VRp(*ab"˱:Hsmg*.XZLS_ pXD""g_;N<07Isi8fZ:ַlSy> *م:jDSSU1"C=AЁbç/\c6Wc㳌68`Pf= lu2I "$Sx75S[;pn}P S\V+ 4$gtzyqMv!//8qߚZW~K""Ӌ͋0)c;Pv@cM8Cs"^ 0Nݲ2 ar4zz'^إ0٪wqJa1dJB4*$ͶPWpAHel:ÒFdw4$ED(j5ô?*p>x1"Jqz:*՘Fu^J+NP1F3GM7F+S?Bٽs3,+QfT+!hS:^aZG᠟'xA)Og@•6 0 J7m- ŗ[ N,EZCSĵ*E62'4!"WB!"27o1Z+x.z a0Ck3DAƋPox>." |&%<y>FTE8{dyD QE;16hBpDqcQxz Scg=YVPc T8vV%+B 2>;/sF97-5dkCC#)'.Ap  (VT ISX_1QH@<9@)! 4~Fԛ1A`p}FĿ矸;D9O'2[lJQ2a8$#xuqTJKOe"$F<6̸ygCpv3x<{ wgxFnd3Fi߽ϑk-t@^^:(kWw+1˛]Dx<o` h PƄ`3^@aEa+҆&/mqxڻ= gkyVyko"/~8̙IK^>W!j\M(_{֦{WnF~B/s\ sXqޣ h )_;(u];,9-7tjC;CՐV=9CMZ/yM(=]|>hn_i2߈seMӋ,OְjuǹJ p$[ Q]|,|Bfz<??E*xliwFID5`;bXnY| V7cD%c#2KH'g廖 &0Wq k$#% (˒:m _v;xrg~~/)6luRf JXjUw. Z@k%(%(59Q`86Sca 4(5k uZUË]+1 הN$Ou5?d3ƍG(<9 g<~O:K4(E-zycxrO/3|ZP3mJ/^c݁HCxdsxʥ \Y~y7pg84j% p" SWyƐnZ ":0B-JXlhh*S:l&Nƻ-[Zli1JYd' ߻vv6#~{}L6F݄8ĵ59\Y8";u< ֏':Nr1Zsz^byjwlݸGBxD*ҞOѯq/e&3UFy戫H .&4yB#LW U\-`Xiu6vK;((K=J >p!Yw?v|7"}S{ [> XBChﹰ5`wK B#ThE=Pk, y.o(c-ʕhA БI{j7-{wo۴?(Z82,w; 1Q(bU1WU&nfi„XtQՊ4(D:Ը~dN?v|3o;^c<*3r<&D!hMVzW6KUC#*X=[#u,WCB & QJ@')tG o\iv_LVr:*JΜZ4芢c\ijTչ,ԈP3°,g{Ql,Ѐ+LS Q6#!"κ?XZbmyYа;JkZ2b'%qm~%>)zan/\Co>v3o6}-g&_pi&jnZjrJD`:8r~RrqǷEIҾ'ۿX9Ϝk/=GUl QwW%0}i* f̱IN,7Gh-'FaN(ʒ;a0Mkߘl=O§-e3+'=%yr?JAdC@c"[v iAMϊ-eh+cL܍H/ɥ; 3WU.ִD&AS⒵^t OnbC|yer%Й`_ĕ+:$=TvQfGv%_ DХ3V<2=DqeλRWs2JL&&!AJwqt=lص]T>N ejzgzN/9Um%"RJ6"*{\)e*BBpE$9'8  & zCX6h,ATg%I趌*ͳ}*:R)erp8deT Z'T $:iE0 {?Lzji/,^tH*Q^V9w,V@<'NѷT*RJbi=oss{70H@ZF^M ’ #GF(wb94& (]7  LLLHAeGկ}C"H""0h?Dh,"loosQ~hhǙfIJh Bs,.-WEhuXM NM1Lbii]gaa'F>X(bX^^f<~@{'H.@,nݾb<-@SFw>h44 $$YhiydzYΕ{޽{G3"ͷJ}LﵑX_ve~OceyQrÚm{C@'n@%mQ=n4LLL^+.⋊`&Ϟ=ò,* m˃vCGS )a8yaj}v|x|ЉYH2g $u}1{G}ǩ-_xyH0 Ξ=˙3gzdwL,EX___ҥK78EJ}VD ͛~XVKZ-666W^nf(CZ|tec<,ˢ^jh6lll4]c`#EV}<#R\r">>{~b}jVfff5MD)^w8۷'O,OOOK g10AGC~[T 6-yŞdxܻw.\/Dgd +| x&ҦQa6?^䍰e-@8'1h^cH s!:z " }rjIENDB`cb2bib-2.0.1/src/icons/PaxHeaders.5700/tex.png0000644000000000000000000000007414011522151015512 xustar0030 atime=1613145424.838620334 30 ctime=1613145424.306620349 cb2bib-2.0.1/src/icons/tex.png0000644000175000001440000000426014011522151017106 0ustar00constansusers00000000000000PNG  IHDR szz pHYs  gAMA|Q cHRMz%u0`:o_F&IDATxb?C~~EEEE߿@ A!Pp1FFFO<:uT bI012ep 1 ǯ _~(A @P@051hH24Trx F *\Ato"WSPBH̋nEKit`ەaI5bAŅ [xPM #X;ЧL3: s&W30<| Fo? Ѡ1a F#8\FHDC s /'0 1*?g`eac:X6r,(d@@DDELQK"'#Mh 1@ 42 t pX\쳿q(7(CgD wex%4'@@11sdu,gbbbPSScFQ @,X Cv#T[[[Dt Cs ۷o( Rk[Y +pOEI,/ihL3ЕO |uN;Q`v0K돿1xq2Xx `YTRVAJ/Uvxʠ'g _}g`bmfR+r2gga CnR2 Oa8} 0|AY!'Pǯ yDQB PÅ/ڒ.*R X-30pK8N6V`Ej-`o2$3xj1+`N>| *L(-7bAnkp'/N ;LW30> +ì} eq20s 0r S B \|C/[yҪaW,?0t 7830!}c l%S(r0l&@pm'G&`B?` .fΝVQ!'@=~9B"4Ɉ7V899QJ=666w1־5kV̙3$j,1?~d{5m4; =D@3 ˁ7aY#888^~܌a9MB~ ۷oa~]=@0+ @qZĂ'Aoܸgɒ%̙r FPɹ,++{B|ŋOfϞmz/7#4 :rM@Pv0HyW;IENDB`cb2bib-2.0.1/src/icons/PaxHeaders.5700/configure_bibtex.png0000644000000000000000000000007414011522151020230 xustar0030 atime=1613145424.838620334 30 ctime=1613145424.306620349 cb2bib-2.0.1/src/icons/configure_bibtex.png0000644000175000001440000000534714011522151021633 0ustar00constansusers00000000000000PNG  IHDR00WsBIT|d pHYs11(RtEXtSoftwarewww.inkscape.org< dIDATh͚]U!$Yݙ/K7M03/(,}XD٧T1ĕdY0 AB,&!3q:L=]u{>=LQuϹVRfBlT$ ! - j:n[ iohXM}ZaZQ!Q› h*M3MUf[9!SU0- @84)" QkLJ"TF2"V "FR [j\ <s#wt蘦|0Bt]G X/a(d2lShIGJZ𠎎#uq=#P"oI A˲p]7rJmmcBLEID2 cRj %0X,.L 64wqqyܟu]r$]]]`f^nl\.?Ϲs8}a\5}4:Q49y$SSSe[LӤtZʕ+Au]l޼7| 6ݖ@{:k$X%49Mdƍ sNnL u'}T*3<:thy}xu]*a077iT*:loo/vb@?a;@PJeb سgccc|mKKJM"~\r>Gn3M:<UU9v9.\`lٲ+W.#4M \W^̙3Zj]P8Kڋj0M9_J"jTY+ʰRtG)'''e8s\[P!@۶qr4tuuDwhFT\MJ$G~Q_`j̰n/|k$Cͻ[,=jbHXd||||ppO4&I!x{3L$JC Ͽ \! ӯ , .#R={WՋ/@KP- qW:$8aKTX,r WI:Ik?m&Z<Ľ8z$ݻw/ @u!idl-Y{.]]]J%~ǟXV/fQ\[k˗cǎ(`YlRMQ.^xfǎ{GL&*M , o_^ 𨏔X!t3SlB$I&IRJEHQ!2$IReB 3q?>*Vز#Ew[Qs=Wq\gs^Ӓ*-HR<σ8yT* Tl6O-IR !,*7:dYV#艪t:v`޼y⋙Z>51mxt{c֨\rDԿt\xrJ hW/ҌBL&sq<NR$ tZCrQtzӽ0>5mmmBO?vvvzjVii5T“_*Y(~߾u?^leˤy۳gOwY$3FO&/ˡd z2P`;::MV1>1OfSangfЄ$5߃}먣zabOOO*kܚ5krD3,͚5 v.]DjF_#н}ZE\FX5PEb&S P山1Uwt؏H{mD R) .?Al޼O= "x]TX~ɛ7oބ)Sn|r~```l"=PuYhii(o}axx(2vN 2ɷƪT*llQ* 5p(˾fdY,8Xh9̟?Gy$,Y[l!癥R-_|8q R}}}Wd2#R49s9Hrxᇱm6C bf*SO $add֯_ŋ3q[oŦMJ ‘xɒ%+l6X,_ߴiӑBl3gbHرcNT*POh@_(ˎ TL&1֭[q7sEpgC?4J7׿޸|m+W1S pRL&"'> dYlݺ~;$Ib"_? o PVQVM{|?:mX,nW̟?q=BP(\<00p!G5k\n,˟%7o>`y}ݪy@FDQUŕ$ g- pYpM: h$ѻcoZߎo}[8C1w\޽8 dp$zzzt;ꨣ I|AJ%`M?Ngq?@%lпA04r<>裏ƞ={utt===wQs 6p(LGa-\6m5A aHH:H p-F.c~DI\^ja޽ӿsFL [lG@HL 黥ǎl*}@8qسga"#_2 H AX+svG;vkQWp HyppPsh|NaFS;]eATAh"m'/َDO+@' GGG T+@7tZmqg8ǟn4Lg:\.!~% j(0 gy'̨F'O 8̖2#9^D Z* g3B[]3[ÁxV kTB` BҒ>N' ݋^ٳ 2/b pg^)t:YI#0@zNa #l< 3qϳƈP(0::1X,T*!͆ۢSrR b#,Jޮ vs  vMy % ?]6].NUqDEbd7JzA` 7@V?G#hcƌ4d΍ `.*v'B! 8k NҥK-3/bg ;S`"{UީZZX5tvѸ0ynJ(gۅ/uxy:C"6]QH$vf1Qhz3ϸ@`OExA RzDDÀu(4"nxO( Nh ,L$@w<ZX?m N' d!jV O>852tLFݤ4i:KKX PRTjHR־Fl_Kɏ22 ZZZT{` _ݏ#ffX~=111JE:БL1cΝVd2_D/KqqxAmJkk+сRI<A`z ^ aVF1V8CKK :::ىv56Y;PG ިFZqhmmuafU椽ֆ&E{5;Qd2dYtvvfYJ%W@~(t3ӌH!gӪq`GG̙KA5*LgNE> %r:)8$#m08G]^ܑslCJo z@P˚fr, %k I&~+.GU6;taMY e6`olNr;NAдv";`v W#e2Q׿]3[)'* Vbr/d_ HU(ZӁ wN6Ǥm An)ɲV(@ WTj*XWZ+Gb(BTU#0;dsYyWmjB`64; ((S^S=ąqc5RG\FRAZռb"ժ^,˚z?IZUڵy Z/(/A1D HG RT*abbR RI#[fO6dYPO4NILeYV&\CgP*<9Y]W?$ZE\?xڌ83fqM$80 #U l@¼V6{6,$H`vY-Pȯ{mw`Q?"?AXB.WcQ|aS(umIZ<ϣ^9<]A_4Ec%IBZERQGM~3[3G|:9_/6utvik?I0V(ЧZ?@*vHϖ/== H-V=>{oᄃws;M~E AZz|:~|iK%#WFЕbFh'vd,[A=307[FoD񩹺Eן^RmV^ƳW;?f䠸nb׷z`L%v9)GsK|;/!W*R< N|: h9#˲DlI{ {#>o 8 @ *~q&N|wA~F5^. %p)ɷAQw߾wM|I7dS [ą@|zm=3qFFOv ݑ)71i<:BB~<6K5yrqd! |oӻ&P?%{PMXǴ7؇'w;#C|:k~ޱn1[и GA|V2;%gۭPh:(=&|/W_\^|LeBhVG7 #a!r8y*c- Fv^(/4©Aھq-.NKA|?~B"P,Dg#y4wMz/#(/OpYVd !0p{7.qq2h\qPvyN͒?MyhGj)tUDD q ˈ)avfMXilg^1CB]~ ^[7Ih MspQfSh:Tw-p$ Y{{7طEA8=MK.g/X>4+{ `*8+XGo_?C= !lؐTB~0c-贿zC},-k^FKKJ=݊gV"ab,˘5 k֜cU G;tv;"M#VĸJE\q=q[8|b+2=?暿R_?q4~6C]HOt rBKU O`Al>bYǃQ'*q{Q*UM͘őGm=-®eAAյp*6ٙGExhkK3C%<kic7>G$P;Gn^ &P\`|5 n٩b٩+w~5(7_yioX5GBNZ>;IEDf]}د<,cCCEppo>Q('T|}9k3gfqeK}]Y>-|UpJ898`kx63r%;]LL>u4LҶp뭟BGGF&2.X B^z_yzL5@36?\|UXv,6Gd Xt~k9zZ?]?I8Y nFFv&sm]9qh 1^o׮SG'4j il3=(|sh<qǛ&lM\|e?aV\tB*2\h#hsАp'\ I;G \PE~^AMW/;0J Mk-|RCq_(E[^êU?|D WOGTP&e%?!+b֬6d)y|"9/PA%.RBēއ+N\~~Gϟw3?wv3F٤ "i3PSmV*=ǡ=:he;&EooX?щ8_=\/wW}ط>>O&ff+S>=a̞ Qumv5ȩА>iwq:OoU2oF_zY njA\8v>Mf sMrV`6z/j5ux}g\D%; p 8nė/zz``g5OlÍ7W^y*=aFszIsf'?{z&s,'(iCCElْx}RЮ]cصk0ߖ_[^;lޔÉ:^_W9ԓpo|n|;⁁ |kⴏ,w{mZ^ls f-m`VWf嗝/;0>Qŏ~ |0\{GTPו'I2FG+Kظq5;ҋ =j#XwW]rɳ8q1s!2 -x?>*8WW"XM1_owtdpi =狇 ӧbAOx/g~t&ݻ4y8ԺZp#Ө\q`b\ {Ob: p4ܯ~X6] 37JC_?+V&;Ey;v\rɇ4I6m—0.Y?| s{=g0C3ϙǙ`V)`D~Ӫ/_ӞqGMwA}SjnY=tt\v) yyM{CjpDT*J~JlCM{e~p+sO(\Ejgg&ܐƃΛΧcLjzVvKpycΜv\}Gl;:\"~z;CiElf%A2 sfeI~8w L7I+|w!q] J/F-%d $˾ᬚB/Nב߉blw@+Sg?y n\q_pc+._꣚s{?iÏ*W|nr*3rn_][ny:)`Іõ|d1Xk i\j nya@η3@5te;zTvzկ^~: ӏP(ظq;w 1vy RݧGct'{sznŊ'qg3p.\`0C\4u0~̦7s4E0:R$Vem;|x/ÚόY~gяޭ(b֮ ( STψ3*ǭT3`!6+C!?ßlj'.h/x~<t_o߸»=~-q}h!V8I3K=k{7i,[vF_K.Y{} ۶ e˟5׼ͦO,cەz7~R+PXoD lْk@ ޑQ=mmi* WYm"b|\J˴ilڀu#0g7j7144 pa7֯߇%U5;Fq:h3tX!)cxXiۣ ; ȩi%-#}umy==Kڹ;4ȀI+:mN[l~޻ >xE;8U~U(0,z@\엶ਧgI ͫ˞]_CKK O8fׂ  4H)Pm=fNam^ۇKgNkxs@fu9-c<󱹗A-$Ooa%fa@-'[oY`~)79%뎏 x]8YdDdžKTVmf/}.L;ʕQ.8Yd$@fGDx,i,ΒƋ@0{ڐ[^']XfF*`~ H4v?o?z^H{8 vPH?ӛ\ ORndFSraA/3=Xp& Rk۹q*A'`7K1nۥRq㓟W3r_kxl \koLuS'AJePwx%qꩋ e|sϛz)qdL `Ϗ=OjZ$cxe]${]_i|##eLLm[;vXN@HG Ànz~ÓOnSOgLg[=0}zGa'Y"+p mg =f%]7ݹ: W]uF{3J87TXai꯿ee)MZ "a {GϫOb7~v ]n85zI ˗E]&!3'Q20.R7l~I՟um[}ۨP|D1aT%:mK SYz,4Bݵoաs_ P&:3.7`^_Čfd'Yg3e A xة0,5p{HoYK=ʹ((Qi2P&20Fc&FgFьfR;h 7Àll^Y|6ߝeƮQG B|3A@O>[y"Bhmɪ xz(ˢw}gyv?HKf_~%rO>NSO|_#~*8EQ,UPL3a@e!Qd$ < \QL=\C 3 BxY,I$O41m}jryN T*U X, EPwz8!v"?(~L0H @sE^$DusT| #A k`G~Zr!CX=.Ww秇,no24f萈:zGkPܩN/T(h#Wɿ?o۶m+ܦmD3aGyc 38#]'=8  #ϡщ ]w}p99~!tfF@? P"lJRs!a87 0 $0̗f~di0VEmGтF!(y/} W'C!op/K(>@:a&#XsFe8E\zFQwDU E;>tϯ1D__vn Q(=~< 0yloOZa3h%XiO?QA辡A˛7[o.('~: #L8?Dh(hiia(Om\?3&I_yBQ{=xU1zuWj=?J=4%IB&,o~788}<{W3{_? LǏ=L:.] {[YSVɴXޯ?4~o>sk42ޟ hƶ0S4QmT\ D 7ګJO@ V0^쒩I{ p0?($-kxU\2G߇ݻzz y睭r Kzd.8 ~>K$2ėhG?߆yIc\ڻo>޽s7z{{AI=<}WFqJ~ROv=zͿ@7|YD}ϟJ "2Jyrصk7y{wu׍_BXN5+ڑh#DY;n'?9?}'Q HNz=]/Uu R\#czh]n(~\@,k̴4zJ.Iq]jtwwG% ubҫvC=#PT~]{€;Wv $ J 'vB5:?SiBǑ%* j0Z k28]k U }_z<"#? (2SM fmy;}(dF_iTQd6`shXӦuSqz_0r9esW]VЮCo|^:W򩔜iiA6hRttu~ (UЈU{iԩZ@&ϣZKYotl׿C/V<~'?BXrtٍF.c<QiisP.P*1^T*}A<,X[srkz憧Bkt@9tbl6۰d7Yp`{ϯuPOHO(3\ y7ϗE/J(K(Gal c(kBVY=NnÖHAGXfMLjZ; j{Wvh#@[4 D4 藊l"/RGCt`Y:JA*ݍ}Dy~/nܸU{P_ӒH@3  M!E^dȲM6aᄑ~˳{{{N=4!D4m)By*ǩKYn] zyaFAAd]vawYӟ^zv.Fާwmzh&PBP gYTU-Czxtd^ɐ>6fk#_d$`޽ص{'ʕ?=obbCnR[$y@4*WRNN7OJIDv6|T'ˬ@ulllƍo]qъ_?R@Lh @GZ@ 5Y-D= o]ғsdsΦ aEsuS:i($si$Вv !@hgS Z|Ϡ-LuЂO҆>/A;>3$90P;OPOzĴS` B}p&<[@$ 7h Z˺|&%/HQ'=/- RdqE*68/!;esShB3 /Ѧ|:7U!ۜ'H^GZ#!z $H k~ V%tEXtdate:create2019-02-09T23:34:22+01:00v %tEXtdate:modify2019-02-09T23:31:07+01:00[Q+IENDB`(    %(()))))))))))))))))))))))))))))))'&"  &2=CFGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGFEB?80& %8KYbghhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhge`ZPC7' 0J1   9X ;# #@bB( fff```]]] bbb UUUUUUUUUffffffffffffffffffffffffwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwxxxIII$$$2Oq$$$M* 2qqi>>;/.-!! ...X, /db^YXSUURGGE775"""###$$$%%%%%%&&&'''((()))******+++,,,------...//////000000000000111111111111111222222222222222222222333333333333333333222///***$$$777a.fffcc]|QPL[[VHHGAAABBBDDDFFFHHHJJJLLLNNNPPPRRRTTTVVVWWWYYY[[[]]]^^^```bbbcccdddeeefffgggggghhhhhhiiijjjjjjkkkkkkkkklllllllllmmmmmmmmmmmmmmmmmmjjjddd[[[NNNCECk/```-,*DDACCB>>>AAACCCDDDFFFHHHJJJLLLNNNOOOQQQSSSUUUWWWYYYZZZ[[[]]]___```bbbcccddddddeeeffffffgggggghhhhhhiiiiiijjjjjjkkkkkkkkkkkkkkkkkkllllllhhhcccYYYLLLJJJy0]]] 11/===???AAABBBDDDDDDEEEFFFHHHIIIKKKMMMOOOPPPRRRSSSUUUWWWXXXZZZ[[[\\\]]]^^^______`````````aaaaaabbbbbbccccccdddddddddeeeeeeeeeeeeeeeeeeccc]]]TTTHHHQSS1NNN %%%===???AAACCCBBBAAA@@@@@@@@@BBBCCCEEEEEEGGGHHHJJJKKKMMMMMMOOOPPPQQQRRRRRRSSSSSSSSSTTTUUUUUUUUUUUUVVVVVVWWWWWWWWWXXXXXXXXXXXXXXXXXXXXXVVVQQQIII???WWW4UUU""">>>@@@AAAAAA@@@<<<999777666666777888999:::;;;<<<===>>>???@@@@@@AAAAAABBBBBBBBBCCCCCCCCCDDDDDDDDDDDDEEEEEEEEEEEEEEEEEEFFFFFFFFFFFFFFFDDDAAA:::111\]]5!UUU""">>>@@@AAAAAA>>>777111---*********+++,,,,,,------......///000000000000111111111111111111222222222222222333333333333333333333333333333222///***$$$bcc8"UUU###???AAABBB@@@;;;777jkk9"UUU$$#???AAAAAA@@@:::555psq=$ UUU%%%@@@BBBBBB@@@999444wyxB% UUU%%%@@@BBBBBB@@@999555}~J& UUU''&@@@CCCCCCAAA:::555///V( UUU'''AAACCCCCCAAA:::555BBBd' UUU'''AAACCCCCCBBB:::555RTTp) UUU(('BBBDDDDDDBBB:::555cee( UUU)))BBBDDDDDDBBB;;;666tvv' UUU)))BBBDDDEEEBBB;;;666' UUU*))CCCEEEEEEBBB;;;666$ UUU++*CCCEEEEEECCC<<<666!UUU++*CCCFFFFFFCCC<<<6661UUU+++DDDFFFFFFCCC===777@&UUU,,,DDDFFFFFFDDD===777N/ UUU,,,DDDGGGGGGDDD===777X7 UUU--,EEEGGGGGGDDD===777]<! UUU---EEEGGGGGGEEE===777a?#UUU---EEEHHHHHHEEE===777b?#UUU..-FFFHHHHHHEEE>>>777b?$UUU..-FFFHHHHHHFFF>>>777b?$UUU..-FFFHHHIIIFFF>>>777b?$UUU 00/FFFIIIIIIFFF>>>888b?$UUU 00/GGGIIIIIIFFF???888b?$UUU 00/GGGIIIIIIGGG???888b?$UUU 000GGGIIIJJJGGG???888b?$UUU 000GGGJJJJJJGGG???888b?$UUU 000HHHJJJJJJGGG???888̝†††††††††††سb?$UUU 000HHHJJJJJJHHH???888ڸ͟""uuկڸڸڸڸԫΟKKAAb?$UUU 000HHHJJJKKKHHH???999SS00b?$UUU!! 000HHHKKKKKKHHH???999TT b?$UUU! 00/HHHKKKKKKHHH@@@999TTbbb?$fff!! 111IIIKKKKKKHHH@@@999TTϢ͝b?$fff!! 111IIIKKKKKKHHH@@@999TSuub?$fff 111IIIKKKLLLHHH@@@999Ү::00## ! !!!!''33\\SS>> FF  66b?$fff 221IIIKKKLLLHHH@@@999EDִSSϢۺʗ ll~~b?$fff 111IIIKKKLLLHHH@@@999ssSSuuۺ))))PPb?$fff 111IIILLLLLLHHHAAA999uuSS͞ ۺܽhhiib?$fff 110IIILLLLLLHHHAAA999utSS,+1111**ۺ{{Ӫְܻb?$fff!!!111IIILLLLLLIIIAAA999ttSSڹKKwwb?$fff!!!111JJJLLLLLLIIIAAA999ttSRڹLLEE55b?$fff!! 110JJJLLLLLLIIIAAA999ttRRϣٸϢċ b?$fff 000JJJLLLLLLIIIAAA999ttRR[[aa͞b?$fff! 100JJJLLLMMMIIIAAA:::tsRROOFF,,SSb?$fff!! 110JJJLLLMMMIIIAAA:::tsRR]] b?$fff 00/JJJLLLMMMIIIAAA:::ssRRyyϤb?$fff///JJJLLLMMMIIIAAA:::ssRRȕb?$fff///JJJLLLMMMIIIAAA:::ss<<׸{z԰::>>CCb?$fff///JJJLLLMMMIIIAAA:::srLK ! ! !!!!!!!!!!||Чppb?$fff///JJJLLLMMMIIIAAA:::Ըsr]\Σbbԯb?$fff///JJJLLLMMMIIIAAA:::rqrrgg cc<<b?$fff///JJJLLLMMMIIIAAA:::XWrryyUU((OOb?$fff///JJJLLLMMMIIIAAA:::/.rrĒȘÌb?$fff///JJJLLLMMMIIIAAA:::ʥoo00ɞ 22ڽb?$fff///JJJLLLMMMIIIAAA:::,+baƚӷջּּ??ǚؾؾؾѮ..Ӳ++%% b?$fff000JJJLLLMMMIIIAAA:::tsMMMMNMNMNNNNNNNNNNONONOOOOOOOOOOOOOOqq55ͣ!!**b?$fff 000JJJLLLLLLIIIAAA:::b?$fff 000JJJLLLLLLIIIAAA999b?$fff 000JJJLLLLLLIIIAAA999b?$fff 000JJJLLLLLLIIIAAA999b?$fff 111IIILLLLLLHHHAAA999b?$fff111IIILLLLLLHHHAAA999b?$fff 111IIILLLLLLHHHAAA999b?$fff 111IIIKKKLLLHHH@@@999b?$fff 111IIIKKKLLLHHH@@@999b?$fff 222IIIKKKKKKHHH@@@999b?$fff 333IIIKKKKKKHHH@@@999b?$UUU 222HHHKKKKKKHHH@@@999b?$UUU 333HHHKKKKKKHHH???999`>#UUU 333HHHJJJKKKHHH???999Z: UUU 444HHHJJJJJJHHH???888P4 UUU 555HHHJJJJJJHHH???888@)UUU!!!555GGGJJJJJJGGG???888$$$,,,222444555333&&& pgggggggggggggggggggggggd]P@.UUU"""666GGGJJJJJJGGG???888***333:::===>>>;;;--- LAAAAAAAAAAAAAAAAAAAAAAA?:1' UUU###666GGGIIIJJJGGG???888...888AAACCCCCCAAA333 .!!!!!!!!!!!!!!!!!!!!!!!! UUU$$$666GGGIIIIIIGGG???888111<<>>888222===EEEHHHIIIFFF888%%%UUUUUU%%%777FFFHHHHHHFFF>>>777222===EEEHHHHHHFFF777%%%UUUUUU%%%777FFFHHHHHHEEE>>>777222===DDDHHHHHHFFF777%%%UUUUUU&&&888EEEHHHHHHEEE===777222<<>>888444===DDDFFFEEECCC999(((UUUUUU(((999CCCEEEFFFEEE@@@<<<888@@@DDDFFFEEECCC:::(((UUUUUU(((999BBBEEEFFFFFFCCCAAA===BBBFFFFFFEEEBBB:::(((UUUUUU(((999BBBDDDEEEGGGFFFCCCAAA???>>>???@@@AAACCCDDDEEEFFFCCC<<<333(((***IIIHHHHHHFFFEEEDDDCCCAAA@@@>>>===>>>AAADDDEEEGGGEEEDDDCCC999(((UUUUUU)))999HHHDDDFFFGGGHHHHHHHHHHHHHHHJJJLLLMMMOOOPPPRRRTTTPPPIII===111333WWWVVVUUUTTTRRRPPPOOOMMMLLLJJJHHHHHHHHHGGGHHHGGGFFFDDDMMM999)))[[[bbb ***888eeeCCCFFFHHHIIIKKKLLLMMMNNNQQQSSSUUUWWWYYY[[[]]]ZZZRRRFFF888:::aaa```___]]][[[YYYWWWUUUSSSQQQNNNMMMLLLKKKIIIHHHFFFCCCiii888***NNN ]]] )))666CCCEEEGGGIIILLLNNNPPPRRRTTTVVVXXXZZZ\\\^^^```^^^WWWLLL>>>===eeedddbbb```^^^\\\ZZZXXXVVVTTTRRRPPPNNNLLLIIIGGGEEECCC666)))]]] ```)))444mmmEEEGGGIIIKKKMMMOOOQQQSSSVVVXXXZZZ\\\^^^___^^^YYYOOOAAA???eeecccaaa___^^^\\\ZZZXXXVVVSSSQQQOOOMMMKKKIIIGGGEEEooo333***```fff333A111ZZZbbbGGGIIIKKKMMMOOOQQQSSSUUUWWWYYY[[[]]]______\\\SSSGGGDDDdddcccaaa___]]][[[YYYWWWUUUSSSQQQOOOMMMKKKIIIGGGdddWWW000555?fffUUUUUU 111999{{{YYYKKKLLLNNNPPPRRRTTTVVVXXXZZZ\\\^^^___]]]XXXOOOLLLdddbbb```^^^\\\ZZZXXXVVVTTTRRRPPPNNNLLLKKKZZZwww999000UUU UUUJJJ777@@@eeebbb???888JJJfffIIIUUU???EEEGGGFFFCCCBBB@@@>>><<<:::888999888999999::::::888666444222111111000000000000000888wumwumwumwumwumwumwumwumwumwumwumwumwumwum///000000000000000111111222333555:::;;;:::999999888999888:::<<<>>>@@@BBBCCCFFFGGGEEE>>>UUUIIIUUUUUU IIIBFFF???<<<888444111---***'''&&&&&&&&&&&&%%%%%%%%%$$$###"""!!! !!! *** !!! !!!""""""$$$%%%%%%%%%&&&&&&&&&&&&'''***---111444888<<?hmkBMJH{@?<qtsGVUS@@@KKKPPPTTTXXX\\\```eeehhhlllnnnoooqqqrrrssstttuuuvvvvvvwwwwwwuuuOOOz}|MBBBBBBFFFJJJNNNRRRVVVZZZ]]]aaaeeeeeegggiiiiiikkklllmmmmmmnnnnnnnnnmmmIIIRDDECCCBBB???BBBEEEHHHKKKNNNOOORRRSSSTTTUUUVVVWWWXXXXXXYYYYYYZZZZZZYYY666XEEECCC'''a FFFCCC k#GGGDDD! w%HHHDDD466' IIIEEEKML(HHHFFFuuuxxxzz{]a` IIIGGG% JJJGGG, JJJHHH3 KKKHHH4 LLLIII4 LLLJJJ4 LMMJJJ4MMMKKK4MMMKKK4NNNKKK4NNNLLL4NNNLLL4OOOMMM4OOOMMM4 OOOMMM4 OOOMMM4 OOQMMM4 OOOMMM4 QQQNNN4 OOOMMM4 QQQMMM4 OOOMMM4 OOOMMM4 OOOMMM4OOOMMM4OOOLLL4NNNLLL4MMMLLL4MMMKKK2LLLKKK%LLLJJJ)))+++4@@@@@@@@@@@?- KKKJJJIIIKKKKKKIIIIIIKKKJJJIIIHHHJJJJJJHHHccc]]]]]]^^^^^^^^^^^^_________`````````aaa```aaabbbbbbbbbccccccccciiiHHHJJJHHHHHHGGGHHHHHHGGGGGGHHHGGGFFFFFFGGGFFFFFF{{{ FFFFFF GGGGGGFFFIII___EEEGGG666999===@@@DDDIII!!!"""IIIDDD@@@===999666GGGEEEaaa}}}^^^FFFGGGKKKOOOSSSWWW\\\777333]]]WWWSSSOOOKKKGGGFFF___}}}!!!'''444444'''!!!333888===000$$$ vtkywoywoywoywoywovtk $$$000===888333AAA=5AAAIAHA=4 4@@@@@@@@@@@4 ?(0` $ Kgllllllllllll_G/ ktttE zwoNSRL872984983762762762761651651651651651651651651540kmlxun&~wQPOCCDIIIOOOUUVYY[```ddehhijjjlllmmnooopppppqqqqooo>>?~('$f21.???DDDKKKPPPVVVZZZ___dddgggiiijjjlllmmmnnnoooooonnn===xzyT42-AAA888 !!!###""""""############[0/+CCCb-,)DDDj**'EEEs!('$FFG&&%{&%"GHH<## HHJT! KKK^KKK^MMM^MMM^NNN^OOO^OOO^OOO^PPP^PPP^ QQQ^ QQQ^ QQQ^ QQQ^ PPP^PPP^PPP^OOO^OOO^NNN^MMMLLLL 000&&&&&&&&" KKK$$$LLLKKKvvvtttuuuvvvvvvvvvwwwxxxxxxyyyyyyyyyyyyyyyzzzzzz{{{{{{###JJJHHH"""III GGG"""HHH!!!"""GGG!!!GGG""""""KKK+++000MMM###񃃃>>>999>>>DDDKKK+++###KKKDDD>>>999>>>(((___```(((###<<<000 y||||y 000<<<###888"#999/0'(#%(&........&!#'?( @  ***/HIIIIIIII?#>>=__\111222222111111111000000000111 ^^[CCBCCCKKKSSS[[[bbbhhhkkkllloooppp<<< u +++<<>>+++ $$$AAA+++011 BBB,,,FHGDDD...DEEE...ZGGG///[HHH000[HHH111[III111[III333[III444[ III444[###III444[$$$III444[%%%III333['''HHH111[***GGG111[...FFF000[222EEE///[888CCC...lllqqqqqqqqqssssssbbb===>>>>>>>>>???>>>T^^^]-:::AAA---...???666<<<@@@000...===888999iii===333;;;)))777000;;;ggg555===󀀀YYY``_``_YYY888AAA@666&&& rqktsnrqk ***:::>>>@!'Ŀ,:::*++++++999?????????(,  .//8444844484448444844483338i###r"""p$$$n$$$m$$$j%%%i&&&g662QmlhOOM222222111000000111z{zq000777@@@IIISSS[[[___aaa888~Y&&&666Z!!!(((\+++;---T...Q///Q000Q000Q000Q///Q///Q---Q ,,,Q!!!*** 14/+'!!!111###"""JJJRRR---"""eee```***,,,<<< &&&:::000((()))4S AAAH<@@@@?D<< (   ,onnnnmmh...222111000111555('''999111>>>EEEIII(((LML1###fgf1!!!p$$$o%%%o&&&o&&&o%%%o%%%o""""""ajjB###&&&"""###KKKJJJ%%%%%%A::: ;;;+++EJOcb2bib-2.0.1/src/icons/PaxHeaders.5700/application-x-none.png0000644000000000000000000000007414011522151020417 xustar0030 atime=1613145424.838620334 30 ctime=1613145424.306620349 cb2bib-2.0.1/src/icons/application-x-none.png0000644000175000001440000000113714011522151022013 0ustar00constansusers00000000000000PNG  IHDRasBIT|d pHYs:tEXtSoftwarewww.inkscape.org<IDAT8=kSahkmE -v .~qRѽY|Rui ҂.)FЛܗ{7ں1(g}pu0Ag TYn|+{& ]* 1˞]+I?rd1T9_ޞYnSWgVY$VT2Oά­`u NV//i ,xE;/:IENDB`cb2bib-2.0.1/src/icons/PaxHeaders.5700/cb2bib22.png0000644000000000000000000000007414011522151016201 xustar0030 atime=1613145424.838620334 30 ctime=1613145424.306620349 cb2bib-2.0.1/src/icons/cb2bib22.png0000644000175000001440000000216614011522151017600 0ustar00constansusers00000000000000PNG  IHDRĴl;bKGD pHYs B(xtIME /1IDAT8˅?lTGw;0'0$(d#0H(NA)R(DJR&itCC*2}"Q\D a;{vSlS-v5ͬ|$ayyk:gZk0dii)L7o>D!c* j8q199P*(J=pԀQJ y P(hmQ(%qV _i͛7[˶V8dY(%(ؾk24CE$ICZ+R(Qf㙛xdwfllb1Bk|$M!MSeh @6KoV>|%O.9G"mC)ZVR4mْEooocvf[twww&&YiG`ʚ/QJǎ*qT,VHj.YH@_aJ!\a^Q.QRP`1悐$s~<5yAfyXV%c' Зyvt-rb F`.'~6OPR!7'_GHNN!33am5S4IQ" y1)5IʜUz%A+{wQ~X8#ߩ/HFUU.b?g:?IFQ6ٓ9eXzخN>":jkĵDŽcS" /:::(|'`+!QͲD`QH`dcрN`(~ IENDB`cb2bib-2.0.1/src/icons/PaxHeaders.5700/bullet.png0000644000000000000000000000007414011522151016201 xustar0030 atime=1613145424.838620334 30 ctime=1613145424.306620349 cb2bib-2.0.1/src/icons/bullet.png0000644000175000001440000000071214011522151017573 0ustar00constansusers00000000000000PNG  IHDR d-gAMAOX2bKGD pHYs  tIME 92GIDATM1jP?/ ,.B'7ADG(tҞWX .DrNEj}Җ~oTj=l9c&h6dY錢(2I4Mv5Դ؀q0{}~.IENDB`cb2bib-2.0.1/src/icons/PaxHeaders.5700/cb2bib128.png0000644000000000000000000000007414011522151016270 xustar0030 atime=1613145424.838620334 30 ctime=1613145424.306620349 cb2bib-2.0.1/src/icons/cb2bib128.png0000644000175000001440000001640314011522151017666 0ustar00constansusers00000000000000PNG  IHDR>abKGD pHYs B(xtIME y(^WIDATx]yp՝{ftdY-ف H1`08 $8 c݊!GR[ N`5 $PaCpŠvlɲd,H3czzigzzx~{ߣPX@1rӕm H+^TT4WjY\GQTe}EI8R vߑ=Z(@*@cc#Dt!Θ  FKbX$;Չw(A|x>~BI @Ӵ:C\DQ4,H:v/_NWVV1(2~˲ZYY&{ 9rD,c`h(OThB!G6:HF20b CꫯJ'@}}=}a@OODQ\ɲU(P,DQيmZ](Jt@$d׭[7JQT>ȽC>Ҭ0 Km}>_a@ Mָ|r /륂%@}}=/++*)))YTWWŋ ÀeYph%qX,+VX˲ؼy.(_aiV۫ݶqFꪘJ4 a޽cǾӳ`ƌ_V\\PX|9 000EK, 7܀|)Z)$Iyx7tMq(r쟭jFGuV̙3GWVYQQQK.+WĖ-[cǎ ߫ tSSeϟ?^{-ykg%2<7"@> v H$\UeB!hmmŭފN~s}ee$[' 1Xle0j1OEm?|O i3-]]]ؼy3>ϣF8_PEpMӈbhnnN$)UKkq`Г{?$e<^kU60 dYZ) ~?MQY4M%JD@%[atWQ<8q S 갶Kʯњ1DhYK)BOOO0Y4MC,x<e,XE,KV詷D-DB^*884M0\j(ǧ,8p\ȳɠުC\ICepWkD%I¶ml]`dd8vڦlܽދTI  UG@ر1a#fJ  all~y @T ](VrD WD޹466:i'vI+@Ĩvi: Ν;% ԔuA]fv9y2)Il;8)߂Smg6UgT!s^SsA+94iu];%@qq1JKK,JJJ\]]GeVB`0 ?~###Fdꤑ$r fΜڜvS"pC,0k\FdŨČ3\)S hF0DYYjkk]#Z.5ze8 ׂ?=xIW3릥 нc&L{$ڭ=JW9 w"\d[ }x&[ q\F1iS!:::T+.N-R:u亐AHMLrOUp"")[h qDR$B< Fޓcccg6$8r(-nfJ$FD"Fb)Kj)))IQ~OeYAUɧ"F(1 @T7r^DYE8ŋ'5ʶ[k!ר\AQ (^B%'rK7|7ڗ{^czE~o\Q6WS/s_Yw c9!Tk*AS[#p $e.vH`L #r!BV @9vn|n˽'yK͛' 2L;m}l+vH=^-4+AI8p$e{hz~>3 tl#\PHx3f[ɽqȦ|Y` UPw[\Ht Cp)!נoX!GȚn|!|Zt;rOyENpB=?o36+Xe@HN)CTj`!3 @QY 4@Y^X hүw}v avO*&?N_z G[IAXڿU8 P_ vs $CJKX|B$,t#B CC%Ԕwc֬R[Ï | ho k0o^9|AGs+SFYK/5!}ϧq9@_Ep-oSi ]rC}4Ē%/xeի//@$aŊ7󹍼jY ̥M Jb+ؿ3@eG[?|1As_ŬYhlǣ5wb>B D8 T@Ͽo|smH2Sov? +W~*@{LMM9}W|K _8're7܈s%ʲ,˽Io |͵x̛7 (H(oYgn qM>WrVZgiw@UU.N `1{%INGI3 r~E']ҥAG(FG1,+m۾s>F/~TV7 /Duu)~KgʁB#l(,]Z֥d,p+9_ZGem9+p vߴ7oGyOێB $io[%s³nޅϯ2bAI)Cn[ja oB~oo/| :HuZ|vbw@Sƣ/GF6 u$n,ַ^ôiE(K 'x W0Hi n DHu+碤$=D8s c>lz }n>"*lk{:pFnSl %h)è)^tE VH)tB`DUЫ;kȖS^'RA 7Uֹ4„ǎĎջdnoW޵Ue lka'cwq ?V@^ys-Nݪ&YQ|H̡$ 9Ա ^ؑջJN}hOmӰB2`Jɴ|C|/#$)cbl=U KCrX& -LNZ 0Wn4M T H0jz<$CkjpճWA!χx<0oS+9^&kW 9-.^!*E | "0 x<>m; c2 KS욋|e6q<&-]HUN4E|(**G @)SӏboG$2~$ &1 P R4VzQ[E#<qjkkmpX,Qv ~|!K@}7PhKC>RL'C"@"p~28h ! Ǐ__?4"$',*tV!H$`Y6 `Yh{q| /o &A[Hyn4ht###AsK=?~SqN'q@:lhU >avC{﾿j۶m;1\zXxSM IR`"O/uɮE1y@@{894Ǐq߾g=Db@tT@8ihɵi`AOIAEƵk`FqLےiEQ` K/ i Vm.*ڒ8C[[[AY}$H1s)O @ٳ6l| ILoI# i:ujn&v݁~OYE<=%DM .x<81#-ؽs_~NzQKe%a0LZ[MӐe~>/jנ_ V*aIR5ߟ*%Aqq1|>_*?Џfp3/F#Hg!***b4SD{T,CIq\}eeJF0F?ЇfٴW cc-`F^94j%$)t5ZN`''IgATj*,4Mc lh##ɼ~KK~e˖)G0#(nm3A^j4Z*`Fw"|2dv)ttpaw޲eC*sPjjj/zkh,,X^I1::!]6u+K6778e҇$Y?$I0zz{pH3ګojhhhRY>ʜ.FI5wvΉY֭`S£cUH l'b%ڷq6yW Y:88xC8FwO7ڎO/sCJj7v; 72T}}=pLj~:tVQH$2//o5Ҧ$L'uXũSho?gc |M %/j ,,eyd<9,]w䯟x~%DG[$%@bV9ߍ*u0 ڎ?; Eh=Cb+(rY0h{To'A\bDޡ裗QBYI*"FGGc~3Ԯ&x*T)4%̲J88DH_'Ȋ\JaRJAb0HYu =y)PX)'%"*ު*m|z_DE Obpz Ye^ZDž*gtQRIENDB`cb2bib-2.0.1/src/icons/PaxHeaders.5700/edit16.png0000644000000000000000000000007414011522151016006 xustar0030 atime=1613145424.838620334 30 ctime=1613145424.306620349 cb2bib-2.0.1/src/icons/edit16.png0000644000175000001440000000126414011522151017403 0ustar00constansusers00000000000000PNG  IHDRasBIT|d pHYs:tEXtSoftwarewww.inkscape.org<1IDAT8KHTQwhFȊ"6!-jS @M=E !BI&aQ"Z1A0HHih;3k1#>8|sϹbfHTˀH8K$k>ML3jffTʲ٬u<>DVW/ퟧot8q 33 13ZZZ=@%U13//\eH4IENDB`cb2bib-2.0.1/src/icons/PaxHeaders.5700/connect_no.png0000644000000000000000000000007414011522151017037 xustar0030 atime=1613145424.838620334 30 ctime=1613145424.306620349 cb2bib-2.0.1/src/icons/connect_no.png0000644000175000001440000000375014011522151020436 0ustar00constansusers00000000000000PNG  IHDR szz pHYs  gAMA|Q cHRMz%u0`:o_F^IDATxb?@bbhA].***,,,@>36E {s3LKK{WDD$D *'%%XpYfZ?!!{bb=== Jhee:׻w_WWCWWw ;;{6P݁Ptɓ' "ҙk:ΝrppTAiMcee Bl0YPWW6ms_v{{@a_ @V-9翪^ WpPA\ Ogmٲٳgϙ3翎:2226WXyĸdƘY8_ZZO@@ &=eʔgGgP|&)@) fK.}~/^wSN_t!@()jhh(d.,,f7oƌA[DBBB_~~ׯ?~Q__2`q^ojj˟@7P z"##3.? ;vu _d/@!;l'05 p&5(0-ȑ#@ٳ_ӧ  >7n;X0g  PYhQ%%U@)#X]vcww@681ʁk׮/_EC.\N\sd&^–  9y\S̤I?~lً/qp8 @t]]]?0 H*ݻw_\uցt[[[rξ}Q Lg*@`` ylx޽n9nn.ؑ qP!X ݃ {he,;w'رc`>(=lذ5ijhq  v@HH,YժU`Àu2P  GBTK@z`| l"DPl@ d٦MWTT GȲ3gx"8Jz{{ `XBPk f9 p:X. CP*dyyyx?ap"%ӧO߶m+WAxAmPX *9졡A d8(@9۷6F%(Z@ (t@YsѢEMLL@ź% @V5zٲe`A8lhTf߳gAB%8a345 `A&` ?DžG`:- A a\ XT3(wBAG>@*P@ZZZMFG(PXYВ T)(^Xf-,,N 9V1@Jf0ÆM3408 `%5cPJ @d 4P5N@)XÁJ8`&"( @忐t) `kk; -A;g@a/,鄠,\ Ϝu@a Rd/@`WPP#++S%=#vhJ!%; @0&?PIENDB`cb2bib-2.0.1/src/icons/PaxHeaders.5700/application-x-txt.png0000644000000000000000000000007414011522151020277 xustar0030 atime=1613145424.838620334 30 ctime=1613145424.306620349 cb2bib-2.0.1/src/icons/application-x-txt.png0000644000175000001440000000121014011522151021663 0ustar00constansusers00000000000000PNG  IHDRasBIT|d pHYs:tEXtSoftwarewww.inkscape.org<IDAT8jA{{zt~t3D.$;w">E}BB' n 1C({zgOƉ \*8sJ  l5`8==PUT)`*qӱ7l'"LjS0Ûpt 30i.45.p\Aj ::6NFQ9F )FPDa@/& EY7ڝ ԁ^v9 \$ eY'*IϿ"б~6yj&fFQ "z8h.4 Ð4IMHB{ӫ\t",--dY6C !2b0 s)e~~qD͈9}Yvg`gƁf@yA+}D'';pΗF~! 0 Ad]x??00\ w⮪ @xKDRp]tmG@_@?0x 7oĚ @L$Zƅ @K6`20|˝pc`e(Q Hr(\Y!+?@Y #% &* (n @,X @?c|;si{6 y3021m&@?0',W_~2?w@䀿ԁ ?QKۖp1 @D; 7h`(1|N '+3 Gh~2M^5Lfo e}'/v@00d- "02a:'330{PyFB! r!0 JwV0pkOz3ܿvA4/h'lA@q( :/O8XMr@ tWn(>###!lw((8T^fi9Nb? /gWP4  _ ?jH #@tbnFvP_Pd`xCA_%䟟_&_aɗO @CZ} < `ŋ } ~f;?m Xp=[ ׀ 1<p AXCb^e JF9~1e8bwЮ@dj^KGO_D ObMd`': P(fR(?@`D{{371(>ʹr!?6+(q' i D |s-( s;; ''(MR8c X|/r@ Ïj!| h)++$tFlFbဿH ,LK!gZ̕,XJ1K!pŰm< 6!,ـqDv@`~c0@(0cӀ9 `eLC; FX>(`trIENDB`cb2bib-2.0.1/src/icons/PaxHeaders.5700/configure_clipboard.png0000644000000000000000000000007414011522151020712 xustar0030 atime=1613145424.838620334 30 ctime=1613145424.306620349 cb2bib-2.0.1/src/icons/configure_clipboard.png0000644000175000001440000000330714011522151022307 0ustar00constansusers00000000000000PNG  IHDR00WsBIT|d pHYs11(RtEXtSoftwarewww.inkscape.org<DIDAThKlGGMJhT% RQrPQRpB[ P*AqA*7ZUBIB(PIDm'ce=kOw;}3]s0zR+ݻwxKseYJ)H)cw:hm p 3\$!tK\8c 1PJ91ι)o.^X 7k joK uT>~Dl%S1{]`?>:\\QL@ !G1ض JJ9\(>JQg[X__,Bf BbOL,@\7)mrccc+xCG|>P Y6R,/߰w^lAww7(+x_Ǐx@ NTO8,N謭Z"J{(ȣN:\lTóP@'mVWW~|_|QZ@M 'ePjX6߽wߝpٳg,,9764sܺuO:5wj!(c`.,-U˯c8w[ض ^5$B0V%50L|ׯ_3YT4&9oBL;&ܜhB Z T^ `lg=sιDw[76 QJJTJm۶1&(1cs![n+JZYYQ juzzzߟ/JqH(HWRw8R\7!%9Tݽ}kT*XIEbi"?2YEGmEIENDB`cb2bib-2.0.1/src/icons/PaxHeaders.5700/mimeFolder.png0000644000000000000000000000007414011522151016775 xustar0030 atime=1613145424.838620334 30 ctime=1613145424.306620349 cb2bib-2.0.1/src/icons/mimeFolder.png0000644000175000001440000000110014011522151020357 0ustar00constansusers00000000000000PNG  IHDRĴl;sBIT|d pHYsaa0UtEXtSoftwarewww.inkscape.org<IDAT8Օ=A_uWϨ!DdN|I,C!p@Br2Âj}ҨOoJݤx J0/&gfԬcjuMTp8$8p'"]"`Z$$۳E$$al6yn_UհcYkci4Soj0spqn}4EQLzn{,~꽇s03ns{,n1t)<Ty>7|EqmjvgYK$B;`~3󜈬<09,>1;9mib\vO{wMYN5zx<Bcd1ڔTT""Vh c0sLd6 *UsED@ 9𻉪*O濺7"ݮYIENDB`cb2bib-2.0.1/src/icons/PaxHeaders.5700/application-x-html.png0000644000000000000000000000007414011522151020424 xustar0030 atime=1613145424.838620334 30 ctime=1613145424.306620349 cb2bib-2.0.1/src/icons/application-x-html.png0000644000175000001440000000131214011522151022013 0ustar00constansusers00000000000000PNG  IHDRasBIT|d pHYs:tEXtSoftwarewww.inkscape.org<GIDAT8KOAҖEJQ*`6,\ w._FwQX ! 1ʭj7̼ϼ3JDPJ)O "+5BԲ(Q Rǁ2bH(ˀU:) PZaZkV /]!# wUJfz ^erc#Ndzb_@k]+ /k8~e 5µ%jqe% *=w Dk4C l (ypFO3GEG.قǗ}lە@gbsgtXkl\39SR5L"nToF|nv&* "\c2K"fBQ7#m WOKɓK4ԥ$˕oC[[qx8N~$L233N+XѲ4M,KlqBE߄̈́`ihd`aZs8mkd %"$$ @FE@vNkj-DBBBBBD"ICN#????icl8VV+V]]]^3333V++VW333,]^33W]]]WWWWWWW]]W333]^333333333333333333,]^33333333333333333,,]^33333333333333333,,]^333332,,,,,,,,,,,,,]]33333+,]]33333W]33333+]33333+]33333]33333]33333]33333++W33333VVW33333+VVVW33333++++VW33333V+V+VW33333+VVW33333V+++VV+VW33333+++++++W33333]]]]]+il32˜ʛſ҇ɻ­·ȵЇ҇ччۀ ЇЇ·džͅƄӄ؄ Ϻ׹ބ  ݸŻܦĸ߄߄Ƭބؠ֭̓ٷׄԄфj΅#&""##̋ɋŋ˜_ſgídns~wd[[dȽd侪dچⳇdنdždنͅdنƄdӄd؄[ ̶նބ [ ܵ¸dۡ´d߄m߄mŨބmכʎԩ״ׄmԄdրфU|΅̋ɋŋ˜?p|}ſ8WbcexĮ|zyt6W\TSV^gpwywtoje_cjn~v?X`_a__acdgiknqrtxz|w?Ybbegikmoqsuvxz|}~x?Ycdfhj lnprtvxz{}z?Ydegij|?Zefhjkܗz?\ggikmˆړ?]hhklnˆdž?]iilmpˆͅ?^jjmopʆƄ?_kkmpqӄ?allnpr؄?ammoqr ʳԲބ 6dnnprs ڲ?jpnpssоٝHmnoqss߄HgnortsބHenprtsĤބHenpsuuחȉҦձׄHdoqsuwԄHfrsvxyф5RWY_e`΅̋ɋŋl8mkvCB3fm闑f7422CBBAGv^ it32W ƶ˼µUUm|qsx¾m s¼s?!fĭywaݎ$¾~{yɂԎف׀ل%ǽ~ԀܐҸցׁځºǁƾ݃߉ұǃρ/Ǥµ߁؁Г΀>|فЏ x̀:ƽ~݁z rȀ8yx~Հ׀z mļрzxvuttry u mŹ7~|wvqpmt z mȺkehinoqswx}~ z mɺnhjkoprswxz{ z m̿ŀƀ z m  ɂրz mˁ̓ʁ͂ЃӅԃր׀فz ḿςЁ҃ԃՁׂ؃څ܁z m΀΂ЁсҁӁԁՁւ؃څ܄u m΀΀πЁсҁӁԁՁׂ؃څ܄u m΂ЁсҁӁԁՁւ؃څ܅u m΀πЁсҁӁԁՁր׀؃څ܅umς΂Ђ҃ԃւ؃څ܅ uḿπЃ҃ԃր׀؃څ܅ u m΂Ёсҁԃք؂څ܅݂u m΀πЁсҁԃր׀؃څ܅݃umπ΀ЁсҁӁԁք؂فڃ܃ޅzmππЁсҁӁԁր׀؃فڃ܃ނ zm΂Ё҃ӃՆ؁فڃۅ܃ރzm΀πЁҁ҂؈فځۃ܅݀zm΃ЁсҀzm΀πЁсҀzm΂Ђҁzm΀Ѓҁzm΁Ё҃z mπЁ҃zm΁Ђҁz mЃҁz mЁ҃umπЁ҃ψ8 mЂҁԀӹmЃҁԀúڢmЁ҃ԀѶm΀Ё҃ԀڠmЁҁԂ ƶm΀Ёҁӄ ڞmЁׁ҃ ƶmЁ҂ր ڜmЁҁ׀ mЁҁ׀ ömπсҁ ԙmπсҁ ſƙmπҁӀ ʜmЀҁ̞mЀҁ׀ ѐmЀҁ׀ Ӊmсҁր ҅mсҁՀր ҂mҁӀրԂmҁӀր ԂmҁՁփՂmҁԁփ  Ոmрҁԁց ߱蛅 ՂmЁҁԁց*С蛍ՈmҁӁՁցؘ߯ۯֈaҁӁՁ͑黭ֈaҁԁփ򰧯̾܍ֈmҁԁր󳬽̉󷧄䍀Ո mԁր𠐁Ո mԁր 욋Ղ mӀԁր ٲ鎂ݍ Ղ mӀԁր ʨ獃֋õՂ mԁՁր ˽ɔ׋̼ʾԂ mԁՁʑΐĴؼԂ mԁփ񸮮𫛃Ԃ mԁրô褐방 Ԃ mԁրᕉɬ䑃ėт mԁր،ލԡт mԁրĴӲljɊς mԁր񺪅̵ξ ӋςmӀՁր졑Ե𶦄 ΂mӀՁ뜌͸ ΂mԁՁրꑁѸꗇ ڋ˂mԁՁ˻咄 ъ|mԁրꕅ緸-ƾ¨ˊ˂mԁր=뙉ڲ龷ݼ⪝|mԁր)۪$৙ծ|mԁր%NѨ㱣~#ћȤ|mԁր%ު~迳|mԁր踭 |mԁր|mԁր؁|mԁր؁|mԁւ |mԁր |mԁր׀|mӀօ|mсЁ Ҁva¿vYv6Bad``^`aaccddcbapɿv)KNIJLKK`ǿvHɿvAǿvdżvnżv|Ļv|Ļv|ùv|v|voy޼ixٵkD{Ӆуσ̀ʅɃȁƁŁĀ¼o41hzÄp\(!#7;686863431! ƶ˼µUUm|qsx¾m s¼s?!fĭywafm$¾~{yf&~mǁƾm|9µ~x_|5|~v Pt{3{|dLszHywxz` Hryр/zxutqpor`Hry8{{Ŀyxtronhl `+Ht{uoWSWX[]_`deijnorswxyz}}~~}{{zzyxwvttponq ` Ht{ wqUQTUWX\\^_bcfgijmnpqttuvwxyyzz{||{ yyxwvusw `*Ht{yvwxxyzz||~~ ` Ht{` Ht{ `Ht{` Ht{`Ht{[Ht{[Ht{[Ht{[Ht{`Ht{[Ht{`Ht{`Ut{`Ht{ `Ut{fUt{ ۊߒfUt{fUt{۽fUt{½fUt{ԼfUt{ fUw}ӷfUw}ٽfUw}кfUw} ׿z8Uw}ѶUw}úڢUw}ѶUw} ڠUw} ƶUw} ڞUw} ƶUw} ڜUw} Uw} öUy ԙUyſƙUyʜUy̞Ut} ѐHt} ӉUt} ҅ Ut} ҂ Ht}Ԃ Ut} ԂUt}ՂHt} Ո Ut} ܮ畆 Ղ Ht} *̞~|敆~xx}Ո Hr{֓~|xxyz߬}|حֈ Hr{ ˌy~}踩ֈHr{ 򬢬ʼz~ۆzֈHt 򰨺ʃy~yՈHt} x}zyՈ Ut x떆|yՂ Ut ׮{ۈ| ξ~Ղ Ut Ȥ|ԅ{Ղ Uy ȹƐօʺǺԂ UyǍ̋׸Ԃ U{ ο񴪫輪|y Ԃ U{亂ꬥ|{ԂU{Ȩ}‘т U{׉ȿއ{ѝтU{ѭŃ}DŽ}ςU{~ȱͽ~ ӄ{ςU{읍{Ҳ~ x}΂U{뗇z˴| x|΂U{|x϶铃| مy˂U{{xǺ Єz|U{!x峴-Żɿʃ{~˂U{?ꔄyخ轶ܹο|᧙|U{S}٦ッ࢔|Ӫ|U{'︩Уᮠ}x"yЗz~ƞ|U{!ݨ~xy罰|{xx|U{綪뾰 |U{|U{ |U{|U{|U{ |U{ |U{|UyvHtyvLkov(1MNJHHKMMNNPPMLK^ɿv <>:9;:QǿvEɿvAǿvdżvnżv|Ļv|Ļv|ùv|v|voy޼ixٵkD{Ӆуσ̀ʅɃȁƁŁĀ¼o41hzÄp\(!#7;686863431! ƶ˼µUUm|qsx¾m s¼s?!fĭywa3H#¾~{ytqrx3\k'~}qHVbǁƾ~~n6LNYZ[^ijor.nljiefjpµ|{{yz {z{{zyxwwP ?KMVXXZegijmmnnjjhg(ms|{~zyzzyxxwvvP 5FKXZXX[[_``a0ccgips~yxvu vwyzz{|{zyxxyywvE 3EJY[XXZZ\\^=_`dguyywqoppopttvx~ywxzywvB0EIY[ZYXWQQRRST[bр!zxtronihedfggh ijuw{|{ywvB0EIY[ZYWVPPQRX^{.|zvtpojifebbddeeffgitw|}{ywvB 0EIY[ZZ]\WVSUTKICBDEGHLMOPTUWX]^_`bbddfeeddccbbaa`__^\\[[XWWVSUdghi jjkmvx}}{yzxB 0EIY[ZZ]\XWTVUKH=;<ո)9>DEEEEEEEEEEEEEEEEEEFL_ո)'+01111111111111111112:Nո) 3ո).ո))ո))ո))ո))ո))ո)(ո)(ϲ)&Ũ&t܉n b{t[  .9\ckllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllkc\6*  )CIPQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQPIC(      cb2bib-2.0.1/src/icons/PaxHeaders.5700/viewBackward.png0000644000000000000000000000007414011522151017323 xustar0030 atime=1613145424.838620334 30 ctime=1613145424.306620349 cb2bib-2.0.1/src/icons/viewBackward.png0000644000175000001440000000062414011522151020717 0ustar00constansusers00000000000000PNG  IHDRabKGD@ pHYs  tIME ƒctEXtCommentCreated with The GIMPd%nIDAT8˵1n0DInEplK &{)@Q@$3߷GV1 Ð4O{fImӟ|7Kϛf2mt}5Lw}cKL@`2yD\aecL2A` 4Af$< ^dY0oQ^xծ א0"g.M>n4MQ96T]Ihʫ\jUU% >MS8q sy3SY(C'~оIENDB`cb2bib-2.0.1/src/icons/PaxHeaders.5700/application-x-tex.png0000644000000000000000000000007414011522151020260 xustar0030 atime=1613145424.838620334 30 ctime=1613145424.306620349 cb2bib-2.0.1/src/icons/application-x-tex.png0000644000175000001440000000126614011522151021657 0ustar00constansusers00000000000000PNG  IHDRasBIT|d pHYs:tEXtSoftwarewww.inkscape.org<3IDAT8J\QyA0h5 BA[g,- byAB 1pu)\u8?@ a}k6Ǩ*Ƙ 0յr{|ߒ$0` u]< Xky! tZ a&IE}BB' n 1C({zgOƉ \*8sJ  l5`8==PUT)`*qӱ7l'"LjS0Ûpt 30i.45.p\Aj ::6NFQ9F )FPDa@/& EY7ڝ ԁ^v9 \$ eY'*IϿ"б~6yj&fFQ "z8h.4 Ð4IMHB{ӫ\t",--dY6C !2b0 s)e~~qD͈9}Yvg`gƁf@yA+}D''ժU| 8ܹsnݹs}}ؽ{G'Wz90@(lٲ]]]GUUճ&((e700POʋ>ׯ_'O{Ǐ:u0@ * rpZ aaa ,985EHsUTTT޼yï_#߿O>s޽ Y򿲲rw󲚚lll.9`LA 0M*uǾ~ ߿` ۷o_|-r@,q)))SSSA 쫹 `z*ePI_f`x"8A ?~`89⿱}}@@ $L`-nnFFFRfFD`J^8eʔ322WVVv֭Ϟ= sPE !o޼XԜ4"$꺮_֭[Aĸv(jhh_TTv PO`F) @  ɓ'{߿߿l7Q*6o̙AX0onn5ӧO?&&||<(ZCn[l9J a Ǽ}_zٳg`]v?|9[@!J۶m;&338`4,%9r`a/P6~ Ǡlg?cǎ={62P A8f^ PPb9 P,P00T, P|r¹sX@ĉA0SPP[l)L> t)HBMM- X7o~zp|@:FJI84M6`@ i(0 mp_JO"^zH) BR С,T*i /B+f*ax`۶QJQx-_|abb7odXF!@\.G*"Q,y Vd2Ifee%޼ym>uT*j5=z$w%#$Hp5J<~G"  133˗/q]L&Í7V|ׯ_S(bddu`zuzzxH$B6֭[TUr$I:/^q*NիW.ru\ÇlnnAh|聊+ vbS. ÜC&attԴփ!^t:X~:{{{DQ88:]>grrZ <{O,wӧOH)qf=ܻw5"m{$Rϟ?s&JGhBܖRn).F*1Mf1Z~,Aࡣ4B$%Uv:_ `0hFq)e)aԔRcBsnhIENDB`cb2bib-2.0.1/src/icons/PaxHeaders.5700/edit-undo.png0000644000000000000000000000007414011522151016602 xustar0030 atime=1613145424.838620334 30 ctime=1613145424.306620349 cb2bib-2.0.1/src/icons/edit-undo.png0000644000175000001440000000154214011522151020176 0ustar00constansusers00000000000000PNG  IHDRasBIT|d pHYs:tEXtSoftwarewww.inkscape.org<IDATxڥKhQϙ;ɴI/GnD\nƅVpƍn+u+*.WnDP-Zj[km5Mb$&3MPAt7s0Os2]GjwDZ6􈾐$ 8,]dk-+kl5pښJ]^ps%ItA{gAk5̀?"իcoWBSߖ]0I$ lUu NcM99'+HM*N@0670lji1㪯:*]@|)mA mLhֆmLҢјY.ш\[[q`sJ[罃VgՆhY0F.‹ݑ 킩!f6[C1csvY:jriʾ`9[p{GdrE57DY{*O{* &Jq _L>AbPHrg5@PeI?H/t(IENDB`cb2bib-2.0.1/src/icons/PaxHeaders.5700/clipboard.png0000644000000000000000000000007414011522151016651 xustar0030 atime=1613145424.838620334 30 ctime=1613145424.306620349 cb2bib-2.0.1/src/icons/clipboard.png0000644000175000001440000000102114011522151020235 0ustar00constansusers00000000000000PNG  IHDRasBIT|d pHYs:tEXtSoftwarewww.inkscape.org<IDATxڅSOP4qf?_j,,$+)N2q&2&I4z\~^wW%`t:+|~}8gtڀHf!(J_d28VT*Bir| !(d۶mr<UUq(IٌqLSj a|9bXM3˝ 0 Ƙp!+{1v_Ǔod~Z}4-ۉ=6/-eHCIENDB`cb2bib-2.0.1/src/icons/PaxHeaders.5700/viewZoomIn.png0000644000000000000000000000007414011522151017020 xustar0030 atime=1613145424.838620334 30 ctime=1613145424.306620349 cb2bib-2.0.1/src/icons/viewZoomIn.png0000644000175000001440000000303114011522151020407 0ustar00constansusers00000000000000PNG  IHDRĴl; pHYs  gAMA|Q cHRMz%u0`:o_FIDATxb9s&xxx4 Ǐ?8HDDDׯ_ߟ>}zPXXxo0| 9, sXYYݿ}6EFFVEVV(oGU>{lP}1 Xa/##:''Gv99y],V(--鳢_d`bd񐖖-#((t_EZ'߿g.!8  @>>H### 660&&F8edK2 X]80H  tXl@.#Zhp80>211a5 XT{ׯ`P  4d)3?`d0l @.G**B@#02@"`ׂ bgge+(EaIJcV ̬  ZFx9?s~:T@,?f-Uyjk] "P<~2`;L8 2b07ax+,̽RR,p32?0W!޽;}}w[[[ _~oPR@182| ߯Du'Lw>ܹϝ;o66VN`@.0#\@׉ 02ة1ۨ3hK02?tƷo={\`Dmݶm3gr~{[&o mZF0]*AEݻwG3 Ǐw`. FlG8̀EÜ{Gn>(h/= >˞0cSAC)X+nlgd?#CCC1pqq1k87nS~`8/o?P K2<`d`fo?6ڵk)@ lbvcWgxG`~z޳3ci`-a6F0O~Xcc]=/[_gf鬠z 緀ٙ hcmP L~߁G`_@~+d0>IENDB`cb2bib-2.0.1/src/icons/PaxHeaders.5700/filesaveas.png0000644000000000000000000000007414011522151017034 xustar0030 atime=1613145424.838620334 30 ctime=1613145424.306620349 cb2bib-2.0.1/src/icons/filesaveas.png0000644000175000001440000000402514011522151020427 0ustar00constansusers00000000000000PNG  IHDR szzgAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxb?5)ՙ~}x3e7~^?wgOH/@Q2@vCO/@Ba#_FF?1AՀhY x𥜁V?O{ΧA@_> cK\E VOdP2p%0~+ #.o~O?0od``e`ge8C_fe``:rn>0ܔgpa j PZn.v#yA>.~.ySho@5L nc+&Q@,Z @6 0H 0>00lc`dd`xL _f ԇJHB Q~ @^fx ho?]8j3k1?/``VZh9ec`&LO݋>W~3+Aâpjs@P'P`xx ×}k@f:_p"T?PAA<Ǡ|"0 v 1%Û}~.7~b=8*;Q F+Ơo Lt@YvfvPrx@AB ,BPII|߄d 7$ @1|L= 2 ˿Cх+ 9>[ o`T;ѐv @,a /`I/?X &@` XN=bg`Y Wh 1!)A k-KA߀Eϟ}C 4?/+dy%f<3k=Pt1aNb 7`!1p=bl,~}}z@C3lƏ??H Rp9}@)? ~F0 r_~@a >" }ǐNrPe`,r|:XF +ý.J2|q`22tڮbՂ ?~f&ʿ( 00F]pZx:s%.[فY(8 ( @7x$(03]6 0:ñ^d3R l_p=, 8Pp} Xu0QJc'RT,_Yhod8̟JŠ2\V&@.}2(2ppY/Y Ь )x  :8[< 2~660\l?h-ήK17?_C *:(q'Bb׿> @XZ% _R UD!Jο(YX,02 ×  @0dO#$ ,~h3 eOp,%A W&` ~H !3N/`{O#(1޽{)|D~$Ty__We\8@10Hp7=x0lt/@Ճ::p ZSr@11 0w@{()IENDB`cb2bib-2.0.1/src/icons/PaxHeaders.5700/exec22.png0000644000000000000000000000007414011522151016002 xustar0030 atime=1613145424.838620334 30 ctime=1613145424.306620349 cb2bib-2.0.1/src/icons/exec22.png0000644000175000001440000000217314011522151017377 0ustar00constansusers00000000000000PNG  IHDRĴl;sBIT|d pHYsaa0UtEXtSoftwarewww.inkscape.org<IDATxڅUMH\W>͛:X⌴n b tאHign]R.FZ!quƆҍTM, }o;$8޽;|l6KOkN Z*eYS:;.wAiG%%%f#֢" R+gffCC?85QVVu\7jkkFۙH$O*666u]?<<; (AeVi~NwGFF 'TxTFG~>::2WVV>X'-  Y#7987JKKh+PVZ;;; ϯ!m<\Qhƀ:q괋)BW072==݌B"= TiHņCw᤺;44TWWa/+ӁفPX%.J[A=Gî 2ab_7Ȁ>CzrNtW9B:??CDQk|5oӳgADNt.c9C@h|rj`u>R $b]P(9s%gpYa"@:G /G4A |3Hwkk>ɀHRROOθ Us O,.Z\\|+4SFoj///8;;{gItLK%>z9FIENDB`cb2bib-2.0.1/src/icons/PaxHeaders.5700/clear_left.png0000644000000000000000000000007414011522151017012 xustar0030 atime=1613145424.838620334 30 ctime=1613145424.306620349 cb2bib-2.0.1/src/icons/clear_left.png0000644000175000001440000000060414011522151020404 0ustar00constansusers00000000000000PNG  IHDRagAMA abKGD oFFs1 pHYs  d_tIME- TCsIDATx1n0E  !ؽri(L"7{I"1Q/YbF|ȿĚ^<4mdY9u]p1mqα+9ڶ0 ZjuzTޯ i&>e*`&Ze1ޣ_{TU#ס7 !|Boi9g)ӃQTUb$0&9S4^""o/8k]IENDB`cb2bib-2.0.1/src/icons/PaxHeaders.5700/help16.png0000644000000000000000000000007414011522151016011 xustar0030 atime=1613145424.838620334 30 ctime=1613145424.306620349 cb2bib-2.0.1/src/icons/help16.png0000644000175000001440000000125414011522151017405 0ustar00constansusers00000000000000PNG  IHDRasBIT|d pHYs:tEXtSoftwarewww.inkscape.org<)IDATxڍOa( ABd"1. &,?`\L0 D BwzV!\'}wZ=ϣ>'~-ޟ4.rcO/s\ro an`i# j$->z.wȚ<>.=%-ٌKgJ25\2> urYXxģK|0J q]3h'qՇ sK#=ͻT>ȸ*]%?> 5/0KAL8˳etOGDdoNZ@u7P$3I%5,Hc-iiӈ h6*+]|Ow m,ږO6/ F+**^!gpmժxۛ76YHy=;/ٹVC}IENDB`cb2bib-2.0.1/src/icons/PaxHeaders.5700/cb2bib.png0000644000000000000000000000007414011522151016035 xustar0030 atime=1613145424.838620334 30 ctime=1613145424.306620349 cb2bib-2.0.1/src/icons/cb2bib.png0000644000175000001440000000657014011522151017437 0ustar00constansusers00000000000000PNG  IHDR@@iqbKGD pHYs  tIME![ IDATxݛkUzsNUuu܌066`nRHUZ* QP@lH ˆ_cz^;cc 3S]UGuUWϴgwmQRMtTsFp {/;cƌ%|Fݳgn[hf.&}m۶PJSNMGlԇjժ}Xzsmrĉǎöm\q=}}}=/Ru'|cǎ ͒=͒dp]uvtt:u @>3zB)r9<\ufK&q[ZZ^ܵkХ$wJYfeY?RJaYVP˲=^JIOOǏ~̙W_Y9s§ӅV|DF:y_YH=`v\J:ĩS<5AlNGK!Æ(Dgt= Eo陃<"oAXvDR@>Ȁ3~O:ijjs\.G[k ObH&֚}'EY꜊`s^?B7P1@9I3ڛC Q B2dljnON$/OR 5yb aaHݟfN;LnLmmiF kSMDbBc8s|e~޶93L>M@I q*SJqSHb>y7@V.5rk!@(t!T)%Kl%lRX¶,l²$R(Kb T)@P@Ch-42BӒ!p )JY/U!1"D)IF)͚2Ѡ $RFF)DH"C߁@H#!ɻND(!1`IA,[uʠ @KA((&_ՔԆ2h(D9%C `II0S 0BښEƐH0J&E2 _F(^FDA)!@Arz xQ/+<_QGGiJ#;PR$QPt)cS+S6:{3P_XK={"R"QzRj% qU " "դ ">/C\ja*)'NV= v&,,HRAҦQ[`0#A6(%+$]Bܺ2:ϖЏ6;(!G1*Ɨ~73}7Ɣ 68pU reAewAox'oƞAZj^ٓlO@,1]AK2!'40bXt- Ciiܼe #@1'o, 4qi0̬^vC@3 >^@ '7t;vXRwJ+(b3L󭭭olݺuI Z[.)c߇aXYLBsss~ҤI_1 MfG?6>Rʊ )&%Ɩ-[E¨JVm*9q.:b&(,QZ7/^xsp%^/Fm`I)%h ub8NP(=(@*~F` Ƙ8!+"]d/t*"yI )A@l"g[5M49"B,5emUH3?Ah]_)U `YVh=^C2Q͛=r7օ%KKJ fH ͌3Yz}\}͔lM}@jKNLMNCܳ9H gӆwNrL6Woz|S/<,\U_ւL  bwy?`[+v߹-,`a:!m+o D}?Ê;coC#`n T(wu>%)-=ټi=GƲmZE߾s,`=yKzϞai䛚v~ ZKߊ_1&<|Z6qwЪsI^z1 xԝ|ߞݥwÐ>>ܹ]w/[>*\H°RĈuaSo}w3ױe _ac.;5gnű|@uto\@>+~W*c ~m n~*nD[oY6{I]>1!|ppώ!o⩧J8azu/Ǟ`TTZ#H1-A oѲc<n;o@ke\?{.|~~kɱu!= )4ưf͝7nSڿw?C?ZJ,s;*>)X0R{[mbi`g6.?*. CzC*Ŭs[/-#jn5T2J;Yw IDK/y^'d+B0T(e^I߷vu؎zȦ o[&78:gBn!Jp$y;pܵǩ_֯r璥8D7oΎeӆs?֜;O~-aώnFanG' o+5_c "Fd3I{AG];nxh&'Jy?#^:yTyȻBe2u0\3Ǹ˃+61}g|^~`pl5!ac ~j+ ^:3" վ&@+ !dY7Xu/8ծ044k/1 ftOьi" QIENDB`cb2bib-2.0.1/src/icons/PaxHeaders.5700/filesaveas22.png0000644000000000000000000000007414011522151017200 xustar0030 atime=1613145424.838620334 30 ctime=1613145424.306620349 cb2bib-2.0.1/src/icons/filesaveas22.png0000644000175000001440000000232114011522151020570 0ustar00constansusers00000000000000PNG  IHDRĴl;sBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<NIDATxڵmlE{* J[l b@LK/Z*؊Zb%! /@BP 1AH  UFP- \KKzwۻٻu6Yf63>8t]`ieUO ȱm}s=N%~C((J 7[عm H`NCC]ݔc~\ ]ะ0b3veeb{#yi:!( Wҭ D.1԰g{W+oM_&<Ӏ?\D$*k]Op,LWC dYú Rlm0XZC$GoX茅g; TmcaS-o9+9_U$` `9=13i?:#&uJ.=qgzV,QXE (3y[lfױs3ޢy&xf*65A!I\Ī-R>EF~&ol%A&+ޱ,sBV^⦪du]2nL0$28"R̚ZH<4iΟ"+/;n~LKNK/OSiڗjG͵YHE D~*Sn1M|guR\m s]_ҥ%0<z#>IDATxmJAgvu TB+;( 򠃮vR( DKiw _yAy1N|fAr!t1 AD{b0 =dB@U`tE6R)F%b-?PN亴rqf1m+ո]KL\fFd#ma@m>СnJmhVVg֛G8.M 0ޫbmJ%eaJ~piJW!}?vNuDQx'9hs-7Q@iJJ|y""Gh/dL'\r)$@K+;M.Mn݆KqjGZmk<=yztYcbtaK-^q75yi5GWj_Gw6G?8L^|Gw<<}1oW>r$vpQthW.s̕2)U 7Sa=aoS1|Ti!%#.qy*]Ud dzhmN Q@u)T&r\p,tWImi>}~PNx<;'l S.vJ>1 2sLݧڨƩ}*R B6  vv$-I]U=/x^(?x'?ISx3mF[#/x/ uSr98C)>5~T9l@m>g{;YՒtQK !qJ7Y\z7:1q ?X1 ^uSpι 㮽sX}|Z> TWUB{笧ZӇ ^^! ]d њ@i P4#H4^b@/ mIGQ 7nr>P{>d uS P*CcZF-uS߳ó~ 6mIM^5QXRJ)?}0m~5a/y2VN*i{(LE%rE!UJ+~+&-ME?L xvȿiX pؑ# [&l{EMџ}IY^^u}zNE: CB @Aiu( ~2 )VM¥":A # q@dڨ6"2S{G{$YR$E |!L܎|ݲuU8<$uu +Yrs\2yV*O@1A%y+s>Z3{gpl6cq RR' ui4v÷emU'8xӞM{*Kekg}ML֨+&41Hy8 + H0S'E~9#dArU.ELe*!cۨfxxxx8?>l|gxpI]Re KddI\ `1: r%&-m=8΂+ROiU4苊j'~n@?vs@^Ԛ I+.풖%$A#rƨ U Dw$WU,$@$K2Hs rY.x/K \F[}!HÕp \DXYr_s $_]< dIF! ^qq ,1c@X:Z:޶GQURI8c|6ly?2s?} 3R[j+U ][]A HX 1Qͦeh u. c{rA.y9{l9)'A<. KL༺< cDNq(\.2ٌ.@2$S΁|-#0- JԪU#[3:mtcVO?>[vIWCcR66l#Onߟ @@N( EE!EAuRԳ:U ,Zd]rV΂6wm nI9!2W悺E.+\?%.q/$2$W9Ed.)5~O>WZG>G aLL:`Sϧ.k?k?PWF{{oڡj g7|6m6F,B*)FF`ooYbUu CJ06mp6,:ZWlM=~ D-^*CUg͍xȒcbS 2GUeuUp(Ŵe#Y$ْ &&5ߘl3@ tXR&kXb[ʷCvyk3ʋ͋Ӟ {& ZΉjhmh#7ܜޏE n }7& TUUk֩u /} QFjw}O%: _-,󀁌gHc$H Mi Ƴ6}+H}ܰ`,,]-߅Z N (q e }C;_p˜ݜAI+u^]RaobE>2x_h[H6?j@7@a#2MMtB9ȗ0R6xA>Bf )+`Fee;ЂJzm[-lKŷ@t$?(Uq7jo4 L(^2#G s4|B"S@&faz}l+`f`(f8-'1'h)A Ozڎ'67ӬH%r$IvZ[m\;͎6 BP`h h Tݪ5S_ٺ_( 5: n& H6&53BP5EH@B)қ~*S='q fp ˼7y o60{[g;+a~@kb C詆 #W?Gxj3Ԇ341b'HHsή.ЦIZ4mt- A̓@tII02@}%h @()r wOI{OPTMC#CK>x>N3{k, M5!/ぃ^'-L3vM iD#x3?,:Hi$@n߯K )5,7.UO[Wۀ6" (sņk!m|KjC^Nw :PDzb U^"PT^QJy Zee6, nWG?р^yӝygA&zjDI$JLvdL]3  7JPrPy7l~ֆjn7ƃvZZ(9!zvPy:6z_BP8->HmSpk˾}EPf3/_Uw >'/h^rV\y&\.;Cx8mmF͚F{i!-*$A -H5a+c@f&Xo d?[ Js3d6_MS֧@Fɛ Ui rXˑp,l&.K8=.m) Ó#;)4wu!M7A'{TYYxBuXa |!YH5gTO}Lf `}JPL-oT$Oэn UNuPc;;- cMm'ed6̐AM~6ChX[0J(\>%} |TJffrV w'Nh+Y`lko-=<0q|/ٱdG^C{ATA1b 铅 Ě7}Ba Ko^f6XSH h*n le YӀ;^rLc{7nB8 .v A~_$pd,u rRF0{ m@ JUWA[zAAeAq܋!Ep@Ka1⌻'`coY*HPxXml- \-f_+>4<]hY?-PDσ=kA-cKOLqt'^J[[ WUq柰Cz'&H07ZCzd〆^M`%cE-]y8'M0Û{f{4PIRCj@9Usm-PAqhKU`,=DZ׷.h ։:ԁ{< 6]:esb^wyQzM[#HuDP)SN!~UZۘNgȾqraxg:6@/2x{xK_Y6צBozT¤.r#@"r8qa o,;(|f3*i)iC.u<F })cܗ;`k]̈́s-q9r.%77zl@v; eUEiEQ`Iη.{ +^[e';8)jo H&i59Io R[uU]A")KY^ SPj@-hRFJYPYꞺ|KxMDfʉسZj 6(F' d {{Pm\WSH=5..,1Ç>9 }.[? Km2"^f`ǁBص[ǃOAEkV)x &e O'>x$~'2(ZX$Ju Jmvz;Iw~oPH- oy;f uyZO'ݥ;U9-$pTkV/e 0kO[J[J>ds7Tڀx4f0R !yI scI-~x1Xނク?Ʋˇ}no*(O; 7  qPUD;уn 6`)ƣkq`f8H&7zBizP0Ra fɮ(eHݶl>i~? GrvӠiv 7|P UYa 0g`8 Q1#8 ӰP[~=`ؗ{[1m*-wFƧaṕ߹w.^j٫euꍪ7fZ;o2~+_m9w|^ͬ2!5&Hj/z/7\\~k=2L/QPl;̃gOȄou^d퀠:^+_kFj*TJ5\ŨP{!`c0zZGu-ڗז&`5D[-kQ֢!Y„= {>,1fR'zw32l|X|%MxNG?^ C$RTnLߠjN ;>[|@©I&Q_-ߪ|Kh==\ ipNxbkBOm}8/aS;*_@ozHݨj FoăzI^T*f_KPP;!#Bz)+x^`+iOj'ک;޹}⨒\222&]rwVY}fh^{y,&j:]-_) xyoɀ:Ɗ 23{c uCB)}JM"D~Pjv5w,!(khۮ7sPS@HyC!ꢺ*J)1܆TT&yna\\heT1YFVZy|g3P[|rE'>dɐ%CLe*Szp@|vwYwg>khh ?y,.-7/R(f&`)1OzO8ς lp!ж;fQ edI'2qdLk{*ɲPjpo/nì!% ajnY./ʨPP1EOm.:źu=[7,k9svզ}4hԑSRJ-m2xVY鞻۫hu \ǥ%ݗt_p_լ~8RdEB,o $vhmm/8s}{[Hp*Ce Y :ըAR8e\1 yƾgO:3 iI-gMG#>Q¤rrr<<<2.O޿XYgݞuIqUB_=e!No87Uϫ^x[YWggWLLW)ӵTVٹgPӿVJhBhJ2$r+_cX5V)OMOMOMSwJVfOgl9H3\8 eXagSIVZKhWZO85i 륾ʿG{Q[$Tzԫ[KwVm}Nk1 kb+TUu-[[kSD'˟Dž2P|0g -KЗP~@D>DT=UOPҔsjF5v#H4YGe*SYL)S[kNbqjk}bo[oEp_q7mz;zꗫOp'f Wf]/P[+3jg_P!-7d" j2set0׿Kce)7 yiԣYX62y<_ZVj,5aa5a5j!NdXc7+f;WҟSR[wLQČ[J=EL&ߣRbN&yivWk†nkk|ehKEKEr_F atGD_1]ܯ'|-8b6>u 1TcMf>jJ1Jl%p.]~~~iإ__-7sbF!qleq, jQP &u.~APpl'5кRss;;~h=TVWC!0h vt)*bL BC(|"FaPH\)W.vINbN"Y|cu4V}AyP/1r yyE͔Ӱڐ"J7F1 EBx`pvim(}}vJR4ol=wN n~WU@y<E)*B X@pd>>@uU몀[KwU,,!&$mk+֞#AJ:]tg8N:^J&6u`A>e зl[0U47qgtqȝ *|L7*:uP/ʿ;p{wх;n9~tP~J)'qĢY4v :Jtf @xGo>V@̝ 3z2B{@Ty) |؂^y+sx6@q @3żൃ]ρ@xaB `l4{}aٯ򗯛qlcĖ^PS*Vik'M 5 ta=)X$iwmwZ+-kݶ_F-5zIc[/gZVwtX;xՎWV2 jk4SY|A993]zyRWqYgaҀ(k繷ϝ|`a}i/vvԺumAg󒮒۱ba? jwwt~⿖g׺ÿM/boM+l*Kx}D_jګj^r\|̘̔LӒ\1ñcDѮh@# YH}beeٔo6HL2fZ$6J) t#zBl{{vkCNË_JJɊ8}{2O͝DH55:j4 I''q?Xc}]Ifˮw\D!o炄baGXMNVS&M~auɺUU.s|!ƫƫh'''?h&Ϟ"zTXtSoftwarex+//.NN,H/J6XS\IENDB`cb2bib-2.0.1/src/icons/PaxHeaders.5700/configure.png0000644000000000000000000000007414011522151016673 xustar0030 atime=1613145424.838620334 30 ctime=1613145424.306620349 cb2bib-2.0.1/src/icons/configure.png0000644000175000001440000000414414011522151020270 0ustar00constansusers00000000000000PNG  IHDR szzgAMAܲIDATx{TƟ7o qQ: LMѣǞhON\le)(-NQk,A2pI yIB?Lb8n׮]Ǚ9{ڵkee2٤Ç2%"NS'NMM]RKHxxx&""㨯\.]tI/֭+uv@c>SQQ~2 p8̙3]aaa"o7Xb/JrX0UUUX8r/;V,5k\X,h/"@zFFF @SRQIII#x&¥޽+߶mOCBB^~E1˖-{W*n7aN'x<t:aQSSw+#*VcD2H$EqqhxOXaTww7GP<ޮX,q[l˲+ӧO_NKKރVx,X ͆v矫`@ԩRTqUnӣS:h4B!F#;rE"```ʕ+5M1bvDݻOIՒZ׫0G$ ( ;KVTnllZjmm%NG.Z}?%%99y~aaQQQRIN'f3aT9=vqDE<_-zٳAȵ̘t8=x)Ngkk/Xf_|}:J͊O/!rV Z;s~K,YZRRrN$tCL0|n],C|eLd\|kǞ/U ##cՉş0 ߣ"X> ~~Bx/zB^:+iRh_Դk+ y}q*MJJ+2 ^>Ё+Z.4Y87t;0׏A+_ԟ#ɢ%IX,NRm)))oٳ]j5\]&IH(@3 ges^W( aDGGx^~K1PVe=L&sW^Eu4M N(Bˬbd2FFFiMp]בe7obi @6m:SSS(twwMB I---B!$I"HJBT.IRBTr]Y[@  ~_M3_lvuu8Ӱ^e$I6] ض AHR;I,H_]R)pggg9|0nhNA4z噪Ύxy}4d2ӧo߾Φx[8&Lr…mK(;/:۶L-Mwbeeވ2/pGرc_ٴ yqnfFgr\ZpZkZ<Çfy(ul ^J ^D+GzLD_WU2i gsW{nH_|leis{G'"|=g ?xPUxJD8qT,Y|XϯKҳfrwqer+DE<&C}a,"DG$ O 1!íYL:{&$Pwz!wmBZ; !w̻͟BUip[JUT]Tjë5^BgEgsn`5DV*P .1j (X?M9 @&GkK* @"\h"W&> D4I`ja;M|_Y+VXE)KRܪZ::! 72* !!0CZj4|RSF*,Uc1%Enqb9/a@6gd$XH҅;0GI_|rI,0%|2[ސY"JA>J#l*#jOzF{=KcN,k5%iRqVBi5̦ԗn<5<'}ZԪ U\iC[V%0Vb$/UJӺMr , j%Vzp}L{c We*'31ʁb1qQ ?w/;"E,rwBcfGc JF?>]< Ìc ^yAZ~ ÅP8(oHi!P\˼7l>=7FP*"u cd=YN ^KoZGAzIV `zClN̹ؽ6XZ#pvw6uVH5iFwb{ D?*z1TͩY5@Y*/CXKӒy 2bt'c]w? ȣJZk-#r;BGg˰6'G5<69638!qY fKPߨj"2  +7{]`cBj l2ZF7kT{Fi'I >PgE.a8s-m@>!59h߳Ûݾj SGP0pl+`b#91\>mxEK`2g(:\( @!=L9h09vўM$Ȏ ?W2puz 8$d|ˡ֮25.*{./)lI_"0t*E(jB,soIVM>ZCK?ުnp%v8?QYptpc+̚!5AU@X)Y+S=PIЙN$dHDI9:AXumz5u -q`|ZePpĩ{zBR 'U F|{Lޠ#̨a8^oCтiEro]'@׭@_e)TUa|Kw%:G,q0n 8^``n@] @ou.d!㰵2 -ޥގ98bub`D PBLG>dL(ʼ ej|+~Xed@mUsc*>ed#/4wa@5pA<Ћ_Hs6Hm1b N̴Ӡw`s,+LrG5 OCO*$D6dnv@L5j/nPtV%xhn@Dq(R#jPw #-5Ƚ)B΅`/4|b=Fg5c&XP0y QE6Q@C4TeANj$GY(<ꁞCASuM j1 uG|jZ#t+݀U5]M2Yۯoksr1 p`v1;7?3J[q1=1I MA@:Y$c>-Z/8Y΀D jjj@U;q$p#(R#inrKn@]zuoGL Or/!Unxp9]nWGꇹ@x:j| =5 tc7ZV\t"D4pg]Nr3X? t/E8 R]I3*[Xk&ac1x^dPoC| BC]HmZ>C5fmSQ|!匧rXo-k"me iy42Fkt~Q!-5p )2QwRvAsmځ]P$xΛ8s]Pd6ܷ~wuo+oomYF+ #%!W_~ ݻsITg#{#Jl.8%3F 5v6t` X 'vA)ƫ` n,ۥr&AqIq] e5:xJt;}s~N:{ߛT k'\JXTSu.P!4T&Pm28He $Sҡ{]>mA,AXe(R0` O jwA@#UV B(T0$8fHSZBdMwc kXET{Tw;"L8n'ZO7owc}ҼI*̫NO;mmfo=:뺨I,ҼOw,5WG|ʫ|p۾m÷b:2ʷ Z%+!9"4Bs3ό&`?clS[>۱EE g^SPip+v HoHLܷw`T6Rv{ 1Ng;;uקshJ)]LueI,/~6uP4TA_N;ޓfvq9___grf^*^*+Tr\ۧ J•ʝ_E]Tޓ]Q*omz|Rս}Ms *"繼<K(upnR*-cպr1Rk^^3e͔CVXqWOş3;1;/Qs9(R~B|%K׭9@}ۥcެ<5UUza:j~~GFu1;HiY[(u6L/+9zf՛UnV 5|ȗi1&HXVhF\ R7Az.*7钷JRjO=-g9\Ynغb s}\rv ;7h_;ךdͷ>shC [2df2;7ߓomfH})vWN:SJqZ|eӕwv04s=?_>~}QXH;RӼd ;k{]_S34i.?.(GjZ9V.)*s$u)EF猡j'+^|^=S]Bxf? k(m-۶^J+ EtL%}iZi3jx Q34֟dTIDkB*fӃ U wk \[~ yeɉ:k׬=@'B-G? J! #v+ݯ''W{Va9lkjV*C)RRP'KR)H~DpPYH<_l-vmK-m>6ml5,d*A@?iw*mCZoq %A3Qݾ xࡪ͂Prt.h)\p̅"zTXtSoftwarex+//.NN,H/J6XS\IENDB`cb2bib-2.0.1/src/icons/PaxHeaders.5700/viewbib.png0000644000000000000000000000007414011522151016341 xustar0030 atime=1613145424.838620334 30 ctime=1613145424.306620349 cb2bib-2.0.1/src/icons/viewbib.png0000644000175000001440000000364314011522151017741 0ustar00constansusers00000000000000PNG  IHDR szzbKGD pHYs  tIME 5V0IDATxڵYlT眻̽3oclL6b Ȕ%*oU**}H#"A] @-F iIU؃>\Ƙ͘~ѝss˹#1T'nM~za׉;-l^M2880D\2LxxmFJeC&[ qRo> `f铧͍RFQ1H)R (54ai}ϟ߰ˁM)G ?#KRJR\6G!3cGPVke`CGlʏ~eDcx&|e`S4' shL#A@z3XxtR<}WLs^9R c;c΍!y}߼řӃ],`_ÿ$}Wc['׭˫?s&W/fDA)1\|c#OlӞ,F.W }dcJYcd6twԩ$1+I$=VP[WCu`_75}`j"gxM?~s1Ą 5kY2ߟ"L0kvƀc@k=UYq k'@ qgl}_4NZ c+*p2zYT4Rߟ۹iW4s BqEpZ,9.MU#xan8O<Dk3V%gK9qP !ĴӖ#_֜I" {+c X^+_{P^vR:=Z31xL?Wlc*>S2N1y5d6k;Gqyy.d'|JD6jbѿo+{ұz]"}{#y˵?ꐴzU8kWpמ_5-EuKdihhhd^ IENDB`cb2bib-2.0.1/src/icons/PaxHeaders.5700/configure_fonts.png0000644000000000000000000000007414011522151020104 xustar0030 atime=1613145424.838620334 30 ctime=1613145424.306620349 cb2bib-2.0.1/src/icons/configure_fonts.png0000644000175000001440000000577214011522151021511 0ustar00constansusers00000000000000PNG  IHDR00WsBIT|d pHYs11(RtEXtSoftwarewww.inkscape.org< wIDATh͚{\}?>fܙw׋i4}!cQZ(HcS\DZPh5mB (QUHA%nژ8cv;{Ow]Tis~9wGH)!9B@ej@EJNh_7 ` ?Rj FĀ-7۩ Dc!\:3{F(e` HN۶ PD/=W@9hbk@s[#M^G4䐞}T -joḵƄ #=1Xо)%b9C- ~$Ju]4nSokGiaFDc[5[͍ZݲMNNbF@`kf3_ӓbn!B<)ٽ{7y t/+.L&;rBK_[E~_~Ҕ^܏jA( 0iS* iiv=+x}tn߼fLY^: [u%)Q5~#d2BTU065WUx<Z \Z9~5x\2bmFjĊ(UWaX"-ZSUP]׃y#<eg|ُv0Hcuo]L$i ۆ`ZIR:fR?_e_qp=T=X t]r^;SQ{j0EQD"변ߑRր,pa|-nmw_6 j zo. ZXBQR-"5Ħq|'o'$ ;hhK@Ymj=~',b&mDRLߛ'wQs`xX 8,//fT*=N@}(ۦR72[ !<{(PM}VضXK P $ `l&m_1,%Dw]jJZu5ϕH(cccLoFAií<\^gJBRuۊiAK)P3e8SSS\"W0,0/ҫA oz^Jy Fٲu+SSۘ.6nOMs"KUAD"dY,[ p\AV\mYULLN ~q{s߁E.f.`ll|>j@'֢@gK-&^4d8W y#_eY>lٲL&/ DOj]C=0AD4u]ޟ$I>{%Q?c XYYZzp>={]va4Q,r8yl !ǎ;~СgY:J@x;R|+XZO[-* /^ԩSOΑor~AZ RbYCCC>aҒɇ ^05- 88[44oS!0M]׉D"q>u_h[\qa|||>O.#N9KKK XRʁlmCd0e^w3Z-8'5?8\٥>? .@TU%:euD=ϣ\unJ>gff&o߾G9嵀Ka4M^#h[a2ilLZRJ[hig2YJ3NR`st>6>uqݼ09R(DBsA8p<\C097Y+$ƱEKM,qsѕ)d2'qXc:`fI`ݚոڗCqjQ8ma8{ʂ5'wt BPi>9ɍ S;~v\4ĹaV:r#dd̰\fw0:[dp}@VQl4?O!0T8) C<}iZًr^z{{%~!"8ȢvaCpN@XX z S pnh_o4us1c~"IIQQs[,fjoLv}/3 [ kʃHyoRO58@~;Bb4T[woN hm2'#Bd-AuB TV s%0"Hd^1FQ@0@:J聦k-`D0Fxpx"CUYQ]Ж_83}nGys|#19·_iӦ+,6eaAD#~9Im+~3ųEw>cNMMqW*",`J3e STȲU>.Pc``۶mϗ[+r}!)b6Ks_>cff΃ȲpQ,=pu>rlƬyV յ.c ,o* ׯ㿄ZG X[vʩS>n.|95!"tww}=[[UKwE:p "%h7M4R###z{{n| />bհ6^oyùR I8R0000Z \YǥK,ˮn)Qh4jTU:7o޺F1{B*QIRV|29TU\S\ֺ..VVJ4%cjZF(8+ĿVŴgycϣxIӔ$I(9ɡCFh;jӬ߾}}ZKQczz:9vǏB8`5LDm߾7nܸEUʕ+N>a'C;^&1IENDB`cb2bib-2.0.1/src/icons/PaxHeaders.5700/viewZoomOut.png0000644000000000000000000000007414011522151017221 xustar0030 atime=1613145424.838620334 30 ctime=1613145424.306620349 cb2bib-2.0.1/src/icons/viewZoomOut.png0000644000175000001440000000307714011522151020622 0ustar00constansusers00000000000000PNG  IHDRĴl; pHYs  gAMA|Q cHRMz%u0`:o_FIDATxb9s&xxx4 Ǐ?8HDDDׯ_ߟ>}zPXXxo0| 9, sXYYݿ}6EFFVEVV(oGU>{lP}1 Xa/##:''Gv99y],V(--鳢_d`bd񐖖-#((t_EZ'߿g.!8  @>>H### 660&&F8edK2 X]80H  tXl@.#Zhp80>211a5 XT{ׯ`P  4d)3?`d0l @.G**B@#02@"`ׂ bgge+(EaIJcV ̬  ZFx9?s~:T@,?f-Uyjk] "P<~2`;L8 2b07ax+,̽RR,p32?0W!޽;}}w[[[ _~oPR@182| ߯Du'Lw>ܹϝ;o66VN`@.0#\@׉ 02ة1ۨ3hK02?tƷo={\`Dmݶm3gr|+0>$ZLf\uwkފ+k&bdxAիW W5YXX,vׯMutt}#+@ YMXeE8;Tq1p1K y&M7  J-^ 4PB@@ h&` @L̜Q,@?203r2 0\}/?s' *555?*ŷxA' B$S*0;$R`pC\ 1pqq1k87n]kXī _ʞ񟉙o2nUgh,3ؕ2pp0(10g<- +_VP0`dd&??{ ߋ+ "?~e HD1baa&''m mq mee=XWo7YE: 0X2 Χ0A#IIENDB`cb2bib-2.0.1/src/icons/PaxHeaders.5700/exit.png0000644000000000000000000000007414011522151015663 xustar0030 atime=1613145424.838620334 30 ctime=1613145424.306620349 cb2bib-2.0.1/src/icons/exit.png0000644000175000001440000000311214011522151017252 0ustar00constansusers00000000000000PNG  IHDR szzgAMA abKGD pHYs )ItIME CJIDATxŗmϙ{U^UR]hZ &,@# ZOY PZRI h"RCT$mn\5uwwvWo{̜;slB syM5o2pp}jJ5vէ3{Jf5֠528hkA;hu68s~޺c;MlM14&dZtx!˜@Y7x-ۙa #o<PH褘ː?GyɅ{O<ǹ矤ϹP 4^Dm?:~9c>}w/O.D"k ^OS ]q@SF3L ڬBH<$\1?[m.\/GDW]ی^&neW{y5 }OѮvP_dڗٓ"e&ۇ/|l -(PTO])b6SpX(Q1$fn;5ZtE^-B^%".\YSWŗOfRݬy i߅+=.P;R1t>PI'(2#_-@7gf‡v,m9"a+[T\u\!p湊?ڽ/Tj\ElJO7| P.eU/-@]:Lk__5~1 ^ɛW |կjy{G MB mA,p+ϓ<.M?o0?DhlYBjFv) wFF~Tg{,WR~I"m#\Y1)#,{s/D+N] b2t9|f*S4,aM4,]啢@>>< 0nSj8vJwӊ6:h_709| u⭊z"?OϧG;6Ja"ETXq,>r;sEq1۵IJEͱۆVG B)0nswl|IT;Q@}Ӛ]c;5}v{]֔ ˣf'=^Ny<\^),IENDB`cb2bib-2.0.1/src/PaxHeaders.5700/c2bConsole.cpp0000644000000000000000000000013214011522520015561 xustar0030 mtime=1613145424.410620346 30 atime=1613145424.826620334 30 ctime=1613145424.410620346 cb2bib-2.0.1/src/c2bConsole.cpp0000644000175000001440000000567414011522520017174 0ustar00constansusers00000000000000/*************************************************************************** * Copyright (C) 2004-2021 by Pere Constans * constans@molspaces.com * cb2Bib version 2.0.1. Licensed under the GNU GPL version 3. * See the LICENSE file that comes with this distribution. ***************************************************************************/ #include "c2bConsole.h" #include "c2bNetworkQuery.h" #include "c2bSettings.h" #include "c2bTests.h" #include #include #include #include #include #include #include c2bConsole::c2bConsole(QObject* parento) : QObject(parento) {} c2bConsole::~c2bConsole() {} void c2bConsole::load() { // Send _process to application cue QTimer::singleShot(0, this, SLOT(_process())); } void c2bConsole::_process() { int code(0); if (c2bSettingsP->cl_html_annote) code = cl_html_annote(); else if (c2bSettingsP->cl_doc2bib) code = cl_doc2bib(); else if (c2bSettingsP->cl_txt2bib) code = cl_txt2bib(); else if (c2bSettingsP->cl_index) code = cl_index(); else if (c2bSettingsP->cl_cb2bib_tests) code = cl_cb2bib_tests(); else if (c2bSettingsP->cl_cb2bib_information) code = cl_cb2bib_information(); QCoreApplication::exit(code); } int c2bConsole::cl_html_annote() { if (QFileInfo::exists(c2bSettingsP->cl_annote_filename)) { const QString tex(c2bUtils::fileToString(c2bSettingsP->cl_annote_filename)); const QString htmlf(c2bSettingsP->cl_annote_filename + ".html"); texToHtml t2h; t2h.toHtml(tex, htmlf); return 0; } else { c2bUtils::warn(QObject::tr("Error: Could not open %1 file for reading").arg(c2bSettingsP->cl_annote_filename)); return 1; } } int c2bConsole::cl_doc2bib() { bibParser bp; metadataParser mp(&bp); c2bNetworkQuery nq(&bp); // needs c2bUtils::fromHtmlString bibExtractor be(&bp, &mp, &nq); const int c(be.extract(c2bSettingsP->cl_extract_input_filenames, c2bSettingsP->cl_extract_output_filename, bibExtractor::Document)); return c; } int c2bConsole::cl_txt2bib() { bibParser bp; metadataParser mp(&bp); c2bNetworkQuery nq(&bp); bibExtractor be(&bp, &mp, &nq); const int c(be.extract(c2bSettingsP->cl_extract_input_filenames, c2bSettingsP->cl_extract_output_filename, bibExtractor::PlainText)); return c; } int c2bConsole::cl_index() { bibParser bp; collectionIndex ci(&bp); const int c(ci.index(c2bSettingsP->cl_index_dirname)); return c; } int c2bConsole::cl_cb2bib_information() { c2bTests* t(new c2bTests()); const int passed(t->writeInformation()); delete t; return passed; } int c2bConsole::cl_cb2bib_tests() { c2bTests* t(new c2bTests()); const int passed(t->allTests()); delete t; return passed; } cb2bib-2.0.1/src/PaxHeaders.5700/c2bSaveRegExp.cpp0000644000000000000000000000013214011522520016170 xustar0030 mtime=1613145424.442620345 30 atime=1613145424.830620334 30 ctime=1613145424.446620345 cb2bib-2.0.1/src/c2bSaveRegExp.cpp0000644000175000001440000002060314011522520017570 0ustar00constansusers00000000000000/*************************************************************************** * Copyright (C) 2004-2021 by Pere Constans * constans@molspaces.com * cb2Bib version 2.0.1. Licensed under the GNU GPL version 3. * See the LICENSE file that comes with this distribution. ***************************************************************************/ #include "c2bSaveRegExp.h" #include "c2b.h" #include "c2bSaveREHighlighter.h" #include "c2bSettings.h" #include "c2bUtils.h" #include /** \page regexpeditor Regular Expression Editor Once a manual processing is done, cb2Bib clipboard area contains the extraction tags, plus, possibly, some other cb2Bib tags introduced during the preprocessing (see \ref clipboard). The RegExp Editor will generate a guess regular expression or matching pattern usable for automated extractions. The cb2Bib matching patterns consist of four lines: a brief description, the reference type, an ordered list of captured fields, and the regular expression itself. \htmlonly
    # cb2Bib GET_VERSION Pattern:
    American Chemical Society Publications
    article
    journal volume pages year title author abstract
    ^(.+), (\d+) \(.+\), ([\d|\-|\s]+),(\d\d\d\d)\..+<NewLine3>(.+)<NewLine4>
    (.+)<NewLine5>.+Abstract:<NewLine\d+>(.+)$
    
    \endhtmlonly The Regular Expression Editor provides the basic skeleton and a set of predefined suggestions. The regular expressions follow a Perl-like sintax. There are, however, some slight differences and minor limitations. Information about the basics on the editing and working with Regular Expressions as used by cb2Bib can be found at the Qt document file \htmlonly
    Qt Documentation's QRegExp Class. \endhtmlonly Remember when creating and editing regular expressions: - Switch the clipboard mode to 'Tagged Clipboard Data', using the clipboard panel context menu. - Extract the bibliographic reference manually. On the clipboard panel will appear some cb2Bib tags that indicate which fields are being extracted. Once done, type Alt+I to enter to the regular expression editor. In the editor, there are the four line edits that define a cb2Bib pattern, one copy of the clipboard panel, and an information panel. The information panel displays possible issues, and, once everything is correct, the actual extracted fields. The clipboard panel highlights the captures for the current regular expression and current input text. - Patterns can be modified at any time by typing Alt+E to edit the regular expression file. Patterns are reloaded each time the automatic pattern recognition is started. This permits editing and testing. - cb2Bib processes sequentially the list of regular expressions as found in the regular expression file. It stops and picks the first match for the current input. Therefore, the order of the regular expressions is important. Consequently, to avoid possible clashing among similar patterns, consider sorting them from the most restrictive pattern to the less one. As a rule of thumb, the more captions it has the most restrictive a pattern is. - The cb2Bib proposed patterns are general, and not necessarily the most appropriate for a particular capture. E.g. tag pages becomes ([\\d|\\-|\\s]+), which considers digits, hyphens, and spaces. It must be modified accordingly for reference sources with, e.g., pages written as Roman ordinals. - Avoid whenever possible general patterns (.+). There is a risk that such a caption could include text intended for a posterior caption. This is why, sometimes, the cb2Bib proposed pattern is not hit by the input stream that originated it. Use, whenever possible, cb2Bib anchors like \ instead of \. They prevent (.+) captions to overextend. - To debug a large regular expression it might be useful to break it to the first capturing parenthesis. For instance, the above pattern will be \verbatim # cb2Bib GET_VERSION Pattern: American Chemical Society Publications article journal ^(.+), \endverbatim - Then, check if anything is captured and if this corresponds to journal. - Add on successive steps your set of captions and BibTeX fields. */ c2bSaveRegExp::c2bSaveRegExp(const QStringList& pattern, const QString& input, QWidget* parentw) : QDialog(parentw) { Q_ASSERT_X(pattern.count() == 3, "c2bSaveRegExp", "Expected exactly three strings for pattern"); ui.setupUi(this); setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint); connect(ui.buttonBox, SIGNAL(helpRequested()), this, SLOT(help())); c2bSettings* settings(c2bSettingsP); ui.Input->setFont(settings->c2bMonoFont); ui.Type->setText(pattern.at(0)); ui.Fields->setText(pattern.at(1)); ui.RegExp->setText(pattern.at(2)); ui.Name->setFocus(); updateInput(input); _pattern_rx.setMinimal(true); _sreS = new c2bSaveREHighlighter(_pattern_rx, ui.Input->document()); setInformation(); connect(ui.Type, SIGNAL(textChanged(QString)), this, SLOT(setInformation())); connect(ui.Fields, SIGNAL(textChanged(QString)), this, SLOT(setInformation())); connect(ui.RegExp, SIGNAL(textChanged(QString)), this, SLOT(setInformation())); connect(ui.Input, SIGNAL(textChanged()), this, SLOT(inputMightHaveChanged())); } c2bSaveRegExp::~c2bSaveRegExp() {} void c2bSaveRegExp::setInformation() { QString info; bool can_save(false); const QStringList field_list(ui.Fields->text().split(' ', QString::SkipEmptyParts)); const int fields(field_list.count()); _pattern_rx.setPattern(ui.RegExp->text()); const int captures(_pattern_rx.captureCount()); if (_pattern_rx.isValid() && fields > 0 && fields == captures && !ui.Type->text().isEmpty()) { info += tr("Reference type: %1\n").arg(ui.Type->text()); info += tr("Number of fields: %1\n").arg(fields); can_save = true; } else { if (ui.Type->text().isEmpty()) info += tr("[Error] Invalid pattern: empty reference type\n"); if (fields == 0) info += tr("[Error] Invalid pattern: no fields declared\n"); if (_pattern_rx.isValid()) { if (captures == 0) { if (_pattern_rx.pattern().isEmpty()) info += tr("[Error] Invalid pattern: empty regular expression\n"); else info += tr("[Error] Invalid pattern: no captures defined in the regular expression\n"); } else if (fields != captures) info += tr("[Error] Invalid pattern: declared %1 fields while the regular expression has %2 captures\n") .arg(fields) .arg(captures); } else info += tr("[Error] Invalid regular expression: %1\n").arg(_pattern_rx.errorString()); } if (can_save) { if (_pattern_rx.indexIn(ui.Input->toPlainText()) == -1 || _pattern_rx.matchedLength() < 1) info += tr("[Info] Regular expression does not match input text\n"); else { bibParser* bp = c2b::bibParser(); for (int i = 0; i < fields; ++i) { const QString& f = field_list.at(i); const QString v(bp->parse(f, _pattern_rx.cap(i + 1))); info += QString("[%1]: '%2'\n").arg(f, v); } } } ui.Information->setPlainText(info); ui.buttonBox->button(QDialogButtonBox::Save)->setEnabled(can_save); _sreS->rehighlight(); } void c2bSaveRegExp::updateInput(const QString& text) { if (!ui.Input->textCursor().hasSelection()) ui.Input->setPlainText(c2b::bibParser()->setTags(text)); } void c2bSaveRegExp::inputMightHaveChanged() { // Avoid recursively calling setInformation due to syntax highlighting if (_input_text == ui.Input->toPlainText()) return; _input_text = ui.Input->toPlainText(); setInformation(); } void c2bSaveRegExp::accept() { const QString rx(ui.Type->text() + '\n' + ui.Fields->text() + '\n' + ui.RegExp->text()); emit savePatternInfo(rx, ui.Name->text()); QDialog::accept(); } void c2bSaveRegExp::help() { c2bUtils::displayHelp("https://www.molspaces.com/cb2bib/doc/regexpeditor/"); } cb2bib-2.0.1/src/PaxHeaders.5700/c2bShortcutPushButton.h0000644000000000000000000000013214011522520017473 xustar0030 mtime=1613145424.558620342 30 atime=1613145424.830620334 30 ctime=1613145424.558620342 cb2bib-2.0.1/src/c2bShortcutPushButton.h0000644000175000001440000000253314011522520021075 0ustar00constansusers00000000000000/*************************************************************************** * Copyright (C) 2004-2021 by Pere Constans * constans@molspaces.com * cb2Bib version 2.0.1. Licensed under the GNU GPL version 3. * See the LICENSE file that comes with this distribution. ***************************************************************************/ #ifndef C2BSHORTCUTPUSHBUTTON_H #define C2BSHORTCUTPUSHBUTTON_H #include class c2bShortcutPushButton : public QPushButton { Q_OBJECT public: explicit inline c2bShortcutPushButton(QWidget* parentw = 0) : QPushButton(parentw) {} inline ~c2bShortcutPushButton() {} void setKeysequence(const QKeySequence& ks); void setDefaultKeysequence(const QKeySequence& ks) { _default_keysequence = ks; } inline QKeySequence keysequence() const { return _keysequence; } signals: void shortcutChanged(const QKeySequence& oldks, const QKeySequence& newks); public slots: void clear(); void reset(); protected: virtual void keyPressEvent(QKeyEvent* qevent); private: inline void _set_keysequence(const QKeySequence& ks) { const QKeySequence oldks(_keysequence); setKeysequence(ks); emit shortcutChanged(oldks, ks); } QKeySequence _default_keysequence; QKeySequence _keysequence; }; #endif cb2bib-2.0.1/src/PaxHeaders.5700/c2bUtils.h0000644000000000000000000000013214011522520014724 xustar0030 mtime=1613145424.566620341 30 atime=1613145424.830620334 30 ctime=1613145424.570620341 cb2bib-2.0.1/src/c2bUtils.h0000644000175000001440000000364214011522520016330 0ustar00constansusers00000000000000/*************************************************************************** * Copyright (C) 2004-2021 by Pere Constans * constans@molspaces.com * cb2Bib version 2.0.1. Licensed under the GNU GPL version 3. * See the LICENSE file that comes with this distribution. ***************************************************************************/ #ifndef C2BUTILS_H #define C2BUTILS_H #include #include "dialog.h" #include #include #include /** General cb2Bib Utils: GUI related utilities */ namespace c2bUtils { extern bool openFile(const QString& fn, QWidget* w = 0); inline void displayHelp(const QString& url) { openFile(url); } inline QUrl stringToUrl(const QString& fn) { // Avoid cross-platform pitfalls regarding string to url conversions // Avoid possible issues regarding QUrl and local files not starting with 'file://' if (QFileInfo::exists(fn)) return QUrl::fromLocalFile(fn); else return QUrl(fn, QUrl::TolerantMode); } inline QString fromHtmlString(const QString& str, const bool addMetadata = false) { QTextDocument converter; converter.setHtml(str); if (addMetadata) { const QString md(converter.metaInformation(QTextDocument::DocumentTitle).trimmed()); if (md.isEmpty()) return converter.toPlainText(); else return "Document Title: " + md + "\n\n" + converter.toPlainText(); } else return converter.toPlainText(); } inline void addSeparator(QWidget* w) { // Adds separator to widget w QAction* action = new QAction(w); action->setSeparator(true); w->addAction(action); } inline void setWidgetOnTop(QWidget* w) { if (w) { if (w->isHidden()) w->show(); if (w->isMinimized()) w->showNormal(); w->raise(); w->activateWindow(); } } } // namespace c2bUtils #endif cb2bib-2.0.1/src/PaxHeaders.5700/c2bClipEdit.h0000644000000000000000000000013214011522520015321 xustar0030 mtime=1613145424.506620343 30 atime=1613145424.830620334 30 ctime=1613145424.510620343 cb2bib-2.0.1/src/c2bClipEdit.h0000644000175000001440000000252714011522520016726 0ustar00constansusers00000000000000/*************************************************************************** * Copyright (C) 2004-2021 by Pere Constans * constans@molspaces.com * cb2Bib version 2.0.1. Licensed under the GNU GPL version 3. * See the LICENSE file that comes with this distribution. ***************************************************************************/ #ifndef C2BCLIPEDIT_H #define C2BCLIPEDIT_H #include /** @author Pere Constans */ class c2bClipEdit : public QPlainTextEdit { Q_OBJECT public: enum Mode { Editor, Browser }; explicit c2bClipEdit(const Mode mode, QWidget* parentw = 0); ~c2bClipEdit(); void setText(const QString& text, const QString& tagged_text = QString()); void setTaggedViewMode(bool tagged_view); void insertTag(const QString& tag); void updatePlainText(const QString& text); signals: void userEndedSelection(const QPoint& position); protected: virtual void contextMenuEvent(QContextMenuEvent* qevent); virtual void keyPressEvent(QKeyEvent* qevent); virtual void keyReleaseEvent(QKeyEvent* qevent); virtual void mouseReleaseEvent(QMouseEvent* qevent); private slots: virtual void selectionHasChanged(); private: QString _tagged_text; QString _text; bool _has_selecting_ended; bool _is_tagged_view; }; #endif cb2bib-2.0.1/src/PaxHeaders.5700/c2bReferenceList.cpp0000644000000000000000000000013214011522520016711 xustar0030 mtime=1613145424.438620345 30 atime=1613145424.826620334 30 ctime=1613145424.438620345 cb2bib-2.0.1/src/c2bReferenceList.cpp0000644000175000001440000006105514011522520020317 0ustar00constansusers00000000000000/*************************************************************************** * Copyright (C) 2004-2021 by Pere Constans * constans@molspaces.com * cb2Bib version 2.0.1. Licensed under the GNU GPL version 3. * See the LICENSE file that comes with this distribution. ***************************************************************************/ #include "c2bReferenceList.h" #include "c2b.h" #include "c2bBibParser.h" #include "c2bCoreCiter.h" #include "c2bRLWebSearchSettings.h" #include "c2bSettings.h" #include "c2bTextBrowser.h" #include "c2bTextEdit.h" #include "c2bUtils.h" #include #include #include #include #include class TreeWidgetItem : public QTreeWidgetItem { // Reimplement sorting public: explicit TreeWidgetItem(const QStringList& strings) : QTreeWidgetItem(strings) {} bool operator<(const QTreeWidgetItem& other) const { const int sortCol(treeWidget()->sortColumn()); const QString str(c2bUtils::toAscii(text(sortCol), c2bUtils::Collation)); const QString other_str(c2bUtils::toAscii(other.text(sortCol), c2bUtils::Collation)); return str < other_str; } }; c2bReferenceList::c2bReferenceList(c2bTextEdit* ed, c2bTextBrowser* br, QWidget* parentw) : QWidget(parentw) { ui.setupUi(this); _editorP = ed; _browserP = br; _citerP = new c2bCoreCiter(this); _settingsP = c2bSettingsP; _settingsP->setDefaultValue("c2bReferenceList/SearchEngine", "https://www.google.com/search?ie=UTF-8&q="); _settingsP->setDefaultValue("c2bReferenceList/SearchEngineAddQuotes", false); setupFilterBar(); _key_index = 0; _id_index = 1; _year_index = 2; _journal_index = 3; _author_index = 4; _title_index = 5; QStringList header; header.append(tr("Key")); header.append(tr("ID")); header.append(tr("Year")); header.append(tr("Journal")); header.append(tr("Author")); header.append(tr("Title")); ui.listView->sortItems(_key_index, Qt::AscendingOrder); ui.listView->setHeaderLabels(header); ui.listView->hideColumn(_id_index); ui.listView->setContextMenuPolicy(Qt::ActionsContextMenu); citeEntryAction = new QAction(this); citeEntryAction->setText(tr("Cite Selected Entries")); _settingsP->setKeysequence("Shortcuts/Editor/", citeEntryAction); connect(citeEntryAction, SIGNAL(triggered()), this, SLOT(citeEntry())); ui.listView->addAction(citeEntryAction); c2bUtils::addSeparator(ui.listView); openFileAction = new QAction(this); openFileAction->setText(tr("Open Document File")); openFileAction->setStatusTip(tr("Open document file")); _settingsP->setKeysequence("Shortcuts/Editor/", openFileAction); connect(openFileAction, SIGNAL(triggered()), this, SLOT(openFile())); ui.listView->addAction(openFileAction); openUrlAction = new QAction(this); openUrlAction->setText(tr("Open Document URL")); openUrlAction->setStatusTip(tr("Open document URL")); _settingsP->setKeysequence("Shortcuts/Editor/", openUrlAction); connect(openUrlAction, SIGNAL(triggered()), this, SLOT(openUrl())); ui.listView->addAction(openUrlAction); openDOIAction = new QAction(this); openDOIAction->setText(tr("Browse Reference by DOI")); openDOIAction->setStatusTip(tr("Browse reference by DOI")); _settingsP->setKeysequence("Shortcuts/Editor/", openDOIAction); connect(openDOIAction, SIGNAL(triggered()), this, SLOT(openDOI())); ui.listView->addAction(openDOIAction); c2bUtils::addSeparator(ui.listView); openAuthorsWebSearchAction = new QAction(this); openAuthorsWebSearchAction->setText(tr("Web Search by Author")); openAuthorsWebSearchAction->setStatusTip(tr("Web search by Author")); _settingsP->setKeysequence("Shortcuts/Editor/", openAuthorsWebSearchAction); connect(openAuthorsWebSearchAction, SIGNAL(triggered()), this, SLOT(openAuthorWebSearch())); ui.listView->addAction(openAuthorsWebSearchAction); openTitleWebSearchAction = new QAction(this); openTitleWebSearchAction->setText(tr("Web Search by Title")); openTitleWebSearchAction->setStatusTip(tr("Web search by Title")); _settingsP->setKeysequence("Shortcuts/Editor/", openTitleWebSearchAction); connect(openTitleWebSearchAction, SIGNAL(triggered()), this, SLOT(openTitleWebSearch())); ui.listView->addAction(openTitleWebSearchAction); c2bUtils::addSeparator(ui.listView); webSearchSettingsAction = new QAction(this); webSearchSettingsAction->setText(tr("Web Search Settings")); webSearchSettingsAction->setStatusTip(tr("Web search settings")); _settingsP->setKeysequence("Shortcuts/Editor/", webSearchSettingsAction); connect(webSearchSettingsAction, SIGNAL(triggered()), this, SLOT(webSearchSettings())); ui.listView->addAction(webSearchSettingsAction); c2bUtils::addSeparator(ui.listView); clearSelectionsAction = new QAction(this); clearSelectionsAction->setText(tr("Clear Entry Selection")); clearSelectionsAction->setStatusTip(tr("Clear entry selection")); _settingsP->setKeysequence("Shortcuts/Editor/", clearSelectionsAction); connect(clearSelectionsAction, SIGNAL(triggered()), this, SLOT(clearSelections())); ui.listView->addAction(clearSelectionsAction); c2bUtils::addSeparator(ui.listView); refreshListAction = new QAction(this); refreshListAction->setShortcut(QKeySequence(QKeySequence::Refresh)); refreshListAction->setText(tr("Refresh List and Browser")); refreshListAction->setStatusTip(tr("Refresh list and browser")); connect(refreshListAction, SIGNAL(triggered()), this, SLOT(refreshList())); ui.listView->addAction(refreshListAction); connect(ui.listView, SIGNAL(itemActivated(QTreeWidgetItem*,int)), this, SLOT(goToReference(QTreeWidgetItem*))); // Actions dependent on selection and availability itemSelectionChanged(); connect(ui.listView, SIGNAL(itemSelectionChanged()), this, SLOT(itemSelectionChanged())); // Browser functionality _references_html = c2bUtils::fileToString(":/htm/htm/references.html"); _references_html.replace("GET_CB2BIB_VERSION_NUMBER", C2B_VERSION); _bib_item_html = c2bUtils::fileToString(":/htm/htm/bib_item.html"); QString references_css(c2bUtils::fileToString(_settingsP->fileName("cb2Bib/BrowserCssFile"))); if (references_css.isEmpty()) references_css = c2bUtils::fileToString(":/htm/htm/references.css"); _browserP->document()->setDefaultStyleSheet(references_css); openTextLocalSearchAction = new QAction(this); openTextLocalSearchAction->setText(tr("Local Search for Selected Text")); openTextLocalSearchAction->setStatusTip(tr("Local search for selected text")); _settingsP->setKeysequence("Shortcuts/Editor/", openTextLocalSearchAction); connect(openTextLocalSearchAction, SIGNAL(triggered()), this, SLOT(openTextLocalSearch())); openTextLocalSearchAction->setEnabled(false); connect(_browserP, SIGNAL(copyAvailable(bool)), openTextLocalSearchAction, SLOT(setEnabled(bool))); openTextWebSearchAction = new QAction(this); openTextWebSearchAction->setText(tr("Web Search for Selected Text")); openTextWebSearchAction->setStatusTip(tr("Web search for selected text")); _settingsP->setKeysequence("Shortcuts/Editor/", openTextWebSearchAction); connect(openTextWebSearchAction, SIGNAL(triggered()), this, SLOT(openTextWebSearch())); openTextWebSearchAction->setEnabled(false); connect(_browserP, SIGNAL(copyAvailable(bool)), openTextWebSearchAction, SLOT(setEnabled(bool))); QList al = ui.listView->actions(); for (int i = 0; i < 2; ++i) _browserP->addAction(al.at(i)); _browserP->addAction(openTextLocalSearchAction); _browserP->addAction(openTextWebSearchAction); c2bUtils::addSeparator(_browserP); for (int i = 6; i < al.count(); ++i) _browserP->addAction(al.at(i)); _browserP->setContextMenuPolicy(Qt::ActionsContextMenu); connect(_browserP, SIGNAL(anchorClicked(QUrl)), this, SLOT(openLink(QUrl))); connect(_browserP, SIGNAL(highlighted(QString)), parentw->parent(), SLOT(showMessage(QString))); } c2bReferenceList::~c2bReferenceList() {} void c2bReferenceList::loadList(const QString& txt, bibSearcher* searcher) { QApplication::setOverrideCursor(QCursor(Qt::WaitCursor)); c2bBibParser* bpP(c2b::bibParser()); QString references_html(_references_html); QString references; QStringList fields; fields.append("abstract"); fields.append("author"); fields.append("booktitle"); fields.append("doi"); fields.append("editor"); fields.append("file"); fields.append("journal"); fields.append("pages"); fields.append("title"); fields.append("url"); fields.append("volume"); fields.append("year"); bibReference ref; bpP->initReferenceParsing(_editorP->editorFilename(), fields, &ref); const QRegExp initials1("\\b\\w\\b"); const QRegExp initials2("[^\\w\\s]"); const QRegExp nonletters("[^\\w\\s-]"); int ref_counter(0); while (bpP->referencesIn(txt, &ref)) { QString author(ref.anyAuthor()); QString author_long; if (!author.isEmpty()) { author = bpP->authorFromBibTeX(author); author_long = author; author_long.remove(nonletters); author_long.replace(" and ", ", "); c2bUtils::simplifyString(author_long); author_long += '.'; author.remove(initials1); author.remove(initials2); author.replace(" and ", ", "); c2bUtils::simplifyString(author); } QString title(ref.anyTitle()); c2bUtils::cleanTitle(title, true); QString doi(ref.value("doi")); if (!doi.isEmpty()) if (!doi.startsWith("http")) doi = "https://dx.doi.org/" + QUrl::toPercentEncoding(doi); const QString file(ref.value("file")); const QString url(ref.value("url")); QString link; if (!file.isEmpty()) link = QDir::cleanPath(file); else if (!url.isEmpty()) link = url; else if (!doi.isEmpty()) link = doi; QString ID; ID.setNum(ref_counter + 1); QString year(ref.value("year")); const QString abstract(ref.value("abstract")); const QString journal(ref.anyJournal()); const QString key(ref.citeidName); _doiList.append(doi); _fileList.append(file); _urlList.append(url); _positionList.append(ref.positionValue); QStringList dataList; dataList.append(key); dataList.append(ID); dataList.append(year); dataList.append(journal); dataList.append(author); dataList.append(title); TreeWidgetItem* qi(new TreeWidgetItem(dataList)); qi->setStatusTip(_journal_index, bpP->fullJournal(journal)); qi->setStatusTip(_author_index, author_long); qi->setStatusTip(_title_index, title); ui.listView->insertTopLevelItem(0, qi); QString pages(ref.value("pages")); const QString volume(ref.value("volume")); if (!pages.isEmpty()) { if (!volume.isEmpty()) pages = ", " + pages; else pages = ' ' + pages; } if (!year.isEmpty()) year = '(' + year + ")."; QString bib_item_html(_bib_item_html); bib_item_html.replace("GET_REFERENCE_ANCHOR_ID", ID); bib_item_html.replace("GET_REFERENCE_ANCHOR_NAME", ID); bib_item_html.replace("GET_REFERENCE_AUTHOR", author_long); bib_item_html.replace("GET_REFERENCE_LINK", link); bib_item_html.replace("GET_REFERENCE_PAGES", pages); bib_item_html.replace("GET_REFERENCE_SOURCE", journal); bib_item_html.replace("GET_REFERENCE_TITLE", c2bUtils::toHtmlString(title)); bib_item_html.replace("GET_REFERENCE_VOLUME", volume); bib_item_html.replace("GET_REFERENCE_YEAR", year); if (searcher) { if (searcher->isSearchSimilar()) bib_item_html.replace("GET_REFERENCE_ABSTRACT", c2bUtils::toHtmlString(abstract) + searcher->hitHtmlDatum(ref_counter)); else bib_item_html.replace("GET_REFERENCE_ABSTRACT", searcher->hitHtmlAbstract(ref_counter) + searcher->hitHtmlDatum(ref_counter)); } else bib_item_html.replace("GET_REFERENCE_ABSTRACT", c2bUtils::toHtmlString(abstract)); references += bib_item_html; ++ref_counter; } if (searcher && ref_counter != searcher->hitsCount()) c2bUtils::warn(tr("Mismatch while loading searched references")); ui.listView->sortItems(ui.listView->sortColumn(), ui.listView->header()->sortIndicatorOrder()); ui.listView->resizeColumnToContents(_year_index); references_html.replace("GET_REFERENCES", references); _browserP->updateHtml(references_html); QApplication::restoreOverrideCursor(); c2b::showMessage(tr("Parsed %1 references.").arg(ref_counter)); } void c2bReferenceList::citeEntry() { QStringList keys; QTreeWidgetItemIterator it(ui.listView, QTreeWidgetItemIterator::Selected | QTreeWidgetItemIterator::NotHidden); while (*it) { if (!(*it)->text(_key_index).isEmpty()) keys.append((*it)->text(_key_index)); ++it; } _citerP->cite(keys); } void c2bReferenceList::openDOI() { bool zdoi(false); QTreeWidgetItemIterator it(ui.listView, QTreeWidgetItemIterator::Selected | QTreeWidgetItemIterator::NotHidden); while (*it) { const QString doi(_doiList.at((*it)->text(_id_index).toInt() - 1)); if (!doi.isEmpty()) { zdoi = true; c2bUtils::openFile(doi, parentWidget()); } ++it; } if (!zdoi) c2b::showMessage(tr("No DOI entry among selected references.")); } void c2bReferenceList::openFile() { bool zfile(false); QTreeWidgetItemIterator it(ui.listView, QTreeWidgetItemIterator::Selected | QTreeWidgetItemIterator::NotHidden); while (*it) { const QString file(_fileList.at((*it)->text(_id_index).toInt() - 1)); if (!file.isEmpty()) { zfile = true; c2bUtils::openFile(file, parentWidget()); } ++it; } if (!zfile) c2b::showMessage(tr("No file entry among selected references.")); } void c2bReferenceList::openUrl() { bool zurl(false); QTreeWidgetItemIterator it(ui.listView, QTreeWidgetItemIterator::Selected | QTreeWidgetItemIterator::NotHidden); while (*it) { const QString url(_urlList.at((*it)->text(_id_index).toInt() - 1)); if (!url.isEmpty()) { zurl = true; c2bUtils::openFile(url, parentWidget()); } ++it; } if (!zurl) c2b::showMessage(tr("No URL entry among selected references.")); } void c2bReferenceList::openLink(const QUrl& ln) { QString ln_str(QUrl::fromPercentEncoding(ln.toEncoded())); if (ln_str.isEmpty()) c2b::showMessage(tr("No link available for this reference.")); else if (ln_str.startsWith("Select reference ")) scrollToReference(ln_str.remove(QRegExp("\\D"))); else if (ln_str.contains(QRegExp(":\\d+$"))) emit openFile(ln_str); else c2bUtils::openFile(ln_str, parentWidget()); } void c2bReferenceList::openAuthorWebSearch() { const QString searchEngine(_settingsP->value("c2bReferenceList/SearchEngine").toString()); bool zwebs(false); QTreeWidgetItemIterator it(ui.listView, QTreeWidgetItemIterator::Selected | QTreeWidgetItemIterator::NotHidden); while (*it) { if (!(*it)->text(_author_index).isEmpty()) { zwebs = true; QString webs((*it)->text(_author_index)); webs.remove(','); webs = searchEngine + webs.simplified(); c2bUtils::openFile(webs, parentWidget()); } ++it; } if (!zwebs) c2b::showMessage(tr("No author entry among selected references.")); } void c2bReferenceList::openTitleWebSearch() { const QString searchEngine(_settingsP->value("c2bReferenceList/SearchEngine").toString()); const bool addQuotes(_settingsP->value("c2bReferenceList/SearchEngineAddQuotes").toBool()); bool zwebs(false); QTreeWidgetItemIterator it(ui.listView, QTreeWidgetItemIterator::Selected | QTreeWidgetItemIterator::NotHidden); while (*it) { if (!(*it)->text(_title_index).isEmpty()) { zwebs = true; QString webs((*it)->text(_title_index)); if (addQuotes) webs = '\"' + webs + '\"'; webs = searchEngine + webs; c2bUtils::openFile(webs, parentWidget()); } ++it; } if (!zwebs) c2b::showMessage(tr("No title entry among selected references.")); } void c2bReferenceList::openTextWebSearch() { const QString searchEngine(_settingsP->value("c2bReferenceList/SearchEngine").toString()); QString webs(_browserP->textCursor().selectedText()); if (_settingsP->value("c2bReferenceList/SearchEngineAddQuotes").toBool()) webs = '\"' + webs + '\"'; webs = searchEngine + webs; c2bUtils::openFile(webs, parentWidget()); } void c2bReferenceList::webSearchSettings() { c2bRLWebSearchSettings searchSettings(this); searchSettings.exec(); } void c2bReferenceList::openTextLocalSearch() { const QString text(_browserP->textCursor().selectedText()); const QString fn(_editorP->editorFilename()); c2b::doSearchInFiles(text, fn); } void c2bReferenceList::refreshList() { _doiList.clear(); _fileList.clear(); _urlList.clear(); _positionList.clear(); ui.listView->clear(); ui.comboFilter->clearEditText(); loadList(_editorP->toPlainText()); } void c2bReferenceList::goToReference(const QString& id) { QTextCursor tc(_editorP->textCursor()); tc.setPosition(_positionList.at(id.toInt() - 1)); _editorP->setTextCursor(tc); _editorP->verticalScrollBar()->setValue(_editorP->verticalScrollBar()->maximum()); _editorP->ensureCursorVisible(); _browserP->scrollToAnchor(id); int scrollPosition(_browserP->verticalScrollBar()->value()); _browserP->verticalScrollBar()->setValue(scrollPosition - 10); } void c2bReferenceList::goToReference(const int position) { // Maps position to internal reference id. It is needed by the search browser, when a // citation is edited in the original file. If this file is changed multiple times, // positions in the search browser get outdated, so the mapping position-id is inexact. // Thus, search for the closest reference. int ip(0); int pdiff_min(1000000); for (int i = 0; i < _positionList.count(); ++i) { int p(_positionList.at(i)); if (p == position) { ip = i; break; } int pdiff(abs(p - position)); if (pdiff < pdiff_min) { pdiff_min = pdiff; ip = i; } } QString id; goToReference(id.setNum(ip + 1)); } void c2bReferenceList::goToReference(QTreeWidgetItem* ref) { if (ref == 0) return; const QString id(ref->text(_id_index)); goToReference(id); } void c2bReferenceList::scrollToReference(const QString& id) { if (id.isEmpty()) return; QList items(ui.listView->findItems(id, Qt::MatchExactly, 1)); if (items.count() == 0) return; QTreeWidgetItem* item(items.at(0)); ui.listView->setFocus(); item->setSelected(!item->isSelected()); ui.listView->scrollToItem(item); QTextCursor tc(_editorP->textCursor()); tc.setPosition(_positionList.at(id.toInt() - 1)); _editorP->setTextCursor(tc); _editorP->verticalScrollBar()->setValue(_editorP->verticalScrollBar()->maximum()); _editorP->ensureCursorVisible(); } void c2bReferenceList::clearSelections() { disconnect(ui.listView, SIGNAL(itemSelectionChanged()), this, SLOT(itemSelectionChanged())); QTreeWidgetItemIterator it(ui.listView, QTreeWidgetItemIterator::Selected); while (*it) { (*it)->setSelected(false); ++it; } itemSelectionChanged(); connect(ui.listView, SIGNAL(itemSelectionChanged()), this, SLOT(itemSelectionChanged())); } void c2bReferenceList::itemSelectionChanged() { int entries(0); int doi(0); int file(0); int url(0); int author(0); int title(0); QTreeWidgetItemIterator it(ui.listView, QTreeWidgetItemIterator::Selected | QTreeWidgetItemIterator::NotHidden); while (*it) { if (!_doiList.at((*it)->text(_id_index).toInt() - 1).isEmpty()) ++doi; if (!_fileList.at((*it)->text(_id_index).toInt() - 1).isEmpty()) ++file; if (!_urlList.at((*it)->text(_id_index).toInt() - 1).isEmpty()) ++url; if (!(*it)->text(_author_index).isEmpty()) ++author; if (!(*it)->text(_title_index).isEmpty()) ++title; ++entries; ++it; } citeEntryAction->setEnabled(entries > 0); citeEntryAction->setStatusTip(tr("Cite selected entries. %1 Entries selected.").arg(entries)); openDOIAction->setEnabled(doi > 0); openDOIAction->setStatusTip(tr("Browse reference by DOI. %1 DOIs in selected entries.").arg(doi)); openFileAction->setEnabled(file > 0); openFileAction->setStatusTip(tr("Open document file. %1 Files in selected entries.").arg(file)); openUrlAction->setEnabled(url > 0); openUrlAction->setStatusTip(tr("Open document URL. %1 URLs in selected entries.").arg(url)); openAuthorsWebSearchAction->setEnabled(author > 0); openAuthorsWebSearchAction->setStatusTip(tr("Web search by Author. %1 Entries selected.").arg(author)); openTitleWebSearchAction->setEnabled(title > 0); openTitleWebSearchAction->setStatusTip(tr("Web search by Title. %1 Entries selected.").arg(title)); emit hasSelectedItems(entries > 0); } QStringList c2bReferenceList::selectedKeys() const { QStringList keys; QTreeWidgetItemIterator it(ui.listView, QTreeWidgetItemIterator::Selected | QTreeWidgetItemIterator::NotHidden); while (*it) { if (!(*it)->text(_key_index).isEmpty()) keys.append((*it)->text(_key_index)); ++it; } return keys; } void c2bReferenceList::setLyXPipe() { _citerP->setLyXPipe(); } /*************************************************************************** Filter Bar ***************************************************************************/ void c2bReferenceList::setupFilterBar() { const QStringList types(searchPattern::types()); _filter_mode = _settingsP->value("c2bReferenceList/FilterMode", types.first()).toString(); QActionGroup* filterMode = new QActionGroup(this); filterMode->setExclusive(true); for (int i = 0; i < types.count(); ++i) { const QString& t = types.at(i); QAction* act = filterMode->addAction(t); act->setCheckable(true); if (_filter_mode == t) act->setChecked(true); } QMenu* filterModeM = new QMenu(this); filterModeM->addActions(filterMode->actions()); ui.filterB->setMenu(filterModeM); connect(filterMode, SIGNAL(triggered(QAction*)), this, SLOT(setFilterMode(QAction*))); connect(ui.comboFilter, SIGNAL(editTextChanged(QString)), this, SLOT(blockFilterSignals())); } void c2bReferenceList::setFilterMode(QAction* mode) { _filter_mode = mode->text(); _settingsP->setValue("c2bReferenceList/FilterMode", _filter_mode); filterList(); } void c2bReferenceList::blockFilterSignals() { ui.comboFilter->blockSignals(true); QTimer::singleShot(500, this, SLOT(filterList())); } void c2bReferenceList::filterList() { const QString text(ui.comboFilter->currentText()); if (text.isEmpty()) { QTreeWidgetItemIterator it(ui.listView); while (*it) { (*it)->setHidden(false); ++it; } } else { searchPattern pattern(text, _filter_mode); QTreeWidgetItemIterator it(ui.listView); while (*it) { QTreeWidgetItem* item = *it; if (pattern.matches(item->text(_author_index)) || pattern.matches(item->text(_title_index))) item->setHidden(false); else item->setHidden(true); ++it; } QTimer::singleShot(5000, this, SLOT(keepFilterPattern())); } itemSelectionChanged(); ui.comboFilter->blockSignals(false); } void c2bReferenceList::keepFilterPattern() { const QString text(ui.comboFilter->currentText()); if (!text.isEmpty()) if (ui.comboFilter->findText(text) < 0) ui.comboFilter->addItem(text); } cb2bib-2.0.1/src/PaxHeaders.5700/c2bConfigureFR.h0000644000000000000000000000013214011522520015775 xustar0030 mtime=1613145424.514620343 30 atime=1613145424.830620334 30 ctime=1613145424.518620343 cb2bib-2.0.1/src/c2bConfigureFR.h0000644000175000001440000000142314011522520017374 0ustar00constansusers00000000000000/*************************************************************************** * Copyright (C) 2004-2021 by Pere Constans * constans@molspaces.com * cb2Bib version 2.0.1. Licensed under the GNU GPL version 3. * See the LICENSE file that comes with this distribution. ***************************************************************************/ #ifndef C2BCONFIGUREFR_H #define C2BCONFIGUREFR_H #include "ui_c2bConfigureFR.h" #include class QTreeWidgetItem; class c2bConfigureFR : public QDialog { Q_OBJECT public: explicit c2bConfigureFR(QTreeWidgetItem* item, QWidget* parentw = 0); ~c2bConfigureFR(); private: QTreeWidgetItem* itemFindReplace; Ui::c2bConfigureFR ui; protected slots: void accept(); void reject(); }; #endif cb2bib-2.0.1/src/PaxHeaders.5700/c2bRLWebSearchSettings.h0000644000000000000000000000013214011522520017446 xustar0030 mtime=1613145424.546620342 30 atime=1613145424.830620334 30 ctime=1613145424.546620342 cb2bib-2.0.1/src/c2bRLWebSearchSettings.h0000644000175000001440000000134214011522520021045 0ustar00constansusers00000000000000/*************************************************************************** * Copyright (C) 2004-2021 by Pere Constans * constans@molspaces.com * cb2Bib version 2.0.1. Licensed under the GNU GPL version 3. * See the LICENSE file that comes with this distribution. ***************************************************************************/ #ifndef C2BRLWEBSEARCHSETTINGS_H #define C2BRLWEBSEARCHSETTINGS_H #include "ui_c2bRLWebSearchSettings.h" #include class c2bRLWebSearchSettings : public QDialog { Q_OBJECT public: explicit c2bRLWebSearchSettings(QWidget* parentw = 0); ~c2bRLWebSearchSettings(); private: Ui::c2bRLWebSearchSettings ui; protected slots: void accept(); }; #endif cb2bib-2.0.1/src/PaxHeaders.5700/c2bHighlighter.h0000644000000000000000000000013214011522520016062 xustar0030 mtime=1613145424.530620342 30 atime=1613145424.830620334 30 ctime=1613145424.530620342 cb2bib-2.0.1/src/c2bHighlighter.h0000644000175000001440000000200614011522520017457 0ustar00constansusers00000000000000/*************************************************************************** * Copyright (C) 2004-2021 by Pere Constans * constans@molspaces.com * cb2Bib version 2.0.1. Licensed under the GNU GPL version 3. * See the LICENSE file that comes with this distribution. ***************************************************************************/ #ifndef C2BHIGHLIGHTER_H #define C2BHIGHLIGHTER_H #include /** clipboard SyntaxHighLighter @author Pere Constans */ class c2bColors; class c2bHighlighter : public QSyntaxHighlighter { public: explicit c2bHighlighter(QTextDocument* doc); ~c2bHighlighter(); protected: virtual void highlightBlock(const QString& text); private: QColor text_color; QRegExp rx0; QRegExp rx1; QRegExp rx2; QRegExp rx3; QRegExp rx4; QRegExp rx5; QRegExp rx6; QRegExp rx_extracted_ends; QRegExp rx_extracted_starts; QRegExp rx_metadata_ends; QRegExp rx_metadata_starts; c2bColors* c; }; #endif cb2bib-2.0.1/src/PaxHeaders.5700/c2bConfigureFR.ui0000644000000000000000000000007414011522151016170 xustar0030 atime=1613145424.830620334 30 ctime=1613145424.302620349 cb2bib-2.0.1/src/c2bConfigureFR.ui0000644000175000001440000001027014011522151017562 0ustar00constansusers00000000000000 Pere Constans c2bConfigureFR 0 0 666 151 0 0 Edit Find-Replace - cb2Bib 6 6 Qt::LeftToRight true Qt::Horizontal QDialogButtonBox::Cancel|QDialogButtonBox::Ok false Qt::Horizontal QSizePolicy::Expanding 271 20 QFrame::HLine QFrame::Sunken Qt::Horizontal 0 6 Description: Find: Replace: c2bLineEdit QLineEdit
    c2bLineEdit.h
    lineEditFind lineEditReplace lineEditDescription buttonBox rejected() c2bConfigureFR reject() 637 119 104 117 buttonBox accepted() c2bConfigureFR accept() 558 122 24 118
    cb2bib-2.0.1/src/PaxHeaders.5700/c2bExport.h0000644000000000000000000000013214011522520015105 xustar0030 mtime=1613145424.522620343 30 atime=1613145424.830620334 30 ctime=1613145424.522620343 cb2bib-2.0.1/src/c2bExport.h0000644000175000001440000000154014011522520016504 0ustar00constansusers00000000000000/*************************************************************************** * Copyright (C) 2004-2021 by Pere Constans * constans@molspaces.com * cb2Bib version 2.0.1. Licensed under the GNU GPL version 3. * See the LICENSE file that comes with this distribution. ***************************************************************************/ #ifndef C2BEXPORT_H #define C2BEXPORT_H #include #include class c2bExport : public QObject { Q_OBJECT public: explicit c2bExport(QObject* parento = 0); ~c2bExport(); struct export_data { QString bibtex_contents; QString bibtex_fn; QString documents_dir; QString export_fn; QStringList bibtex_keys; bool copy_documents; bool relative_dir; }; void exportEntries(const export_data& ed); }; #endif cb2bib-2.0.1/src/PaxHeaders.5700/c2bBibPreparserLog.h0000644000000000000000000000013214011522520016646 xustar0030 mtime=1613145424.486620344 30 atime=1613145424.826620334 30 ctime=1613145424.486620344 cb2bib-2.0.1/src/c2bBibPreparserLog.h0000644000175000001440000000153514011522520020251 0ustar00constansusers00000000000000/*************************************************************************** * Copyright (C) 2004-2021 by Pere Constans * constans@molspaces.com * cb2Bib version 2.0.1. Licensed under the GNU GPL version 3. * See the LICENSE file that comes with this distribution. ***************************************************************************/ #ifndef C2BBIBPREPARSERLOG_H #define C2BBIBPREPARSERLOG_H #include "ui_c2bLogWidget.h" #include class QCheckBox; class c2bBibPreparserLog : public QDialog { Q_OBJECT public: explicit c2bBibPreparserLog(QWidget* parentw = 0); ~c2bBibPreparserLog(); void append(const QString& ms); public slots: void show(); protected slots: void help(); private: QCheckBox* PreparserShowLog; Ui::c2bLogWidget ui; void closeEvent(QCloseEvent* qevent); }; #endif cb2bib-2.0.1/src/PaxHeaders.5700/c2bSaveRegExp.h0000644000000000000000000000013214011522520015635 xustar0030 mtime=1613145424.546620342 30 atime=1613145424.830620334 30 ctime=1613145424.550620342 cb2bib-2.0.1/src/c2bSaveRegExp.h0000644000175000001440000000202314011522520017231 0ustar00constansusers00000000000000/*************************************************************************** * Copyright (C) 2004-2021 by Pere Constans * constans@molspaces.com * cb2Bib version 2.0.1. Licensed under the GNU GPL version 3. * See the LICENSE file that comes with this distribution. ***************************************************************************/ #ifndef C2BSAVEREGEXP_H #define C2BSAVEREGEXP_H #include "ui_c2bSaveRegExp.h" #include class c2bSaveREHighlighter; class c2bSaveRegExp : public QDialog { Q_OBJECT public: c2bSaveRegExp(const QStringList& pattern, const QString& input, QWidget* parentw = 0); ~c2bSaveRegExp(); signals: void savePatternInfo(const QString& rx, const QString& rxname); public slots: void accept(); void help(); void updateInput(const QString& text); private: QRegExp _pattern_rx; QString _input_text; Ui::c2bSaveRegExp ui; c2bSaveREHighlighter* _sreS; private slots: void inputMightHaveChanged(); void setInformation(); }; #endif cb2bib-2.0.1/src/PaxHeaders.5700/c2bSearchInFilesPattern.cpp0000644000000000000000000000013214011522520020174 xustar0030 mtime=1613145424.450620345 30 atime=1613145424.830620334 30 ctime=1613145424.450620345 cb2bib-2.0.1/src/c2bSearchInFilesPattern.cpp0000644000175000001440000000702714011522520021601 0ustar00constansusers00000000000000/*************************************************************************** * Copyright (C) 2004-2021 by Pere Constans * constans@molspaces.com * cb2Bib version 2.0.1. Licensed under the GNU GPL version 3. * See the LICENSE file that comes with this distribution. ***************************************************************************/ #include "c2bSearchInFilesPattern.h" #include "c2b.h" #include "c2bBibParser.h" #include "c2bSettings.h" #include #include c2bSearchInFilesPattern::c2bSearchInFilesPattern(QWidget* parentw) : QWidget(parentw) { ui.setupUi(this); c2bBibParser* bp = c2b::bibParser(); ui.patternType->addItems(searchPattern::types()); ui.patternType->setCurrentIndex(c2bSettingsP->value("c2bSearchInFiles/PatternTypeIndex", 0).toInt()); ui.patternScope->addItems(bp->sortedBibliographicFields()); ui.yearScope->hide(); ui.inputPattern->setFocus(); connect(ui.clearB, SIGNAL(clicked()), this, SLOT(patternChanged())); connect(ui.inputPattern, SIGNAL(textEdited(QString)), this, SLOT(patternChanged())); connect(ui.patternScope, SIGNAL(currentIndexChanged(QString)), this, SLOT(showYearScope(QString))); } c2bSearchInFilesPattern::~c2bSearchInFilesPattern() { c2bSettingsP->setValue("c2bSearchInFiles/PatternTypeIndex", ui.patternType->currentIndex()); } void c2bSearchInFilesPattern::patternChanged() { emit patternAvailable(isAvailable()); } void c2bSearchInFilesPattern::setText(const QString& text) { ui.inputPattern->setText(text); ui.inputPattern->setFocus(); } void c2bSearchInFilesPattern::clear() { ui.inputPattern->clear(); ui.inputPattern->setFocus(); } void c2bSearchInFilesPattern::setPattern(QTreeWidgetItem* pattern) { if (!pattern) return; if (pattern->columnCount() != ITEMS_IN_SEARCH_PATTERN) return; if (pattern->text(0) == "NOT") ui.NOT->setChecked(true); else ui.NOT->setChecked(false); if (pattern->text(1) == "Sensitive") ui.caseSensitive->setChecked(true); else ui.caseSensitive->setChecked(false); ui.patternType->setCurrentIndex(ui.patternType->findText(pattern->text(2))); ui.patternScope->setCurrentIndex(ui.patternScope->findText(pattern->text(3))); if (pattern->text(4) == "=") ui.yearScope->setCurrentIndex(ui.yearScope->findText("Exact")); else if (pattern->text(4) == ">") ui.yearScope->setCurrentIndex(ui.yearScope->findText("Newer")); else ui.yearScope->setCurrentIndex(ui.yearScope->findText("Older")); ui.inputPattern->setText(pattern->text(5)); } const QStringList c2bSearchInFilesPattern::patterns() { QStringList p; if (ui.NOT->isChecked()) p.append("NOT"); else p.append(QString()); if (ui.caseSensitive->isChecked()) p.append("Sensitive"); else p.append("Insensitive"); p.append(ui.patternType->currentText()); p.append(ui.patternScope->currentText()); if (ui.yearScope->isHidden()) p.append(" "); else if (ui.yearScope->currentText() == "Exact") p.append("="); else if (ui.yearScope->currentText() == "Newer") p.append(">"); else if (ui.yearScope->currentText() == "Older") p.append("<"); p.append(ui.inputPattern->text()); return p; } void c2bSearchInFilesPattern::showYearScope(const QString& scope) { if (scope == "year") ui.yearScope->show(); else ui.yearScope->hide(); } void c2bSearchInFilesPattern::setFocus() { ui.inputPattern->setFocus(); } cb2bib-2.0.1/src/PaxHeaders.5700/c2bEditor.h0000644000000000000000000000013214011522520015052 xustar0030 mtime=1613145424.518620343 30 atime=1613145424.830620334 30 ctime=1613145424.522620343 cb2bib-2.0.1/src/c2bEditor.h0000644000175000001440000000556514011522520016464 0ustar00constansusers00000000000000/*************************************************************************** * Copyright (C) 2004-2021 by Pere Constans * constans@molspaces.com * cb2Bib version 2.0.1. Licensed under the GNU GPL version 3. * See the LICENSE file that comes with this distribution. ***************************************************************************/ #ifndef C2BEDITOR_H #define C2BEDITOR_H #include "ui_c2bEditor.h" #include #include class QDockWidget; class QLabel; class QStackedWidget; class QSyntaxHighlighter; class bibSearcher; class c2bBibParser; class c2bReferenceList; class c2bSettings; class c2bTextBrowser; class c2bTextEdit; class findDialog; class c2bEditor : public QMainWindow { Q_OBJECT public: enum Mode { Annote, BibTeX, JAbbrev, NetQInfo, RegExp }; c2bEditor(const QString& file, const Mode mode, QWidget* main, QWidget* parentw = 0); c2bEditor(const QString& file, bibSearcher* searcher, QWidget* main, QWidget* parentw = 0); ~c2bEditor(); inline QString editorFilename() const { return _editor_fn; } bool closeEditor(); signals: void editFileRenamed(const QString& old_name, const QString& new_name); void execute(); void openBookmarks(); void openFile(const QString& fn); void restartEngine(); void restartQuery(); protected: virtual void closeEvent(QCloseEvent* qevent); protected slots: bool fileSave(); bool fileSaveAs(); void cursorPositionChanged(); void exportEntries(); void fileOpen(); void helpCb2Bib(); void helpEditor(); void htmlView(); void isModified(int position, int charsRemoved, int charsAdded); void journalsToAbbreviated(); void journalsToAlternateAbbreviated(); void journalsToAlternateFull(); void journalsToFull(); void load(); void overwriteModeChanged(); void pasteCurrentBibTeX(); void postProcess(); void reload(const QString& fn); void saveAndExecute(); void setViewMode(bool edit_mode); void showMessage(const QString& ms); void updateMetadata(); void viewCb2Bib(); private: Mode _editor_mode; QDockWidget* _dockWidgetP; QLabel* _lineLabelP; QLabel* _overwriteLabelP; QPointer _searcherP; QStackedWidget* _stackedWidgetP; QString _edit_reference_at_position; QString _editor_fn; QSyntaxHighlighter* _shP; QWidget* _c2b_mainP; Ui::c2bEditor ui; bool _is_modified_by_user; c2bBibParser* _bpP; c2bReferenceList* _referencesP; c2bSettings* _settingsP; c2bTextBrowser* _browserP; c2bTextEdit* _editorP; findDialog* _textFinderP; void createReferenceList(); void importActions(); void initEditor(); void setEditorMode(); QMenu* createPopupMenu() // to avoid default context menu { return 0; } }; #endif cb2bib-2.0.1/src/PaxHeaders.5700/c2bRLWebSearchSettings.cpp0000644000000000000000000000013214011522520020001 xustar0030 mtime=1613145424.442620345 30 atime=1613145424.830620334 30 ctime=1613145424.442620345 cb2bib-2.0.1/src/c2bRLWebSearchSettings.cpp0000644000175000001440000000301714011522520021401 0ustar00constansusers00000000000000/*************************************************************************** * Copyright (C) 2004-2021 by Pere Constans * constans@molspaces.com * cb2Bib version 2.0.1. Licensed under the GNU GPL version 3. * See the LICENSE file that comes with this distribution. ***************************************************************************/ #include "c2bRLWebSearchSettings.h" #include "c2bSettings.h" c2bRLWebSearchSettings::c2bRLWebSearchSettings(QWidget* parentw) : QDialog(parentw) { ui.setupUi(this); setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint); resize(size().width(), 1); c2bSettings* settings(c2bSettingsP); const QString searchEngine(settings->value("c2bReferenceList/SearchEngine").toString()); ui.searchEngine->addItem(searchEngine); ui.searchEngine->addItem("https://www.google.com/search?ie=UTF-8&q="); ui.searchEngine->addItem("https://scholar.google.com/scholar?ie=UTF-8&q="); ui.searchEngine->addItem("https://pubmed.ncbi.nlm.nih.gov/?term="); ui.searchEngine->setCurrentIndex(0); ui.searchEngine->setFocus(); ui.addQuotes->setChecked(settings->value("c2bReferenceList/SearchEngineAddQuotes").toBool()); } c2bRLWebSearchSettings::~c2bRLWebSearchSettings() {} void c2bRLWebSearchSettings::accept() { c2bSettings* settings(c2bSettingsP); settings->setValue("c2bReferenceList/SearchEngine", ui.searchEngine->currentText()); settings->setValue("c2bReferenceList/SearchEngineAddQuotes", ui.addQuotes->isChecked()); QDialog::accept(); } cb2bib-2.0.1/src/PaxHeaders.5700/c2bIdPatternLineEdit.h0000644000000000000000000000013214011522520017134 xustar0030 mtime=1613145424.530620342 30 atime=1613145424.830620334 30 ctime=1613145424.534620342 cb2bib-2.0.1/src/c2bIdPatternLineEdit.h0000644000175000001440000000315614011522520020540 0ustar00constansusers00000000000000/*************************************************************************** * Copyright (C) 2004-2021 by Pere Constans * constans@molspaces.com * cb2Bib version 2.0.1. Licensed under the GNU GPL version 3. * See the LICENSE file that comes with this distribution. * * Improvements and modifications: * July 2009 - Added <>, (C) 2009 by Dayu Huang ***************************************************************************/ #ifndef C2BIDPATTERNLINEEDIT_H #define C2BIDPATTERNLINEEDIT_H #include "c2bLineEdit.h" class QAction; class c2bIdPatternLineEdit : public c2bLineEdit { Q_OBJECT public: explicit c2bIdPatternLineEdit(QWidget* parentw = 0); ~c2bIdPatternLineEdit(); void setDocumentIDEdit(); protected: QAction* a_author_all_abbreviated; QAction* a_author_all_initials; QAction* a_author_first; QAction* a_author_first_lowercase; QAction* a_citeid; QAction* a_journal_initials; QAction* a_pages_first; QAction* a_ppages_first; QAction* a_reset; QAction* a_title; QAction* a_title_first_word; QAction* a_title_underscored; QAction* a_volume; QAction* a_year_abbreviated; QAction* a_year_full; protected slots: void author_all_abbreviated(); void author_all_initials(); void author_first(); void author_first_lowercase(); void citeid(); void journal_initials(); void pages_first(); void ppages_first(); void reset(); void title(); void title_first_word(); void title_underscored(); void volume(); void year_abbreviated(); void year_full(); }; #endif cb2bib-2.0.1/src/PaxHeaders.5700/c2bUtils.cpp0000644000000000000000000000013214011522520015257 xustar0030 mtime=1613145424.466620344 30 atime=1613145424.830620334 30 ctime=1613145424.466620344 cb2bib-2.0.1/src/c2bUtils.cpp0000644000175000001440000000243514011522520016662 0ustar00constansusers00000000000000/*************************************************************************** * Copyright (C) 2004-2021 by Pere Constans * constans@molspaces.com * cb2Bib version 2.0.1. Licensed under the GNU GPL version 3. * See the LICENSE file that comes with this distribution. ***************************************************************************/ #include "c2bUtils.h" #include #include namespace c2bUtils { bool openFile(const QString& fn, QWidget* w) { // URL fn is decoded always, in the hope of making openFile encoding agnostic const QString decoded(QUrl::fromPercentEncoding(fn.toUtf8())); const QUrl url(stringToUrl(decoded)); if (!url.isValid()) { if (w) QMessageBox::warning(w, QObject::tr("Warning - cb2Bib"), QObject::tr("Unable to open file.\nError: URL '%1' is not valid.").arg(url.toString()), QMessageBox::Ok); return false; } if (!QDesktopServices::openUrl(url)) { if (w) QMessageBox::warning(w, QObject::tr("Warning - cb2Bib"), QObject::tr("Unable to open file '%1'.").arg(fn), QMessageBox::Ok); return false; } return true; } } // namespace c2bUtils cb2bib-2.0.1/src/PaxHeaders.5700/c2bColors.h0000644000000000000000000000013214011522520015065 xustar0030 mtime=1613145424.510620343 30 atime=1613145424.830620334 30 ctime=1613145424.510620343 cb2bib-2.0.1/src/c2bColors.h0000644000175000001440000000222414011522520016464 0ustar00constansusers00000000000000/*************************************************************************** * Copyright (C) 2004-2021 by Pere Constans * constans@molspaces.com * cb2Bib version 2.0.1. Licensed under the GNU GPL version 3. * See the LICENSE file that comes with this distribution. ***************************************************************************/ #ifndef C2BCOLORS_H #define C2BCOLORS_H #include #include class c2bSettings; /** cb2Bib Color Scheme */ class c2bColors { public: c2bColors(); ~c2bColors(); QColor bib_delimiter_color; QColor bib_reference_field_color; QColor bib_reference_type_color; QColor cb2bib_digit_color; QColor cb2bib_highly_relevant_color; QColor cb2bib_metadata_color; QColor cb2bib_relevant_color; QColor cb2bib_tag_color; QColor cb2bib_unrelevant_color; QColor comment_color; QColor netqinf_command_content_color; QColor netqinf_command_key_color; QHash colorList; void loadColors(c2bSettings* settings); void saveColors(c2bSettings* settings); void updateColor(const QColor& color, const QString& colorName); }; #endif cb2bib-2.0.1/src/PaxHeaders.5700/clipboardPoll.cpp0000644000000000000000000000013214011522520016356 xustar0030 mtime=1613145424.470620344 30 atime=1613145424.830620334 30 ctime=1613145424.470620344 cb2bib-2.0.1/src/clipboardPoll.cpp0000644000175000001440000001671514011522520017767 0ustar00constansusers00000000000000/*************************************************************************** * clipboardPoll, modified by Pere Constans for cb2Bib, 2005 * constans@molspaces.com * cb2Bib version 2.0.1. Licensed under the GNU GPL version 3. * * * Author and Copyright (C) 2003 by Lubos Lunak * Distributed under the GNU General Public License * * * This file is part of the KDE project * Copyright (C) 2003 by Lubos Lunak * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; see the file COPYING. If not, write to * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. ***************************************************************************/ #include "clipboardPoll.h" #include #include #include /* The polling magic: There's no way with X11 how to find out if the selection has changed (unless its ownership is taken away from the current client). In the future, there will be hopefully such notification, which will make this whole file more or less obsolete. But for now, Klipper has to poll. In order to avoid transferring all the data on every time pulse, this file implements two optimizations: The first one is checking whether the selection owner is Qt application (using the _QT_SELECTION/CLIPBOARD_SENTINEL atoms on the root window of screen 0), and if yes, Klipper can rely on QClipboard's signals. If the owner is not Qt app, and the ownership has changed, it means the selection has changed as well. Otherwise, first only the timestamp of the last selection change is requested using the TIMESTAMP selection target, and if it's the same, it's assumed the contents haven't changed. Note that some applications (like XEmacs) does not provide this information, so Klipper has to assume that the clipboard might have changed in this case --- this is what is meant by REFUSED below. */ clipboardPoll::clipboardPoll(QWidget* parentw) : QWidget(parentw) { // kapp->installX11EventFilter( this ); timer = new QTimer(this); connect(timer, SIGNAL(timeout()), this, SLOT(timeout())); const char* names[6] = { "_QT_SELECTION_SENTINEL", "_QT_CLIPBOARD_SENTINEL", "CLIPBOARD", "TIMESTAMP", "KLIPPER_SELECTION_TIMESTAMP", "KLIPPER_CLIPBOARD_TIMESTAMP" }; Atom atoms[6]; XInternAtoms(QX11Info::display(), const_cast(names), 6, False, atoms); selection.sentinel_atom = atoms[0]; clipboard.sentinel_atom = atoms[1]; xa_clipboard = atoms[2]; xa_timestamp = atoms[3]; selection.timestamp_atom = atoms[4]; clipboard.timestamp_atom = atoms[5]; selection.atom = XA_PRIMARY; clipboard.atom = xa_clipboard; selection.last_change = clipboard.last_change = QX11Info::appTime(); // don't trigger right after startup selection.last_owner = XGetSelectionOwner(QX11Info::display(), XA_PRIMARY); clipboard.last_owner = XGetSelectionOwner(QX11Info::display(), xa_clipboard); selection.waiting_for_timestamp = false; clipboard.waiting_for_timestamp = false; updateQtOwnership(selection); updateQtOwnership(clipboard); } clipboardPoll::~clipboardPoll() { delete timer; } bool clipboardPoll::x11Event(XEvent* e) { // note that this is also installed as app-wide filter if (e->type == SelectionNotify && e->xselection.requestor == winId()) { if (changedTimestamp(selection, *e)) { emit clipboardChanged(true); } if (changedTimestamp(clipboard, *e)) { emit clipboardChanged(false); } return true; // filter out } return false; } void clipboardPoll::updateQtOwnership(SelectionData& sData) { Atom type; int format; unsigned long nitems; unsigned long after; unsigned char* prop = NULL; if (XGetWindowProperty(QX11Info::display(), QX11Info::appRootWindow(0), sData.sentinel_atom, 0, 2, False, XA_WINDOW, &type, &format, &nitems, &after, &prop) != Success || type != XA_WINDOW || format != 32 || nitems != 2 || prop == NULL) { sData.owner_is_qt = false; if (prop != NULL) XFree(prop); return; } Window owner = reinterpret_cast(prop)[0]; // [0] is new owner, [1] is previous XFree(prop); Window current_owner = XGetSelectionOwner(QX11Info::display(), sData.atom); sData.owner_is_qt = (owner == current_owner); } void clipboardPoll::timeout() { // KlipperWidget::updateTimestamp(); if (!qApp->clipboard()->ownsSelection() && checkTimestamp(selection)) { emit clipboardChanged(true); } if (!qApp->clipboard()->ownsClipboard() && checkTimestamp(clipboard)) { emit clipboardChanged(false); } } bool clipboardPoll::checkTimestamp(SelectionData& sData) { Window current_owner = XGetSelectionOwner(QX11Info::display(), sData.atom); updateQtOwnership(sData); if (sData.owner_is_qt) { sData.last_change = CurrentTime; sData.last_owner = current_owner; sData.waiting_for_timestamp = false; return false; } if (current_owner != sData.last_owner) // owner has changed { sData.last_owner = current_owner; sData.waiting_for_timestamp = false; sData.last_change = CurrentTime; return true; } if (current_owner == None) { return false; // None also last_owner... } if (sData.waiting_for_timestamp) { // We're already waiting for the timestamp of the last check return false; } XDeleteProperty(QX11Info::display(), winId(), sData.timestamp_atom); XConvertSelection(QX11Info::display(), sData.atom, xa_timestamp, sData.timestamp_atom, winId(), QX11Info::appTime()); sData.waiting_for_timestamp = true; sData.waiting_x_time = QX11Info::appTime(); return false; } bool clipboardPoll::changedTimestamp(SelectionData& sData, const XEvent& ev) { if (ev.xselection.requestor != winId() || ev.xselection.selection != sData.atom || ev.xselection.time != sData.waiting_x_time) { return false; } sData.waiting_for_timestamp = false; if (ev.xselection.property == None) { return true; } Atom type; int format; unsigned long nitems; unsigned long after; unsigned char* prop = NULL; if (XGetWindowProperty(QX11Info::display(), winId(), ev.xselection.property, 0, 1, False, AnyPropertyType, &type, &format, &nitems, &after, &prop) != Success || format != 32 || nitems != 1 || prop == NULL) { if (prop != NULL) XFree(prop); return true; } Time timestamp = reinterpret_cast(prop)[0]; XFree(prop); if (timestamp != sData.last_change || timestamp == CurrentTime) { sData.last_change = timestamp; return true; } return false; // ok, same timestamp } cb2bib-2.0.1/src/PaxHeaders.5700/c2bCoreCiter.h0000644000000000000000000000013214011522520015503 xustar0030 mtime=1613145424.518620343 30 atime=1613145424.830620334 30 ctime=1613145424.518620343 cb2bib-2.0.1/src/c2bCoreCiter.h0000644000175000001440000000164114011522520017104 0ustar00constansusers00000000000000/*************************************************************************** * Copyright (C) 2004-2021 by Pere Constans * constans@molspaces.com * cb2Bib version 2.0.1. Licensed under the GNU GPL version 3. * See the LICENSE file that comes with this distribution. ***************************************************************************/ #ifndef C2BCORECITER_H #define C2BCORECITER_H #include #include class settings; class c2bCoreCiter : public QObject { Q_OBJECT public: explicit c2bCoreCiter(QWidget* parentw = 0); ~c2bCoreCiter(); void cite(const QStringList& keys); public slots: void setLyXPipe(); private: void _cite_to_clipboard(const QStringList& keys) const; void _cite_to_lyx_pipe(const QStringList& keys) const; QRegExp _citeids; QString _command; QString _lyxpipe; QWidget* _parentWP; settings* _settingsP; }; #endif cb2bib-2.0.1/src/PaxHeaders.5700/c2bCiterWidget.h0000644000000000000000000000013214011522520016036 xustar0030 mtime=1613145424.502620343 30 atime=1613145424.826620334 30 ctime=1613145424.502620343 cb2bib-2.0.1/src/c2bCiterWidget.h0000644000175000001440000000343314011522520017440 0ustar00constansusers00000000000000/*************************************************************************** * Copyright (C) 2004-2021 by Pere Constans * constans@molspaces.com * cb2Bib version 2.0.1. Licensed under the GNU GPL version 3. * See the LICENSE file that comes with this distribution. ***************************************************************************/ #ifndef C2BCITERWIDGET_H #define C2BCITERWIDGET_H #include "ui_c2bCiterWidget.h" #include class QLabel; class c2bCiterModel; class c2bCoreCiter; class c2bSettings; class c2bCiterWidget : public QWidget { Q_OBJECT public: explicit c2bCiterWidget(QWidget* parentw = 0); ~c2bCiterWidget(); public: void load(); void setTrayIcon(); public slots: void show(); void toggleVisible(); signals: void openAnnote(); void openFile(const QString& fn); private: QString _status_label; QStringList _bibtex_files; QSystemTrayIcon* _tray_icon; Ui::c2bCiterWidget ui; bool _clipboard_connected; c2bCiterModel* _citations; c2bCoreCiter* _citerP; c2bSettings* _settingsP; void reload(const c2bCiter::State& state); void setActions(); private slots: void citeReferences(); void doSearchInFiles(); void editReference(); void filterDataChanged(const QString& filter); void help(); void indexDocuments(); void openDirectory(); void openFile(); void openFiles(); void openUrl(); void reload(); void showLabel(); void showLabel(const QString& label); void showMessage(const QString& message); void toggleCb2Bib(); void toggleClipboard(); void toggleFullScreen(); void trayIconActivated(QSystemTrayIcon::ActivationReason r); void updatePatternFilter(const bool mode, const QString& pattern); }; #endif cb2bib-2.0.1/src/PaxHeaders.5700/cb2Bib.ui0000644000000000000000000000007414011522151014513 xustar0030 atime=1613145424.830620334 30 ctime=1613145424.306620349 cb2bib-2.0.1/src/cb2Bib.ui0000644000175000001440000006761514011522151016124 0ustar00constansusers00000000000000 Pere Constans cb2Bib 0 0 1432 820 cb2Bib 6 6 6 0 :/icons/icons/cb2bib.png:/icons/icons/cb2bib.png 32 32 :/icons/icons/configure.png:/icons/icons/configure.png 32 32 :/icons/icons/tex.png:/icons/icons/tex.png 32 32 :/icons/icons/pdf.png:/icons/icons/pdf.png 32 32 Qt::Horizontal QSizePolicy::Fixed 20 20 :/icons/icons/exit.png:/icons/icons/exit.png 32 32 Qt::Horizontal QSizePolicy::Expanding 205 20 :/icons/icons/connect_established.png:/icons/icons/connect_established.png 32 32 :/icons/icons/package_network.png:/icons/icons/package_network.png 32 32 :/icons/icons/viewbib.png:/icons/icons/viewbib.png 32 32 :/icons/icons/filesaveas.png:/icons/icons/filesaveas.png 32 32 :/icons/icons/edit.png:/icons/icons/edit.png 32 32 0 0 :/icons/icons/mimeFolder.png:/icons/icons/mimeFolder.png 0 0 true true Add to: Qt::Horizontal Qt::Horizontal 0 0 QTabWidget::South QTabWidget::Rounded 0 Main 9 6 Keywords File 0 0 true false Type Year Number Volume Abstract Pages Journal Author Title CITEID 0 0 false false false false false false false false false false false Other Fields 9 6 Book Title Annote DOI Chapter Address Eprint Editor Edition ISSN ISBN Institution Organization Note Month Series School Publisher URL false false false false false false false false false false false false false false false false false false Clear All Fields Insert Regular Expression Insert regular expression Edit Bookmarks Edit bookmarks Edit Regular Expressions Edit regular expressions Guess Bibliographic Fields Guess bibliographic fields Postprocess BibTeX Preparse Clipboard Preparse clipboard Restart Recognition true View Tagged Clipboard Data View Tagged Clipboard Data View tagged clipboard data Open Document Open document Edit Journal Abbreviations Edit journal abbreviations Select Document File Select document file Annote Editor Annote Editor Check Repeated Check repeated c2bLineEdit QLineEdit
    c2bLineEdit.h
    c2bComboBox QComboBox
    c2bComboBox.h
    tabWidget id typecombo title author journal pages volume number year abstract keywords file bibtexfile BibTeXDir ViewAboutB ConfigureB SearchInFilesB PdfImportB ExitB ConnectB MakeNetworkQueryB ViewBibB AddBibB EditBibTeXB booktitle annote address edition institution month publisher url chapter editor isbn note school doi eprint issn organization series
    cb2bib-2.0.1/src/PaxHeaders.5700/c2bSearchInFiles.ui0000644000000000000000000000007414011522151016476 xustar0030 atime=1613145424.830620334 30 ctime=1613145424.302620349 cb2bib-2.0.1/src/c2bSearchInFiles.ui0000644000175000001440000002402014011522151020066 0ustar00constansusers00000000000000 Pere Constans c2bSearchInFiles 0 0 824 494 Search in files - cb2Bib 6 6 6 6 6 Modifier 9 9 9 9 6 &Simplify source Qt::Horizontal 40 20 Search scope 9 9 9 9 6 Scan &linked documents Scan all &BibTeX files Qt::Horizontal 16 22 Search for ... Qt::Horizontal Qt::Horizontal Qt::Horizontal Qt::NoFocus Qt::Horizontal QDialogButtonBox::Abort|QDialogButtonBox::Close|QDialogButtonBox::Help Pattern 9 9 9 9 6 Qt::Horizontal 0 0 Composite pattern 9 9 9 9 6 false &Edit false &Delete false Qt::PreventContextMenu &Add 0 0 true false true Case Type Scope Pattern Qt::Vertical 75 91 false All Any c2bSearchInFilesPattern QWidget
    c2bSearchInFilesPattern.h
    patternList addPatternB deletePatternB allBibFiles documentFiles buttonBox buttonBox rejected() c2bSearchInFiles reject() 325 565 286 274
    cb2bib-2.0.1/src/PaxHeaders.5700/c2bTextBrowser.h0000644000000000000000000000013214011522520016114 xustar0030 mtime=1613145424.562620342 30 atime=1613145424.830620334 30 ctime=1613145424.566620341 cb2bib-2.0.1/src/c2bTextBrowser.h0000644000175000001440000000146114011522520017515 0ustar00constansusers00000000000000/*************************************************************************** * Copyright (C) 2004-2021 by Pere Constans * constans@molspaces.com * cb2Bib version 2.0.1. Licensed under the GNU GPL version 3. * See the LICENSE file that comes with this distribution. ***************************************************************************/ #ifndef C2BTEXTBROWSER_H #define C2BTEXTBROWSER_H #include class QAction; /** @author Pere Constans */ class c2bTextBrowser : public QTextBrowser { Q_OBJECT public: explicit c2bTextBrowser(QWidget* parentw = 0); ~c2bTextBrowser(); void updateHtml(const QString& newHtml); public slots: virtual void setSource(const QUrl& name); protected: virtual void contextMenuEvent(QContextMenuEvent* qevent); }; #endif cb2bib-2.0.1/src/PaxHeaders.5700/c2bSearchInFiles.cpp0000644000000000000000000000013214011522520016636 xustar0030 mtime=1613145424.446620345 30 atime=1613145424.830620334 30 ctime=1613145424.450620345 cb2bib-2.0.1/src/c2bSearchInFiles.cpp0000644000175000001440000001704214011522520020241 0ustar00constansusers00000000000000/*************************************************************************** * Copyright (C) 2004-2021 by Pere Constans * constans@molspaces.com * cb2Bib version 2.0.1. Licensed under the GNU GPL version 3. * See the LICENSE file that comes with this distribution. ***************************************************************************/ #include "c2bSearchInFiles.h" #include "c2b.h" #include "c2bUtils.h" #include #include c2bSearchInFiles::c2bSearchInFiles(const QString& file, QWidget* parentw) : QDialog(parentw) { ui.setupUi(this); setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint); // Set blank title to columns 0 and 4. Qt 4.4.0 needs it, otherwise it takes column number as default title. // Recheck whenever ui files are generated for 4.4 instead of current 4.2. ui.patternList->headerItem()->setText(0, QApplication::translate("c2bSearchInFiles", "", 0)); ui.patternList->headerItem()->setText(4, QApplication::translate("c2bSearchInFiles", "", 0)); for (int i = 0; i < ITEMS_IN_SEARCH_PATTERN; ++i) ui.patternList->resizeColumnToContents(i); ui.buttonBox->button(QDialogButtonBox::Abort)->setAutoDefault(false); ui.buttonBox->button(QDialogButtonBox::Abort)->setDefault(false); ui.buttonBox->button(QDialogButtonBox::Abort)->setEnabled(false); ui.buttonBox->button(QDialogButtonBox::Close)->setAutoDefault(false); ui.buttonBox->button(QDialogButtonBox::Close)->setDefault(false); _searchB = new QPushButton(tr("Search")); ui.buttonBox->addButton(_searchB, QDialogButtonBox::ActionRole); _searchB->setAutoDefault(true); _searchB->setDefault(true); _searchB->setEnabled(false); _bibtex_file.clear(); _bibtex_dir.clear(); setBibTeXFile(file); connect(_searchB, SIGNAL(clicked()), this, SLOT(searchB_clicked())); connect(ui.allBibFiles, SIGNAL(clicked()), this, SLOT(setBibTeXFile())); connect(ui.buttonBox, SIGNAL(helpRequested()), this, SLOT(help())); connect(ui.pattern, SIGNAL(patternAvailable(bool)), this, SLOT(updateForm())); connect(ui.patternList, SIGNAL(itemActivated(QTreeWidgetItem*,int)), this, SLOT(on_editPatternB_clicked())); connect(ui.patternList, SIGNAL(itemClicked(QTreeWidgetItem*,int)), this, SLOT(updateForm())); } c2bSearchInFiles::~c2bSearchInFiles() {} void c2bSearchInFiles::updateForm() { ui.addPatternB->setEnabled(ui.pattern->isAvailable()); ui.Boolean->setEnabled((ui.patternList->topLevelItemCount() > 1) || (ui.pattern->isAvailable() && ui.patternList->topLevelItemCount() > 0)); _searchB->setEnabled(!_bibtex_dir.isEmpty() && (ui.pattern->isAvailable() || ui.patternList->topLevelItemCount() > 0)); if (ui.patternList->currentItem()) { ui.deletePatternB->setEnabled(true); ui.editPatternB->setEnabled(true); } else { ui.deletePatternB->setEnabled(false); ui.editPatternB->setEnabled(false); } ui.searchLog->setText(_search_log); } void c2bSearchInFiles::on_addPatternB_clicked() { new QTreeWidgetItem(ui.patternList, ui.pattern->patterns()); for (int i = 0; i < ITEMS_IN_SEARCH_PATTERN; ++i) ui.patternList->resizeColumnToContents(i); ui.pattern->clear(); updateForm(); } void c2bSearchInFiles::on_deletePatternB_clicked() { QTreeWidgetItem* item = ui.patternList->currentItem(); delete item; item = ui.patternList->currentItem(); if (item) ui.patternList->currentItem()->setSelected(true); updateForm(); } void c2bSearchInFiles::on_editPatternB_clicked() { QDialog editor(this); ui_editor.setupUi(&editor); QTreeWidgetItem* item = ui.patternList->currentItem(); ui_editor.pattern->setPattern(item); connect(ui_editor.pattern, SIGNAL(patternAvailable(bool)), ui_editor.buttonBox->button(QDialogButtonBox::Ok), SLOT(setEnabled(bool))); if (editor.exec() == QDialog::Accepted) { const QStringList pattern(ui_editor.pattern->patterns()); for (int i = 0; i < ITEMS_IN_SEARCH_PATTERN; ++i) item->setText(i, pattern.at(i)); for (int i = 0; i < ITEMS_IN_SEARCH_PATTERN; ++i) ui.patternList->resizeColumnToContents(i); } } void c2bSearchInFiles::searchB_clicked() { QApplication::setOverrideCursor(QCursor(Qt::WaitCursor)); _searchB->setEnabled(false); ui.buttonBox->button(QDialogButtonBox::Abort)->setEnabled(true); ui.searchLog->setText(_search_log); bibSearcher searcher(c2b::bibParser()); connect(ui.buttonBox->button(QDialogButtonBox::Abort), SIGNAL(clicked()), &searcher, SLOT(abort())); searcher.setSearchScope(_bibtex_file, _bibtex_dir, ui.allBibFiles->isChecked(), ui.documentFiles->isChecked()); searcher.setSimplifySource(ui.simplifySource->isChecked()); searcher.setBoolean(ui.Boolean->currentText() == "All"); if (ui.addPatternB->isEnabled()) { const QStringList p(ui.pattern->patterns()); searcher.addPattern(p.at(0) == "NOT", p.at(1) == "Sensitive", p.at(2), p.at(3), p.at(4).at(0), p.at(5)); } QTreeWidgetItemIterator it(ui.patternList); while (*it) { QStringList p; for (int i = 0; i < ITEMS_IN_SEARCH_PATTERN; ++i) p.append((*it)->text(i)); searcher.addPattern(p.at(0) == "NOT", p.at(1) == "Sensitive", p.at(2), p.at(3), p.at(4).at(0), p.at(5)); ++it; } if (searcher.patternsCount() == 0) return; const unsigned long start_time(clock()); searcher.exec(); const double time(double(clock() - start_time) / double(CLOCKS_PER_SEC)); QString search_status; if (searcher.hitsCount() > 0 || searcher.errorsCount() > 0) { if (searcher.hitsCount() > 0) search_status = tr("Found %1 hits from %2 references (%3s)") .arg(searcher.hitsCount()) .arg(searcher.referencesCount()) .arg(time, 0, 'g', 3); else ui.searchLog->setText(_search_log); QApplication::processEvents(); emit searchDone(_bibtex_dir, &searcher); } else if (searcher.errorsCount() < 0) search_status = tr("Search aborted"); else search_status = tr("No reference found (%1s)").arg(time, 0, 'g', 3); if (!search_status.isEmpty()) { ui.searchLog->setText(search_status); c2b::showMessage(search_status); } ui.buttonBox->button(QDialogButtonBox::Abort)->setEnabled(false); _searchB->setEnabled(true); QApplication::restoreOverrideCursor(); } void c2bSearchInFiles::setBibTeXFile(const QString& file) { if (!file.isEmpty()) { QFileInfo fi(file); QDir d(fi.absolutePath()); if (d.exists()) { _bibtex_file = fi.absoluteFilePath(); _bibtex_dir = fi.absolutePath(); } else _bibtex_dir.clear(); } if (_bibtex_dir.isEmpty()) _search_log = tr("No existing file or directory set for searching"); else if (ui.allBibFiles->isChecked()) _search_log = tr("Search in files at %1").arg(_bibtex_dir); else _search_log = tr("Search in file %1").arg(_bibtex_file); updateForm(); } void c2bSearchInFiles::setCurrentText(const QString& text) { if (text.isEmpty()) return; ui.pattern->setText(text); updateForm(); } void c2bSearchInFiles::show() { c2bUtils::setWidgetOnTop(this); ui.pattern->setFocus(); QDialog::show(); } void c2bSearchInFiles::help() { c2bUtils::displayHelp("https://www.molspaces.com/cb2bib/doc/bibsearch/"); } cb2bib-2.0.1/src/PaxHeaders.5700/cb2Bib.cpp0000644000000000000000000000013214011522520014653 xustar0030 mtime=1613145424.466620344 30 atime=1613145424.830620334 30 ctime=1613145424.470620344 cb2bib-2.0.1/src/cb2Bib.cpp0000644000175000001440000031421614011522520016261 0ustar00constansusers00000000000000/*************************************************************************** * Copyright (C) 2004-2021 by Pere Constans * constans@molspaces.com * cb2Bib version 2.0.1. Licensed under the GNU GPL version 3. * See the LICENSE file that comes with this distribution. ***************************************************************************/ #include "cb2Bib.h" #include "c2b.h" #include "c2bBibMenu.h" #include "c2bBibParser.h" #include "c2bCiterWidget.h" #include "c2bClipEdit.h" #include "c2bClipboard.h" #include "c2bEditor.h" #include "c2bFileDialog.h" #include "c2bNetworkQuery.h" #include "c2bPdfImport.h" #include "c2bPostprocess.h" #include "c2bSaveRegExp.h" #include "c2bSearchInFiles.h" #include "c2bSettings.h" #include "c2bTextBrowser.h" #include "c2bUtils.h" #include #include #include /** \page overview Overview cb2Bib is a free, open source, and multiplatform application for rapidly extracting unformatted, or unstandardized bibliographic references from email alerts, journal Web pages, and PDF files. cb2Bib facilitates the capture of single references from unformatted and non standard sources. Output references are written in BibTeX. Article files can be easily linked and renamed by dragging them onto the cb2Bib window. Additionally, it permits editing and browsing BibTeX files, citing references, searching references and the full contents of the referenced documents, inserting bibliographic metadata to documents, and writing short notes that interrelate several references. Current version: cb2Bib GET_VERSION. See \ref changelog for a detailed list of changes and acknowledgments, and \ref relnotes for additional notes and information. See \ref relnotes201.

     

    GET_TABLE_OF_CONTENTS

     

    \section descrip Description cb2Bib reads the clipboard text contents and process it against a set of predefined patterns. If this automatic detection is successful, cb2Bib formats the clipboard data according to the structured BibTeX reference syntax. Otherwise, if no predefined format pattern is found or if detection proves to be difficult, manual data extraction is greatly simplified by cb2Bib. In most cases, such manual data extraction will provide with a new, personalized pattern to be included within the predefined pattern set for future automatic extractions. Once the bibliographic reference is correctly extracted, it is added to a specified BibTeX database file. Optionally, document files are renamed to a DocumentID filename and moved to a desired directory as a personal article library, and their metadata is updated with the bibliographic reference. See \ref metadata section. cb2Bib facilitates writing short notes related to bibliographic collections. Notes are written using a minimalist markup on a plain text editor, and can latter be converted to HTML. Related references and links become easily accessible on any browser or by the embedded cb2Bib viewer. See \ref relnotes110.

     

    \section usage Using cb2Bib \subsection procedure Procedure - Select the reference to import from the email or web browser \n On Unix machines, cb2Bib automatically detects mouse selections and clipboard changes. On Windows machines, copy or Ctrl-C is necessary to activate cb2Bib automatic processing. - cb2Bib automatic processing \n Once text is selected cb2Bib initiates the automatic reference extraction. It uses the predefined patterns from file regexp.txt to attempt automatic extraction. See \ref c2bconf_files section for setting the user predefined pattern matching expression file. After a successful detection bibliographic fields appear on the cb2Bib item line edits. Manual editing is possible at this stage. - cb2Bib manual processing \n If no predefined format pattern is found or if detection proves to be difficult, a manual data extraction must be performed. Select, either using mouse or Shift+arrow keys, the reference fields from the cb2Bib clipboard area. A popup menu will appear after selection is made. Choose the corresponding bibliographic field. See \ref entrytype. If operating with the keyboard, first letter of the field is set as a menu shortcut. Then, typing 'A' sets selection to 'author', or '+A' to 'add authors'. Selection is postprocessed and added to the cb2Bib item line edit. cb2Bib field tags will show on the cb2Bib clipboard area. Once the manual processing is done, cb2Bib clipboard area will contain the matching pattern. The pattern can be further edited and stored to the regexp.txt file using Insert Regular Expression, Alt+I. See the \ref clipboard and \ref regexpeditor sections. - Download reference to cb2Bib \n cb2Bib has the built-in functionality to interact with publishers "Download reference to Citation Manager" service. Choose BibTeX format, or any other format that you can translate using External Clipboard Preparsing Command. See \ref keyboard, Alt C. Click "Download" from your browser. When asked "Open with..." select cb2Bib. cb2Bib will be launched if no running instance is found. If already running, it will place the downloaded reference to the clipboard, and it will start processing. Make sure your running instance is aware of clipboard changes. See \ref c2bbuttons. For convenience, the shell script c2bimport, and the desktop config file c2bimport.desktop are also provided. - Adding documents \n PDF and other documents can be added to the BibTeX reference by dragging the file icon and dropping it into the cb2Bib's panel. Optionally, document files, are renamed to a DocumentID filename and moved to a desired directory as a personal article library (See \ref c2bconf_documents section). Linked to a reference documents correspond to the BibTeX tag file. Usual reference manager software will permit to retrieve and visualize these files. Download, copy and/or moving is scheduled and performed once the reference is accepted, e.g., once it is saved by pressing Save Reference button. - Multiple retrieving from PDF files \n Multiple PDF or convertible to text files can be sequentially processed by dragging a set of files into cb2Bib's PDFImport dialog. By starting the processing button, files are sequentially converted to text and send to cb2Bib clipboard panel for reference extraction. See \ref pdfimport for details. - Journal-Volume-Page Queries \n Takes input Journal, Volume, and first page from the corresponding edit lines and attempts to complete the reference. Additionally, queries consider title, DOI, and an excerpt, which is a simplified clipboard panel contents. See \ref c2bconf_network section, the distribution file netqinf.txt, and \ref relnotes035 for customization and details. - BibTeX Editor \n cb2Bib includes a practical text editor suitable for corrections and additions. cb2Bib capabilities are readily available within the editor. E.g., the reference is first sent to cb2Bib by selecting it, and later retrieved from cb2Bib to the editor using 'right click' + 'Paste Current BibTeX'. Interconversions Unicode <-> LaTeX, long <-> abbreviated journal name, and adding/renaming PDF files are easily available. BibTeX Editor is also accessible through a shell command line. See \ref commandline and \ref bibeditor. \subsection c2bbuttons Buttons Functionality - \b About \n About cb2Bib, bookmarks, and online help. - \b Configure \n Configure cb2Bib. See \ref configuration section. - Search references \n Opens the cb2Bib's search dialog. The search is performed either on the current BibTeX file, or for all BibTeX files on the current directory. Optionally, the search is extended to reference's files. Hits are displayed on an editor window. See \ref bibsearch. See also \ref c2bconf_utilities section to configure the external to text converter. - \b PDFImport \n Launches cb2Bib's PDFImport window. Files dragged into PDFImport window are sequentially translated to text and sent to cb2Bib clipboard panel. cb2Bib automatic and manual capabilities are then easily available to extract and supervise reference extractions. See \ref pdfimport. - \b Exit \n Exits cb2Bib. - Dis/Connect Clipboard \n Toggles automatic cb2Bib and desktop clipboard connection. While the automatic cb2Bib-clipboard connection permits reducing keystrokes, the disconnected mode is needed in cases where multiple mouse selections or copies are required to complete a reference extraction. See also \ref relnotes041 and \ref relnotes021 if you experience problems with this feature. - Network Reference Query \n Starts Network Query. It usually takes input Journal, Volume, and first page from the corresponding edit lines and attempts to complete the reference. See \ref c2bconf_network network section to customize querying. See the distribution file netqinf.txt and also \ref relnotes035 for the details. - View BibTeX Reference \n View current reference as will be output to the BibTeX file. Eventual manual changes should be done on the item line edit. - Save Reference \n Inserts the current bibliographic reference to the output BibTeX file. This action decides whether or not a reference is accepted. Scheduled actions such as PDF downloading, copying or renaming will be performed at this time. - Open BibTeX File \n Opens the current BibTeX output file. Right click within the BibTeX Editor window for its particular functionality. See also \ref bibeditor. \subsection keyboard Additional Keyboard Functionality Most keyboard shortcuts are customizable. See \ref c2bconf_shortcuts. In the following, default shortcuts are used to describe functionality. - Alt A \n Starts \ref c2bannote. Specify the note's filename in the dialog. A new note is created if the file name does not exist. The cb2Bib Annote is opened as a separate program. Exiting cb2Bib will not exit the note's viewer. On the viewer, pressing key E launches the default text editor. The viewer will track the editor, and will update the note's display each time the editor saves it. The viewer's functionality is disabled if cb2Bib was not compiled and linked against WebKit. See \ref commandline to use Annote in command line mode. - Alt B \n Edits the Bookmarks and Network Query Info file netqinf.txt. - Alt C \n Preparses cb2Bib's clipboard through a user specified external script or tool. Preparsing is necessary to catch formatted references that can not be easily extracted using recognition patterns, or that are written in ambiguous formats. Many available scripts or specific user-written tools can be incorporated to cb2Bib through this external preparsing capability. In addition, simple, one-line scripts can be used within PDFImport to provide, for instance, the journal name when missing from the PDF first page. The cb2Bib distribution contains the sample scripts isi2bib and ris2bib that convert ISI and RIS formatted strings to BibTeX. See \ref c2bconf_clipboard for details. - Alt D \n Deletes temporary BibTeX output file. This permits using cb2Bib output files as temporary media to transfer references to a preferred reference manager and preferred format. Caution: This feature is not intended for the users who actually store their references in one or several BibTeX files. Remember to import references prior to delete cb2Bib output file. - Alt E \n Edits the regular expression file. It permits an easy access and modification of stored extraction patterns. New patterns are conveniently added to to the regular expression file by using the RegExp Editor button functionality. - Alt F \n Launches a file dialog for selecting the source file name for the BibTeX entry file. Selected files are displayed either, as the actual source filename, or, as the target filename, depending on the file copy/rename/move settings. See \ref c2bconf_documents. Alternatively to Alt F, documents can be easily linked to a reference by dragging the document file and dropping it to the cb2Bib panel. - Alt I \n Edits and optionally inserts the current regular expression pattern. See the \ref clipboard and \ref regexpeditor sections. - Alt J \n Edits the Journal Abbreviations file. - Alt O \n Opens the currently linked document for browsing. Documents can be easily linked to a reference by dragging the document file and dropping it to the cb2Bib panel, or with Alt F. Linked documents correspond to the BibTeX tag file. - Alt P \n Postprocess BibTeX output file. It launches a user specified script or program to postprocess the current BibTeX file. The cb2Bib distribution contains two sample scripts. One, bib2pdf is a shell script for running latex and bibtex; this permits to check the BibTeX file for possible errors, and to easily produce a suitable output for printing. The other one, bib2end.bat is a batch script for running bib2xml and xml2end, which converts references into Endnote format. See \ref c2bconf_bibtex for details. - Alt R \n Restarts cb2Bib automatic engine. Takes input data not from the system clipboard but from the cb2Bib clipboard panel. This permits editting the input stream from poorly translated PDF captions, correcting for author superscripts, or helps in debugging regular expressions. - Alt W \n Writes current reference to the source document file. This option is intended for writing and updating bibliographic metadata to document files without needing to use BibTeX files. Only local and writable files are considered. - Alt X \n Check Repeated looks for existing references in the BibTeX directory similar to the current one. The search is done for exact cite ID, and for title and author field values, or, if empty, for booktitle and editor,using the \htmlonly approximate string \endhtmlonly search pattern. See also \ref c2bconf_bibtex. - F4 \n Toggles between Main and Other Fields reference edit tabs. - Esc \n Quits cb2Bib popup menu. The cb2Bib menu pops up each time a selection in made in the clipboard panel. This saves keystrokes in a normal bibliographic extraction. Press Esc or Right Click mouse button if you need to gain access to the editor cut/copy/paste functionality instead.

     

    \section detail Advanced Features Advanced features, and processing and extraction details are described in the following sections: - \ref faq_automatic_extraction - \ref clipboard - \ref authorproc - \ref journalproc - \ref heuristics - \ref regexpeditor Configuration information is described in the following sections: - \ref configuration - \ref predefinedplaceholders Utilities and modules are described in the following sections: - \ref bibsearch - \ref bibeditor - \ref pdfimport - \ref metadata - \ref commandline - \ref c2bannote - \ref c2bciter

     

    \section requirements Requirements \subsection requirements_comp Compilation To compile cb2Bib, the following libraries must be present and accessible: - Qt 5.7.0 or later from \htmlonly Qt Project. \endhtmlonly On a Linux platform with Qt preinstalled, make sure that the devel packages and Qt tools are also present. - QtWebKit or QtWebEngine library (optional) to compile cb2Bib Annote viewer. No special action/flag is needed during compilation. - Compression libraries \htmlonly LZ4 \endhtmlonly or \htmlonly LZO \endhtmlonly (optional). To chose a particular one, type configure --enable-lz4 or configure --enable-lzo. On machines with SSE4 instruction set, the \htmlonly LZSSE \endhtmlonly compressor can be used in place of LZ4 and LZO, by typing configure --enable-lzsse. If none of the above compressors were appropiate on a particular platform, type configure --enable-qt-zlib before compiling. - X11 header files if compiling on Unix platforms. Concretely, headers X11/Xlib.h and X11/Xatom.h are needed. - The header files fcntl.h and unistd.h from glibc-devel package are also required. Otherwise compilation will fail with `::close' undeclared. \subsection requirements_run Deployment Although not needed for running cb2Bib, the following tools extend cb2Bib applicability: - MathJax, available at \htmlonly https://www.mathjax.org, \endhtmlonly for displaying mathematical notation. Simply, download and unzip it in a desired directory. See \ref c2bconf_annote. - ExifTool, version 7.31 or later, available at \htmlonly https://exiftool.org, \endhtmlonly for metadata insertion. - pdftotext, found packaged as xpdf, and downloadable from \htmlonly https://www.xpdfreader.com/download.html. \endhtmlonly - The bib2xml and xml2end \htmlonly BibUtils, \endhtmlonly for the postprocessing script bib2end.bat on Windows platforms. - LaTeX packages, for checking BibTeX files correctness and for references printing through the shell script bib2pdf.

     

    \section credits Credits and License The cb2Bib icons are taken from the Oxygen, Crystal SVG, and Noia icon sets, to be found at the \htmlonly KDE Desktop Environment. \endhtmlonly Several people has contributed with suggestions, bug reports or patches. For a detailed list of acknowledgments see the \ref changelog. The cb2Bib program is licensed under the terms of the \htmlonly GNU General Public License \endhtmlonly version 3.

     

    > GET_UPDATEDON \n > First released version 0.1.0 on 2004-06-29. \n > © 2004-2021 Pere Constans \n */ /** \page relnotes Release Notes \section relnotes201 Release Note cb2Bib 2.0.1 To optimize search on PDF's contents, cb2Bib keeps a cache with the extracted text streams, that are compressed to reduce disk space and reading overhead. Nowadays, compressors with extremely high decompression speed are available. Two of them are LZSSE, for SSE4 capable architectures, and LZ4, for a broader range of CPUs. These two compressors can now be used by cb2Bib, with the latter set as the default compression library in cb2Bib builds. When upgrading to version 2.0.1, the first search on the document collection will recreate the cache, and this step will be noticeably slow. Additionally, cb2Bib 2.0.1 includes original, optimized text matching code for AVX2 capable architectures that is used for search matching and BibTeX parsing. This code is not set in default builds and needs to be explicitly enabled at compilation time. Finally, it is important mentioning the inclusion in version 2.0.1 of stemmed context search, see \ref contextsearch for details, and contributed feedback in handling citations and extending cite commands to markdown syntax, see \ref predefinedplaceholders.

     

    */ /** \page relnotes Release Notes \section relnotes200 Release Note cb2Bib 2.0.0 Throughout the 1.9.x series, the cb2Bib sources were updated to the improved string processing capabilities of Qt5 and PCRE libraries. This update has brought a remarkable speedup for in-document searches and full search indexing. Alternate normalization of journal titles and abbreviations, upgrading jsMath to MathJax, extending network queries syntax, and a PDF user manual are the additional enhancements in cb2Bib 2.0.0. Back in version 0.3.3, cb2Bib introduced network queries to obtain the data for a citation. While convenient, queries to publishers' websites were difficult to setup and fragile. Nowadays, fortunately, arXiv, PubMed and Crossref offer structured APIs. These interfaces provide to the end user an easy setup for completing bibliographic citations.

     

    */ /** \page relnotes Release Notes \section relnotes190 Release Note cb2Bib 1.9.0 The cb2Bib sources have been ported to Qt5. To highlight this major update in library requirements the version number is set to 1.9.0. Later, once stabilized and new functionality related to Qt5 enhancements are applied, version number will be set to 2. At this point cb2Bib has exactly the same functionality as its preceding version 1.5.0. To build the program, however, only qmake and its related config procedure are available. The cmake scripts have not yet been ported. Qt5 brings important enhancements related to regular expressions and string processing. Some careful updates to the cb2Bib sources are needed to fully benefit from them. They will implemented through the 1.9.x series. We expect by then a performance boost on full text, regular expression based searches.

     

    */ /** \page relnotes Release Notes \section relnotes150 Release Note cb2Bib 1.5.0 Included in version 1.5.0 sources there is a patch for XPDF 3.0.4, the default tool to convert PDF documents to plain text. The modified code separates superscripts to avoid words being joined to reference numbers and author names joined to affiliations' glyphs. Interested users will need to download the package, apply the patch, and compile it. Additionally, this version improves converted text postprocessing. This step normalizes character codes, reverts ligatures, restores when possible orphan diacritics and broken words, and undoes text hyphenation. Conversion to text and postprocessing is important for reference extraction, and document indexing and searching. It is therefore recommended to delete cached document-to-text data to benefit from the present improvements. cb2Bib stores cached texts in *c2b files in an user specified directory. After that, by performing a search or initiating indexing an updated cache will be created.

     

    */ /** \page relnotes Release Notes \section relnotes147 Release Note cb2Bib 1.4.7 Approximate and context searches effectively locate our references of interest. As collections grow in size, and low performance devices, netbooks and tablets, start being used, complete document searches become demanding. Besides, it is often not clear what to query for, and then a glossary of terms provides guidance. Often too, interest lies on subsetting documents by being similar to a given one. Version 1.4.7 adds a pragmatic term or keyword extraction from the document contents. Accepted keywords are set as the substrings appearing at least twice in one document, appearing at least in three documents, and conforming to predefined part-of-speech (POS) sequences. Keyword extraction is performed by either clicking on Index Documents at the c2bciter desktop tray menu, or, by typing cb2bib --index [bibdirname] on a shell. During extraction, the Part Of Speech (POS) Lexicon distribution file must be available and readable. On termination, indexing files are saved on the Search In Files Cache Directory. Simply copying this directory will synchronize keyword indexing to a second computer. After refreshing c2bciter module, pressing key G displays the glossary of terms. On a reference, pressing K displays its list of keywords. Pressing R on a keyword lists the references related to that keyword. Pressing R on a reference lists similarly related references. Similarity is assessed based on keyword occurrences. Left and Right keys provide previous and next navigation. Pressing V on either a reference keyword, or a keyword reference, visualizes the keyword excerpts from the reference's document. To close excerpt dialog press Esc or Left keys. See also \ref c2bciter, \ref c2bconf_files, and \ref commandline.

     

    */ /** \page relnotes Release Notes \section relnotes140 Release Note cb2Bib 1.4.0 The c2bciter module was introduced in version 1.3.0. Its name, as it was described, states its purpose of being "aimed to ease inserting citation IDs into documents". In fact, it does have such functionality. And, it has also another, equally important one: it provides a very fast way to retrieve a given work from our personal collections. Retrieving is accomplished through pre-sorted views of the references and filtering. Both, views and filtering, scale on the (tens of) thousands references. Usually, we recall a work from its publication year, a few words from its title, or (some of the letters of) one of its authors names. Often, what we remember is when a reference was included into our collection. Therefore, having such a chronological view was desirable. The implementation of this sorted-by-inclusion-date view was not done during the 1.3.x series, but postponed to version 1.4.0; somehow, to indicate that some sort of 'proprietary' BibTeX tag might be required to specify inclusion timestamps. I have been reluctant through the cb2Bib's life span to introduce 'cb2Bib-only' tags in the BibTeX outputs. I believe that there is little gain, and it costs, possibly, breaking interoperability. In the end, the choice was to not write any 'timestamp' tag in references. Instead, c2bciter checks for the last modified date of the linked documents to build an approximated chronological view. The advantage is that all, not just 'version 1.4.0 or later', references are sorted. Furthermore, if a reference is later corrected, and the document metadata is updated too, the modification date is reflected in the view. The obvious inconvenience is that no such sorting can be done for references without an attached document. See also \ref c2bciter.

     

    */ /** \page relnotes Release Notes \section relnotes130 Release Note cb2Bib 1.3.0 When version 0.2.7 came up, it was mentioned in \ref relnotes027 that cb2Bib 'doesn't have the means to automatically discern an author name from a department or street name'. I forgot mentioning, that I did not expect cb2Bib would have had such a feature. Since the last \ref relnotes110, the cb2Bib internals had changed significantly. Some changes, such heuristic recognition for interlaced authors and affiliations, get easily noticed. Other changes, however, do not, and need additional explanation. From version 1.2.3, the switches --txt2bib and --doc2bib set cb2Bib to work on console mode. The non-exact nature of the involved extractions makes logging necessary. On Windows, graphic or console modes must be decided not at run time, but when the application is built. So far, logging and globing were missing. This release adds the convenience wrapper c2bconsole. Typing c2bconsole --txt2bib i*.txt out.bib, for instance, will work as it does in the other platforms. Lists of references are now sorted case and diacritic insensitive. For some languages such a choice is not the expected one, and some operating systems offer local-aware collation. Due to usual inconsistencies and inaccuracies in references, this decision was taken to group together 'Density Matrix' with 'Density-matrix', and \htmlonly Møller \endhtmlonly with Moller, which, in a personal collection, most probably, refer to the same concept and to the same person. Additionally, document to text converted strings are now clean from extraneous, non-textual symbols. Therefore, recreating cache files is recommended. Finally, this release introduces a new module, named c2bciter, and aimed to ease inserting citation IDs into documents. The module should ideally stay idle at the system tray, and be recalled as needed by pressing a global, desktop shortcut. This functionality, while desirable, and usual in dictionaries, is platform and desktop dependent. On KDE there are currently known issues when switching among virtual desktops. See also \ref c2bciter, and \ref commandline.

     

    */ /** \page relnotes Release Notes \section relnotes110 Release Note cb2Bib 1.1.0 A frequent request from cb2Bib users has been to expand the command line functionality. So far few progress has been seen in this regard. First, the addition of in-document searches and reading/inserting metadata were priorities. Second, cb2Bib is not the tool to interconvert among bibliographic formats. And third, cb2Bib is designed to involve the user in the search process, in the archiving and validation of the discovered works and references. For the latter reason, and for not knowing a priori how would such a tool be designed, the cb2Bib internals had been interlaced to its graphical interface. At the time of version 0.7.0, when the graphical libraries changed, and a major refactoring was required, the code started moving toward a better modularization and structure. The current release pushes code organization further. As a result, it adds two new command line switches: --html-annote and --view-annote. The new cb2Bib module is named after the BibTeX key 'annote'. Annote is not for a 'one reference annotation' though. Instead, Annote is for short notes that interrelate several references. Annote takes a plain text note, with minimal or no markup, inserts the bibliographic citations, and converts it to a HTML page with links to the referenced documents. From within cb2Bib, to write your notes, type Alt+A, enter a filename, either new or existing, and once in Annote, type E to launch your default text editor. For help, type F1. Each time you save the document the viewer will be updated. To display mathematical notations, install \htmlonly jsMath \endhtmlonly locally. And, remember, code refactoring introduces bugs. See also \ref c2bannote and \ref commandline.

     

    */ /** \page relnotes Release Notes \section relnotes100 Release Note cb2Bib 1.0.0 Approximately four years ago the first cb2Bib was released. It included the possibility of easily linking a document to its bibliographic reference, in a handy way, by dragging the file to the main (at that time, single) panel. Now, in version 1.0.0, when a file is dropped, cb2Bib scans the document for metadata packets, and checks, in a rather experimental way, whether or not they contain relevant bibliographic information. Publishers metadata might or might not be accurate. Some, for instance, assign the DOI to the key Title. cb2Bib extracts possibly relevant key-value pairs and adds them to clipboard panel. Whenever key-value pairs are found accurate, just pressing Alt+G imports them to the line edits. If keys with the prefix bibtex are found, their values are automatically imported. The preparsed metadata that is added to the clipboard panel begins with [Bibliographic Metadata and ends with /Bibliographic Metadata]. Therefore, if you are using PDFImport together with a set of regular expressions, such that they contain the begin (^) or end ($) anchors, you can safely replace them by the above tags. In this manner, existing regular expressions remain useful with this minor change. And, with the advantage that, if recognition fails for a given document, metadata might give the hardest fields to extract from a PDF article, which are author and title. See also \ref metadata.

     

    */ /** \page relnotes Release Notes \section relnotes084 Release Note cb2Bib 0.8.4 The previous cb2Bib release added the command line option --conf [full_path]cb2bib.conf to specify the settings location. This feature was intended, mainly, as a clean way to run the program on a host computer from a removable drive. The work done focused on arranging the command line and settings related code. It was left for a later release to solve some requirements regarding the managing of file pathnames and temporary files. This release addresses these two points. Now, when cb2Bib is launched as cb2bib --conf --without a configuration filename-- it treats filenames as being relative to the cb2Bib actual location. Temporary files, if needed, will be placed at this location as well. Therefore, no data is being written on the host, and cb2Bib works independently of the actual address that the host assigns to the removable drive. The Windows' un/installer cleans/sets configuration data on the registry. Being aware of this particular, it might be better not to install the program directly to the USB drive. Just copy the cb2Bib base directory from a home/own computer to the removable drive, and then run it on the host computer as cb2bib --conf.

     

    */ /** \page relnotes Release Notes \section relnotes083 Release Note cb2Bib 0.8.3 cb2Bib accepts several arguments on its command line to access specific functionality. So far, the command cb2bib tmp_ref permits importing references from the browser, whenever a download to reference manager choice is available. In addition, the command cb2bib --bibedit ref.bib directly launches the BibTeX editor for file browsing and editing. This release adds the command line option --conf [full_path]cb2bib.conf to specifically set a file where all internal settings are being retrieved and stored. This has two interesting applications. On one hand, it easily permits switching from several sets of extraction rules, since the files abbreviations.txt, regexps.txt, and netqinf.txt are all stored in the cb2Bib's settings. And, on the other hand, it allows installing the program on a USB flash drive, and cleanly running it on any (e. g., library) computer. Settings can be stored and kept on the external device, and therefore, no data will be written on the registry or settings directory of the host computer. So far, however, this feature should be regarded as experimental. The Qt library to which cb2Bib is linked does read/write access to system settings in a few places (concretely, in file and color dialogs). On Unix and Mac OS systems this access can be modified by setting the environment variable DAG_CONFIG_HOME. No such workaround is presently available in Windows. See \ref commandline for a detailed syntax description.

     

    */ /** \page relnotes Release Notes \section relnotes081 Release Note cb2Bib 0.8.1 Several changes in this release affect installation and deployment. First, the cb2Bib internals for settings management has been reorganized. Version 0.8.1 will not read previous settings, as user colors, file locations, etc. On Unix, settings are stored at ~/.config/MOLspaces/cb2Bib.conf. This file can be removed, or renamed. On Windows, it is recommended to uninstall previous versions before upgrading. Second, cb2Bib tags are not shown by default. Instead, it is shown plain, raw clipboard data, as it is easier to identify with the original source. To write a regular expression, right click, on the menu, check 'View Tagged Clipboard Data', and perform the extraction from this view. And finally, cb2Bib adds the tag <> for network queries. It takes a simplified version of the clipboard contents and sends it to, e.g. Google Scholar. From there, one can easily import BibTeX references related to that contents. Therefore one should unchecked in most cases the 'Perform Network Queries after automatic reference extractions' box.

     

    */ /** \page relnotes Release Notes \section relnotes072 Release Note cb2Bib 0.7.2 cb2Bib reads the clipboard contents, processes it, and places it to the main cb2Bib's panel. If clipboard contents can be recognized as a reference, it writes the corresponding BibTeX entry. If not, the user can interact from the cb2Bib panel and complete or correct the reference. Additionally, this process permits to write down a regular expression matching the reference's pattern. To ease pattern writing, cb2Bib preprocesses the raw input data. This can consider format conversion by external tools and general substitutions, in addition to including some special tags. The resulting preprocessed data is usually less readable. A particularly illustrating case is when input data comes from a PDF article. cb2Bib now optionally presents input data, as raw, unprocessed data. This preserves the block text format of the source, and thus identifying the relevant bibliographic fields by visual inspection is more straightforward. In this raw mode view panel, interaction works in a similar manner. Except that, no conversions or substitutions are seen there, and that no regular expression tags are written.

     

    */ /** \page relnotes Release Notes \section relnotes070 Release Note cb2Bib 0.7.0 This release moves forward cb2Bib base requirement to Qt 4.2.0. Compilation errors related to rehighlight() library calls, kindly reported by Bongard, Seemann, and Luisser, should not appear anymore. File/URL opening is carried now by this library, in a desktop integrated manner. Additionally, Gnome users will enjoy better integration, as Cleanlooks widget style is available. All known regressions in 0.6.9x series have been fixed. Also, a few minor improvements have been included. In particular, file selection dialogs display navigation history, and BibTeX output file can be conveniently selected from the list of '*.bib' files at the current directory. Such a feature will be specially useful to users that sort references in thematic files located at a given directory.

     

    */ /** \page relnotes Release Notes \section relnotes0691 Release Note cb2Bib 0.6.91 This release fixes a regression in the cb2Bib network capabilities. Network, and hence querying was erratic, both for the internal HTTP routines and for external clients. In addition to this fix, the netqinf.txt has been updated. PubMed is working again. Queries are also extended to include DOI's. A possible applicability will be for indexing a set of PDF articles with PDFImport. If the article contains its DOI number, and 'Perform Network Queries after automatic reference extractions' is checked, chances are that automatic extractions will work smooth.

     

    */ /** \page relnotes Release Notes \section relnotes0690 Release Note cb2Bib 0.6.90 cb2Bib has been ported from Qt3 to Qt4, a migration in its underlying system library. Qt experienced many changes and improvements in this major release upgrade. Relevant to cb2Bib, these changes will provide a better file management, word completion, faster searches, and better desktop integration. Upgrading to Qt4 it is not a "plug and recompile" game. Thorough refactoring and rewriting was required. The resulting cb2Bib code is cleaner and more suitable to further development. As one might expect, major upgrades introduce new bugs that must be fixed. The cb2Bib 0.6.90 is actually a preview version. It has approximately the same functionality than its predecessor. So, no additions were considered at this point. Its use, bug reporting, and feedback are encouraged. This will help to get sooner a stable cb2Bib 0.7. To compile it, type ./configure as usual. The configure script calls the qmake tool to generate an appropriate Makefile. To make sure the right, Qt4 qmake is invocated, you can setup QTDIR environment variable prior to ./configure. The configure's call statement will then be '$QTDIR/bin/qmake'. E. g., type 'setenv QTDIR /usr' if qmake happens to be at the directory/usr/bin.

     

    */ /** \page relnotes Release Notes \section relnotes060 Release Note cb2Bib 0.6.0 cb2Bib uses the internal tags <> and <> to ease the creation of regular expressions for reference extraction. New line and tabular codes from the input stream are substituted by these numbered tags. Numbering new lines and tabulars gives an extra safety when writing down a regular expression. E. g., suppose field title is 'anything' between '<> and <>'. We can then easily write 'anything' as '.+' without the risk of overextending the caption to several '\\n' codes. On the other hand, one still can use <> if not interested in a specific numbering. All these internal tags are later removed, once cb2Bib postprocesses the entry fields. The cb2Bib identified so far new lines by checking for '\\n' codes. I was unaware that this was a platform dependent, as well as a not completely accurate way of detecting new lines. McKay Euan reported that <> tags were not appearing as expected in the MacOSX version. I later learn that MacOSX uses '\\r' codes, and that Windows uses '\\r\\n', instead of '\\n' for new line encoding. This release addresses this issue. It is supposed now that the cb2Bib regular expressions will be more transferable among the different platforms. Extraction from plain text sources is expected to be completely platform independent. Extraction from web pages will still remain browser dependent. In fact, each browser adds its peculiar interpretation of a given HTML source. For example, in Wiley webpages we see the sectioning header 'Abstract' in its source and in several browsers, but we see, and get, 'ABSTRACT' if using Konqueror. What we pay for this more uniform approach is, however, a break in compatibility with previous versions of cb2Bib. Unix/Linux users should not expect many differences, though. Only one from the nine regular expressions in the examples needed to be modified, and the two contributed regular expressions work perfectly without any change. Windows users will not see a duplication of <> tags. To update previous expressions it should be enough just shifting the <> numbering. And, of course, any working regular expression that does not uses <> tags will still be working in this new version. Finally, just to mention that I do not have a MacOSX to test any of the cb2Bib releases in this particular platform. I am therefore assuming that these changes will fix the problem at hand. If otherwise, please, let me know. Also, let me know if release 0.6.0 'break' your own expressions. I consider this release a sort of experimental or beta version, and the previous version 0.5.3, will still be available during this testing period.

     

    */ /** \page relnotes Release Notes \section relnotes050 Release Note cb2Bib 0.5.0 Two issues had appeared regarding cb2Bib installation and deployment on MacOSX platforms. First, if you encounter a 'nothing to install'-error during installation on MacOSX 10.4.x using the cb2Bib binary installer available at naranja.umh.es/~atg/, please delete the cb2bib-receipts from /Library/Receipts and then rerun the installer. See also M. Bongard's clarifying note 'MACOSX 10.4.X "NOTHING TO INSTALL"-ERROR' for details. Second, and also extensible to other cb2Bib platform versions, if PDFImport issues the error message 'Failed to call some_format_to_text' tool, make sure such a tool is installed and available. Go to Configure->PDFImport, click at the 'Select External Convert Tool' button, and navigate to set its full path. Since version 0.5.0 the default full path for the MacOSX is already set, and pointing to /usr/local/bin/pdftotext.

     

    */ /** \page relnotes Release Notes \section relnotes041 Release Note cb2Bib 0.4.1 Qt/KDE applications emit notifications whenever they change the clipboard contents. cb2Bib uses these notifications to automatically start its 'clipboard to BibTeX' processing. Other applications, however, does not notify about them. Since version 0.2.1, see \ref relnotes021, cb2Bib started checking the clipboard periodically. This checking was later disabled as a default, needing a few lines of code to be uncomented to activate it. Without such a checking, cb2Bib appears unresponsive when selecting/copying from e.g., acroread or Mozilla. This release includes the class clipboardpoll written by L. Lunak for the KDE's Klipper. Checking is performed in a very optimized way. This checking is enabled by default. If you experience problems with this feature, or if the required X11 headers aren't available, consider disabling it by typing ./configure --disable-cbpoll prior to compilation. This will disable checking completely. If the naive, old checking is preferred, uncomment the four usual lines, ./configure --disable-cbpoll, and compile.

     

    */ /** \page relnotes Release Notes \section relnotes035 Release Note cb2Bib 0.3.5 Releases 0.3.3 and 0.3.4 brought querying functionality to cb2Bib. In essence, cb2Bib was rearranged to accommodate copying and opening of network files. Queries were then implemented as user customizable HTML posts to journal databases. In addition, these arrangements permitted defining convenience, dynamic bookmarks that were placed at the cb2Bib's 'About' panel. cb2Bib contains three viewing panels: 'About', 'Clipboard' and 'View BibTeX', being the 'Clipboard' panel the main working area. To keep cb2Bib simple, only two buttons, 'About' and 'View BibTeX', are set to navigate through the panels. The 'About' and 'View BibTeX' buttons are toggle buttons for momentarily displaying their corresponding panels. Guidance was so far provided by enabling/disabling the buttons. After the bookmark introduction, the 'About' panel has greatly increased its usefullness. Button functionality has been slightly redesigned now to avoid as many keystrokes and mouse clicks as possible. The buttons remain switchable, but they no longer disable the other buttons. User is guided by icon changes instead. Hopefully these changes will not be confusing or counterintuitive. Bookmarks and querying functionality are customizable through the netqinf.txt file, which is editable by pressing the Alt+B keys. Supported queries are of the form 'Journal-Volume-First Page'. cb2Bib parses netqinf.txt each time a query is performed. It looks for journal=Full_Name|[code] to obtain the required information for a specific journal. Empty, 'journal=' entries have a meaning of 'any journal'. New in this release, cb2Bib will test all possible queries for a given journal instead of giving up at the first No article found message. The query process stops at the first successfull hit or, otherwise, once netqinf.txt is parsed completely (in an equivalent way as the automatic pattern recognition works). This permits querying multiple -and incomplete- journal databases. Users should order the netqinf.txt file in a way it is more convenient. E.g., put PubMed in front of JACS if desired an automatic extraction. Or JACS in front of PubMed and extract from the journal web page, if author accented characters are wanted. So far, this querying functionality is still tagged as experimental. Either the querying itself or its syntax seem quite successful. However, downloading of PDF files, on windows OS + T1 network, was found to freeze once progress reaches the 30-50%. Any feedback on this issue will be greatly appreciated. Also, information on kfmclient equivalent tools for non KDE desktops would be worth to be included in the cb2Bib documentation.

     

    */ /** \page relnotes Release Notes \section relnotes030 Release Note cb2Bib 0.3.0 cb2Bib considers the whole set of authors as an author-string pattern. This string is later postprocessed, without requirements on the actual number of authors it may contain, or on how the names are written. Once considered author-string patterns, the extraction of bibliographic references by means of regular expressions becomes relatively simple. There are situations, however, where several author-strings are required. The following box shows one of these cases. Authors are grouped according to their affiliations. Selecting from 'F. N. First' to 'F. N. Fifth' would include 'First Affiliation' within the author string. Cleaning up whatever wording 'First Affiliation' may contain is a rather ill-posed problem. Instead, cb2Bib includes an Add Authors option. The way of operation is then to select 'F. N. First, F. N. Second, F. N. Third' and chose Authors and right after, select 'F. N. Fourth and F. N. Fifth' and chose Add Authors. \verbatim Journal Name, 10, 1100-1105, 2004 AN EXAMPLE WITH MULTIPLE AUTHOR SETS F. N. First, F. N. Second, F. N. Third First Affiliation F. N. Fourth and F. N. Fifth Second Affiliation Abstract: Select from "Journal Name ..." to "... second author set.". The 'F. N. First, F. N. Second, F. N. Third' author string is automatically processed as one author set, while 'F. N. Fourth and F. N. Fifth' is processed as another, second author set. \endverbatim At this point in the manual extraction, the user was faced with a red <> tag in the cb2Bib clipboard panel. The <> tag was intended to warn the user about the fact that cb2Bib would not be able to consider the resulting extraction pattern as a valid, general regular expression. Usual regular expressions are built up from an a priori known level of nesting. In these cases, however, the level of nesting is variable. It depends on the number of different affiliations occurring in a particular reference. So far the <> tag has become a true FAQ about cb2Bib and a source of many confusions. There is no real need, however, for such an user warning. The <> has therefore been removed and cb2Bib has taken an step further, to its 0.3.0 version. The cb2Bib 0.3.0 manual extraction works as usual. By clicking Authors the Authors edit line is reseted and selection contents moved there. Alternatively, if Add Authors is clicked, selection contents is added to the author field. On this version, however, both operations are tagged as <> (singular form, as it is the BibTeX keyword for Authors). The generated extraction pattern can now contain any number of <> fields. In automatic mode, cb2Bib now adds all author captions to Authors. In this way, cb2Bib can treat interlaced author-affiliation cases. Obviously, users needing such extractions will have to write particular regular expressions for cases with one set of authors, for two sets, and so on. Eventhough it is not rare a work having a hundred of authors, it would be quite umprobable that they were working on so many different institutions. Therefore, few regular expressions should actually be required in practice. Although not elegant, this breaks what was a cb2Bib limitation and broadens its use when extracting from PDF sources. Remember here to sort these regular expressions in decreasing order, since at present, cb2Bib stops at the first hit. Also, consider Any Pattern to get ride of the actual affiliation contents, as you might not want to extract authors addresses.

     

    */ /** \page relnotes Release Notes \section relnotes027 Release Note cb2Bib 0.2.7 The cb2Bib 0.2.7 release introduces multiple retrieving from PDF files. PDF documents are becoming more and more widely used, not only to transfer and printing articles, but also are substituting the personal paper files and classifiers for the electronic equivalents. cb2Bib is intended to help updating personal databases of papers. It is a tool focused on what is left behind in database retrieving. Cases such as email alerts, or inter colleague references and PDF sharing are example situations. Though in an electronic format, sources are not standardized or not globally used as to permit using habitual import filters in reference managers. cb2Bib is designed to consider a direct user intervention, either by creating its own useful filters or by a simple copy-paste assistance when handtyping. Hopefully someday cb2Bib will be able to take that old directory, with perhaps a few hundreds of papers, to automatically index the references and rename the files by author, in a consistent manner. The required mechanism is already there, in this version. But I guess that this new feature will manifest some present limitations in cb2Bib. For instance, most printed and PDF papers interlace author names and affiliations. cb2Bib doesn't have the means to automatically discern an author name from a department or street name. So far one needs to manually use the 'Add to Authors' feature to deal with these situations. Also, the managing of regular expressions needs developing, specially thinking in the spread variety of design patterns in publications. In summary, this current version is already useful in classifying and extracting the reference of that couple of papers that someone send right before submitting a work. A complete unsupervised extraction is still far away, however.

     

    */ /** \page relnotes Release Notes \section relnotes021 Release Note cb2Bib 0.2.1 The cb2Bib mechanism 'select-and-catch' failed in some cases. Acrobat and Mozilla selections were not always notified to cb2Bib. Indeed, this 'window manager - application' connection seems to be broken on a KDE 3.3.0 Qt 3.3.3 system. The cb2Bib 0.2.1 continues to listen to system clipboard change notifications, whenever they are received and whenever cb2Bib is on connected mode. Additionally, the cb2Bib 0.2.1 periodically checks for changes in the system clipboard. Checks are performed every second, approximately. This permits cb2Bib to work as usual, although one could experience 1-2 seconds delays in systems where the automatic notification is broken. If the 'select-and-catch' functionality appears 'sticky', possibly happening while using non KDE applications from where text is selected, check the source file c2bclipboard.cpp, look for 'Setting timer', and set variable interval to 1000. This is the interval of time in ms that cb2Bib will use to check for clipboard changes.

     

    */ cb2Bib::cb2Bib(QWidget* parentw) : QMainWindow(parentw), _connected(false), _is_check_repeated_done(false), _modified(false), _tagged_view_mode(false) { _settingsP = c2bSettingsP; ui.setupUi(this); connect(ui.id, SIGNAL(textChanged(QString)), this, SLOT(setWindowTitle(QString))); // Creating cb2Bib global resources c2b* c2b_resources = new c2b(this, this); connect(c2b_resources, SIGNAL(statusMessage(QString)), this, SLOT(showMessage(QString))); connect(c2b_resources, SIGNAL(searchInFiles(QString,QString)), this, SLOT(doSearchInFiles(QString,QString))); // Actions and shortcuts c2bUtils::addSeparator(this); addAction(ui.checkRepeatedAction); _settingsP->setKeysequence("Shortcuts/cb2Bib/", ui.checkRepeatedAction); c2bUtils::addSeparator(this); addAction(ui.clearFieldsAction); _settingsP->setKeysequence("Shortcuts/cb2Bib/", ui.clearFieldsAction); addAction(ui.guessFieldsAction); _settingsP->setKeysequence("Shortcuts/cb2Bib/", ui.guessFieldsAction); addAction(ui.startEngineAction); _settingsP->setKeysequence("Shortcuts/cb2Bib/", ui.startEngineAction); c2bUtils::addSeparator(this); addAction(ui.preparseClipboardAction); _settingsP->setKeysequence("Shortcuts/cb2Bib/", ui.preparseClipboardAction); addAction(ui.postprocessBibTeXAction); _settingsP->setKeysequence("Shortcuts/cb2Bib/", ui.postprocessBibTeXAction); c2bUtils::addSeparator(this); addAction(ui.editBookmarksAction); _settingsP->setKeysequence("Shortcuts/cb2Bib/", ui.editBookmarksAction); addAction(ui.editAbbreviationsAction); _settingsP->setKeysequence("Shortcuts/cb2Bib/", ui.editAbbreviationsAction); addAction(ui.editRegExpsAction); _settingsP->setKeysequence("Shortcuts/cb2Bib/", ui.editRegExpsAction); c2bUtils::addSeparator(this); addAction(ui.openAnnoteAction); _settingsP->setKeysequence("Shortcuts/cb2Bib/", ui.openAnnoteAction); c2bUtils::addSeparator(this); addAction(ui.insertRegExpAction); _settingsP->setKeysequence("Shortcuts/cb2Bib/", ui.insertRegExpAction); addAction(ui.viewTaggedClipEditAction); _settingsP->setKeysequence("Shortcuts/cb2Bib/", ui.viewTaggedClipEditAction); setAcceptDrops(true); c2bUtils::addSeparator(ui.file); ui.file->addAction(ui.selectFileAction); _settingsP->setKeysequence("Shortcuts/cb2Bib/", ui.selectFileAction); ui.file->addAction(ui.openFileDocumentAction); _settingsP->setKeysequence("Shortcuts/cb2Bib/", ui.openFileDocumentAction); ui.openFileDocumentAction->setEnabled(false); QShortcut* sc(new QShortcut(this)); _settingsP->setKeysequence("Shortcuts/cb2Bib/Delete Temporary BibTeX File", sc); connect(sc, SIGNAL(activated()), this, SLOT(deleteTmpBib())); sc = new QShortcut(this); _settingsP->setKeysequence("Shortcuts/cb2Bib/Write Metadata to Document", sc); connect(sc, SIGNAL(activated()), this, SLOT(addMetadata())); sc = new QShortcut(this); _settingsP->setKeysequence("Shortcuts/cb2Bib/Toggle Reference Tabs", sc); connect(sc, SIGNAL(activated()), this, SLOT(toggleReferenceTabs())); sc = new QShortcut(QKeySequence(Qt::Key_F2), this); // Made consistent with c2bCiter and c2bEditor connect(sc, SIGNAL(activated()), this, SLOT(hide())); ClipEdit = new c2bClipEdit(c2bClipEdit::Editor, this); ClipEdit->setObjectName("ClipEdit"); ClipEdit->addActions(actions()); ui.stackedWidget->addWidget(ClipEdit); AboutBrowser = new c2bTextBrowser(this); AboutBrowser->setObjectName("AboutBrowser"); AboutBrowser->addActions(actions()); ui.stackedWidget->addWidget(AboutBrowser); BibBrowser = new c2bClipEdit(c2bClipEdit::Browser, this); BibBrowser->setObjectName("BibBrowser"); BibBrowser->addActions(actions()); ui.stackedWidget->addWidget(BibBrowser); connect(AboutBrowser, SIGNAL(anchorClicked(QUrl)), this, SLOT(linkClicked(QUrl))); connect(AboutBrowser, SIGNAL(highlighted(QString)), this, SLOT(showLink(QString))); // Connect Actions connect(ui.checkRepeatedAction, SIGNAL(triggered()), this, SLOT(checkRepeated())); connect(ui.clearFieldsAction, SIGNAL(triggered()), this, SLOT(c2bInit())); connect(ui.editAbbreviationsAction, SIGNAL(triggered()), this, SLOT(abbreviationsEditor())); connect(ui.editBookmarksAction, SIGNAL(triggered()), this, SLOT(bookmarksEditor())); connect(ui.editRegExpsAction, SIGNAL(triggered()), this, SLOT(regExpsEditor())); connect(ui.guessFieldsAction, SIGNAL(triggered()), this, SLOT(guessFields())); connect(ui.insertRegExpAction, SIGNAL(triggered()), this, SLOT(insertRegExp())); connect(ui.openAnnoteAction, SIGNAL(triggered()), this, SLOT(openAnnote())); connect(ui.openFileDocumentAction, SIGNAL(triggered()), this, SLOT(openFileDocument())); connect(ui.postprocessBibTeXAction, SIGNAL(triggered()), this, SLOT(postprocessBibTeX())); connect(ui.preparseClipboardAction, SIGNAL(triggered()), this, SLOT(preparseClipboard())); connect(ui.selectFileAction, SIGNAL(triggered()), this, SLOT(selectFile())); connect(ui.startEngineAction, SIGNAL(triggered()), this, SLOT(restartEngine())); connect(ui.viewTaggedClipEditAction, SIGNAL(triggered(bool)), this, SLOT(setTaggedClipEditMode(bool))); setBibMenu(); _pdfImportP = 0; _searchInFilesP = 0; setTaggedClipEditMode(false); // Set checkRepeated ui.checkRepeatedAction->setVisible(false); connect(ui.author, SIGNAL(textChanged(QString)), this, SLOT(updateCheckRepeatedAction())); connect(ui.booktitle, SIGNAL(textChanged(QString)), this, SLOT(updateCheckRepeatedAction())); connect(ui.editor, SIGNAL(textChanged(QString)), this, SLOT(updateCheckRepeatedAction())); connect(ui.id, SIGNAL(textChanged(QString)), this, SLOT(updateCheckRepeatedAction())); connect(ui.title, SIGNAL(textChanged(QString)), this, SLOT(updateCheckRepeatedAction())); // cb2Bib Settings loadSettings(); connect(_settingsP, SIGNAL(newSettings()), this, SLOT(loadSettings())); resize(_settingsP->value("cb2Bib/size", size()).toSize()); ui.bibtexfile->completer()->setCompletionMode(QCompleter::PopupCompletion); updateBibfile(_settingsP->fileName("cb2Bib/BibTeXFile")); // Setting Bibliographic Parser _bpP = c2b::bibParser(); setWidgetMapping(); ui.AddBibB->setEnabled(_modified); // Setting cb2bib network queries _netQP = new c2bNetworkQuery(_bpP, c2b::net(), this); connect(_netQP, SIGNAL(statusMessage(QString)), c2b_resources, SIGNAL(statusMessage(QString))); connect(_netQP, SIGNAL(queryEnded(bool,QString,QString)), this, SLOT(netQueryEnded(bool,QString,QString))); // Set citer if (_settingsP->cl_citer) { _citerP = new c2bCiterWidget; _citerP->setTrayIcon(); _citerP->load(); connect(_citerP, SIGNAL(openAnnote()), this, SLOT(openAnnote())); connect(_citerP, SIGNAL(openFile(QString)), this, SLOT(bibEditor(QString))); } else _citerP = 0; // Connecting cb2Bib clipboard and start c2bClipboard* cbP = c2b::clipboard(); connect(cbP, SIGNAL(cbDataChanged(QString)), this, SLOT(dataChanged(QString))); on_ConnectB_clicked(); // Set button and update _connected dataChanged(QString()); if (_settingsP->cl_bibedit) initAsBibTeXEditor(); } cb2Bib::~cb2Bib() { delete _citerP; delete _searchInFilesP; } /**************************************************************************** GUI FUNCTIONALITY *****************************************************************************/ void cb2Bib::show() { if (_settingsP->cl_citer && _citerP) _citerP->toggleVisible(); else if (!_settingsP->cl_bibedit) QMainWindow::show(); } void cb2Bib::on_ViewAboutB_clicked() { if (ui.stackedWidget->currentWidget() == AboutBrowser) { ui.stackedWidget->setCurrentWidget(ClipEdit); ClipEdit->setFocus(); } else { const QColor linkColor(palette().buttonText().color()); const QString sheet(QString::fromLatin1("a { text-decoration: underline; color: %1 }").arg(linkColor.name())); AboutBrowser->document()->setDefaultStyleSheet(sheet); const QString AboutS( tr("

    cb2Bib %1

    " "

    " "Bibliographic Reference Extracting and Managing Tool
    " "

    " "

    " "" "cb2Bib Help and User's Guide


    " "

    Additional Functionality:

    " "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "
    KeysDescription
    " + _settingsP->ksname("Shortcuts/cb2Bib/Check Repeated") + "Check repeated
    " + _settingsP->ksname("Shortcuts/cb2Bib/Delete Temporary BibTeX File") + "Delete temporary BibTeX file
    " + _settingsP->ksname("Shortcuts/cb2Bib/Edit Bookmarks") + "Edit bookmarks
    " + _settingsP->ksname("Shortcuts/cb2Bib/Edit Journal Abbreviations") + "Edit journal abbreviations
    " + _settingsP->ksname("Shortcuts/cb2Bib/Edit Regular Expressions") + "Edit regular expressions
    " + _settingsP->ksname("Shortcuts/cb2Bib/Insert Regular Expression") + "Insert regular expression
    " + _settingsP->ksname("Shortcuts/cb2Bib/Open Document") + "Open document
    " + _settingsP->ksname("Shortcuts/cb2Bib/Postprocess BibTeX") + "Postprocess BibTeX
    " + _settingsP->ksname("Shortcuts/cb2Bib/Preparse Clipboard") + "Preparse clipboard
    " + _settingsP->ksname("Shortcuts/cb2Bib/Restart Recognition") + "Restart recognition
    " + _settingsP->ksname("Shortcuts/cb2Bib/Select Document File") + "Select document file
    " + _settingsP->ksname("Shortcuts/cb2Bib/Annote Editor") + "Open cb2Bib Annote
    " + _settingsP->ksname("Shortcuts/cb2Bib/Toggle Reference Tabs") + "Toggle reference tabs
    " + _settingsP->ksname("Shortcuts/cb2Bib/Write Metadata to Document") + "Write metadata to document
    EscQuit cb2Bib popup menu
    Right ClickShow cb2Bib main panel popup menu" "
    " "
    %2
    " "

    Copyright (C) 2004-2021 by Pere Constans
    " "" "https://www.molspaces.com/cb2bib/

     " "

    cb2Bib is licensed under the terms of the " "" "GNU General Public License version 3" "

     ") .arg(C2B_VERSION, c2b::netqinf()->bookmarksToHtml())); const int scrollPosition(AboutBrowser->verticalScrollBar()->value()); AboutBrowser->setHtml(AboutS); AboutBrowser->verticalScrollBar()->setValue(scrollPosition); ui.stackedWidget->setCurrentWidget(AboutBrowser); AboutBrowser->setFocus(); } updateViewButtons(); } void cb2Bib::on_ConfigureB_clicked() { c2b::configure(); } void cb2Bib::on_SearchInFilesB_clicked() { doSearchInFiles(); } void cb2Bib::on_PdfImportB_clicked() { if (!_pdfImportP) { _pdfImportP = new c2bPdfImport; _pdfImportP->setAttribute(Qt::WA_DeleteOnClose); connect(this, SIGNAL(addedBibToFile(QString)), _pdfImportP, SLOT(processNext())); connect(this, SIGNAL(endedProcessing(bool)), _pdfImportP, SLOT(referenceExtacted(bool))); connect(_pdfImportP, SIGNAL(textProcessed(QString)), this, SLOT(forceDataChange(QString))); connect(_pdfImportP, SIGNAL(fileProcessed(QString)), this, SLOT(fileDropped(QString))); connect(_pdfImportP, SIGNAL(saveReferenceRequest()), this, SLOT(on_AddBibB_clicked())); connect(_pdfImportP, SIGNAL(setClipboardDisabled(bool)), ui.ConnectB, SLOT(setDisabled(bool))); showMessage(tr("PDF Import launched.")); } _pdfImportP->show(); } void cb2Bib::on_ExitB_clicked() { c2b::instance()->exitRequested(); } void cb2Bib::on_ConnectB_clicked() { if (_connected) { ui.ConnectB->setIcon(QIcon(C2B_ICON_DIR + C2B_ICON_DISCONNECT_B)); ui.ConnectB->setStatusTip(buttonStatusTip(tr("Connect clipboard"), ui.ConnectB->shortcut())); _connected = false; } else { ui.ConnectB->setIcon(QIcon(C2B_ICON_DIR + C2B_ICON_CONNECT_B)); ui.ConnectB->setStatusTip(buttonStatusTip(tr("Disconnect clipboard"), ui.ConnectB->shortcut())); _connected = true; } } void cb2Bib::on_MakeNetworkQueryB_clicked() { makeNetQuery(); } void cb2Bib::on_ViewBibB_clicked() { if (ui.stackedWidget->currentWidget() == BibBrowser) { ui.stackedWidget->setCurrentWidget(ClipEdit); ClipEdit->setFocus(); } else { BibBrowser->updatePlainText(_bpP->toBibTeX()); ui.stackedWidget->setCurrentWidget(BibBrowser); BibBrowser->setFocus(); } updateViewButtons(); } void cb2Bib::on_AddBibB_clicked() { // Prepare Save Reference to file ui.AddBibB->setEnabled(false); if (!_is_check_repeated_done && _settingsP->value("cb2Bib/CheckRepeatedOnSave").toBool()) { _is_check_repeated_done = true; if (isReferenceRepeated()) { ui.AddBibB->setEnabled(_modified); return; } } QFile bibtexfile(ui.bibtexfile->currentText()); bool is_writable; if (bibtexfile.exists()) is_writable = bibtexfile.open(QIODevice::WriteOnly | QIODevice::Text | QIODevice::Append); else is_writable = bibtexfile.open(QIODevice::WriteOnly | QIODevice::Text); if (!is_writable) { QMessageBox::information(this, tr("Information - cb2Bib"), tr("Unable to open file %1 for writing.\nError: '%2'.") .arg(ui.bibtexfile->currentText(), bibtexfile.errorString()), QMessageBox::Ok); ui.AddBibB->setEnabled(_modified); return; } if (_dropped_document_file.isEmpty() || ui.file->text().isEmpty() || !_settingsP->value("cb2Bib/MovePdf").toBool()) { _target_document_file.clear(); addToFile(true); } else { _target_document_file = c2bUtils::documentAbsoluteName( _settingsP->value("cb2Bib/RelativePdfDirectory").toBool(), ui.bibtexfile->currentText(), _settingsP->fileName("cb2Bib/PdfDirectory"), ui.file->text()); const QString doc_dir_name(QFileInfo(_target_document_file).absolutePath()); QDir doc_dir(doc_dir_name); if (!doc_dir.exists()) if (!doc_dir.mkpath(doc_dir_name)) { QMessageBox::information(this, tr("Information - cb2Bib"), tr("Unable to create directory %1.").arg(doc_dir_name), QMessageBox::Ok); ui.AddBibB->setEnabled(_modified); return; } const network::Action CopyMovePdf(network::actionType(_settingsP->value("cb2Bib/CopyMovePdf").toString())); c2b::net()->getFile(_dropped_document_file, _target_document_file, CopyMovePdf, this, SLOT(addToFile(bool))); } } void cb2Bib::on_EditBibTeXB_clicked() { bibEditor(ui.bibtexfile->currentText()); } void cb2Bib::on_BibTeXDir_clicked() { const QString fn(c2bFileDialog::getFilename(this, "Select a BibTeX filename", ui.bibtexfile->currentText(), "BibTeX (*.bib);;All (*)")); if (!fn.isEmpty()) updateBibfile(fn); } void cb2Bib::loadSettings() { ClipEdit->setFont(_settingsP->c2bMonoFont); BibBrowser->setFont(_settingsP->c2bMonoFont); AboutBrowser->setFont(_settingsP->c2bMonoFont); ui.AddBibB->setShortcut(QKeySequence::Save); ui.EditBibTeXB->setShortcut(QKeySequence::Open); ui.SearchInFilesB->setShortcut(QKeySequence::Find); ui.ExitB->setShortcut(QKeySequence::Quit); ui.BibTeXDir->setShortcut(_settingsP->keysequence("Shortcuts/cb2Bib/Select BibTeX File")); ui.ConfigureB->setShortcut(_settingsP->keysequence("Shortcuts/cb2Bib/Button Configure")); ui.ConnectB->setShortcut(_settingsP->keysequence("Shortcuts/cb2Bib/Button Toggle Connection")); ui.MakeNetworkQueryB->setShortcut(_settingsP->keysequence("Shortcuts/cb2Bib/Button Network Query")); ui.PdfImportB->setShortcut(_settingsP->keysequence("Shortcuts/cb2Bib/Button Start PDFImport")); ui.ViewAboutB->setShortcut(_settingsP->keysequence("Shortcuts/cb2Bib/Button About and Bookmarks")); ui.ViewBibB->setShortcut(_settingsP->keysequence("Shortcuts/cb2Bib/Button View BibTeX")); ui.AddBibB->setStatusTip(buttonStatusTip(tr("Save reference to BibTeX file"), ui.AddBibB->shortcut())); ui.BibTeXDir->setStatusTip(buttonStatusTip(tr("Select BibTeX file"), ui.BibTeXDir->shortcut())); ui.ConfigureB->setStatusTip(buttonStatusTip(tr("Configure cb2Bib"), ui.ConfigureB->shortcut())); ui.ConnectB->setStatusTip( buttonStatusTip(_connected ? tr("Disconnect clipboard") : tr("Connect clipboard"), ui.ConnectB->shortcut())); ui.EditBibTeXB->setStatusTip(buttonStatusTip(tr("Open BibTeX file"), ui.EditBibTeXB->shortcut())); ui.ExitB->setStatusTip(buttonStatusTip(tr("Close all windows and exit"), ui.ExitB->shortcut())); ui.MakeNetworkQueryB->setStatusTip( buttonStatusTip(tr("Network query for current reference"), ui.MakeNetworkQueryB->shortcut())); ui.PdfImportB->setStatusTip( buttonStatusTip(tr("Import references from a set of PDF files"), ui.PdfImportB->shortcut())); ui.SearchInFilesB->setStatusTip( buttonStatusTip(tr("Search BibTeX file for references"), ui.SearchInFilesB->shortcut())); updateViewButtons(); } QString cb2Bib::buttonStatusTip(const QString& ms, const QKeySequence& ks) const { if (ks.isEmpty()) return ms; else return ms + QLatin1String(" - ") + ks.toString(QKeySequence::NativeText); } void cb2Bib::updateViewButtons() { QWidget* viewing = ui.stackedWidget->currentWidget(); if (viewing == BibBrowser) { ui.ViewBibB->setIcon(QIcon(C2B_ICON_DIR + C2B_ICON_VIEWC2B_B)); ui.ViewAboutB->setIcon(QIcon(C2B_ICON_DIR + C2B_ICON_ABOUT_B)); ui.ViewBibB->setStatusTip(buttonStatusTip(tr("View cb2Bib clipboard"), ui.ViewBibB->shortcut())); ui.ViewAboutB->setStatusTip( buttonStatusTip(tr("About cb2bib and cb2bib bookmarks"), ui.ViewAboutB->shortcut())); } else if (viewing == AboutBrowser) { ui.ViewBibB->setIcon(QIcon(C2B_ICON_DIR + C2B_ICON_VIEWBIB_B)); ui.ViewAboutB->setIcon(QIcon(C2B_ICON_DIR + C2B_ICON_ABOUT_B_BACK)); ui.ViewBibB->setStatusTip(buttonStatusTip(tr("View BibTeX for current reference"), ui.ViewBibB->shortcut())); ui.ViewAboutB->setStatusTip(buttonStatusTip(tr("Back to cb2Bib clipboard"), ui.ViewAboutB->shortcut())); } else { ui.ViewBibB->setIcon(QIcon(C2B_ICON_DIR + C2B_ICON_VIEWBIB_B)); ui.ViewAboutB->setIcon(QIcon(C2B_ICON_DIR + C2B_ICON_ABOUT_B)); ui.ViewBibB->setStatusTip(buttonStatusTip(tr("View BibTeX for current reference"), ui.ViewBibB->shortcut())); ui.ViewAboutB->setStatusTip( buttonStatusTip(tr("About cb2bib and cb2bib bookmarks"), ui.ViewAboutB->shortcut())); } } void cb2Bib::toggleReferenceTabs() { if (ui.tabWidget->currentIndex() == 0) ui.tabWidget->setCurrentIndex(1); else ui.tabWidget->setCurrentIndex(0); } void cb2Bib::updateBibfile(const QString& fn) { ui.bibtexfile->clear(); QFileInfo fi(fn); const QStringList flist(fi.isDir() ? c2bUtils::filesInDir(fn, QStringList() << "*.bib") : c2bUtils::filesInDir(fi.absolutePath(), QStringList() << "*.bib")); for (int i = 0; i < flist.count(); ++i) ui.bibtexfile->addItem(flist.at(i)); const int index(ui.bibtexfile->findText(fn)); if (index == -1) ui.bibtexfile->setEditText(fn); else ui.bibtexfile->setCurrentIndex(index); } void cb2Bib::showLink(const QString& ln) { statusBar()->showMessage(c2b::encodeLink(ln), C2B_MESSAGE_TIME); } void cb2Bib::showMessage(const QString& ms) { statusBar()->showMessage(ms, C2B_MESSAGE_TIME); } void cb2Bib::dragEnterEvent(QDragEnterEvent* qevent) { if (qevent->mimeData()->hasUrls()) qevent->acceptProposedAction(); } void cb2Bib::dropEvent(QDropEvent* qevent) { QList fns = qevent->mimeData()->urls(); if (fns.count() > 0) { if (fns.at(0).scheme() == "file") { c2bUtils::setWidgetOnTop(this); fileDroppedByUser(fns.at(0).toLocalFile().trimmed()); } else fileDroppedByUser(fns.at(0).toString().trimmed()); } qevent->acceptProposedAction(); } void cb2Bib::fileDroppedByUser(const QString& fn) { if (fn.isEmpty()) return; bool has_bibtex(false); if (_settingsP->value("cb2Bib/AddMetadata").toBool()) { const QString metadata(c2b::documentMetadata(fn)); if (!metadata.isEmpty()) { QString text(ClipEdit->toPlainText()); if (_settingsP->value("cb2Bib/PreAppendMetadata").toString() == "prepend") text = metadata + text; else text = text + '\n' + metadata; has_bibtex = _bpP->hasBibTeX(metadata); if (has_bibtex) forceDataChange(text); else ClipEdit->setText(text); } } fileDropped(fn); if (!has_bibtex) showMessage(tr("Scheduled inclusion of file '%1'.").arg(fn)); if (QFileInfo::exists(fn)) _settingsP->setFilename("cb2Bib/LastDroppedFile", fn); } void cb2Bib::fileDropped(const QString& fn) { if (fn.isEmpty()) return; _dropped_document_file = fn.trimmed(); ui.openFileDocumentAction->setEnabled(true); ui.openFileDocumentAction->setText(tr("Open '%1'").arg(_dropped_document_file)); setDocumentFilename(); if (_settingsP->value("cb2Bib/MovePdf").toBool()) ui.file->setStatusTip(tr("From file '%1'.").arg(_dropped_document_file)); } void cb2Bib::closeEvent(QCloseEvent* qevent) { if (_pdfImportP) _pdfImportP->close(); if (_searchInFilesP) _searchInFilesP->close(); _settingsP->setValue("cb2Bib/size", size()); _settingsP->setFilename("cb2Bib/BibTeXFile", QFileInfo(ui.bibtexfile->currentText()).absoluteFilePath()); qevent->accept(); } void cb2Bib::setTaggedClipEditMode(bool tagged) { _tagged_view_mode = tagged; ui.insertRegExpAction->setEnabled(tagged); ClipEdit->setTaggedViewMode(tagged); if (_tagged_view_mode) _bib_menu->setAnyPatternText(tr("Any Pattern")); else _bib_menu->setAnyPatternText(tr("Delete")); ui.stackedWidget->setCurrentWidget(ClipEdit); ClipEdit->setFocus(); updateViewButtons(); } void cb2Bib::doSearchInFiles(const QString& string, const QString& fn) { if (!_searchInFilesP) { _searchInFilesP = new c2bSearchInFiles(ui.bibtexfile->currentText()); connect(ui.bibtexfile, SIGNAL(editTextChanged(QString)), _searchInFilesP, SLOT(setBibTeXFile(QString))); connect(_searchInFilesP, SIGNAL(searchDone(QString,bibSearcher*)), this, SLOT(bibEditor(QString,bibSearcher*))); showMessage(tr("BibTeX Search launched.")); } if (fn.isEmpty()) _searchInFilesP->setBibTeXFile(ui.bibtexfile->currentText()); else _searchInFilesP->setBibTeXFile(fn); _searchInFilesP->setCurrentText(string); _searchInFilesP->show(); } void cb2Bib::setWindowTitle(const QString& title) { if (title.isEmpty()) QMainWindow::setWindowTitle(tr("cb2Bib")); else QMainWindow::setWindowTitle(tr("%1 - cb2Bib").arg(title)); } /**************************************************************************** CB2BIB FUNCTIONALITY *****************************************************************************/ void cb2Bib::setWidgetMapping() { _bpP->addField("abstract", ui.abstract); _bpP->addField("address", ui.address); _bpP->addField("annote", ui.annote); _bpP->addField("author", ui.author); _bpP->addField("booktitle", ui.booktitle); _bpP->addField("chapter", ui.chapter); _bpP->addField("doi", ui.doi); _bpP->addField("edition", ui.edition); _bpP->addField("editor", ui.editor); _bpP->addField("eprint", ui.eprint); _bpP->addField("file", ui.file); _bpP->addField("id", ui.id); _bpP->addField("institution", ui.institution); _bpP->addField("isbn", ui.isbn); _bpP->addField("issn", ui.issn); _bpP->addField("journal", ui.journal); _bpP->addField("keywords", ui.keywords); _bpP->addField("month", ui.month); _bpP->addField("note", ui.note); _bpP->addField("number", ui.number); _bpP->addField("organization", ui.organization); _bpP->addField("pages", ui.pages); _bpP->addField("publisher", ui.publisher); _bpP->addField("school", ui.school); _bpP->addField("series", ui.series); _bpP->addField("title", ui.title); _bpP->addField("url", ui.url); _bpP->addField("volume", ui.volume); _bpP->addField("year", ui.year); _bpP->addTypes(ui.typecombo); _bpP->setWidgetMapping(); connect(_bpP, SIGNAL(bibModified(bool)), this, SLOT(bibModified(bool))); } void cb2Bib::setBibMenu() { _bib_menu = new c2bBibMenu(this); connect(_bib_menu->addAuthorAction(), SIGNAL(triggered()), this, SLOT(addAuthors())); connect(_bib_menu->addEditorAction(), SIGNAL(triggered()), this, SLOT(addEditors())); connect(_bib_menu->anyPatternAction(), SIGNAL(triggered()), this, SLOT(anyPattern())); connect(ClipEdit, SIGNAL(userEndedSelection(QPoint)), this, SLOT(readField(QPoint))); } void cb2Bib::readField(const QPoint& position) { QAction* action = _bib_menu->exec(position); if (!action) return; const QString field(action->data().toString()); if (field.isEmpty()) return; _bpP->setField(field, ClipEdit->textCursor().selectedText()); ClipEdit->insertTag("<<" + field + ">>"); } void cb2Bib::addAuthors() { _bpP->setField("addauthors", ClipEdit->textCursor().selectedText(), ui.author->text()); ClipEdit->insertTag("<>"); if (_tagged_view_mode) showMessage(tr("Info: Creating a pattern with multiple author sets.")); } void cb2Bib::addEditors() { _bpP->setField("addeditors", ClipEdit->textCursor().selectedText(), ui.editor->text()); ClipEdit->insertTag("<>"); if (_tagged_view_mode) showMessage(tr("Info: Creating a pattern with multiple ui.editor sets.")); } void cb2Bib::anyPattern() { if (_tagged_view_mode) ClipEdit->insertTag(""); else ClipEdit->insertPlainText(QString()); } void cb2Bib::preparseClipboard() { c2bPreparse(_raw_input_data); } void cb2Bib::restartEngine() { const QString text(ClipEdit->toPlainText()); if (!text.isEmpty()) c2bParse(text); } void cb2Bib::guessFields() { const QString text(ClipEdit->toPlainText()); if (!text.isEmpty()) { const QString keep_dropped_article_file(_dropped_document_file); c2bInit(); _bpP->guessFields(text); fileDropped(keep_dropped_article_file); processingEnded(); } } void cb2Bib::dataChanged(const QString& str) { bool do_allow(isVisible()); if (ui.stackedWidget->currentWidget() == ClipEdit) { if (ClipEdit->textCursor().hasSelection()) do_allow = false; } else if (ui.stackedWidget->currentWidget() == BibBrowser) { if (BibBrowser->textCursor().hasSelection()) do_allow = false; } if (_connected && ui.ConnectB->isEnabled() && do_allow) forceDataChange(str); } void cb2Bib::forceDataChange(const QString& str) { if (!str.isEmpty()) { _raw_input_data = str.trimmed(); if (_settingsP->value("cb2Bib/PreparserAutomatic").toBool()) c2bPreparse(str); else c2bParse(str); } } void cb2Bib::c2bInit() { _dropped_document_file.clear(); ui.openFileDocumentAction->setEnabled(false); ui.openFileDocumentAction->setText(tr("Open File Document")); ui.file->setStatusTip(QString()); disconnect(_bpP, SIGNAL(setDocumentFilename()), this, SLOT(setDocumentFilename())); _bpP->clearCurrentReference(); _is_check_repeated_done = false; _modified = false; ui.AddBibB->setEnabled(_modified); } void cb2Bib::c2bParse(const QString& text) { c2bInit(); QString out_text, out_tagtext; _bpP->parse(text, &out_text, &out_tagtext); ClipEdit->setText(out_text, out_tagtext); processingEnded(); } void cb2Bib::c2bPreparse(const QString& text) { QString out_text; _bpP->preparse(text, &out_text); if (!out_text.isEmpty()) c2bParse(out_text); } void cb2Bib::deleteTmpBib() { QMessageBox msgBox(this); QPushButton* deleteButton = msgBox.addButton(tr("&Delete"), QMessageBox::DestructiveRole); msgBox.setDefaultButton(msgBox.addButton(QMessageBox::Cancel)); msgBox.setWindowTitle(tr("Confirmation - cb2Bib")); msgBox.setText(tr("Delete temporary BibTeX file %1 ?").arg(ui.bibtexfile->currentText())); msgBox.setIcon(QMessageBox::Question); msgBox.exec(); if (msgBox.clickedButton() == deleteButton) { QFile BibFile(ui.bibtexfile->currentText()); if (BibFile.remove()) showMessage(tr("File %1 deleted.").arg(ui.bibtexfile->currentText())); else QMessageBox::warning( this, tr("Warning - cb2Bib"), tr("Unable to delete the file %1.\nError: '%2'").arg(ui.bibtexfile->currentText(), BibFile.errorString()), QMessageBox::Ok); } } void cb2Bib::insertRegExp() { QStringList pattern; // Extracting Reference Type pattern.append(ui.typecombo->currentText()); // Extracting Field Order QString order(ClipEdit->toPlainText()); QRegExp rx("<<(" + _bpP->bibliographicFields().join("|") + ")>>"); QStringList list; int ipos(0); while (ipos >= 0) { ipos = rx.indexIn(order, ipos); if (ipos > -1) { list += rx.cap(1); ipos += rx.matchedLength(); c2bUtils::debug(rx.cap(1)); } } order = list.join(" "); c2bUtils::debug(order); pattern.append(order); // Parsing Regular Expression QString str('^' + QRegExp::escape(ClipEdit->toPlainText()) + '$'); str.replace(QRegExp("<>"), "(.+)"); str.replace(QRegExp("<
    >"), "(.+)"); str.replace(QRegExp("<>"), "(.+)"); str.replace(QRegExp(""), ".+"); str.replace(QRegExp("<>"), "(.+)"); str.replace(QRegExp("<>"), "(.+)"); str.replace(QRegExp("<>"), "(\\d+)"); str.replace(QRegExp("<>"), "(10\\.[\\d\\.]+/\\S+)"); str.replace(QRegExp("<>"), "(.+)"); str.replace(QRegExp("<>"), "(.+)"); str.replace(QRegExp("<>"), "(.+)"); str.replace(QRegExp("<>"), "(\\S+)"); str.replace(QRegExp("<>"), "(.+)"); str.replace(QRegExp("<>"), "(.+)"); str.replace(QRegExp("<>"), "(.+)"); str.replace(QRegExp("<>"), "(.+)"); str.replace(QRegExp("<>"), "(.+)"); str.replace(QRegExp("<>"), "(.+)"); str.replace(QRegExp("<>"), "(.+)"); str.replace(QRegExp("<>"), "(\\d+)"); str.replace(QRegExp("<>"), "(.+)"); str.replace(QRegExp("<>"), "([\\d\\-" + QString(QChar(8211)) + "\\s]+)"); str.replace(QRegExp("<>"), "(.+)"); str.replace(QRegExp("<>"), "(.+)"); str.replace(QRegExp("<>"), "(.+)"); str.replace(QRegExp("<>"), "(.+)"); str.replace(QRegExp("<<url>>"), "(\\S+)"); str.replace(QRegExp("<<volume>>"), "(\\d+)"); str.replace(QRegExp("<<year>>"), "(\\d\\d\\d\\d)"); c2bUtils::debug(str); pattern.append(str); // User Editting c2bSaveRegExp Sdiag(pattern, _raw_input_data, this); connect(c2b::clipboard(), SIGNAL(cbDataChanged(QString)), &Sdiag, SLOT(updateInput(QString))); connect(&Sdiag, SIGNAL(savePatternInfo(QString,QString)), this, SLOT(savePattern(QString,QString))); ui.ConnectB->setDisabled(true); if (Sdiag.exec() == QDialog::Rejected) showMessage(tr("Cancelled.")); ui.ConnectB->setDisabled(false); } void cb2Bib::savePattern(const QString& rx, const QString& rxname) { const QString regular_expression_f(_settingsP->fileName("cb2Bib/RegularExpressionFile")); QFile file(regular_expression_f); bool fopen; if (file.exists()) fopen = file.open(QIODevice::WriteOnly | QIODevice::Text | QIODevice::Append); else fopen = file.open(QIODevice::WriteOnly | QIODevice::Text); if (fopen) { QTextStream stream(&file); stream.setCodec("UTF-8"); stream.setAutoDetectUnicode(true); stream << ("# cb2Bib " + C2B_VERSION + " Pattern:") << endl << rxname << endl << rx << endl << endl; file.close(); showMessage(tr("Pattern '%1' added to %2.").arg(rxname, regular_expression_f)); } else QMessageBox::warning( this, tr("Warning - cb2Bib"), tr("Unable to open the file %1 for writing.\nError: '%2'.").arg(regular_expression_f, file.errorString()), QMessageBox::Ok); c2bUtils::debug("signal:"); c2bUtils::debug(rx); c2bUtils::debug(rxname); } void cb2Bib::setDocumentFilename() { disconnect(_bpP, SIGNAL(setDocumentFilename()), this, SLOT(setDocumentFilename())); if (_dropped_document_file.isEmpty()) return; ui.file->setText(_bpP->documentFilename(_dropped_document_file, ui.bibtexfile->currentText())); connect(_bpP, SIGNAL(setDocumentFilename()), this, SLOT(setDocumentFilename())); } void cb2Bib::addToFile(bool ready) { if (!ready) { QMessageBox::information(this, tr("Information - cb2Bib"), tr("Not ready to add reference.\n%2").arg(c2b::net()->errorString()), QMessageBox::Ok); ui.AddBibB->setEnabled(_modified); return; } QFile file(ui.bibtexfile->currentText()); bool fopen; if (file.exists()) fopen = file.open(QIODevice::WriteOnly | QIODevice::Text | QIODevice::Append); else fopen = file.open(QIODevice::WriteOnly | QIODevice::Text); if (fopen) { QTextStream stream(&file); stream.setCodec("UTF-8"); stream.setAutoDetectUnicode(true); stream << _bpP->toBibTeX(); file.close(); c2b::showMessage(tr("Bib Item %1 added to %2.").arg(ui.id->text(), ui.bibtexfile->currentText())); if (_settingsP->value("cb2Bib/InsertMetadata").toBool()) if (!_target_document_file.isEmpty()) if (!c2b::metaParser()->insertMetadata(_bpP->currentReference(), _target_document_file)) c2b::showMessage(tr("Unable to insert metadata to file %1.").arg(_target_document_file)); _is_check_repeated_done = false; _modified = false; ui.AddBibB->setEnabled(_modified); emit addedBibToFile(ui.bibtexfile->currentText()); } else QMessageBox::warning( this, tr("Warning - cb2Bib"), tr("Unable to open file %1 for writing.\nError: '%2'.").arg(ui.bibtexfile->currentText(), file.errorString()), QMessageBox::Ok); } void cb2Bib::addMetadata() { if (!_dropped_document_file.isEmpty()) { if (QFileInfo(_dropped_document_file).isWritable() && c2b::metaParser()->insertMetadata(_bpP->currentReference(), _dropped_document_file)) c2b::showMessage(tr("Inserted metadata to file %1.").arg(_dropped_document_file)); else c2b::showMessage(tr("Unable to insert metadata to file %1.").arg(_dropped_document_file)); } } void cb2Bib::postprocessBibTeX() { c2bPostprocess* ppBib = new c2bPostprocess(ui.bibtexfile->currentText(), this); showMessage(tr("BibTeX Postprocessing launched.")); if (ppBib->exec() != QDialog::Accepted) showMessage(tr("BibTeX Postprocessing exited.")); } void cb2Bib::bookmarksEditor() { if (_openDocuments.contains("bookmark_network_editor")) { c2bUtils::setWidgetOnTop(_openDocuments.value("bookmark_network_editor")); return; } c2bEditor* ed = new c2bEditor(_settingsP->fileName("cb2Bib/NetworkFile"), c2bEditor::NetQInfo, this); ed->setObjectName("bookmark_network_editor"); _openDocuments.insert("bookmark_network_editor", ed); ui.editBookmarksAction->setEnabled(false); connect(ed, SIGNAL(restartQuery()), this, SLOT(makeNetQuery())); connect(ed, SIGNAL(destroyed(QObject*)), this, SLOT(updateOpenDocuments(QObject*))); connect(ed, SIGNAL(openFile(QString)), this, SLOT(bibEditor(QString))); ed->show(); showMessage(tr("Bookmark File Editor launched.")); } void cb2Bib::abbreviationsEditor() { c2bEditor* ed = new c2bEditor(_settingsP->fileName("cb2Bib/JournalFile"), c2bEditor::JAbbrev, this); ed->setObjectName("journal_abbreviations_editor"); _openDocuments.insert("journal_abbreviations_editor", ed); ui.editAbbreviationsAction->setEnabled(false); connect(ed, SIGNAL(destroyed(QObject*)), this, SLOT(updateOpenDocuments(QObject*))); connect(ed, SIGNAL(openFile(QString)), this, SLOT(bibEditor(QString))); connect(ed, SIGNAL(openBookmarks()), this, SLOT(bookmarksEditor())); ed->show(); showMessage(tr("Journal Abbreviations Editor launched.")); } void cb2Bib::regExpsEditor() { c2bEditor* ed = new c2bEditor(_settingsP->fileName("cb2Bib/RegularExpressionFile"), c2bEditor::RegExp, this); ed->setObjectName("regular_expression_editor"); _openDocuments.insert("regular_expression_editor", ed); ui.editRegExpsAction->setEnabled(false); connect(ed, SIGNAL(restartEngine()), this, SLOT(restartEngine())); connect(ed, SIGNAL(destroyed(QObject*)), this, SLOT(updateOpenDocuments(QObject*))); connect(ed, SIGNAL(openFile(QString)), this, SLOT(bibEditor(QString))); connect(ed, SIGNAL(openBookmarks()), this, SLOT(bookmarksEditor())); ed->show(); showMessage(tr("RegExp File Editor launched.")); } void cb2Bib::annoteEditor(const QString& annotefile) { c2bEditor* ed = new c2bEditor(annotefile, c2bEditor::Annote, this); ed->setObjectName("annote_editor"); _openDocuments.insert("annote_editor", ed); connect(ed, SIGNAL(destroyed(QObject*)), this, SLOT(updateOpenDocuments(QObject*))); connect(ed, SIGNAL(openFile(QString)), this, SLOT(bibEditor(QString))); connect(ed, SIGNAL(openBookmarks()), this, SLOT(bookmarksEditor())); ed->show(); showMessage(tr("Annote Editor launched.")); } void cb2Bib::initAsBibTeXEditor() { for (int i = 0; i < _settingsP->cl_bibedit_filenames.count(); ++i) bibEditor(_settingsP->cl_bibedit_filenames.at(i)); } void cb2Bib::bibEditor(const QString& bibtexfile, bibSearcher* searcher) { if (bibtexfile.isEmpty()) return; if (_openDocuments.contains(bibtexfile)) { c2bUtils::setWidgetOnTop(_openDocuments.value(bibtexfile)); return; } c2bEditor* ed = new c2bEditor(bibtexfile, searcher, this); ed->setObjectName(ed->editorFilename()); _openDocuments.insert(ed->editorFilename(), ed); connect(ed, SIGNAL(destroyed(QObject*)), this, SLOT(updateOpenDocuments(QObject*))); connect(ed, SIGNAL(openFile(QString)), this, SLOT(bibEditor(QString))); connect(ed, SIGNAL(openBookmarks()), this, SLOT(bookmarksEditor())); connect(ed, SIGNAL(editFileRenamed(QString,QString)), this, SLOT(updateOpenDocuments(QString,QString))); ed->show(); showMessage(tr("BibTeX Editor launched.")); } void cb2Bib::updateOpenDocuments(QObject* obj) { _openDocuments.remove(obj->objectName()); if (!_openDocuments.contains("bookmark_network_editor")) ui.editBookmarksAction->setEnabled(true); if (!_openDocuments.contains("journal_abbreviations_editor")) ui.editAbbreviationsAction->setEnabled(true); if (!_openDocuments.contains("regular_expression_editor")) ui.editRegExpsAction->setEnabled(true); if (_settingsP->cl_bibedit && _openDocuments.count() == 0 && isHidden()) close(); } void cb2Bib::updateOpenDocuments(const QString& old_name, const QString& new_name) { c2bEditor* ed = _openDocuments.take(old_name); if (ed) { if (ed->objectName() == "bookmark_network_editor" || ed->objectName() == "journal_abbreviations_editor" || ed->objectName() == "regular_expression_editor" || ed->objectName() == "annote_editor") return; ed->setObjectName(new_name); _openDocuments.insert(new_name, ed); updateBibfile(new_name); } } void cb2Bib::bibModified(bool modified) { _modified = modified; ui.AddBibB->setEnabled(_modified); if (ui.stackedWidget->currentWidget() == BibBrowser) BibBrowser->updatePlainText(_bpP->toBibTeX()); } void cb2Bib::updateCheckRepeatedAction() { // Do not use anyAuthor/anyTitle, _bpP->currentReference() might not yet be set ui.checkRepeatedAction->setVisible(!ui.author->text().isEmpty() || !ui.title->text().isEmpty() || !ui.editor->text().isEmpty() || !ui.booktitle->text().isEmpty() || !ui.id->text().isEmpty()); } void cb2Bib::checkRepeated() { QApplication::setOverrideCursor(QCursor(Qt::WaitCursor)); isReferenceRepeated(); QApplication::restoreOverrideCursor(); } bool cb2Bib::isReferenceRepeated() { QFileInfo fi(ui.bibtexfile->currentText()); showMessage(tr("Checking for similar references at %1.").arg(fi.absolutePath())); bibSearcher searcher(_bpP, fi.absolutePath()); searcher.exec(); const bool repeated(searcher.hitsCount() > 0); if (repeated) { QApplication::processEvents(); bibEditor(fi.absolutePath(), &searcher); QApplication::processEvents(); if (searcher.hitsCount() == 1) c2b::showMessage(tr("Found %1 similar reference.").arg(searcher.hitsCount())); else c2b::showMessage(tr("Found %1 similar references.").arg(searcher.hitsCount())); } else showMessage(tr("No similar references found at %1.").arg(fi.absolutePath())); return repeated; } /**************************************************************************** NETWORK FUNCTIONALITY *****************************************************************************/ void cb2Bib::makeNetQuery() { if (!ui.MakeNetworkQueryB->isEnabled()) { showMessage(tr("Currently processing previous query. Resubmit later.")); return; } ui.MakeNetworkQueryB->setEnabled(false); QApplication::setOverrideCursor(QCursor(Qt::WaitCursor)); _netQP->submitQuery(_bpP->currentReference(), ClipEdit->toPlainText(), !_pdfImportP); } void cb2Bib::netQueryEnded(bool succeeded, const QString& targetPDF, const QString& targetBib) { if (!succeeded) { emit endedProcessing(false); c2b::showMessage(tr("Query submission information. %1").arg(_netQP->errorString())); } else if (targetPDF.isEmpty() && targetBib.isEmpty()) { emit endedProcessing(false); c2b::showMessage(tr("Query submitted. %1").arg(_netQP->errorString())); } else { const QString previous_article_file( _dropped_document_file); // Keep dropped file in case this is auto recognized forceDataChange(targetBib); if (_bpP->isAutoRecognized() && !targetPDF.isEmpty()) fileDropped(targetPDF); else if (_bpP->isAutoRecognized()) fileDropped(previous_article_file); } QApplication::restoreOverrideCursor(); ui.MakeNetworkQueryB->setEnabled(true); } void cb2Bib::processingEnded() { if (_settingsP->value("cb2Bib/AutomaticQuery").toBool()) if (ui.MakeNetworkQueryB->isEnabled() && !_bpP->autoRecognizedString().contains("BibTeX")) { makeNetQuery(); return; } if (_pdfImportP) fileDropped(_pdfImportP->processedFile); emit endedProcessing(_bpP->isAutoRecognized()); } void cb2Bib::linkClicked(const QUrl& ln) { // Encode link sets dynamic link. c2bUtils::openFile(c2b::encodeLink(ln.toString()), this); } void cb2Bib::openFileDocument() { if (!_dropped_document_file.isEmpty()) c2bUtils::openFile(_dropped_document_file, this); } void cb2Bib::selectFile() { const QString fn(c2bFileDialog::getOpenFilename( this, QString(), _settingsP->fileName("cb2Bib/LastDroppedFile"), "Portable Document Format (*.pdf);;DjVu (*.djvu);;Post Script (*.ps);;TeX (*.tex);;All (*)")); if (!fn.isEmpty()) fileDroppedByUser(fn); } void cb2Bib::openAnnote() { const QString fn(c2bFileDialog::getFilename(this, QString(), _settingsP->fileName("cb2Bib/LastAnnoteFile"), "Annote HTML output (*.tex.html);;LaTeX (*.tex);;All (*)")); if (fn.isEmpty()) return; const QString tex_fn(QString(fn).remove(QRegExp("\\.html$"))); if (!QFileInfo::exists(tex_fn)) { const QString empty_note("%\\c2b_bibtex_directory{" + QFileInfo(ui.bibtexfile->currentText()).absolutePath() + "}\n%\\c2b_makeindex\n\n\n\\title{New Note}\n\n\n\n"); if (!c2bUtils::stringToFile(empty_note, tex_fn)) { QMessageBox::information(this, tr("Information - cb2Bib"), tr("Unable to create new note %1.\nCheck writing permission.").arg(tex_fn), QMessageBox::Ok); return; } } _settingsP->setFilename("cb2Bib/LastAnnoteFile", fn); #ifdef C2B_USE_QWEB const QStringList flags(QStringList() << "--view-annote" << fn << _settingsP->confCommandFlags()); QProcess::startDetached(QCoreApplication::applicationFilePath(), flags); #else annoteEditor(tex_fn); #endif } ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������cb2bib-2.0.1/src/PaxHeaders.5700/c2bComboBox.h������������������������������������������������������0000644�0000000�0000000�00000000132�14011522520�015334� x����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������30 mtime=1613145424.510620343 30 atime=1613145424.830620334 30 ctime=1613145424.514620343 ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������cb2bib-2.0.1/src/c2bComboBox.h����������������������������������������������������������������������0000644�0001750�0000144�00000001172�14011522520�016734� 0����������������������������������������������������������������������������������������������������ustar�00constans������������������������users���������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*************************************************************************** * Copyright (C) 2004-2021 by Pere Constans * constans@molspaces.com * cb2Bib version 2.0.1. Licensed under the GNU GPL version 3. * See the LICENSE file that comes with this distribution. ***************************************************************************/ #ifndef C2BCOMBOBOX_H #define C2BCOMBOBOX_H #include <QComboBox> class c2bComboBox : public QComboBox { Q_OBJECT public: explicit c2bComboBox(QWidget* parentw = 0); ~c2bComboBox(); protected: virtual void contextMenuEvent(QContextMenuEvent* e); }; #endif ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������cb2bib-2.0.1/src/PaxHeaders.5700/c2bREHighlighter.cpp�����������������������������������������������0000644�0000000�0000000�00000000132�14011522520�016644� x����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������30 mtime=1613145424.438620345 30 atime=1613145424.826620334 30 ctime=1613145424.442620345 ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������cb2bib-2.0.1/src/c2bREHighlighter.cpp���������������������������������������������������������������0000644�0001750�0000144�00000005750�14011522520�020252� 0����������������������������������������������������������������������������������������������������ustar�00constans������������������������users���������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*************************************************************************** * Copyright (C) 2004-2021 by Pere Constans * constans@molspaces.com * cb2Bib version 2.0.1. Licensed under the GNU GPL version 3. * See the LICENSE file that comes with this distribution. ***************************************************************************/ #include "c2bREHighlighter.h" #include "c2bSettings.h" #include <QPalette> #include <QTextDocument> c2bREHighlighter::c2bREHighlighter(QTextDocument* doc) : QSyntaxHighlighter(doc) { QPalette p; text_color = p.text().color(); c2bSettings* settings(c2bSettingsP); c = &settings->colors; connect(settings, SIGNAL(newSettings()), this, SLOT(rehighlight())); rx0 = QRegExp("\\b(?:abstract|address|annote|author|booktitle|chapter|" "doi|edition|editor|eprint|file|institution|isbn|issn|journal|" "keywords|month|note|number|organization|pages|publisher|" "school|series|title|url|volume|year)\\b"); rx0.setMinimal(true); rx1 = QRegExp("\\b(?:article|book|booklet|conference|inbook|incollection|" "inproceedings|manual|mastersthesis|misc|periodical|phdthesis|" "proceedings|techreport|unpublished)\\b"); rx2 = QRegExp("^[a-z_]+=\\S.+$"); rx3 = QRegExp("^[a-z_]+="); rx4 = QRegExp("<<[a-z]+>>"); rx5 = QRegExp("^#.*$"); } c2bREHighlighter::~c2bREHighlighter() {} void c2bREHighlighter::highlightBlock(const QString& text) { const int len(text.length()); setFormat(0, len - 1, text_color); int pos(0); while (pos >= 0) { pos = rx0.indexIn(text, pos); if (pos > -1) { setFormat(pos, rx0.matchedLength(), c->bib_reference_field_color); pos += rx0.matchedLength(); } } pos = 0; while (pos >= 0) { pos = rx1.indexIn(text, pos); if (pos > -1) { setFormat(pos, rx1.matchedLength(), c->bib_reference_type_color); pos += rx1.matchedLength(); } } pos = 0; while (pos >= 0) { pos = rx2.indexIn(text, pos); if (pos > -1) { setFormat(pos, rx2.matchedLength(), c->netqinf_command_content_color); pos += rx2.matchedLength(); } } pos = 0; while (pos >= 0) { pos = rx3.indexIn(text, pos); if (pos > -1) { setFormat(pos, rx3.matchedLength(), c->netqinf_command_key_color); pos += rx3.matchedLength(); } } pos = 0; while (pos >= 0) { pos = rx4.indexIn(text, pos); if (pos > -1) { setFormat(pos, rx4.matchedLength(), c->cb2bib_tag_color); pos += rx4.matchedLength(); } } pos = 0; while (pos >= 0) { pos = rx5.indexIn(text, pos); if (pos > -1) { setFormat(pos, rx5.matchedLength(), c->comment_color); pos += rx5.matchedLength(); } } } ������������������������cb2bib-2.0.1/src/PaxHeaders.5700/findDialog.cpp�����������������������������������������������������0000644�0000000�0000000�00000000132�14011522520�015630� x����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������30 mtime=1613145424.470620344 30 atime=1613145424.830620334 30 ctime=1613145424.474620344 ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������cb2bib-2.0.1/src/findDialog.cpp���������������������������������������������������������������������0000644�0001750�0000144�00000013047�14011522520�017234� 0����������������������������������������������������������������������������������������������������ustar�00constans������������������������users���������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*************************************************************************** * Copyright (C) 2004-2021 by Pere Constans * constans@molspaces.com * cb2Bib version 2.0.1. Licensed under the GNU GPL version 3. * See the LICENSE file that comes with this distribution. * findDialog was originally adapted from Qt Designer * Copyright (C) 2001 Trolltech AS. All rights reserved. ***************************************************************************/ #include "findDialog.h" #include <QAction> #include <QPlainTextEdit> #include <QPushButton> #include <QScrollBar> #include <QTextEdit> findDialog::findDialog(QWidget* parentw) : QDialog(parentw) { ui.setupUi(this); setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint); resize(size().width(), 1); ui.buttonBox->button(QDialogButtonBox::Ok)->setText(tr("Find")); _editor = 0; QAction* act = new QAction(this); act->setSeparator(true); addAction(act); findAction = new QAction(this); addAction(findAction); findAction->setShortcut(QKeySequence::Find); findAction->setText(tr("Find")); findAction->setStatusTip(tr("Find in text")); connect(findAction, SIGNAL(triggered()), this, SLOT(findText())); findNextAction = new QAction(this); addAction(findNextAction); findNextAction->setShortcut(QKeySequence::FindNext); findNextAction->setText(tr("Find Next")); findNextAction->setStatusTip(tr("Find next occurrence")); connect(findNextAction, SIGNAL(triggered()), this, SLOT(findNext())); findPreviousAction = new QAction(this); addAction(findPreviousAction); findPreviousAction->setShortcut(QKeySequence::FindPrevious); findPreviousAction->setText(tr("Find Previous")); findPreviousAction->setStatusTip(tr("Find previous occurrence")); connect(findPreviousAction, SIGNAL(triggered()), this, SLOT(findPrevious())); } findDialog::~findDialog() {} void findDialog::init() { ui.notFound->hide(); raise(); if (_editor->inherits("QPlainTextEdit")) ui.comboFind->setEditText(qobject_cast<QPlainTextEdit*>(_editor)->textCursor().selectedText().trimmed()); else if (_editor->inherits("QTextEdit")) ui.comboFind->setEditText(qobject_cast<QTextEdit*>(_editor)->textCursor().selectedText().trimmed()); ui.comboFind->setFocus(); } void findDialog::setEditor(QPlainTextEdit* editor) { _editor = editor; } void findDialog::setEditor(QTextEdit* editor) { _editor = editor; } int findDialog::exec() { if (!_editor) return (-1); init(); return QDialog::exec(); } void findDialog::show() { if (!_editor) return; init(); QDialog::show(); } void findDialog::accept() { if (ui.comboFind->currentText().isEmpty()) return; if (_editor) { if (findText(ui.comboFind->currentText(), ui.radioForward->isChecked(), ui.checkCase->isChecked(), ui.checkWords->isChecked())) QDialog::accept(); else ui.notFound->show(); } } void findDialog::findText() { show(); } bool findDialog::findText(const QString& pattern, bool do_forward, bool do_case_sensitive, bool do_whole_words) { if (pattern.isEmpty()) return false; m_find_pattern = pattern; m_find_case = do_case_sensitive; m_find_words = do_whole_words; QTextDocument* doc; QTextCursor c; if (_editor->inherits("QPlainTextEdit")) { QPlainTextEdit* ed = qobject_cast<QPlainTextEdit*>(_editor); doc = ed->document(); c = ed->textCursor(); } else if (_editor->inherits("QTextEdit")) { QTextEdit* ed = qobject_cast<QTextEdit*>(_editor); doc = ed->document(); c = ed->textCursor(); } else return false; QTextDocument::FindFlags options; if (c.hasSelection()) c.setPosition(do_forward ? c.position() : c.anchor(), QTextCursor::MoveAnchor); if (!do_forward) options |= QTextDocument::FindBackward; if (m_find_case) options |= QTextDocument::FindCaseSensitively; if (m_find_words) options |= QTextDocument::FindWholeWords; QTextCursor newCursor(doc->find(m_find_pattern, c, options)); bool found(true); if (newCursor.isNull()) { QTextCursor ac(doc); ac.movePosition((options & QTextDocument::FindBackward) ? QTextCursor::End : QTextCursor::Start); newCursor = doc->find(m_find_pattern, ac, options); if (newCursor.isNull()) { newCursor = c; found = false; } } if (!found) return false; if (_editor->inherits("QPlainTextEdit")) { QPlainTextEdit* ed = qobject_cast<QPlainTextEdit*>(_editor); ed->setTextCursor(newCursor); ed->verticalScrollBar()->setValue(ed->verticalScrollBar()->maximum()); ed->centerCursor(); } else if (_editor->inherits("QTextEdit")) { QTextEdit* ed = qobject_cast<QTextEdit*>(_editor); ed->setTextCursor(newCursor); ed->verticalScrollBar()->setValue(ed->verticalScrollBar()->maximum()); ed->ensureCursorVisible(); ed->verticalScrollBar()->setValue(ed->verticalScrollBar()->value() - ed->viewport()->height() / 3); ed->ensureCursorVisible(); } return found; } void findDialog::findNext() { if (m_find_pattern.isEmpty()) findText(); else findText(m_find_pattern, true, m_find_case, m_find_words); } void findDialog::findPrevious() { if (m_find_pattern.isEmpty()) findText(); else findText(m_find_pattern, false, m_find_case, m_find_words); } �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������cb2bib-2.0.1/src/PaxHeaders.5700/c2bConfigure.cpp���������������������������������������������������0000644�0000000�0000000�00000000132�14011522520�016100� x����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������30 mtime=1613145424.406620346 30 atime=1613145424.826620334 30 ctime=1613145424.406620346 ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������cb2bib-2.0.1/src/c2bConfigure.cpp�������������������������������������������������������������������0000644�0001750�0000144�00000134745�14011522520�017515� 0����������������������������������������������������������������������������������������������������ustar�00constans������������������������users���������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*************************************************************************** * Copyright (C) 2004-2021 by Pere Constans * constans@molspaces.com * cb2Bib version 2.0.1. Licensed under the GNU GPL version 3. * See the LICENSE file that comes with this distribution. ***************************************************************************/ #include "c2bConfigure.h" #include "c2b.h" #include "c2bConfigureFR.h" #include "c2bFileDialog.h" #include "c2bSettings.h" #include "c2bUtils.h" #include <QColorDialog> #include <QHeaderView> #include <QStatusTipEvent> /** \page configuration Configuration <p> </p> GET_TABLE_OF_CONTENTS <p> </p> \section c2bconf_annote Configuring Annote - <b>Annote Cascading Style Sheet (CSS)</b> \n This file contains the style sheet to personalize the appearance of the HTML notes generated by the cb2Bib. The cb2Bib distribution includes the <tt>tex2html.css</tt> file as a CSS template. - <b>MathJax Header File</b> \n The mathematical notation in the text notes is displayed by \htmlonly <a href="https://www.mathjax.org/" target="_blank">MathJax</a>, \endhtmlonly the successor of the \htmlonly <a href="http://www.math.union.edu/~dpvc/jsMath/" target="_blank">jsMath</a> \endhtmlonly Java Script library. Its location and configuration must be specified inside the HTML files in order to be known by the browser. Check and eventually edit the distribution file <tt>tex2html_local_mathjax_header.html</tt>. Should web script be preferred set script source to <tt>https://cdn.mathjax.org/mathjax/latest/MathJax.js</tt>. - <b>Include CSS in HTML</b> \n Styles for the notes will be included, if checked, into the HTML file. In this way, all the information, text and layout, is contained in one single file. - <b>Use relative links</b> \n If checked, linked local files will be set relative to the current HTML document. - <b>Annote Viewer Fonts</b> \n Selects default and monospaced fonts for the Annote viewer. Changes in the fonts might need restarting the viewer unless using some of the latest QtWebKit libraries. The viewer is disabled if cb2Bib was not compiled and linked against WebKit. Note also that fonts specified in the CSS prevail over this selection. \section c2bconf_bibtex Configuring BibTeX - <b>Cite ID Pattern</b> \n Specifies the pattern for formatting cite's ID. Predefined placeholders are available as a context menu, by right-clicking this edit line. Placeholders will be substituted by the actual reference field values. See \ref idplaceholders for descriptions. - <b>Author and Editor Name Format</b> \n Sets Authors and Editor names in abbreviated or full form, if the latter is available. - <b>Journal Name Format</b> \n Sets output journal names in abbreviated or full form. Note that this feature only works if journal names are found in the <tt>Journal Abbreviation List file</tt>. See \ref journalproc. - <b>Number Separator</b> \n Sets number separator, e.g., ' - ' or ' -- '. Spaces count. It applies to <tt>pages</tt>, multiple <tt>volume</tt>, <tt>number</tt>, and <tt>year</tt> cases. - <b>Cite Command Pattern</b> \n Specifies the pattern for formatting cite command. Predefined command patterns for LaTeX and Markdown (see \htmlonly <a href="https://pandoc.org/MANUAL.html#citations" target="_blank">Pandoc User's Guide</a>) \endhtmlonly are available in the line context menu. Other, customized command patterns are also available, see \ref citeplaceholders for descriptions. - <b>Convert entry strings to LaTeX</b> \n If checked, cb2Bib converts special characters to LaTeX commands. Most BibTeX import filters do not process LaTeX escaped characters. Therefore, keeping this box unchecked can be appropriate when using cb2Bib as a temporary media to transfer references to non BibTeX reference managers. - <b>Set 'title' in double braces</b> \n If checked, it writes extra braces in title. This will keep capitalization as is, when processed by BibTeX. - <b>Postprocess 'month'</b> \n If checked, cb2Bib elaborates the 'month' string on a BibTeX fashion. E.g., 'April 1' becomes '"1~" # apr'. No processing is done if the input string is not written in English. - <b>Try Heuristic Guess if recognition fails</b> \n If checked, when automatic recognition fails, cb2Bib tries to catch some of the fields of the reference through an heuristic set of rules. See \ref heuristics. - <b>Check Repeated On Save</b> \n If checked, cb2Bib looks for existing references in the BibTeX directory similar to the one being saved. The search is based on exact cite ID match, or on reference contents, by considering title and author field values, or, if empty, booktitle and editor, and using the \htmlonly <a href="https://arxiv.org/abs/0705.0751" target="_blank">approximate string</a> \endhtmlonly search pattern. If similar references are found, the current reference is not saved, and the similar ones are displayed. Pressing the <b>save button one second time will proceed to actually saving the current reference</b>. Note that this feature is not applied in command line mode, when using <tt>cb2bib --txt2bib</tt> or <tt>cb2bib --doc2bib</tt>. See also \ref keyboard. - <b>External BibTeX Postprocessing</b> \n Use this box to select a BibTeX postprocessing external tool. The name of the executable, the command arguments and the output file extension are required fields. Arguments, any number, are passed to the executable. For the sake of generality, it is required to specify the <tt>\%finput</tt> and <tt>\%foutput</tt> placeholders. The first one is later substituted by the current BibTeX filename. The second one is substituted by the current filename with the specified output extension. <b>Caution:</b> Be careful if using the same file extension for input and output, e.g., using <tt>bib</tt> because you want to use a beautifier or a sorting script. cb2Bib has no control on external disk modifications. Therefore, if the script failed, the input data would possibly be lost. See also \ref keyboard. \section c2bconf_clipboard Configuring Clipboard - <b>Replace/Remove from Input Stream</b> \n If checked, input stream is preprocessed by performing a customizable set of string substitutions/removals. This option is mainly intended to remove image HTML <tt>alt</tt> tags. Although not visible, <tt>alt</tt> tags reach the clipboard when selecting and copying text. Author lists with email icons may contain <tt>alt</tt> strings that would interfere with the author names processing. In addition, this option is also appropriate to help translating special characters to Unicode and LaTeX. Use it carefully, as to avoid unwanted or unsuspected substitutions. See also \ref clipboard. - <b>External Clipboard Preparsing Command</b> \n Preparses input stream through an external, user-defined tool. Use the box bellow to specify its name and path. cb2Bib executes the command <tt>tool_name tmp_inputfile tmp_outputfile</tt>. You might consider a wrapper shell script to fullfill this particular syntax requirement. Two examples, <tt>isi2bib</tt> and <tt>ris2bib</tt> are provided. To test them, make sure the \htmlonly <a href="http://bibutils.refbase.org/" target="_blank">BibUtils Package</a> \endhtmlonly is available on your machine. Otherwise, modify these scripts according to your needs. See also \ref keyboard, \ref clipboard, and the examples \ref ex_isi_format and \ref ex_ris. - <b>Perform always, as part of an automatic extraction</b> \n Performs preparsing each time the recognition engine is invoked. <b>Caution:</b> cb2Bib, when not in disconnected mode, starts the recognition engine each time the clipboard changes. Therefore, it might send arbitrary data to the external parsing tool. The tool might not be prepared to handle <b>'any data'</b> and might fall into a sort of <b>'infinite loop'</b>. cb2Bib kills the external tool after a reasonable waiting. But, if the tool is called through a wrapper script, killing the script will not end the tool itself. Therefore, <b>check this box only when needed</b>. If you write your own preparser, design it as to write no data to output file whenever it can not process an input properly. When the preparser produces no data, cb2Bib sends instead the input stream to the recognition engine. In this way, preparsing and normal cb2Bib functioning will work harmoniously. - <b>Do not show log</b> \n If unchecked, the external process messages, and the input and output streams are shown in a log window. Showing output logs is useful for debugging purposes. - <b>Add document metadata to Input Stream</b> \n When checked, if the document linked to a reference contains relevant metadata, then metadata will be added to the current clipboard contents. The metadata is included at the time of adding the document to the current reference, e. g., when dropping a file into the cb2Bib panel. If the document has BibTeX information, cb2Bib will automatically set the corresponding fields. If it has not, but relevant bibliographic information is found, this data is only added to the clipboard panel. To insert it in the edit lines, activate the Heuristic Guess (Alt+G). The option <b>Prepend</b> or <b>Append</b> to the clipboard contents is provided for conveniently writing regular expressions considering metadata contents. File documents are linked to the references by the BibTeX tag 'file'. See also \ref metadata. \section c2bconf_documents Configuring Documents - <b>Rename and Copy/Move document files to Directory</b> \n If selected, each file 'drag and dropped' onto the cb2Bib main window is renamed to <tt>DocumentID.pdf</tt> (or DocumentID.ps, DocumentID.dvi, etc.) and moved to the storage directory. If unselected, the file URL is written to the <tt>file</tt> BibTeX keyword, without any renaming or moving of the file. The actual copy/move action is scheduled and performed once the reference is accepted, e.g., once it is saved. - <b>Copy or Move document files</b> \n Choose whether copy or move Network Files dropped onto the cb2Bib main window. See also <b>Use External Network Client</b>. - <b>Set directory relative to the BibTeX File Directory</b> \n If checked, the document file is copied/moved to the current BibTeX file directory. If the Documents Directory box contains a <b>relative directory</b> it will be added to the file name. For example, if it contains <tt>articles</tt>, files will be copied to <tt>/current_bibtex_path/articles/</tt>. An absolute path in the Documents Directory box will be ignored in this context. Note that the file dialog returns here relative file addresses. Consequently, only the necessary portion of the full name, instead of the fullpath filename, is written to the BibTeX entry. File retrieving from within the cb2Bib browser will be relative to the BibTeX file absolute location. \n Use this option if you plan to store in a same or a related directory the BibTeX and document files. This option is appropriate for storing bibliographic collections in removal devices. Likewise, when cb2Bib is launched in USB mode, by means of the command line switch <tt>--conf</tt>, the alternate option is not available. See \ref relnotes084 and \ref export_entries. - <b>Insert BibTeX metadata to document files</b> \n If checked, cb2Bib will write bibliographic metadata to the linked document, once the current reference is accepted and saved. See also \ref metadata. - <b>Document ID Pattern</b> \n Specifies the pattern for formatting the document's filenames. Predefined placeholders are available as a context menu, by right-clicking this edit line. Placeholders will be substituted by the actual reference field values. See \ref idplaceholders for descriptions. - <b>ExifTool Metadata writer</b> \n cb2Bib uses \htmlonly <a href="https://exiftool.org/" target="_blank">ExifTool</a> \endhtmlonly for writing bibliographic metadata to the attached documents. Select here the ExifTool path name. On Windows, remember renaming <tt>exiftool(-k).exe</tt> to <tt>exiftool.exe</tt> for command line use. See also \ref metadata_write. \section c2bconf_files Configuring Files - <b>Journal Abbreviation List File</b> \n This file contains a list of journal names equivalences: a capital-letter acronym, standard abbreviated form, and full name of the journal. If an input journal name is recognized, cb2Bib will use the standard abbreviated form for the <tt>journal</tt> bibkey. If your usual journal were not within the distributed, default <tt>abbreviations.txt</tt>, you could edit this file, or point to a personalized abbreviation file. <b>Note:</b> Changes in the abbreviation file only take place after reestarting cb2Bib. See \ref journalproc. - <b>Regular Expression List File</b> \n The cb2Bib distribution includes the file <tt>regexps.txt</tt> with a few set of rules for reference extraction. This includes most of the scientific literature. Extracting from email alerts or publisher abstract pages is a <em>volatile</em> task. Information does not follow a standardized structure. Extraction pattern may then change as often as the web design needs to. Besides, such extraction from the clipboard is system dependent, in a way that produces different formatting of the text copies on different systems. You can use your personalized <tt>regexps.txt</tt> file, for testing, debugging -regular expressions are reloaded each time the automatic recognition engine executes-, and fullfiling your particular extraction needs. - <b>Bookmarks and Network Query Info File</b> \n The cb2Bib distribution includes the file <tt>netqinf.txt</tt> that contains bookmarks data, and server related information for bibliographic querying. Note that cb2Bib treats bibliographic queries as generalized net bookmarks. This allows accessing almost any online bibliographic resource. Check this file for implementations details and customization. - <b>Browser Cascading Style Sheet (CSS)</b> \n This file contains the style sheet to configure the appearance of the bibliographic references when viewed in browser mode. The cb2Bib distribution includes the <tt>references.css</tt> and <tt>references-dark.css</tt> file as a CSS examples. - <b>Part Of Speech (POS) Lexicon</b> \n This box must contain the address to the cb2Bib distribution file <tt>lexicon.pos</tt>. This file contains a set of patterns and related POS information required for indexing documents, i. e., to extract keywords from documents for the c2bCiter module. - <b>Search In Files Cache Directory</b> \n Directory containing internal data for Search In Files functionality. If an existing directory is selected cb2Bib will write all internal data on it. If otherwise, cache data will be written on the same directory from where BibTeX are searched. It might be, therefore, convenient to group all this files in a separate directory that does not need to be backup, and that can easily be deleted whenever desired. \section c2bconf_fonts Configuring Fonts - <b>Font Selector</b> \n Selects the main window and editor font family and size. - <b>Context Colors</b> \n Doubleclick on context color items to select syntax highlighter font color. Besides syntax highlighting, and to ease manual bibliographic extractions, cb2Bib has the following coloring convention. 'cb2Bib unrelevant text' colors non-word, non-digit, and cb2Bib's internal tags. 'cb2Bib relevant text' refers to the reference's year. 'cb2Bib highly relevant' attempts to guess text sectioning, highlighting 'abstract', 'introduction', and 'keywords'. \section c2bconf_network Configuring Network - <b>Use External Network Client</b> \n cb2Bib manages local and network files in an equivalent manner. Network file retrieving, however, requires sometimes password and/or cookies administration. The KDE desktop incorporates <tt>kfmclient</tt> utility. A command <tt>kfmclient (copy|move|exec) source [destination]</tt> permits copying or moving files, with <tt>kfmclient</tt> taking care of advanced browsing preferences. By checking this box, cb2Bib will use the specified file manger client. - <b>Use Proxy</b> \n If checked, cb2Bib will access the network through a proxy host. Set the Host name, the Port, and the proxy Type. A login dialog will appear if the proxy requires authentication. Login data is not stored, it must be entered at each session. - <b>Perform Network Queries after automatic reference extractions</b> \n Network queries can be used to complete a partial reference extraction. For instance, provided a reference 'J. Name, 25, 103' and an appropriate pattern to extract it, cb2Bib will attempt to complete the reference automatically. No query is performed if automatic reference extraction was tagged as BibTeX. - <b>Download document if available</b> \n If checked, cb2Bib downloads document files to the directory specified in <b>Rename and Copy/Move document files to Directory</b>. See also the file <tt>netqinf.txt</tt> for details. Download is scheduled and performed once the reference is accepted, e.g., once it is saved. Note that when document file is local, e.g., when PDFImport or switch <tt>--doc2bib</tt> is used, no document is downloaded. - <b>Keep Query temporary files (Debug Only)</b> \n cb2Bib may use up to three temporary files to perform a network query. If this box is checked, the temporary files are not deleted. This facilitates the testing and customization of the information file <tt>netqinf.txt</tt>. \section c2bconf_shortcuts Configuring Shortcuts - Customizes most key sequences for actions shortcuts. Concretely, cb2Bib specific actions are configurable, but not standard actions such as 'Open', 'Exit', 'Copy', or 'Paste', which are already predefined to the standard, specific key sequences for each platform. Shortcuts are customizable for the cb2Bib main panel, editor, and reference list actions. Single-key shortcuts, i.e., for manual reference extraction and shortcuts in c2bCiter, are non-configurable, since they they closely map non-translatable BibTeX keywords. \section c2bconf_utilities Configuring Utilities - <b>To plain text converter</b> \n Selects the external <tt>some_format_to_text</tt> tool that cb2Bib uses to convert document files prior to reference extraction and searching. cb2Bib executes the line command <tt>converter [options] inputfile tmp_output.txt</tt>, where <tt>[options]</tt> are user defined arguments. As a default, cb2Bib launches <tt>pdf2cb</tt>, a modified PDF to text utility found in the XPDF package. Modifications are available at xpdf/ directory in the cb2Bib sources. Default arguments are <tt>-q -f 1 -l 1</tt> to extract only the first, title page when used within PDFImport, and <tt>-q</tt>, to convert the complete document when used within Search in Files. Appropriate for PDFImport could also be a document metadata extractor. Often metadata contains structured information regarding document authors, title, and source. A simple shell script wrapper could be the following <tt>any2text_search</tt>: \verbatim #!/bin/csh # Convert documents to text according to filename extension # any2text_search input_fn.ext output_fn.txt set ext = $1:e if ( $ext == 'djvu' ) then /usr/bin/djvutxt "$1" "$2" if ($status) exit 1 else if ( $ext == 'chm' ) then (/usr/local/bin/archmage -c text "$1" "$2") >& /dev/null if ($status) exit 1 else # If using pdf2cb /path/to/pdf2cb -q "$1" "$2" # If using pdftotex # /usr/bin/pdftotext -enc UTF-8 "$1" "$2" if ($status) exit 1 endif \endverbatim <p> </p> */ c2bConfigure::c2bConfigure(QWidget* parentw) : QDialog(parentw) { ui.setupUi(this); setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint); setWindowFlags(windowFlags() | Qt::WindowMinMaxButtonsHint); resize(QSize(1, 1)); // Set it at minimum size settings = c2bSettingsP; for (int i = 0; i < ui.contentsWidget->count(); ++i) ui.contentsWidget->item(i)->setStatusTip(tr("Configure %1").arg(ui.contentsWidget->item(i)->text())); connect(ui.contentsWidget, SIGNAL(currentItemChanged(QListWidgetItem*,QListWidgetItem*)), this, SLOT(changePage(QListWidgetItem*,QListWidgetItem*))); ui.contentsWidget->setCurrentItem(ui.contentsWidget->item(settings->value("c2bConfigure/CurrentPage", 0).toInt())); ui.buttonBox->button(QDialogButtonBox::Apply)->setAutoDefault(false); ui.buttonBox->button(QDialogButtonBox::Cancel)->setAutoDefault(false); ui.buttonBox->button(QDialogButtonBox::Help)->setAutoDefault(false); connect(ui.buttonBox->button(QDialogButtonBox::Apply), SIGNAL(clicked()), this, SLOT(apply())); connect(ui.buttonBox, SIGNAL(helpRequested()), this, SLOT(help())); populateFontCombos(); // Annote ui.AnnoteCssFile->setText(settings->fileName("c2bAnnote/AnnoteCssFile")); connect(ui.AnnoteCssDir, SIGNAL(clicked()), this, SLOT(getAnnoteCssFile())); ui.MathJaxHeaderFile->setText(settings->fileName("c2bAnnote/MathJaxHeaderFile")); connect(ui.MathJaxDir, SIGNAL(clicked()), this, SLOT(getMathJaxHeaderFile())); ui.IncludeCSS->setChecked(settings->value("c2bAnnote/IncludeCSS").toBool()); ui.UseRelativeLinks->setChecked(settings->value("c2bAnnote/UseRelativeLinks").toBool()); fontSelection(settings->value("c2bAnnote/Font").value<QFont>(), ui.af_familycombo, ui.af_psizecombo); fontSelection(settings->value("c2bAnnote/FixedFont").value<QFont>(), ui.aff_familycombo, ui.aff_psizecombo); #ifndef C2B_USE_QWEB ui.AnnoteViewerFont->setDisabled(true); ui.AnnoteViewerFixedFont->setDisabled(true); #endif // BibTeX ui.CiteIdPattern->setText(settings->value("cb2Bib/CiteIdPattern").toString()); ui.UseAbbreviatedNames->setChecked(!settings->value("cb2Bib/UseFullNames").toBool()); ui.UseFullNames->setChecked(settings->value("cb2Bib/UseFullNames").toBool()); ui.SetJournalsToAbbreviated->setChecked(!settings->value("cb2Bib/SetJournalsToFullname").toBool()); ui.SetJournalsToFullname->setChecked(settings->value("cb2Bib/SetJournalsToFullname").toBool()); ui.PageNumberSeparator->setText(settings->value("cb2Bib/PageNumberSeparator").toString()); ui.CiteCommandPattern->setText(settings->value("cb2Bib/CiteCommandPattern").toString()); ui.ConvertReferenceToLaTeX->setChecked(settings->value("cb2Bib/ConvertReferenceToLaTeX").toBool()); ui.UseDoubleBraces->setChecked(settings->value("cb2Bib/UseDoubleBraces").toBool()); ui.PostprocessMonth->setChecked(settings->value("cb2Bib/PostprocessMonth").toBool()); ui.DoHeuristicGuess->setChecked(settings->value("cb2Bib/DoHeuristicGuess").toBool()); ui.CheckRepeatedOnSave->setChecked(settings->value("cb2Bib/CheckRepeatedOnSave").toBool()); ui.PostprocessBibTeXBin->setText(settings->fileName("cb2Bib/PostprocessBibTeXBin")); ui.PostprocessBibTeXArg->setText(settings->value("cb2Bib/PostprocessBibTeXArg").toString()); ui.PostprocessBibTeXExt->setText(settings->value("cb2Bib/PostprocessBibTeXExt").toString()); connect(ui.CiteCommandPattern, SIGNAL(statusMessage(QString)), this, SLOT(showMessage(QString))); connect(ui.PostprocessBibTeXDir, SIGNAL(clicked()), this, SLOT(getPostprocessBibTeXBin())); // Clipboard ui.FindReplaceInput->setChecked(settings->value("cb2Bib/FindReplaceInput").toBool()); connect(ui.FindReplaceInput, SIGNAL(toggled(bool)), this, SLOT(updateFindReplaceInputButtons())); updateFindReplaceInputButtons(); QStringList FindReplaceInputList(settings->value("cb2Bib/FindReplaceInputList").toStringList()); QStringList::Iterator i = FindReplaceInputList.begin(); while (i != FindReplaceInputList.end()) { const QStringList spLine((*i).split('|')); new QTreeWidgetItem(ui.FindReplaceList, spLine); ++i; } connect(ui.FindReplaceList, SIGNAL(itemActivated(QTreeWidgetItem*,int)), this, SLOT(FindReplaceDialog_Edit())); connect(ui.FindReplaceList, SIGNAL(itemClicked(QTreeWidgetItem*,int)), this, SLOT(updateFindReplaceInputButtons())); connect(ui.FRNew, SIGNAL(clicked()), this, SLOT(FindReplaceDialog_New())); connect(ui.FREdit, SIGNAL(clicked()), this, SLOT(FindReplaceDialog_Edit())); connect(ui.FRDelete, SIGNAL(clicked()), this, SLOT(FindReplaceDialog_Delete())); ui.AddMetadata->setChecked(settings->value("cb2Bib/AddMetadata").toBool()); const QString PreAppendMetadata(settings->value("cb2Bib/PreAppendMetadata").toString()); if (PreAppendMetadata == "prepend") ui.Prepend->setChecked(true); else if (PreAppendMetadata == "append") ui.Append->setChecked(true); if (ui.AddMetadata->isChecked()) ui.PreAppendMetadata->setEnabled(true); else ui.PreAppendMetadata->setEnabled(false); connect(ui.AddMetadata, SIGNAL(toggled(bool)), ui.PreAppendMetadata, SLOT(setEnabled(bool))); ui.PreparserAutomatic->setChecked(settings->value("cb2Bib/PreparserAutomatic").toBool()); ui.PreparserShowLog->setChecked(!settings->value("cb2Bib/PreparserShowLog").toBool()); ui.PreparserBin->setText(settings->fileName("cb2Bib/PreparserBin")); connect(ui.PreparserDir, SIGNAL(clicked()), this, SLOT(getPreparserBin())); // Documents ui.MovePdf->setChecked(settings->value("cb2Bib/MovePdf").toBool()); ui.PdfDirectory->setText(settings->fileName("cb2Bib/PdfDirectory")); connect(ui.PdfDir, SIGNAL(clicked()), this, SLOT(getPdfDirectory())); const QString CopyMovePdf(settings->value("cb2Bib/CopyMovePdf").toString()); if (CopyMovePdf == "copy") ui.Copy->setChecked(true); else if (CopyMovePdf == "move") ui.Move->setChecked(true); if (ui.MovePdf->isChecked()) { ui.RenameCopyMovePdf->setEnabled(true); ui.DocumentIdPatternBox->setEnabled(true); } else { ui.RenameCopyMovePdf->setEnabled(false); ui.DocumentIdPatternBox->setEnabled(false); } connect(ui.MovePdf, SIGNAL(toggled(bool)), ui.RenameCopyMovePdf, SLOT(setEnabled(bool))); ui.RelativePdfDirectory->setChecked(settings->value("cb2Bib/RelativePdfDirectory").toBool()); ui.RelativePdfDirectory->setDisabled(settings->isUsbConfiguredMode()); ui.InsertMetadata->setChecked(settings->value("cb2Bib/InsertMetadata").toBool()); ui.DocumentIdPattern->setDocumentIDEdit(); ui.DocumentIdPattern->setText(settings->value("cb2Bib/DocumentIdPattern").toString()); connect(ui.MovePdf, SIGNAL(toggled(bool)), ui.DocumentIdPatternBox, SLOT(setEnabled(bool))); ui.ExifToolBin->setText(settings->fileName("cb2Bib/ExifToolBin")); connect(ui.ExifToolDir, SIGNAL(clicked()), this, SLOT(getExifToolBin())); // Files ui.JournalFile->setText(settings->fileName("cb2Bib/JournalFile")); connect(ui.JournalDir, SIGNAL(clicked()), this, SLOT(getJournalFile())); ui.RegularExpressionFile->setText(settings->fileName("cb2Bib/RegularExpressionFile")); connect(ui.RegularExpressionDir, SIGNAL(clicked()), this, SLOT(getRegularExpressionFile())); ui.NetworkFile->setText(settings->fileName("cb2Bib/NetworkFile")); connect(ui.NetworkDir, SIGNAL(clicked()), this, SLOT(getNetworkFile())); ui.BrowserCssFile->setText(settings->fileName("cb2Bib/BrowserCssFile")); connect(ui.BrowserCssDir, SIGNAL(clicked()), this, SLOT(getBrowserCssFile())); ui.PosLexiconFile->setText(settings->fileName("cb2Bib/PosLexiconFile")); connect(ui.PosLexiconDir, SIGNAL(clicked()), this, SLOT(getPosLexiconFile())); ui.CacheDirectory->setText(settings->fileName("cb2Bib/CacheDirectory")); connect(ui.CacheDir, SIGNAL(clicked()), this, SLOT(getCacheDirectory())); // Fonts c2bMonoFont = settings->c2bMonoFont; ui.samplelineedit->setFont(c2bMonoFont); fontSelection(c2bMonoFont, ui.familycombo, ui.psizecombo); connect(ui.familycombo, SIGNAL(activated(QString)), this, SLOT(comboFamilyChanged(QString))); connect(ui.psizecombo, SIGNAL(activated(QString)), this, SLOT(comboSizeChanged(QString))); colors.loadColors(settings); QHashIterator<QString, QColor*> cit(colors.colorList); while (cit.hasNext()) { cit.next(); QTreeWidgetItem* item = new QTreeWidgetItem(QStringList(cit.key())); item->setData(0, Qt::DecorationRole, *cit.value()); item->setData(0, Qt::ForegroundRole, *cit.value()); ui.ColorList->insertTopLevelItem(0, item); } ui.ColorList->header()->setSortIndicatorShown(false); ui.ColorList->viewport()->setCursor(QCursor(static_cast<Qt::CursorShape>(Qt::PointingHandCursor))); ui.ColorList->sortItems(0, Qt::AscendingOrder); connect(ui.ColorList, SIGNAL(itemClicked(QTreeWidgetItem*,int)), this, SLOT(changeContextColor(QTreeWidgetItem*))); connect(ui.ColorList, SIGNAL(itemActivated(QTreeWidgetItem*,int)), this, SLOT(changeContextColor(QTreeWidgetItem*))); // Network ui.FmClient->setChecked(settings->value("cb2Bib/FmClient").toBool()); ui.clientGroupBox->setEnabled(settings->value("cb2Bib/FmClient").toBool()); ui.FmClientCopyBin->setText(settings->fileName("cb2Bib/FmClientCopyBin")); ui.FmClientCopyArg->setText(settings->value("cb2Bib/FmClientCopyArg").toString()); ui.FmClientMoveBin->setText(settings->fileName("cb2Bib/FmClientMoveBin")); ui.FmClientMoveArg->setText(settings->value("cb2Bib/FmClientMoveArg").toString()); connect(ui.FmClientCopyDir, SIGNAL(clicked()), this, SLOT(getFmClientCopyBin())); connect(ui.FmClientMoveDir, SIGNAL(clicked()), this, SLOT(getFmClientMoveBin())); ui.UseProxy->setChecked(settings->value("cb2Bib/UseProxy").toBool()); ui.proxyGroupBox->setEnabled(settings->value("cb2Bib/UseProxy").toBool()); ui.ProxyHostName->setText(settings->value("cb2Bib/ProxyHostName", QString()).toString()); QValidator* proxyPortValidator = new QIntValidator(0, 999999, this); ui.ProxyPort->setValidator(proxyPortValidator); ui.ProxyPort->setText(settings->value("cb2Bib/ProxyPort").toString()); ui.ProxyType->setCurrentIndex(settings->value("cb2Bib/ProxyType").toInt()); ui.AutomaticQuery->setChecked(settings->value("cb2Bib/AutomaticQuery").toBool()); ui.AutomaticPdfDownload->setChecked(settings->value("cb2Bib/AutomaticPdfDownload").toBool()); ui.KeepTmpNQFiles->setChecked(settings->value("cb2Bib/KeepTmpNQFiles").toBool()); // Shortcuts ui.cb2BibShortcuts->setShortcutNames("Shortcuts/cb2Bib/", settings->shortcutNames()); connect(ui.cb2BibShortcuts, SIGNAL(statusMessage(QString)), this, SLOT(showMessage(QString))); ui.EditorShortcuts->setShortcutNames("Shortcuts/Editor/", settings->shortcutNames()); connect(ui.EditorShortcuts, SIGNAL(statusMessage(QString)), this, SLOT(showMessage(QString))); // Utilities ui.PdfImportPdf2TextBin->setText(settings->fileName("c2bPdfImport/Pdf2TextBin")); ui.PdfImportPdf2TextArg->setText(settings->value("c2bPdfImport/Pdf2TextArg").toString()); connect(ui.PdfImportPdf2TextDir, SIGNAL(clicked()), this, SLOT(getPdfImportPdf2TextBin())); ui.BibSearcherPdf2TextBin->setText(settings->fileName("c2bBibSearcher/Pdf2TextBin")); ui.BibSearcherPdf2TextArg->setText(settings->value("c2bBibSearcher/Pdf2TextArg").toString()); connect(ui.BibSearcherPdf2TextDir, SIGNAL(clicked()), this, SLOT(getBibSearcherPdf2TextBin())); } c2bConfigure::~c2bConfigure() {} void c2bConfigure::setPage(int index) { ui.contentsWidget->setCurrentItem(ui.contentsWidget->item(index)); } void c2bConfigure::accept() { apply(); QDialog::accept(); } void c2bConfigure::apply() { settings->setValue("c2bConfigure/CurrentPage", ui.contentsWidget->row(ui.contentsWidget->currentItem())); // Annote settings->setFilename("c2bAnnote/AnnoteCssFile", ui.AnnoteCssFile->text()); settings->setFilename("c2bAnnote/MathJaxHeaderFile", ui.MathJaxHeaderFile->text()); settings->setValue("c2bAnnote/IncludeCSS", ui.IncludeCSS->isChecked()); settings->setValue("c2bAnnote/UseRelativeLinks", ui.UseRelativeLinks->isChecked()); settings->setValue("c2bAnnote/Font", selectedFont(ui.af_familycombo, ui.af_psizecombo)); settings->setValue("c2bAnnote/FixedFont", selectedFont(ui.aff_familycombo, ui.aff_psizecombo)); // BibTeX settings->setValue("cb2Bib/CiteIdPattern", ui.CiteIdPattern->text()); settings->setValue("cb2Bib/UseFullNames", ui.UseFullNames->isChecked()); settings->setValue("cb2Bib/SetJournalsToFullname", ui.SetJournalsToFullname->isChecked()); settings->setValue("cb2Bib/PageNumberSeparator", ui.PageNumberSeparator->text()); settings->setValue("cb2Bib/CiteCommandPattern", ui.CiteCommandPattern->text()); settings->setValue("cb2Bib/ConvertReferenceToLaTeX", ui.ConvertReferenceToLaTeX->isChecked()); settings->setValue("cb2Bib/UseDoubleBraces", ui.UseDoubleBraces->isChecked()); settings->setValue("cb2Bib/PostprocessMonth", ui.PostprocessMonth->isChecked()); settings->setValue("cb2Bib/DoHeuristicGuess", ui.DoHeuristicGuess->isChecked()); settings->setValue("cb2Bib/CheckRepeatedOnSave", ui.CheckRepeatedOnSave->isChecked()); settings->setFilename("cb2Bib/PostprocessBibTeXBin", ui.PostprocessBibTeXBin->text()); settings->setValue("cb2Bib/PostprocessBibTeXArg", ui.PostprocessBibTeXArg->text()); settings->setValue("cb2Bib/PostprocessBibTeXExt", ui.PostprocessBibTeXExt->text()); // Clipboard QStringList FindReplaceInputList; QTreeWidgetItemIterator it(ui.FindReplaceList); while (*it) { QTreeWidgetItem* item(*it); FindReplaceInputList.append(QString("%1|%2|%3").arg(item->text(0), item->text(1), item->text(2))); ++it; } if (FindReplaceInputList.isEmpty()) { FindReplaceInputList = QString(C2B_FIND_REPLACE_LIST).split("^e"); settings->setValue("cb2Bib/FindReplaceInput", false); } else settings->setValue("cb2Bib/FindReplaceInput", ui.FindReplaceInput->isChecked()); settings->setValue("cb2Bib/FindReplaceInputList", FindReplaceInputList); QString PreAppendMetadata; if (ui.Prepend->isChecked()) PreAppendMetadata = "prepend"; else PreAppendMetadata = "append"; settings->setValue("cb2Bib/PreAppendMetadata", PreAppendMetadata); settings->setValue("cb2Bib/AddMetadata", ui.AddMetadata->isChecked()); settings->setValue("cb2Bib/PreparserAutomatic", ui.PreparserAutomatic->isChecked()); settings->setValue("cb2Bib/PreparserShowLog", !ui.PreparserShowLog->isChecked()); settings->setFilename("cb2Bib/PreparserBin", ui.PreparserBin->text()); // Documents QString CopyMovePdf; if (ui.Copy->isChecked()) CopyMovePdf = "copy"; else CopyMovePdf = "move"; settings->setValue("cb2Bib/CopyMovePdf", CopyMovePdf); settings->setValue("cb2Bib/MovePdf", ui.MovePdf->isChecked()); settings->setFilename("cb2Bib/PdfDirectory", ui.PdfDirectory->text()); settings->setValue("cb2Bib/RelativePdfDirectory", ui.RelativePdfDirectory->isChecked()); settings->setValue("cb2Bib/InsertMetadata", ui.InsertMetadata->isChecked()); settings->setValue("cb2Bib/DocumentIdPattern", ui.DocumentIdPattern->text()); settings->setFilename("cb2Bib/ExifToolBin", ui.ExifToolBin->text()); // Files settings->setFilename("cb2Bib/JournalFile", ui.JournalFile->text()); settings->setFilename("cb2Bib/RegularExpressionFile", ui.RegularExpressionFile->text()); settings->setFilename("cb2Bib/NetworkFile", ui.NetworkFile->text()); settings->setFilename("cb2Bib/BrowserCssFile", ui.BrowserCssFile->text()); settings->setFilename("cb2Bib/PosLexiconFile", ui.PosLexiconFile->text()); settings->setFilename("cb2Bib/CacheDirectory", ui.CacheDirectory->text()); // Fonts settings->setValue("cb2Bib/MonoFont", c2bMonoFont); colors.saveColors(settings); // Network settings->setValue("cb2Bib/FmClient", ui.FmClient->isChecked()); settings->setFilename("cb2Bib/FmClientCopyBin", ui.FmClientCopyBin->text()); settings->setFilename("cb2Bib/FmClientMoveBin", ui.FmClientMoveBin->text()); settings->setValue("cb2Bib/FmClientCopyArg", ui.FmClientCopyArg->text().simplified()); settings->setValue("cb2Bib/FmClientMoveArg", ui.FmClientMoveArg->text().simplified()); settings->setValue("cb2Bib/UseProxy", ui.UseProxy->isChecked()); settings->setValue("cb2Bib/ProxyHostName", ui.ProxyHostName->text().trimmed()); settings->setValue("cb2Bib/ProxyPort", ui.ProxyPort->text().trimmed()); settings->setValue("cb2Bib/ProxyType", ui.ProxyType->currentIndex()); settings->setValue("cb2Bib/AutomaticQuery", ui.AutomaticQuery->isChecked()); settings->setValue("cb2Bib/AutomaticPdfDownload", ui.AutomaticPdfDownload->isChecked()); settings->setValue("cb2Bib/KeepTmpNQFiles", ui.KeepTmpNQFiles->isChecked()); // Shortcuts settings->setKeysequences(ui.cb2BibShortcuts->modifiedKeysequences()); settings->setKeysequences(ui.EditorShortcuts->modifiedKeysequences()); // Utilities settings->setValue("c2bPdfImport/Pdf2TextArg", ui.PdfImportPdf2TextArg->text().simplified()); settings->setFilename("c2bPdfImport/Pdf2TextBin", ui.PdfImportPdf2TextBin->text()); settings->setValue("c2bBibSearcher/Pdf2TextArg", ui.BibSearcherPdf2TextArg->text().simplified()); settings->setFilename("c2bBibSearcher/Pdf2TextBin", ui.BibSearcherPdf2TextBin->text()); // Notify settings settings->notify(); } void c2bConfigure::comboFamilyChanged(const QString& family) { ui.samplelineedit->setFont(QFont(family, ui.psizecombo->currentText().toInt())); c2bMonoFont.setFamily(family); } void c2bConfigure::comboSizeChanged(const QString& pt) { ui.samplelineedit->setFont(QFont(ui.familycombo->currentText(), pt.toInt())); c2bMonoFont.setPointSize(pt.toInt()); } void c2bConfigure::FindReplaceDialog_Delete() { QTreeWidgetItem* item(ui.FindReplaceList->currentItem()); delete item; item = ui.FindReplaceList->currentItem(); if (item) item->setSelected(true); updateFindReplaceInputButtons(); } void c2bConfigure::FindReplaceDialog_Edit() { QTreeWidgetItem* item(ui.FindReplaceList->currentItem()); if (item) { c2bConfigureFR* frD(new c2bConfigureFR(item, this)); frD->exec(); delete frD; } } void c2bConfigure::FindReplaceDialog_New() { QStringList newlist; newlist << QString() << QString() << QString(); QTreeWidgetItem* fri(new QTreeWidgetItem(ui.FindReplaceList, newlist)); c2bConfigureFR* frD(new c2bConfigureFR(fri, this)); if (frD->exec() != QDialog::Accepted) delete fri; delete frD; } void c2bConfigure::updateFindReplaceInputButtons() { if (!ui.FindReplaceInput->isChecked()) { ui.FindReplaceList->setEnabled(false); ui.FRNew->setEnabled(false); ui.FREdit->setEnabled(false); ui.FRDelete->setEnabled(false); return; } else { ui.FindReplaceList->setEnabled(true); ui.FRNew->setEnabled(true); if (ui.FindReplaceList->topLevelItemCount() > 0) { ui.FREdit->setEnabled(true); ui.FRDelete->setEnabled(true); } else { ui.FREdit->setEnabled(false); ui.FRDelete->setEnabled(false); } } } void c2bConfigure::getAnnoteCssFile() { const QString fn(ui.AnnoteCssFile->text()); const QString new_fn(c2bFileDialog::getOpenFilename(this, tr("Select CSS filename"), fn, tr("Cascading Style Sheets (*.css);;All (*)"))); if (!new_fn.isEmpty()) ui.AnnoteCssFile->setText(new_fn); } void c2bConfigure::getMathJaxHeaderFile() { const QString fn(ui.MathJaxHeaderFile->text()); const QString new_fn( c2bFileDialog::getOpenFilename(this, tr("Select MathJax filename"), fn, tr("HTML Header (*.html);;All (*)"))); if (!new_fn.isEmpty()) ui.MathJaxHeaderFile->setText(new_fn); } void c2bConfigure::getJournalFile() { const QString fn(ui.JournalFile->text()); const QString new_fn(c2bFileDialog::getOpenFilename(this, tr("Select a filename (Restart to apply changes)"), fn, tr("cb2Bib Journal Lists (*.txt);;All (*)"))); if (!new_fn.isEmpty()) ui.JournalFile->setText(new_fn); } void c2bConfigure::getRegularExpressionFile() { const QString fn(ui.RegularExpressionFile->text()); const QString new_fn(c2bFileDialog::getFilename(this, QString(), fn, tr("cb2Bib RegExp Lists (*.txt);;All (*)"))); if (!new_fn.isEmpty()) ui.RegularExpressionFile->setText(new_fn); } void c2bConfigure::getNetworkFile() { const QString fn(ui.NetworkFile->text()); const QString new_fn( c2bFileDialog::getFilename(this, QString(), fn, tr("cb2Bib Network Query Info (*.txt);;All (*)"))); if (!new_fn.isEmpty()) ui.NetworkFile->setText(new_fn); } void c2bConfigure::getBrowserCssFile() { const QString fn(ui.BrowserCssFile->text()); const QString new_fn(c2bFileDialog::getOpenFilename(this, tr("Select a filename (Restart browser to apply changes)"), fn, tr("Cascading Style Sheets (*.css);;All (*)"))); if (!new_fn.isEmpty()) ui.BrowserCssFile->setText(new_fn); } void c2bConfigure::getFmClientCopyBin() { const QString fn(ui.FmClientCopyBin->text()); const QString new_fn(c2bFileDialog::getOpenFilename(this, QString(), fn, tr("File Manager Client executable (*)"))); if (!new_fn.isEmpty()) ui.FmClientCopyBin->setText(new_fn); } void c2bConfigure::getPreparserBin() { const QString fn(ui.PreparserBin->text()); const QString new_fn(c2bFileDialog::getOpenFilename(this, QString(), fn, tr("External Parser executable (*)"))); if (!new_fn.isEmpty()) ui.PreparserBin->setText(new_fn); } void c2bConfigure::getFmClientMoveBin() { const QString fn(ui.FmClientMoveBin->text()); const QString new_fn(c2bFileDialog::getOpenFilename(this, QString(), fn, tr("File Manager Client executable (*)"))); if (!new_fn.isEmpty()) ui.FmClientMoveBin->setText(new_fn); } void c2bConfigure::getPostprocessBibTeXBin() { const QString fn(ui.PostprocessBibTeXBin->text()); const QString new_fn(c2bFileDialog::getOpenFilename(this, QString(), fn, tr("BibTeX Postprocess executable (*)"))); if (!new_fn.isEmpty()) ui.PostprocessBibTeXBin->setText(new_fn); } void c2bConfigure::getPdfImportPdf2TextBin() { const QString fn(ui.PdfImportPdf2TextBin->text()); const QString new_fn(c2bFileDialog::getOpenFilename(this, QString(), fn, tr("PDF to text converter (*)"))); if (!new_fn.isEmpty()) ui.PdfImportPdf2TextBin->setText(new_fn); } void c2bConfigure::getBibSearcherPdf2TextBin() { const QString fn(ui.BibSearcherPdf2TextBin->text()); const QString new_fn(c2bFileDialog::getOpenFilename(this, QString(), fn, tr("PDF to text converter (*)"))); if (!new_fn.isEmpty()) ui.BibSearcherPdf2TextBin->setText(new_fn); } void c2bConfigure::getExifToolBin() { const QString fn(ui.ExifToolBin->text()); const QString new_fn(c2bFileDialog::getOpenFilename(this, QString(), fn, tr("ExifTool (*)"))); if (!new_fn.isEmpty()) ui.ExifToolBin->setText(new_fn); } void c2bConfigure::getPosLexiconFile() { const QString fn(ui.PosLexiconFile->text()); const QString new_fn( c2bFileDialog::getFilename(this, QString(), fn, tr("cb2Bib Part Of Speech Lexicon (*.pos);;All (*)"))); if (!new_fn.isEmpty()) ui.PosLexiconFile->setText(new_fn); } void c2bConfigure::getCacheDirectory() { const QString new_dir( c2bFileDialog::getExistingDirectory(this, tr("Select a cache directory"), ui.CacheDirectory->text())); if (!new_dir.isEmpty()) ui.CacheDirectory->setText(new_dir); } void c2bConfigure::getPdfDirectory() { const QString dir(c2bUtils::documentAbsoluteName(ui.RelativePdfDirectory->isChecked(), settings->fileName("cb2Bib/BibTeXFile"), ui.PdfDirectory->text(), QString())); QString new_dir(c2bFileDialog::getExistingDirectory(this, tr("Select documents directory"), dir)); if (!new_dir.isEmpty()) { new_dir = c2bUtils::documentDirName(ui.RelativePdfDirectory->isChecked(), settings->fileName("cb2Bib/BibTeXFile"), new_dir); ui.PdfDirectory->setText(new_dir); } } void c2bConfigure::populateFontCombos() { QFontDatabase db; QList<int> sizes(db.standardSizes()); QList<int>::Iterator it(sizes.begin()); while (it != sizes.end()) { ui.psizecombo->insertItem(0, QString::number(*it)); ui.af_psizecombo->insertItem(0, QString::number(*it)); ui.aff_psizecombo->insertItem(0, QString::number(*it)); it++; } } void c2bConfigure::fontSelection(const QFont& f, QFontComboBox* fc, QComboBox* sc) { fc->setCurrentFont(f); const int p_font_size(f.pointSize()); int i(0); while (i < sc->count()) { if (sc->itemText(i) == QString::number(p_font_size)) { sc->setCurrentIndex(i); break; } i++; } } QFont c2bConfigure::selectedFont(QFontComboBox* fc, QComboBox* sc) const { QFont f(fc->currentFont()); f.setPointSize(sc->currentText().toInt()); return f; } void c2bConfigure::changeContextColor(QTreeWidgetItem* item) { const QColor newColor(QColorDialog::getColor(item->foreground(0).color(), this)); if (newColor.isValid()) { item->setData(0, Qt::ForegroundRole, newColor); item->setData(0, Qt::DecorationRole, newColor); colors.updateColor(newColor, item->text(0)); } } void c2bConfigure::changePage(QListWidgetItem* current, QListWidgetItem* previous) { if (!current) current = previous; setWindowTitle(tr("Configure %1 - cb2Bib").arg(current->text())); ui.pagesWidget->setCurrentIndex(ui.contentsWidget->row(current)); } void c2bConfigure::showMessage(const QString& ms) { ui.statusBar->showMessage(ms, C2B_MESSAGE_TIME); } bool c2bConfigure::event(QEvent* qevent) { if (qevent->type() == QEvent::StatusTip) { ui.statusBar->showMessage(static_cast<QStatusTipEvent*>(qevent)->tip()); return true; } else return QDialog::event(qevent); } void c2bConfigure::help() { c2bUtils::displayHelp("https://www.molspaces.com/cb2bib/doc/configuration/#configuring-" + ui.contentsWidget->currentItem()->text().toLower()); } ���������������������������cb2bib-2.0.1/src/PaxHeaders.5700/c2bSettings.h������������������������������������������������������0000644�0000000�0000000�00000000132�14011522520�015424� x����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������30 mtime=1613145424.554620342 30 atime=1613145424.830620334 30 ctime=1613145424.558620342 ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������cb2bib-2.0.1/src/c2bSettings.h����������������������������������������������������������������������0000644�0001750�0000144�00000004112�14011522520�017021� 0����������������������������������������������������������������������������������������������������ustar�00constans������������������������users���������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*************************************************************************** * Copyright (C) 2004-2021 by Pere Constans * constans@molspaces.com * cb2Bib version 2.0.1. Licensed under the GNU GPL version 3. * See the LICENSE file that comes with this distribution. ***************************************************************************/ #ifndef C2BSETTINGS_H #define C2BSETTINGS_H #include "c2bColors.h" #include <settings.h> #include <QFont> #include <QKeySequence> class QAction; class QProgressBar; class QShortcut; class c2bSettings : public settings { Q_OBJECT public: ~c2bSettings(); QFont c2bMonoFont; c2bColors colors; void notify(); void update(); static c2bSettings* initSettings(); void setKeysequence(const QString& fullname, QShortcut* shortcut); void setKeysequence(const QString& path, QAction* action); void setKeysequences(const QHash<QString, QKeySequence>& keysequences); inline QKeySequence keysequence(const QString& fullname) const { return value(fullname).value<QKeySequence>(); } inline QKeySequence defaultKeysequence(const QString& fullname) const { return _default_keysequences.value(fullname); } inline QByteArray ksname(const QString& fullname) const { return value(fullname).value<QKeySequence>().toString(QKeySequence::NativeText).toLatin1(); } inline QStringList shortcutNames() const { return _default_keysequences.keys(); } signals: void newSettings(); private: c2bSettings(const QString& organization, const QString& application, QObject* parento = 0); explicit c2bSettings(const QString& fn, QObject* parento = 0); QMap<QString, QKeySequence> _default_keysequences; QProgressBar* _progress_bar; void init(); void processReferenceFile(); void setDefaults(); #ifdef Q_OS_WIN QString decodeFilename(const QString& fn) const override; #endif private slots: void guiExits(); void processReferenceFileEvent(); }; #define c2bSettingsP (static_cast<c2bSettings*>(settings::instance())) #endif ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������cb2bib-2.0.1/src/PaxHeaders.5700/c2bEditor.cpp������������������������������������������������������0000644�0000000�0000000�00000000132�14011522520�015405� x����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������30 mtime=1613145424.414620346 30 atime=1613145424.826620334 30 ctime=1613145424.414620346 ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������cb2bib-2.0.1/src/c2bEditor.cpp����������������������������������������������������������������������0000644�0001750�0000144�00000076477�14011522520�017031� 0����������������������������������������������������������������������������������������������������ustar�00constans������������������������users���������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*************************************************************************** * Copyright (C) 2004-2021 by Pere Constans * constans@molspaces.com * cb2Bib version 2.0.1. Licensed under the GNU GPL version 3. * See the LICENSE file that comes with this distribution. ***************************************************************************/ #include "c2bEditor.h" #include "bookmarkPlugin.h" #include "c2b.h" #include "c2bBibHighlighter.h" #include "c2bBibParser.h" #include "c2bExportDialog.h" #include "c2bFileDialog.h" #include "c2bPostprocess.h" #include "c2bREHighlighter.h" #include "c2bReferenceList.h" #include "c2bSettings.h" #include "c2bTextBrowser.h" #include "c2bTextEdit.h" #include "c2bUpdateMetadata.h" #include "c2bUtils.h" #include "findDialog.h" #include <bibSearcher.h> #include <texToHtml.h> #include <QCloseEvent> #include <QDir> #include <QDockWidget> #include <QLabel> #include <QMessageBox> #include <QStackedWidget> #include <QTextCursor> #include <QTextStream> /** \page bibeditor Embedded File Editor <p>GET_TABLE_OF_CONTENTS</p> cb2Bib contains a practical editor suitable to manipulate the files related to a cb2Bib session. Abbreviations, bookmarks, regular expressions, and BibTeX are readily available. On BibTeX mode, the editor contains a Reference List to ease file navigation, and to extend the editor functionality. The BibTeX editor can optionally be turned to a reference browser. \section bookmarks Bookmarks Bookmarks pointing to local or network files are available at the editor menu bar. They provide a fast access to external resources. Concretely, they are suitable for retrieving working documents, writing notes, or for accessing internet databases. The editor bookmark functionality had been introduced in the cb2Bib version 0.9.3. Currently, bookmarks are set manually in the <tt>netqinf.txt</tt> file, see \ref c2bconf_files. Each bookmark is an entry line with the form \verbatim editorbookmark=Description|Target file name|Shortcut|Icon file name \endverbatim having four fields, description, target file name, shortcut, and icon file name, separated with three (required) vertical bars |. \verbatim # Bookmark Examples: # - A URL: editorbookmark=URL Description|https://www.molspaces.com/cb2bib/doc/bibeditor/|| # - A separator, which is a blank line: editorbookmark= # - A TeX document, which will be opened with its default application: editorbookmark=Document Description|/home/doc/chapter1.tex|| \endverbatim \section update_metadata Update Documents Metadata The Update Documents Metadata functionality is available at the Edit and context menus on the BibTeX editor mode. Documents referred in the BibTeX file tags are scanned for metadata. If the BibTeX reference does not coincide with the bibliographic metadata, the document metadata is updated. In this way, metadata is synchronized with the BibTeX file contents. A log window appears, and possible errors are reported. Reported errors are, non-existence of a document file, read-only files, mismatches between BibTeX references and the actual metadata (often due to HTML tags or other illegal characters in BibTeX), or that the writing to the document format is not implemented. Note that this process will update all documents referenced in the BibTeX file. <b>While this process is safe, it implies writing into the documents.</b> Therefore take the usual measures and backup your data. See also \ref metadata_write. \section export_entries Export Selected Entries Selected entries can be exported to a separate BibTeX document. Click on <tt>File->Export Entries</tt> menu option, and provide an export filename at the Export Dialog. Optionally, export will copy the document files attached to the citation. The copy of documents is similar to the cb2Bib 'rename/copy/move' general procedure. See \ref c2bconf_documents, on <b>Set directory relative to the BibTeX File Directory</b>, for copying options. Documents will not be overwritten: copying of existing documents is skipped. Possible issues are reported in the new document, as LaTeX comments. \section c2beditor_menu Right-Click Menu Functionality \htmlonly <center><table cellpadding="4" cellspacing="2" border="1" summary="Summary table of Right-Click Menu Functionality"> <tr> <th valign="top">Default Key</th> <th valign="top">Action</th></tr> <tr> <td valign="top">Ctrl+F</td> <td valign="top">Find in text</td></tr> <tr> <td valign="top"></td> <td valign="top">Toggle word wrapping</td></tr> <tr> <td valign="top"></td> <td valign="top">Selection to LaTeX</td></tr> <tr> <td valign="top"></td> <td valign="top">Selection to Unicode</td></tr> <tr> <td valign="top"></td> <td valign="top">Journals to full name</td></tr> <tr> <td valign="top"></td> <td valign="top">Journals to alternate full name</td></tr> <tr> <td valign="top"></td> <td valign="top">Journals to abbreviated name</td></tr> <tr> <td valign="top"></td> <td valign="top">Journals to alternate abbreviated name</td></tr> <tr> <td valign="top"></td> <td valign="top">Update documents metadata</td></tr> <tr> <td valign="top">Shift+Ins</td> <td valign="top">Paste current BibTeX</td></tr> <tr> <td valign="top">Alt+P</td> <td valign="top">Save and postprocess BibTeX file</td></tr> </table></center> \endhtmlonly \section references_menu Reference List Right-Click Menu Functionality \htmlonly <center><table cellpadding="4" cellspacing="2" border="1" summary="Summary table of References Right-Click Menu Functionality"> <tr> <th valign="top">Default Key</th> <th valign="top">Action</th></tr> <tr> <td valign="top">Alt+C</td> <td valign="top">Cite selected entries</td></tr> <tr> <td valign="top"></td> <td valign="top">Open document file</td></tr> <tr> <td valign="top"></td> <td valign="top">Browse by DOI</td></tr> <tr> <td valign="top"></td> <td valign="top">Web search by Author</td></tr> <tr> <td valign="top"></td> <td valign="top">Web search by Title</td></tr> <tr> <td valign="top"></td> <td valign="top">Web search settings</td></tr> <tr> <td valign="top"></td> <td valign="top">Clear entry selection</td></tr> <tr> <td valign="top"></td> <td valign="top">Refresh list and browser</td></tr> </table></center> \endhtmlonly \section browser_menu BibTeX Browser Right-Click Menu Functionality \htmlonly <center><table cellpadding="4" cellspacing="2" border="1" summary="Summary table of Browser Right-Click Menu Functionality"> <tr> <th valign="top">Default Key</th> <th valign="top">Action</th></tr> <tr> <td valign="top">Alt+C</td> <td valign="top">Cite selected entries</td></tr> <tr> <td valign="top"></td> <td valign="top">Local search for selected text</td></tr> <tr> <td valign="top"></td> <td valign="top">Web search for selected text</td></tr> <tr> <td valign="top"></td> <td valign="top">Web search settings</td></tr> <tr> <td valign="top"></td> <td valign="top">Clear entry selection</td></tr> <tr> <td valign="top"></td> <td valign="top">Refresh list and browser</td></tr> </table></center> \endhtmlonly \section c2beditor_qt Additional Functionality \htmlonly <center><table cellpadding="4" cellspacing="2" border="1" summary="Summary table of Additional Functionality"> <tr> <td valign="top">Backspace</td> <td valign="top">Deletes the character to the left of the cursor</td></tr> <tr> <td valign="top">Delete</td> <td valign="top">Deletes the character to the right of the cursor</td></tr> <tr> <td valign="top">Ctrl+A</td> <td valign="top">Selects all text</td></tr> <tr> <td valign="top">Ctrl+C</td> <td valign="top">Copy the selected text to the clipboard</td></tr> <tr> <td valign="top">Ctrl+Insert</td> <td valign="top">Copy the selected text to the clipboard</td></tr> <tr> <td valign="top">Ctrl+K</td> <td valign="top">Deletes to the end of the line</td></tr> <tr> <td valign="top">Ctrl+V</td> <td valign="top">Pastes the clipboard text into text edit</td></tr> <tr> <td valign="top">Shift+Insert</td> <td valign="top">Pastes the clipboard text into text edit</td></tr> <tr> <td valign="top">Ctrl+X</td> <td valign="top">Deletes the selected text and copies it to the clipboard</td></tr> <tr> <td valign="top">Shift+Delete</td> <td valign="top">Deletes the selected text and copies it to the clipboard</td></tr> <tr> <td valign="top">Ctrl+Z</td> <td valign="top">Undoes the last operation</td></tr> <tr> <td valign="top">Ctrl+Y</td> <td valign="top">Redoes the last operation</td></tr> <tr> <td valign="top">LeftArrow</td> <td valign="top">Moves the cursor one character to the left</td></tr> <tr> <td valign="top">Ctrl+LeftArrow</td> <td valign="top">Moves the cursor one word to the left</td></tr> <tr> <td valign="top">RightArrow</td> <td valign="top">Moves the cursor one character to the right</td></tr> <tr> <td valign="top">Ctrl+RightArrow</td> <td valign="top">Moves the cursor one word to the right</td></tr> <tr> <td valign="top">UpArrow</td> <td valign="top">Moves the cursor one line up</td></tr> <tr> <td valign="top">Ctrl+UpArrow</td> <td valign="top">Moves the cursor one word up</td></tr> <tr> <td valign="top">DownArrow</td> <td valign="top">Moves the cursor one line down</td></tr> <tr> <td valign="top">Ctrl+Down Arrow</td> <td valign="top">Moves the cursor one word down</td></tr> <tr> <td valign="top">PageUp</td> <td valign="top">Moves the cursor one page up</td></tr> <tr> <td valign="top">PageDown</td> <td valign="top">Moves the cursor one page down</td></tr> <tr> <td valign="top">Home</td> <td valign="top">Moves the cursor to the beginning of the line</td></tr> <tr> <td valign="top">Ctrl+Home</td> <td valign="top">Moves the cursor to the beginning of the text</td></tr> <tr> <td valign="top">End</td> <td valign="top">Moves the cursor to the end of the line</td></tr> <tr> <td valign="top">Ctrl+End</td> <td valign="top">Moves the cursor to the end of the text</td></tr> <tr> <td valign="top">Alt+Wheel</td> <td valign="top">Scrolls the page horizontally</td></tr> <tr> <td valign="top">Ctrl+Wheel</td> <td valign="top">Zooms the text</td></tr> </table></center> \endhtmlonly */ c2bEditor::c2bEditor(const QString& file, const Mode mode, QWidget* main, QWidget* parentw) : QMainWindow(parentw) { _editor_fn = QDir::toNativeSeparators(file); _editor_mode = mode; _c2b_mainP = main; _searcherP = 0; initEditor(); } c2bEditor::c2bEditor(const QString& file, bibSearcher* searcher, QWidget* main, QWidget* parentw) : QMainWindow(parentw) { _editor_fn = QDir::toNativeSeparators(file); _editor_mode = BibTeX; _c2b_mainP = main; _searcherP = searcher; initEditor(); } c2bEditor::~c2bEditor() { if (_browserP) _settingsP->setValue("c2bEditor/BrowserFontPointSize", _browserP->font().pointSize()); } void c2bEditor::initEditor() { ui.setupUi(this); setAttribute(Qt::WA_DeleteOnClose); _settingsP = c2bSettingsP; if (_editor_mode == BibTeX) _bpP = c2b::bibParser(); else _bpP = 0; _browserP = 0; _editorP = new c2bTextEdit(this); _referencesP = 0; _stackedWidgetP = new QStackedWidget(this); setCentralWidget(_stackedWidgetP); _stackedWidgetP->addWidget(_editorP); _textFinderP = new findDialog(this); _lineLabelP = new QLabel(); _lineLabelP->setText(tr(" Line: 1 Col: 1 ")); _lineLabelP->setAlignment(Qt::AlignVCenter | Qt::AlignRight); _lineLabelP->setFrameStyle(QFrame::NoFrame); _lineLabelP->setLineWidth(1); _lineLabelP->setFixedHeight(_lineLabelP->fontMetrics().height()); statusBar()->addWidget(_lineLabelP, 1); connect(_editorP, SIGNAL(cursorPositionChanged()), this, SLOT(cursorPositionChanged())); _overwriteLabelP = new QLabel(); _overwriteLabelP->setText(tr(" INS ")); _overwriteLabelP->setAlignment(Qt::AlignVCenter | Qt::AlignRight); _overwriteLabelP->setFrameStyle(QFrame::NoFrame); _overwriteLabelP->setLineWidth(1); _overwriteLabelP->setFixedHeight(_overwriteLabelP->fontMetrics().height()); statusBar()->addWidget(_overwriteLabelP); _editorP->setOverwriteMode(false); connect(_editorP, SIGNAL(overwriteModeChanged()), this, SLOT(overwriteModeChanged())); connect(ui.fileCloseAction, SIGNAL(triggered()), this, SLOT(close())); connect(ui.fileExecAction, SIGNAL(triggered()), this, SLOT(saveAndExecute())); connect(ui.fileExitAction, SIGNAL(triggered()), c2b::instance(), SLOT(exitRequested())); connect(ui.fileSaveAction, SIGNAL(triggered()), this, SLOT(fileSave())); connect(ui.fileSaveAsAction, SIGNAL(triggered()), this, SLOT(fileSaveAs())); connect(ui.helpEditorAction, SIGNAL(triggered()), this, SLOT(helpEditor())); connect(ui.helpCb2BibAction, SIGNAL(triggered()), this, SLOT(helpCb2Bib())); connect(ui.viewCb2BibAction, SIGNAL(triggered()), this, SLOT(viewCb2Bib())); // Standard shortcuts ui.fileCloseAction->setShortcut(QKeySequence(QKeySequence::Close)); ui.fileOpenAction->setShortcut(QKeySequence(QKeySequence::Open)); ui.fileSaveAction->setShortcut(QKeySequence(QKeySequence::Save)); ui.helpEditorAction->setShortcut(QKeySequence(QKeySequence::HelpContents)); ui.viewZoomInAction->setShortcut(QKeySequence(QKeySequence::ZoomIn)); ui.viewZoomOutAction->setShortcut(QKeySequence(QKeySequence::ZoomOut)); ui.fileExitAction->setShortcut(QKeySequence(QKeySequence::Quit)); ui.fileSaveAsAction->setShortcut(QKeySequence(QKeySequence::SaveAs)); // Editor Settings resize(_settingsP->value("c2bEditor/size", size()).toSize()); ui.menuView->addAction(ui.toolBar->toggleViewAction()); ui.setLyXPipeAction->setVisible(false); _editorP->setFont(_settingsP->c2bMonoFont); connect(ui.settingsCb2BibAction, SIGNAL(triggered()), c2b::instance(), SLOT(configure())); // Bookmarks bookmarkPlugin* bookmarks = new bookmarkPlugin(this); menuBar()->insertMenu(ui.menuSettings->menuAction(), bookmarks); connect(bookmarks, SIGNAL(openFile(QString)), this, SIGNAL(openFile(QString))); connect(bookmarks, SIGNAL(editBookmarks()), this, SIGNAL(openBookmarks())); load(); setEditorMode(); importActions(); QApplication::processEvents(); // Qt 4.7.0 emits contentsChange with position inconsistently defined, make sure it // is not captured connect(_editorP->document(), SIGNAL(contentsChange(int,int,int)), this, SLOT(isModified(int,int,int))); connect(c2b::instance(), SIGNAL(statusMessage(QString)), this, SLOT(showMessage(QString))); } void c2bEditor::setEditorMode() { if (_editor_mode == RegExp) { _shP = new c2bREHighlighter(_editorP->document()); ui.fileExecAction->setText(tr("Restart Recognition")); ui.fileExecAction->setStatusTip(tr("Restart recognition")); _settingsP->setKeysequence("Shortcuts/Editor/", ui.fileExecAction); connect(this, SIGNAL(execute()), this, SIGNAL(restartEngine())); ui.toolBar->setVisible(_settingsP->value("c2bEditor/ToolBar", true).toBool()); setViewMode(true); } else if (_editor_mode == NetQInfo) { _shP = new c2bREHighlighter(_editorP->document()); ui.fileExecAction->setText(tr("Restart Network Query")); ui.fileExecAction->setStatusTip(tr("Restart network query")); _settingsP->setKeysequence("Shortcuts/Editor/", ui.fileExecAction); connect(this, SIGNAL(execute()), this, SIGNAL(restartQuery())); ui.toolBar->setVisible(_settingsP->value("c2bEditor/ToolBar", true).toBool()); setViewMode(true); } else if (_editor_mode == JAbbrev) { ui.fileExecAction->setVisible(false); ui.toolBar->setVisible(_settingsP->value("c2bEditor/ToolBar", true).toBool()); setViewMode(true); } else if (_editor_mode == Annote) { _shP = new c2bBibHighlighter(_editorP->document()); ui.fileExecAction->setText(tr("View Note in External Browser")); ui.fileExecAction->setStatusTip(tr("View Note in External Browser")); _settingsP->setKeysequence("Shortcuts/Editor/", ui.fileExecAction); _editorP->setLaTeXActions(); connect(this, SIGNAL(execute()), this, SLOT(htmlView())); ui.toolBar->setVisible(_settingsP->value("c2bEditor/ToolBar", true).toBool()); setViewMode(true); } else if (_editor_mode == BibTeX) { // Editor _shP = new c2bBibHighlighter(_editorP->document()); ui.fileOpenAction->setVisible(true); connect(ui.fileOpenAction, SIGNAL(triggered()), this, SLOT(fileOpen())); _editorP->setBibTeXActions(); connect(_editorP->pasteCurrentBibTeXAction, SIGNAL(triggered()), this, SLOT(pasteCurrentBibTeX())); connect(_editorP->journalsToAbbreviatedAction, SIGNAL(triggered()), this, SLOT(journalsToAbbreviated())); connect(_editorP->journalsToAlternateAbbreviatedAction, SIGNAL(triggered()), this, SLOT(journalsToAlternateAbbreviated())); connect(_editorP->journalsToFullAction, SIGNAL(triggered()), this, SLOT(journalsToFull())); connect(_editorP->journalsToAlternateFullAction, SIGNAL(triggered()), this, SLOT(journalsToAlternateFull())); connect(_editorP->updateMetadataAction, SIGNAL(triggered()), this, SLOT(updateMetadata())); connect(_c2b_mainP, SIGNAL(addedBibToFile(QString)), this, SLOT(reload(QString))); ui.fileExecAction->setText(tr("Save and Postprocess")); ui.fileExecAction->setStatusTip(tr("Save and postprocess")); _settingsP->setKeysequence("Shortcuts/Editor/", ui.fileExecAction); connect(this, SIGNAL(execute()), this, SLOT(postProcess())); // Browser _browserP = new c2bTextBrowser(this); _browserP->setFont( QFont(QFont().family(), _settingsP->value("c2bEditor/BrowserFontPointSize", QFont().pointSize()).toInt())); _stackedWidgetP->addWidget(_browserP); ui.viewEditorModeAction->setVisible(true); _settingsP->setKeysequence("Shortcuts/Editor/", ui.viewEditorModeAction); connect(ui.viewEditorModeAction, SIGNAL(triggered(bool)), this, SLOT(setViewMode(bool))); connect(ui.viewZoomInAction, SIGNAL(triggered()), _browserP, SLOT(zoomIn())); connect(ui.viewZoomOutAction, SIGNAL(triggered()), _browserP, SLOT(zoomOut())); // Reference List createReferenceList(); _referencesP->loadList(_editorP->toPlainText(), _searcherP); bool edit_mode(false); if (_searcherP) { edit_mode = (_searcherP->hitsCount() == 0 && _searcherP->errorsCount() > 0); connect(_referencesP, SIGNAL(openFile(QString)), this, SIGNAL(openFile(QString))); } if (!_edit_reference_at_position.isEmpty()) { edit_mode = true; _referencesP->goToReference(_edit_reference_at_position.toInt()); } ui.viewEditorModeAction->setChecked(edit_mode); setViewMode(edit_mode); ui.setLyXPipeAction->setVisible(true); _settingsP->setKeysequence("Shortcuts/Editor/", ui.setLyXPipeAction); // Export entries ui.fileExportEntriesAction->setVisible(true); _settingsP->setKeysequence("Shortcuts/Editor/", ui.fileExportEntriesAction); connect(ui.fileExportEntriesAction, SIGNAL(triggered()), this, SLOT(exportEntries())); connect(_referencesP, SIGNAL(hasSelectedItems(bool)), ui.fileExportEntriesAction, SLOT(setEnabled(bool))); } else c2bUtils::debug(tr("c2bEditor::setEditorMode: '%1' invalid Editor Mode.").arg(_editor_mode)); } void c2bEditor::importActions() { QList<QAction*> acts = _textFinderP->actions(); for (int i = 0; i < acts.count(); ++i) ui.menuEdit->addAction(acts.at(i)); acts = _editorP->actions(); for (int i = 0; i < acts.count(); ++i) ui.menuEdit->addAction(acts.at(i)); if (_browserP) { ui.menuEdit->addSeparator(); acts = _browserP->actions(); for (int i = 0; i < acts.count(); ++i) ui.menuEdit->addAction(acts.at(i)); } } void c2bEditor::createReferenceList() { _dockWidgetP = new QDockWidget(this); _dockWidgetP->setObjectName("dwRList"); _referencesP = new c2bReferenceList(_editorP, _browserP, _dockWidgetP); addDockWidget(Qt::BottomDockWidgetArea, _dockWidgetP); _dockWidgetP->setWidget(_referencesP); _dockWidgetP->setWindowTitle("Reference List"); QByteArray state = _settingsP->value("c2bEditor/state").toByteArray(); restoreState(state); ui.menuView->addAction(_dockWidgetP->toggleViewAction()); // State contains toolBar info, too, but it can be changed from non BibTeX editors // State can not be used for non BibTeX editors. They don't have referenceList. ui.toolBar->setVisible(_settingsP->value("c2bEditor/ToolBar", true).toBool()); connect(ui.setLyXPipeAction, SIGNAL(triggered()), _referencesP, SLOT(setLyXPipe())); } void c2bEditor::closeEvent(QCloseEvent* qevent) { if (closeEditor()) qevent->accept(); else qevent->ignore(); } bool c2bEditor::closeEditor() { // Use _is_modified_by_user to check if closing is possible. This way, // no question is asked to exit browsing of search results. Do not use // here ui.fileSaveAction->isEnabled(). if (_is_modified_by_user) { const int button(QMessageBox::information( this, tr("Information - cb2Bib"), tr("The document has been modified.\nDo you want to save the changes?"), QMessageBox::Save | QMessageBox::Discard | QMessageBox::Cancel, QMessageBox::Save)); if (button == QMessageBox::Save) { if (!fileSave()) return false; } else if (button == QMessageBox::Cancel) return false; } _settingsP->setValue("c2bEditor/size", size()); if (_editor_mode == BibTeX) _settingsP->setValue("c2bEditor/state", saveState()); _settingsP->setValue("c2bEditor/ToolBar", !ui.toolBar->isHidden()); return true; } void c2bEditor::isModified(int position, int charsRemoved, int charsAdded) { if (position == 0 && charsAdded == charsRemoved) return; ui.fileSaveAction->setEnabled(true); setWindowModified(true); _is_modified_by_user = true; } void c2bEditor::fileOpen() { if (_editor_mode == BibTeX) { const QString filename( c2bFileDialog::getOpenFilename(this, "Select a BibTeX filename", _editor_fn, "BibTeX (*.bib)")); if (!filename.isEmpty()) emit openFile(filename); } } bool c2bEditor::fileSave() { if (_editor_fn.contains("unnamed_")) return fileSaveAs(); QFile file(_editor_fn); if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) { QMessageBox::warning( this, tr("Warning - cb2Bib"), tr("Unable to open the file %1 for writing.\nError: '%2'.").arg(_editor_fn, file.errorString()), QMessageBox::Ok); return false; } QTextStream stream(&file); stream.setCodec("UTF-8"); stream.setAutoDetectUnicode(true); stream << _editorP->toPlainText(); ui.fileSaveAction->setEnabled(false); _editorP->document()->setModified(false); setWindowModified(false); _is_modified_by_user = false; return true; } bool c2bEditor::fileSaveAs() { QString filename; if (_editor_mode == BibTeX) filename = c2bFileDialog::getSaveFilename(this, QString(), _editor_fn, "BibTeX (*.bib);;All (*)"); else if (_editor_mode == Annote) filename = c2bFileDialog::getSaveFilename(this, QString(), _editor_fn, "LaTeX (*.tex);;All (*)"); else filename = c2bFileDialog::getSaveFilename(this, QString(), _editor_fn, "Text (*.txt);;All (*)"); if (filename.isEmpty() || filename.contains("unnamed_")) return false; const QString old_name(_editor_fn); _editor_fn = filename; setWindowTitle(tr("%1[*] - cb2Bib").arg(_editor_fn)); _editorP->setEditorFilename(_editor_fn); emit editFileRenamed(old_name, _editor_fn); return fileSave(); } void c2bEditor::saveAndExecute() { // Use ui.fileSaveAction->isEnabled() instead of _is_modified_by_user. // If browsing search results there is no file on disk. if (ui.fileSaveAction->isEnabled()) { if (fileSave()) emit execute(); } else emit execute(); } void c2bEditor::load() { bool modified_flag(false); QFileInfo fi(_editor_fn); if (_editor_fn.isEmpty() || fi.isDir()) // Set an appropriate working name { QStringList unamedList; foreach (QWidget* widget, QApplication::topLevelWidgets()) { if (widget->inherits("c2bEditor")) unamedList.append(widget->objectName()); } int i(1); while (unamedList.indexOf(QRegExp(QString(".*unnamed_%1.bib").arg(i))) > -1) ++i; _editor_fn = QDir::toNativeSeparators(QDir::cleanPath(_editor_fn + QDir::separator() + QString("unnamed_%1.bib").arg(i))); if (_searcherP) { _editorP->setPlainText(_searcherP->logString() + _searcherP->hitsString()); modified_flag = true; } } else { QRegExp edit_ref_id(":(\\d+)$"); if (edit_ref_id.indexIn(_editor_fn) > -1) { _edit_reference_at_position = edit_ref_id.cap(1); _editor_fn.remove(edit_ref_id); } QFile file(_editor_fn); if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) { QMessageBox::warning( _c2b_mainP, tr("Warning - cb2Bib"), tr("Unable to open the file %1 for reading.\nError: '%2'.").arg(_editor_fn, file.errorString()), QMessageBox::Ok); } else { QTextStream stream(&file); stream.setCodec("UTF-8"); stream.setAutoDetectUnicode(true); _editorP->setPlainText(stream.readAll()); } } setWindowTitle(tr("%1[*] - cb2Bib").arg(_editor_fn)); _editorP->setEditorFilename(_editor_fn); ui.fileSaveAction->setEnabled(modified_flag); _editorP->document()->setModified(modified_flag); setWindowModified(modified_flag); _is_modified_by_user = false; } void c2bEditor::reload(const QString& fn) { // This function must be called ONLY in BibTeX mode // Pointers are undefined otherwise if (_editor_mode != BibTeX || _editor_fn != fn) return; if (ui.fileSaveAction->isEnabled()) { QMessageBox msgBox(this); msgBox.addButton(tr("Discard and Reload"), QMessageBox::AcceptRole); msgBox.addButton(QMessageBox::Cancel); msgBox.setDefaultButton(msgBox.addButton(QMessageBox::Save)); msgBox.setWindowTitle(tr("Information - cb2Bib")); msgBox.setText(tr("The document has been modified on disk when the reference was inserted. " "No automatic reloading is done because it also has local changes. " "To preserve local changes press Save and insert again the last reference.\n\n" "Do you want to save the changes?")); msgBox.setIcon(QMessageBox::Information); const int button(msgBox.exec()); if (button == QMessageBox::Save) { fileSave(); _referencesP->refreshList(); return; } else if (button == QMessageBox::Cancel) return; } load(); _referencesP->refreshList(); QTextCursor cur = _editorP->textCursor(); cur.movePosition(QTextCursor::End, QTextCursor::MoveAnchor); _editorP->setTextCursor(cur); _editorP->ensureCursorVisible(); } void c2bEditor::exportEntries() { const QStringList keys(_referencesP->selectedKeys()); if (keys.count() == 0) return; c2bExportDialog ed(_editor_fn, _editorP->toPlainText(), keys, this); if (ed.exec()) emit openFile(ed.exportFilename()); } void c2bEditor::pasteCurrentBibTeX() { _editorP->insertPlainText(_bpP->toBibTeX(false)); } void c2bEditor::journalsToFull() { QApplication::setOverrideCursor(QCursor(Qt::WaitCursor)); const QString text(_bpP->setJournalsToFull(_editorP->toPlainText(), false)); _editorP->updatePlainText(text); QApplication::restoreOverrideCursor(); } void c2bEditor::journalsToAlternateFull() { QApplication::setOverrideCursor(QCursor(Qt::WaitCursor)); const QString text(_bpP->setJournalsToFull(_editorP->toPlainText(), true)); _editorP->updatePlainText(text); QApplication::restoreOverrideCursor(); } void c2bEditor::journalsToAbbreviated() { QApplication::setOverrideCursor(QCursor(Qt::WaitCursor)); const QString text(_bpP->setJournalsToAbbreviated(_editorP->toPlainText(), false)); _editorP->updatePlainText(text); QApplication::restoreOverrideCursor(); } void c2bEditor::journalsToAlternateAbbreviated() { QApplication::setOverrideCursor(QCursor(Qt::WaitCursor)); const QString text(_bpP->setJournalsToAbbreviated(_editorP->toPlainText(), true)); _editorP->updatePlainText(text); QApplication::restoreOverrideCursor(); } void c2bEditor::updateMetadata() { c2bUpdateMetadata um(this); um.update(_editor_fn, _editorP->toPlainText()); } void c2bEditor::htmlView() { QApplication::setOverrideCursor(QCursor(Qt::WaitCursor)); const QString html_filename(_editor_fn + ".html"); texToHtml t2h; t2h.toHtml(c2bUtils::fileToString(_editor_fn), html_filename); c2bUtils::openFile(html_filename); QApplication::restoreOverrideCursor(); } void c2bEditor::postProcess() { c2bPostprocess* ppBib = new c2bPostprocess(_editor_fn, this); ppBib->show(); } void c2bEditor::helpEditor() { c2bUtils::displayHelp("https://www.molspaces.com/cb2bib/doc/bibeditor/"); } void c2bEditor::helpCb2Bib() { const QString umanual(QDir::cleanPath(_settingsP->applicationDataDir() + "/doc/cb2bib_user_manual.pdf")); if (QFileInfo::exists(umanual)) c2bUtils::displayHelp(umanual); else c2bUtils::displayHelp("https://www.molspaces.com/cb2bib/doc/contents/"); } void c2bEditor::viewCb2Bib() { c2bUtils::setWidgetOnTop(_c2b_mainP); } void c2bEditor::setViewMode(bool edit_mode) { QList<QAction*> acts; if (edit_mode) { _textFinderP->setEditor(_editorP); if (_browserP) { acts = _browserP->actions(); for (int i = 0; i < acts.count(); ++i) acts.at(i)->setVisible(false); ui.viewZoomInAction->setVisible(false); ui.viewZoomOutAction->setVisible(false); } acts = _editorP->actions(); for (int i = 0; i < acts.count(); ++i) acts.at(i)->setVisible(true); _overwriteLabelP->setVisible(true); _lineLabelP->setVisible(true); _stackedWidgetP->setCurrentWidget(_editorP); } else { // Browser defined _textFinderP->setEditor(_browserP); acts = _editorP->actions(); for (int i = 0; i < acts.count(); ++i) acts.at(i)->setVisible(false); acts = _browserP->actions(); for (int i = 0; i < acts.count(); ++i) acts.at(i)->setVisible(true); ui.viewZoomInAction->setVisible(true); ui.viewZoomOutAction->setVisible(true); _overwriteLabelP->setVisible(false); _lineLabelP->setVisible(false); _stackedWidgetP->setCurrentWidget(_browserP); } } void c2bEditor::showMessage(const QString& ms) { statusBar()->showMessage(ms, C2B_MESSAGE_TIME); } void c2bEditor::cursorPositionChanged() { int ln, lp; _editorP->cursorPosition(&ln, &lp); _lineLabelP->setText(tr(" Line: %1 Col: %2 ").arg(ln).arg(lp)); } void c2bEditor::overwriteModeChanged() { if (_editorP->overwriteMode()) _overwriteLabelP->setText(tr(" OVR ")); else _overwriteLabelP->setText(tr(" INS ")); } �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������cb2bib-2.0.1/src/PaxHeaders.5700/qtsingleapplication������������������������������������������������0000644�0000000�0000000�00000000074�14011522151�017066� x����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������30 atime=1613145424.838620334 30 ctime=1613145424.306620349 ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������cb2bib-2.0.1/src/qtsingleapplication/���������������������������������������������������������������0000755�0001750�0000144�00000000000�14011522151�020535� 5����������������������������������������������������������������������������������������������������ustar�00constans������������������������users���������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������cb2bib-2.0.1/src/qtsingleapplication/PaxHeaders.5700/README.TXT�������������������������������������0000644�0000000�0000000�00000000074�14011522151�020501� x����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������30 atime=1613145424.838620334 30 ctime=1613145424.306620349 ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������cb2bib-2.0.1/src/qtsingleapplication/README.TXT�����������������������������������������������������0000644�0001750�0000144�00000001641�14011522151�022075� 0����������������������������������������������������������������������������������������������������ustar�00constans������������������������users���������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������Qt Solutions Component: Single Application The QtSingleApplication component provides support for applications that can be only started once per user. Version history: 2.0: - Version 1.3 ported to Qt 4. 2.1: - Fix compilation problem on Mac. 2.2: - Really fix the Mac compilation problem. - Mac: fix crash due to wrong object releasing. - Mac: Fix memory leak. 2.3: - Windows: Force creation of internal widget to make it work with Qt 4.2. 2.4: - Fix the system for automatic window raising on message reception. NOTE: minor API change. 2.5: - Mac: Fix isRunning() to work and report correctly. 2.6: - - initialize() is now obsolete, no longer necessary to call it - - Fixed race condition where multiple instances migth be started - - QtSingleCoreApplication variant provided for non-GUI (console) usage - Complete reimplementation. Visible changes: - LGPL release. �����������������������������������������������������������������������������������������������cb2bib-2.0.1/src/qtsingleapplication/PaxHeaders.5700/INSTALL.TXT������������������������������������0000644�0000000�0000000�00000000074�14011522151�020652� x����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������30 atime=1613145424.838620334 30 ctime=1613145424.306620349 ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������cb2bib-2.0.1/src/qtsingleapplication/INSTALL.TXT����������������������������������������������������0000644�0001750�0000144�00000022374�14011522151�022254� 0����������������������������������������������������������������������������������������������������ustar�00constans������������������������users���������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������INSTALLATION INSTRUCTIONS These instructions refer to the package you are installing as some-package.tar.gz or some-package.zip. The .zip file is intended for use on Windows. The directory you choose for the installation will be referred to as your-install-dir. Note to Qt Visual Studio Integration users: In the instructions below, instead of building from command line with nmake, you can use the menu command 'Qt->Open Solution from .pro file' on the .pro files in the example and plugin directories, and then build from within Visual Studio. Unpacking and installation -------------------------- 1. Unpacking the archive (if you have not done so already). On Unix and Mac OS X (in a terminal window): cd your-install-dir gunzip some-package.tar.gz tar xvf some-package.tar This creates the subdirectory some-package containing the files. On Windows: Unpack the .zip archive by right-clicking it in explorer and choosing "Extract All...". If your version of Windows does not have zip support, you can use the infozip tools available from www.info-zip.org. If you are using the infozip tools (in a command prompt window): cd your-install-dir unzip some-package.zip 2. Configuring the package. The configure script is called "configure" on unix/mac and "configure.bat" on Windows. It should be run from a command line after cd'ing to the package directory. You can choose whether you want to use the component by including its source code directly into your project, or build the component as a dynamic shared library (DLL) that is loaded into the application at run-time. The latter may be preferable for technical or licensing (LGPL) reasons. If you want to build a DLL, run the configure script with the argument "-library". Also see the note about usage below. (Components that are Qt plugins, e.g. styles and image formats, are by default built as a plugin DLL.) The configure script will prompt you in some cases for further information. Answer these questions and carefully read the license text before accepting the license conditions. The package cannot be used if you do not accept the license conditions. 3. Building the component and examples (when required). If a DLL is to be built, or if you would like to build the examples, next give the commands qmake make [or nmake if your are using Microsoft Visual C++] The example program(s) can be found in the directory called "examples" or "example". Components that are Qt plugins, e.g. styles and image formats, are ready to be used as soon as they are built, so the rest of this installation instruction can be skipped. 4. Building the Qt Designer plugin (optional). Some of the widget components are provided with plugins for Qt Designer. To build and install the plugin, cd into the some-package/plugin directory and give the commands qmake make [or nmake if your are using Microsoft Visual C++] Restart Qt Designer to make it load the new widget plugin. Note: If you are using the built-in Qt Designer from the Qt Visual Studio Integration, you will need to manually copy the plugin DLL file, i.e. copy %QTDIR%\plugins\designer\some-component.dll to the Qt Visual Studio Integration plugin path, typically: C:\Program Files\Trolltech\Qt VS Integration\plugins Note: If you for some reason are using a Qt Designer that is built in debug mode, you will need to build the plugin in debug mode also. Edit the file plugin.pro in the plugin directory, changing 'release' to 'debug' in the CONFIG line, before running qmake. Solutions components are intended to be used directly from the package directory during development, so there is no 'make install' procedure. Using a component in your project --------------------------------- To use this component in your project, add the following line to the project's .pro file (or do the equivalent in your IDE): include(your-install-dir/some-package/src/some-package.pri) This adds the package's sources and headers to the SOURCES and HEADERS project variables respectively (or, if the component has been configured as a DLL, it adds that library to the LIBS variable), and updates INCLUDEPATH to contain the package's src directory. Additionally, the .pri file may include some dependencies needed by the package. To include a header file from the package in your sources, you can now simply use: #include <SomeClass> or alternatively, in pre-Qt 4 style: #include <some-class.h> Refer to the documentation to see the classes and headers this components provides. Install documentation (optional) -------------------------------- The HTML documentation for the package's classes is located in the your-install-dir/some-package/doc/html/index.html. You can open this file and read the documentation with any web browser. To install the documentation into Qt Assistant (for Qt version 4.4 and later): 1. In Assistant, open the Edit->Preferences dialog and choose the Documentation tab. Click the Add... button and select the file your-install-dir/some-package/doc/html/some-package.qch For Qt versions prior to 4.4, do instead the following: 1. The directory your-install-dir/some-package/doc/html contains a file called some-package.dcf. Execute the following commands in a shell, command prompt or terminal window: cd your-install-dir/some-package/doc/html/ assistant -addContentFile some-package.dcf The next time you start Qt Assistant, you can access the package's documentation. Removing the documentation from assistant ----------------------------------------- If you have installed the documentation into Qt Assistant, and want to uninstall it, do as follows, for Qt version 4.4 and later: 1. In Assistant, open the Edit->Preferences dialog and choose the Documentation tab. In the list of Registered Documentation, select the item com.nokia.qtsolutions.some-package_version, and click the Remove button. For Qt versions prior to 4.4, do instead the following: 1. The directory your-install-dir/some-package/doc/html contains a file called some-package.dcf. Execute the following commands in a shell, command prompt or terminal window: cd your-install-dir/some-package/doc/html/ assistant -removeContentFile some-package.dcf Using the component as a DLL ---------------------------- 1. Normal components The shared library (DLL) is built and placed in the some-package/lib directory. It is intended to be used directly from there during development. When appropriate, both debug and release versions are built, since the run-time linker will in some cases refuse to load a debug-built DLL into a release-built application or vice versa. The following steps are taken by default to help the dynamic linker to locate the DLL at run-time (during development): Unix: The some-package.pri file will add linker instructions to add the some-package/lib directory to the rpath of the executable. (When distributing, or if your system does not support rpath, you can copy the shared library to another place that is searched by the dynamic linker, e.g. the "lib" directory of your Qt installation.) Mac: The full path to the library is hardcoded into the library itself, from where it is copied into the executable at link time, and ready by the dynamic linker at run-time. (When distributing, you will want to edit these hardcoded paths in the same way as for the Qt DLLs. Refer to the document "Deploying an Application on Mac OS X" in the Qt Reference Documentation.) Windows: the .dll file(s) are copied into the "bin" directory of your Qt installation. The Qt installation will already have set up that directory to be searched by the dynamic linker. 2. Plugins For Qt Solutions plugins (e.g. image formats), both debug and release versions of the plugin are built by default when appropriate, since in some cases the release Qt library will not load a debug plugin, and vice versa. The plugins are automatically copied into the plugins directory of your Qt installation when built, so no further setup is required. Plugins may also be built statically, i.e. as a library that will be linked into your application executable, and so will not need to be redistributed as a separate plugin DLL to end users. Static building is required if Qt itself is built statically. To do it, just add "static" to the CONFIG variable in the plugin/plugin.pro file before building. Refer to the "Static Plugins" section in the chapter "How to Create Qt Plugins" for explanation of how to use a static plugin in your application. The source code of the example program(s) will also typically contain the relevant instructions as comments. Uninstalling ------------ The following command will remove any fils that have been automatically placed outside the package directory itself during installation and building make distclean [or nmake if your are using Microsoft Visual C++] If Qt Assistant documentation or Qt Designer plugins have been installed, they can be uninstalled manually, ref. above. Enjoy! :) - The Qt Solutions Team. ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������cb2bib-2.0.1/src/qtsingleapplication/PaxHeaders.5700/src��������������������������������������������0000644�0000000�0000000�00000000074�14011522151�017655� x����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������30 atime=1613145424.838620334 30 ctime=1613145424.306620349 ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������cb2bib-2.0.1/src/qtsingleapplication/src/�����������������������������������������������������������0000755�0001750�0000144�00000000000�14011522151�021324� 5����������������������������������������������������������������������������������������������������ustar�00constans������������������������users���������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������cb2bib-2.0.1/src/qtsingleapplication/src/PaxHeaders.5700/qtlockedfile.h�����������������������������0000644�0000000�0000000�00000000074�14011522151�022551� x����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������30 atime=1613145424.838620334 30 ctime=1613145424.306620349 ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������cb2bib-2.0.1/src/qtsingleapplication/src/qtlockedfile.h���������������������������������������������0000644�0001750�0000144�00000006320�14011522151�024144� 0����������������������������������������������������������������������������������������������������ustar�00constans������������������������users���������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/**************************************************************************** ** ** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). ** Contact: http://www.qt-project.org/legal ** ** This file is part of the Qt Solutions component. ** ** $QT_BEGIN_LICENSE:BSD$ ** You may use this file under the terms of the BSD license as follows: ** ** "Redistribution and use in source and binary forms, with or without ** modification, are permitted provided that the following conditions are ** met: ** * Redistributions of source code must retain the above copyright ** notice, this list of conditions and the following disclaimer. ** * Redistributions in binary form must reproduce the above copyright ** notice, this list of conditions and the following disclaimer in ** the documentation and/or other materials provided with the ** distribution. ** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names ** of its contributors may be used to endorse or promote products derived ** from this software without specific prior written permission. ** ** ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT ** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR ** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT ** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT ** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, ** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY ** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." ** ** $QT_END_LICENSE$ ** ****************************************************************************/ #ifndef QTLOCKEDFILE_H #define QTLOCKEDFILE_H #include <QFile> #ifdef Q_OS_WIN #include <QVector> #endif #if defined(Q_OS_WIN) # if !defined(QT_QTLOCKEDFILE_EXPORT) && !defined(QT_QTLOCKEDFILE_IMPORT) # define QT_QTLOCKEDFILE_EXPORT # elif defined(QT_QTLOCKEDFILE_IMPORT) # if defined(QT_QTLOCKEDFILE_EXPORT) # undef QT_QTLOCKEDFILE_EXPORT # endif # define QT_QTLOCKEDFILE_EXPORT __declspec(dllimport) # elif defined(QT_QTLOCKEDFILE_EXPORT) # undef QT_QTLOCKEDFILE_EXPORT # define QT_QTLOCKEDFILE_EXPORT __declspec(dllexport) # endif #else # define QT_QTLOCKEDFILE_EXPORT #endif namespace QtLP_Private { class QT_QTLOCKEDFILE_EXPORT QtLockedFile : public QFile { public: enum LockMode { NoLock = 0, ReadLock, WriteLock }; QtLockedFile(); explicit QtLockedFile(const QString& name); ~QtLockedFile(); bool open(OpenMode mode); bool lock(LockMode mode, bool block = true); bool unlock(); bool isLocked() const; LockMode lockMode() const; private: #ifdef Q_OS_WIN Qt::HANDLE wmutex; Qt::HANDLE rmutex; QVector<Qt::HANDLE> rmutexes; QString mutexname; Qt::HANDLE getMutexHandle(int idx, bool doCreate); bool waitMutex(Qt::HANDLE mutex, bool doBlock); #endif LockMode m_lock_mode; }; } #endif ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������cb2bib-2.0.1/src/qtsingleapplication/src/PaxHeaders.5700/qtlocalpeer.cpp����������������������������0000644�0000000�0000000�00000000074�14011522151�022751� x����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������30 atime=1613145424.838620334 30 ctime=1613145424.306620349 ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������cb2bib-2.0.1/src/qtsingleapplication/src/qtlocalpeer.cpp��������������������������������������������0000644�0001750�0000144�00000015145�14011522151�024351� 0����������������������������������������������������������������������������������������������������ustar�00constans������������������������users���������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/**************************************************************************** ** ** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). ** Contact: http://www.qt-project.org/legal ** ** This file is part of the Qt Solutions component. ** ** $QT_BEGIN_LICENSE:BSD$ ** You may use this file under the terms of the BSD license as follows: ** ** "Redistribution and use in source and binary forms, with or without ** modification, are permitted provided that the following conditions are ** met: ** * Redistributions of source code must retain the above copyright ** notice, this list of conditions and the following disclaimer. ** * Redistributions in binary form must reproduce the above copyright ** notice, this list of conditions and the following disclaimer in ** the documentation and/or other materials provided with the ** distribution. ** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names ** of its contributors may be used to endorse or promote products derived ** from this software without specific prior written permission. ** ** ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT ** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR ** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT ** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT ** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, ** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY ** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." ** ** $QT_END_LICENSE$ ** ****************************************************************************/ #include "qtlocalpeer.h" #include <QCoreApplication> #include <QDataStream> #include <QTime> #if defined(Q_OS_WIN) #include <QLibrary> #include <qt_windows.h> typedef BOOL(WINAPI*PProcessIdToSessionId)(DWORD,DWORD*); static PProcessIdToSessionId pProcessIdToSessionId = 0; #endif #if defined(Q_OS_UNIX) #include <sys/types.h> #include <time.h> #include <unistd.h> #endif namespace QtLP_Private { #include "qtlockedfile.cpp" #if defined(Q_OS_WIN) #include "qtlockedfile_win.cpp" #else #include "qtlockedfile_unix.cpp" #endif } const char* QtLocalPeer::ack = "ack"; QtLocalPeer::QtLocalPeer(QObject* parento, const QString& appId) : QObject(parento), id(appId) { QString prefix = id; if (id.isEmpty()) { id = QCoreApplication::applicationFilePath(); #if defined(Q_OS_WIN) id = id.toLower(); #endif prefix = id.section(QLatin1Char('/'), -1); } prefix.remove(QRegExp("[^a-zA-Z]")); prefix.truncate(6); QByteArray idc = id.toUtf8(); quint16 idNum = qChecksum(idc.constData(), idc.size()); socketName = QLatin1String("qtsingleapp-") + prefix + QLatin1Char('-') + QString::number(idNum, 16); #if defined(Q_OS_WIN) if (!pProcessIdToSessionId) { QLibrary lib("kernel32"); pProcessIdToSessionId = (PProcessIdToSessionId)lib.resolve("ProcessIdToSessionId"); } if (pProcessIdToSessionId) { DWORD sessionId = 0; pProcessIdToSessionId(GetCurrentProcessId(), &sessionId); socketName += QLatin1Char('-') + QString::number(sessionId, 16); } #else socketName += QLatin1Char('-') + QString::number(::getuid(), 16); #endif server = new QLocalServer(this); QString lockName = QDir(QDir::tempPath()).absolutePath() + QLatin1Char('/') + socketName + QLatin1String("-lockfile"); lockFile.setFileName(lockName); lockFile.open(QIODevice::ReadWrite); } bool QtLocalPeer::isClient() { if (lockFile.isLocked()) return false; if (!lockFile.lock(QtLP_Private::QtLockedFile::WriteLock, false)) return true; bool res = server->listen(socketName); #if defined(Q_OS_UNIX) && (QT_VERSION >= QT_VERSION_CHECK(4,5,0)) // ### Workaround if (!res && server->serverError() == QAbstractSocket::AddressInUseError) { QFile::remove(QDir::cleanPath(QDir::tempPath()) + QLatin1Char('/') + socketName); res = server->listen(socketName); } #endif if (!res) qWarning("QtSingleCoreApplication: listen on local socket failed, %s", qPrintable(server->errorString())); QObject::connect(server, SIGNAL(newConnection()), SLOT(receiveConnection())); return false; } bool QtLocalPeer::sendMessage(const QString& message, int timeout) { if (!isClient()) return false; QLocalSocket socket; bool connOk = false; for (int i = 0; i < 2; i++) { // Try twice, in case the other instance is just starting up socket.connectToServer(socketName); connOk = socket.waitForConnected(timeout / 2); if (connOk || i) break; int ms = 250; #if defined(Q_OS_WIN) Sleep(DWORD(ms)); #else struct timespec ts = { ms / 1000, (ms % 1000) * 1000 * 1000 }; nanosleep(&ts, NULL); #endif } if (!connOk) return false; QByteArray uMsg(message.toUtf8()); QDataStream ds(&socket); ds.writeBytes(uMsg.constData(), uMsg.size()); bool res = socket.waitForBytesWritten(timeout); if (res) { res &= socket.waitForReadyRead(timeout); // wait for ack if (res) res &= (socket.read(qstrlen(ack)) == ack); } return res; } void QtLocalPeer::receiveConnection() { QLocalSocket* socket = server->nextPendingConnection(); if (!socket) return; while (socket->bytesAvailable() < (int)sizeof(quint32)) socket->waitForReadyRead(); QDataStream ds(socket); QByteArray uMsg; quint32 remaining; ds >> remaining; uMsg.resize(remaining); int got = 0; char* uMsgBuf = uMsg.data(); do { got = ds.readRawData(uMsgBuf, remaining); remaining -= got; uMsgBuf += got; } while (remaining && got >= 0 && socket->waitForReadyRead(2000)); if (got < 0) { qWarning("QtLocalPeer: Message reception failed %s", socket->errorString().toLatin1().constData()); delete socket; return; } QString message(QString::fromUtf8(uMsg)); socket->write(ack, qstrlen(ack)); socket->waitForBytesWritten(1000); socket->waitForDisconnected(1000); // make sure client reads ack delete socket; emit messageReceived(message); //### (might take a long time to return) } ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������cb2bib-2.0.1/src/qtsingleapplication/src/PaxHeaders.5700/qtlockedfile.cpp���������������������������0000644�0000000�0000000�00000000074�14011522151�023104� x����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������30 atime=1613145424.838620334 30 ctime=1613145424.306620349 ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������cb2bib-2.0.1/src/qtsingleapplication/src/qtlockedfile.cpp�������������������������������������������0000644�0001750�0000144�00000013746�14011522151�024511� 0����������������������������������������������������������������������������������������������������ustar�00constans������������������������users���������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/**************************************************************************** ** ** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). ** Contact: http://www.qt-project.org/legal ** ** This file is part of the Qt Solutions component. ** ** $QT_BEGIN_LICENSE:BSD$ ** You may use this file under the terms of the BSD license as follows: ** ** "Redistribution and use in source and binary forms, with or without ** modification, are permitted provided that the following conditions are ** met: ** * Redistributions of source code must retain the above copyright ** notice, this list of conditions and the following disclaimer. ** * Redistributions in binary form must reproduce the above copyright ** notice, this list of conditions and the following disclaimer in ** the documentation and/or other materials provided with the ** distribution. ** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names ** of its contributors may be used to endorse or promote products derived ** from this software without specific prior written permission. ** ** ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT ** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR ** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT ** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT ** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, ** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY ** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." ** ** $QT_END_LICENSE$ ** ****************************************************************************/ #include "qtlockedfile.h" /*! \class QtLockedFile \brief The QtLockedFile class extends QFile with advisory locking functions. A file may be locked in read or write mode. Multiple instances of \e QtLockedFile, created in multiple processes running on the same machine, may have a file locked in read mode. Exactly one instance may have it locked in write mode. A read and a write lock cannot exist simultaneously on the same file. The file locks are advisory. This means that nothing prevents another process from manipulating a locked file using QFile or file system functions offered by the OS. Serialization is only guaranteed if all processes that access the file use QLockedFile. Also, while holding a lock on a file, a process must not open the same file again (through any API), or locks can be unexpectedly lost. The lock provided by an instance of \e QtLockedFile is released whenever the program terminates. This is true even when the program crashes and no destructors are called. */ /*! \enum QtLockedFile::LockMode This enum describes the available lock modes. \value ReadLock A read lock. \value WriteLock A write lock. \value NoLock Neither a read lock nor a write lock. */ /*! Constructs an unlocked \e QtLockedFile object. This constructor behaves in the same way as \e QFile::QFile(). \sa QFile::QFile() */ QtLockedFile::QtLockedFile() : QFile() { #ifdef Q_OS_WIN wmutex = 0; rmutex = 0; #endif m_lock_mode = NoLock; } /*! Constructs an unlocked QtLockedFile object with file \a name. This constructor behaves in the same way as \e QFile::QFile(const QString&). \sa QFile::QFile() */ QtLockedFile::QtLockedFile(const QString& name) : QFile(name) { #ifdef Q_OS_WIN wmutex = 0; rmutex = 0; #endif m_lock_mode = NoLock; } /*! Opens the file in OpenMode \a mode. This is identical to QFile::open(), with the one exception that the Truncate mode flag is disallowed. Truncation would conflict with the advisory file locking, since the file would be modified before the write lock is obtained. If truncation is required, use resize(0) after obtaining the write lock. Returns true if successful; otherwise false. \sa QFile::open(), QFile::resize() */ bool QtLockedFile::open(OpenMode mode) { if (mode & QIODevice::Truncate) { qWarning("QtLockedFile::open(): Truncate mode not allowed."); return false; } return QFile::open(mode); } /*! Returns \e true if this object has a in read or write lock; otherwise returns \e false. \sa lockMode() */ bool QtLockedFile::isLocked() const { return m_lock_mode != NoLock; } /*! Returns the type of lock currently held by this object, or \e QtLockedFile::NoLock. \sa isLocked() */ QtLockedFile::LockMode QtLockedFile::lockMode() const { return m_lock_mode; } /*! \fn bool QtLockedFile::lock(LockMode mode, bool block = true) Obtains a lock of type \a mode. The file must be opened before it can be locked. If \a block is true, this function will block until the lock is aquired. If \a block is false, this function returns \e false immediately if the lock cannot be aquired. If this object already has a lock of type \a mode, this function returns \e true immediately. If this object has a lock of a different type than \a mode, the lock is first released and then a new lock is obtained. This function returns \e true if, after it executes, the file is locked by this object, and \e false otherwise. \sa unlock(), isLocked(), lockMode() */ /*! \fn bool QtLockedFile::unlock() Releases a lock. If the object has no lock, this function returns immediately. This function returns \e true if, after it executes, the file is not locked by this object, and \e false otherwise. \sa lock(), isLocked(), lockMode() */ /*! \fn QtLockedFile::~QtLockedFile() Destroys the \e QtLockedFile object. If any locks were held, they are released. */ ��������������������������cb2bib-2.0.1/src/qtsingleapplication/src/PaxHeaders.5700/qtsingleapplication.h����������������������0000644�0000000�0000000�00000000074�14011522151�024155� x����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������30 atime=1613145424.838620334 30 ctime=1613145424.306620349 ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������cb2bib-2.0.1/src/qtsingleapplication/src/qtsingleapplication.h��������������������������������������0000644�0001750�0000144�00000007654�14011522151�025563� 0����������������������������������������������������������������������������������������������������ustar�00constans������������������������users���������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/**************************************************************************** ** ** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). ** Contact: http://www.qt-project.org/legal ** ** This file is part of the Qt Solutions component. ** ** $QT_BEGIN_LICENSE:BSD$ ** You may use this file under the terms of the BSD license as follows: ** ** "Redistribution and use in source and binary forms, with or without ** modification, are permitted provided that the following conditions are ** met: ** * Redistributions of source code must retain the above copyright ** notice, this list of conditions and the following disclaimer. ** * Redistributions in binary form must reproduce the above copyright ** notice, this list of conditions and the following disclaimer in ** the documentation and/or other materials provided with the ** distribution. ** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names ** of its contributors may be used to endorse or promote products derived ** from this software without specific prior written permission. ** ** ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT ** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR ** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT ** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT ** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, ** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY ** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." ** ** $QT_END_LICENSE$ ** ****************************************************************************/ #ifndef QTSINGLEAPPLICATION_H #define QTSINGLEAPPLICATION_H #include <QApplication> class QtLocalPeer; #if defined(Q_OS_WIN) # if !defined(QT_QTSINGLEAPPLICATION_EXPORT) && !defined(QT_QTSINGLEAPPLICATION_IMPORT) # define QT_QTSINGLEAPPLICATION_EXPORT # elif defined(QT_QTSINGLEAPPLICATION_IMPORT) # if defined(QT_QTSINGLEAPPLICATION_EXPORT) # undef QT_QTSINGLEAPPLICATION_EXPORT # endif # define QT_QTSINGLEAPPLICATION_EXPORT __declspec(dllimport) # elif defined(QT_QTSINGLEAPPLICATION_EXPORT) # undef QT_QTSINGLEAPPLICATION_EXPORT # define QT_QTSINGLEAPPLICATION_EXPORT __declspec(dllexport) # endif #else # define QT_QTSINGLEAPPLICATION_EXPORT #endif class QT_QTSINGLEAPPLICATION_EXPORT QtSingleApplication : public QApplication { Q_OBJECT public: QtSingleApplication(int& argc, char** argv, bool GUIenabled = true); QtSingleApplication(const QString& appId, int& argc, char** argv); #if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) QtSingleApplication(int& argc, char** argv, Type type); # if defined(Q_WS_X11) QtSingleApplication(Display* dpy, Qt::HANDLE visual = 0, Qt::HANDLE cmap = 0); QtSingleApplication(Display* dpy, int& argc, char** argv, Qt::HANDLE visual = 0, Qt::HANDLE cmap = 0); QtSingleApplication(Display* dpy, const QString& appId, int argc, char** argv, Qt::HANDLE visual = 0, Qt::HANDLE cmap = 0); # endif // Q_WS_X11 #endif // QT_VERSION < 0x050000 bool isRunning(); QString id() const; void setActivationWindow(QWidget* aw, bool activateOnMessage = true); QWidget* activationWindow() const; // Obsolete: void initialize(bool dummy = true) { isRunning(); Q_UNUSED(dummy) } public Q_SLOTS: bool sendMessage(const QString& message, int timeout = 5000); void activateWindow(); Q_SIGNALS: void messageReceived(const QString& message); private: void sysInit(const QString& appId = QString()); QtLocalPeer* peer; QWidget* actWin; }; #endif // QTSINGLEAPPLICATION_H ������������������������������������������������������������������������������������cb2bib-2.0.1/src/qtsingleapplication/src/PaxHeaders.5700/qtlockedfile_win.cpp�����������������������0000644�0000000�0000000�00000000074�14011522151�023761� x����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������30 atime=1613145424.838620334 30 ctime=1613145424.306620349 ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������cb2bib-2.0.1/src/qtsingleapplication/src/qtlockedfile_win.cpp���������������������������������������0000644�0001750�0000144�00000015055�14011522151�025361� 0����������������������������������������������������������������������������������������������������ustar�00constans������������������������users���������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/**************************************************************************** ** ** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). ** Contact: http://www.qt-project.org/legal ** ** This file is part of the Qt Solutions component. ** ** $QT_BEGIN_LICENSE:BSD$ ** You may use this file under the terms of the BSD license as follows: ** ** "Redistribution and use in source and binary forms, with or without ** modification, are permitted provided that the following conditions are ** met: ** * Redistributions of source code must retain the above copyright ** notice, this list of conditions and the following disclaimer. ** * Redistributions in binary form must reproduce the above copyright ** notice, this list of conditions and the following disclaimer in ** the documentation and/or other materials provided with the ** distribution. ** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names ** of its contributors may be used to endorse or promote products derived ** from this software without specific prior written permission. ** ** ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT ** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR ** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT ** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT ** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, ** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY ** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." ** ** $QT_END_LICENSE$ ** ****************************************************************************/ #include "qtlockedfile.h" #include <qt_windows.h> #include <QFileInfo> #define MUTEX_PREFIX "QtLockedFile mutex " // Maximum number of concurrent read locks. Must not be greater than MAXIMUM_WAIT_OBJECTS #define MAX_READERS MAXIMUM_WAIT_OBJECTS #if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0) #define QT_WA(unicode, ansi) unicode #endif Qt::HANDLE QtLockedFile::getMutexHandle(int idx, bool doCreate) { if (mutexname.isEmpty()) { QFileInfo fi(*this); mutexname = QString::fromLatin1(MUTEX_PREFIX) + fi.absoluteFilePath().toLower(); } QString mname(mutexname); if (idx >= 0) mname += QString::number(idx); Qt::HANDLE mutex; if (doCreate) { QT_WA({ mutex = CreateMutexW(NULL, FALSE, (TCHAR*)mname.utf16()); }, { mutex = CreateMutexA(NULL, FALSE, mname.toLocal8Bit().constData()); }); if (!mutex) { qErrnoWarning("QtLockedFile::lock(): CreateMutex failed"); return 0; } } else { QT_WA({ mutex = OpenMutexW(SYNCHRONIZE | MUTEX_MODIFY_STATE, FALSE, (TCHAR*)mname.utf16()); }, { mutex = OpenMutexA(SYNCHRONIZE | MUTEX_MODIFY_STATE, FALSE, mname.toLocal8Bit().constData()); }); if (!mutex) { if (GetLastError() != ERROR_FILE_NOT_FOUND) qErrnoWarning("QtLockedFile::lock(): OpenMutex failed"); return 0; } } return mutex; } bool QtLockedFile::waitMutex(Qt::HANDLE mutex, bool doBlock) { Q_ASSERT(mutex); DWORD res = WaitForSingleObject(mutex, doBlock ? INFINITE : 0); switch (res) { case WAIT_OBJECT_0: case WAIT_ABANDONED: return true; break; case WAIT_TIMEOUT: break; default: qErrnoWarning("QtLockedFile::lock(): WaitForSingleObject failed"); } return false; } bool QtLockedFile::lock(LockMode mode, bool block) { if (!isOpen()) { qWarning("QtLockedFile::lock(): file is not opened"); return false; } if (mode == NoLock) return unlock(); if (mode == m_lock_mode) return true; if (m_lock_mode != NoLock) unlock(); if (!wmutex && !(wmutex = getMutexHandle(-1, true))) return false; if (!waitMutex(wmutex, block)) return false; if (mode == ReadLock) { int idx = 0; for (; idx < MAX_READERS; idx++) { rmutex = getMutexHandle(idx, false); if (!rmutex || waitMutex(rmutex, false)) break; CloseHandle(rmutex); } bool ok = true; if (idx >= MAX_READERS) { qWarning("QtLockedFile::lock(): too many readers"); rmutex = 0; ok = false; } else if (!rmutex) { rmutex = getMutexHandle(idx, true); if (!rmutex || !waitMutex(rmutex, false)) ok = false; } if (!ok && rmutex) { CloseHandle(rmutex); rmutex = 0; } ReleaseMutex(wmutex); if (!ok) return false; } else { Q_ASSERT(rmutexes.isEmpty()); for (int i = 0; i < MAX_READERS; i++) { Qt::HANDLE mutex = getMutexHandle(i, false); if (mutex) rmutexes.append(mutex); } if (rmutexes.size()) { DWORD res = WaitForMultipleObjects(rmutexes.size(), rmutexes.constData(), TRUE, block ? INFINITE : 0); if (res != WAIT_OBJECT_0 && res != WAIT_ABANDONED) { if (res != WAIT_TIMEOUT) qErrnoWarning("QtLockedFile::lock(): WaitForMultipleObjects failed"); m_lock_mode = WriteLock; // trick unlock() to clean up - semiyucky unlock(); return false; } } } m_lock_mode = mode; return true; } bool QtLockedFile::unlock() { if (!isOpen()) { qWarning("QtLockedFile::unlock(): file is not opened"); return false; } if (!isLocked()) return true; if (m_lock_mode == ReadLock) { ReleaseMutex(rmutex); CloseHandle(rmutex); rmutex = 0; } else { foreach (Qt::HANDLE mutex, rmutexes) { ReleaseMutex(mutex); CloseHandle(mutex); } rmutexes.clear(); ReleaseMutex(wmutex); } m_lock_mode = QtLockedFile::NoLock; return true; } QtLockedFile::~QtLockedFile() { if (isOpen()) unlock(); if (wmutex) CloseHandle(wmutex); } �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������cb2bib-2.0.1/src/qtsingleapplication/src/PaxHeaders.5700/qtsinglecoreapplication.h������������������0000644�0000000�0000000�00000000074�14011522151�025026� x����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������30 atime=1613145424.838620334 30 ctime=1613145424.306620349 ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������cb2bib-2.0.1/src/qtsingleapplication/src/qtsinglecoreapplication.h����������������������������������0000644�0001750�0000144�00000005030�14011522151�026416� 0����������������������������������������������������������������������������������������������������ustar�00constans������������������������users���������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/**************************************************************************** ** ** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). ** Contact: http://www.qt-project.org/legal ** ** This file is part of the Qt Solutions component. ** ** $QT_BEGIN_LICENSE:BSD$ ** You may use this file under the terms of the BSD license as follows: ** ** "Redistribution and use in source and binary forms, with or without ** modification, are permitted provided that the following conditions are ** met: ** * Redistributions of source code must retain the above copyright ** notice, this list of conditions and the following disclaimer. ** * Redistributions in binary form must reproduce the above copyright ** notice, this list of conditions and the following disclaimer in ** the documentation and/or other materials provided with the ** distribution. ** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names ** of its contributors may be used to endorse or promote products derived ** from this software without specific prior written permission. ** ** ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT ** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR ** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT ** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT ** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, ** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY ** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." ** ** $QT_END_LICENSE$ ** ****************************************************************************/ #ifndef QTSINGLECOREAPPLICATION_H #define QTSINGLECOREAPPLICATION_H #include <QCoreApplication> class QtLocalPeer; class QtSingleCoreApplication : public QCoreApplication { Q_OBJECT public: QtSingleCoreApplication(int& argc, char** argv); QtSingleCoreApplication(const QString& appId, int& argc, char** argv); bool isRunning(); QString id() const; public Q_SLOTS: bool sendMessage(const QString& message, int timeout = 5000); Q_SIGNALS: void messageReceived(const QString& message); private: QtLocalPeer* peer; }; #endif // QTSINGLECOREAPPLICATION_H ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������cb2bib-2.0.1/src/qtsingleapplication/src/PaxHeaders.5700/qtlocalpeer.h������������������������������0000644�0000000�0000000�00000000074�14011522151�022416� x����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������30 atime=1613145424.838620334 30 ctime=1613145424.306620349 ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������cb2bib-2.0.1/src/qtsingleapplication/src/qtlocalpeer.h����������������������������������������������0000644�0001750�0000144�00000005216�14011522151�024014� 0����������������������������������������������������������������������������������������������������ustar�00constans������������������������users���������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/**************************************************************************** ** ** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). ** Contact: http://www.qt-project.org/legal ** ** This file is part of the Qt Solutions component. ** ** $QT_BEGIN_LICENSE:BSD$ ** You may use this file under the terms of the BSD license as follows: ** ** "Redistribution and use in source and binary forms, with or without ** modification, are permitted provided that the following conditions are ** met: ** * Redistributions of source code must retain the above copyright ** notice, this list of conditions and the following disclaimer. ** * Redistributions in binary form must reproduce the above copyright ** notice, this list of conditions and the following disclaimer in ** the documentation and/or other materials provided with the ** distribution. ** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names ** of its contributors may be used to endorse or promote products derived ** from this software without specific prior written permission. ** ** ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT ** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR ** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT ** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT ** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, ** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY ** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." ** ** $QT_END_LICENSE$ ** ****************************************************************************/ #ifndef QTLOCALPEER_H #define QTLOCALPEER_H #include <QLocalServer> #include <QLocalSocket> #include <QDir> #include "qtlockedfile.h" class QtLocalPeer : public QObject { Q_OBJECT public: QtLocalPeer(QObject* parento = 0, const QString& appId = QString()); bool isClient(); bool sendMessage(const QString& message, int timeout); QString applicationId() const { return id; } Q_SIGNALS: void messageReceived(const QString& message); protected Q_SLOTS: void receiveConnection(); protected: QString id; QString socketName; QLocalServer* server; QtLP_Private::QtLockedFile lockFile; private: static const char* ack; }; #endif // QTLOCALPEER_H ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������cb2bib-2.0.1/src/qtsingleapplication/src/PaxHeaders.5700/qtsinglecoreapplication.cpp����������������0000644�0000000�0000000�00000000074�14011522151�025361� x����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������30 atime=1613145424.838620334 30 ctime=1613145424.306620349 ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������cb2bib-2.0.1/src/qtsingleapplication/src/qtsinglecoreapplication.cpp��������������������������������0000644�0001750�0000144�00000012321�14011522151�026752� 0����������������������������������������������������������������������������������������������������ustar�00constans������������������������users���������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/**************************************************************************** ** ** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). ** Contact: http://www.qt-project.org/legal ** ** This file is part of the Qt Solutions component. ** ** $QT_BEGIN_LICENSE:BSD$ ** You may use this file under the terms of the BSD license as follows: ** ** "Redistribution and use in source and binary forms, with or without ** modification, are permitted provided that the following conditions are ** met: ** * Redistributions of source code must retain the above copyright ** notice, this list of conditions and the following disclaimer. ** * Redistributions in binary form must reproduce the above copyright ** notice, this list of conditions and the following disclaimer in ** the documentation and/or other materials provided with the ** distribution. ** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names ** of its contributors may be used to endorse or promote products derived ** from this software without specific prior written permission. ** ** ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT ** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR ** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT ** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT ** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, ** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY ** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." ** ** $QT_END_LICENSE$ ** ****************************************************************************/ #include "qtsinglecoreapplication.h" #include "qtlocalpeer.h" /*! \class QtSingleCoreApplication qtsinglecoreapplication.h \brief A variant of the QtSingleApplication class for non-GUI applications. This class is a variant of QtSingleApplication suited for use in console (non-GUI) applications. It is an extension of QCoreApplication (instead of QApplication). It does not require the QtGui library. The API and usage is identical to QtSingleApplication, except that functions relating to the "activation window" are not present, for obvious reasons. Please refer to the QtSingleApplication documentation for explanation of the usage. A QtSingleCoreApplication instance can communicate to a QtSingleApplication instance if they share the same application id. Hence, this class can be used to create a light-weight command-line tool that sends commands to a GUI application. \sa QtSingleApplication */ /*! Creates a QtSingleCoreApplication object. The application identifier will be QCoreApplication::applicationFilePath(). \a argc and \a argv are passed on to the QCoreAppliation constructor. */ QtSingleCoreApplication::QtSingleCoreApplication(int& argc, char** argv) : QCoreApplication(argc, argv) { peer = new QtLocalPeer(this); connect(peer, SIGNAL(messageReceived(QString)), SIGNAL(messageReceived(QString))); } /*! Creates a QtSingleCoreApplication object with the application identifier \a appId. \a argc and \a argv are passed on to the QCoreAppliation constructor. */ QtSingleCoreApplication::QtSingleCoreApplication(const QString& appId, int& argc, char** argv) : QCoreApplication(argc, argv) { peer = new QtLocalPeer(this, appId); connect(peer, SIGNAL(messageReceived(QString)), SIGNAL(messageReceived(QString))); } /*! Returns true if another instance of this application is running; otherwise false. This function does not find instances of this application that are being run by a different user (on Windows: that are running in another session). \sa sendMessage() */ bool QtSingleCoreApplication::isRunning() { return peer->isClient(); } /*! Tries to send the text \a message to the currently running instance. The QtSingleCoreApplication object in the running instance will emit the messageReceived() signal when it receives the message. This function returns true if the message has been sent to, and processed by, the current instance. If there is no instance currently running, or if the running instance fails to process the message within \a timeout milliseconds, this function return false. \sa isRunning(), messageReceived() */ bool QtSingleCoreApplication::sendMessage(const QString& message, int timeout) { return peer->sendMessage(message, timeout); } /*! Returns the application identifier. Two processes with the same identifier will be regarded as instances of the same application. */ QString QtSingleCoreApplication::id() const { return peer->applicationId(); } /*! \fn void QtSingleCoreApplication::messageReceived(const QString& message) This signal is emitted when the current instance receives a \a message from another instance of this application. \sa sendMessage() */ ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������cb2bib-2.0.1/src/qtsingleapplication/src/PaxHeaders.5700/qtsingleapplication.cpp��������������������0000644�0000000�0000000�00000000074�14011522151�024510� x����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������30 atime=1613145424.838620334 30 ctime=1613145424.306620349 ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������cb2bib-2.0.1/src/qtsingleapplication/src/qtsingleapplication.cpp������������������������������������0000644�0001750�0000144�00000027001�14011522151�026102� 0����������������������������������������������������������������������������������������������������ustar�00constans������������������������users���������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/**************************************************************************** ** ** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). ** Contact: http://www.qt-project.org/legal ** ** This file is part of the Qt Solutions component. ** ** $QT_BEGIN_LICENSE:BSD$ ** You may use this file under the terms of the BSD license as follows: ** ** "Redistribution and use in source and binary forms, with or without ** modification, are permitted provided that the following conditions are ** met: ** * Redistributions of source code must retain the above copyright ** notice, this list of conditions and the following disclaimer. ** * Redistributions in binary form must reproduce the above copyright ** notice, this list of conditions and the following disclaimer in ** the documentation and/or other materials provided with the ** distribution. ** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names ** of its contributors may be used to endorse or promote products derived ** from this software without specific prior written permission. ** ** ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT ** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR ** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT ** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT ** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, ** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY ** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." ** ** $QT_END_LICENSE$ ** ****************************************************************************/ #include "qtsingleapplication.h" #include "qtlocalpeer.h" #include <QWidget> /*! \class QtSingleApplication qtsingleapplication.h \brief The QtSingleApplication class provides an API to detect and communicate with running instances of an application. This class allows you to create applications where only one instance should be running at a time. I.e., if the user tries to launch another instance, the already running instance will be activated instead. Another usecase is a client-server system, where the first started instance will assume the role of server, and the later instances will act as clients of that server. By default, the full path of the executable file is used to determine whether two processes are instances of the same application. You can also provide an explicit identifier string that will be compared instead. The application should create the QtSingleApplication object early in the startup phase, and call isRunning() to find out if another instance of this application is already running. If isRunning() returns false, it means that no other instance is running, and this instance has assumed the role as the running instance. In this case, the application should continue with the initialization of the application user interface before entering the event loop with exec(), as normal. The messageReceived() signal will be emitted when the running application receives messages from another instance of the same application. When a message is received it might be helpful to the user to raise the application so that it becomes visible. To facilitate this, QtSingleApplication provides the setActivationWindow() function and the activateWindow() slot. If isRunning() returns true, another instance is already running. It may be alerted to the fact that another instance has started by using the sendMessage() function. Also data such as startup parameters (e.g. the name of the file the user wanted this new instance to open) can be passed to the running instance with this function. Then, the application should terminate (or enter client mode). If isRunning() returns true, but sendMessage() fails, that is an indication that the running instance is frozen. Here's an example that shows how to convert an existing application to use QtSingleApplication. It is very simple and does not make use of all QtSingleApplication's functionality (see the examples for that). \code // Original int main(int argc, char **argv) { QApplication app(argc, argv); MyMainWidget mmw; mmw.show(); return app.exec(); } // Single instance int main(int argc, char **argv) { QtSingleApplication app(argc, argv); if (app.isRunning()) return !app.sendMessage(someDataString); MyMainWidget mmw; app.setActivationWindow(&mmw); mmw.show(); return app.exec(); } \endcode Once this QtSingleApplication instance is destroyed (normally when the process exits or crashes), when the user next attempts to run the application this instance will not, of course, be encountered. The next instance to call isRunning() or sendMessage() will assume the role as the new running instance. For console (non-GUI) applications, QtSingleCoreApplication may be used instead of this class, to avoid the dependency on the QtGui library. \sa QtSingleCoreApplication */ void QtSingleApplication::sysInit(const QString& appId) { actWin = 0; peer = new QtLocalPeer(this, appId); connect(peer, SIGNAL(messageReceived(QString)), SIGNAL(messageReceived(QString))); } /*! Creates a QtSingleApplication object. The application identifier will be QCoreApplication::applicationFilePath(). \a argc, \a argv, and \a GUIenabled are passed on to the QAppliation constructor. If you are creating a console application (i.e. setting \a GUIenabled to false), you may consider using QtSingleCoreApplication instead. */ QtSingleApplication::QtSingleApplication(int& argc, char** argv, bool GUIenabled) : QApplication(argc, argv, GUIenabled) { sysInit(); } /*! Creates a QtSingleApplication object with the application identifier \a appId. \a argc and \a argv are passed on to the QAppliation constructor. */ QtSingleApplication::QtSingleApplication(const QString& appId, int& argc, char** argv) : QApplication(argc, argv) { sysInit(appId); } #if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) /*! Creates a QtSingleApplication object. The application identifier will be QCoreApplication::applicationFilePath(). \a argc, \a argv, and \a type are passed on to the QAppliation constructor. */ QtSingleApplication::QtSingleApplication(int& argc, char** argv, Type type) : QApplication(argc, argv, type) { sysInit(); } # if defined(Q_WS_X11) /*! Special constructor for X11, ref. the documentation of QApplication's corresponding constructor. The application identifier will be QCoreApplication::applicationFilePath(). \a dpy, \a visual, and \a cmap are passed on to the QApplication constructor. */ QtSingleApplication::QtSingleApplication(Display* dpy, Qt::HANDLE visual, Qt::HANDLE cmap) : QApplication(dpy, visual, cmap) { sysInit(); } /*! Special constructor for X11, ref. the documentation of QApplication's corresponding constructor. The application identifier will be QCoreApplication::applicationFilePath(). \a dpy, \a argc, \a argv, \a visual, and \a cmap are passed on to the QApplication constructor. */ QtSingleApplication::QtSingleApplication(Display* dpy, int& argc, char** argv, Qt::HANDLE visual, Qt::HANDLE cmap) : QApplication(dpy, argc, argv, visual, cmap) { sysInit(); } /*! Special constructor for X11, ref. the documentation of QApplication's corresponding constructor. The application identifier will be \a appId. \a dpy, \a argc, \a argv, \a visual, and \a cmap are passed on to the QApplication constructor. */ QtSingleApplication::QtSingleApplication(Display* dpy, const QString& appId, int argc, char** argv, Qt::HANDLE visual, Qt::HANDLE cmap) : QApplication(dpy, argc, argv, visual, cmap) { sysInit(appId); } # endif // Q_WS_X11 #endif // QT_VERSION < 0x050000 /*! Returns true if another instance of this application is running; otherwise false. This function does not find instances of this application that are being run by a different user (on Windows: that are running in another session). \sa sendMessage() */ bool QtSingleApplication::isRunning() { return peer->isClient(); } /*! Tries to send the text \a message to the currently running instance. The QtSingleApplication object in the running instance will emit the messageReceived() signal when it receives the message. This function returns true if the message has been sent to, and processed by, the current instance. If there is no instance currently running, or if the running instance fails to process the message within \a timeout milliseconds, this function return false. \sa isRunning(), messageReceived() */ bool QtSingleApplication::sendMessage(const QString& message, int timeout) { return peer->sendMessage(message, timeout); } /*! Returns the application identifier. Two processes with the same identifier will be regarded as instances of the same application. */ QString QtSingleApplication::id() const { return peer->applicationId(); } /*! Sets the activation window of this application to \a aw. The activation window is the widget that will be activated by activateWindow(). This is typically the application's main window. If \a activateOnMessage is true (the default), the window will be activated automatically every time a message is received, just prior to the messageReceived() signal being emitted. \sa activateWindow(), messageReceived() */ void QtSingleApplication::setActivationWindow(QWidget* aw, bool activateOnMessage) { actWin = aw; if (activateOnMessage) connect(peer, SIGNAL(messageReceived(QString)), this, SLOT(activateWindow())); else disconnect(peer, SIGNAL(messageReceived(QString)), this, SLOT(activateWindow())); } /*! Returns the applications activation window if one has been set by calling setActivationWindow(), otherwise returns 0. \sa setActivationWindow() */ QWidget* QtSingleApplication::activationWindow() const { return actWin; } /*! De-minimizes, raises, and activates this application's activation window. This function does nothing if no activation window has been set. This is a convenience function to show the user that this application instance has been activated when he has tried to start another instance. This function should typically be called in response to the messageReceived() signal. By default, that will happen automatically, if an activation window has been set. \sa setActivationWindow(), messageReceived(), initialize() */ void QtSingleApplication::activateWindow() { if (actWin) { actWin->setWindowState(actWin->windowState() & ~Qt::WindowMinimized); actWin->raise(); actWin->activateWindow(); } } /*! \fn void QtSingleApplication::messageReceived(const QString& message) This signal is emitted when the current instance receives a \a message from another instance of this application. \sa sendMessage(), setActivationWindow(), activateWindow() */ /*! \fn void QtSingleApplication::initialize(bool dummy = true) \obsolete */ �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������cb2bib-2.0.1/src/qtsingleapplication/src/PaxHeaders.5700/qtlockedfile_unix.cpp����������������������0000644�0000000�0000000�00000000074�14011522151�024147� x����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������30 atime=1613145424.838620334 30 ctime=1613145424.306620349 ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������cb2bib-2.0.1/src/qtsingleapplication/src/qtlockedfile_unix.cpp��������������������������������������0000644�0001750�0000144�00000006600�14011522151�025543� 0����������������������������������������������������������������������������������������������������ustar�00constans������������������������users���������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/**************************************************************************** ** ** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). ** Contact: http://www.qt-project.org/legal ** ** This file is part of the Qt Solutions component. ** ** $QT_BEGIN_LICENSE:BSD$ ** You may use this file under the terms of the BSD license as follows: ** ** "Redistribution and use in source and binary forms, with or without ** modification, are permitted provided that the following conditions are ** met: ** * Redistributions of source code must retain the above copyright ** notice, this list of conditions and the following disclaimer. ** * Redistributions in binary form must reproduce the above copyright ** notice, this list of conditions and the following disclaimer in ** the documentation and/or other materials provided with the ** distribution. ** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names ** of its contributors may be used to endorse or promote products derived ** from this software without specific prior written permission. ** ** ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT ** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR ** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT ** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT ** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, ** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY ** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." ** ** $QT_END_LICENSE$ ** ****************************************************************************/ #include <string.h> #include <errno.h> #include <unistd.h> #include <fcntl.h> #include "qtlockedfile.h" bool QtLockedFile::lock(LockMode mode, bool block) { if (!isOpen()) { qWarning("QtLockedFile::lock(): file is not opened"); return false; } if (mode == NoLock) return unlock(); if (mode == m_lock_mode) return true; if (m_lock_mode != NoLock) unlock(); struct flock fl; fl.l_whence = SEEK_SET; fl.l_start = 0; fl.l_len = 0; fl.l_type = (mode == ReadLock) ? F_RDLCK : F_WRLCK; int cmd = block ? F_SETLKW : F_SETLK; int ret = fcntl(handle(), cmd, &fl); if (ret == -1) { if (errno != EINTR && errno != EAGAIN) qWarning("QtLockedFile::lock(): fcntl: %s", strerror(errno)); return false; } m_lock_mode = mode; return true; } bool QtLockedFile::unlock() { if (!isOpen()) { qWarning("QtLockedFile::unlock(): file is not opened"); return false; } if (!isLocked()) return true; struct flock fl; fl.l_whence = SEEK_SET; fl.l_start = 0; fl.l_len = 0; fl.l_type = F_UNLCK; int ret = fcntl(handle(), F_SETLKW, &fl); if (ret == -1) { qWarning("QtLockedFile::lock(): fcntl: %s", strerror(errno)); return false; } m_lock_mode = NoLock; return true; } QtLockedFile::~QtLockedFile() { if (isOpen()) unlock(); } ��������������������������������������������������������������������������������������������������������������������������������cb2bib-2.0.1/src/PaxHeaders.5700/c2bSettings.cpp����������������������������������������������������0000644�0000000�0000000�00000000132�14011522520�015757� x����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������30 mtime=1613145424.450620345 30 atime=1613145424.830620334 30 ctime=1613145424.450620345 ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������cb2bib-2.0.1/src/c2bSettings.cpp��������������������������������������������������������������������0000644�0001750�0000144�00000027460�14011522520�017367� 0����������������������������������������������������������������������������������������������������ustar�00constans������������������������users���������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*************************************************************************** * Copyright (C) 2004-2021 by Pere Constans * constans@molspaces.com * cb2Bib version 2.0.1. Licensed under the GNU GPL version 3. * See the LICENSE file that comes with this distribution. ***************************************************************************/ #include "c2bSettings.h" #include "c2bUtils.h" #include <QApplication> #include <QClipboard> #include <QMessageBox> #include <QProgressBar> #include <QShortcut> #include <QTimer> /** Global settings for cb2Bib */ c2bSettings::c2bSettings(const QString& organization, const QString& application, QObject* parento) : settings(organization, application, parento), _progress_bar(0) {} c2bSettings::c2bSettings(const QString& fn, QObject* parento) : settings(fn, parento), _progress_bar(0) {} c2bSettings::~c2bSettings() { delete _progress_bar; } c2bSettings* c2bSettings::initSettings() { c2bSettings* s; if (c2bSettings::isConfiguredMode()) s = new c2bSettings(c2bSettings::configuredFilename()); else s = new c2bSettings(qApp->organizationName(), qApp->applicationName()); s->init(); return s; } void c2bSettings::init() { settings::init(); _progress_bar = 0; if (cl_console_mode) return; setDefaults(); if (cl_import) // Process cl_import_filename and update cl_cb2bib_import_mode processReferenceFile(); if (cl_cb2bib_mode && !cl_cb2bib_import_mode) { setValue("cb2Bib/isRunning", true); sync(); connect(qApp, SIGNAL(lastWindowClosed()), this, SLOT(guiExits())); } } void c2bSettings::notify() { update(); emit newSettings(); } void c2bSettings::update() { // Values for very general GUI settings c2bMonoFont = value("cb2Bib/MonoFont").value<QFont>(); colors.loadColors(this); } void c2bSettings::setDefaults() { QHash<QString, QVariant> defaults; defaults["cb2Bib/MonoFont"] = QFont("Courier"); const QStringList keys(defaults.keys()); for (int i = 0; i < keys.count(); ++i) setValue(keys.at(i), value(keys.at(i), defaults.value(keys.at(i)))); // Shortcuts _default_keysequences.clear(); _default_keysequences["Shortcuts/cb2Bib/Button About and Bookmarks"] = QKeySequence(Qt::CTRL + Qt::Key_Tab); _default_keysequences["Shortcuts/cb2Bib/Button Configure"] = QKeySequence(); _default_keysequences["Shortcuts/cb2Bib/Button Network Query"] = QKeySequence(Qt::ALT + Qt::Key_N); _default_keysequences["Shortcuts/cb2Bib/Button Start PDFImport"] = QKeySequence(); _default_keysequences["Shortcuts/cb2Bib/Button Toggle Connection"] = QKeySequence(); _default_keysequences["Shortcuts/cb2Bib/Button View BibTeX"] = QKeySequence(Qt::ALT + Qt::Key_V); _default_keysequences["Shortcuts/cb2Bib/Check Repeated"] = QKeySequence(Qt::ALT + Qt::Key_X); _default_keysequences["Shortcuts/cb2Bib/Clear All Fields"] = QKeySequence(); _default_keysequences["Shortcuts/cb2Bib/Delete Temporary BibTeX File"] = QKeySequence(Qt::ALT + Qt::Key_D); _default_keysequences["Shortcuts/cb2Bib/Edit Bookmarks"] = QKeySequence(Qt::ALT + Qt::Key_B); _default_keysequences["Shortcuts/cb2Bib/Edit Journal Abbreviations"] = QKeySequence(Qt::ALT + Qt::Key_J); _default_keysequences["Shortcuts/cb2Bib/Edit Regular Expressions"] = QKeySequence(Qt::ALT + Qt::Key_E); _default_keysequences["Shortcuts/cb2Bib/Guess Bibliographic Fields"] = QKeySequence(Qt::ALT + Qt::Key_G); _default_keysequences["Shortcuts/cb2Bib/Insert Regular Expression"] = QKeySequence(Qt::ALT + Qt::Key_I); _default_keysequences["Shortcuts/cb2Bib/Open Document"] = QKeySequence(Qt::ALT + Qt::Key_O); _default_keysequences["Shortcuts/cb2Bib/Postprocess BibTeX"] = QKeySequence(Qt::ALT + Qt::Key_P); _default_keysequences["Shortcuts/cb2Bib/Preparse Clipboard"] = QKeySequence(Qt::ALT + Qt::Key_C); _default_keysequences["Shortcuts/cb2Bib/Restart Recognition"] = QKeySequence(Qt::ALT + Qt::Key_R); _default_keysequences["Shortcuts/cb2Bib/Select BibTeX File"] = QKeySequence(Qt::ALT + Qt::Key_S); _default_keysequences["Shortcuts/cb2Bib/Select Document File"] = QKeySequence(Qt::ALT + Qt::Key_F); _default_keysequences["Shortcuts/cb2Bib/Annote Editor"] = QKeySequence(Qt::ALT + Qt::Key_A); _default_keysequences["Shortcuts/cb2Bib/Toggle Reference Tabs"] = QKeySequence(Qt::Key_F4); _default_keysequences["Shortcuts/cb2Bib/View Tagged Clipboard Data"] = QKeySequence(); _default_keysequences["Shortcuts/cb2Bib/Write Metadata to Document"] = QKeySequence(Qt::ALT + Qt::Key_W); _default_keysequences["Shortcuts/Editor/Browse Reference by DOI"] = QKeySequence(); _default_keysequences["Shortcuts/Editor/Cite Selected Entries"] = QKeySequence(Qt::ALT + Qt::Key_C); _default_keysequences["Shortcuts/Editor/Clear Entry Selection"] = QKeySequence(Qt::Key_Delete); _default_keysequences["Shortcuts/Editor/Export Entries"] = QKeySequence(); _default_keysequences["Shortcuts/Editor/Local Search for Selected Text"] = QKeySequence(); _default_keysequences["Shortcuts/Editor/Open Document File"] = QKeySequence(); _default_keysequences["Shortcuts/Editor/Open Document URL"] = QKeySequence(); _default_keysequences["Shortcuts/Editor/Paste Current BibTeX"] = QKeySequence(Qt::SHIFT + Qt::Key_Insert); _default_keysequences["Shortcuts/Editor/Restart Network Query"] = QKeySequence(Qt::ALT + Qt::Key_N); _default_keysequences["Shortcuts/Editor/Restart Recognition"] = QKeySequence(Qt::ALT + Qt::Key_R); _default_keysequences["Shortcuts/Editor/Save and Postprocess"] = QKeySequence(Qt::ALT + Qt::Key_P); _default_keysequences["Shortcuts/Editor/Selection to LaTeX"] = QKeySequence(); _default_keysequences["Shortcuts/Editor/Selection to Unicode"] = QKeySequence(); _default_keysequences["Shortcuts/Editor/Set Journals to Abbreviated Name"] = QKeySequence(); _default_keysequences["Shortcuts/Editor/Set Journals to Full Name"] = QKeySequence(); _default_keysequences["Shortcuts/Editor/Set LyX Pipe"] = QKeySequence(Qt::ALT + Qt::Key_L); _default_keysequences["Shortcuts/Editor/Toggle Editing and Browsing"] = QKeySequence(Qt::CTRL + Qt::Key_Tab); _default_keysequences["Shortcuts/Editor/Toggle Word Wrapping"] = QKeySequence(); _default_keysequences["Shortcuts/Editor/Update Documents Metadata"] = QKeySequence(); _default_keysequences["Shortcuts/Editor/View Note in External Browser"] = QKeySequence(); _default_keysequences["Shortcuts/Editor/Web Search Settings"] = QKeySequence(); _default_keysequences["Shortcuts/Editor/Web Search by Author"] = QKeySequence(); _default_keysequences["Shortcuts/Editor/Web Search by Title"] = QKeySequence(); _default_keysequences["Shortcuts/Editor/Web Search for Selected Text"] = QKeySequence(); const QStringList sc(_default_keysequences.keys()); for (int i = 0; i < sc.count(); ++i) setValue(sc.at(i), value(sc.at(i), _default_keysequences.value(sc.at(i)))); update(); } void c2bSettings::setKeysequences(const QHash<QString, QKeySequence>& keysequences) { if (keysequences.size() == 0) return; QHash<QString, QKeySequence>::const_iterator it(keysequences.constBegin()); while (it != keysequences.constEnd()) { setValue(it.key(), it.value()); ++it; } // Set keysequences to created objects const QString sctag("Shortcuts/"); foreach (QWidget* w, QApplication::topLevelWidgets()) { const QList<QAction*> alist(w->findChildren<QAction*>()); for (int i = 0; i < alist.count(); ++i) { const QString fullname(alist.at(i)->data().toString()); if (fullname.startsWith(sctag)) alist.at(i)->setShortcut(keysequence(fullname)); } const QList<QShortcut*> sclist(w->findChildren<QShortcut*>()); for (int i = 0; i < sclist.count(); ++i) { const QString fullname(sclist.at(i)->objectName()); if (fullname.startsWith(sctag)) sclist.at(i)->setKey(keysequence(fullname)); } } } void c2bSettings::setKeysequence(const QString& path, QAction* action) { if (!action) return; const QString fullname(path + action->text()); if (_default_keysequences.contains(fullname)) { action->setShortcut(keysequence(fullname)); action->setData(fullname); } else c2bUtils::warn(tr("Action '%1' is not registered in default keysequence list").arg(fullname)); } void c2bSettings::setKeysequence(const QString& fullname, QShortcut* shortcut) { if (!shortcut) return; if (_default_keysequences.contains(fullname)) { shortcut->setObjectName(fullname); shortcut->setKey(keysequence(fullname)); } else c2bUtils::warn(tr("Shortcut '%1' is not registered in default keysequence list").arg(fullname)); } #ifdef Q_OS_WIN #include <QFileDialog> QString c2bSettings::decodeFilename(const QString& fn) const { // This function is meant for fn given by the command shell and that will end up being visible const QString dfn(settings::decodeFilename(fn)); QFileDialog fd(0, QString(), dfn); const QStringList fns(fd.selectedFiles()); if (fns.count() == 0) return dfn; const QString wdfn(fns.first()); if (QFileInfo(wdfn).exists()) return QDir::toNativeSeparators(wdfn); else return dfn; } #endif /*************************************************************************** * Downloaded reference extraction ***************************************************************************/ void c2bSettings::processReferenceFile() { // The "Download reference to reference manager" functionality to cb2Bib is implemented as follows: // - Put downloaded reference into the clipboard // - If no cb2Bib instance is running, launch cb2Bib GUI, otherwise exit // This is simple, enough, and consistent with a 'clipboard to BibTeX' program. // The 'single instance' implementation is naive, but it is sufficient for cb2Bib, and does not prevent // from having multiple cb2Bib instances in its usual deployment, if so desired. // Aware of QClipboard X11 note: "You should not store or retrieve the clipboard contents in response // to timer or non-user-input events". Functions processReferenceFile() and processprocessReferenceFileEvent() // do not follow it. It seems to work smooth, for all platforms, and, overall, it is a feasible solution // in this particular case. QFile file(cl_import_filename); if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) { cl_cb2bib_import_mode = true; QMessageBox::warning(0, tr("Warning - cb2Bib"), tr("Unable to open the reference file %1 for reading.\nError: '%2'.") .arg(cl_import_filename, file.errorString()), QMessageBox::Ok); QTimer::singleShot(500, qApp, SLOT(quit())); } else { if (value("cb2Bib/isRunning", false).toBool()) { cl_cb2bib_import_mode = true; if (!_progress_bar) _progress_bar = new QProgressBar; _progress_bar->setRange(0, 100); _progress_bar->setWindowTitle(QObject::tr("Importing...")); _progress_bar->show(); _progress_bar->setValue(50); } QTimer::singleShot(500, this, SLOT(processReferenceFileEvent())); } } void c2bSettings::processReferenceFileEvent() { const QString reference(c2bUtils::fileToString(cl_import_filename).trimmed()); QClipboard* cb = qApp->clipboard(); cb->setText(reference, QClipboard::Clipboard); if (cl_cb2bib_import_mode) { if (_progress_bar) _progress_bar->setValue(100); QTimer::singleShot(500, qApp, SLOT(quit())); } } void c2bSettings::guiExits() { setValue("cb2Bib/isRunning", false); sync(); } ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������cb2bib-2.0.1/src/PaxHeaders.5700/c2bUpdateMetadata.h������������������������������������������������0000644�0000000�0000000�00000000132�14011522520�016507� x����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������30 mtime=1613145424.566620341 30 atime=1613145424.830620334 30 ctime=1613145424.566620341 ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������cb2bib-2.0.1/src/c2bUpdateMetadata.h����������������������������������������������������������������0000644�0001750�0000144�00000002110�14011522520�020100� 0����������������������������������������������������������������������������������������������������ustar�00constans������������������������users���������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*************************************************************************** * Copyright (C) 2004-2021 by Pere Constans * constans@molspaces.com * cb2Bib version 2.0.1. Licensed under the GNU GPL version 3. * See the LICENSE file that comes with this distribution. ***************************************************************************/ #ifndef C2BUPDATEMETADATA_H #define C2BUPDATEMETADATA_H #include "ui_c2bLogWidget.h" #include <QDialog> class bibReference; class c2bBibParser; class c2bUpdateMetadata : public QDialog { Q_OBJECT public: explicit c2bUpdateMetadata(QWidget* parentw = 0); ~c2bUpdateMetadata(); void update(const QString& fn, const QString& bibtex); private slots: void aborted(); void help(); void update(); private: QPushButton* _buttonAbort; QString _bibtex; QString _fn; Ui::c2bLogWidget ui; bool _aborted; bool needsUpdating(const bibReference& ref, const bibReference& mref); c2bBibParser* _bpP; void writeDifferences(const bibReference& ref, const bibReference& mref); }; #endif ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������cb2bib-2.0.1/src/PaxHeaders.5700/src.pro������������������������������������������������������������0000644�0000000�0000000�00000000074�14011522151�014402� x����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������30 atime=1613145424.830620334 30 ctime=1613145424.306620349 ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������cb2bib-2.0.1/src/src.pro����������������������������������������������������������������������������0000644�0001750�0000144�00000015134�14011522151�016000� 0����������������������������������������������������������������������������������������������������ustar�00constans������������������������users���������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������FORMS += c2bCiterWidget.ui \ c2bConfigure.ui \ c2bConfigureFR.ui \ c2bEditor.ui \ c2bExportDialog.ui \ c2bLogWidget.ui \ c2bPdfImport.ui \ c2bRLWebSearchSettings.ui \ c2bReferenceList.ui \ c2bSaveRegExp.ui \ c2bSearchInFiles.ui \ c2bSearchInFilesPattern.ui \ c2bSearchInFilesPatternEdit.ui \ c2bShortcutWidget.ui \ cb2Bib.ui \ findDialog.ui \ proxyDialog.ui RESOURCES += cb2bib.qrc HEADERS += bookmarkPlugin.h \ c2b.h \ c2bBibHighlighter.h \ c2bBibMenu.h \ c2bBibParser.h \ c2bBibPreparserLog.h \ c2bCitePatternLineEedit.h \ c2bCiter.h \ c2bCiterExcerptView.h \ c2bCiterHistory.h \ c2bCiterModel.h \ c2bCiterView.h \ c2bCiterWidget.h \ c2bClipEdit.h \ c2bClipboard.h \ c2bCollectionIndex.h \ c2bColors.h \ c2bComboBox.h \ c2bConfigure.h \ c2bConfigureFR.h \ c2bConsole.h \ c2bCoreCiter.h \ c2bEditor.h \ c2bExport.h \ c2bExportDialog.h \ c2bFileDialog.h \ c2bFileSystemWatcher.h \ c2bHighlighter.h \ c2bIdPatternLineEdit.h \ c2bLineEdit.h \ c2bNetworkQuery.h \ c2bNetworkQueryInfo.h \ c2bPdfImport.h \ c2bPostprocess.h \ c2bREHighlighter.h \ c2bRLWebSearchSettings.h \ c2bReferenceList.h \ c2bSaveREHighlighter.h \ c2bSaveRegExp.h \ c2bSearchInFiles.h \ c2bSearchInFilesPattern.h \ c2bSettings.h \ c2bShortcutPushButton.h \ c2bShortcutWidget.h \ c2bTests.h \ c2bTextBrowser.h \ c2bTextEdit.h \ c2bUpdateMetadata.h \ c2bUtils.h \ cb2Bib.h \ dialog.h \ findDialog.h SOURCES += bookmarkPlugin.cpp \ c2b.cpp \ c2bBibHighlighter.cpp \ c2bBibMenu.cpp \ c2bBibParser.cpp \ c2bBibPreparserLog.cpp \ c2bCitePatternLineEedit.cpp \ c2bCiterExcerptView.cpp \ c2bCiterHistory.cpp \ c2bCiterModel.cpp \ c2bCiterView.cpp \ c2bCiterWidget.cpp \ c2bClipEdit.cpp \ c2bClipboard.cpp \ c2bCollectionIndex.cpp \ c2bColors.cpp \ c2bComboBox.cpp \ c2bConfigure.cpp \ c2bConfigureFR.cpp \ c2bConsole.cpp \ c2bCoreCiter.cpp \ c2bEditor.cpp \ c2bExport.cpp \ c2bExportDialog.cpp \ c2bFileDialog.cpp \ c2bFileSystemWatcher.cpp \ c2bHighlighter.cpp \ c2bIdPatternLineEdit.cpp \ c2bLineEdit.cpp \ c2bNetworkQuery.cpp \ c2bNetworkQueryInfo.cpp \ c2bPdfImport.cpp \ c2bPostprocess.cpp \ c2bREHighlighter.cpp \ c2bRLWebSearchSettings.cpp \ c2bReferenceList.cpp \ c2bSaveREHighlighter.cpp \ c2bSaveRegExp.cpp \ c2bSearchInFiles.cpp \ c2bSearchInFilesPattern.cpp \ c2bSettings.cpp \ c2bShortcutPushButton.cpp \ c2bShortcutWidget.cpp \ c2bTests.cpp \ c2bTextBrowser.cpp \ c2bTextEdit.cpp \ c2bUpdateMetadata.cpp \ c2bUtils.cpp \ cb2Bib.cpp \ findDialog.cpp \ main.cpp HEADERS += $$files(qtsingleapplication/src/*.h) SOURCES += $$files(qtsingleapplication/src/*.cpp) TEMPLATE = app QT += widgets network CONFIG += c++11 LIBS += -lc2b QMAKE_LIBDIR += . INCLUDEPATH += c2b . qtHaveModule(webkitwidgets){ CONFIG += use_webkit } else { qtHaveModule(webenginewidgets){ CONFIG += use_webengine }} CONFIG(use_webkit) { message(cb2Bib will be linked against QtWebKit library) HEADERS += c2bAnnote.h qweb/kit/c2bWebBrowser.h SOURCES += c2bAnnote.cpp qweb/kit/c2bWebBrowser.cpp INCLUDEPATH += ./qweb/kit DEFINES += C2B_USE_QWEB C2B_USE_QWEBKIT QT += webkitwidgets } CONFIG(use_webengine) { message(cb2Bib will be linked against QtWebEngine library) HEADERS += c2bAnnote.h qweb/engine/c2bWebBrowser.h SOURCES += c2bAnnote.cpp qweb/engine/c2bWebBrowser.cpp INCLUDEPATH += ./qweb/engine DEFINES += C2B_USE_QWEB C2B_USE_QWEBENGINE QT += webenginewidgets } !use_lzsse : !use_lz4 : !use_lzo : !use_qt_zlib { CONFIG += use_lz4 } use_lzsse { message(cb2Bib will be linked against LZSSE library) DEFINES += C2B_USE_LZSSE } use_lz4 { message(cb2Bib will be linked against LZ4 library) LIBS += -llz4 DEFINES += C2B_USE_LZ4 } use_lzo { message(cb2Bib will be linked against LZO library) LIBS += -llzo2 DEFINES += C2B_USE_LZO } use_qt_zlib { message(cb2Bib will be linked against Qt ZLIB library) DEFINES += C2B_USE_ZLIB } use_avx2 { QMAKE_CXXFLAGS += -mavx2 } TARGET = cb2bib DESTDIR = ../bin DEPENDPATH += . POST_TARGETDEPS += libc2b.a QMAKE_CXXFLAGS_DEBUG += -DC2B_DEBUG enable_cbpoll { unix { message(Building with clipboardPoll) QT += x11extras HEADERS += clipboardPoll.h SOURCES += clipboardPoll.cpp DEFINES += C2B_USE_CBPOLL LIBS += -lX11 }} unix { INSTALLS += target script cb2bibdata cb2bibdoc icons desktop target.path = /usr/bin script.files += ../c2bscripts/c2bimport ../c2bscripts/c2bciter script.path = /usr/bin desktop.files += ../c2bscripts/cb2bib.desktop ../c2bscripts/c2bciter.desktop ../c2bscripts/c2bimport.desktop desktop.path = /usr/share/applications icons.files += ../src/icons/cb2bib.png icons.path = /usr/share/pixmaps cb2bibdata.files += ../AUTHORS ../COPYRIGHT ../LICENSE ../CHANGELOG ../data ../c2btools ../testPDFImport cb2bibdata.path = /usr/share/cb2bib cb2bibdoc.files += ../doc/cb2bib_user_manual.pdf cb2bibdoc.path = /usr/share/cb2bib/doc } win32 { RC_FILE = ../cb2bib.rc } macx { ICON = ../src/icons/cb2bib.icns INSTALLS += target script cb2bibdata target.path = /Applications script.files += ../c2bscripts/c2bimport ../c2bscripts/c2bciter script.path = /Applications cb2bibdata.files += ../AUTHORS ../COPYRIGHT ../LICENSE ../CHANGELOG ../data ../doc ../c2btools ../testPDFImport cb2bibdata.path = Contents/Resources QMAKE_BUNDLE_DATA += script cb2bibdata # Set this directory if third party tools, like pdftotext are packaged # INSTALLS += externtools # externtools.files += # externtools.path = c2bExternTools # Set Library data # QMAKE_BUNDLE_DATA += externtools } ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������cb2bib-2.0.1/src/PaxHeaders.5700/main.cpp�����������������������������������������������������������0000644�0000000�0000000�00000000132�14011522520�014514� x����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������30 mtime=1613145424.474620344 30 atime=1613145424.830620334 30 ctime=1613145424.474620344 ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������cb2bib-2.0.1/src/main.cpp���������������������������������������������������������������������������0000644�0001750�0000144�00000006771�14011522520�016126� 0����������������������������������������������������������������������������������������������������ustar�00constans������������������������users���������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*************************************************************************** * Copyright (C) 2004-2021 by Pere Constans * constans@molspaces.com * cb2Bib version 2.0.1. Licensed under the GNU GPL version 3. * See the LICENSE file that comes with this distribution. ***************************************************************************/ #include "qtsingleapplication/src/qtsingleapplication.h" #include "qtsingleapplication/src/qtsinglecoreapplication.h" #include "c2bConfigure.h" #include "c2bConsole.h" #include "c2bSettings.h" #include "cb2Bib.h" #ifdef C2B_USE_QWEB #include "c2bAnnote.h" #endif int main(int argc, char* argv[]) { Q_INIT_RESOURCE(cb2bib); Q_INIT_RESOURCE(c2blib); c2bSettings* c2b_settings; // Delete before app, this avoids QVariant::save: unable to save type 67/64 int code(0); if (c2bSettings::isConsoleMode(argc, argv)) { // Cannot use QCoreApplication, QTextDocument is required by c2bUtils::fromHtmlString // Needs also workaround c2bSettings::decodeFilename() QApplication app(argc, argv); app.setOrganizationName(C2B_ORGANIZATION); app.setApplicationName(C2B_APPLICATION); c2b_settings = c2bSettings::initSettings(); if (c2b_settings->loaded()) { c2bConsole c2B; c2B.load(); code = app.exec(); } delete c2b_settings; } else if (c2bSettings::isSingleApplicationMode(argc, argv)) { // Avoid connecting to the graphic server. On Windows it would create a void window. { QtSingleCoreApplication* capp = new QtSingleCoreApplication(argc, argv); const bool is_running = capp->sendMessage(QString()); delete capp; if (is_running) return code; } QtSingleApplication app(argc, argv); if (app.isRunning()) // Activate local peer return code; app.setQuitOnLastWindowClosed(false); app.setOrganizationName(C2B_ORGANIZATION); app.setApplicationName(C2B_APPLICATION); app.setWindowIcon(QIcon(":/icons/icons/cb2bib.ico")); c2b_settings = c2bSettings::initSettings(); if (c2b_settings->loaded()) { cb2Bib c2B; c2B.show(); QObject::connect(&app, SIGNAL(messageReceived(QString)), &c2B, SLOT(show())); code = app.exec(); } delete c2b_settings; } else { QApplication app(argc, argv); app.setOrganizationName(C2B_ORGANIZATION); app.setApplicationName(C2B_APPLICATION); app.setWindowIcon(QIcon(":/icons/icons/cb2bib.ico")); c2b_settings = c2bSettings::initSettings(); if (c2b_settings->loaded()) { if (c2b_settings->cl_cb2bib_import_mode) code = app.exec(); else if (c2b_settings->cl_configure) { c2bConfigure c2B; c2B.show(); code = app.exec(); } else if (c2b_settings->cl_view_annote) { #ifdef C2B_USE_QWEB c2bAnnote c2B; if (c2B.show()) code = app.exec(); #else fprintf(stdout, "cb2Bib Annote is disabled. Recompile using QtWebKit or QtWebEngine library.\n"); #endif } else { cb2Bib c2B; c2B.show(); code = app.exec(); } } delete c2b_settings; } return code; } �������cb2bib-2.0.1/src/PaxHeaders.5700/c2bBibMenu.cpp�����������������������������������������������������0000644�0000000�0000000�00000000132�14011522520�015500� x����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������30 mtime=1613145424.378620347 30 atime=1613145424.818620334 30 ctime=1613145424.378620347 ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������cb2bib-2.0.1/src/c2bBibMenu.cpp���������������������������������������������������������������������0000644�0001750�0000144�00000013163�14011522520�017103� 0����������������������������������������������������������������������������������������������������ustar�00constans������������������������users���������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*************************************************************************** * Copyright (C) 2004-2021 by Pere Constans * constans@molspaces.com * cb2Bib version 2.0.1. Licensed under the GNU GPL version 3. * See the LICENSE file that comes with this distribution. ***************************************************************************/ #include "c2bBibMenu.h" #include <cb2bib_parameters.h> #include <QKeyEvent> c2bBibMenu::c2bBibMenu(QWidget* parentw) : QMenu(parentw), _keyboard_selection(0), _was_plus_pressed(false) { _title_action = addAction("Title"); _title_action->setData("title"); _author_action = addAction("Author"); _author_action->setData("author"); _add_author_action = addAction("Add authors"); _add_author_action->setIcon(QIcon(C2B_ICON_DIR + "add.png")); _journal_action = addAction("Journal"); _journal_action->setData("journal"); addSeparator(); _pages_action = addAction("Pages"); _pages_action->setData("pages"); _volume_action = addAction("Volume"); _volume_action->setData("volume"); _number_action = addAction("Number"); _number_action->setData("number"); _year_action = addAction("Year"); _year_action->setData("year"); addSeparator(); _abstract_action = addAction("Abstract"); _abstract_action->setData("abstract"); _keywords_action = addAction("Keywords"); _keywords_action->setData("keywords"); _file_action = addAction("File"); _file_action->setData("file"); QMenu* submenu = new QMenu("Other fields...", this); _address_action = submenu->addAction("Address"); _address_action->setData("address"); _annote_action = submenu->addAction("Annote"); _annote_action->setData("annote"); _booktitle_action = submenu->addAction("Booktitle"); _booktitle_action->setData("booktitle"); _chapter_action = submenu->addAction("Chapter"); _chapter_action->setData("chapter"); _doi_action = submenu->addAction("DOI"); _doi_action->setData("doi"); _edition_action = submenu->addAction("Edition"); _edition_action->setData("edition"); _editor_action = submenu->addAction("Editor"); _editor_action->setData("editor"); _add_editor_action = submenu->addAction("Add editors"); _add_editor_action->setIcon(QIcon(C2B_ICON_DIR + "add.png")); _eprint_action = submenu->addAction("Eprint"); _eprint_action->setData("eprint"); _institution_action = submenu->addAction("Institution"); _institution_action->setData("institution"); _isbn_action = submenu->addAction("ISBN"); _isbn_action->setData("isbn"); _issn_action = submenu->addAction("ISSN"); _issn_action->setData("issn"); _month_action = submenu->addAction("Month"); _month_action->setData("month"); _note_action = submenu->addAction("Note"); _note_action->setData("note"); _organization_action = submenu->addAction("Organization"); _organization_action->setData("organization"); _publisher_action = submenu->addAction("Publisher"); _publisher_action->setData("publisher"); _school_action = submenu->addAction("School"); _school_action->setData("school"); _series_action = submenu->addAction("Series"); _series_action->setData("series"); _url_action = submenu->addAction("URL"); _url_action->setData("url"); addSeparator(); addMenu(submenu); addSeparator(); _any_pattern_action = addAction(QString()); } QAction* c2bBibMenu::exec(const QPoint& p) { _keyboard_selection = 0; _was_plus_pressed = false; QAction* a = QMenu::exec(p); if (a) return a; else return _keyboard_selection; } void c2bBibMenu::keyPressEvent(QKeyEvent* qevent) { switch (qevent->key()) { case Qt::Key_A: if (_was_plus_pressed) _keyboard_selection = _add_author_action; else _keyboard_selection = _author_action; break; case Qt::Key_B: _keyboard_selection = _booktitle_action; break; case Qt::Key_C: _keyboard_selection = _chapter_action; break; case Qt::Key_D: _keyboard_selection = _doi_action; break; case Qt::Key_E: if (_was_plus_pressed) _keyboard_selection = _add_editor_action; else _keyboard_selection = _editor_action; break; case Qt::Key_F: _keyboard_selection = _file_action; break; case Qt::Key_I: _keyboard_selection = _isbn_action; break; case Qt::Key_J: _keyboard_selection = _journal_action; break; case Qt::Key_K: _keyboard_selection = _keywords_action; break; case Qt::Key_M: _keyboard_selection = _month_action; break; case Qt::Key_N: _keyboard_selection = _number_action; break; case Qt::Key_O: _keyboard_selection = _organization_action; break; case Qt::Key_P: _keyboard_selection = _pages_action; break; case Qt::Key_S: _keyboard_selection = _series_action; break; case Qt::Key_T: _keyboard_selection = _title_action; break; case Qt::Key_U: _keyboard_selection = _url_action; break; case Qt::Key_V: _keyboard_selection = _volume_action; break; case Qt::Key_Y: _keyboard_selection = _year_action; break; case Qt::Key_Plus: _was_plus_pressed = true; break; default: _keyboard_selection = 0; _was_plus_pressed = false; } if (_keyboard_selection) { qevent->accept(); hide(); _keyboard_selection->trigger(); } else QMenu::keyPressEvent(qevent); } �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������cb2bib-2.0.1/src/PaxHeaders.5700/c2bLineEdit.cpp����������������������������������������������������0000644�0000000�0000000�00000000132�14011522520�015654� x����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������30 mtime=1613145424.426620345 30 atime=1613145424.826620334 30 ctime=1613145424.430620345 ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������cb2bib-2.0.1/src/c2bLineEdit.cpp��������������������������������������������������������������������0000644�0001750�0000144�00000002044�14011522520�017253� 0����������������������������������������������������������������������������������������������������ustar�00constans������������������������users���������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*************************************************************************** * Copyright (C) 2004-2021 by Pere Constans * constans@molspaces.com * cb2Bib version 2.0.1. Licensed under the GNU GPL version 3. * See the LICENSE file that comes with this distribution. ***************************************************************************/ #include "c2bLineEdit.h" #include <QAction> #include <QContextMenuEvent> #include <QMenu> c2bLineEdit::c2bLineEdit(QWidget* parentw) : QLineEdit(parentw) {} c2bLineEdit::~c2bLineEdit() {} void c2bLineEdit::contextMenuEvent(QContextMenuEvent* e) { QMenu* menu = QLineEdit::createStandardContextMenu(); QList<QAction*> acts = menu->actions(); QAction* act; act = new QAction("Clear", menu); act->setEnabled(!text().isEmpty()); connect(act, SIGNAL(triggered()), this, SLOT(clear())); menu->insertAction(acts.at(7), act); acts = actions(); for (int i = 0; i < acts.count(); ++i) menu->addAction(acts.at(i)); menu->exec(e->globalPos()); delete menu; } ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������cb2bib-2.0.1/src/PaxHeaders.5700/dialog.h�����������������������������������������������������������0000644�0000000�0000000�00000000132�14011522520�014474� x����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������30 mtime=1613145424.574620341 30 atime=1613145424.830620334 30 ctime=1613145424.574620341 ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������cb2bib-2.0.1/src/dialog.h���������������������������������������������������������������������������0000644�0001750�0000144�00000001125�14011522520�016072� 0����������������������������������������������������������������������������������������������������ustar�00constans������������������������users���������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*************************************************************************** * Copyright (C) 2004-2021 by Pere Constans * constans@molspaces.com * cb2Bib version 2.0.1. Licensed under the GNU GPL version 3. * See the LICENSE file that comes with this distribution. ***************************************************************************/ #ifndef DIALOG_H #define DIALOG_H #include <Qt> /** Remove What's This button from c2b dialogues */ namespace dialog { static const Qt::WindowFlags flags(Qt::WindowTitleHint | Qt::WindowSystemMenuHint); } // namespace dialog #endif �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������cb2bib-2.0.1/src/PaxHeaders.5700/c2bFileDialog.cpp��������������������������������������������������0000644�0000000�0000000�00000000132�14011522520�016156� x����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������30 mtime=1613145424.418620346 30 atime=1613145424.826620334 30 ctime=1613145424.422620346 ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������cb2bib-2.0.1/src/c2bFileDialog.cpp������������������������������������������������������������������0000644�0001750�0000144�00000015571�14011522520�017566� 0����������������������������������������������������������������������������������������������������ustar�00constans������������������������users���������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*************************************************************************** * Copyright (C) 2004-2021 by Pere Constans * constans@molspaces.com * cb2Bib version 2.0.1. Licensed under the GNU GPL version 3. * See the LICENSE file that comes with this distribution. ***************************************************************************/ #include "c2bFileDialog.h" #include "c2bSettings.h" #include <QLineEdit> #include <QTimer> c2bFileDialog::c2bFileDialog(QWidget* parentw, const QString& caption, const QString& fpath, const QString& ffilter) : QFileDialog(parentw, caption, fpath, ffilter) { setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint); setWindowFlags(windowFlags() | Qt::WindowMinMaxButtonsHint); setOptions(QFileDialog::DontUseNativeDialog); setModal(true); settings = c2bSettingsP; } c2bFileDialog::~c2bFileDialog() {} QString c2bFileDialog::getFilename(QWidget* parentw, const QString& caption, const QString& path, const QString& filter) { c2bFileDialog* dlg(new c2bFileDialog(parentw, _caption(tr("Select a filename"), caption), _path(path), filter)); dlg->setFileMode(AnyFile); dlg->setOption(QFileDialog::DontConfirmOverwrite, true); dlg->setAcceptMode(AcceptSave); dlg->setLabelText(QFileDialog::Accept, "Select"); const QString fn(dlg->fileName(path)); delete dlg; return fn; } QString c2bFileDialog::getOpenFilename(QWidget* parentw, const QString& caption, const QString& path, const QString& filter) { c2bFileDialog* dlg(new c2bFileDialog(parentw, _caption(tr("Select a filename"), caption), _path(path), filter)); dlg->setFileMode(ExistingFile); dlg->setLabelText(QFileDialog::Accept, "Select"); const QString fn(dlg->fileName(path)); delete dlg; return fn; } QStringList c2bFileDialog::getOpenFilenames(QWidget* parentw, const QString& caption, const QString& path, const QString& filter) { c2bFileDialog* dlg(new c2bFileDialog(parentw, _caption(tr("Select filenames"), caption), _path(path), filter)); dlg->setFileMode(ExistingFiles); dlg->setLabelText(QFileDialog::Accept, "Select"); const QString fn(dlg->fileName(path)); QStringList fns; if (!fn.isEmpty()) fns = dlg->selectedFiles(); delete dlg; return fns; } QString c2bFileDialog::getSaveFilename(QWidget* parentw, const QString& caption, const QString& path, const QString& filter) { c2bFileDialog* dlg(new c2bFileDialog(parentw, _caption(tr("Save As"), caption), _path(path), filter)); dlg->setFileMode(AnyFile); dlg->setAcceptMode(AcceptSave); const QString fn(dlg->fileName(path)); delete dlg; return fn; } QString c2bFileDialog::getExistingDirectory(QWidget* parentw, const QString& caption, const QString& path) { c2bFileDialog* dlg(new c2bFileDialog(parentw, _caption("Select directory", caption), _dirpath(path), QString())); dlg->setFileMode(Directory); dlg->setOption(QFileDialog::ShowDirsOnly, true); dlg->setLabelText(QFileDialog::Accept, "Select"); const QString fn(dlg->fileName(QString())); delete dlg; return fn; } QString c2bFileDialog::getSystemFilename(QWidget* parentw, const QString& caption, const QString& path, const QString& filter) { c2bFileDialog* dlg(new c2bFileDialog(parentw, _caption(tr("Select a filename"), caption), _path(path), filter)); dlg->setFileMode(AnyFile); dlg->setLabelText(QFileDialog::Accept, "Select"); dlg->setFilter(QDir::Drives | QDir::AllDirs | QDir::NoDotAndDotDot | QDir::System); dlg->setOption(QFileDialog::HideNameFilterDetails, true); const QString fn(dlg->fileName(path)); delete dlg; return fn; } QString c2bFileDialog::fileName(const QString& path) { readSettings(); _current_file = path; const QStringList fnf(nameFilters().filter(QFileInfo(path).completeSuffix() + ')', Qt::CaseInsensitive)); if (fnf.count() > 0) selectNameFilter(fnf.at(0)); QTimer::singleShot(250, this, SLOT(selectCurrentFile())); QString sfn; if (QFileDialog::exec() == QDialog::Accepted) { const QStringList selected(selectedFiles()); if (selected.count() > 0) sfn = selected.first(); } writeSettings(); return QDir::toNativeSeparators(QDir::cleanPath(sfn)); } void c2bFileDialog::accept() { // Set suffix for getSaveFilename dialog if (acceptMode() == AcceptSave) { QString suffix(selectedNameFilter()); QRegExp sre("\\*\\.([\\w\\.]+)"); if (sre.indexIn(suffix) != -1) { suffix = sre.cap(1); setDefaultSuffix(suffix); } } QFileDialog::accept(); } void c2bFileDialog::selectCurrentFile() { // Bug fix for Qt 4.4 not giving correct selection const QString fn(_filename(_current_file)); QLineEdit* le = findChild<QLineEdit*>(); if (le) { le->setText(fn); le->selectAll(); } } void c2bFileDialog::readSettings() { // Size resize(settings->value("c2bFileDialog/size", sizeHint()).toSize()); // History QStringList dhistory(settings->value("c2bFileDialog/history").toStringList()); dhistory.removeAll(directory().absolutePath()); std::sort(dhistory.begin(), dhistory.end()); setHistory(dhistory); } void c2bFileDialog::writeSettings() { // Size settings->setValue("c2bFileDialog/size", size()); // History if (result() == QDialog::Accepted) { // Unique paths, keeping the newest history entries QStringList dhistory(history()); dhistory.append(directory().absolutePath()); dhistory.removeAll(QDir::homePath()); dhistory.removeAll(QDir::rootPath()); QStringList chronological(settings->value("c2bFileDialog/history").toStringList()); chronological.append(dhistory.last()); // Discard repeated dhistory.clear(); for (int i = chronological.count() - 1; i > -1; --i) if (!dhistory.contains(chronological.at(i))) { dhistory.prepend(chronological.at(i)); if (dhistory.count() > 10) break; } settings->setValue("c2bFileDialog/history", dhistory); } } QString c2bFileDialog::_caption(const QString& generic, const QString& caption) { if (caption.isEmpty()) return generic + " - cb2Bib"; else return caption + " - cb2Bib"; } QString c2bFileDialog::_filename(const QString& path) { if (path.isEmpty()) return path; else return QFileInfo(path).fileName(); } QString c2bFileDialog::_path(const QString& path) { if (path.isEmpty()) return QDir::homePath(); else return QFileInfo(path).absolutePath(); } QString c2bFileDialog::_dirpath(const QString& path) { if (path.isEmpty()) return QDir::homePath(); else return QFileInfo(path + '/').absolutePath(); } ���������������������������������������������������������������������������������������������������������������������������������������cb2bib-2.0.1/src/PaxHeaders.5700/c2bConsole.h�������������������������������������������������������0000644�0000000�0000000�00000000132�14011522520�015226� x����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������30 mtime=1613145424.518620343 30 atime=1613145424.830620334 30 ctime=1613145424.518620343 ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������cb2bib-2.0.1/src/c2bConsole.h�����������������������������������������������������������������������0000644�0001750�0000144�00000001463�14011522520�016631� 0����������������������������������������������������������������������������������������������������ustar�00constans������������������������users���������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*************************************************************************** * Copyright (C) 2004-2021 by Pere Constans * constans@molspaces.com * cb2Bib version 2.0.1. Licensed under the GNU GPL version 3. * See the LICENSE file that comes with this distribution. ***************************************************************************/ #ifndef C2BCONSOLE_H #define C2BCONSOLE_H #include <QObject> /** Interface for console functionality */ class c2bConsole : public QObject { Q_OBJECT public: explicit c2bConsole(QObject* parento = 0); ~c2bConsole(); void load(); private: int cl_cb2bib_information(); int cl_cb2bib_tests(); int cl_doc2bib(); int cl_html_annote(); int cl_index(); int cl_txt2bib(); private slots: void _process(); }; #endif �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������cb2bib-2.0.1/src/PaxHeaders.5700/c2bCiterModel.h����������������������������������������������������0000644�0000000�0000000�00000000132�14011522520�015653� x����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������30 mtime=1613145424.498620343 30 atime=1613145424.826620334 30 ctime=1613145424.498620343 ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������cb2bib-2.0.1/src/c2bCiterModel.h��������������������������������������������������������������������0000644�0001750�0000144�00000016673�14011522520�017267� 0����������������������������������������������������������������������������������������������������ustar�00constans������������������������users���������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*************************************************************************** * Copyright (C) 2004-2021 by Pere Constans * constans@molspaces.com * cb2Bib version 2.0.1. Licensed under the GNU GPL version 3. * See the LICENSE file that comes with this distribution. ***************************************************************************/ #ifndef C2BCITERMODEL_H #define C2BCITERMODEL_H #include "c2bCiter.h" #include "c2bCiterHistory.h" #include <collectionAnalyzer.h> #include <QAbstractTableModel> #include <QColor> #include <QHash> #include <QStringList> #include <QVector> class c2bCiterModel : public QAbstractTableModel { Q_OBJECT public: explicit c2bCiterModel(QObject* parento = 0); inline ~c2bCiterModel() {} QList<int> sizeHintForColumns() const; QStringList dataSelectedCiteIds() const; QVariant data(const QModelIndex& i, int role = Qt::DisplayRole) const; c2bCiter::State currentState(const QModelIndex& current_index) const; void clearCurrentFilter(QModelIndex* current_index); void clearSelection(); void loadCitations(const QString& fn); void loadCitations(const QStringList& fns); void reloadCitations(const QStringList& fns, const c2bCiter::State& state, QModelIndex* current_index); void restoreNextState(QModelIndex* current_index); void restorePreviousState(QModelIndex* current_index); void restoreState(const c2bCiter::State& s, QModelIndex* current_index); void setDocumentFilter(const QString& documentfn, QModelIndex* current_index); void setGlossaryView(QModelIndex* current_index); void setKeywordFilter(const QString& keyword, QModelIndex* current_index); void setPatternFilter(const QString& pattern, QModelIndex* current_index, const c2bCiter::Format format); void setRelatedFilter(const QString& documentfn, QModelIndex* current_index, const c2bCiter::Format format = c2bCiter::R); void setSelectedFilter(QModelIndex* current_index); void updateFormat(const c2bCiter::Format format, QModelIndex* current_index); inline QString dataBibTeXPosition(const QModelIndex& i) const { if (_is_index_valid(i)) return _bibtex_position.at(_offset(i.row())); else return QString(); } inline QString dataBibTeXFile(const QModelIndex& i) const { return dataBibTeXPosition(i).remove(QRegExp(":(\\d+)$")); } inline QString dataFile(const QModelIndex& i) const { if (_is_index_valid(i)) return _file.key(_offset(i.row())); else return QString(); } inline QString dataUrl(const QModelIndex& i) const { if (_is_index_valid(i)) return _url.at(_offset(i.row())); else return QString(); } inline QString dataKeyword(const QModelIndex& i) const { if (_format == c2bCiter::K && _is_index_valid(i)) return _analyzer.sentence(_offset(i.row())); else return QString(); } inline c2bCiter::KeywordData keywordData(const QModelIndex& i) const { c2bCiter::KeywordData kd; if (_filter == c2bCiter::Document && _format == c2bCiter::K) { kd.bibtexfn = QString(_bibtex_position.at(_file.value(_fstring))).remove(QRegExp(":(\\d+)$")); kd.documentfn = _fstring; kd.keyword = dataKeyword(i); } else if (_filter == c2bCiter::Keyword) { kd.bibtexfn = dataBibTeXFile(i); kd.documentfn = dataFile(i); kd.keyword = _fstring; } kd.valid = !kd.bibtexfn.isEmpty() && !kd.documentfn.isEmpty() && !kd.keyword.isEmpty(); return kd; } inline bool isKeywordView() const { return _format == c2bCiter::K; } inline Qt::ItemFlags flags(const QModelIndex& /* i */) const { return Qt::ItemIsSelectable | Qt::ItemIsEnabled; } inline int count() const { return _row_count; } inline int rowCount(const QModelIndex& /* parent */ = QModelIndex()) const { return _row_count; } inline int columnCount(const QModelIndex& /* parent */ = QModelIndex()) const { return _column_count; } inline c2bCiter::Filter currentFilter() const { return _filter; } inline c2bCiter::Format currentFormat() const { return _format; } inline c2bCiter::Format lastCitationFormat() const { return _history.lastCitationFormat(); } inline void restoreLastNonKeywordState(QModelIndex* current_index) { restoreState(_history.lastNonKeywordState(), current_index); } inline void restoreLastNonSelectedState(QModelIndex* current_index) { restoreState(_history.lastNonSelectedState(), current_index); } public slots: void selectCitation(const QModelIndex& i); signals: void patternFilterChanged(const QString& pattern); void statusLabel(const QString& label); void statusMessage(const QString& message); private: Q_DISABLE_COPY(c2bCiterModel) QColor _first_column_color; QString _display_ajyt(const int row, const int column) const; QString _display_it(const int row, const int column) const; QString _display_jya(const int row, const int column) const; QString _display_k(const int row, const int column) const; QString _display_r(const int row, const int column) const; QString _display_t(const int row, const int column) const; QString _display_yajt(const int row, const int column) const; QString(c2bCiterModel::*_display_ptr)(const int row, const int column) const; int _current_item(const QString& index_data) const; int _offset(const int i) const; void _add_citations(const QString& fn); void _clear(); void _set_mapping(); void _set_sort_indices(); void _set_table_data(); void _update_current_index(const int current_item, QModelIndex* current_index) const; void _update_format(const c2bCiter::Format format = c2bCiter::AJYT); inline bool _is_index_valid(const QModelIndex& i) const { const int r(i.row()); return _row_count > 0 && r >= 0 && r < _row_count; } inline int _current_item(const QModelIndex& current_index) const { return _is_index_valid(current_index) ? _offset(current_index.row()) : -1; } inline int _current_item(const QModelIndex* const current_index) const { return current_index ? _current_item(*current_index) : -1; } // Collection analyzer helper collectionAnalyzer _analyzer; // History helper QString _fstring; c2bCiter::Filter _filter; c2bCiter::Format _format; c2bCiterHistory _history; // Model data QHash<QString, int> _file; QList<uint> _included_date; QStringList _author_string; QStringList _bibtex_position; QStringList _citeId; QStringList _journal; QStringList _title; QStringList _url; QStringList _year; QVector<QString> _author; QVector<QString> _search_string; QVector<bool> _is_selected; QVector<bool> _matches_filter; QVector<int> _map_ajyt; QVector<int> _map_author; QVector<int> _map_filter; QVector<int> _map_it; QVector<int> _map_jya; QVector<int> _map_t; QVector<int> _map_yajt; QVector<int>* _mapping; int _author_count; int _author_max_length; int _citation_count; int _column_count; int _journal_max_length; int _keyword_count; int _related_count; int _row_count; }; #endif ���������������������������������������������������������������������cb2bib-2.0.1/src/PaxHeaders.5700/c2bAnnote.h��������������������������������������������������������0000644�0000000�0000000�00000000132�14011522520�015050� x����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������30 mtime=1613145424.478620344 30 atime=1613145424.826620334 30 ctime=1613145424.482620344 ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������cb2bib-2.0.1/src/c2bAnnote.h������������������������������������������������������������������������0000644�0001750�0000144�00000002054�14011522520�016450� 0����������������������������������������������������������������������������������������������������ustar�00constans������������������������users���������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*************************************************************************** * Copyright (C) 2004-2021 by Pere Constans * constans@molspaces.com * cb2Bib version 2.0.1. Licensed under the GNU GPL version 3. * See the LICENSE file that comes with this distribution. ***************************************************************************/ #ifndef C2BANNOTE_H #define C2BANNOTE_H #include <QMainWindow> class c2bFileSystemWatcher; class c2bSettings; class c2bWebBrowser; class texToHtml; class c2bAnnote : public QMainWindow { Q_OBJECT public: explicit c2bAnnote(QWidget* parentw = 0); ~c2bAnnote(); bool show(); private: QString _annote_filename; QString _html_filename; c2bFileSystemWatcher* _fsw; c2bSettings* _settingsP; c2bWebBrowser* _view_port; texToHtml* _t2h; private slots: void annote(); void configure(); void edit(); void help(); void loadSettings(); void setWindowTitle(const QString& title); void showMessage(const QString& ms); void update(); }; #endif ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������cb2bib-2.0.1/src/PaxHeaders.5700/c2bBibParser.cpp���������������������������������������������������0000644�0000000�0000000�00000000132�14011522520�016030� x����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������30 mtime=1613145424.378620347 30 atime=1613145424.818620334 30 ctime=1613145424.382620347 ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������cb2bib-2.0.1/src/c2bBibParser.cpp�������������������������������������������������������������������0000644�0001750�0000144�00000015675�14011522520�017445� 0����������������������������������������������������������������������������������������������������ustar�00constans������������������������users���������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*************************************************************************** * Copyright (C) 2004-2021 by Pere Constans * constans@molspaces.com * cb2Bib version 2.0.1. Licensed under the GNU GPL version 3. * See the LICENSE file that comes with this distribution. ***************************************************************************/ #include "c2bBibParser.h" #include "c2b.h" #include "c2bSettings.h" #include <bibPreparser.h> #include <QComboBox> #include <QMessageBox> c2bBibParser::c2bBibParser(QObject* parento) : bibParser(parento) { _c2b_mainP = c2b::mainWidget(); _bp_updates_gui = false; // Warn users if journal database file is not setup const QString journal_f(_settingsP->fileName("cb2Bib/JournalFile")); if (journal_f.isEmpty()) QMessageBox::information(_c2b_mainP, tr("Information - cb2Bib"), tr("No Abbreviation Journal file has been specified.\n\n" "Note: Abbreviation files are specified through the cb2Bib Configure dialog."), QMessageBox::Ok); else { QFile f(journal_f); if (!f.open(QIODevice::ReadOnly | QIODevice::Text)) // jdbfile.exists wouldn't produce an errorString QMessageBox::warning(_c2b_mainP, tr("Warning - cb2Bib"), tr("Unable to open the Journal Abbreviation file %1 for reading.\nError: '%2'.\n\n" "Note: Abbreviation files are specified through the cb2Bib Configure dialog.") .arg(journal_f, f.errorString()), QMessageBox::Ok); else f.close(); } // Set status messages connect(this, SIGNAL(statusMessage(QString)), c2b::instance(), SIGNAL(statusMessage(QString))); // Set preparser log connect(_preparserP, SIGNAL(preparserLogAvailable(QString)), this, SLOT(showLog(QString))); } c2bBibParser::~c2bBibParser() {} void c2bBibParser::currentReferenceUpdated() { // Current reference has been updated by the base class. // Update it in the GUI _bp_updates_gui = true; bibReferenceIterator i; for (i = _current_reference.constBegin(); i != _current_reference.constEnd(); ++i) _field_editors[i.key()]->setText(i.value()); // Set default type to article if (_current_reference.typeName.isEmpty()) _current_reference.typeName = "article"; setReferenceType(_current_reference.typeName); setCiteID(); _bp_updates_gui = false; emit bibModified(fieldCount() > 0); } void c2bBibParser::clearCurrentReference() { _bp_updates_gui = true; // Clear by setting empty QString as a workaround for bug // http://bugreports.qt.nokia.com/browse/QTBUG-7866 // Affects versions 4.6.x, expected to be fixed in 4.6.3 for (int i = 0; i < _bibliographic_fields.count(); ++i) _field_editors[_bibliographic_fields.at(i)]->setText(QString()); // _field_editors[_bibliographic_fields.at(i)]->clear(); _field_editors["id"]->setText(QString()); // _field_editors["id"]->clear(); bibParser::clearCurrentReference(); _current_reference.typeName = "article"; _type_editor->setCurrentIndex(1); _bp_updates_gui = false; emit bibModified(false); } void c2bBibParser::referenceEdited(const QString& value) { if (_bp_updates_gui) return; if (sender()) { const QString name(sender()->objectName()); if (name == "id") { _current_reference.citeidName = value; emit setDocumentFilename(); } else if (name == "typecombo") _current_reference.typeName = value; else if (name == "file") _current_reference[name] = value; else { // Attention: No name checking is done. // Only reference editors must be connected here. _current_reference[name] = value; setCiteID(); emit setDocumentFilename(); } emit bibModified(fieldCount() > 0); } } void c2bBibParser::setCiteID() { bibParser::setCiteID(); _field_editors["id"]->setText(_current_reference.citeidName); } void c2bBibParser::setField() { if (sender()) { const QString name(sender()->objectName()); if (_field_editors.contains(name)) _field_editors[name]->setText(parse(name, _field_editors.value(name)->text())); } } void c2bBibParser::setReferenceType(const QString& type) { int i(0); while (i < _type_editor->count()) { if (_type_editor->itemText(i) == type) { _type_editor->setCurrentIndex(i); return; } ++i; } _type_editor->setCurrentIndex(0); _type_editor->setItemText(0, type); } void c2bBibParser::setWidgetMapping() { // Setting Reference Types _type_editor->insertItems(0, _bibliographic_types); _type_editor->setCurrentIndex(1); _current_reference.typeName = "article"; // Tracking Field Editor Line changes // Track using textChanged instead of editTextChanged. The latter does not track line clears for (int i = 0; i < _bibliographic_fields.count(); ++i) { const QString& name = _bibliographic_fields.at(i); connect(_field_editors.value(name), SIGNAL(returnPressed()), this, SLOT(setField())); connect(_field_editors.value(name), SIGNAL(textChanged(QString)), this, SLOT(referenceEdited(QString))); } connect(_field_editors.value("id"), SIGNAL(textChanged(QString)), this, SLOT(referenceEdited(QString))); connect(_type_editor, SIGNAL(editTextChanged(QString)), this, SLOT(referenceEdited(QString))); } void c2bBibParser::showLog(const QString& log) { if (!_preparser_logP) _preparser_logP = new c2bBibPreparserLog(_c2b_mainP); _preparser_logP->append(log); _preparser_logP->show(); // Don't use exec(), it could be a recursive call if clipboard changed } void c2bBibParser::checkRegExpFile(const QString& fn) { if (fn.isEmpty()) { QMessageBox::information(_c2b_mainP, tr("Information - cb2Bib"), tr("No RegExp filename has been specified.\n\n" "Note: RegExp files are specified through the cb2Bib Configure dialog."), QMessageBox::Ok); return; } QFile f(fn); if (!f.open(QIODevice::ReadOnly | QIODevice::Text)) QMessageBox::warning(_c2b_mainP, tr("Warning - cb2Bib"), tr("Unable to open the RegExp file %1 for reading.\nError: '%2'.\n\n" "Note: RegExp files are specified through the cb2Bib Configure dialog. " "After manual matching, patterns can be edited and stored in a " "RegExp file for future autodetection.") .arg(fn, f.errorString()), QMessageBox::Ok); else f.close(); } �������������������������������������������������������������������cb2bib-2.0.1/src/PaxHeaders.5700/c2bReferenceList.ui������������������������������������������������0000644�0000000�0000000�00000000074�14011522151�016551� x����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������30 atime=1613145424.830620334 30 ctime=1613145424.302620349 ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������cb2bib-2.0.1/src/c2bReferenceList.ui����������������������������������������������������������������0000644�0001750�0000144�00000010725�14011522151�020150� 0����������������������������������������������������������������������������������������������������ustar�00constans������������������������users���������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?> <ui version="4.0"> <author>Pere Constans</author> <class>c2bReferenceList</class> <widget class="QWidget" name="c2bReferenceList"> <property name="geometry"> <rect> <x>0</x> <y>0</y> <width>738</width> <height>153</height> </rect> </property> <property name="sizePolicy"> <sizepolicy hsizetype="Ignored" vsizetype="Preferred"> <horstretch>0</horstretch> <verstretch>0</verstretch> </sizepolicy> </property> <property name="windowTitle"> <string>References</string> </property> <layout class="QGridLayout"> <property name="margin"> <number>0</number> </property> <property name="spacing"> <number>2</number> </property> <item row="2" column="2"> <widget class="QToolButton" name="clearB"> <property name="toolTip"> <string/> </property> <property name="statusTip"> <string>Clear filter</string> </property> <property name="text"> <string/> </property> <property name="icon"> <iconset resource="cb2bib.qrc"> <normaloff>:/icons/icons/clear_left.png</normaloff>:/icons/icons/clear_left.png</iconset> </property> </widget> </item> <item row="2" column="0"> <widget class="QToolButton" name="filterB"> <property name="statusTip"> <string>Filter Author and Title</string> </property> <property name="text"> <string>...</string> </property> <property name="icon"> <iconset resource="cb2bib.qrc"> <normaloff>:/icons/icons/filter.png</normaloff>:/icons/icons/filter.png</iconset> </property> <property name="popupMode"> <enum>QToolButton::InstantPopup</enum> </property> </widget> </item> <item row="1" column="0" colspan="3"> <widget class="Line" name="line"> <property name="frameShape"> <enum>QFrame::HLine</enum> </property> <property name="frameShadow"> <enum>QFrame::Sunken</enum> </property> <property name="orientation"> <enum>Qt::Horizontal</enum> </property> </widget> </item> <item row="0" column="0" colspan="3"> <widget class="QTreeWidget" name="listView"> <property name="mouseTracking"> <bool>true</bool> </property> <property name="frameShadow"> <enum>QFrame::Raised</enum> </property> <property name="tabKeyNavigation"> <bool>true</bool> </property> <property name="selectionMode"> <enum>QAbstractItemView::ExtendedSelection</enum> </property> <property name="rootIsDecorated"> <bool>false</bool> </property> <property name="sortingEnabled"> <bool>true</bool> </property> <property name="columnCount"> <number>6</number> </property> <column> <property name="text"> <string>0</string> </property> </column> <column> <property name="text"> <string>1</string> </property> </column> <column> <property name="text"> <string>2</string> </property> </column> <column> <property name="text"> <string>3</string> </property> </column> <column> <property name="text"> <string>4</string> </property> </column> <column> <property name="text"> <string>5</string> </property> </column> </widget> </item> <item row="2" column="1"> <widget class="c2bComboBox" name="comboFilter"> <property name="sizePolicy"> <sizepolicy hsizetype="Ignored" vsizetype="Ignored"> <horstretch>0</horstretch> <verstretch>0</verstretch> </sizepolicy> </property> <property name="editable"> <bool>true</bool> </property> <property name="duplicatesEnabled"> <bool>false</bool> </property> </widget> </item> </layout> </widget> <layoutdefault spacing="6" margin="11"/> <customwidgets> <customwidget> <class>c2bComboBox</class> <extends>QComboBox</extends> <header>c2bComboBox.h</header> </customwidget> </customwidgets> <resources> <include location="cb2bib.qrc"/> </resources> <connections> <connection> <sender>clearB</sender> <signal>clicked()</signal> <receiver>comboFilter</receiver> <slot>clearEditText()</slot> <hints> <hint type="sourcelabel"> <x>735</x> <y>152</y> </hint> <hint type="destinationlabel"> <x>548</x> <y>151</y> </hint> </hints> </connection> </connections> </ui> �������������������������������������������cb2bib-2.0.1/src/PaxHeaders.5700/c2bExportDialog.h��������������������������������������������������0000644�0000000�0000000�00000000132�14011522520�016225� x����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������30 mtime=1613145424.522620343 30 atime=1613145424.830620334 30 ctime=1613145424.526620343 ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������cb2bib-2.0.1/src/c2bExportDialog.h������������������������������������������������������������������0000644�0001750�0000144�00000002004�14011522520�017620� 0����������������������������������������������������������������������������������������������������ustar�00constans������������������������users���������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*************************************************************************** * Copyright (C) 2004-2021 by Pere Constans * constans@molspaces.com * cb2Bib version 2.0.1. Licensed under the GNU GPL version 3. * See the LICENSE file that comes with this distribution. ***************************************************************************/ #ifndef C2BEXPORTDIALOG_H #define C2BEXPORTDIALOG_H #include "c2bExport.h" #include "ui_c2bExportDialog.h" #include <QDialog> class c2bSettings; class c2bExportDialog : public QDialog { Q_OBJECT public: c2bExportDialog(const QString& fn, const QString& contents, const QStringList& keys, QWidget* parentw = 0); ~c2bExportDialog(); inline const QString exportFilename() const { return ui.ExportFile->text(); } private: Ui::c2bExportDialog ui; c2bExport::export_data _ed; c2bSettings* settings; private slots: void _export(); void getDocumentsDirectory(); void getExportFile(); void help(); }; #endif ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������cb2bib-2.0.1/src/PaxHeaders.5700/c2bBibMenu.h�������������������������������������������������������0000644�0000000�0000000�00000000132�14011522520�015145� x����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������30 mtime=1613145424.482620344 30 atime=1613145424.826620334 30 ctime=1613145424.482620344 ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������cb2bib-2.0.1/src/c2bBibMenu.h�����������������������������������������������������������������������0000644�0001750�0000144�00000003757�14011522520�016560� 0����������������������������������������������������������������������������������������������������ustar�00constans������������������������users���������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*************************************************************************** * Copyright (C) 2004-2021 by Pere Constans * constans@molspaces.com * cb2Bib version 2.0.1. Licensed under the GNU GPL version 3. * See the LICENSE file that comes with this distribution. ***************************************************************************/ #ifndef C2BBIBMENU_H #define C2BBIBMENU_H #include <QMenu> class c2bBibMenu : public QMenu { Q_OBJECT public: explicit c2bBibMenu(QWidget* parentw = 0); inline ~c2bBibMenu() {} inline QAction* addAuthorAction() const { return _add_author_action; } inline QAction* addEditorAction() const { return _add_editor_action; } inline QAction* anyPatternAction() const { return _any_pattern_action; } inline void setAnyPatternText(const QString& text) { _any_pattern_action->setText(text); } QAction* exec(const QPoint& p); protected: void keyPressEvent(QKeyEvent* qevent); private: QAction* _abstract_action; QAction* _add_author_action; QAction* _add_editor_action; QAction* _address_action; QAction* _annote_action; QAction* _any_pattern_action; QAction* _author_action; QAction* _booktitle_action; QAction* _chapter_action; QAction* _doi_action; QAction* _edition_action; QAction* _editor_action; QAction* _eprint_action; QAction* _file_action; QAction* _institution_action; QAction* _isbn_action; QAction* _issn_action; QAction* _journal_action; QAction* _keyboard_selection; QAction* _keywords_action; QAction* _month_action; QAction* _note_action; QAction* _number_action; QAction* _organization_action; QAction* _pages_action; QAction* _publisher_action; QAction* _school_action; QAction* _series_action; QAction* _title_action; QAction* _url_action; QAction* _volume_action; QAction* _year_action; bool _was_plus_pressed; }; #endif �����������������cb2bib-2.0.1/src/PaxHeaders.5700/c2bNetworkQuery.h��������������������������������������������������0000644�0000000�0000000�00000000132�14011522520�016303� x����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������30 mtime=1613145424.534620342 30 atime=1613145424.830620334 30 ctime=1613145424.534620342 ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������cb2bib-2.0.1/src/c2bNetworkQuery.h������������������������������������������������������������������0000644�0001750�0000144�00000002031�14011522520�017676� 0����������������������������������������������������������������������������������������������������ustar�00constans������������������������users���������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*************************************************************************** * Copyright (C) 2004-2021 by Pere Constans * constans@molspaces.com * cb2Bib version 2.0.1. Licensed under the GNU GPL version 3. * See the LICENSE file that comes with this distribution. ***************************************************************************/ #ifndef C2BNETWORKQUERY_H #define C2BNETWORKQUERY_H #include "c2bUtils.h" #include <networkQuery.h> class c2bNetworkQuery : public networkQuery { Q_OBJECT public: explicit c2bNetworkQuery(bibParser* bp, QObject* parento = 0); c2bNetworkQuery(bibParser* bp, network* net, QObject* parento = 0); ~c2bNetworkQuery(); protected: bool checkQueryFile(const QString& fn) const override; inline QString fromHtmlString(const QString& str, const bool addMetadata = false) const override { return c2bUtils::fromHtmlString(str, addMetadata); } bool openFile(const QString& fn) const override { return c2bUtils::openFile(fn); } }; #endif �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������cb2bib-2.0.1/src/PaxHeaders.5700/c2bSearchInFiles.h�������������������������������������������������0000644�0000000�0000000�00000000132�14011522520�016303� x����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������30 mtime=1613145424.550620342 30 atime=1613145424.830620334 30 ctime=1613145424.554620342 ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������cb2bib-2.0.1/src/c2bSearchInFiles.h�����������������������������������������������������������������0000644�0001750�0000144�00000002431�14011522520�017702� 0����������������������������������������������������������������������������������������������������ustar�00constans������������������������users���������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*************************************************************************** * Copyright (C) 2004-2021 by Pere Constans * constans@molspaces.com * cb2Bib version 2.0.1. Licensed under the GNU GPL version 3. * See the LICENSE file that comes with this distribution. ***************************************************************************/ #ifndef C2BSEARCHINFILES_H #define C2BSEARCHINFILES_H #include "ui_c2bSearchInFiles.h" #include "ui_c2bSearchInFilesPatternEdit.h" #include <QDialog> class bibSearcher; class c2bSearchInFiles : public QDialog { Q_OBJECT public: explicit c2bSearchInFiles(const QString& file, QWidget* parentw = 0); ~c2bSearchInFiles(); void setCurrentText(const QString& text); public slots: void setBibTeXFile(const QString& file = QString()); void show(); signals: void searchDone(const QString& filename, bibSearcher* searcher); private slots: void help(); void on_addPatternB_clicked(); void on_deletePatternB_clicked(); void on_editPatternB_clicked(); void searchB_clicked(); void updateForm(); private: QPushButton* _searchB; QString _bibtex_dir; QString _bibtex_file; QString _search_log; Ui::c2bSearchInFiles ui; Ui::c2bSearchInFilesPatternEdit ui_editor; }; #endif ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������cb2bib-2.0.1/src/PaxHeaders.5700/cb2Bib.h�����������������������������������������������������������0000644�0000000�0000000�00000000132�14011522520�014320� x����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������30 mtime=1613145424.570620341 30 atime=1613145424.830620334 30 ctime=1613145424.570620341 ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������cb2bib-2.0.1/src/cb2Bib.h���������������������������������������������������������������������������0000644�0001750�0000144�00000007741�14011522520�015730� 0����������������������������������������������������������������������������������������������������ustar�00constans������������������������users���������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*************************************************************************** * Copyright (C) 2004-2021 by Pere Constans * constans@molspaces.com * cb2Bib version 2.0.1. Licensed under the GNU GPL version 3. * See the LICENSE file that comes with this distribution. ***************************************************************************/ #ifndef CB2BIB_H #define CB2BIB_H #include "ui_cb2Bib.h" #include <QHash> #include <QMainWindow> #include <QPointer> class bibSearcher; class c2bBibMenu; class c2bBibParser; class c2bCiterWidget; class c2bClipEdit; class c2bEditor; class c2bNetworkQuery; class c2bPdfImport; class c2bSearchInFiles; class c2bSettings; class c2bTextBrowser; class cb2Bib : public QMainWindow { Q_OBJECT public: explicit cb2Bib(QWidget* parentw = 0); ~cb2Bib(); public slots: void show(); signals: void addedBibToFile(const QString&); void endedProcessing(bool status); private: QHash<QString, c2bEditor*> _openDocuments; QPointer<c2bPdfImport> _pdfImportP; QPointer<c2bSearchInFiles> _searchInFilesP; QString _dropped_document_file; QString _raw_input_data; QString _target_document_file; QString buttonStatusTip(const QString& ms, const QKeySequence& ks) const; Ui::cb2Bib ui; bool _connected; bool _is_check_repeated_done; bool _modified; bool _tagged_view_mode; bool isReferenceRepeated(); c2bBibMenu* _bib_menu; c2bBibParser* _bpP; c2bCiterWidget* _citerP; c2bClipEdit* BibBrowser; c2bClipEdit* ClipEdit; c2bNetworkQuery* _netQP; c2bSettings* _settingsP; c2bTextBrowser* AboutBrowser; void annoteEditor(const QString& annotefile); void c2bParse(const QString& text); void c2bPreparse(const QString& text); void closeEvent(QCloseEvent* qevent); void dragEnterEvent(QDragEnterEvent* qevent); void dropEvent(QDropEvent* qevent); void fileDroppedByUser(const QString& fn); void initAsBibTeXEditor(); void processingEnded(); void setBibMenu(); void setWidgetMapping(); void updateBibfile(const QString& fn); void updateViewButtons(); private slots: void abbreviationsEditor(); void addAuthors(); void addEditors(); void addMetadata(); void addToFile(bool ready); void anyPattern(); void bibEditor(const QString& bibtexfile, bibSearcher* searcher = 0); void bibModified(bool modified); void bookmarksEditor(); void c2bInit(); void checkRepeated(); void dataChanged(const QString& str); void deleteTmpBib(); void doSearchInFiles(const QString& string = QString(), const QString& fn = QString()); void fileDropped(const QString& fn); void forceDataChange(const QString& str); void guessFields(); void insertRegExp(); void linkClicked(const QUrl& ln); void loadSettings(); void makeNetQuery(); void netQueryEnded(bool succeeded, const QString& targetPDF, const QString& targetBib); void on_AddBibB_clicked(); void on_BibTeXDir_clicked(); void on_ConfigureB_clicked(); void on_ConnectB_clicked(); void on_EditBibTeXB_clicked(); void on_ExitB_clicked(); void on_MakeNetworkQueryB_clicked(); void on_PdfImportB_clicked(); void on_SearchInFilesB_clicked(); void on_ViewAboutB_clicked(); void on_ViewBibB_clicked(); void openAnnote(); void openFileDocument(); void postprocessBibTeX(); void preparseClipboard(); void readField(const QPoint& position); void regExpsEditor(); void restartEngine(); void savePattern(const QString& rx, const QString& rxname); void selectFile(); void setDocumentFilename(); void setTaggedClipEditMode(bool tagged); void setWindowTitle(const QString& title = QString()); void showLink(const QString& ln); void showMessage(const QString& ms); void toggleReferenceTabs(); void updateCheckRepeatedAction(); void updateOpenDocuments(QObject* obj); void updateOpenDocuments(const QString& old_name, const QString& new_name); }; #endif �������������������������������cb2bib-2.0.1/src/PaxHeaders.5700/c2bExportDialog.ui�������������������������������������������������0000644�0000000�0000000�00000000074�14011522151�016420� x����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������30 atime=1613145424.830620334 30 ctime=1613145424.302620349 ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������cb2bib-2.0.1/src/c2bExportDialog.ui�����������������������������������������������������������������0000644�0001750�0000144�00000012546�14011522151�020022� 0����������������������������������������������������������������������������������������������������ustar�00constans������������������������users���������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?> <ui version="4.0"> <class>c2bExportDialog</class> <widget class="QDialog" name="c2bExportDialog"> <property name="geometry"> <rect> <x>0</x> <y>0</y> <width>563</width> <height>308</height> </rect> </property> <property name="windowTitle"> <string>Dialog</string> </property> <layout class="QGridLayout"> <item row="0" column="0"> <widget class="QGroupBox" name="groupBox2"> <property name="title"> <string/> </property> <layout class="QGridLayout"> <item row="0" column="0"> <widget class="QLabel" name="label"> <property name="text"> <string>BibTeX File:</string> </property> </widget> </item> <item row="0" column="1"> <layout class="QHBoxLayout"> <property name="spacing"> <number>6</number> </property> <property name="margin"> <number>0</number> </property> <item> <widget class="c2bLineEdit" name="ExportFile"> <property name="text"> <string/> </property> </widget> </item> <item> <widget class="QToolButton" name="ExportFileDir"> <property name="statusTip"> <string>Select BibTeX directory</string> </property> <property name="icon"> <iconset resource="cb2bib.qrc"> <normaloff>:/icons/icons/mimeFolder.png</normaloff>:/icons/icons/mimeFolder.png</iconset> </property> </widget> </item> </layout> </item> </layout> </widget> </item> <item row="1" column="0"> <widget class="Line" name="line_2"> <property name="orientation"> <enum>Qt::Horizontal</enum> </property> </widget> </item> <item row="2" column="0"> <widget class="QGroupBox" name="groupBox"> <property name="title"> <string/> </property> <layout class="QGridLayout"> <item row="0" column="0"> <widget class="QCheckBox" name="CopyDocuments"> <property name="text"> <string>Copy Documents</string> </property> <property name="shortcut"> <string/> </property> </widget> </item> </layout> </widget> </item> <item row="3" column="0"> <widget class="QGroupBox" name="DocumentsDirectoryBox"> <property name="title"> <string>Documents Directory</string> </property> <layout class="QGridLayout"> <item row="0" column="0"> <layout class="QHBoxLayout"> <property name="spacing"> <number>6</number> </property> <property name="margin"> <number>0</number> </property> <item> <widget class="c2bLineEdit" name="DocumentsDirectory"> <property name="text"> <string/> </property> </widget> </item> <item> <widget class="QToolButton" name="DocumentsDirectoryDir"> <property name="statusTip"> <string>Select PDF directory</string> </property> <property name="icon"> <iconset resource="cb2bib.qrc"> <normaloff>:/icons/icons/mimeFolder.png</normaloff>:/icons/icons/mimeFolder.png</iconset> </property> </widget> </item> </layout> </item> <item row="1" column="0"> <widget class="QCheckBox" name="RelativeDocumentDirectory"> <property name="text"> <string>Set directory relative to the BibTeX File Directory</string> </property> </widget> </item> </layout> </widget> </item> <item row="4" column="0"> <spacer> <property name="orientation"> <enum>Qt::Vertical</enum> </property> <property name="sizeHint" stdset="0"> <size> <width>20</width> <height>20</height> </size> </property> </spacer> </item> <item row="5" column="0"> <widget class="Line" name="line"> <property name="orientation"> <enum>Qt::Horizontal</enum> </property> </widget> </item> <item row="6" column="0"> <widget class="QDialogButtonBox" name="buttonBox"> <property name="orientation"> <enum>Qt::Horizontal</enum> </property> <property name="standardButtons"> <set>QDialogButtonBox::Cancel|QDialogButtonBox::Help</set> </property> </widget> </item> </layout> </widget> <customwidgets> <customwidget> <class>c2bLineEdit</class> <extends>QLineEdit</extends> <header>c2bLineEdit.h</header> </customwidget> </customwidgets> <resources> <include location="cb2bib.qrc"/> </resources> <connections> <connection> <sender>buttonBox</sender> <signal>rejected()</signal> <receiver>c2bExportDialog</receiver> <slot>reject()</slot> <hints> <hint type="sourcelabel"> <x>603</x> <y>259</y> </hint> <hint type="destinationlabel"> <x>630</x> <y>156</y> </hint> </hints> </connection> <connection> <sender>CopyDocuments</sender> <signal>clicked(bool)</signal> <receiver>DocumentsDirectoryBox</receiver> <slot>setEnabled(bool)</slot> <hints> <hint type="sourcelabel"> <x>23</x> <y>80</y> </hint> <hint type="destinationlabel"> <x>154</x> <y>134</y> </hint> </hints> </connection> </connections> </ui> ����������������������������������������������������������������������������������������������������������������������������������������������������������cb2bib-2.0.1/src/PaxHeaders.5700/c2bCiterWidget.ui��������������������������������������������������0000644�0000000�0000000�00000000074�14011522151�016231� x����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������30 atime=1613145424.830620334 30 ctime=1613145424.302620349 ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������cb2bib-2.0.1/src/c2bCiterWidget.ui������������������������������������������������������������������0000644�0001750�0000144�00000006735�14011522151�017636� 0����������������������������������������������������������������������������������������������������ustar�00constans������������������������users���������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?> <ui version="4.0"> <class>c2bCiterWidget</class> <widget class="QWidget" name="c2bCiterWidget"> <property name="geometry"> <rect> <x>0</x> <y>0</y> <width>901</width> <height>400</height> </rect> </property> <property name="windowTitle"> <string>c2bCiter - cb2Bib</string> </property> <layout class="QGridLayout" name="gridLayout"> <property name="leftMargin"> <number>3</number> </property> <property name="topMargin"> <number>6</number> </property> <property name="rightMargin"> <number>3</number> </property> <property name="bottomMargin"> <number>6</number> </property> <item row="0" column="0"> <widget class="Line" name="line1"> <property name="orientation"> <enum>Qt::Horizontal</enum> </property> </widget> </item> <item row="1" column="0"> <widget class="c2bCiterView" name="citationsView"> <property name="frameShape"> <enum>QFrame::NoFrame</enum> </property> <property name="frameShadow"> <enum>QFrame::Plain</enum> </property> <property name="showDropIndicator" stdset="0"> <bool>false</bool> </property> <property name="selectionMode"> <enum>QAbstractItemView::SingleSelection</enum> </property> <property name="selectionBehavior"> <enum>QAbstractItemView::SelectRows</enum> </property> <property name="showGrid"> <bool>false</bool> </property> <property name="gridStyle"> <enum>Qt::NoPen</enum> </property> <property name="wordWrap"> <bool>false</bool> </property> <property name="cornerButtonEnabled"> <bool>false</bool> </property> </widget> </item> <item row="2" column="0"> <widget class="Line" name="line2"> <property name="orientation"> <enum>Qt::Horizontal</enum> </property> </widget> </item> <item row="3" column="0"> <layout class="QHBoxLayout" name="horizontalLayout"> <property name="rightMargin"> <number>7</number> </property> <item> <widget class="QStatusBar" name="statusBar"> <property name="sizePolicy"> <sizepolicy hsizetype="Expanding" vsizetype="Preferred"> <horstretch>0</horstretch> <verstretch>0</verstretch> </sizepolicy> </property> <property name="sizeGripEnabled"> <bool>false</bool> </property> </widget> </item> <item> <widget class="QLabel" name="filterIcon"> <property name="text"> <string/> </property> <property name="pixmap"> <pixmap resource="cb2bib.qrc">:/icons/icons/filter.png</pixmap> </property> </widget> </item> <item> <widget class="QLabel" name="clipboardIcon"> <property name="text"> <string/> </property> <property name="pixmap"> <pixmap resource="cb2bib.qrc">:/icons/icons/clipboard.png</pixmap> </property> </widget> </item> </layout> </item> <item row="4" column="0"> <widget class="Line" name="line3"> <property name="orientation"> <enum>Qt::Horizontal</enum> </property> </widget> </item> </layout> </widget> <customwidgets> <customwidget> <class>c2bCiterView</class> <extends>QTableView</extends> <header>c2bCiterView.h</header> </customwidget> </customwidgets> <resources> <include location="cb2bib.qrc"/> </resources> <connections/> </ui> �����������������������������������cb2bib-2.0.1/src/PaxHeaders.5700/c2bReferenceList.h�������������������������������������������������0000644�0000000�0000000�00000000132�14011522520�016356� x����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������30 mtime=1613145424.542620342 30 atime=1613145424.830620334 30 ctime=1613145424.542620342 ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������cb2bib-2.0.1/src/c2bReferenceList.h�����������������������������������������������������������������0000644�0001750�0000144�00000005026�14011522520�017760� 0����������������������������������������������������������������������������������������������������ustar�00constans������������������������users���������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*************************************************************************** * Copyright (C) 2004-2021 by Pere Constans * constans@molspaces.com * cb2Bib version 2.0.1. Licensed under the GNU GPL version 3. * See the LICENSE file that comes with this distribution. ***************************************************************************/ #ifndef C2BREFERENCELIST_H #define C2BREFERENCELIST_H #include "ui_c2bReferenceList.h" #include <QWidget> class bibSearcher; class c2bCoreCiter; class c2bRLWebSearchSettings; class c2bSettings; class c2bTextBrowser; class c2bTextEdit; class c2bReferenceList : public QWidget { Q_OBJECT public: c2bReferenceList(c2bTextEdit* ed, c2bTextBrowser* br, QWidget* parentw = 0); ~c2bReferenceList(); QAction* citeEntryAction; QAction* clearSelectionsAction; QAction* openAuthorsWebSearchAction; QAction* openDOIAction; QAction* openFileAction; QAction* openTextLocalSearchAction; QAction* openTextWebSearchAction; QAction* openTitleWebSearchAction; QAction* openUrlAction; QAction* refreshListAction; QAction* webSearchSettingsAction; QStringList selectedKeys() const; void goToReference(const QString& id); void goToReference(const int position); public slots: void loadList(const QString& txt, bibSearcher* searcher = 0); void refreshList(); void setLyXPipe(); signals: void hasSelectedItems(bool); void openFile(const QString& fn); protected slots: void citeEntry(); void clearSelections(); void goToReference(QTreeWidgetItem* ref); void itemSelectionChanged(); void openAuthorWebSearch(); void openDOI(); void openFile(); void openLink(const QUrl& ln); void openTextLocalSearch(); void openTextWebSearch(); void openTitleWebSearch(); void openUrl(); void scrollToReference(const QString& id); void webSearchSettings(); private: QList<int> _positionList; QString _bib_item_html; QString _filter_mode; QString _references_html; QStringList _doiList; QStringList _fileList; QStringList _urlList; Ui::c2bReferenceList ui; c2bCoreCiter* _citerP; c2bSettings* _settingsP; c2bTextBrowser* _browserP; c2bTextEdit* _editorP; int _author_index; int _id_index; int _journal_index; int _key_index; int _title_index; int _year_index; void setupFilterBar(); private slots: void blockFilterSignals(); void filterList(); void keepFilterPattern(); void setFilterMode(QAction* mode); }; #endif ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������cb2bib-2.0.1/src/PaxHeaders.5700/proxyDialog.ui�����������������������������������������������������0000644�0000000�0000000�00000000074�14011522151�015731� x����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������30 atime=1613145424.830620334 30 ctime=1613145424.306620349 ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������cb2bib-2.0.1/src/proxyDialog.ui���������������������������������������������������������������������0000644�0001750�0000144�00000005433�14011522151�017330� 0����������������������������������������������������������������������������������������������������ustar�00constans������������������������users���������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<ui version="4.0" > <class>proxyDialog</class> <widget class="QDialog" name="proxyDialog" > <property name="geometry" > <rect> <x>0</x> <y>0</y> <width>454</width> <height>127</height> </rect> </property> <property name="windowTitle" > <string>Proxy Authentication - cb2Bib</string> </property> <layout class="QGridLayout" name="gridLayout_2" > <property name="margin" > <number>6</number> </property> <item row="0" column="0" colspan="2" > <layout class="QGridLayout" name="gridLayout" > <item row="0" column="0" > <widget class="QLabel" name="usernameLabel" > <property name="text" > <string>Username:</string> </property> </widget> </item> <item row="0" column="1" > <widget class="QLineEdit" name="userNameLineEdit" /> </item> <item row="1" column="0" > <widget class="QLabel" name="passwordLabel" > <property name="text" > <string>Password:</string> </property> </widget> </item> <item row="1" column="1" > <widget class="QLineEdit" name="passwordLineEdit" > <property name="echoMode" > <enum>QLineEdit::Password</enum> </property> </widget> </item> </layout> </item> <item row="1" column="1" > <spacer name="verticalSpacer" > <property name="orientation" > <enum>Qt::Vertical</enum> </property> <property name="sizeHint" stdset="0" > <size> <width>0</width> <height>0</height> </size> </property> </spacer> </item> <item row="2" column="0" colspan="2" > <widget class="Line" name="line" > <property name="orientation" > <enum>Qt::Horizontal</enum> </property> </widget> </item> <item row="3" column="1" > <widget class="QDialogButtonBox" name="buttonBox" > <property name="orientation" > <enum>Qt::Horizontal</enum> </property> <property name="standardButtons" > <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set> </property> </widget> </item> </layout> </widget> <resources/> <connections> <connection> <sender>buttonBox</sender> <signal>accepted()</signal> <receiver>proxyDialog</receiver> <slot>accept()</slot> <hints> <hint type="sourcelabel" > <x>248</x> <y>254</y> </hint> <hint type="destinationlabel" > <x>157</x> <y>274</y> </hint> </hints> </connection> <connection> <sender>buttonBox</sender> <signal>rejected()</signal> <receiver>proxyDialog</receiver> <slot>reject()</slot> <hints> <hint type="sourcelabel" > <x>316</x> <y>260</y> </hint> <hint type="destinationlabel" > <x>286</x> <y>274</y> </hint> </hints> </connection> </connections> </ui> �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������cb2bib-2.0.1/src/PaxHeaders.5700/htm����������������������������������������������������������������0000644�0000000�0000000�00000000074�14011522151�013604� x����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������30 atime=1613145424.838620334 30 ctime=1613145424.306620349 ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������cb2bib-2.0.1/src/htm/�������������������������������������������������������������������������������0000755�0001750�0000144�00000000000�14011522151�015253� 5����������������������������������������������������������������������������������������������������ustar�00constans������������������������users���������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������cb2bib-2.0.1/src/htm/PaxHeaders.5700/bib_item.html��������������������������������������������������0000644�0000000�0000000�00000000074�14011522151�016321� x����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������30 atime=1613145424.838620334 30 ctime=1613145424.306620349 ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������cb2bib-2.0.1/src/htm/bib_item.html������������������������������������������������������������������0000644�0001750�0000144�00000001060�14011522151�017710� 0����������������������������������������������������������������������������������������������������ustar�00constans������������������������users���������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������ <tr> <td width="5%"> <a href="Select reference GET_REFERENCE_ANCHOR_ID" name="GET_REFERENCE_ANCHOR_NAME" id="GET_REFERENCE_ANCHOR_ID" class="anchor"> <img src=":/icons/icons/select.png" alt="action" width="16" height="16" /></a></td> <td width="95%"> <p>GET_REFERENCE_AUTHOR <a href="GET_REFERENCE_LINK">GET_REFERENCE_TITLE</a>. <i>GET_REFERENCE_SOURCE</i> <b>GET_REFERENCE_VOLUME</b>GET_REFERENCE_PAGES GET_REFERENCE_YEAR </p> <blockquote> <p>GET_REFERENCE_ABSTRACT</p> </blockquote> </td> </tr>��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������cb2bib-2.0.1/src/htm/PaxHeaders.5700/excerpts.html��������������������������������������������������0000644�0000000�0000000�00000000074�14011522151�016404� x����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������30 atime=1613145424.838620334 30 ctime=1613145424.306620349 ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������cb2bib-2.0.1/src/htm/excerpts.html������������������������������������������������������������������0000644�0001750�0000144�00000001123�14011522151�017773� 0����������������������������������������������������������������������������������������������������ustar�00constans������������������������users���������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html;charset=UTF-8"/> <title>GET_EXCERPTS_TITLE

    GET_EXCERPTS


    cb2bib-2.0.1/src/htm/PaxHeaders.5700/references.css0000644000000000000000000000007414011522151016514 xustar0030 atime=1613145424.362620347 30 ctime=1613145424.306620349 cb2bib-2.0.1/src/htm/references.css0000644000175000001440000000142214011522151020105 0ustar00constansusers00000000000000/* cb2Bib References CSS */ /* general */ body { font-size: 100%; font-family: sans-serif; background-color: #E7E7E7; color: black; padding: 0; margin: 0; } a { color: #010141; text-decoration: none; } a:link { color: #010141; text-decoration: underline; } h1 { background-color: #010141; color: #DBDBDB; font-size: 20px; font-variant: small-caps; font-family: sans-serif; } /* references */ #references{ background-color: #DBDBDB; } #references blockquote{ font-size: small; } #references span{ color: #0000FF; } #excerpt{ font-style: italic; } /* header */ #header { vertical-align: middle; } /* footer */ #footer { color: black; font-family: arial, sans-serif; font-size: 9pt; } #footer td{ padding: 10px; padding-left: 5px; padding-right: 5px; } cb2bib-2.0.1/src/htm/PaxHeaders.5700/tex2html_local_mathjax_header.html0000644000000000000000000000007414011522151022514 xustar0030 atime=1613145424.366620347 30 ctime=1613145424.306620349 cb2bib-2.0.1/src/htm/tex2html_local_mathjax_header.html0000644000175000001440000000044414011522151024110 0ustar00constansusers00000000000000 cb2bib-2.0.1/src/htm/PaxHeaders.5700/references.html0000644000000000000000000000007414011522151016670 xustar0030 atime=1613145424.838620334 30 ctime=1613145424.306620349 cb2bib-2.0.1/src/htm/references.html0000644000175000001440000000222014011522151020256 0ustar00constansusers00000000000000 References


    GET_REFERENCES


    cb2bib-2.0.1/src/htm/PaxHeaders.5700/tex2html_mathjax_header.html0000644000000000000000000000007414011522151021342 xustar0030 atime=1613145424.366620347 30 ctime=1613145424.306620349 cb2bib-2.0.1/src/htm/tex2html_mathjax_header.html0000644000175000001440000000045514011522151022740 0ustar00constansusers00000000000000 cb2bib-2.0.1/src/PaxHeaders.5700/c2bConfigureFR.cpp0000644000000000000000000000013214011522520016330 xustar0030 mtime=1613145424.406620346 30 atime=1613145424.826620334 30 ctime=1613145424.410620346 cb2bib-2.0.1/src/c2bConfigureFR.cpp0000644000175000001440000000223214011522520017726 0ustar00constansusers00000000000000/*************************************************************************** * Copyright (C) 2004-2021 by Pere Constans * constans@molspaces.com * cb2Bib version 2.0.1. Licensed under the GNU GPL version 3. * See the LICENSE file that comes with this distribution. ***************************************************************************/ #include "c2bConfigureFR.h" #include c2bConfigureFR::c2bConfigureFR(QTreeWidgetItem* item, QWidget* parentw) : QDialog(parentw) { ui.setupUi(this); setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint); itemFindReplace = item; ui.lineEditFind->setText(itemFindReplace->text(0)); ui.lineEditReplace->setText(itemFindReplace->text(1)); ui.lineEditDescription->setText(itemFindReplace->text(2)); ui.lineEditFind->setFocus(); } c2bConfigureFR::~c2bConfigureFR() {} void c2bConfigureFR::reject() { QDialog::reject(); } void c2bConfigureFR::accept() { itemFindReplace->setText(0, ui.lineEditFind->text()); itemFindReplace->setText(1, ui.lineEditReplace->text()); itemFindReplace->setText(2, ui.lineEditDescription->text()); QDialog::accept(); } cb2bib-2.0.1/src/PaxHeaders.5700/c2bBibHighlighter.h0000644000000000000000000000013214011522520016477 xustar0030 mtime=1613145424.482620344 30 atime=1613145424.826620334 30 ctime=1613145424.482620344 cb2bib-2.0.1/src/c2bBibHighlighter.h0000644000175000001440000000154114011522520020077 0ustar00constansusers00000000000000/*************************************************************************** * Copyright (C) 2004-2021 by Pere Constans * constans@molspaces.com * cb2Bib version 2.0.1. Licensed under the GNU GPL version 3. * See the LICENSE file that comes with this distribution. ***************************************************************************/ #ifndef C2BBIBHIGHLIGHTER_H #define C2BBIBHIGHLIGHTER_H #include /** BibTeX SyntaxHighLighter @author Pere Constans */ class c2bColors; class c2bBibHighlighter : public QSyntaxHighlighter { public: explicit c2bBibHighlighter(QTextDocument* doc); ~c2bBibHighlighter(); protected: virtual void highlightBlock(const QString& text); private: QColor text_color; QRegExp rx0; QRegExp rx1; QRegExp rx2; QRegExp rx3; c2bColors* c; }; #endif cb2bib-2.0.1/src/PaxHeaders.5700/c2bCiterExcerptView.h0000644000000000000000000000013214011522520017060 xustar0030 mtime=1613145424.490620344 30 atime=1613145424.826620334 30 ctime=1613145424.494620343 cb2bib-2.0.1/src/c2bCiterExcerptView.h0000644000175000001440000000126014011522520020456 0ustar00constansusers00000000000000/*************************************************************************** * Copyright (C) 2004-2021 by Pere Constans * constans@molspaces.com * cb2Bib version 2.0.1. Licensed under the GNU GPL version 3. * See the LICENSE file that comes with this distribution. ***************************************************************************/ #ifndef C2BCITEREXCERPTVIEW_H #define C2BCITEREXCERPTVIEW_H #include class c2bTextBrowser; class c2bCiterExcerptView : public QDialog { Q_OBJECT public: explicit c2bCiterExcerptView(const QString& html, QWidget* parentw = 0); ~c2bCiterExcerptView(); private: c2bTextBrowser* _browserP; }; #endif cb2bib-2.0.1/src/PaxHeaders.5700/c2bNetworkQuery.cpp0000644000000000000000000000013214011522520016636 xustar0030 mtime=1613145424.430620345 30 atime=1613145424.826620334 30 ctime=1613145424.430620345 cb2bib-2.0.1/src/c2bNetworkQuery.cpp0000644000175000001440000000320014011522520020230 0ustar00constansusers00000000000000/*************************************************************************** * Copyright (C) 2004-2021 by Pere Constans * constans@molspaces.com * cb2Bib version 2.0.1. Licensed under the GNU GPL version 3. * See the LICENSE file that comes with this distribution. ***************************************************************************/ #include "c2bNetworkQuery.h" #include "c2b.h" #include c2bNetworkQuery::c2bNetworkQuery(bibParser* bp, QObject* parento) : networkQuery(bp, parento) {} c2bNetworkQuery::c2bNetworkQuery(bibParser* bp, network* net, QObject* parento) : networkQuery(bp, net, parento) {} c2bNetworkQuery::~c2bNetworkQuery() {} bool c2bNetworkQuery::checkQueryFile(const QString& fn) const { if (fn.isEmpty()) { QMessageBox::information(c2b::mainWidget(), tr("Information - cb2Bib"), tr("No Network Query file has been specified.\n\n" "Note: Network Query files are specified through the cb2Bib Configure dialog."), QMessageBox::Ok); return false; } QFile file(fn); if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) { QMessageBox::warning(c2b::mainWidget(), tr("Warning - cb2Bib"), tr("Unable to open the Network Query file %1 for reading.\nError: '%2'.\n\n" "Note: Network Query files are specified through the cb2Bib Configure dialog.") .arg(fn, file.errorString()), QMessageBox::Ok); return false; } return true; } cb2bib-2.0.1/src/PaxHeaders.5700/clipboardPoll.h0000644000000000000000000000013214011522520016023 xustar0030 mtime=1613145424.570620341 30 atime=1613145424.830620334 30 ctime=1613145424.574620341 cb2bib-2.0.1/src/clipboardPoll.h0000644000175000001440000000476414011522520017435 0ustar00constansusers00000000000000/*************************************************************************** * clipboardPoll, modified by Pere Constans for cb2Bib, 2005 * constans@molspaces.com * cb2Bib version 2.0.1. Licensed under the GNU GPL version 3. * * * Author and Copyright (C) 2003 by Lubos Lunak * Distributed under the GNU General Public License * * * This file is part of the KDE project * Copyright (C) 2003 by Lubos Lunak * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; see the file COPYING. If not, write to * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. ***************************************************************************/ #ifndef CLIPBOARDPOLL_H #define CLIPBOARDPOLL_H #include #include #include #include #undef Bool // Workaround for unqualified-id before 'int' for bool signal and slot /** @author Lubos Lunak */ class clipboardPoll : public QWidget { Q_OBJECT public: explicit clipboardPoll(QWidget* parentw = 0); ~clipboardPoll(); inline void startT(uint interval) { timer->start(interval); } inline void stopT() { timer->stop(); } signals: void clipboardChanged(bool selectionMode); protected: virtual bool x11Event(XEvent*); private slots: void timeout(); private: struct SelectionData { Atom atom; Atom sentinel_atom; Atom timestamp_atom; Window last_owner; bool owner_is_qt; Time last_change; bool waiting_for_timestamp; Time waiting_x_time; }; Atom xa_clipboard; Atom xa_timestamp; bool changedTimestamp(SelectionData& sData, const XEvent& ev); bool checkTimestamp(SelectionData& sData); QTimer* timer; SelectionData clipboard; SelectionData selection; void updateQtOwnership(SelectionData& sData); }; #endif cb2bib-2.0.1/src/PaxHeaders.5700/cb2bib.qrc0000644000000000000000000000007414011522151014723 xustar0030 atime=1613145424.830620334 30 ctime=1613145424.306620349 cb2bib-2.0.1/src/cb2bib.qrc0000644000175000001440000000532014011522151016315 0ustar00constansusers00000000000000 icons/add.png icons/annote.png icons/application-x-executable.png icons/application-x-html.png icons/application-x-none.png icons/application-x-pdf.png icons/application-x-tex.png icons/application-x-txt.png icons/back_cb2bib_32.png icons/bullet.png icons/cb2bib.ico icons/cb2bib.png icons/cb2bib22.png icons/cb2bib128.png icons/citer_citation.png icons/citer_citation_checked.png icons/clear_left.png icons/clipboard.png icons/configure.png icons/configure_bibtex.png icons/configure_clipboard.png icons/configure_documents.png icons/configure_files.png icons/configure_fonts.png icons/configure_network.png icons/configure_shortcuts.png icons/configure_utilities.png icons/connect_established.png icons/connect_no.png icons/edit-undo.png icons/edit.png icons/edit16.png icons/edit22.png icons/exec22.png icons/exit.png icons/fileclose22.png icons/fileopen22.png icons/filesave22.png icons/filesaveas22.png icons/filesaveas.png icons/filter.png icons/help16.png icons/mimeFolder.png icons/package_network.png icons/pdf.png icons/select.png icons/tex.png icons/viewBackward.png icons/viewForward.png icons/viewHome.png icons/viewReload.png icons/viewZoomIn.png icons/viewZoomOut.png icons/viewbib.png icons/viewcb.png htm/bib_item.html htm/excerpts.html htm/references.css htm/references.html xml/cb2bib.xmp xml/ExifTool_config cb2bib-2.0.1/src/PaxHeaders.5700/c2bCiterExcerptView.cpp0000644000000000000000000000013214011522520017413 xustar0030 mtime=1613145424.386620347 30 atime=1613145424.826620334 30 ctime=1613145424.386620347 cb2bib-2.0.1/src/c2bCiterExcerptView.cpp0000644000175000001440000000455014011522520021016 0ustar00constansusers00000000000000/*************************************************************************** * Copyright (C) 2004-2021 by Pere Constans * constans@molspaces.com * cb2Bib version 2.0.1. Licensed under the GNU GPL version 3. * See the LICENSE file that comes with this distribution. ***************************************************************************/ #include "c2bCiterExcerptView.h" #include "c2bSettings.h" #include "c2bTextBrowser.h" #include "c2bUtils.h" #include c2bCiterExcerptView::c2bCiterExcerptView(const QString& html, QWidget* parentw) : QDialog(parentw) { setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint); setWindowTitle(tr("Document Excerpt - cb2Bib")); QGridLayout* gl; gl = new QGridLayout(this); gl->setContentsMargins(0, 0, 0, 0); _browserP = new c2bTextBrowser(this); gl->addWidget(_browserP, 0, 0, 1, 1); c2bSettings* settings(c2bSettingsP); resize(settings->value("c2bCiterExcerptView/size", QSize(500, 500)).toSize()); move(settings->value("c2bCiterExcerptView/position", pos()).toPoint()); _browserP->setFont(QFont(QFont().family(), settings->value("c2bCiterExcerptView/BrowserFontPointSize", QFont().pointSize()).toInt())); QString css(c2bUtils::fileToString(settings->fileName("cb2Bib/BrowserCssFile"))); if (css.isEmpty()) css = c2bUtils::fileToString(":/htm/htm/references.css"); _browserP->document()->setDefaultStyleSheet(css); QAction* c(new QAction(this)); c->setShortcut(QKeySequence(Qt::Key_Left)); addAction(c); connect(c, SIGNAL(triggered()), this, SLOT(close())); QAction* vzi(new QAction(this)); vzi->setShortcut(QKeySequence(QKeySequence::ZoomIn)); addAction(vzi); connect(vzi, SIGNAL(triggered()), _browserP, SLOT(zoomIn())); QAction* vzo(new QAction(this)); vzo->setShortcut(QKeySequence(QKeySequence::ZoomOut)); addAction(vzo); connect(vzo, SIGNAL(triggered()), _browserP, SLOT(zoomOut())); _browserP->updateHtml(html); } c2bCiterExcerptView::~c2bCiterExcerptView() { c2bSettings* settings(c2bSettingsP); if (!isFullScreen()) { settings->setValue("c2bCiterExcerptView/position", pos()); settings->setValue("c2bCiterExcerptView/size", size()); } settings->setValue("c2bCiterExcerptView/BrowserFontPointSize", _browserP->font().pointSize()); } cb2bib-2.0.1/src/PaxHeaders.5700/bookmarkPlugin.cpp0000644000000000000000000000013214011522520016554 xustar0030 mtime=1613145424.370620347 30 atime=1613145424.818620334 30 ctime=1613145424.370620347 cb2bib-2.0.1/src/bookmarkPlugin.cpp0000644000175000001440000000750314011522520020160 0ustar00constansusers00000000000000/*************************************************************************** * Copyright (C) 2004-2021 by Pere Constans * constans@molspaces.com * cb2Bib version 2.0.1. Licensed under the GNU GPL version 3. * See the LICENSE file that comes with this distribution. ***************************************************************************/ #include "bookmarkPlugin.h" #include "c2b.h" #include "c2bFileSystemWatcher.h" #include "c2bSettings.h" #include "c2bUtils.h" #include bookmarkPlugin::bookmarkPlugin(QWidget* parentw) : QMenu(parentw) { setObjectName(QString::fromUtf8("menuBookmarks")); setTitle(QApplication::translate("c2bEditor", "&Bookmarks", 0)); connect(c2bSettingsP, SIGNAL(newSettings()), this, SLOT(init())); _fsw = new c2bFileSystemWatcher(this); connect(_fsw, SIGNAL(fileChanged(QString)), this, SLOT(parseBookmarks())); init(); } bookmarkPlugin::~bookmarkPlugin() {} void bookmarkPlugin::init() { const QString nfn(c2bSettingsP->fileName("cb2Bib/NetworkFile")); if (nfn == _bookmark_file) return; if (QFileInfo::exists(nfn)) { if (!_bookmark_file.isEmpty()) _fsw->removePath(_bookmark_file); _bookmark_file = nfn; _fsw->addPath(_bookmark_file); } parseBookmarks(); } void bookmarkPlugin::parseBookmarks() { clear(); const QString bmf(c2bUtils::fileToString(_bookmark_file)); QStringList bookmarks(bmf.split(QRegExp("[\\r\\n]"), QString::KeepEmptyParts)); const QRegExp _bookmark("^editorbookmark="); const QRegExp _separator("^editorbookmark=\\s*$"); for (int i = 0; i < bookmarks.count(); ++i) { if (bookmarks.at(i).contains(_separator)) { addSeparator(); continue; } if (bookmarks.at(i).contains(_bookmark)) { bookmarks[i].remove(_bookmark); const QStringList bm_parts(bookmarks.at(i).split('|', QString::KeepEmptyParts)); if (bm_parts.count() != 4) { c2bUtils::warn(tr("bookmarkPlugin::parseBookmarks: Syntax error at '%1'").arg(bookmarks.at(i))); continue; } QAction* act = addAction(bm_parts.at(0), this, SLOT(openBookmark())); act->setData(bm_parts.at(1)); act->setStatusTip(QString("%1 [%2]").arg(bm_parts.at(0), bm_parts.at(1))); act->setShortcut(bm_parts.at(2)); act->setIcon(QIcon(iconProvider(bm_parts.at(1), bm_parts.at(3)))); } } addSeparator(); QAction* edit_bookmarks = addAction(tr("Edit Bookmarks"), this, SIGNAL(editBookmarks())); edit_bookmarks->setStatusTip(tr("Edit bookmarks")); edit_bookmarks->setIcon(QIcon(":/icons/icons/edit.png")); } QString bookmarkPlugin::iconProvider(const QString& fn, const QString& iconFile) { if (!iconFile.isEmpty()) return iconFile; if (fn.contains(QRegExp("\\.(tex|dvi)\\b", Qt::CaseInsensitive))) return ":/icons/icons/application-x-tex.png"; if (fn.contains(QRegExp("\\.(chm|djvu|pdf|ps)\\b", Qt::CaseInsensitive))) return ":/icons/icons/application-x-pdf.png"; if (fn.contains(QRegExp("\\.(htm|html|php)\\b", Qt::CaseInsensitive))) return ":/icons/icons/application-x-html.png"; if (fn.contains(QRegExp("\\.txt\\b", Qt::CaseInsensitive))) return ":/icons/icons/application-x-tex.png"; if (fn.contains(QRegExp("\\.bib\\b", Qt::CaseInsensitive))) return ":/icons/icons/cb2bib.png"; return ":/icons/icons/application-x-none.png"; } void bookmarkPlugin::openBookmark() { QAction* act = static_cast(sender()); if (act) { const QString fn(act->data().toString()); if (fn.endsWith(".bib")) // Open BiBTeX files internally emit openFile(fn); else c2bUtils::openFile(fn, parentWidget()); } } cb2bib-2.0.1/src/PaxHeaders.5700/xml0000644000000000000000000000007414011522151013614 xustar0030 atime=1613145424.838620334 30 ctime=1613145424.306620349 cb2bib-2.0.1/src/xml/0000755000175000001440000000000014011522151015263 5ustar00constansusers00000000000000cb2bib-2.0.1/src/xml/PaxHeaders.5700/ExifTool_config0000644000000000000000000000007414011522151016672 xustar0030 atime=1613145424.838620334 30 ctime=1613145424.306620349 cb2bib-2.0.1/src/xml/ExifTool_config0000644000175000001440000000176114011522151020271 0ustar00constansusers00000000000000%Image::ExifTool::UserDefined::BibTeX = ( GROUPS => { 0 => 'XMP', 1 => 'XMP-bibtex', 2 => 'Reference' }, NAMESPACE => { 'bibtex' => 'https://www.molspaces.com/cb2bib' }, WRITABLE => 'string', type => { }, abstract => { }, address => { }, annote => { }, author => { }, booktitle => { }, chapter => { }, doi => { }, edition => { }, editor => { }, eprint => { }, file => { }, institution => { }, isbn => { }, issn => { }, journal => { }, keywords => { }, month => { }, note => { }, number => { }, organization => { }, pages => { }, publisher => { }, school => { }, series => { }, title => { }, url => { }, volume => { }, year => { }, ); %Image::ExifTool::UserDefined = ( 'Image::ExifTool::XMP::Main' => { bibtex => { SubDirectory => { TagTable => 'Image::ExifTool::UserDefined::BibTeX', }, }, }, ); 1; cb2bib-2.0.1/src/xml/PaxHeaders.5700/cb2bib.xmp0000644000000000000000000000007414011522151015542 xustar0030 atime=1613145424.838620334 30 ctime=1613145424.306620349 cb2bib-2.0.1/src/xml/cb2bib.xmp0000644000175000001440000000072714011522151017142 0ustar00constansusers00000000000000 GET_BIBTEX_TAGS GET_FORMATTED_AUTHOR cb2bib-2.0.1/src/PaxHeaders.5700/c2bFileDialog.h0000644000000000000000000000013214011522520015623 xustar0030 mtime=1613145424.526620343 30 atime=1613145424.830620334 30 ctime=1613145424.526620343 cb2bib-2.0.1/src/c2bFileDialog.h0000644000175000001440000000433614011522520017230 0ustar00constansusers00000000000000/*************************************************************************** * Copyright (C) 2004-2021 by Pere Constans * constans@molspaces.com * cb2Bib version 2.0.1. Licensed under the GNU GPL version 3. * See the LICENSE file that comes with this distribution. ***************************************************************************/ #ifndef C2BFILEDIALOG_H #define C2BFILEDIALOG_H #include class c2bSettings; class c2bFileDialog : public QFileDialog { Q_OBJECT public: static QString getFilename(QWidget* parentw = 0, const QString& caption = QString(), const QString& path = QString(), const QString& filter = QString()); static QString getOpenFilename(QWidget* parentw = 0, const QString& caption = QString(), const QString& path = QString(), const QString& filter = QString()); static QStringList getOpenFilenames(QWidget* parentw = 0, const QString& caption = QString(), const QString& path = QString(), const QString& filter = QString()); static QString getSaveFilename(QWidget* parentw = 0, const QString& caption = QString(), const QString& path = QString(), const QString& filter = QString()); static QString getExistingDirectory(QWidget* parentw = 0, const QString& caption = QString(), const QString& path = QString()); static QString getSystemFilename(QWidget* parentw = 0, const QString& caption = QString(), const QString& path = QString(), const QString& filter = QString()); private: c2bFileDialog(QWidget* parentw, const QString& caption, const QString& fpath, const QString& ffilter); ~c2bFileDialog(); QString _current_file; QString fileName(const QString& path); c2bSettings* settings; static QString _caption(const QString& generic, const QString& caption); static QString _dirpath(const QString& path); static QString _filename(const QString& path); static QString _path(const QString& path); void readSettings(); void writeSettings(); private slots: void accept(); void selectCurrentFile(); }; #endif cb2bib-2.0.1/src/PaxHeaders.5700/c2bPdfImport.h0000644000000000000000000000013214011522520015530 xustar0030 mtime=1613145424.538620342 30 atime=1613145424.830620334 30 ctime=1613145424.542620342 cb2bib-2.0.1/src/c2bPdfImport.h0000644000175000001440000000266314011522520017136 0ustar00constansusers00000000000000/*************************************************************************** * Copyright (C) 2004-2021 by Pere Constans * constans@molspaces.com * cb2Bib version 2.0.1. Licensed under the GNU GPL version 3. * See the LICENSE file that comes with this distribution. ***************************************************************************/ #ifndef C2BPDFIMPORT_H #define C2BPDFIMPORT_H #include "ui_c2bPdfImport.h" #include class c2bSettings; class c2bPdfImport : public QDialog { Q_OBJECT public: explicit c2bPdfImport(QWidget* parentw = 0); ~c2bPdfImport(); QString processedFile; public slots: void processNext(); void referenceExtacted(bool status); void show(); void showMessage(const QString& ms); signals: void fileProcessed(const QString& filename); void saveReferenceRequest(); void setClipboardDisabled(bool disable); void textProcessed(const QString& text); protected: bool event(QEvent* qevent); void dragEnterEvent(QDragEnterEvent* qevent); void dropEvent(QDropEvent* qevent); private slots: void abort(); void help(); void loadSettings(); void processOneFile(); void saveSettings(); void selectFiles(); private: QPushButton* buttonProcess; QPushButton* buttonSelectFiles; Ui::c2bPdfImport ui; bool c2bAutomaticQuery; bool m_aborted; c2bSettings* settings; void processDocument(); }; #endif cb2bib-2.0.1/src/PaxHeaders.5700/c2bFileSystemWatcher.cpp0000644000000000000000000000013214011522520017561 xustar0030 mtime=1613145424.422620346 30 atime=1613145424.826620334 30 ctime=1613145424.422620346 cb2bib-2.0.1/src/c2bFileSystemWatcher.cpp0000644000175000001440000000156714011522520021171 0ustar00constansusers00000000000000/*************************************************************************** * Copyright (C) 2004-2021 by Pere Constans * constans@molspaces.com * cb2Bib version 2.0.1. Licensed under the GNU GPL version 3. * See the LICENSE file that comes with this distribution. ***************************************************************************/ #include "c2bFileSystemWatcher.h" #include /** Workaround to avoid reading a file when external writing has not yet finished */ c2bFileSystemWatcher::c2bFileSystemWatcher(QObject* parento) : QObject(parento) { connect(&_filewatcher, SIGNAL(fileChanged(QString)), this, SLOT(waitForSaved(QString))); } void c2bFileSystemWatcher::waitForSaved(const QString& path) { _path = path; QTimer::singleShot(500, this, SLOT(fileSaved())); } void c2bFileSystemWatcher::fileSaved() { emit fileChanged(_path); } cb2bib-2.0.1/src/PaxHeaders.5700/c2b.h0000644000000000000000000000013214011522520013703 xustar0030 mtime=1613145424.478620344 30 atime=1613145424.826620334 30 ctime=1613145424.478620344 cb2bib-2.0.1/src/c2b.h0000644000175000001440000000563514011522520015313 0ustar00constansusers00000000000000/*************************************************************************** * Copyright (C) 2004-2021 by Pere Constans * constans@molspaces.com * cb2Bib version 2.0.1. Licensed under the GNU GPL version 3. * See the LICENSE file that comes with this distribution. ***************************************************************************/ #ifndef C2B_H #define C2B_H #include "c2bBibParser.h" #include "c2bNetworkQueryInfo.h" #include #include #include class c2bClipboard; class QProgressDialog; class QWidget; class c2b : public QObject { Q_OBJECT public: explicit c2b(QWidget* main, QObject* parento = 0); ~c2b(); // Actions static inline const QString documentMetadata(const QString& fn) { return metaParser()->metadata(fn); } static inline const QString encodeLink(const QString& ln) { return netqinf()->encodeLink(ln); } static inline void showMessage(const QString& message) { instance()->emitMessage(message); } static inline void doSearchInFiles(const QString& string, const QString& fn) { instance()->emitSearchInFiles(string, fn); } // Pointers static inline c2b* instance() { Q_ASSERT_X(_c2b_single_instance, "c2b", "cb2Bib resources were not instantiated"); return _c2b_single_instance; } static inline QWidget* mainWidget() { return instance()->_c2b_main; } static inline c2bClipboard* clipboard() { return instance()->_c2b_clipboard; } static inline network* net() { return instance()->_c2b_network; } static inline c2bNetworkQueryInfo* netqinf() { return instance()->_c2b_netqinf; } static inline c2bBibParser* bibParser() { return instance()->_c2b_bibparser; } static inline metadataParser* metaParser() { return instance()->_c2b_metadataparser; } public slots: static void configure(int index = -1); void exitRequested(); signals: void searchInFiles(const QString& string, const QString& fn); void statusMessage(const QString& message); private: QProgressDialog* _download_progress; QWidget* _c2b_main; c2bBibParser* _c2b_bibparser; c2bClipboard* _c2b_clipboard; c2bNetworkQueryInfo* _c2b_netqinf; metadataParser* _c2b_metadataparser; network* _c2b_network; static c2b* _c2b_single_instance; inline void emitMessage(const QString& message) { emit statusMessage(message); } inline void emitSearchInFiles(const QString& string, const QString& fn) { emit searchInFiles(string, fn); } private slots: void proxyAuthenticationRequired(const QNetworkProxy& proxy, QAuthenticator* auth); void showMessage(const QString& title, const QString& ms); void updateDownloadProgress(qint64 bytesReceived, qint64 bytesTotal); }; #endif cb2bib-2.0.1/src/PaxHeaders.5700/c2bBibHighlighter.cpp0000644000000000000000000000013214011522520017032 xustar0030 mtime=1613145424.374620347 30 atime=1613145424.818620334 30 ctime=1613145424.378620347 cb2bib-2.0.1/src/c2bBibHighlighter.cpp0000644000175000001440000000375514011522520020443 0ustar00constansusers00000000000000/*************************************************************************** * Copyright (C) 2004-2021 by Pere Constans * constans@molspaces.com * cb2Bib version 2.0.1. Licensed under the GNU GPL version 3. * See the LICENSE file that comes with this distribution. ***************************************************************************/ #include "c2bBibHighlighter.h" #include "c2bSettings.h" #include #include c2bBibHighlighter::c2bBibHighlighter(QTextDocument* doc) : QSyntaxHighlighter(doc) { QPalette p; text_color = p.text().color(); c2bSettings* settings(c2bSettingsP); c = &settings->colors; connect(settings, SIGNAL(newSettings()), this, SLOT(rehighlight())); rx0 = QRegExp("[\\{\\}]+"); rx0.setMinimal(true); rx1 = QRegExp("@\\w+"); rx2 = QRegExp("^\\w+"); rx3 = QRegExp("^%.+$"); } c2bBibHighlighter::~c2bBibHighlighter() {} void c2bBibHighlighter::highlightBlock(const QString& text) { const int len(text.length()); setFormat(0, len - 1, text_color); int pos(0); while (pos >= 0) { pos = rx0.indexIn(text, pos); if (pos > -1) { setFormat(pos, rx0.matchedLength(), c->bib_delimiter_color); pos += rx0.matchedLength(); } } pos = 0; while (pos >= 0) { pos = rx1.indexIn(text, pos); if (pos > -1) { setFormat(pos, rx1.matchedLength(), c->bib_reference_type_color); pos += rx1.matchedLength(); } } pos = 0; while (pos >= 0) { pos = rx2.indexIn(text, pos); if (pos > -1) { setFormat(pos, rx2.matchedLength(), c->bib_reference_field_color); pos += rx2.matchedLength(); } } pos = 0; while (pos >= 0) { pos = rx3.indexIn(text, pos); if (pos > -1) { setFormat(pos, rx3.matchedLength(), c->comment_color); pos += rx3.matchedLength(); } } } cb2bib-2.0.1/src/PaxHeaders.5700/c2bSearchInFilesPattern.ui0000644000000000000000000000007414011522151020034 xustar0030 atime=1613145424.830620334 30 ctime=1613145424.302620349 cb2bib-2.0.1/src/c2bSearchInFilesPattern.ui0000644000175000001440000001106014011522151021424 0ustar00constansusers00000000000000 Pere Constans c2bSearchInFilesPattern 0 0 687 83 Pattern 0 0 0 0 6 Qt::Horizontal 6 0 0 0 0 :/icons/icons/clear_left.png:/icons/icons/clear_left.png Qt::Horizontal 16 20 Type: &NOT Scope: 0 0 &Case sensitive Exact Newer Older all c2bLineEdit QLineEdit
    c2bLineEdit.h
    clearB clicked() inputPattern clear() 639 19 402 9 clearB clicked() inputPattern setFocus() 629 27 477 24
    cb2bib-2.0.1/src/PaxHeaders.5700/c2bPdfImport.cpp0000644000000000000000000000013214011522520016063 xustar0030 mtime=1613145424.434620345 30 atime=1613145424.826620334 30 ctime=1613145424.434620345 cb2bib-2.0.1/src/c2bPdfImport.cpp0000644000175000001440000005113214011522520017464 0ustar00constansusers00000000000000/*************************************************************************** * Copyright (C) 2004-2021 by Pere Constans * constans@molspaces.com * cb2Bib version 2.0.1. Licensed under the GNU GPL version 3. * See the LICENSE file that comes with this distribution. ***************************************************************************/ #include "c2bPdfImport.h" #include "c2b.h" #include "c2bFileDialog.h" #include "c2bSettings.h" #include "c2bUtils.h" #include #include #include #include #include #include /** \page pdfimport PDF Reference Import

    GET_TABLE_OF_CONTENTS

    \section intro_automatic_extraction Introduction Articles in PDF or other formats that can be converted to plain text can be processed and indexed by cb2Bib. Files can be selected using the Select Files button, or dragging them from the desktop or the file manager to the PDFImport dialog panel. Files are converted to plain text by using any external translation tool or script. This tool, and optionally its parameters, are set in the cb2Bib configure dialog. See the \ref c2bconf_utilities section for details. Once the file is converted, the text, and optionally, the preparsed metadata, is sent to cb2Bib for reference recognition. This is the usual, two step process. First, text is optionally preprocessed, using a simple set of rules and/or any external script.or tool. See \ref c2bconf_clipboard. Second, text is processed for reference extraction. cb2Bib so far uses two methods. One considers the text as a full pattern, which is checked against the user's set of regular expressions. The better designed are these rules, the best and most reliable will be the extraction. The second method, used when no regular expression matches the text, considers instead a set of predefined subpatterns. See \ref heuristics. At this point users can interact and supervise their references, right before saving them. Allowing user intervention is and has been a design goal in cb2Bib. Therefore, at this point, cb2Bib helps users to check their references. Poorly translated characters, accented letters, 'forgotten' words, or some minor formatting in the titles might be worth considering. See \htmlonly Glyph & Cog's Text Extraction \endhtmlonly for a description on the intricacies of PDF to text conversions. In addition, if too few fields were extracted, one might perform a network query. Say, only the DOI was catch, then there are chances that such a query will fill the remaining fields. The references are saved from the cb2Bib main panel. Once Save is pressed, and depending on the configuration, see \ref c2bconf_documents, the document file will be either renamed, copied, moved or simply linked onto the file field of the reference. If Insert BibTeX metadata to document files is checked, the current reference will also be inserted into the document itself. When several files are going to be indexed, the sequence can be as follows: - Process next after saving\n Once files are load and Process is pressed, the PDFImport dialog can be minimized (but not closed) for convenience. All required operations to completely fill the desired fields (e.g. dynamic bookmarks, open DOI, etc, which might be required if the data in document is not complete) are at this point accessible from the main panel. The link in the file field will be permanent, without regard to which operations (e.g. clipboard copying) are needed, until the reference is saved. The source file can be open at any time by right clicking the file line edit. Once the reference is saved, the next file will be automatically processed. To skip a given document file from saving its reference, press the Process button. - Unsupervised processing\n In this operation mode, all files will be sequentially processed, following the chosen steps and rules. If the processes is successful, the reference is automatically saved, and the next file is processed. If it is not, the file is skipped and no reference is saved. While processing, the clipboard is disabled for safety. Once finished, this box is unchecked, to avoid a possible accidental saving of a void reference. Network queries that require intervention, i.e., whose result is launching a given page, are skipped. The processes follows until all files are processed. However, it will stop to avoid a file being overwritten, as a result of a repeated key. In this case, it will resume after manual renaming and saving. See also \ref commandline, commands --txt2bib and --doc2bib.

     

    \section faq_automatic_extraction Automatic Extraction: Questions and Answers - When does cb2Bib do automatic extractions?\n cb2Bib is conceived as a lightweight tool to extract references and manage bibliographies in a simple, fast, and accurate way. Accuracy is better achieved in semi-automatic extractions. Such extractions are handy, and allow user intervention and verification. However, in cases where one has accumulated a large number of unindexed documents, automatic processing can be convenient. cb2Bib does automatic extraction when, in PDFImport mode, 'Unsupervised processing' is checked, or, in command line mode, when typing cb2bib --doc2bib *.pdf tmp_references.bib, or, on Windows, c2bconsole.exe instead of cb2bib. - Are PDFImport and command line modes equivalent?\n Yes. There are, however, two minor differences. First, PDFImport adds each reference to the current BibTeX file, as this behavior is the normal one in cb2Bib. On the other hand, command line mode will, instead, overwrite tmp_references.bib if it exists, as this is the expected behavior for almost all command line tools. Second, as for now, command line mode does not follow the configuration option 'Check Repeated On Save'. - How do I do automatic extraction?\n To test and learn about automatic extractions, the cb2Bib distribution includes a set of four PDF files that mimic a paper title page. For these files, distribution also includes a regular expression, in file regexps.txt, capable of extracting the reference fields, provided the pdftotex flags are set to their default values. Processing these files, should, therefore, be automatic, and four messages stating Processed as 'PDF Import Example' should be seen in the logs. Note that extractions are configurable. A reading of \ref configuration will provide additional, useful information. - Why some entries are not saved and files not renamed?\n Once you move from the fabricated examples to real cases, you will realize that some of the files, while being processed, are not renamed and their corresponding BibTeX data is not written. For each document file, cb2Bib converts its first page to text, and from this text it attempts to extract the bibliographic reference. By design, when extraction fails, cb2Bib does nothing: no file is moved, no BibTeX is written. This way, you know that the remaining files in the origin directory need special, manual attention. Extractions are seen as failed, unless reliable data is found in the text. - What is reliable data?\n Note that computer processing of natural texts, as extracting the bibliographic data from a title page, is nowadays an approximated procedure. cb2Bib tries several strategies: 1) allow for including user regular expressions very specific to the extraction at hand, 2) use metadata if available, 3) guess what is reasonable, and, based on this, make customized queries. Then, cb2Bib considers extracted data is reliable if i) data comes from a match to an user supplied regular expression ii) document contains BibTeX metadata, or iii) a guess is transformed through a query to formatted bibliographic data. As formatted bibliographic data, cb2Bib understands BibTeX, PubMed XML, arXiv XML, and CR JSON data. In addition, it allows external processing if needed. Other data, metadata, guesses, and guesses on query results are considered unreliable data. - Is metadata reliable data?\n No. Only author, title, and keywords in standard PDF metadata can be mapped to their corresponding bibliographic fields. Furthermore, publishers most often misuse these three keys, placing, for instance, DOI in title, or setting author to, perhaps, the document typesetter. Only BibTeX XMP metadata is considered reliable. If you consider that a set of PDF files does contain reliable data, you may force to accept it using the command line switch --sloppy together with --doc2bib. - How successful is automatic extraction?\n As it follows from the given definition of reliable data, running automatic extractions without adhoc regexps.txt and netqinf.txt files will certainly give a zero success ratio. In practice, scenario 3) often applies: cb2Bib guesses several fields, and, based on the out-of-the-box netqinf.txt file, it obtains from the web either BibTeX, PubMed XML, arXiv XML, or CR JSON data. - What can I do to increase success ratio?\n First, set your favorite journals in file abbreviations.txt. Besides increasing the chances of journal name recognition, it will provide consistency across your BibTeX database. In general, do not write regular expressions to extract directly from the PDF text. Conversion is often poor. Special characters often break lines, thus breaking your regular expressions too. Write customized queries instead. For instance, if your PDFs have DOI in title page, set the simple query \verbatim journal=The Journal of Everything| query=https://dx.doi.org/<> capture_from_query= referenceurl_prefix= referenceurl_sufix= pdfurl_prefix= pdfurl_sufix= action=htm2txt_query \endverbatim then, if it is feasible to extract the reference from the document's web page using a regular expression, include it in file regexps.txt. Note that querying in cb2Bib had been designed having in mind minority fields of research, for which, established databases might not be available. If cb2Bib failed to make reasonable guesses, then, you might consider writing very simple regular expressions to extract directly from the PDF text. For instance, obtain title only. Then, the posterior query step can provide the remaining information. Note also, especially for old documents, journal name is often missing from the paper title page. If in need of processing a series of those papers, consider using a simple script, that, in the cb2Bib preprocessing step, adds this missing information. - Does successful extraction mean accurate extraction?\n No. An extraction is successful if reliable data, as defined above, is found in the text, in the metadata, or in the text returned by a query. Reference accuracy relies on whether or not user regular expressions are robust, BibTeX metadata is correct, a guess is appropriate, a set of queries can correct a partially incorrect guess, and the text returned by a query is accurate. In general, well designed sets of regular expressions are accurate. Publisher's abstract pages and PubMed are accurate. But, some publishers are still using images for non-ASCII characters, and PubMed algorithms may drop author middle names if a given author has 'too many names'. Expect convenience over accuracy on other sources. - Can I use cb2Bib to extract comma separated value CSV references?\n Yes. To automatically import multiple CSV references you will need one regular expression. If you can control CSV export, choose | as separator, since comma might be used, for instance, in titles. The regular expression for \verbatim AuthName1, AuthName2 | Title | 2010 \endverbatim will simply be \verbatim author title year ^([^|]*)\|([^|]*)\|([^|]*)$ \endverbatim The reference file references.csv can then be split to single-line files typing \verbatim split -l 1 references.csv slineref \endverbatim and the command \verbatim cb2bib --txt2bib slineref* references.bib rm -f slineref* \endverbatim will convert references.csv to BibTeX file references.bib */ c2bPdfImport::c2bPdfImport(QWidget* parentw) : QDialog(parentw) { ui.setupUi(this); setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint); settings = c2bSettingsP; loadSettings(); buttonSelectFiles = new QPushButton(tr("&Select Files")); buttonSelectFiles->setStatusTip(tr("Select PDF files. Hint: Files can be dragged and dropped to this window")); buttonSelectFiles->setMouseTracking(true); ui.buttonBox->addButton(buttonSelectFiles, QDialogButtonBox::ActionRole); buttonProcess = new QPushButton(tr("&Process")); ui.buttonBox->addButton(buttonProcess, QDialogButtonBox::ActionRole); ui.buttonBox->button(QDialogButtonBox::Help)->setAutoDefault(false); buttonProcess->setAutoDefault(true); buttonProcess->setDefault(true); buttonProcess->setEnabled(false); buttonSelectFiles->setAutoDefault(true); buttonSelectFiles->setDefault(true); buttonSelectFiles->setFocus(); ui.buttonBox->button(QDialogButtonBox::Abort)->setAutoDefault(false); ui.buttonBox->button(QDialogButtonBox::Abort)->setEnabled(false); m_aborted = false; connect(ui.buttonBox->button(QDialogButtonBox::Abort), SIGNAL(clicked()), this, SLOT(abort())); connect(ui.buttonBox, SIGNAL(helpRequested()), this, SLOT(help())); connect(buttonSelectFiles, SIGNAL(clicked()), this, SLOT(selectFiles())); connect(buttonProcess, SIGNAL(clicked()), this, SLOT(processOneFile())); connect(ui.DoAll, SIGNAL(toggled(bool)), this, SIGNAL(setClipboardDisabled(bool))); connect(c2b::instance(), SIGNAL(statusMessage(QString)), this, SLOT(showMessage(QString))); ui.Log->appendPlainText( tr("PDF to Text converter: %1\nArguments: %2\n") .arg(settings->fileName("c2bPdfImport/Pdf2TextBin"), settings->value("c2bPdfImport/Pdf2TextArg").toString())); showMessage(tr("See cb2Bib install directory for demo c2bPdfImport files.")); } c2bPdfImport::~c2bPdfImport() { emit setClipboardDisabled(false); saveSettings(); } void c2bPdfImport::processOneFile() { // Converting PDF to Text buttonProcess->setEnabled(false); m_aborted = false; ui.buttonBox->button(QDialogButtonBox::Abort)->setEnabled(ui.DoAll->isChecked()); settings->setValue("networkQuery/isSupervised", !ui.DoAll->isChecked()); settings->setValue("cb2Bib/AutomaticQuery", ui.AutomaticQuery->isChecked()); if (ui.PDFlist->currentItem() == 0) return; processedFile = ui.PDFlist->currentItem()->text(); if (ui.OpenFiles->isChecked()) c2bUtils::openFile(processedFile, this); QCoreApplication::processEvents(); processDocument(); } void c2bPdfImport::processNext() { processedFile.clear(); if (m_aborted) { m_aborted = false; return; } if (ui.PDFlist->currentItem() == 0) return; if (ui.DoNextAfterSaving->isChecked() || ui.DoAll->isChecked()) processOneFile(); } void c2bPdfImport::processDocument() { document doc(processedFile, document::FirstPage); QString text(doc.toString()); const QString log(doc.logString()); if (!log.isEmpty()) ui.Log->appendPlainText(log); const QString error(doc.errorString()); if (!error.isEmpty()) ui.Log->appendPlainText(tr("[cb2bib] %1.").arg(error)); QListWidgetItem* item = ui.PDFlist->currentItem(); delete item; if (ui.PDFlist->currentItem() == 0) { buttonProcess->setEnabled(false); ui.buttonBox->button(QDialogButtonBox::Close)->setFocus(); } else { buttonProcess->setEnabled(true); buttonProcess->setFocus(); } QString metadata; if (settings->value("cb2Bib/AddMetadata").toBool()) metadata = c2b::documentMetadata(processedFile); if (text.isEmpty() && metadata.isEmpty()) { if (ui.DoAll->isChecked()) QTimer::singleShot(500, this, SLOT(processNext())); } else { if (settings->value("cb2Bib/PreAppendMetadata").toString() == "prepend") text = metadata + text; else text = text + '\n' + metadata; ui.Log->appendPlainText(tr("[cb2bib] Conversion completed for file %1.").arg(processedFile)); emit textProcessed(text); emit fileProcessed(processedFile); } } void c2bPdfImport::referenceExtacted(bool status) { if (!ui.DoAll->isChecked()) return; if (ui.PDFlist->currentItem() == 0) { ui.DoAll->setChecked(false); ui.buttonBox->button(QDialogButtonBox::Abort)->setEnabled(false); } // Delay request to make sure fileProcessed has finished if (status) QTimer::singleShot(500, this, SIGNAL(saveReferenceRequest())); else QTimer::singleShot(500, this, SLOT(processNext())); } void c2bPdfImport::dropEvent(QDropEvent* qevent) { const QList fns(qevent->mimeData()->urls()); for (int i = 0; i < fns.count(); ++i) { QString scheme(fns.at(i).scheme()); QString fn; if (scheme == "file") fn = fns.at(i).toLocalFile(); if (!fn.isEmpty()) { QListWidgetItem* item(new QListWidgetItem(fn, ui.PDFlist)); if (ui.PDFlist->currentItem() == 0) ui.PDFlist->setCurrentItem(item); } } qevent->acceptProposedAction(); c2bUtils::setWidgetOnTop(this); buttonProcess->setEnabled(true); buttonProcess->setFocus(); showMessage(tr("%1 files selected.").arg(ui.PDFlist->count())); } void c2bPdfImport::dragEnterEvent(QDragEnterEvent* qevent) { if (qevent->mimeData()->hasUrls()) qevent->acceptProposedAction(); } bool c2bPdfImport::event(QEvent* qevent) { if (qevent->type() == QEvent::StatusTip) { ui.statusBar->showMessage(static_cast(qevent)->tip()); return true; } else return QWidget::event(qevent); } void c2bPdfImport::selectFiles() { const QStringList fns(c2bFileDialog::getOpenFilenames(this, QString(), settings->fileName("c2bPdfImport/LastFile"), tr("Portable Document Format (*.pdf);;All (*)"))); if (fns.isEmpty()) return; settings->setFilename("c2bPdfImport/LastFile", fns.last()); for (QStringList::const_iterator i = fns.constBegin(); i != fns.constEnd(); ++i) { QListWidgetItem* item(new QListWidgetItem(*i, ui.PDFlist)); if (ui.PDFlist->currentItem() == 0) ui.PDFlist->setCurrentItem(item); } buttonProcess->setEnabled(true); buttonProcess->setFocus(); showMessage(tr("%1 files selected.").arg(ui.PDFlist->count())); } void c2bPdfImport::show() { c2bUtils::setWidgetOnTop(this); if (buttonProcess->isEnabled()) buttonProcess->setFocus(); else buttonSelectFiles->setFocus(); QDialog::show(); } void c2bPdfImport::showMessage(const QString& ms) { ui.statusBar->showMessage(ms, C2B_MESSAGE_TIME); if (ms.startsWith(tr("Processed as")) || ms.startsWith(tr("Unable"))) ui.Log->appendPlainText("[cb2bib] " + ms); } void c2bPdfImport::loadSettings() { c2bAutomaticQuery = settings->value("cb2Bib/AutomaticQuery").toBool(); ui.AutomaticQuery->setChecked(settings->value("c2bPdfImport/AutomaticQuery").toBool()); ui.DoNextAfterSaving->setChecked(settings->value("c2bPdfImport/DoNextAfterSaving", true).toBool()); ui.OpenFiles->setChecked(settings->value("c2bPdfImport/OpenFiles", false).toBool()); } void c2bPdfImport::saveSettings() { settings->setValue("c2bPdfImport/AutomaticQuery", ui.AutomaticQuery->isChecked()); settings->setValue("c2bPdfImport/DoNextAfterSaving", ui.DoNextAfterSaving->isChecked()); settings->setValue("c2bPdfImport/OpenFiles", ui.OpenFiles->isChecked()); settings->setValue("cb2Bib/AutomaticQuery", c2bAutomaticQuery); settings->setValue("networkQuery/isSupervised", true); } void c2bPdfImport::abort() { m_aborted = true; ui.DoAll->setChecked(false); ui.buttonBox->button(QDialogButtonBox::Abort)->setEnabled(false); } void c2bPdfImport::help() { c2bUtils::displayHelp("https://www.molspaces.com/cb2bib/doc/pdfimport/"); } cb2bib-2.0.1/src/PaxHeaders.5700/c2bCollectionIndex.cpp0000644000000000000000000000013214011522520017242 xustar0030 mtime=1613145424.398620346 30 atime=1613145424.826620334 30 ctime=1613145424.398620346 cb2bib-2.0.1/src/c2bCollectionIndex.cpp0000644000175000001440000000672114011522520020647 0ustar00constansusers00000000000000/*************************************************************************** * Copyright (C) 2004-2021 by Pere Constans * constans@molspaces.com * cb2Bib version 2.0.1. Licensed under the GNU GPL version 3. * See the LICENSE file that comes with this distribution. ***************************************************************************/ #include "c2bCollectionIndex.h" #include "c2bSettings.h" #include "c2bUtils.h" #include c2bCollectionIndex::c2bCollectionIndex(QWidget* parentw) : QDialog(parentw), _indexerP(0) { ui.setupUi(this); setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint); setWindowTitle(tr("Documents Indexing Log - cb2Bib")); ui.Log->setFont(c2bSettingsP->c2bMonoFont); ui.Log->setLineWrapMode(QPlainTextEdit::NoWrap); _buttonAbort = new QPushButton(tr("Abort")); ui.buttonBox->addButton(_buttonAbort, QDialogButtonBox::ActionRole); connect(_buttonAbort, SIGNAL(clicked()), this, SLOT(aborted())); connect(ui.buttonBox, SIGNAL(helpRequested()), this, SLOT(help())); resize(c2bSettingsP->value("c2bLogWidget/size", size()).toSize()); } c2bCollectionIndex::~c2bCollectionIndex() { c2bSettingsP->setValue("c2bLogWidget/size", size()); } void c2bCollectionIndex::index() { ui.Log->clear(); ui.buttonBox->button(QDialogButtonBox::Close)->setEnabled(false); _indexerP = new QProcess(this); _indexerP->setProcessChannelMode(QProcess::MergedChannels); connect(_indexerP, SIGNAL(finished(int,QProcess::ExitStatus)), this, SLOT(indexingEnded(int,QProcess::ExitStatus))); connect(_indexerP, SIGNAL(readyReadStandardOutput()), this, SLOT(addToLog())); const QStringList flags(QStringList() << "--index" << c2bSettingsP->confCommandFlags()); _indexerP->start(QCoreApplication::applicationFilePath(), flags); if (!_indexerP->waitForStarted()) { ui.Log->appendPlainText(tr("Failed to call %1.").arg(QCoreApplication::applicationFilePath())); _buttonAbort->setEnabled(false); ui.buttonBox->button(QDialogButtonBox::Close)->setEnabled(true); ui.buttonBox->button(QDialogButtonBox::Close)->setFocus(); delete _indexerP; _indexerP = 0; } } void c2bCollectionIndex::addToLog() { const QString log(QString::fromUtf8(_indexerP->readAllStandardOutput().trimmed())); if (log.isEmpty()) return; ui.Log->appendPlainText(log); } void c2bCollectionIndex::indexingEnded(int exit_code, QProcess::ExitStatus exit_status) { _buttonAbort->setEnabled(false); ui.buttonBox->button(QDialogButtonBox::Close)->setEnabled(true); ui.buttonBox->button(QDialogButtonBox::Close)->setFocus(); if (exit_code == 0 && exit_status == QProcess::NormalExit) ui.Log->appendPlainText(tr("\nIndexing ended\nRefresh cb2Bib Citer")); else ui.Log->appendPlainText(tr("\nAbnormal termination")); delete _indexerP; _indexerP = 0; } void c2bCollectionIndex::aborted() { if (_indexerP) _indexerP->kill(); ui.Log->appendPlainText(tr("Aborting...")); } void c2bCollectionIndex::closeEvent(QCloseEvent* qevent) { if (!_indexerP || _indexerP->state() == QProcess::NotRunning) QDialog::closeEvent(qevent); else qevent->ignore(); } void c2bCollectionIndex::reject() { if (!_indexerP || _indexerP->state() == QProcess::NotRunning) QDialog::reject(); } void c2bCollectionIndex::help() { c2bUtils::displayHelp("https://www.molspaces.com/cb2bib/doc/c2bciter/"); } cb2bib-2.0.1/src/PaxHeaders.5700/c2bEditor.ui0000644000000000000000000000007414011522151015245 xustar0030 atime=1613145424.830620334 30 ctime=1613145424.302620349 cb2bib-2.0.1/src/c2bEditor.ui0000644000175000001440000002454014011522151016644 0ustar00constansusers00000000000000 Pere Constans c2bEditor 0 0 801 600 Editor - cb2Bib 0 0 801 30 &Help &Edit &View &Settings &File Tools Qt::Horizontal TopToolBarArea false :/icons/icons/filesave22.png:/icons/icons/filesave22.png Save Save :/icons/icons/filesaveas22.png:/icons/icons/filesaveas22.png Save As... Save As Save As Save as... :/icons/icons/exec22.png:/icons/icons/exec22.png Exec :/icons/icons/fileclose22.png:/icons/icons/fileclose22.png Close Document Close Document Close Document Close document :/icons/icons/exit.png:/icons/icons/exit.png Exit Exit cb2Bib Exit cb2Bib Exit cb2Bib :/icons/icons/help16.png:/icons/icons/help16.png Editor Help Editor Help Editor Help Editor context help :/icons/icons/cb2bib22.png:/icons/icons/cb2bib22.png Toggle cb2Bib Toggle cb2Bib Toggle cb2Bib F2 Set LyX Pipe Set active LyX pipe Set LyX pipe Set active LyX pipe true :/icons/icons/edit22.png:/icons/icons/edit22.png Toggle Editing and Browsing Toggle Editing and Browsing Toggle Editing and Browsing Toggle editing and browsing modes false :/icons/icons/viewZoomIn.png:/icons/icons/viewZoomIn.png Zoom In Zoom in false :/icons/icons/viewZoomOut.png:/icons/icons/viewZoomOut.png Zoom Out Zoom out false :/icons/icons/cb2bib22.png:/icons/icons/cb2bib22.png cb2Bib Help cb2Bib Help cb2Bib Help cb2Bib context help Shift+F1 :/icons/icons/configure.png:/icons/icons/configure.png cb2Bib Settings cb2Bib Settings cb2Bib Settings cb2Bib settings :/icons/icons/fileopen22.png:/icons/icons/fileopen22.png Open Open Open document false false :/icons/icons/configure_bibtex.png:/icons/icons/configure_bibtex.png Export Entries Export Entries Export Entries Export selected entries false cb2bib-2.0.1/src/PaxHeaders.5700/win0000644000000000000000000000013214011522520013604 xustar0030 mtime=1613145424.794620335 30 atime=1613145424.838620334 30 ctime=1613145424.794620335 cb2bib-2.0.1/src/win/0000755000175000001440000000000014011522520015260 5ustar00constansusers00000000000000cb2bib-2.0.1/src/win/PaxHeaders.5700/WinConsole.cpp0000644000000000000000000000013214011522520016445 xustar0030 mtime=1613145424.790620335 30 atime=1613145424.838620334 30 ctime=1613145424.790620335 cb2bib-2.0.1/src/win/WinConsole.cpp0000644000175000001440000000307214011522520020046 0ustar00constansusers00000000000000/*************************************************************************** * Copyright (C) 2004-2021 by Pere Constans * constans@molspaces.com * cb2Bib version 2.0.1. Licensed under the GNU GPL version 3. * See the LICENSE file that comes with this distribution. ***************************************************************************/ #include "WinConsole.h" #include #include #include #include #include WinConsole::WinConsole(QObject* parento) : QObject(parento) { // Exclude _setmode on older Windows consoles if (int(QSysInfo::productVersion().toDouble()) > 7) { try { fflush(stdout); _setmode(_fileno(stdout), _O_U16TEXT); } catch (...) { fflush(stdout); _setmode(_fileno(stdout), _O_TEXT); } } } WinConsole::~WinConsole() {} int WinConsole::execute(const QString& program, const QStringList& arguments) { QEventLoop eventloop(this); _process.setProcessChannelMode(QProcess::MergedChannels); connect(&_process, SIGNAL(readyReadStandardOutput()), this, SLOT(output())); connect(&_process, SIGNAL(finished(int,QProcess::ExitStatus)), &eventloop, SLOT(quit())); _process.start(program, arguments); if (_process.waitForStarted()) eventloop.exec(); output(); std::wcout << std::endl; return _process.exitCode(); } void WinConsole::output() { while (_process.canReadLine()) std::wcout << QString::fromUtf8(_process.readLine()).toStdWString(); } cb2bib-2.0.1/src/win/PaxHeaders.5700/win.pro0000644000000000000000000000007414011522151015205 xustar0030 atime=1613145424.838620334 30 ctime=1613145424.306620349 cb2bib-2.0.1/src/win/win.pro0000644000175000001440000000021514011522151016575 0ustar00constansusers00000000000000QT = core CONFIG += c++11 CONFIG += console TEMPLATE = app TARGET = ../c2bconsole HEADERS += WinConsole.h SOURCES += WinConsole.cpp main.cpp cb2bib-2.0.1/src/win/PaxHeaders.5700/WinConsole.h0000644000000000000000000000013214011522520016112 xustar0030 mtime=1613145424.794620335 30 atime=1613145424.838620334 30 ctime=1613145424.794620335 cb2bib-2.0.1/src/win/WinConsole.h0000644000175000001440000000127314011522520017514 0ustar00constansusers00000000000000/*************************************************************************** * Copyright (C) 2004-2021 by Pere Constans * constans@molspaces.com * cb2Bib version 2.0.1. Licensed under the GNU GPL version 3. * See the LICENSE file that comes with this distribution. ***************************************************************************/ #ifndef WINCONSOLE_H #define WINCONSOLE_H #include class WinConsole : public QObject { Q_OBJECT public: explicit WinConsole(QObject* parento = 0); ~WinConsole(); int execute(const QString& program, const QStringList& arguments); private slots: void output(); private: QProcess _process; }; #endif cb2bib-2.0.1/src/win/PaxHeaders.5700/main.cpp0000644000000000000000000000013214011522520015311 xustar0030 mtime=1613145424.786620335 30 atime=1613145424.838620334 30 ctime=1613145424.790620335 cb2bib-2.0.1/src/win/main.cpp0000644000175000001440000000144514011522520016714 0ustar00constansusers00000000000000/*************************************************************************** * Copyright (C) 2004-2021 by Pere Constans * constans@molspaces.com * cb2Bib version 2.0.1. Licensed under the GNU GPL version 3. * See the LICENSE file that comes with this distribution. ***************************************************************************/ #include "WinConsole.h" #include #include int main(int argc, char* argv[]) { if (argc < 1) return 1; QFileInfo fi(argv[0]); const QString exe(fi.absolutePath() + "/cb2bib.exe"); QStringList arguments; for (int i = 1; i < argc; ++i) arguments.append(argv[i]); QCoreApplication a(argc, argv); WinConsole wc; const int code(wc.execute(exe, arguments)); return code; } cb2bib-2.0.1/PaxHeaders.5700/cb2bib.rc0000644000000000000000000000007414011522151013753 xustar0030 atime=1613145424.814620334 30 ctime=1613145424.298620349 cb2bib-2.0.1/cb2bib.rc0000644000175000001440000000010714011522151015343 0ustar00constansusers00000000000000IDI_ICON1 ICON DISCARDABLE "src/icons/cb2bib.ico" cb2bib-2.0.1/PaxHeaders.5700/xpdf0000644000000000000000000000007414011522151013166 xustar0030 atime=1613145424.838620334 30 ctime=1613145424.306620349 cb2bib-2.0.1/xpdf/0000755000175000001440000000000014011522151014635 5ustar00constansusers00000000000000cb2bib-2.0.1/xpdf/PaxHeaders.5700/pdftohtml.cc0000644000000000000000000000007414011522151015553 xustar0030 atime=1613145424.838620334 30 ctime=1613145424.306620349 cb2bib-2.0.1/xpdf/pdftohtml.cc0000644000175000001440000001161214011522151017146 0ustar00constansusers00000000000000//======================================================================== // // Modified pdftohtml (constans@molspaces.com, 2014) // // pdftohtml.cc // // Copyright 2005 Glyph & Cog, LLC // //======================================================================== #include #include #include #include "parseargs.h" #include "gmem.h" #include "gfile.h" #include "GString.h" #include "GlobalParams.h" #include "PDFDoc.h" #include "HTMLGen.h" #include "Error.h" #include "ErrorCodes.h" #include "config.h" //------------------------------------------------------------------------ static int firstPage = 1; static int lastPage = 0; static GBool skipInvisible = gFalse; static char ownerPassword[33] = "\001"; static char userPassword[33] = "\001"; static GBool quiet = gFalse; static char cfgFileName[256] = ""; static GBool printVersion = gFalse; static GBool printHelp = gFalse; static ArgDesc argDesc[] = { { "-f", argInt, &firstPage, 0, "first page to convert" }, { "-l", argInt, &lastPage, 0, "last page to convert" }, { "-skipinvisible", argFlag, &skipInvisible, 0, "do not draw invisible text" }, { "-opw", argString, ownerPassword, sizeof(ownerPassword), "owner password (for encrypted files)" }, { "-upw", argString, userPassword, sizeof(userPassword), "user password (for encrypted files)" }, { "-q", argFlag, &quiet, 0, "don't print any messages or errors" }, { "-cfg", argString, cfgFileName, sizeof(cfgFileName), "configuration file to use in place of .xpdfrc" }, { "-v", argFlag, &printVersion, 0, "print copyright and version info" }, { "-h", argFlag, &printHelp, 0, "print usage information" }, { "-help", argFlag, &printHelp, 0, "print usage information" }, { "--help", argFlag, &printHelp, 0, "print usage information" }, { "-?", argFlag, &printHelp, 0, "print usage information" }, {NULL} }; //------------------------------------------------------------------------ static int writeToFile(void* file, const char* data, int size) { return (int)fwrite(data, 1, size, (FILE*)file); } int main(int argc, char* argv[]) { PDFDoc* doc; GString* fileName; GString* ownerPW, *userPW; HTMLGen* htmlGen; GString* htmlFileName; FILE* htmlFile; int pg, err, exitCode; GBool ok; exitCode = 99; // parse args ok = parseArgs(argDesc, &argc, argv); if (!ok || argc != 3 || printVersion || printHelp) { fprintf(stderr, "\npdf2cb (a modified pdftohtml version %s for cb2bib)\n", xpdfVersion); fprintf(stderr, "\n%s\n", xpdfCopyright); if (!printVersion) { printUsage("pdf2cb", " ", argDesc); } goto err0; } fileName = new GString(argv[1]); htmlFileName = new GString(argv[2]); // read config file globalParams = new GlobalParams(cfgFileName); if (quiet) { globalParams->setErrQuiet(quiet); } globalParams->setupBaseFonts(NULL); globalParams->setTextEncoding("UTF-8"); // open PDF file if (ownerPassword[0] != '\001') ownerPW = new GString(ownerPassword); else ownerPW = NULL; if (userPassword[0] != '\001') userPW = new GString(userPassword); else userPW = NULL; doc = new PDFDoc(fileName, ownerPW, userPW); if (userPW) delete userPW; if (ownerPW) delete ownerPW; if (!doc->isOk()) { exitCode = 1; goto err1; } // check for copy permission if (!doc->okToCopy()) { error(errNotAllowed, -1, "Copying of text from this document is not allowed."); exitCode = 3; goto err1; } // get page range if (firstPage < 1) { firstPage = 1; } if (lastPage < 1 || lastPage > doc->getNumPages()) { lastPage = doc->getNumPages(); } // set up the HTMLGen object htmlGen = new HTMLGen(); if (!htmlGen->isOk()) { exitCode = 99; goto err1; } htmlGen->setDrawInvisibleText(!skipInvisible); htmlGen->startDoc(doc); if (!(htmlFile = fopen(htmlFileName->getCString(), "wb"))) { error(errIO, -1, "Couldn't open TXT file '{0:t}'", htmlFileName); goto err2; } // convert the pages for (pg = firstPage; pg <= lastPage; ++pg) { err = htmlGen->convertPage(pg, writeToFile, htmlFile); if (err != errNone) { error(errIO, -1, "Error converting page {0:d}", pg); exitCode = 2; goto err2; } } fclose(htmlFile); exitCode = 0; // clean up err2: delete htmlFileName; delete htmlGen; err1: delete doc; delete globalParams; err0: // check for memory leaks Object::memCheck(stderr); gMemReport(stderr); return exitCode; } cb2bib-2.0.1/xpdf/PaxHeaders.5700/HTMLGen.h0000644000000000000000000000007414011522151014612 xustar0030 atime=1613145424.838620334 30 ctime=1613145424.306620349 cb2bib-2.0.1/xpdf/HTMLGen.h0000644000175000001440000000216014011522151016203 0ustar00constansusers00000000000000//======================================================================== // // Modified pdftohtml (constans@molspaces.com, 2014) // // HTMLGen.h // // Copyright 2010 Glyph & Cog, LLC // //======================================================================== #ifndef HTMLGEN_H #define HTMLGEN_H #include #ifdef USE_GCC_PRAGMAS #pragma interface #endif class PDFDoc; class TextOutputDev; class SplashOutputDev; //------------------------------------------------------------------------ class HTMLGen { public: HTMLGen(); ~HTMLGen(); GBool isOk() const { return ok; } GBool getDrawInvisibleText() const { return drawInvisibleText; } void setDrawInvisibleText(GBool drawInvisibleTextA) { drawInvisibleText = drawInvisibleTextA; } void startDoc(PDFDoc* docA); int convertPage(int pg, int (*writeHTML)(void* stream, const char* data, int size), void* htmlStream); private: double backgroundResolution; GBool drawInvisibleText; PDFDoc* doc; TextOutputDev* textOut; SplashOutputDev* splashOut; GBool ok; }; #endif cb2bib-2.0.1/xpdf/PaxHeaders.5700/COPYING30000644000000000000000000000007414011522151014361 xustar0030 atime=1613145424.838620334 30 ctime=1613145424.306620349 cb2bib-2.0.1/xpdf/COPYING30000644000175000001440000010451314011522151015757 0ustar00constansusers00000000000000 GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007 Copyright (C) 2007 Free Software Foundation, Inc. Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The GNU General Public License is a free, copyleft license for software and other kinds of works. The licenses for most software and other practical works are designed to take away your freedom to share and change the works. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change all versions of a program--to make sure it remains free software for all its users. We, the Free Software Foundation, use the GNU General Public License for most of our software; it applies also to any other work released this way by its authors. You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for them if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs, and that you know you can do these things. To protect your rights, we need to prevent others from denying you these rights or asking you to surrender the rights. Therefore, you have certain responsibilities if you distribute copies of the software, or if you modify it: responsibilities to respect the freedom of others. For example, if you distribute copies of such a program, whether gratis or for a fee, you must pass on to the recipients the same freedoms that you received. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. Developers that use the GNU GPL protect your rights with two steps: (1) assert copyright on the software, and (2) offer you this License giving you legal permission to copy, distribute and/or modify it. For the developers' and authors' protection, the GPL clearly explains that there is no warranty for this free software. For both users' and authors' sake, the GPL requires that modified versions be marked as changed, so that their problems will not be attributed erroneously to authors of previous versions. Some devices are designed to deny users access to install or run modified versions of the software inside them, although the manufacturer can do so. This is fundamentally incompatible with the aim of protecting users' freedom to change the software. The systematic pattern of such abuse occurs in the area of products for individuals to use, which is precisely where it is most unacceptable. Therefore, we have designed this version of the GPL to prohibit the practice for those products. If such problems arise substantially in other domains, we stand ready to extend this provision to those domains in future versions of the GPL, as needed to protect the freedom of users. Finally, every program is threatened constantly by software patents. States should not allow patents to restrict development and use of software on general-purpose computers, but in those that do, we wish to avoid the special danger that patents applied to a free program could make it effectively proprietary. To prevent this, the GPL assures that patents cannot be used to render the program non-free. The precise terms and conditions for copying, distribution and modification follow. TERMS AND CONDITIONS 0. Definitions. "This License" refers to version 3 of the GNU General Public License. "Copyright" also means copyright-like laws that apply to other kinds of works, such as semiconductor masks. "The Program" refers to any copyrightable work licensed under this License. Each licensee is addressed as "you". "Licensees" and "recipients" may be individuals or organizations. To "modify" a work means to copy from or adapt all or part of the work in a fashion requiring copyright permission, other than the making of an exact copy. The resulting work is called a "modified version" of the earlier work or a work "based on" the earlier work. A "covered work" means either the unmodified Program or a work based on the Program. To "propagate" a work means to do anything with it that, without permission, would make you directly or secondarily liable for infringement under applicable copyright law, except executing it on a computer or modifying a private copy. Propagation includes copying, distribution (with or without modification), making available to the public, and in some countries other activities as well. To "convey" a work means any kind of propagation that enables other parties to make or receive copies. Mere interaction with a user through a computer network, with no transfer of a copy, is not conveying. An interactive user interface displays "Appropriate Legal Notices" to the extent that it includes a convenient and prominently visible feature that (1) displays an appropriate copyright notice, and (2) tells the user that there is no warranty for the work (except to the extent that warranties are provided), that licensees may convey the work under this License, and how to view a copy of this License. If the interface presents a list of user commands or options, such as a menu, a prominent item in the list meets this criterion. 1. Source Code. The "source code" for a work means the preferred form of the work for making modifications to it. "Object code" means any non-source form of a work. A "Standard Interface" means an interface that either is an official standard defined by a recognized standards body, or, in the case of interfaces specified for a particular programming language, one that is widely used among developers working in that language. The "System Libraries" of an executable work include anything, other than the work as a whole, that (a) is included in the normal form of packaging a Major Component, but which is not part of that Major Component, and (b) serves only to enable use of the work with that Major Component, or to implement a Standard Interface for which an implementation is available to the public in source code form. A "Major Component", in this context, means a major essential component (kernel, window system, and so on) of the specific operating system (if any) on which the executable work runs, or a compiler used to produce the work, or an object code interpreter used to run it. The "Corresponding Source" for a work in object code form means all the source code needed to generate, install, and (for an executable work) run the object code and to modify the work, including scripts to control those activities. However, it does not include the work's System Libraries, or general-purpose tools or generally available free programs which are used unmodified in performing those activities but which are not part of the work. For example, Corresponding Source includes interface definition files associated with source files for the work, and the source code for shared libraries and dynamically linked subprograms that the work is specifically designed to require, such as by intimate data communication or control flow between those subprograms and other parts of the work. The Corresponding Source need not include anything that users can regenerate automatically from other parts of the Corresponding Source. The Corresponding Source for a work in source code form is that same work. 2. Basic Permissions. All rights granted under this License are granted for the term of copyright on the Program, and are irrevocable provided the stated conditions are met. This License explicitly affirms your unlimited permission to run the unmodified Program. The output from running a covered work is covered by this License only if the output, given its content, constitutes a covered work. This License acknowledges your rights of fair use or other equivalent, as provided by copyright law. You may make, run and propagate covered works that you do not convey, without conditions so long as your license otherwise remains in force. You may convey covered works to others for the sole purpose of having them make modifications exclusively for you, or provide you with facilities for running those works, provided that you comply with the terms of this License in conveying all material for which you do not control copyright. Those thus making or running the covered works for you must do so exclusively on your behalf, under your direction and control, on terms that prohibit them from making any copies of your copyrighted material outside their relationship with you. Conveying under any other circumstances is permitted solely under the conditions stated below. Sublicensing is not allowed; section 10 makes it unnecessary. 3. Protecting Users' Legal Rights From Anti-Circumvention Law. No covered work shall be deemed part of an effective technological measure under any applicable law fulfilling obligations under article 11 of the WIPO copyright treaty adopted on 20 December 1996, or similar laws prohibiting or restricting circumvention of such measures. When you convey a covered work, you waive any legal power to forbid circumvention of technological measures to the extent such circumvention is effected by exercising rights under this License with respect to the covered work, and you disclaim any intention to limit operation or modification of the work as a means of enforcing, against the work's users, your or third parties' legal rights to forbid circumvention of technological measures. 4. Conveying Verbatim Copies. You may convey verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice; keep intact all notices stating that this License and any non-permissive terms added in accord with section 7 apply to the code; keep intact all notices of the absence of any warranty; and give all recipients a copy of this License along with the Program. You may charge any price or no price for each copy that you convey, and you may offer support or warranty protection for a fee. 5. Conveying Modified Source Versions. You may convey a work based on the Program, or the modifications to produce it from the Program, in the form of source code under the terms of section 4, provided that you also meet all of these conditions: a) The work must carry prominent notices stating that you modified it, and giving a relevant date. b) The work must carry prominent notices stating that it is released under this License and any conditions added under section 7. This requirement modifies the requirement in section 4 to "keep intact all notices". c) You must license the entire work, as a whole, under this License to anyone who comes into possession of a copy. This License will therefore apply, along with any applicable section 7 additional terms, to the whole of the work, and all its parts, regardless of how they are packaged. This License gives no permission to license the work in any other way, but it does not invalidate such permission if you have separately received it. d) If the work has interactive user interfaces, each must display Appropriate Legal Notices; however, if the Program has interactive interfaces that do not display Appropriate Legal Notices, your work need not make them do so. A compilation of a covered work with other separate and independent works, which are not by their nature extensions of the covered work, and which are not combined with it such as to form a larger program, in or on a volume of a storage or distribution medium, is called an "aggregate" if the compilation and its resulting copyright are not used to limit the access or legal rights of the compilation's users beyond what the individual works permit. Inclusion of a covered work in an aggregate does not cause this License to apply to the other parts of the aggregate. 6. Conveying Non-Source Forms. You may convey a covered work in object code form under the terms of sections 4 and 5, provided that you also convey the machine-readable Corresponding Source under the terms of this License, in one of these ways: a) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by the Corresponding Source fixed on a durable physical medium customarily used for software interchange. b) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by a written offer, valid for at least three years and valid for as long as you offer spare parts or customer support for that product model, to give anyone who possesses the object code either (1) a copy of the Corresponding Source for all the software in the product that is covered by this License, on a durable physical medium customarily used for software interchange, for a price no more than your reasonable cost of physically performing this conveying of source, or (2) access to copy the Corresponding Source from a network server at no charge. c) Convey individual copies of the object code with a copy of the written offer to provide the Corresponding Source. This alternative is allowed only occasionally and noncommercially, and only if you received the object code with such an offer, in accord with subsection 6b. d) Convey the object code by offering access from a designated place (gratis or for a charge), and offer equivalent access to the Corresponding Source in the same way through the same place at no further charge. You need not require recipients to copy the Corresponding Source along with the object code. If the place to copy the object code is a network server, the Corresponding Source may be on a different server (operated by you or a third party) that supports equivalent copying facilities, provided you maintain clear directions next to the object code saying where to find the Corresponding Source. Regardless of what server hosts the Corresponding Source, you remain obligated to ensure that it is available for as long as needed to satisfy these requirements. e) Convey the object code using peer-to-peer transmission, provided you inform other peers where the object code and Corresponding Source of the work are being offered to the general public at no charge under subsection 6d. A separable portion of the object code, whose source code is excluded from the Corresponding Source as a System Library, need not be included in conveying the object code work. A "User Product" is either (1) a "consumer product", which means any tangible personal property which is normally used for personal, family, or household purposes, or (2) anything designed or sold for incorporation into a dwelling. In determining whether a product is a consumer product, doubtful cases shall be resolved in favor of coverage. For a particular product received by a particular user, "normally used" refers to a typical or common use of that class of product, regardless of the status of the particular user or of the way in which the particular user actually uses, or expects or is expected to use, the product. A product is a consumer product regardless of whether the product has substantial commercial, industrial or non-consumer uses, unless such uses represent the only significant mode of use of the product. "Installation Information" for a User Product means any methods, procedures, authorization keys, or other information required to install and execute modified versions of a covered work in that User Product from a modified version of its Corresponding Source. The information must suffice to ensure that the continued functioning of the modified object code is in no case prevented or interfered with solely because modification has been made. If you convey an object code work under this section in, or with, or specifically for use in, a User Product, and the conveying occurs as part of a transaction in which the right of possession and use of the User Product is transferred to the recipient in perpetuity or for a fixed term (regardless of how the transaction is characterized), the Corresponding Source conveyed under this section must be accompanied by the Installation Information. But this requirement does not apply if neither you nor any third party retains the ability to install modified object code on the User Product (for example, the work has been installed in ROM). The requirement to provide Installation Information does not include a requirement to continue to provide support service, warranty, or updates for a work that has been modified or installed by the recipient, or for the User Product in which it has been modified or installed. Access to a network may be denied when the modification itself materially and adversely affects the operation of the network or violates the rules and protocols for communication across the network. Corresponding Source conveyed, and Installation Information provided, in accord with this section must be in a format that is publicly documented (and with an implementation available to the public in source code form), and must require no special password or key for unpacking, reading or copying. 7. Additional Terms. "Additional permissions" are terms that supplement the terms of this License by making exceptions from one or more of its conditions. Additional permissions that are applicable to the entire Program shall be treated as though they were included in this License, to the extent that they are valid under applicable law. If additional permissions apply only to part of the Program, that part may be used separately under those permissions, but the entire Program remains governed by this License without regard to the additional permissions. When you convey a copy of a covered work, you may at your option remove any additional permissions from that copy, or from any part of it. (Additional permissions may be written to require their own removal in certain cases when you modify the work.) You may place additional permissions on material, added by you to a covered work, for which you have or can give appropriate copyright permission. Notwithstanding any other provision of this License, for material you add to a covered work, you may (if authorized by the copyright holders of that material) supplement the terms of this License with terms: a) Disclaiming warranty or limiting liability differently from the terms of sections 15 and 16 of this License; or b) Requiring preservation of specified reasonable legal notices or author attributions in that material or in the Appropriate Legal Notices displayed by works containing it; or c) Prohibiting misrepresentation of the origin of that material, or requiring that modified versions of such material be marked in reasonable ways as different from the original version; or d) Limiting the use for publicity purposes of names of licensors or authors of the material; or e) Declining to grant rights under trademark law for use of some trade names, trademarks, or service marks; or f) Requiring indemnification of licensors and authors of that material by anyone who conveys the material (or modified versions of it) with contractual assumptions of liability to the recipient, for any liability that these contractual assumptions directly impose on those licensors and authors. All other non-permissive additional terms are considered "further restrictions" within the meaning of section 10. If the Program as you received it, or any part of it, contains a notice stating that it is governed by this License along with a term that is a further restriction, you may remove that term. If a license document contains a further restriction but permits relicensing or conveying under this License, you may add to a covered work material governed by the terms of that license document, provided that the further restriction does not survive such relicensing or conveying. If you add terms to a covered work in accord with this section, you must place, in the relevant source files, a statement of the additional terms that apply to those files, or a notice indicating where to find the applicable terms. Additional terms, permissive or non-permissive, may be stated in the form of a separately written license, or stated as exceptions; the above requirements apply either way. 8. Termination. You may not propagate or modify a covered work except as expressly provided under this License. Any attempt otherwise to propagate or modify it is void, and will automatically terminate your rights under this License (including any patent licenses granted under the third paragraph of section 11). However, if you cease all violation of this License, then your license from a particular copyright holder is reinstated (a) provisionally, unless and until the copyright holder explicitly and finally terminates your license, and (b) permanently, if the copyright holder fails to notify you of the violation by some reasonable means prior to 60 days after the cessation. Moreover, your license from a particular copyright holder is reinstated permanently if the copyright holder notifies you of the violation by some reasonable means, this is the first time you have received notice of violation of this License (for any work) from that copyright holder, and you cure the violation prior to 30 days after your receipt of the notice. Termination of your rights under this section does not terminate the licenses of parties who have received copies or rights from you under this License. If your rights have been terminated and not permanently reinstated, you do not qualify to receive new licenses for the same material under section 10. 9. Acceptance Not Required for Having Copies. You are not required to accept this License in order to receive or run a copy of the Program. Ancillary propagation of a covered work occurring solely as a consequence of using peer-to-peer transmission to receive a copy likewise does not require acceptance. However, nothing other than this License grants you permission to propagate or modify any covered work. These actions infringe copyright if you do not accept this License. Therefore, by modifying or propagating a covered work, you indicate your acceptance of this License to do so. 10. Automatic Licensing of Downstream Recipients. Each time you convey a covered work, the recipient automatically receives a license from the original licensors, to run, modify and propagate that work, subject to this License. You are not responsible for enforcing compliance by third parties with this License. An "entity transaction" is a transaction transferring control of an organization, or substantially all assets of one, or subdividing an organization, or merging organizations. If propagation of a covered work results from an entity transaction, each party to that transaction who receives a copy of the work also receives whatever licenses to the work the party's predecessor in interest had or could give under the previous paragraph, plus a right to possession of the Corresponding Source of the work from the predecessor in interest, if the predecessor has it or can get it with reasonable efforts. You may not impose any further restrictions on the exercise of the rights granted or affirmed under this License. For example, you may not impose a license fee, royalty, or other charge for exercise of rights granted under this License, and you may not initiate litigation (including a cross-claim or counterclaim in a lawsuit) alleging that any patent claim is infringed by making, using, selling, offering for sale, or importing the Program or any portion of it. 11. Patents. A "contributor" is a copyright holder who authorizes use under this License of the Program or a work on which the Program is based. The work thus licensed is called the contributor's "contributor version". A contributor's "essential patent claims" are all patent claims owned or controlled by the contributor, whether already acquired or hereafter acquired, that would be infringed by some manner, permitted by this License, of making, using, or selling its contributor version, but do not include claims that would be infringed only as a consequence of further modification of the contributor version. For purposes of this definition, "control" includes the right to grant patent sublicenses in a manner consistent with the requirements of this License. Each contributor grants you a non-exclusive, worldwide, royalty-free patent license under the contributor's essential patent claims, to make, use, sell, offer for sale, import and otherwise run, modify and propagate the contents of its contributor version. In the following three paragraphs, a "patent license" is any express agreement or commitment, however denominated, not to enforce a patent (such as an express permission to practice a patent or covenant not to sue for patent infringement). To "grant" such a patent license to a party means to make such an agreement or commitment not to enforce a patent against the party. If you convey a covered work, knowingly relying on a patent license, and the Corresponding Source of the work is not available for anyone to copy, free of charge and under the terms of this License, through a publicly available network server or other readily accessible means, then you must either (1) cause the Corresponding Source to be so available, or (2) arrange to deprive yourself of the benefit of the patent license for this particular work, or (3) arrange, in a manner consistent with the requirements of this License, to extend the patent license to downstream recipients. "Knowingly relying" means you have actual knowledge that, but for the patent license, your conveying the covered work in a country, or your recipient's use of the covered work in a country, would infringe one or more identifiable patents in that country that you have reason to believe are valid. If, pursuant to or in connection with a single transaction or arrangement, you convey, or propagate by procuring conveyance of, a covered work, and grant a patent license to some of the parties receiving the covered work authorizing them to use, propagate, modify or convey a specific copy of the covered work, then the patent license you grant is automatically extended to all recipients of the covered work and works based on it. A patent license is "discriminatory" if it does not include within the scope of its coverage, prohibits the exercise of, or is conditioned on the non-exercise of one or more of the rights that are specifically granted under this License. You may not convey a covered work if you are a party to an arrangement with a third party that is in the business of distributing software, under which you make payment to the third party based on the extent of your activity of conveying the work, and under which the third party grants, to any of the parties who would receive the covered work from you, a discriminatory patent license (a) in connection with copies of the covered work conveyed by you (or copies made from those copies), or (b) primarily for and in connection with specific products or compilations that contain the covered work, unless you entered into that arrangement, or that patent license was granted, prior to 28 March 2007. Nothing in this License shall be construed as excluding or limiting any implied license or other defenses to infringement that may otherwise be available to you under applicable patent law. 12. No Surrender of Others' Freedom. If conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot convey a covered work so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not convey it at all. For example, if you agree to terms that obligate you to collect a royalty for further conveying from those to whom you convey the Program, the only way you could satisfy both those terms and this License would be to refrain entirely from conveying the Program. 13. Use with the GNU Affero General Public License. Notwithstanding any other provision of this License, you have permission to link or combine any covered work with a work licensed under version 3 of the GNU Affero General Public License into a single combined work, and to convey the resulting work. The terms of this License will continue to apply to the part which is the covered work, but the special requirements of the GNU Affero General Public License, section 13, concerning interaction through a network will apply to the combination as such. 14. Revised Versions of this License. The Free Software Foundation may publish revised and/or new versions of the GNU General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies that a certain numbered version of the GNU General Public License "or any later version" applies to it, you have the option of following the terms and conditions either of that numbered version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of the GNU General Public License, you may choose any version ever published by the Free Software Foundation. If the Program specifies that a proxy can decide which future versions of the GNU General Public License can be used, that proxy's public statement of acceptance of a version permanently authorizes you to choose that version for the Program. Later license versions may give you additional or different permissions. However, no additional obligations are imposed on any author or copyright holder as a result of your choosing to follow a later version. 15. Disclaimer of Warranty. THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 16. Limitation of Liability. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 17. Interpretation of Sections 15 and 16. If the disclaimer of warranty and limitation of liability provided above cannot be given local legal effect according to their terms, reviewing courts shall apply local law that most closely approximates an absolute waiver of all civil liability in connection with the Program, unless a warranty or assumption of liability accompanies a copy of the Program in return for a fee. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively state the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . Also add information on how to contact you by electronic and paper mail. If the program does terminal interaction, make it output a short notice like this when it starts in an interactive mode: Copyright (C) This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, your program's commands might be different; for a GUI interface, you would use an "about box". You should also get your employer (if you work as a programmer) or school, if any, to sign a "copyright disclaimer" for the program, if necessary. For more information on this, and how to apply and follow the GNU GPL, see . The GNU General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. But first, please read . cb2bib-2.0.1/xpdf/PaxHeaders.5700/README0000644000000000000000000000007414011522151014123 xustar0030 atime=1613145424.838620334 30 ctime=1613145424.306620349 cb2bib-2.0.1/xpdf/README0000644000175000001440000003573414011522151015531 0ustar00constansusers00000000000000Xpdf ==== version 3.04 2014-may-28 The Xpdf software and documentation are copyright 1996-2014 Glyph & Cog, LLC. Email: derekn@foolabs.com WWW: http://www.foolabs.com/xpdf/ The PDF data structures, operators, and specification are copyright 1985-2006 Adobe Systems Inc. What is Xpdf? ------------- Xpdf is an open source viewer for Portable Document Format (PDF) files. (These are also sometimes also called 'Acrobat' files, from the name of Adobe's PDF software.) The Xpdf project also includes a PDF text extractor, PDF-to-PostScript converter, and various other utilities. Xpdf runs under the X Window System on UNIX and OS/2. The non-X components (pdftops, pdftotext, etc.) also run on Windows and Mac OSX systems and should run on pretty much any system with a decent C++ compiler. Xpdf will run on 32-bit and 64-bit machines. License & Distribution ---------------------- Xpdf is licensed under the GNU General Pulbic License (GPL), version 2 or 3. This means that you can distribute derivatives of Xpdf under any of the following: - GPL v2 only - GPL v3 only - GPL v2 or v3 The Xpdf source package includes the text of both GPL versions: COPYING for GPL v2, COPYING3 for GPL v3. Please note that Xpdf is NOT licensed under "any later version" of the GPL, as I have no idea what those versions will look like. If you are redistributing unmodified copies of Xpdf (or any of the Xpdf tools) in binary form, you need to include all of the documentation: README, man pages (or help files), COPYING, and COPYING3. If you want to incorporate the Xpdf source code into another program (or create a modified version of Xpdf), and you are distributing that program, you have two options: release your program under the GPL (v2 and/or v3), or purchase a commercial Xpdf source license. If you're interested in commercial licensing, please see the Glyph & Cog web site: http://www.glyphandcog.com/ Compatibility ------------- Xpdf is developed and tested on Linux. In addition, it has been compiled by others on Solaris, AIX, HP-UX, Digital Unix, Irix, and numerous other Unix implementations, as well as OS/2. It should work on pretty much any system which runs X11 and has Unix-like libraries. You'll need ANSI C++ and C compilers to compile it. The non-X components of Xpdf (pdftops, pdftotext, pdfinfo, pdffonts, pdfdetach, pdftoppm, and pdfimages) can also be compiled on Windows and Mac OSX systems. See the Xpdf web page for details. If you compile Xpdf for a system not listed on the web page, please let me know. If you're willing to make your binary available by ftp or on the web, I'll be happy to add a link from the Xpdf web page. I have decided not to host any binaries I didn't compile myself (for disk space and support reasons). If you can't get Xpdf to compile on your system, send me email and I'll try to help. Xpdf has been ported to the Acorn, Amiga, BeOS, and EPOC. See the Xpdf web page for links. Getting Xpdf ------------ The latest version is available from: http://www.foolabs.com/xpdf/ or: ftp://ftp.foolabs.com/pub/xpdf/ Source code and several precompiled executables are available. Announcements of new versions are posted to comp.text.pdf and emailed to a list of people. If you'd like to receive email notification of new versions, just let me know. Running Xpdf ------------ To run xpdf, simply type: xpdf file.pdf To generate a PostScript file, hit the "print" button in xpdf, or run pdftops: pdftops file.pdf To generate a plain text file, run pdftotext: pdftotext file.pdf There are five additional utilities (which are fully described in their man pages): pdfinfo -- dumps a PDF file's Info dictionary (plus some other useful information) pdffonts -- lists the fonts used in a PDF file along with various information for each font pdfdetach -- lists or extracts embedded files (attachments) from a PDF file pdftoppm -- converts a PDF file to a series of PPM/PGM/PBM-format bitmaps pdfimages -- extracts the images from a PDF file Command line options and many other details are described in the man pages: xpdf(1), etc. All of these utilities read an optional configuration file: see the xpdfrc(5) man page. Upgrading from Xpdf 3.02 (and earlier) -------------------------------------- The font configuration system has been changed. Previous versions used mostly separate commands to configure fonts for display and for PostScript output. As of 3.03, configuration options that make sense for both display and PS output have been unified. The following xpdfrc commands have been removed: * displayFontT1, displayFontTT: replaced with fontFile * displayNamedCIDFontT1, displayNamedCIDFontTT: replaced with fontFile * displayCIDFontT1, displayCIDFontTT: replaced with fontFileCC * psFont: replaced with psResidentFont * psNamedFont16: replaced with psResidentFont16 * psFont16: replaced with psResidentFontCC See the xpdfrc(5) man page for more information on the new commands. Pdftops will now embed external 16-bit fonts (configured with the fontFileCC command) when the PDF file refers to a non-embedded font. It does not do any subsetting (yet), so the resulting PS files will be large. Compiling Xpdf -------------- See the separate file, INSTALL. Bugs ---- If you find a bug in Xpdf, i.e., if it prints an error message, crashes, or incorrectly displays a document, and you don't see that bug listed here, please send me email, with a pointer (URL, ftp site, etc.) to the PDF file. Third-Party Libraries --------------------- Xpdf uses the following libraries: * FreeType [http://www.freetype.org/] * libpng [http://www.libpng.com/pub/png/libpng.html] (used by pdftohtml) * zlib [http://zlib.net/] (used by pdftohtml) Acknowledgments --------------- Thanks to: * Patrick Voigt for help with the remote server code. * Patrick Moreau, Martin P.J. Zinser, and David Mathog for the VMS port. * David Boldt and Rick Rodgers for sample man pages. * Brendan Miller for the icon idea. * Olly Betts for help testing pdftotext. * Peter Ganten for the OS/2 port. * Michael Richmond for the Win32 port of pdftops and pdftotext and the xpdf/cygwin/XFree86 build instructions. * Frank M. Siegert for improvements in the PostScript code. * Leo Smiers for the decryption patches. * Rainer Menzner for creating t1lib, and for helping me adapt it to xpdf. * Pine Tree Systems A/S for funding the OPI and EPS support in pdftops. * Easy Software Products for funding several improvements to the PostScript output code. * Tom Kacvinsky for help with FreeType and for being my interface to the FreeType team. * Theppitak Karoonboonyanan for help with Thai support. * Leonard Rosenthol for help and contributions on a bunch of things. * Alexandros Diamantidis and Maria Adaloglou for help with Greek support. * Lawrence Lai for help with the CJK Unicode maps. Various people have contributed modifications made for use by the pdftex project: * Han The Thanh * Martin Schröder of ArtCom GmbH References ---------- Adobe Systems Inc., _PDF Reference, sixth edition: Adobe Portable Document Format version 1.7_. http://www.adobe.com/devnet/pdf/pdf_reference.html [The manual for PDF version 1.7.] Adobe Systems Inc., "Errata for the PDF Reference, sixth edition, version 1.7", October 16, 2006. http://www.adobe.com/devnet/pdf/pdf_reference.html [The errata for the PDF 1.7 spec.] Adobe Systems Inc., _PostScript Language Reference_, 3rd ed. Addison-Wesley, 1999, ISBN 0-201-37922-8. [The official PostScript manual.] Adobe Systems, Inc., _The Type 42 Font Format Specification_, Adobe Developer Support Technical Specification #5012. 1998. http://partners.adobe.com/asn/developer/pdfs/tn/5012.Type42_Spec.pdf [Type 42 is the format used to embed TrueType fonts in PostScript files.] Adobe Systems, Inc., _Adobe CMap and CIDFont Files Specification_, Adobe Developer Support Technical Specification #5014. 1995. http://www.adobe.com/supportservice/devrelations/PDFS/TN/5014.CIDFont_Spec.pdf [CMap file format needed for Japanese and Chinese font support.] Adobe Systems, Inc., _Adobe-Japan1-4 Character Collection for CID-Keyed Fonts_, Adobe Developer Support Technical Note #5078. 2000. http://partners.adobe.com/asn/developer/PDFS/TN/5078.CID_Glyph.pdf [The Adobe Japanese character set.] Adobe Systems, Inc., _Adobe-GB1-4 Character Collection for CID-Keyed Fonts_, Adobe Developer Support Technical Note #5079. 2000. http://partners.adobe.com/asn/developer/pdfs/tn/5079.Adobe-GB1-4.pdf [The Adobe Chinese GB (simplified) character set.] Adobe Systems, Inc., _Adobe-CNS1-3 Character Collection for CID-Keyed Fonts_, Adobe Developer Support Technical Note #5080. 2000. http://partners.adobe.com/asn/developer/PDFS/TN/5080.CNS_CharColl.pdf [The Adobe Chinese CNS (traditional) character set.] Adobe Systems Inc., _Supporting the DCT Filters in PostScript Level 2_, Adobe Developer Support Technical Note #5116. 1992. http://www.adobe.com/supportservice/devrelations/PDFS/TN/5116.PS2_DCT.PDF [Description of the DCTDecode filter parameters.] Adobe Systems Inc., _Open Prepress Interface (OPI) Specification - Version 2.0_, Adobe Developer Support Technical Note #5660. 2000. http://partners.adobe.com/asn/developer/PDFS/TN/5660.OPI_2.0.pdf Adobe Systems Inc., CMap files. ftp://ftp.oreilly.com/pub/examples/nutshell/cjkv/adobe/ [The actual CMap files for the 16-bit CJK encodings.] Adobe Systems Inc., Unicode glyph lists. http://partners.adobe.com/asn/developer/type/unicodegn.html http://partners.adobe.com/asn/developer/type/glyphlist.txt http://partners.adobe.com/asn/developer/type/corporateuse.txt http://partners.adobe.com/asn/developer/type/zapfdingbats.txt [Mappings between character names to Unicode.] Adobe Systems Inc., OpenType Specification v. 1.4. http://partners.adobe.com/public/developer/opentype/index_spec.html [The OpenType font format spec.] Aldus Corp., _OPI: Open Prepress Interface Specification 1.3_. 1993. http://partners.adobe.com/asn/developer/PDFS/TN/OPI_13.pdf Anonymous, RC4 source code. ftp://ftp.ox.ac.uk/pub/crypto/misc/rc4.tar.gz ftp://idea.sec.dsi.unimi.it/pub/crypt/code/rc4.tar.gz [This is the algorithm used to encrypt PDF files.] T. Boutell, et al., "PNG (Portable Network Graphics) Specification, Version 1.0". RFC 2083. [PDF uses the PNG filter algorithms.] CCITT, "Information Technology - Digital Compression and Coding of Continuous-tone Still Images - Requirements and Guidelines", CCITT Recommendation T.81. http://www.w3.org/Graphics/JPEG/ [The official JPEG spec.] A. Chernov, "Registration of a Cyrillic Character Set". RFC 1489. [Documentation for the KOI8-R Cyrillic encoding.] Roman Czyborra, "The ISO 8859 Alphabet Soup". http://czyborra.com/charsets/iso8859.html [Documentation on the various ISO 859 encodings.] L. Peter Deutsch, "ZLIB Compressed Data Format Specification version 3.3". RFC 1950. [Information on the general format used in FlateDecode streams.] L. Peter Deutsch, "DEFLATE Compressed Data Format Specification version 1.3". RFC 1951. [The definition of the compression algorithm used in FlateDecode streams.] Morris Dworkin, "Recommendation for Block Cipher Modes of Operation", National Institute of Standards, NIST Special Publication 800-38A, 2001. [The cipher block chaining (CBC) mode used with AES in PDF files.] Federal Information Processing Standards Publication 197 (FIPS PUBS 197), "Advanced Encryption Standard (AES)", November 26, 2001. [AES encryption, used in PDF 1.6.] Jim Flowers, "X Logical Font Description Conventions", Version 1.5, X Consortium Standard, X Version 11, Release 6.1. ftp://ftp.x.org/pub/R6.1/xc/doc/hardcopy/XLFD/xlfd.PS.Z [The official specification of X font descriptors, including font transformation matrices.] Foley, van Dam, Feiner, and Hughes, _Computer Graphics: Principles and Practice_, 2nd ed. Addison-Wesley, 1990, ISBN 0-201-12110-7. [Colorspace conversion functions, Bezier spline math.] Robert L. Hummel, _Programmer's Technical Reference: Data and Fax Communications_. Ziff-Davis Press, 1993, ISBN 1-56276-077-7. [CCITT Group 3 and 4 fax decoding.] ISO/IEC, _Information technology -- Lossy/lossless coding of bi-level images_. ISO/IEC 14492, First edition (2001-12-15). http://webstore.ansi.org/ [The official JBIG2 standard. The final draft of this spec is available from http://www.jpeg.org/jbighomepage.html.] ISO/IEC, _Information technology -- JPEG 2000 image coding system -- Part 1: Core coding system_. ISO/IEC 15444-1, First edition (2000-12-15). http://webstore.ansi.org/ [The official JPEG 2000 standard. The final committee draft of this spec is available from http://www.jpeg.org/JPEG2000.html, but there were changes made to the bitstream format between that draft and the published spec.] ITU, "Standardization of Group 3 facsimile terminals for document transmission", ITU-T Recommendation T.4, 1999. ITU, "Facsimile coding schemes and coding control functions for Group 4 facsimile apparatus", ITU-T Recommendation T.6, 1993. http://www.itu.int/ [The official Group 3 and 4 fax standards - used by the CCITTFaxDecode stream, as well as the JBIG2Decode stream.] B. Kaliski, "PKCS #5: Password-Based Cryptography Specification, Version 2.0". RFC 2898. [Defines the padding scheme used with AES encryption in PDF files.] Christoph Loeffler, Adriaan Ligtenberg, George S. Moschytz, "Practical Fast 1-D DCT Algorithms with 11 Multiplications". IEEE Intl. Conf. on Acoustics, Speech & Signal Processing, 1989, 988-991. [The fast IDCT algorithm used in the DCTDecode filter.] Microsoft, _TrueType 1.0 Font Files_, rev. 1.66. 1995. http://www.microsoft.com/typography/tt/tt.htm [The TrueType font spec (in MS Word format, naturally).] V. Ostromoukhov, R.D. Hersch, "Stochastic Clustered-Dot Dithering", Conf. Color Imaging: Device-Independent Color, Color Hardcopy, and Graphic Arts IV, 1999, SPIE Vol. 3648, 496-505. http://diwww.epfl.ch/w3lsp/publications/colour/scd.html [The stochastic dithering algorithm used in Xpdf.] P. Peterlin, "ISO 8859-2 (Latin 2) Resources". http://sizif.mf.uni-lj.si/linux/cee/iso8859-2.html [This is a web page with all sorts of useful Latin-2 character set and font information.] Charles Poynton, "Color FAQ". http://www.inforamp.net/~poynton/ColorFAQ.html [The mapping from the CIE 1931 (XYZ) color space to RGB.] R. Rivest, "The MD5 Message-Digest Algorithm". RFC 1321. [MD5 is used in PDF document encryption.] Thai Industrial Standard, "Standard for Thai Character Codes for Computers", TIS-620-2533 (1990). http://www.nectec.or.th/it-standards/std620/std620.htm [The TIS-620 Thai encoding.] Unicode Consortium, "Unicode Home Page". http://www.unicode.org/ [Online copy of the Unicode spec.] W3C Recommendation, "PNG (Portable Network Graphics) Specification Version 1.0". http://www.w3.org/Graphics/PNG/ [Defines the PNG image predictor.] Gregory K. Wallace, "The JPEG Still Picture Compression Standard". ftp://ftp.uu.net/graphics/jpeg/wallace.ps.gz [Good description of the JPEG standard. Also published in CACM, April 1991, and submitted to IEEE Transactions on Consumer Electronics.] F. Yergeau, "UTF-8, a transformation format of ISO 10646". RFC 2279. [A commonly used Unicode encoding.] cb2bib-2.0.1/xpdf/PaxHeaders.5700/PDF2CB.README0000644000000000000000000000007414011522151015022 xustar0030 atime=1613145424.838620334 30 ctime=1613145424.306620349 cb2bib-2.0.1/xpdf/PDF2CB.README0000644000175000001440000000065214011522151016417 0ustar00constansusers00000000000000 pdf2cb: a modified pdftohtml 3.04 for cb2bib . Separate superscripts to avoid words being joined to reference numbers and author names joined to affiliations' glyphs. Download ftp://ftp.foolabs.com/pub/xpdf/xpdf-3.04.tar.gz Copy/Overwrite: cp pdftohtml.cc xpdf-3.04/xpdf/ cp HTMLGen.cc xpdf-3.04/xpdf/ cp HTMLGen.h xpdf-3.04/xpdf/ cd xpdf-3.04/ ./configure make Rename modified pdftohtml: mv xpdf/pdftohtml ../pdf2cb cb2bib-2.0.1/xpdf/PaxHeaders.5700/HTMLGen.cc0000644000000000000000000000007414011522151014750 xustar0030 atime=1613145424.838620334 30 ctime=1613145424.306620349 cb2bib-2.0.1/xpdf/HTMLGen.cc0000644000175000001440000002043014011522151016341 0ustar00constansusers00000000000000//======================================================================== // // Modified pdftohtml (constans@molspaces.com, 2014) // // HTMLGen.cc // // Copyright 2010 Glyph & Cog, LLC // //======================================================================== #include #ifdef USE_GCC_PRAGMAS #pragma implementation #endif #include #include "gmem.h" #include "GString.h" #include "GList.h" #include "PDFDoc.h" #include "TextOutputDev.h" #include "SplashOutputDev.h" #include "ErrorCodes.h" #include "HTMLGen.h" #ifdef _WIN32 # define strcasecmp stricmp # define strncasecmp strnicmp #endif //------------------------------------------------------------------------ // Map Unicode indexes from the private use area, following the Adobe // Glyph list. #define privateUnicodeMapStart 0xf6f9 #define privateUnicodeMapEnd 0xf7ff static int privateUnicodeMap[privateUnicodeMapEnd - privateUnicodeMapStart + 1] = { 0x0141, 0x0152, 0, 0, 0x0160, 0, 0x017d, // f6f9 0, 0, 0, 0, 0, 0, 0, 0, // f700 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // f710 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x0021, 0, 0, 0x0024, 0, 0x0026, 0, // f720 0, 0, 0, 0, 0, 0, 0, 0, 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, // f730 0x0038, 0x0039, 0, 0, 0, 0, 0, 0x003f, 0, 0, 0, 0, 0, 0, 0, 0, // f740 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // f750 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, // f760 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, // f770 0x0058, 0x0059, 0x005a, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // f780 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // f790 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x00a1, 0x00a2, 0, 0, 0, 0, 0, // f7a0 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // f7b0 0, 0, 0, 0, 0, 0, 0, 0x00bf, 0, 0, 0, 0, 0, 0, 0, 0, // f7c0 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // f7d0 0, 0, 0, 0, 0, 0, 0, 0, 0x00c0, 0x00c1, 0x00c2, 0x00c3, 0x00c4, 0x00c5, 0x00c6, 0x00c7, // f7e0 0x00c8, 0x00c9, 0x00ca, 0x00cb, 0x00cc, 0x00cd, 0x00ce, 0x00cf, 0x00d0, 0x00d1, 0x00d2, 0x00d3, 0x00d4, 0x00d5, 0x00d6, 0, // f7f0 0x00d8, 0x00d9, 0x00da, 0x00db, 0x00dc, 0x00dd, 0x00de, 0x0178 }; //------------------------------------------------------------------------ //------------------------------------------------------------------------ HTMLGen::HTMLGen() { TextOutputControl textOutControl; SplashColor paperColor; ok = gTrue; backgroundResolution = 150; drawInvisibleText = gTrue; // set up the TextOutputDev textOutControl.mode = textOutReadingOrder; textOutControl.html = gTrue; textOut = new TextOutputDev(NULL, &textOutControl, gFalse); if (!textOut->isOk()) { ok = gFalse; } // set up the SplashOutputDev paperColor[0] = paperColor[1] = paperColor[2] = 0xff; splashOut = new SplashOutputDev(splashModeRGB8, 1, gFalse, paperColor); splashOut->setSkipText(gTrue, gFalse); } HTMLGen::~HTMLGen() { delete textOut; delete splashOut; } void HTMLGen::startDoc(PDFDoc* docA) { doc = docA; splashOut->startDoc(doc->getXRef()); } int HTMLGen::convertPage(int pg, int (*writeHTML)(void* stream, const char* data, int size), void* htmlStream) { TextPage* text; GList* cols, *pars, *lines, *words; TextColumn* col; TextParagraph* par; TextLine* line; TextWord* word1; GString* s; double base; int colIdx, parIdx, lineIdx, wordIdx; int i, u; const char parsep('\n'); // get the PDF text doc->displayPage(textOut, pg, 72, 72, 0, gFalse, gTrue, gFalse); text = textOut->takeText(); // generate the PDF text cols = text->makeColumns(); for (colIdx = 0; colIdx < cols->getLength(); ++colIdx) { col = (TextColumn*)cols->get(colIdx); pars = col->getParagraphs(); for (parIdx = 0; parIdx < pars->getLength(); ++parIdx) { par = (TextParagraph*)pars->get(parIdx); lines = par->getLines(); for (lineIdx = 0; lineIdx < lines->getLength(); ++lineIdx) { line = (TextLine*)lines->get(lineIdx); words = line->getWords(); base = line->getBaseline(); s = new GString(); for (wordIdx = 0; wordIdx < words->getLength(); ++wordIdx) { word1 = (TextWord*)words->get(wordIdx); if (word1->getBaseline() - base < -0.55) s->append(' '); // superscript for (i = 0; i < word1->getLength(); ++i) { u = word1->getChar(i); if (u >= privateUnicodeMapStart && u <= privateUnicodeMapEnd && privateUnicodeMap[u - privateUnicodeMapStart]) { u = privateUnicodeMap[u - privateUnicodeMapStart]; } if (u <= 0x7f) { s->append((char)u); } else if (u <= 0x7ff) { s->append((char)(0xc0 + (u >> 6))); s->append((char)(0x80 + (u & 0x3f))); } else if (u <= 0xffff) { s->append((char)0xe0 + (u >> 12)); s->append((char)0x80 + ((u >> 6) & 0x3f)); s->append((char)0x80 + (u & 0x3f)); } else if (u <= 0x1fffff) { s->append((char)0xf0 + (u >> 18)); s->append((char)0x80 + ((u >> 12) & 0x3f)); s->append((char)0x80 + ((u >> 6) & 0x3f)); s->append((char)0x80 + (u & 0x3f)); } else if (u <= 0x3ffffff) { s->append((char)0xf8 + (u >> 24)); s->append((char)0x80 + ((u >> 18) & 0x3f)); s->append((char)0x80 + ((u >> 12) & 0x3f)); s->append((char)0x80 + ((u >> 6) & 0x3f)); s->append((char)0x80 + (u & 0x3f)); } else if (u <= 0x7fffffff) { s->append((char)0xfc + (u >> 30)); s->append((char)0x80 + ((u >> 24) & 0x3f)); s->append((char)0x80 + ((u >> 18) & 0x3f)); s->append((char)0x80 + ((u >> 12) & 0x3f)); s->append((char)0x80 + ((u >> 6) & 0x3f)); s->append((char)0x80 + (u & 0x3f)); } } if (word1->getSpaceAfter()) s->append(' '); } s->append('\n'); writeHTML(htmlStream, s->getCString(), s->getLength()); delete s; } writeHTML(htmlStream, &parsep, 1); } } delete text; deleteGList(cols, TextColumn); return errNone; } cb2bib-2.0.1/PaxHeaders.5700/testPDFImport0000644000000000000000000000007414011522151014731 xustar0030 atime=1613145424.838620334 30 ctime=1613145424.306620349 cb2bib-2.0.1/testPDFImport/0000755000175000001440000000000014011522151016400 5ustar00constansusers00000000000000cb2bib-2.0.1/testPDFImport/PaxHeaders.5700/nomeaning4.pdf0000644000000000000000000000007414011522151017540 xustar0030 atime=1613145424.838620334 30 ctime=1613145424.306620349 cb2bib-2.0.1/testPDFImport/nomeaning4.pdf0000644000175000001440000007552014011522151021143 0ustar00constansusers00000000000000%PDF-1.2 7 0 obj << /Type/Encoding /Differences[0/Gamma/Delta/Theta/Lambda/Xi/Pi/Sigma/Upsilon/Phi/Psi/Omega/ff/fi/fl/ffi/ffl/dotlessi/dotlessj/grave/acute/caron/breve/macron/ring/cedilla/germandbls/ae/oe/oslash/AE/OE/Oslash/suppress/exclam/quotedblright/numbersign/dollar/percent/ampersand/quoteright/parenleft/parenright/asterisk/plus/comma/hyphen/period/slash/zero/one/two/three/four/five/six/seven/eight/nine/colon/semicolon/exclamdown/equal/questiondown/question/at/A/B/C/D/E/F/G/H/I/J/K/L/M/N/O/P/Q/R/S/T/U/V/W/X/Y/Z/bracketleft/quotedblleft/bracketright/circumflex/dotaccent/quoteleft/a/b/c/d/e/f/g/h/i/j/k/l/m/n/o/p/q/r/s/t/u/v/w/x/y/z/endash/emdash/hungarumlaut/tilde/dieresis/suppress 160/space/Gamma/Delta/Theta/Lambda/Xi/Pi/Sigma/Upsilon/Phi/Psi 173/Omega/ff/fi/fl/ffi/ffl/dotlessi/dotlessj/grave/acute/caron/breve/macron/ring/cedilla/germandbls/ae/oe/oslash/AE/OE/Oslash/suppress/dieresis] >> endobj 10 0 obj << /Encoding 7 0 R /Type/Font /Subtype/Type1 /Name/F1 /FontDescriptor 9 0 R /BaseFont/NOAEMU+CMR10 /FirstChar 33 /LastChar 196 /Widths[277.8 500 833.3 500 833.3 777.8 277.8 388.9 388.9 500 777.8 277.8 333.3 277.8 500 500 500 500 500 500 500 500 500 500 500 277.8 277.8 277.8 777.8 472.2 472.2 777.8 750 708.3 722.2 763.9 680.6 652.8 784.7 750 361.1 513.9 777.8 625 916.7 750 777.8 680.6 777.8 736.1 555.6 722.2 750 750 1027.8 750 750 611.1 277.8 500 277.8 500 277.8 277.8 500 555.6 444.4 555.6 444.4 305.6 500 555.6 277.8 305.6 527.8 277.8 833.3 555.6 500 555.6 527.8 391.7 394.4 388.9 555.6 527.8 722.2 527.8 527.8 444.4 500 1000 500 500 500 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 625 833.3 777.8 694.4 666.7 750 722.2 777.8 722.2 777.8 0 0 722.2 583.3 555.6 555.6 833.3 833.3 277.8 305.6 500 500 500 500 500 750 444.4 500 722.2 777.8 500 902.8 1013.9 777.8 277.8 500] >> endobj 13 0 obj << /Encoding 7 0 R /Type/Font /Subtype/Type1 /Name/F2 /FontDescriptor 12 0 R /BaseFont/TCDBMP+CMBX10 /FirstChar 33 /LastChar 196 /Widths[350 602.8 958.3 575 958.3 894.4 319.4 447.2 447.2 575 894.4 319.4 383.3 319.4 575 575 575 575 575 575 575 575 575 575 575 319.4 319.4 350 894.4 543.1 543.1 894.4 869.4 818.1 830.6 881.9 755.6 723.6 904.2 900 436.1 594.4 901.4 691.7 1091.7 900 863.9 786.1 863.9 862.5 638.9 800 884.7 869.4 1188.9 869.4 869.4 702.8 319.4 602.8 319.4 575 319.4 319.4 559 638.9 511.1 638.9 527.1 351.4 575 638.9 319.4 351.4 606.9 319.4 958.3 638.9 575 638.9 606.9 473.6 453.6 447.2 638.9 606.9 830.6 606.9 606.9 511.1 575 1150 575 575 575 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 691.7 958.3 894.4 805.6 766.7 900 830.6 894.4 830.6 894.4 0 0 830.6 670.8 638.9 638.9 958.3 958.3 319.4 351.4 575 575 575 575 575 869.4 511.1 597.2 830.6 894.4 575 1041.7 1169.4 894.4 319.4 575] >> endobj 16 0 obj << /Encoding 7 0 R /Type/Font /Subtype/Type1 /Name/F3 /FontDescriptor 15 0 R /BaseFont/EWUVHY+CMBX12 /FirstChar 33 /LastChar 196 /Widths[342.6 581 937.5 562.5 937.5 875 312.5 437.5 437.5 562.5 875 312.5 375 312.5 562.5 562.5 562.5 562.5 562.5 562.5 562.5 562.5 562.5 562.5 562.5 312.5 312.5 342.6 875 531.2 531.2 875 849.5 799.8 812.5 862.3 738.4 707.2 884.3 879.6 419 581 880.8 675.9 1067.1 879.6 844.9 768.5 844.9 839.1 625 782.4 864.6 849.5 1162 849.5 849.5 687.5 312.5 581 312.5 562.5 312.5 312.5 546.9 625 500 625 513.3 343.7 562.5 625 312.5 343.7 593.7 312.5 937.5 625 562.5 625 593.7 459.5 443.8 437.5 625 593.7 812.5 593.7 593.7 500 562.5 1125 562.5 562.5 562.5 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 675.9 937.5 875 787 750 879.6 812.5 875 812.5 875 0 0 812.5 656.2 625 625 937.5 937.5 312.5 343.7 562.5 562.5 562.5 562.5 562.5 849.5 500 574.1 812.5 875 562.5 1018.5 1143.5 875 312.5 562.5] >> endobj 19 0 obj << /Encoding 7 0 R /Type/Font /Subtype/Type1 /Name/F4 /FontDescriptor 18 0 R /BaseFont/QGNGHU+CMBX9 /FirstChar 33 /LastChar 196 /Widths[360.2 617.6 986.1 591.7 986.1 920.4 328.7 460.2 460.2 591.7 920.4 328.7 394.4 328.7 591.7 591.7 591.7 591.7 591.7 591.7 591.7 591.7 591.7 591.7 591.7 328.7 328.7 360.2 920.4 558.8 558.8 920.4 892.9 840.9 854.6 906.6 776.5 743.7 929.9 924.4 446.3 610.8 925.8 710.8 1121.6 924.4 888.9 808 888.9 886.7 657.4 823.1 908.6 892.9 1221.6 892.9 892.9 723.1 328.7 617.6 328.7 591.7 328.7 328.7 575.2 657.4 525.9 657.4 543 361.6 591.7 657.4 328.7 361.6 624.5 328.7 986.1 657.4 591.7 657.4 624.5 488.1 466.8 460.2 657.4 624.5 854.6 624.5 624.5 525.9 591.7 1183.3 591.7 591.7 591.7 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 710.8 986.1 920.4 827.2 788.9 924.4 854.6 920.4 854.6 920.4 0 0 854.6 690.3 657.4 657.4 986.1 986.1 328.7 361.6 591.7 591.7 591.7 591.7 591.7 892.9 525.9 616.8 854.6 920.4 591.7 1071 1202.5 920.4 328.7 591.7] >> endobj 21 0 obj << /Filter[/FlateDecode] /Length 1662 >> stream x}WIs6WjƤ zM'n2N` H&} "o-,}noĢjqH,WqɕTJm/|s*bÃ2e<`!(|G./ Qd]چsv \dc\Ug/v~XJ<+$ژ2k /ӲA_Pf@<"UM&l OWw˶N~&L*uhX7O4o׫ڮx[Elvv΀{(A,R2 TI 4E ЀDp#kEG}J> =H~5OH*qliUyZ\&jJ׊d֊I+^ճW*G~NYhfr+PT&P(#PY5$g"2&o>tkUM\+/:')JV;7fb+]3icΣkUTumExy=O&RpY1xWVm򠻥9 M ,@U'Y-h^'5!}# I$څ0zcFNPݣo!V $ig,K*YoqkːUI[iU:7>-ƮOO8Lv*Tyȸ~W 0`7t1BNܰ &S Rs2\%qx}0\i,S\2V$y2-9B?zLfߵah$9z&FH)5&=(pH#8ne^zuõg#{Z-n{oc8# H&DOy(pO9 +FszR|Xt /V¹jl+I%'=VL`?0˚\9յJ?L:=ףvQ4mS8tbV^jEҠK$En{{fiH$(t=R۬ ͙J |0xݨy #S9GhhÐ7#63(Ȗ8 q# #g7y`ٲY;Z>2:NJ.iRːEUu3v&nt?k?,\"2ͺG:޼3v9m]%㈓TSXn1g Ͱ)9d4i0ItxLCy !N[+lcB8eŁܶk5{cYCz@g`]1~n&=-g endstream endobj 23 0 obj << /F1 10 0 R /F2 13 0 R /F3 16 0 R /F4 19 0 R >> endobj 6 0 obj << /ProcSet[/PDF/Text/ImageC] /Font 23 0 R >> endobj 9 0 obj << /Type/FontDescriptor /CapHeight 850 /Ascent 850 /Descent -200 /FontBBox[-251 -250 1009 969] /FontName/NOAEMU+CMR10 /ItalicAngle 0 /StemV 69 /FontFile 8 0 R /Flags 4 >> endobj 8 0 obj << /Filter[/FlateDecode] /Length1 720 /Length2 11503 /Length3 533 /Length 12060 >> stream xePᶦq,n%Cp8۸;A[pw'{p9gso=zUS*1ٛA`FV&V>*+ E R h I|V^^6ɆH wphiLAc%-@ `Dmmx t:͘YYfV`  s{f.Yr:9d0#2+R.vG[\@' R-fV.v^ 62Y,JY9KY͔sc[g?@ٿC?D%4YUT6=Ƭ3'+w.=soILͬ@51JL݋wXXx\>Rd*daaeg sVMThNiVY ˩h^4mW췤^kA|h4#W4oSONft3So},8ot?UX.)i~g)ElxPxTZ((*}O2omkOo!5:C<=`Z N&d^ MDBiCd8cLa:^ @<-Wcɚ|}Ψd(N `DZAw f0He*5Sd==a[+wIY ziڟ7fj)@SvRdN2ÇxB1Q%+_yu-.!f;(XL܎HUVM/dm ßu63DA7_Iy&夺(Zlov0u&9p<@}zQo$}.?)ۃQ~,ՏYjϪ"H㪡E]^iy#^7^/;,% èAtڃFX K`\h'(ǼOO#.Z~4U{ 'I`b&(O&%-6 s je zeN{<2#JUݻw tBFph 0̄OfO:{Os:PRN-OVGH[5=EY?LEHᦻ/FTz7H1OgI#H+OJDoY cZأ,x` Zv# FAImf*c@Z9()ɶۼyWޕ auU)RjU]^+TA34VK$={ތ+ns/ EzUis|KD36c^_ɑ1J=lO4S!j^@fOڕ^P|g;6CƝT9eo:@'Rk@BNu RQp~c}* fFœ~T'lztYDQuM{ א/:b7hdhMV<Yf"bFz' r;6Y$8n*Kpѻ-qnΣ)k`Hi_PEAuJKƠwpqtG=JS?6F/,קv Kkq*,%[ZsWn*jtK(t0?_oY T?LB`"[a򴛆A5p]<NO@m j\t~eH8|OS < rcܤy#ӿD`@/lJ0{ WOZhgF!c(زw9MU7ᅢ t!"ý td0xbXh|;bpMbL<_ 2kAՁe[?;,H9PLs3D/0w{ۛw VUD|nH[A^;5dx1P`;|,aO&Nt+IU3P똺%} #ö07v&#HDo%؋$Qܐ *COB,dLzp-=7 lXE\qbܒW.-+8sW:n;k:NjM.'#:.qgZB o;6dw;-;r@\z(a jxQ^"9f gjv1Eve^F@q0HMkVRjtz31յdyj6-vtu*(lS ۖT9#k=s3 7=8lҙ; #ar`t4]AW B8TfjUlV!yIy)9ym3#% J@T}S-LISsmn3"--uEX~T"+q+gV](zngImE U haP,3s(_beR4phr ]$O$-%4b ^=,Y}U<^>Wpqӧ_\?噦]Mו yn D)ݟݞZM!]cAe.m*8kULΌ#w+ O%b&S{loU~>@[ هI q%H^}Mg[~kmo…oGg d{ý`ibēF:+^4Б1sjja΢|;d*VB5T`+75ѐʽO(|C &KN ݑ-! OGy=˖\z2J=RU\uŵ z KPMiA!+pז5@1kA!AG,?69.$3XUزxLUuE6,)7ħմY8ұu+vzrfSck$>-S>&LdIapyX1ls4uyptm! <9.V;]-%~s@ vL>"lcNkZMmsd{y\|Kl[UBڷy2MU~BZrǟ~!ON=cZ'RwStް8"Z̞-^IcN>og@BD+$~V{͑k}N.ث bmF?2#1J!H3.JS-ʀ?F| ޾xW_,S_ۖl837ܝ.HԻ"#6 [u44)09o+S#_W0 qQP5K"[7-Д 33>5y>rpbq~<ZꟉ`B,/ ]".ᲁ(YXֆE> vrlm0s& S$|z>uQky|QymLJ/g+=s!]Q > &NJB䇁Qs70.6H (hjEա%U'+u?dh84 N*GdGLB Rj&*VDzYb k8 ~ÁOL8Xb3FJG!$$OYOkV2mv h 2aq1]ÄK!,(.;YK)F\C]B3\HNDFmԶ`;8 zYUEǚORW|yϚ dYOa*/dģYpFruOzd2{^Q7hꡥO'hR ZǽcGu~^"?Syĩ) Q/d0r2Q;U,j  8IE+M H}8ӟ ,]8A!*DϿE9LFSKQOCe̟k#a.|~$-*_" )'- O^kQxt{cl_ RM]ed3Ogs20zw5x:VK0-Sw  c7~.M 2_%š\1A֟.StiD~KGr!uU<ܘًGT)klB 3s}uƢ> MUak鼚&a!$/=( 1_#|YKF;rYW%Ї7ݙ.sѧ{%o yT vA0Ec[QkyrCv8)VD( otb1IoDت҈웡;;Ã)4Ǔs4{d9Bleu~Y FAG拰 90153yGlɈRsU NH{(eM0,.?_,3+ցGy>5 )pt gw=D`[mZz[Ue%"NI Ic}egwg-F54 8>@5VrݬJ#uMr%ݖ~bk켁9|uD:xll)"[zK:GY-st/V֫oe=1 W,ϕ0xk̛M{N?]z^F2c;oS '4[/&({p3nk;ifqw l1 OV#Q=H^Nx1I YRy&WPr|"#3"^(\pd L7`(|=\ea9#Qb>6uVpjf[3M;`EoWi!hLҬWEyX wV1zD1Sx(2|,kl>Dҥho{Q s1-DdiMNrq.8#1:ȴERg$~K&[5SHn%x`R/6@%QSRetƽL.;% AAقRk{ʴpmQ2"D'ԧqH*R>FAs5Wk˕C?$ w<ꂣ֓1FH)@"@K#M e< "+?r}H183о,ցbҹ #BR72.,w1z%!^J G>Ryt@k>gl}&~䒂=W1hdދYه_]BErrB6QnCǯLETs$;LV\b.1`Q{@O!ZP7o_h8[B9mi:jy0 EW1YSvSKQ@w_t bX41_Mh*~YGgo>8N90;U̕X?h>V,ݴRg@4oKp#@>We;2 l Yfz}!~U|[a\U tjz@8N[-~nQ6Hi|h+l$v$!*rDCg5-{ސ}n#N̲~J=D=ިa !5tX{86Sґ5XjddnlG:+y1l='0z+~Jd7U=L)xw҆RgTt䬮E&|aeΘvz]DCXT o6C-R#73,Yu0Ցx$iF'cN\q[ҼZĐ{ɮã "ջa!#U-\>AQ1rÅ,SJ)F7"o FM"x\}TsU.rJ-tKvͶ +2+C|@_LO*C휥2ķ2&UߓIxj9\7g>~͐*/KOU'O#iGq"WP $3nn`mpEy)-3NQYuSA`$%{LAmD)&g5 {Yy1JRC.\&ђGP$^bL ;?MO3 5H]g%4VymT3|7 5 r0.mFO\gP qO$!(acqBд|%LJjl~Ev˗(,[!ELK'U٨+i%HT찱6/9T+i +Fb0S9b3 ).0J%/PõËj]wǭ&bF߭;(ag5y R37շu!0 ǪlPvdbAP&MG[9}{0@Nzw'?@[%=?~q!~wUаu4c_nQ8:ؐlץfz"У#T"Er5>H?rL4#2B>6!9^U;AytDdG'Bzi<6ˎ̧in$X[a d-^U+ r 7m z%`rps}o0Ot@{0,}I'V/(R@M7FhN4{KMz):v`Go LO$mI? džCpOzrvNtR:N(Գt@-(37>u缯:}N7M3 I3hה0Ma,׏X+4j,YYyԹ ?4M0`TzNUm')B3G~ ^_=z'w23]-:]o[]GĊ܂.o5eOgjq=iWz8Ópqtn-Ծ`k%P%Y}}|]Q܇?t"*tΔNH͵2ٵS?w)D?,>:r6T.y4l#pAB9ߥ^ҧ7Ƅ޻RoȘq+j^Т#G5rUXVc{+_X@r@"MU"X"֦$SʊL]{I DnQ}" #eo-@; ctֳ^\ܡR'* @Rw60/ѺPzž}x@dh/{LK=y׹*3&W%.r)O(Qf|u!q$g[`ޑsT_ ECrn̶^~ބ-:=nq,#pQ)&9#FX43څr)%2J&>)kmaŠeZ{S>EDM \e=a6l2^'fAG'#[F1 atJQ3+&ᆮh@bέSV"k>jj=YhY5l.=fpAs9bJ7$duz۸̊U$ "D={.dV󑶭3j1a~7F"CHZ\4f l:FJjVUZcH\Ed 9}n*Lf?\Hg{RIʵ4N>ق"IIcB-Z߇KC,≸d%9x._I{:<̿uelGBbGǓUS+Blܘ>;jmy'(5c7[!se;䤍83'/JiOd%b0'c|VGa$ [k&q3%P!HǴ$?=qb3^IBD'ΗfywKa2^nzrxp_ ġFZ%C5>蜛.XB[ QJX/o- logd endstream endobj 12 0 obj << /Type/FontDescriptor /CapHeight 850 /Ascent 850 /Descent -200 /FontBBox[-301 -250 1164 946] /FontName/TCDBMP+CMBX10 /ItalicAngle 0 /StemV 114 /FontFile 11 0 R /Flags 4 >> endobj 11 0 obj << /Filter[/FlateDecode] /Length1 721 /Length2 2664 /Length3 533 /Length 3205 >> stream xy<%#H6-72fLf$A2(BY[%KY'[bG{|s㾮}ݷ> dy\02p f1$(2H0BA @(ƠbPUрA 2!?%PC*u@hB}A h,HQ}K` &^QeF&꿥1@RI* qb\!Ľ~ olnY?/u ]AA`EĀ$Ÿ.opD_ژQ8,Zo)l16bh_ A{ hhd`e+VEa dC  M` >EH$Je`@ $g$wj*BE*  N̢I$@yGhHt: <ٽ0夾"u,J3?H̖*sm#/k͚ |Eg=5t֞Oeg3]7%A X Mn[n#-`^Of"]$Mv#`k`nlug8IpF2/Z4NT8 -x0~Ù:t1FgKT|A끖|9=cw vƍV}mB߸j3{y\O%_/Xe7m̘oeyWw} Y~Y2eד0՜{}l{*ݠ [͵o߳+˖t@oGXƌH)ũ#T7G_NgIl|K6M8W߫580i6bY/F0I=~C)^ef\\#G]=HBSv[kNJdѸf_N0q|M|)?vu<P~LPZǨ|y]cDA+Z@3 + fsk N 3p4[z}EkGqOH/'eHZ,1P%BⲽdCqu!?dr7-FȐaBMsS]ʰ(,hV0h)^w]Ļq eRxOʁs=oP9!Bpq]M)OjÞU  @NRLۍf q_J\WL{PS .0qtGw둴~? Ybdj۝Q{cbR s'&_+(D&{%K;)*ʬ&ndo&""?~=Z֡}9{aMU%`EϟdxyUcp; 9ܻ;ƥRΕ#dz^9'h if}Q5R 56>ey؉W7_ZV3ttGRn|m~2aZhU^D7kWTɂ. Cnq"mNV~f2WOplC{14 ;V?[)[k~BQ̴{-|铬 >vn#ШZWK_aw_Y:\+,A:S_ gZ=I1Mr9JoQ#lP"Ŝ[zj6~Q^lfu`w[*t.vv:?IN|3Ng.'wc݄'ss /8fe_r='39QMhb/ޚ,yZEV@zK *\Җ>8,4Iv ϴTSѰq,o⠡s WV}St(MɄ%Z-:fI=X:~EK4w^軻?<;nnv@߆yBtÌ_\:Xn dv ]";-XϿveoǓAIU}TE|-J >E WSpS÷}LcP/|\$wh^ا.Vnk%=Tۅ-߂XwVcS]g]-9bl/ݗ$K{dC Dv#6b5e)%_9)YCX3ur=3z#уB~ZF a!r۫2bߖ31k7;\z:&ۛV)͆L:-4B &bvYvԽ r.T:0I%GG)%KǨBnhW$tZsG14YH4=]jw`oz$Fjn@NѯiǒBEZHL3y1h8{Ӷ!A2ų6_/,:D Mtƚϟ(ۈ%Z|<,Nd<Y~4"'i|nVң]}yҔ,75s[PL^Q0cbfmYǑR qtM%|Ѯˆ̌wuYݕuV> endobj 14 0 obj << /Filter[/FlateDecode] /Length1 716 /Length2 2687 /Length3 533 /Length 3224 >> stream xysdu"R >`fop3T L-88(fTZ$T~N&)=J H 0 a D dO(k !hA:c PTv)TJp$@IM4pP5",83עLJ#順˜ A:Vw8SjX3d ?Hd9$LB@3_:H!awm4]ݬmP`:%gMY8AU}%+w.̪Ůټ`Utp\B#_ELsTFߋS^ꩤ6}Bq  nJKT2BK4:$N;~1uטt蛕%cIYUvQ ͩ=c7 >No'/gw*(?ؿY>WC)E)wez\5sv(J-Vfw{]N^ŋr"qh^Aw`$.%M5##U`y }vfxl&QcptmLΎBYÅbiL.X(s7Ƶ@Q,Bs{]AenX;9֫F.SҮȶt%ӮĠ?GZSCޏ$JY+^13Y;10 Ʀ=r]zh&K5txaQ\AQԲ `N *de: x^PySz#E+t_w%YG&ZMj*\\;ɵة2YS]BmD׶0QKܰ첦9uBUHPCx 38*yHd-x9 &nW_`~,|&X Rh<@h-x*&-oz|pe\Y:&8uH6e s)?յI-`ϯ͸y*?d_u1 9o{ZDu*}~}ƆQr^iˠc<#𩒷tP#ei zuX.JE7*+i⹄<vI#Z԰OMw  ^~pءv+3']`^Ynس\77htp6P+f zb/k*-ܿ< 35t91뾚yakZI +ol˖7%6%7ɲ1i=#T1CT^ sĦen ݌1O2l2\W9= p)>|az? Q#]&`sZS("66;F5l#?ϕXdWJ/@;* %+ X'< gzm\%|8MZz{xΠ8B]̙z\bě5:XjK1)7]~Bהk62s'uZ*0ݜ31UjĊs*G. Whld֨^9O5:Lx\CsmR`{s/h[BRe.p,,/'J h/KdZ ilXy :zo;`uvOu켧pS#MlbLr Ol'V;ۑo˹ I:eHQdr_hy( mP%_M@UUɭ_ -^]/aEz\{T_ƅ;RF}3'_xнʨumAڽ҇/2ù%¯P'8:!:/*)1v0j">>迯u`w!oʪ?gr'7/p8F䗊TvIJI7nEQF@D4"]s9$Zze8.U C D EVK%IAf :N%DH܏ɛ<63`JV\RI3 o75O9.%+~ `%8 9*rlFozFunm&u84nC+[GT >.-xB03!xzoUuK endstream endobj 18 0 obj << /Type/FontDescriptor /CapHeight 850 /Ascent 850 /Descent -200 /FontBBox[-58 -250 1195 750] /FontName/QGNGHU+CMBX9 /ItalicAngle 0 /StemV 117 /FontFile 17 0 R /Flags 4 >> endobj 17 0 obj << /Filter[/FlateDecode] /Length1 713 /Length2 3449 /Length3 533 /Length 3992 >> stream xy< Bj$KL٧d02 Ѡ,e_JYY/aBY⧞<u\sͥuQh<( !&z6@@DB@#< VTUA@]W&D'qu#!hMD7q4$b@_xh/%@@IDbp_LP &xsŏ9/)QxD]ic1Cp,+מFx`0=<}hBpZdc1JD`1H]+ Sx`(8t :;~^jzRg$rAY/Ɂ_OCQ+МԿB*@iy`ja|+@oC q߇]0AH@ fE#p@mr*x۾ƌep+"9ʺN!~A~Izlöc3_W¥nfK0*ƖN~]dW*I82M(DϺB|Pus4ja}?x bF\euT,vh#m8؁[?먑O@R؃5h7A" Cz[zosï_l)v[ҪX,c!dus,W-<ͤc>}˧ WxtbЛyLa%m5%-OҤY, ə8E`f|e;l}ԫ<+=ڏ;xUn-X[3ƧmNO[L.,HJ^ LH?޽-eofi+; ?blcM*a8cwzɾH:-`l&N̆Sc8}s?YX@KaD!y\(A_Y%c}NfWt Q14ҰD0`y(Ɯ_z΃///`/n'/D(_n3Ls5Gȝ=#1e !8lwvqYՇi4S;UUC,%)nsfXmoQS{bxe0z L%IU J1Ƈ*?iN~4,t2.1pK37#M $.nczIg\Nu2VQN_և:M D:+ Nuw`x}NCmFͨ4Jˏl&|Y"֤Z/s%+&O3|i*Og 1Il3}QM%ƶo( }4HO1gJ_Nft]bbvPFM=ܵ߻P#F?O+];ٿH⟜xxY&ftҨն}KmrgaB\cF^FW/oC{& K}n% 7.B_D/H%ÒRIŇu( h&#vlKӃ9'bl`2)F\kU\z AۅzluCsz*~߅Sf95$֯^ljg|~gW3MB'=W:#уA1ރZڤq.4cx{ )22R#9(i5M"Kf6jIA=ˬB{%~}@(Ӌnfk?(VKquP=*Mt1YtgVQ?@~v NdLi_X V6cؙ/ENq֚?Ŵ6=~s6X4^%kxCqJ|9J_bx:[£R^'4hEW#f^kQLB @d!GN6)NɋLᮆj#^`SGMu;-iaFU1YnkrQ1W6\N[G}5@' kL)t8 R[hX*@#Mz3kLHUbE+B/,Z4\}wy/&CbD}kyNkií>Is}` x=bgf΍Rw!ϧ@4OL;l8b&B, bh}v+ ?͂a6ZfiF3upn^@A)vKVUJb^ZpK9WLNuo^d!fgh(SOG_< $g:;/XCg,\>1酫:zϛppbQ./~0swLa9<}^ 0|-m~`Uu봋Su';:?Jg^RqűT(fºDZO~ o=5'6'ME?~Y>=x[~l}h9Ny戁=-obVd0QwL]Dk]_|hbT@GD̶f0={!s13QLd}勵9&:' 7ɿ/:_iPۡ/Ys 68в̊ .٠J3^9c_׾>1ܵ!BK3DZɈxLf'$Ò4/LCF$5JvW=4g=Lo~EH,A =w_5 endstream endobj 1 0 obj << /Creator( TeX output 2004.10.19:1440) /Producer(dvipdfm 0.13.2c, Copyright \251 1998, by Mark A. Wicks) /CreationDate(D:20041019144002+01'00') >> endobj 5 0 obj << /Type/Page /Resources 6 0 R /Contents[20 0 R 4 0 R 21 0 R 22 0 R] /Parent 3 0 R >> endobj 3 0 obj << /Type/Pages /Count 1 /Kids[5 0 R] /MediaBox[0 0 595 842] >> endobj 20 0 obj << /Length 1 >> stream endstream endobj 22 0 obj << /Length 1 >> stream endstream endobj 4 0 obj << /Length 33 >> stream 1.00028 0 0 1.00028 72 769.82 cm endstream endobj 24 0 obj << >> endobj 25 0 obj null endobj 26 0 obj << >> endobj 2 0 obj << /Type/Catalog /Pages 3 0 R /Outlines 24 0 R /Threads 25 0 R /Names 26 0 R >> endobj xref 0 27 0000000000 65535 f 0000030264 00000 n 0000030854 00000 n 0000030529 00000 n 0000030707 00000 n 0000030428 00000 n 0000006512 00000 n 0000000009 00000 n 0000006759 00000 n 0000006573 00000 n 0000000913 00000 n 0000019124 00000 n 0000018934 00000 n 0000001829 00000 n 0000022632 00000 n 0000022443 00000 n 0000002765 00000 n 0000026158 00000 n 0000025970 00000 n 0000003711 00000 n 0000030607 00000 n 0000004710 00000 n 0000030657 00000 n 0000006446 00000 n 0000030789 00000 n 0000030811 00000 n 0000030832 00000 n trailer << /Size 27 /Root 2 0 R /Info 1 0 R >> startxref 30949 %%EOF cb2bib-2.0.1/testPDFImport/PaxHeaders.5700/nomeaning3.pdf0000644000000000000000000000007414011522151017537 xustar0030 atime=1613145424.838620334 30 ctime=1613145424.306620349 cb2bib-2.0.1/testPDFImport/nomeaning3.pdf0000644000175000001440000007554214011522151021146 0ustar00constansusers00000000000000%PDF-1.2 7 0 obj << /Type/Encoding /Differences[0/Gamma/Delta/Theta/Lambda/Xi/Pi/Sigma/Upsilon/Phi/Psi/Omega/ff/fi/fl/ffi/ffl/dotlessi/dotlessj/grave/acute/caron/breve/macron/ring/cedilla/germandbls/ae/oe/oslash/AE/OE/Oslash/suppress/exclam/quotedblright/numbersign/dollar/percent/ampersand/quoteright/parenleft/parenright/asterisk/plus/comma/hyphen/period/slash/zero/one/two/three/four/five/six/seven/eight/nine/colon/semicolon/exclamdown/equal/questiondown/question/at/A/B/C/D/E/F/G/H/I/J/K/L/M/N/O/P/Q/R/S/T/U/V/W/X/Y/Z/bracketleft/quotedblleft/bracketright/circumflex/dotaccent/quoteleft/a/b/c/d/e/f/g/h/i/j/k/l/m/n/o/p/q/r/s/t/u/v/w/x/y/z/endash/emdash/hungarumlaut/tilde/dieresis/suppress 160/space/Gamma/Delta/Theta/Lambda/Xi/Pi/Sigma/Upsilon/Phi/Psi 173/Omega/ff/fi/fl/ffi/ffl/dotlessi/dotlessj/grave/acute/caron/breve/macron/ring/cedilla/germandbls/ae/oe/oslash/AE/OE/Oslash/suppress/dieresis] >> endobj 10 0 obj << /Encoding 7 0 R /Type/Font /Subtype/Type1 /Name/F1 /FontDescriptor 9 0 R /BaseFont/DBSFOS+CMR10 /FirstChar 33 /LastChar 196 /Widths[277.8 500 833.3 500 833.3 777.8 277.8 388.9 388.9 500 777.8 277.8 333.3 277.8 500 500 500 500 500 500 500 500 500 500 500 277.8 277.8 277.8 777.8 472.2 472.2 777.8 750 708.3 722.2 763.9 680.6 652.8 784.7 750 361.1 513.9 777.8 625 916.7 750 777.8 680.6 777.8 736.1 555.6 722.2 750 750 1027.8 750 750 611.1 277.8 500 277.8 500 277.8 277.8 500 555.6 444.4 555.6 444.4 305.6 500 555.6 277.8 305.6 527.8 277.8 833.3 555.6 500 555.6 527.8 391.7 394.4 388.9 555.6 527.8 722.2 527.8 527.8 444.4 500 1000 500 500 500 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 625 833.3 777.8 694.4 666.7 750 722.2 777.8 722.2 777.8 0 0 722.2 583.3 555.6 555.6 833.3 833.3 277.8 305.6 500 500 500 500 500 750 444.4 500 722.2 777.8 500 902.8 1013.9 777.8 277.8 500] >> endobj 13 0 obj << /Encoding 7 0 R /Type/Font /Subtype/Type1 /Name/F2 /FontDescriptor 12 0 R /BaseFont/TXSURH+CMBX10 /FirstChar 33 /LastChar 196 /Widths[350 602.8 958.3 575 958.3 894.4 319.4 447.2 447.2 575 894.4 319.4 383.3 319.4 575 575 575 575 575 575 575 575 575 575 575 319.4 319.4 350 894.4 543.1 543.1 894.4 869.4 818.1 830.6 881.9 755.6 723.6 904.2 900 436.1 594.4 901.4 691.7 1091.7 900 863.9 786.1 863.9 862.5 638.9 800 884.7 869.4 1188.9 869.4 869.4 702.8 319.4 602.8 319.4 575 319.4 319.4 559 638.9 511.1 638.9 527.1 351.4 575 638.9 319.4 351.4 606.9 319.4 958.3 638.9 575 638.9 606.9 473.6 453.6 447.2 638.9 606.9 830.6 606.9 606.9 511.1 575 1150 575 575 575 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 691.7 958.3 894.4 805.6 766.7 900 830.6 894.4 830.6 894.4 0 0 830.6 670.8 638.9 638.9 958.3 958.3 319.4 351.4 575 575 575 575 575 869.4 511.1 597.2 830.6 894.4 575 1041.7 1169.4 894.4 319.4 575] >> endobj 16 0 obj << /Encoding 7 0 R /Type/Font /Subtype/Type1 /Name/F3 /FontDescriptor 15 0 R /BaseFont/TNADRM+CMBX12 /FirstChar 33 /LastChar 196 /Widths[342.6 581 937.5 562.5 937.5 875 312.5 437.5 437.5 562.5 875 312.5 375 312.5 562.5 562.5 562.5 562.5 562.5 562.5 562.5 562.5 562.5 562.5 562.5 312.5 312.5 342.6 875 531.2 531.2 875 849.5 799.8 812.5 862.3 738.4 707.2 884.3 879.6 419 581 880.8 675.9 1067.1 879.6 844.9 768.5 844.9 839.1 625 782.4 864.6 849.5 1162 849.5 849.5 687.5 312.5 581 312.5 562.5 312.5 312.5 546.9 625 500 625 513.3 343.7 562.5 625 312.5 343.7 593.7 312.5 937.5 625 562.5 625 593.7 459.5 443.8 437.5 625 593.7 812.5 593.7 593.7 500 562.5 1125 562.5 562.5 562.5 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 675.9 937.5 875 787 750 879.6 812.5 875 812.5 875 0 0 812.5 656.2 625 625 937.5 937.5 312.5 343.7 562.5 562.5 562.5 562.5 562.5 849.5 500 574.1 812.5 875 562.5 1018.5 1143.5 875 312.5 562.5] >> endobj 19 0 obj << /Encoding 7 0 R /Type/Font /Subtype/Type1 /Name/F4 /FontDescriptor 18 0 R /BaseFont/GUFCLH+CMBX9 /FirstChar 33 /LastChar 196 /Widths[360.2 617.6 986.1 591.7 986.1 920.4 328.7 460.2 460.2 591.7 920.4 328.7 394.4 328.7 591.7 591.7 591.7 591.7 591.7 591.7 591.7 591.7 591.7 591.7 591.7 328.7 328.7 360.2 920.4 558.8 558.8 920.4 892.9 840.9 854.6 906.6 776.5 743.7 929.9 924.4 446.3 610.8 925.8 710.8 1121.6 924.4 888.9 808 888.9 886.7 657.4 823.1 908.6 892.9 1221.6 892.9 892.9 723.1 328.7 617.6 328.7 591.7 328.7 328.7 575.2 657.4 525.9 657.4 543 361.6 591.7 657.4 328.7 361.6 624.5 328.7 986.1 657.4 591.7 657.4 624.5 488.1 466.8 460.2 657.4 624.5 854.6 624.5 624.5 525.9 591.7 1183.3 591.7 591.7 591.7 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 710.8 986.1 920.4 827.2 788.9 924.4 854.6 920.4 854.6 920.4 0 0 854.6 690.3 657.4 657.4 986.1 986.1 328.7 361.6 591.7 591.7 591.7 591.7 591.7 892.9 525.9 616.8 854.6 920.4 591.7 1071 1202.5 920.4 328.7 591.7] >> endobj 21 0 obj << /Filter[/FlateDecode] /Length 1601 >> stream x}WKs6WhƤI$6Iөiz$HF*@I}J"~Ye݂׋WMzq]$M?ŕDJ)n˿~|U2"#R)>>*U7LVjR,(yIYZ54#KT%:M2-")d}_&U_fv/ R6$72?\.[%xzK4{f{ fy!xBzU\ˤhf o%?2|nr')BC FeE{!FƣR1j@d@|S/ e` epMfW|< xs01 RXyG$yS7o_^ZQ@͂$a=U!UC;7f"#9I~ x~,zYBmU('F(* g9(+Vlu˦ōtW++ʛŻ%T<(Ġnn &h>h>؅ը]x=0z/Q'S){k_+o!q aYUB37S"1-B9Q-BipXxXZ8k`[ L˴x$j$JUdk?Y M>[,ňQdp*NfO6\qE<Davi,S\|euji2mXgRIsLvq^ކBaKpȔճajQSdu B"t#7^ω{O3;_Hg^PGNHx?L'>)20,Њ 4+Q`Q< c.pPm&>[LY0eCN(8&fa>!R鸥5]Dq(!p%ptcYbԬpwSxN{lEFf#IPӦe ݩqLB®B/?W 2j<up0zCXQvw뙨-a;<7^`u4菕cC TxrةjP"F*ir@Ĕ*]Fc~4ݞZfM@7;[a |,\"q=-z{fm2V3HP!Vz$㬇 ͙'M)# ` :W04;UDy8L|Et64֛Ȗxqqc "e8?YdɖG΢h쀌qIY4tW0;ƢP^PUW 0c hčl>X0[hwcW$Хn29I%J*Kr9DoH!gm,>{ȣtgF ; %!ۘP1:@3v_t'epCllLu0s3|9DKx333#Qi¿*#8}JK JJp/ ggcOz ׸rg~cu:%./ռ endstream endobj 23 0 obj << /F1 10 0 R /F2 13 0 R /F3 16 0 R /F4 19 0 R >> endobj 6 0 obj << /ProcSet[/PDF/Text/ImageC] /Font 23 0 R >> endobj 9 0 obj << /Type/FontDescriptor /CapHeight 850 /Ascent 850 /Descent -200 /FontBBox[-251 -250 1009 969] /FontName/DBSFOS+CMR10 /ItalicAngle 0 /StemV 69 /FontFile 8 0 R /Flags 4 >> endobj 8 0 obj << /Filter[/FlateDecode] /Length1 720 /Length2 11820 /Length3 533 /Length 12377 >> stream xUP%qww6 lܡqƥ;4n[#C9sĜ;/61UkW+WDR}Sa634ubdDY,@ff**QɄ 01;rr" PD,̝tPqmL,@y_#5@[[#@00rY"0J\LrhIJilgk061E`R_c ׿K8[[+laZ4l읝Lv&.0Ϳg@F¶f&,%,LY8LA֎&;ILDEBQ_7C9-;so[ؚT@  w(;7OFV>cfp_j?M\rw+z !}-;d&É>,Uk44"(%x&7WEa3#?ar_MY̢N:G?bK2 &gx[gzI5*ݛai`_c9#[ZIT#\1{e T!N, u'8ͲS=ݯO~w%cymK4 6~jǧ  Nyn 3pQ#Mlt>ep\A)yTA1.đST HԥזMQeR[-Ẫ)mLD},y[VvrgɪЁ>X#$]R\GKsD$+壎ci±mA}0 Q1l# t l-Ԝ^~7n8!2EԇU,>F@41J4|@)gO ̺㖸V So6b HgFt^e#|'֥VQWQ=#9K"wzbv],Pƕ"- s0m,SDͷO(: OVQ R}8v;9wc+*_aP_[d`抹\B#AHGv}UV}n|^l+㈙uN$m2Ʃ۹W ,n&ՐAPd[h|,"p7%&CIDPIzh]ֺty]7WH8]w'C`OΕWS필`>$ݛ;Vz!.Vן *Xhv>׏ 'Sb}CK05r扩\7* yxBiy6+Dɂ8s%܄S,eS,sPR6%Dt|;|?8{_.>vqL=//t}M&a\ <~j`ԉ}+@(z:1ےbZgٶF"o>@IxKv-ɛ(F7gz㶨pD_YOY fAP2k-vmח=1z6[O?cK7CaG/;Ov9{gsqzؑ=\)ɷJ+Iv)%(z9DT7|s1?/6cЙ'[RsH#zZ$&%I4(\‡@w@[0[=3ZdO4F\-1t07ME{BJ0sq{wd]D$Z&$@Tz( ih+MRKB;4B )R?jO=o`a MU+旽T9$c$2s/2UZyf1S,39&wsP)f$62,6ݻ{H;9=eqxЀEO-T=4.iZg;, l\ *(}+SJs0DX_.]kϷ{x0_]PM Jw,0bŚx4Q JZCjI[g"_;\8 P]e{CozDj_d  nI?3(PayRBIPlaI3Ngf.dp.Ñ`gX3Q?\!~XP0ͮ61}<;HʪHk-Ă#ycw- ֔En=iv`ZJwE =smi:HRR/[t DV8itpnR8jW(e ;7F2/H0"h-B4!}%Gw*#V!_L!'ʱ:C/ņ\PЩTݼZk{Si kHy5=9-sMrÇ630:?8> R"㕧bb\ۻ1d2R2Ji/fI6d_ڑSrFĥ2KX9[߄ZA`40:h5i>n|PJڬz;ﴸ=BC.4:$ jY5y%@4ŝfrrL^_;%?֭%S'v([]p mE[G.Mh|"yf]bQxݐvmA2dW' ?\:)A1f6EP$]k hy] il vVO âTMn 97=7Z&}"h;H+5=l` RucϭZ2QMϮ) Rt'X4_Lړ7d 6NrO13v?bhR 5[W~ߺ'G>ڲQ.zmo;~cHF׍՘qX4gS%@䆓:qLdԓ  b{I}(y'4hΤBý7Mě%Tֿg.~h\h|"o ̤u/$4t# #e\ZDT[~ $LPQ.%= n Ȋ p̵DN`(Lm$x 20Ee ׄ.;02nDoM%cC]YH( Q4 ſ%`z5&_:ʬ&5GQʛj҇qfHřsPO(% 9,=v3Pj{*A.le-rMRPi", 'N;8-Ƀߥm~}2¯~V߃EKo̢0pR<5=81<occ/rt#NnU%$ l; !yh8sQ{]xT,QM,rip_NS(}?fpyXRv[BIwC89ȪkԬ o?9Yt/7{Q^Zm'$-=V J6犷SPw*xtN| pK֞RFr& &OV0җ~ ;|]҇l r_jC}u0sPZ#B0G WA#rǃ?LN|ǜmEb.An/>(?pzD>h/a{&Lћ}K<^m[I$XLD_1b0UayK)ML.,ߙΝjR(v3ioWT9Y vS9Lo33U $1,h+ᐫy63c.~,_I0&xso!#P KÔ7 `reMoGP!JT 3m[HTy3y@eaHԫIt~3^l/g$V=Rf^hMin1:IoңnzDXryǒ:q9XLUGVA=ݫmEg$W;s&GFc7򳾚*rB=\mb:I~d~?gPcXoz݈N-F(WWzX-w*vA'xAX=›fڤ*r5N$E t̶^_Cϓ΃s hBMJ|4.8 %T,9WH˔OTe+dZ;y2SraoP~^2"8ʜ'T9jþKg'38bOP >?bu ߔuAJݩ| iC7NYjb,kM ӒUogaF*c@r1#)#>.+YdkB?$˿6GPHd񔁋:-X!<21s>%Z6L&PK6gЁkǟ/P>"ՙ f}ika?Wݪ Go\X]pb AH)vl}`AgZ o/.:mOĈOfUhtPȖ{h #[&>:]ɾ{ϝ+CpT [O{Y)l[ 3zQLXã#S|/mlS޴^ʂ.٫Tǡ^i\Q@4&4u="FPp*Tl@,"҅vm6]w뼅n( u[" } \p=O)rvXEG5d3)ן)vkM1lXp&xz*gQZ-UʞX;[4?ly;Ey H" E($8u@`O2U4I=*uF[Rlsp-G`emӝQxfܖdWIS.!SuvR?޶s5*̓z*S%gwf %R35e~tهD)K"^Gm~&4cwmH&jkOT xkoT.(>yuʄ9`ܭtaJӎς @Gl2+*Vb1D+K7 Ӓyz*.%π[OzqդisGD(mTN`g5lY/Nql 'T(,"cU? +pB^5%Sr_kD l>ݥLUvgk줙wQagw˟/Ht '#Ԉ{Ky lÌ(M¥;wNK ZrŤP }!C@}?;_p!cT?3!J)(328Jwh9jXbDAӻW?װ a=FMAٳj=3-tEЙ(Gy g͹:'";U"Ɓ["{| Ԁ\?l%+r9=tu]|x30ewgݰK{Fj=3ivBi:؃- W`hVknHP¢Ď XsQM-Sd h3ihЊRՐ&op_]4[Ї"8e2MAU-(*2 RpdI*w}[igiÿS亠7'gNi$e|;X !n]g"?WއΈ6tS+BVT?;PR7o͐c9]S7ӏ.eG4-hT4LXAlqi*%H>L+۝[gֽ~QhP)ynQ&4l"L7щ*-~˟=ь_lYɉB8<1#*=6"T,@A%I@+ dX"=Y7uM܍ӍPt?^ gaoJ,;pw|+" + s]eEm{rKh6d,LKЊ?% PП?[#_a/>V+)܏9Uy2m6d}y/>I$^lkX2*3*Bsuv~fcW~G}f _^uH'd{RdwVKGorTt(_ ):P t4B" T:7_ 5|z SvG-zXG)o!^%I dOnzi|ruVY46Yqf!J|I=S:buzkq[ۂRAWNxaQ>I,b`Le@)0Lt˓9.K\ ΋H:2Z⥠aD>L2M#fp~ټ;tĝW?%$ZhFOnuv%zC_ǍO./ v_ƽRGDt ZVի{]y<"b7:>gݗ(L\TKlt,%aąKL"4 @#.pjK?Ct^Jp( } >tMbo41"CfX\ L3)lbqz| =MpE<0vdGxĢeYpշ뒆c@Ͳlrfx+n(&L-;w'3z]:wR+mL`E/aU}&/LbIea틶:{O~_YaeY>Gp>o^zU>;howudc]-vUy٫_ )x")WC C)IEe&\bKib9}QxI͜͟=& I("P9DJ M`ɱdԓ)tR+{X]:ǐ "<kܲm ځ c}W^H+)1\hVjk*qۋS;daHn S~ {LY7vJ'%I.Ԙv?e8jvj3n$,XҺ\;{T-R[J > = ݮ1< Dwk(Ǹo&Δ6,~èF3Oi)_ CNX|:47Oi?q¶w,G!Ⱦ(-u"J lV~(K=8B I;ҥӟ*н?W[HC;~r#WAXfbrI%8"cwA|wbugG̟Tux 2^#ī4W{Rڐ9Nt҃_Q A_pX> rRK]]r}ʫ")Pi .JcY 3 2OH/A`R_W,_A1 GqLsTI#ZdB,v=> endobj 11 0 obj << /Filter[/FlateDecode] /Length1 721 /Length2 2808 /Length3 533 /Length 3352 >> stream xgXSa HU)H IE@BrH 14)J&H.RTFiR*"R.:3>}o{?ko1!k[i44$Ir2rBu!bbzDIH ȩChq**B 1@O\$z?Tʀ$bPH<`$y# P/:X,`~ Z pbX&x{g$q?I%#N4РD֒pC.C+w$nX!%̒ls1 !k|~1׀/^g-]mɆMn̊2z֠5Mdj+H甃t/]ec)S&:?IpEvl|} s L*Nn/hp ں7ۣtT5{`gu͑vhι5wr9b݈SI[bXm\n5"k2ĿG^R{oKR6A ^AY 4tkR+WGR[LtWNo{BødWv A1V Ȭ`sك#D/p,=}@GUVyi j2zUέ:<9 ߋ"7Mӑ257 R{'y..I1~)&!'s;Bm>f}l48)s kjkmmgAԷ0,$QU. v\Iش~VAYevQ a4ޜ4yI|w+sU2\wX(;L9l3FmKDwZpN,~*ʷ%WKfйKJ+lDCN/ jyx9-GbJ3jz½ ¸Zwy`se4H X/kf|Qϥ4}Wmu6rfGF-_DS W(SSn.J>fSNg/H)\y_<03x]œsIKʓ:W#aE6ܝdԀ0z; L1oT ©rӋBct_>M6Nq/vgJ#䩌Xd 6 i;5ewjCGEFᔅT/AX#ĊԋMXY>+u͛ WyβN5H_mH ~ k!|]7cuWk6f.M ʸ$LntM!ojH&ѳei33 ڞe4eBͱRpǹJsٯ0=c_8l<7Zʹu%g<-h^wC5.8RHiO0/0A^Y&\$v= /*)rd{q&H -GEc>6gvIܪ9sdt^#oX\4\fk-:B)evSE-DwP:y"UaP{R烙K~S3[bwЎXTڳŎiUo<>sJd4]Jvvp7']B5/^0mX YAui3ڵoj,Tp/'{KlFq%4'N%(kf~[P3qL}k1_JPma)>gŨTJ;5W<&?tNMq cE0fUMfI+RU^ yꄣ3Rakcn$lEǐTjȁIW_@F;V5X a#=5lMMM|A;VrlBݧA$Q CI o5` Sxd̀g_b!N|AȥZnm1*Li#*76ve7Tߟ+Ӗ[q40eւrP15lA!ײxi}(uo<(#NdHzX;luOY69wSǐ~Z"ugkvGOa׏ wso/F}"ݏp0G-`q W4C"IAea$Jk݀ ֥jR- Jxd2nEh.w#E JΧRɋBQ)~]b ?d)OjU9Oy&-^~=;[ث+o1J! (w+ek2c?Ff ڂFTD9w{+׮enqK,JEyԄ|1%%u*'t4 s}R*ކ>1q֊ȩ+#R>2^S$Tv+[;zrD7!plX#nFrdI7 3Oښ}}>&أA``&?v`=밊ΔͷbzLjsUe4ҥ0yXv72>VNfg0uZ ڶ|@lVb'L> endobj 14 0 obj << /Filter[/FlateDecode] /Length1 716 /Length2 2297 /Length3 533 /Length 2838 >> stream xy8TǭLT ɱu̐uPL5L3g1Pd+d_dKq-,%/]ze, s=9sN(2h5P>`fkkp( dl*&A}@'G@33Ebf*_]dQID:`Kd{>!$" pb ; ( pz @pL%S' SwmN`̠ӂ2Hh1,1ֿ1ŸF#|>TZӟ [dL4* EDd,M(DM @ h+t ?rڿaQ< Wn?L3d*pbd"T:ڀõ,_'T_t`0Q7bt`)` HdfIPeV<[] c!tVs>XI㇎. acSהeѕm [V AARR'Wf5j\y4zw|ZYȹlf69ڍMOɷ]՚:G.O7p铆X'eV]Uh\Ԏ:dq"tlHJsϲ3GsqI"բFޝ#_dz̭K2g8dgg* K\R:)_JrKO/Κ+vxu;Whh0vO{Bgm _B:*O_4[y]x2m~&Vr&NE?姧"خzo8}ZPfIJ喧Ê} lSآ{L&' ..i hԊa|ޟ`4PҞNj*F+T`gNNh0CfaЍ(ns_r3ee/M$j(#_R >Yux10F OYuSxdKP-2uq$Fךl6 ??߫*PhboG ۜs) z}V<#34{Īשl:0Ͳh-'\=/%q9Q7ZРR.ህ!`3כyxM[ )+<Åp~vˆC.ˁ!`L/TW;X~j Agq,=!.Pa͔2l6& ^AϾ: h̉,XESH[7{gR{/j1mh{|8Q,v0{ 8 A ėJxͻαöw#K*,4Uӊ^iݪF2'pª! 24OY^"'R ZUITJ_9- ~^ 7_ Z lqBcX#2~Ku>}^ӭR*'2qH|ne7^d}tVHO3iS{ܝ]'n{پjQk~貂ϝj|Sd"n85oTd^H|ͺoRGxtwd?eLL_;k.P|:%ŶuMn_~N#cL ^zsqK5zqV$q<);gNe\*4LƼn uJXdeڹfR]>~~ m?RhOhc.{N˷{qcPN)v=O[ O͊ mtnM%ug`uc~"Dji3)&_$rZ.jdAa+D늣bz 'ckk©mzCig=%Y#'#so?~ܨGM>x}ᓲܢ>|^˯f>}NPF݆#wՔ7*ޟەrXȯ6m{>}7 Uc,x_jQKz"Y~!_Oh fYVV endstream endobj 18 0 obj << /Type/FontDescriptor /CapHeight 850 /Ascent 850 /Descent -200 /FontBBox[-58 -250 1195 750] /FontName/GUFCLH+CMBX9 /ItalicAngle 0 /StemV 117 /FontFile 17 0 R /Flags 4 >> endobj 17 0 obj << /Filter[/FlateDecode] /Length1 713 /Length2 3449 /Length3 533 /Length 3993 >> stream xy<ǭAvH샱2dɞ}L c, }I2*YCdɾfɾ" Y%~9w^?\Z6 bk DD 4D  %5%5y0 =I(˥ @0Hh =C,Ġ$ PzhF|(0H"&b\@?e_-_4 (~yxL$ 5OC`_6%CD&x'.)P"A\hܟF1DF8@Pg$rAY/Ɂ_OCQ+МԿB*@iy`ja|P= XNNNYI!8Cp.h$ 1IJPryqQ8.g% CXg2ʼc[Ǥu4D=qDZD/+]k7VKzmK'۰v+&7Pg6!AB[α5䈾QdN \/euT"vh-m z K.y-Bx83|t\^J XC۝7.xgHLO7b%_Ek呈"Wl5Us6ڙXn[۠6Ktxi)iMȢDek͈VTߥeǮ&b^&=l #E߽NuA"Xa>%=OҔY]L hir0B3_ٺJ9}xD̈|*_XS'NOZM.,JI^ LJw<޽-mofi>^~2~ĺ٦Ϛ\eb-lMR/0NM ٴa/LiT⇵DKrDR|e攌9]Q3G5GH'(6CÀeXs69Ѓ -0͕?Ţ)~H@t)sߍO:>H:?n. {Wk>ޡMh-i-cyYЬ'D:|9SJv#T#2~ޅX|0Z}ZnohԴMO 91/pcX_ja&r^e%~D^Eu*JJvy%MLu619;) m#0 /zVK^O|&is9r?ҥ2Ů!qjsŃQP G8Yl;)_SavGym>32ru04ob;ifXKt(dq<=<"U|Qz<N)9H6KEuBn@~2 c[5\cY|{b'd׾YzCK.~iUhn0rQQK&W0ϩa$qbs; >͝ ]݉O]*FPGbd:k.4^cxG )**J#y(i- M"Kf6jME=ˬB1DyEe{y3_y%BۤwROxe!+Ahu@3\ 8U9cꃓ BN\40rYZб9룦 Nm+X@fZEHNڞtApCRKT.X!wǹ:\ /Q1+]aSʹ"R TO@/vhHp&!]m& ʐ#'L{z^T.xWC5K5ёN@J3X&t0#ٗ UΜ`YyW.7֭lŭ{kzȺ S(B0.+I*P y̚|?)3*T1ɽ5he;]ūݔ5+o042DzIY=җ7vqK1ު4g+2B7"ݹX].H3H)w G[|IKF;^ye1\aA0F4O$upnA`A9)vVJb^W>/AW4_Q}ȐCо=3R@}=Hy3|Dep^ȾXjM?八>zϛxpbQ(ꉜ=;yX1E |Cg6+*XuUDuڥi:+xÓ- ۝ۤ.)/8wX*{ B`ݢmp?$ēͦFKqH,"&օ_'G߬-Ve*F"xZ@s@obvT0@%%/f~OC2 D+a$[B#־cccJyBEHfS Y 0O)e9 ١^HZ<E{xP[='޶+zvMKr 'X4@{ $ endstream endobj 1 0 obj << /Creator( TeX output 2004.10.19:1439) /Producer(dvipdfm 0.13.2c, Copyright \251 1998, by Mark A. Wicks) /CreationDate(D:20041019143933+01'00') >> endobj 5 0 obj << /Type/Page /Resources 6 0 R /Contents[20 0 R 4 0 R 21 0 R 22 0 R] /Parent 3 0 R >> endobj 3 0 obj << /Type/Pages /Count 1 /Kids[5 0 R] /MediaBox[0 0 595 842] >> endobj 20 0 obj << /Length 1 >> stream endstream endobj 22 0 obj << /Length 1 >> stream endstream endobj 4 0 obj << /Length 33 >> stream 1.00028 0 0 1.00028 72 769.82 cm endstream endobj 24 0 obj << >> endobj 25 0 obj null endobj 26 0 obj << >> endobj 2 0 obj << /Type/Catalog /Pages 3 0 R /Outlines 24 0 R /Threads 25 0 R /Names 26 0 R >> endobj xref 0 27 0000000000 65535 f 0000030282 00000 n 0000030872 00000 n 0000030547 00000 n 0000030725 00000 n 0000030446 00000 n 0000006451 00000 n 0000000009 00000 n 0000006698 00000 n 0000006512 00000 n 0000000913 00000 n 0000019380 00000 n 0000019190 00000 n 0000001829 00000 n 0000023035 00000 n 0000022846 00000 n 0000002765 00000 n 0000026175 00000 n 0000025987 00000 n 0000003711 00000 n 0000030625 00000 n 0000004710 00000 n 0000030675 00000 n 0000006385 00000 n 0000030807 00000 n 0000030829 00000 n 0000030850 00000 n trailer << /Size 27 /Root 2 0 R /Info 1 0 R >> startxref 30967 %%EOF cb2bib-2.0.1/testPDFImport/PaxHeaders.5700/nomeaning1.pdf0000644000000000000000000000007414011522151017535 xustar0030 atime=1613145424.838620334 30 ctime=1613145424.306620349 cb2bib-2.0.1/testPDFImport/nomeaning1.pdf0000644000175000001440000007576314011522151021151 0ustar00constansusers00000000000000%PDF-1.2 7 0 obj << /Type/Encoding /Differences[0/Gamma/Delta/Theta/Lambda/Xi/Pi/Sigma/Upsilon/Phi/Psi/Omega/ff/fi/fl/ffi/ffl/dotlessi/dotlessj/grave/acute/caron/breve/macron/ring/cedilla/germandbls/ae/oe/oslash/AE/OE/Oslash/suppress/exclam/quotedblright/numbersign/dollar/percent/ampersand/quoteright/parenleft/parenright/asterisk/plus/comma/hyphen/period/slash/zero/one/two/three/four/five/six/seven/eight/nine/colon/semicolon/exclamdown/equal/questiondown/question/at/A/B/C/D/E/F/G/H/I/J/K/L/M/N/O/P/Q/R/S/T/U/V/W/X/Y/Z/bracketleft/quotedblleft/bracketright/circumflex/dotaccent/quoteleft/a/b/c/d/e/f/g/h/i/j/k/l/m/n/o/p/q/r/s/t/u/v/w/x/y/z/endash/emdash/hungarumlaut/tilde/dieresis/suppress 160/space/Gamma/Delta/Theta/Lambda/Xi/Pi/Sigma/Upsilon/Phi/Psi 173/Omega/ff/fi/fl/ffi/ffl/dotlessi/dotlessj/grave/acute/caron/breve/macron/ring/cedilla/germandbls/ae/oe/oslash/AE/OE/Oslash/suppress/dieresis] >> endobj 10 0 obj << /Encoding 7 0 R /Type/Font /Subtype/Type1 /Name/F1 /FontDescriptor 9 0 R /BaseFont/SRPUXN+CMR10 /FirstChar 33 /LastChar 196 /Widths[277.8 500 833.3 500 833.3 777.8 277.8 388.9 388.9 500 777.8 277.8 333.3 277.8 500 500 500 500 500 500 500 500 500 500 500 277.8 277.8 277.8 777.8 472.2 472.2 777.8 750 708.3 722.2 763.9 680.6 652.8 784.7 750 361.1 513.9 777.8 625 916.7 750 777.8 680.6 777.8 736.1 555.6 722.2 750 750 1027.8 750 750 611.1 277.8 500 277.8 500 277.8 277.8 500 555.6 444.4 555.6 444.4 305.6 500 555.6 277.8 305.6 527.8 277.8 833.3 555.6 500 555.6 527.8 391.7 394.4 388.9 555.6 527.8 722.2 527.8 527.8 444.4 500 1000 500 500 500 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 625 833.3 777.8 694.4 666.7 750 722.2 777.8 722.2 777.8 0 0 722.2 583.3 555.6 555.6 833.3 833.3 277.8 305.6 500 500 500 500 500 750 444.4 500 722.2 777.8 500 902.8 1013.9 777.8 277.8 500] >> endobj 13 0 obj << /Encoding 7 0 R /Type/Font /Subtype/Type1 /Name/F2 /FontDescriptor 12 0 R /BaseFont/XHPQKW+CMBX10 /FirstChar 33 /LastChar 196 /Widths[350 602.8 958.3 575 958.3 894.4 319.4 447.2 447.2 575 894.4 319.4 383.3 319.4 575 575 575 575 575 575 575 575 575 575 575 319.4 319.4 350 894.4 543.1 543.1 894.4 869.4 818.1 830.6 881.9 755.6 723.6 904.2 900 436.1 594.4 901.4 691.7 1091.7 900 863.9 786.1 863.9 862.5 638.9 800 884.7 869.4 1188.9 869.4 869.4 702.8 319.4 602.8 319.4 575 319.4 319.4 559 638.9 511.1 638.9 527.1 351.4 575 638.9 319.4 351.4 606.9 319.4 958.3 638.9 575 638.9 606.9 473.6 453.6 447.2 638.9 606.9 830.6 606.9 606.9 511.1 575 1150 575 575 575 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 691.7 958.3 894.4 805.6 766.7 900 830.6 894.4 830.6 894.4 0 0 830.6 670.8 638.9 638.9 958.3 958.3 319.4 351.4 575 575 575 575 575 869.4 511.1 597.2 830.6 894.4 575 1041.7 1169.4 894.4 319.4 575] >> endobj 16 0 obj << /Encoding 7 0 R /Type/Font /Subtype/Type1 /Name/F3 /FontDescriptor 15 0 R /BaseFont/CYZVRG+CMBX12 /FirstChar 33 /LastChar 196 /Widths[342.6 581 937.5 562.5 937.5 875 312.5 437.5 437.5 562.5 875 312.5 375 312.5 562.5 562.5 562.5 562.5 562.5 562.5 562.5 562.5 562.5 562.5 562.5 312.5 312.5 342.6 875 531.2 531.2 875 849.5 799.8 812.5 862.3 738.4 707.2 884.3 879.6 419 581 880.8 675.9 1067.1 879.6 844.9 768.5 844.9 839.1 625 782.4 864.6 849.5 1162 849.5 849.5 687.5 312.5 581 312.5 562.5 312.5 312.5 546.9 625 500 625 513.3 343.7 562.5 625 312.5 343.7 593.7 312.5 937.5 625 562.5 625 593.7 459.5 443.8 437.5 625 593.7 812.5 593.7 593.7 500 562.5 1125 562.5 562.5 562.5 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 675.9 937.5 875 787 750 879.6 812.5 875 812.5 875 0 0 812.5 656.2 625 625 937.5 937.5 312.5 343.7 562.5 562.5 562.5 562.5 562.5 849.5 500 574.1 812.5 875 562.5 1018.5 1143.5 875 312.5 562.5] >> endobj 19 0 obj << /Encoding 7 0 R /Type/Font /Subtype/Type1 /Name/F4 /FontDescriptor 18 0 R /BaseFont/NWSIIM+CMBX9 /FirstChar 33 /LastChar 196 /Widths[360.2 617.6 986.1 591.7 986.1 920.4 328.7 460.2 460.2 591.7 920.4 328.7 394.4 328.7 591.7 591.7 591.7 591.7 591.7 591.7 591.7 591.7 591.7 591.7 591.7 328.7 328.7 360.2 920.4 558.8 558.8 920.4 892.9 840.9 854.6 906.6 776.5 743.7 929.9 924.4 446.3 610.8 925.8 710.8 1121.6 924.4 888.9 808 888.9 886.7 657.4 823.1 908.6 892.9 1221.6 892.9 892.9 723.1 328.7 617.6 328.7 591.7 328.7 328.7 575.2 657.4 525.9 657.4 543 361.6 591.7 657.4 328.7 361.6 624.5 328.7 986.1 657.4 591.7 657.4 624.5 488.1 466.8 460.2 657.4 624.5 854.6 624.5 624.5 525.9 591.7 1183.3 591.7 591.7 591.7 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 710.8 986.1 920.4 827.2 788.9 924.4 854.6 920.4 854.6 920.4 0 0 854.6 690.3 657.4 657.4 986.1 986.1 328.7 361.6 591.7 591.7 591.7 591.7 591.7 892.9 525.9 616.8 854.6 920.4 591.7 1071 1202.5 920.4 328.7 591.7] >> endobj 21 0 obj << /Filter[/FlateDecode] /Length 1647 >> stream x}WYs6~[ș& &n:qqv:m n_=@Q/XU&iZnǫY$MG" E!2M\$MFTwQ\) 2g2RA7%Qeu~tww5U* .ER'Fʢ y-CşU~cVLGq^gl {72AUj_gl4 1#'d@s XExDJh;r Cue.Ư^LI=Svb>VX- #WX cSb'W'Ke>E <'X$,3d<_*LE8O2_\2ʊ9_԰¥pɠXZ156z;tϼ,#Y!40BDžBQqM*p(R.7U+g?:p5>TubF;ݨTQGTI8_ESW<ƃYJQLjxg*֖ {gڙ;>^CԱ`R M]Q!f:AedR < nϓ)2Ol$N#7 /;*$_P*$O- Mi< !ʬJaA>z@̶ww뙨.v8m,#jb3JOڹ %_",Xc5-%tQuvPefMp ONVֿ8JDH\hW:sa4ij*5*]06e>Hs?>)&@08(ywх~Aӆ!S-̠Pf#.Eo[8?a!7/v:-;y!(e (gwyozpOew"{AU]`+ɡ݂|M@nqBw3Iۖ?k̿8@nA\LSXn1 M)9DŇN9y 8!R 5;mPb mYS-Kniu$,<3 Τ"4*֊#śC.J"aOh~7*OX&)􈏏:>/쎍:]O׸j~cTһ*7eZ endstream endobj 23 0 obj << /F1 10 0 R /F2 13 0 R /F3 16 0 R /F4 19 0 R >> endobj 6 0 obj << /ProcSet[/PDF/Text/ImageC] /Font 23 0 R >> endobj 9 0 obj << /Type/FontDescriptor /CapHeight 850 /Ascent 850 /Descent -200 /FontBBox[-251 -250 1009 969] /FontName/SRPUXN+CMR10 /ItalicAngle 0 /StemV 69 /FontFile 8 0 R /Flags 4 >> endobj 8 0 obj << /Filter[/FlateDecode] /Length1 720 /Length2 11638 /Length3 533 /Length 12196 >> stream xct&c۶ƶmolul۶t:ݱts;kΝ/۬U{jJRe5FsGS#  /* sY;:yIXxxXI$/^v^V88J1G'/kK+71HD.f&$ &nV@&f&v$jf@7/&;;63}Ƅ6[l|)9Zվ}Mr3gM',lL&z_k +>7ޭg+v̶k %2"=kkE*7D)Q`* u$.U4dLߜZ U}_G uu7Xa;y3cֻsMU5:ȦOE؉_Ǹy!P#?΄|4w, Γˢ۹-/{3W"6@!ѳWRo8T?G||aEz^0xNn№YZIvU#NV)Tc!^+]F`| 5wK5WwZ;gzXGkwR+6^A-d>L1>{$02E0a.!E $ǵrcNze̢S1Vrʲ"-h ۶ՕӒI,:˟\k6mDtoOpO]Zgff4x W’K!?f0h ZMcVKK JOEQGR}J^a…ͥ=LERM?lsv H뱐9|">dzôT2erF]%q0?}&TXn}I(o$Z>Dl?[ )q3^"uטS2=.@K T12Kxut ݞGj4PJL\Lxg"g_V^&5*6)6!/vE)C;wN[kU_1|@,8z S5qte~QgoFMnMjJ+z(̍ɃdI8fC0siD[ 95 Nk?Uv}Ukr8?[t(UՉ cz 2RS  Y0\ 7a \<ŁҘI UA.녔8$KE7yKZՖTl ,%1|:eSbP(' C׳x]':ѳOgLl)hEb;O\\ԘV܁m0ߴ+J8^+̻8 xߓJ T[4o&"MJ1&])Α*F Y%Lu_ -膀s|ͤt=!@en"75U$3:r2w{h^P5kf/2~Us%}cc4]faFmr^%n4s13M5i!*͚k e~(lwsifQęQNX8A[ПIUb;f 8]̨yC,#%D!}\`/W b9j']rD„R]hy.'FLhJ:8| o="BD5Ǽ3Jpv|}NWnH\,w’6PcU40ZXa;?=|=~ EN,J'I 3)cth&>PWP^s~& ܘ0z?jǦ=t3P([G=0ןVGqlR^R[IZ)d%Cxw%Om[cp*cQ?!}T¸H <w˰" 7z/:>v* -nnt٠.1l<=[Kդ~.9|4,'Q ZeEIuTO1cG4mV2lH23rN)g1NL*N5[hd+U_Ɛy3AzQ88+R$dJfj_'7y b? Ӹ(Yմ%9rѷ~*dٙSs3H7yaB*Nv=XvD=ď@vK.dǫ>un9>GhK Ϸh?G~Yez&>'!wmhxax~b>4Tä[^+*3nhOK%EКsrDv?8+.7db1F5xrOxNY~H]ȏajMT.} 1 z5Xwy)9̚3Pl?#ȉmzKg>$7T2fEp[;Gv6}d9Fc7n!f{yyUHɇ2`D8k}2[ Q@O+ g7jI<ۢ_^? =xW4vB7b"1e>){9Nf徥j2VP㟍Z?biuYVQװk$AǾWrb{Yw=ZN՛k/HΤGt;ө\_jq3vpb#Tn6͉9L(9pDŽ +)z1cAyT,3?6I՞]MuPw妾ueoDYEٗBt9K=`ʠ]pѠ@4m.u+i _'_WI6ʛ:#z_2XbA5fjOt-ToMO^ ^P;73ZkhpZ;37Bhg1i)+(wӽMgjݶ^X*鲜aÒgަ(ZG>Ju^2n`ZӲ`. X=s_~<3aЅC>wiu5ٺ a˒L`"]x߻(ǥIQ`ClY{xqQ 9'c=;s[3nH#MGFQZm}}IϦWyl@&0\0zNĭQ=0|ϪVs5I&&hr"hl \w"lǨՑɉ*mrZι:"8*zF4#]8LBgž%ƿ~4 p|6t}ϯ6fIpXhҎZ $ƛN (_2xέ vOʷB%4Nj[6f~`P uptd&5OԦ=V5PIHErcBp`, .eݭtM!bnE -:mHtI'ָ~gn^=60 @ےn}'{ڜZMQ|PfoF\`"a8[G^O<Y@߰#%A99;̑>D 70\ ީı8>Vqٷkg7lք [} #\w U[Iܢ,yFs.X+c\v86Izp)b|jW< %td j8]U "E []&A|%8f-'[X_"ncʉX{̱kht'O\kf7#n0c1vF_bfd5a4%sP qwnf:,FpfH<xI GU/A'{VI@ T1&zQkx'UKh;ӟ["gj4Qu9.!((lJWA"/MD7&tw YF t}j0DU(^*Ixpa#3 ѐ_"1vQ=8roWI`Tj3+iWK+ |JՀc\.V~\>//O=MVĈX+.D1lX'%k<d IؾEUM8rP\zr>_>SY8&ֆS$tzDPMME.#GQ3>U5Smk\V*S8E~@4lGc'ק5vQsl̷$oܡ/H`}$>JsMOJY]@}M^kW`ewסGP4GK5se*)brT >ڱ,;]h7Ql4VQjp|ymIyN%J4e( ӜZ+ =27~e& bx* x#Wz]NޗS]Shdt=挴̫"4oKI*~!F˯ǡΖADl?P9;Y%[k8;u&/^4]N]ӪdP[ P />:TcAJ!3ƏyynFklޔs(0Yw^?yaXYT^*LHE{ c' n&K'҇k+\ȫI^#*TY$!*s }Acjn$H8,zQ8MxkX#.RDVW K@u3,e)gt$e"+7;$D/`ků EyX)o^=BWzkaOIp03e5$*.ӺiJ9Y'1J,4tOa&Cm ^jrN H H8Rڧ'\-?UX~Wϰ}!&M Y}ZF ڂom٧Y# yo22up v,k o'$A'_mLDOt7sda IK,u ĻbQ㍥7L߿ǏvwTX?Dt17εÈ&&3]=tNl$(_ko4^7N9*VR?pxP~>{-Pb_)9pqQ(?\ ޼e ,?ňK(nγ3NnO}f`[P.[E zZMk{aLJl{ aBPrMo^,}/˩搗b"K$('2o-WMb}hYˌdRTsP2dg[+e0abHw6(5)D]CZ~3T[ pmB~X6/p6 m4Wkz#zR] ZHe͐KͻPz<3Qhy'0qJN*+ CQkRx0N6~gF?HjC`{"J{Pys@N(E'(F*[ ՜v0)-X>me@XKŚzZXԣuAW;j 1)"dW^]Cj]/#ਣK[ 6+t _nu0 *X-)|t`gL~' NI :]Y6x!JRuڮz'vT+eu beQ+y15b'Yqf$~2L8+s_0n;O\Sߒ~$0<_lY`cfA?\vU̲CǫR֍I.jiK RΊ-fWsqZ~dP3ʢ $P-&E\#Λ$FwI񲡺z be!C sM! YF5W./$zr50L/$p۲GRŽ!MG#hR\[vԮd\W'iK^b8ʬT_w.}a Rb7EOTE"u8\om,n\8"iP 9izPIriM@fa`[Grs'KY֟&;aaP Zf_$ct2[67RSގ2Q~riO.-A$vX hӺ C~9A l٭i69oV3HyYұZ!}ӱq3.uDʸ''UfW#ON>^VaJ6Y&[gcRJiՊ U$²$T:jBdزL,kD3;HGoNH'BTeozVg'kiĦG8:oP6B ۲A ˽lZS :~AP/T1kY!z6lT?؉ˤcԘ%$\ӱjnɮ/SJc"C5ߴO~lG`]PyEkW+~ vtN 7գ V$"UCl^.u#!8ZN_t߱^;vwCe|-1,= ƚ(\h#Fڒ 59['neg}|ޒOIw|9~t9C"aHw tW1nŖ(AYb=vDQ9S;0 vLkOT"2ڭѹ::jZãG9d٨IDee&YQI<1&k7_z `6Μk[kٌ0T&hM"=X)TmZTC1nv1Β1Vݛ:nfmy yN6]U=~n$˧9;q|$Lqa{S\%*(2raXHl;4oXknĥ|sǙDFXTnuX7,ٱθǦ.g 8 ʧ{LbL)\b!.i7绗B̙У[b\sUs$Ggou}K}L׺7)]nH qO1s"?Mp>,vuDul.7Dz xuFDvrbSl>䷑An_Nx/'pW?G,1vDT"P?l.RJ!LI?ɠ(]J5f? N?F|roWvJ.KZRڃcZʻs?`oomBtk8#RbPEǩoy&ErT._uBk1F,c2"" onJѪPȿh8B?c:>6GPR6+'QHǜ`;Ev)o@ NȴL<*ʙOZFȸ /}^E-/ClOd}nլpRH1gA3&F7ƕg;HeEFn%.u3%*cqicy,D{Da@"0z%@cY3oGYU%0>'YZHUn˕,2 uK"91`~8*إ8|e֌Lu2. "oQ~q-"`b|Ƀohq\zlo͆FⶥfV;VCl[DJ,::@bl;3j|%8V0&B8\Cw:n`@,{QIeb[ڱss<6a Q hD.2kI!z7ɑw3k\m}OǹsBI\Y% @OΏe뜕+-` l0׹i\4DV:ێ3|P0WiJAI\~yWl}Zk4џ6*7р儃}OggfL؎7Uc# %} 5 Q䏌7ICsg^q; oc70 D6雧xY*{֛ZR^Z͜ pe y(%#ѮPPhv渻S ^TQdz~,TNyF!y1қP}ajbQm"іG]k+e2OKKf6KKv(PO?]]fuEh6n{LqY5L"ʽ ؗ2%@tƖɡ(8tYQ~@-6RD &Nf6+\1}jEzgH3>;uzq5gx){s[} ^l)Cp8u>]:Bx[7!,Ib!r!j]G<n3,Y.\!-zL833X}: XaAHYk__ԟa,v O‎f%Mq &gb! \1 .Qew] s]wOny 0D|B3Li^P $(=;DeccܵD)"iH!)ՒG17$~MV"|Qz+)bHTn6lٍkC<RüuCipY%+dS@1R_#Fe,q,pbp=~poiŕ+ͩQy7AB"+*B+JiDG9|q1e+ўJi6ff#uG-x%)Ý#2Y5Yr2@ӭ B'd=7R, Zʗ3b)L=[v r׈ks0v9d>jni;N0MboEp#@53ٕ{i$z&x? 3cv6 F^[Iح^A&  @mKSjs.v!Z/ Ғ tqPcsO*϶-vG#UٸW]^%k:9b` u\P{ǞhH=6 Ի10W F=+;=o&X)o/{QM ;yD]ց>Fc7ؽxtXNy{rŘHڹo(~0 Ny ΝH +lU>vt'ɥgw]>u嚔>(=i;$3=J7j,qPTPh|cBЉdĬg}fU<+Qă/nM'5HzYދ SSYuՍi 3YoW tri,0 |Mhh=T[hceỏ<^ґƇDZ?t Q/ cE %lmЕ\ތC>,*m ~+ͦ:jl 6,AC_v C BI&Ly^1'0OƢq?{t;S¿Z]!I#޿;H]uKFҞldf/я<ԭ'R]ha!vfqd轐o )TFl#8 ! ^^L28 b٨`7\Þ3}³$P$|7Y­hJi g@K<3J1SR;l)@ g6I0c;[|PI<"F252M~P`Qd#$gӇAAHA~ YtZlv2eO)L ?vAxD='õpM<2XŢw>ƫtb*MC6q3Sm(x9|[1t{kJ>d_~U7S_p 3;-:I/ endstream endobj 12 0 obj << /Type/FontDescriptor /CapHeight 850 /Ascent 850 /Descent -200 /FontBBox[-301 -250 1164 946] /FontName/XHPQKW+CMBX10 /ItalicAngle 0 /StemV 114 /FontFile 11 0 R /Flags 4 >> endobj 11 0 obj << /Filter[/FlateDecode] /Length1 721 /Length2 2808 /Length3 533 /Length 3353 >> stream xgXSa H"x(Q*EABrH 1HT4A ERiR*"R.:3>}o{?ko.$i995@BQ`z(T"II9UUyt;Z}jJj0e O /C@"H';2A!-I26?~l@e 99A72h_?K~ I*q x?!~/k9Ց8 K :kcBBb1(]`0>2ƐP;̃x_@n DZ^FbK!;>C.Î+w$rc>Jk—]顼KgV䧉V7gŋ?Kj>n{%Udj#HԇAюұHΜWz&ڕ*Í?IpEm|}-jT kN&ݨ]:Su>oGif*SIn{;_Dw9gr9b݈SIGbX}\^/%"tQwߘj ߭ Q3ѻ%~)Q[Ly,L5+)Nõ<&#;؉/W׭fhalqCf *`ك"Ķ/p,=}@{SW xjf ;/j2zM9 ߫W3f~x?h(sR6voeaO/6w2D5 &D|J3*봋\oͯqN{o%vO_ʿÚfVJ&o`S1Rk\,츆sb vffK_tYD敲|cZdcr5a/kJG'8!<ᇡ2F ŗ %Ƿ# J)OQ. o qph勹fOy+ fΈT(Ul|y0yc\2FJQZA\oDݽ/HmRY* S,*w$1k9Nxnڈ9|y\n|oսѹ *;Y˪7h /8F5nس$dk^|qjBz4B(UM2`, 8iڼQU _yN+tp_4`NY8pLNp|5ZQdbϪXlMlt~KuIu`*ܲ眰ַB/j3Xw;ecpO+-|1AHbA^܉*`~lID/Y6#}FttZ۳ƶLb6[:n8W=i.桇ܣv gG 6Vޤ% K I470tфkZ?}R-aCE"iJY^% >2T4_M`0v}]ϱMn)q`(p`X­(1ON~OFWMM9@ӁetEw[@;W2}n(`efJ#Od5+.?jO_r0c/x|*}fKd:}gE5 zL٬4miA[y':T׵{i<.>Pf!5jץ͸׾U4SWcýI}xqix?gJOJUalJnbڿ:vG^U+ۋQ)9w.ƹeL~b' a\<.AgWLfJ((QkWzgx键_fu d|zFm8{[{!{?|A#a@k [* W>פɫo?Qےw{evvW9EJڝ뷠wJeYZ*Oꨙ8:Ŗ oU1er}As7;\l6KhFU!_ wIkdGj*Cx =x͋"9?)moFK\юȩ'#Z>"N]4Tv+S'zrD7!plX3vFrx7 3Oܚk)/ԭAp`*?v)=㰊ΐ˳bzLJcee4ҹ qXv72>FNfk?uJ ڶx:+^SSH&(W=]ŲxJŕ[\7}i^/Z-2iWopne].{ΰ "$I@ klK endstream endobj 15 0 obj << /Type/FontDescriptor /CapHeight 850 /Ascent 850 /Descent -200 /FontBBox[-53 -251 1139 750] /FontName/CYZVRG+CMBX12 /ItalicAngle 0 /StemV 109 /FontFile 14 0 R /Flags 4 >> endobj 14 0 obj << /Filter[/FlateDecode] /Length1 716 /Length2 2582 /Length3 533 /Length 3117 >> stream xy<C%Cvc+kp,e]) &ha07ˤA ox~@0B8RD_-9%Ozu^_yAC Nvsg.)Eq0Nx͖fkxɨ҄vD'/n׫L)"q7=Mgj_xj>+f\f.ѕ8M>hu6p"AcO3=J?uG |-1T&mgޣYY^GUz\U4.޸hW-;Az^qO6 T]nn6HUBGijskѨ[tP.M7%@n%|Cu ƨ7|SM=:pL}nP nHzձVlBt-3SΣ73$n[##=3nA#G򴀰B0 tbScA,Czl1%i1{:*Hd\}[DMѦqjAեx:kJoS0Voܓfm=NTYmocgԌ=;e$ËTAo>f2:m\pl5G ,ϏjJ9ufIT&w!X62"*i&8868'AI{ ZVtJl'ϖU7e!ɵa( Ϛt6W݀dAnZ[>x~]PP8?M¿\LIB3$gJWzI@rѣr{̊6;%tVK1@iGtk25}sQ w̵83ԜTb lWrƳ6~$pwn)+5bD 3ȟx>hlzN `[؋vTդ'14Ji4ՖP)6WKxe`P,T}Yq<~w{є#zPv\!,=YhL]-+ҲP5S}.8e9?onXˁ7ϠTpb@.)/E9؜{i)>#&ÃץYE G.%Ȗi*JG8=_̋MA[_DFi#[7?&e*jZlordMHs)n!LSD}'mg'fـI"gע)ؖYFt!9[ i蜌ݫU;\OUpbɝ=I!]NL{~LWRP=ǬuaJoJfLFY pX&x>.^)=Xss߈{=,;{cKk{+I$^3ԵD_tר0ÅVtr<#^4]tdg_K{&/Oph~|7eTVABHWr K<^~y@镤D%T:p>~{ZHL(W>mē竏NTtsEmhbv{KE;YB[atØ Q}3c ~W˄u%JI'j_cG :_/(2nmK[RѾ0˟+Ҵtccwb_v,~$zJO* {”Wp-/ vU`WsȘfiFC)[2<S߳׈%~XC 5tZP8fZ8r5TgJ L'u.p"k$d:nI~Qb?~VYj|3_ul}Ry)㶉Ugk{Js]TNTME?SMeg޸>,axަ2PSȪ rjb桐hasK"#/¡(%iI)şxC‰$|zjB%M> endobj 17 0 obj << /Filter[/FlateDecode] /Length1 713 /Length2 3449 /Length3 533 /Length 3993 >> stream xgTS{Ʃ*h)$DJ"]zLĄB(Ҕ^D$H H^H/  4)‹޹יּw̚o/g?9}p ( !OɂԁS=[5 HV * !$  Ձ 55PARVWTVW@LĸK\*h"M$wQZ4, ^^D_4J( vrxWPOWM>Jq^QxBGG,c>8W=a xxD)&nAɦGc an84PO mGyh<G[ gfcJCl<ɒ_5?1@{yYyyБo H wZxO(== X(>:@ 50P,_Vx˫(V>D"O}>s4d<;K Iml4\y3 ,|}k8fw7#°1%xL:JL5Zd|ݵE4Wv r +jg2)*8wYMboMP8Nss\ :r8A*y>C.QU ;Zו *786_ϯ9v-ۖ&sqk>cd};v8!c`|@,õ QF'оW,Å)aI/ClkQ)Hj[T/!. X;ba;qшg29yYoUgh'͉l+k׾Dع`ݸuFg)ZqJn$~Lզla5[x;{ã~2S}MVې"t;]u #G!!͙#xHzC,4bdP:76(a0@kJ+ꁕ'AV7Ds+BHNuXW}'Oz4OZ ~u!%T7tC1$K[Խ%} E 榩aw;x22A- \>ֱ nªS_ao{d@*Y;rT6gͺcLb|a~!Jd,zwdHx S`Lutoe>sK[ 0i\aԇ^h}39qί),7FvO__VU,YY^iB=vaOTc>dib/$+.F杳8,ӝJZ!G*-cowNF\۹"yΝv$⃗Bz_L٣=I2q]HtMhK7Z2)1'ϛL̷3MPц%JӽVZ?_kzu܌^@LC[FQV&yCM6~m 'ulm/I{<¬;73e;>7KJR֙/ōMl"ꆚ)8>D?E,7Z" ߍQ+.aǚx"쇱q$8~rjڤqtI7X HP#oisA85ӻUˇ0:RJFݛƶWIKUyԒ1`D sj=b3:Rpӛ΍1 y jrߗĝ ~y@0uw/? g6rIg~3Jc2rjՊNyuƹY68bʟmIy+jCN坘4sYJ0}#sή*dx˺Üj)6,C14$;j\ƳY$˄$Q Ƈ<5멦hgMDub`|{"[óĻM)I7Ye3k $hUk~1u&& {S2.kFxSl;7uJoܸ0a ʩcԫU,tvqZj"Ir\Oڞ̉J)˓RìOYBםBu'z6aQ\U-MѨiۈsbbq#s"Ő,r3BLKP↚;iB.M)Wj5轌bi*V:ǹϽ/@LY(y㠚9sFb簃3R6ص;r\Zl]k&dU)#J,]*u+li [km4 n~c:"u}0}CdX)Ix58vݧ{c|ke}BY{ZG{}!~pyFgw&RF.E,m 0cyVdz٥k`tYĢwܨ̗Q:yez0dYDĂx ,9-Z1Sr@.mԐp_&^h86:fjif(h1v FFO[ͳQj >>[XҠ\tuVoD_7ݒ=.McW.42_՝fqyRTo~ M~(?+$NыO{J5wJs+ْ4RWc}pLAcrL+ܖ+tl:k΅iدmZ,kSizn1W7ycI~EUN7N8w[ttEo95<:,%xZS$C@FTx1bA#| I{"`DUqEo㕽8ʅhei"91H Ut ߠ3ݚ.y fL^e:P,i^!(&Nnύu乧1[{a.&(&f3ȒzʀR!%,qJeRqd7O*#MVjf'VzvW'wAMJܛC [q^2kxO׽eLl\fSA7k,Nk!&#gwn_. F/ <R{bʱ!hmTKdTKnu^6,Y2[sXk~+Ljcɩvg[VІ[YP>]bqnЬG~E!C0?CvmNGK o}p7~ Y! !]6>ez"f` Hi?_Nûx'rzA< }N 8r5}^Pc Oc.;.t*nvhɮ2`ɇgTQ3'4 ͂uu|l@jH6-?~އE>pKy5{XͪyvE6餠֨]moRvT0`Ee/;~OA#2 -ӍDk$$(g \Iǃp>[- 5^?U|}iø@rkVԀ t:-4f\C}bnjǔ/ֆË͝Ƨ"f6@a5ٔff`irs;Te9#%o v/vvڴO qhD@B endstream endobj 1 0 obj << /Creator( TeX output 2004.10.19:1439) /Producer(dvipdfm 0.13.2c, Copyright \251 1998, by Mark A. Wicks) /CreationDate(D:20041019143951+01'00') >> endobj 5 0 obj << /Type/Page /Resources 6 0 R /Contents[20 0 R 4 0 R 21 0 R 22 0 R] /Parent 3 0 R >> endobj 3 0 obj << /Type/Pages /Count 1 /Kids[5 0 R] /MediaBox[0 0 595 842] >> endobj 20 0 obj << /Length 1 >> stream endstream endobj 22 0 obj << /Length 1 >> stream endstream endobj 4 0 obj << /Length 33 >> stream 1.00028 0 0 1.00028 72 769.82 cm endstream endobj 24 0 obj << >> endobj 25 0 obj null endobj 26 0 obj << >> endobj 2 0 obj << /Type/Catalog /Pages 3 0 R /Outlines 24 0 R /Threads 25 0 R /Names 26 0 R >> endobj xref 0 27 0000000000 65535 f 0000030427 00000 n 0000031017 00000 n 0000030692 00000 n 0000030870 00000 n 0000030591 00000 n 0000006497 00000 n 0000000009 00000 n 0000006744 00000 n 0000006558 00000 n 0000000913 00000 n 0000019245 00000 n 0000019055 00000 n 0000001829 00000 n 0000022901 00000 n 0000022712 00000 n 0000002765 00000 n 0000026320 00000 n 0000026132 00000 n 0000003711 00000 n 0000030770 00000 n 0000004710 00000 n 0000030820 00000 n 0000006431 00000 n 0000030952 00000 n 0000030974 00000 n 0000030995 00000 n trailer << /Size 27 /Root 2 0 R /Info 1 0 R >> startxref 31112 %%EOF cb2bib-2.0.1/testPDFImport/PaxHeaders.5700/nomeaning2.pdf0000644000000000000000000000007414011522151017536 xustar0030 atime=1613145424.838620334 30 ctime=1613145424.306620349 cb2bib-2.0.1/testPDFImport/nomeaning2.pdf0000644000175000001440000007425314011522151021143 0ustar00constansusers00000000000000%PDF-1.2 7 0 obj << /Type/Encoding /Differences[0/Gamma/Delta/Theta/Lambda/Xi/Pi/Sigma/Upsilon/Phi/Psi/Omega/ff/fi/fl/ffi/ffl/dotlessi/dotlessj/grave/acute/caron/breve/macron/ring/cedilla/germandbls/ae/oe/oslash/AE/OE/Oslash/suppress/exclam/quotedblright/numbersign/dollar/percent/ampersand/quoteright/parenleft/parenright/asterisk/plus/comma/hyphen/period/slash/zero/one/two/three/four/five/six/seven/eight/nine/colon/semicolon/exclamdown/equal/questiondown/question/at/A/B/C/D/E/F/G/H/I/J/K/L/M/N/O/P/Q/R/S/T/U/V/W/X/Y/Z/bracketleft/quotedblleft/bracketright/circumflex/dotaccent/quoteleft/a/b/c/d/e/f/g/h/i/j/k/l/m/n/o/p/q/r/s/t/u/v/w/x/y/z/endash/emdash/hungarumlaut/tilde/dieresis/suppress 160/space/Gamma/Delta/Theta/Lambda/Xi/Pi/Sigma/Upsilon/Phi/Psi 173/Omega/ff/fi/fl/ffi/ffl/dotlessi/dotlessj/grave/acute/caron/breve/macron/ring/cedilla/germandbls/ae/oe/oslash/AE/OE/Oslash/suppress/dieresis] >> endobj 10 0 obj << /Encoding 7 0 R /Type/Font /Subtype/Type1 /Name/F1 /FontDescriptor 9 0 R /BaseFont/TKGDPV+CMR10 /FirstChar 33 /LastChar 196 /Widths[277.8 500 833.3 500 833.3 777.8 277.8 388.9 388.9 500 777.8 277.8 333.3 277.8 500 500 500 500 500 500 500 500 500 500 500 277.8 277.8 277.8 777.8 472.2 472.2 777.8 750 708.3 722.2 763.9 680.6 652.8 784.7 750 361.1 513.9 777.8 625 916.7 750 777.8 680.6 777.8 736.1 555.6 722.2 750 750 1027.8 750 750 611.1 277.8 500 277.8 500 277.8 277.8 500 555.6 444.4 555.6 444.4 305.6 500 555.6 277.8 305.6 527.8 277.8 833.3 555.6 500 555.6 527.8 391.7 394.4 388.9 555.6 527.8 722.2 527.8 527.8 444.4 500 1000 500 500 500 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 625 833.3 777.8 694.4 666.7 750 722.2 777.8 722.2 777.8 0 0 722.2 583.3 555.6 555.6 833.3 833.3 277.8 305.6 500 500 500 500 500 750 444.4 500 722.2 777.8 500 902.8 1013.9 777.8 277.8 500] >> endobj 13 0 obj << /Encoding 7 0 R /Type/Font /Subtype/Type1 /Name/F2 /FontDescriptor 12 0 R /BaseFont/AWUTTI+CMBX10 /FirstChar 33 /LastChar 196 /Widths[350 602.8 958.3 575 958.3 894.4 319.4 447.2 447.2 575 894.4 319.4 383.3 319.4 575 575 575 575 575 575 575 575 575 575 575 319.4 319.4 350 894.4 543.1 543.1 894.4 869.4 818.1 830.6 881.9 755.6 723.6 904.2 900 436.1 594.4 901.4 691.7 1091.7 900 863.9 786.1 863.9 862.5 638.9 800 884.7 869.4 1188.9 869.4 869.4 702.8 319.4 602.8 319.4 575 319.4 319.4 559 638.9 511.1 638.9 527.1 351.4 575 638.9 319.4 351.4 606.9 319.4 958.3 638.9 575 638.9 606.9 473.6 453.6 447.2 638.9 606.9 830.6 606.9 606.9 511.1 575 1150 575 575 575 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 691.7 958.3 894.4 805.6 766.7 900 830.6 894.4 830.6 894.4 0 0 830.6 670.8 638.9 638.9 958.3 958.3 319.4 351.4 575 575 575 575 575 869.4 511.1 597.2 830.6 894.4 575 1041.7 1169.4 894.4 319.4 575] >> endobj 16 0 obj << /Encoding 7 0 R /Type/Font /Subtype/Type1 /Name/F3 /FontDescriptor 15 0 R /BaseFont/QADBYN+CMBX12 /FirstChar 33 /LastChar 196 /Widths[342.6 581 937.5 562.5 937.5 875 312.5 437.5 437.5 562.5 875 312.5 375 312.5 562.5 562.5 562.5 562.5 562.5 562.5 562.5 562.5 562.5 562.5 562.5 312.5 312.5 342.6 875 531.2 531.2 875 849.5 799.8 812.5 862.3 738.4 707.2 884.3 879.6 419 581 880.8 675.9 1067.1 879.6 844.9 768.5 844.9 839.1 625 782.4 864.6 849.5 1162 849.5 849.5 687.5 312.5 581 312.5 562.5 312.5 312.5 546.9 625 500 625 513.3 343.7 562.5 625 312.5 343.7 593.7 312.5 937.5 625 562.5 625 593.7 459.5 443.8 437.5 625 593.7 812.5 593.7 593.7 500 562.5 1125 562.5 562.5 562.5 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 675.9 937.5 875 787 750 879.6 812.5 875 812.5 875 0 0 812.5 656.2 625 625 937.5 937.5 312.5 343.7 562.5 562.5 562.5 562.5 562.5 849.5 500 574.1 812.5 875 562.5 1018.5 1143.5 875 312.5 562.5] >> endobj 19 0 obj << /Encoding 7 0 R /Type/Font /Subtype/Type1 /Name/F4 /FontDescriptor 18 0 R /BaseFont/SBJCEJ+CMBX9 /FirstChar 33 /LastChar 196 /Widths[360.2 617.6 986.1 591.7 986.1 920.4 328.7 460.2 460.2 591.7 920.4 328.7 394.4 328.7 591.7 591.7 591.7 591.7 591.7 591.7 591.7 591.7 591.7 591.7 591.7 328.7 328.7 360.2 920.4 558.8 558.8 920.4 892.9 840.9 854.6 906.6 776.5 743.7 929.9 924.4 446.3 610.8 925.8 710.8 1121.6 924.4 888.9 808 888.9 886.7 657.4 823.1 908.6 892.9 1221.6 892.9 892.9 723.1 328.7 617.6 328.7 591.7 328.7 328.7 575.2 657.4 525.9 657.4 543 361.6 591.7 657.4 328.7 361.6 624.5 328.7 986.1 657.4 591.7 657.4 624.5 488.1 466.8 460.2 657.4 624.5 854.6 624.5 624.5 525.9 591.7 1183.3 591.7 591.7 591.7 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 710.8 986.1 920.4 827.2 788.9 924.4 854.6 920.4 854.6 920.4 0 0 854.6 690.3 657.4 657.4 986.1 986.1 328.7 361.6 591.7 591.7 591.7 591.7 591.7 892.9 525.9 616.8 854.6 920.4 591.7 1071 1202.5 920.4 328.7 591.7] >> endobj 21 0 obj << /Filter[/FlateDecode] /Length 1581 >> stream x}WKs6Wh&I6qӉiz$HF*@I}Eo_"Mt_rx-)wŪN<~aRJw^G"OTH5YUT*d%Zeʹd Ȳ)P$+D*&+F;}^VTInn*Tus̟/ɳ,O"y(x,WYVKğOoYUE=ERݽEL\Z͟k&+Y.2 n%HhbE&I^eU0#ƣ\'9/A.d:1IIDEJ=RɄ3`"J_]c4٤ǡ Γ,F)q_ΣWV"FOo:lFpHS[f~#E&mM8'Y˼@VG*r EřxNUe#v]fYUF95IQd=0ƣ  vw85AAMw.څ'18 tKzЫ IՕ^-į=)k`|8,1vcRǣRi0l,k<, Tڍ`9LgO2UvBS@-o#bl%\&S RS/6\qxc 1>j:js1-at+]LMBьp~"u43f6  [%~&F06JI 4 (pӍPma&bF#?'>k$5 IyqI#6i@ $Lǫsz8J*FڝVRP̚{M|Էj} XophzCFqK]Gz$`9rP5~v[b,Ԭpcx^{l2%nxձBwjFЃ+P jďCヌN:a=ȇaE5޷'m&>Xx%++(ʱņ+*CEaq @,*KńyrWt6hfu4Rs|9DKx333#"I#Z>s%zuOJ7URWOJ`/쎍ypb~ku.~* endstream endobj 23 0 obj << /F1 10 0 R /F2 13 0 R /F3 16 0 R /F4 19 0 R >> endobj 6 0 obj << /ProcSet[/PDF/Text/ImageC] /Font 23 0 R >> endobj 9 0 obj << /Type/FontDescriptor /CapHeight 850 /Ascent 850 /Descent -200 /FontBBox[-251 -250 1009 969] /FontName/TKGDPV+CMR10 /ItalicAngle 0 /StemV 69 /FontFile 8 0 R /Flags 4 >> endobj 8 0 obj << /Filter[/FlateDecode] /Length1 720 /Length2 11503 /Length3 533 /Length 12060 >> stream xePᶦq,n%Cp8۸;A[pw'{p9gso=zUS*1ٛA`FV&V>*+ E R h I|V^^6ɆH wphiLAc%-@ `Dmmx t:͘YYfV`  s{f.Yr:9d0#2+R.vG[\@' R-fV.v^ 62Y,JY9KY͔sc[g?@ٿC?%5YUT6=Ƭ3'+w.=soILͬ@51JL݋wXXx\>Rd*daaeg sVMThNiVY ˩h^4mW췤^kA|h4#W4oSONft3So},8ot?UX.)i~g)ElxPxTZ((*}O2omkOo!5:C<=`Z N&d^ MDBiCd8cLa:^ @<-Wcɚ|}Ψd(N `DZAw f0He*5Sd==a[+wIY ziڟ7fj)@SvRdN2ÇxB1Q%+_yu-.!f;(XL܎HUVM/dm ßu63DA7_Iy&夺(Zlov0u&9p<@}zQo$}.?)ۃQ~,ՏYjϪ"H㪡E]^iy#^7^/;,% èAtڃFX K`\h'(ǼOO#.Z~4U{ 'I`b&(O&%-6 s je zeN{<2#JUݻw tBFph 0̄OfO:{Os:PRN-OVGH[5=EY?LEHᦻ/FTz7H1OgI#H+OJDoY cZأ,x` Zv# FAImf*c@Z9()ɶۼyWޕ auU)RjU]^+TA34VK$={ތ+ns/ EzUis|KD36c^_ɑ1J=lO4S!j^@fOڕ^P|g;6CƝT9eo:@'Rk@BNu RQp~c}* fFœ~T'lztYDQuM{ א/:b7hdhMV<Yf"bFz' r;6Y$8n*Kpѻ-qnΣ)k`Hi_PEAuJKƠwpqtG=JS?6F/,קv Kkq*,%[ZsWn*jtK(t0?_oY T?LB`"[a򴛆A5p]<NO@m j\t~eH8|OS < rcܤy#ӿD`@/lJ0{ WOZhgF!c(زw9MU7ᅢ t!"ý td0xbXh|;bpMbL<_ 2kAՁe[?;,H9PLs3D/0w{ۛw VUD|nH[A^;5dx1P`;|,aO&Nt+IU3P똺%} #ö07v&#HDo%؋$Qܐ *COB,dLzp-=7 lXE\qbܒW.-+8sW:n;k:NjM.'#:.qgZB o;6dw;-;r@\z(a jxQ^"9f gjv1Eve^F@q0HMkVRjtz31յdyj6-vtu*(lS ۖT9#k=s3 7=8lҙ; #ar`t4]AW B8TfjUlV!yIy)9ym3#% J@T}S-LISsmn3"--uEX~T"+q+gV](zngImE U haP,3s(_beR4phr ]$O$-%4b ^=,Y}U<^>Wpqӧ_\?噦]Mו yn D)ݟݞZM!]cAe.m*8kULΌ#w+ O%b&S{loU~>@[ هI q%H^}Mg[~kmo…oGg d{ý`ibēF:+^4Б1sjja΢|;d*VB5T`+75ѐʽO(|C &KN ݑ-! OGy=˖\z2J=RU\uŵ z KPMiA!+pז5@1kA!AG,?69.$3XUزxLUuE6,)7ħմY8ұu+vzrfSck$>-S>&LdIapyX1ls4uyptm! <9.V;]-%~s@ vL>"lcNkZMmsd{y\|Kl[UBڷy2MU~BZrǟ~!ON=cZ'RwStް8"Z̞-^IcN>og@BD+$~V{͑k}N.ث bmF?2#1J!H3.JS-ʀ?F| ޾xW_,S_ۖl837ܝ.HԻ"#6 [u44)09o+S#_W0 qQP5K"[7-Д 33>5y>rpbq~<ZꟉ`B,/ ]".ᲁ(YXֆE> vrlm0s& S$|z>uQky|QymLJ/g+=s!]Q > &NJB䇁Qs70.6H (hjEա%U'+u?dh84 N*GdGLB Rj&*VDzYb k8 ~ÁOL8Xb3FJG!$$OYOkV2mv h 2aq1]ÄK!,(.;YK)F\C]B3\HNDFmԶ`;8 zYUEǚORW|yϚ dYOa*/dģYpFruOzd2{^Q7hꡥO'hR ZǽcGu~^"?Syĩ) Q/d0r2Q;U,j  8IE+M H}8ӟ ,]8A!*DϿE9LFSKQOCe̟k#a.|~$-*_" )'- O^kQxt{cl_ RM]ed3Ogs20zw5x:VK0-Sw  c7~.M 2_%š\1A֟.StiD~KGr!uU<ܘًGT)klB 3s}uƢ> MUak鼚&a!$/=( 1_#|YKF;rYW%Ї7ݙ.sѧ{%o yT vA0Ec[QkyrCv8)VD( otb1IoDت҈웡;;Ã)4Ǔs4{d9Bleu~Y FAG拰 90153yGlɈRsU NH{(eM0,.?_,3+ցGy>5 )pt gw=D`[mZz[Ue%"NI Ic}egwg-F54 8>@5VrݬJ#uMr%ݖ~bk켁9|uD:xll)"[zK:GY-st/V֫oe=1 W,ϕ0xk̛M{N?]z^F2c;oS '4[/&({p3nk;ifqw l1 OV#Q=H^Nx1I YRy&WPr|"#3"^(\pd L7`(|=\ea9#Qb>6uVpjf[3M;`EoWi!hLҬWEyX wV1zD1Sx(2|,kl>Dҥho{Q s1-DdiMNrq.8#1:ȴERg$~K&[5SHn%x`R/6@%QSRetƽL.;% AAقRk{ʴpmQ2"D'ԧqH*R>FAs5Wk˕C?$ w<ꂣ֓1FH)@"@K#M e< "+?r}H183о,ցbҹ #BR72.,w1z%!^J G>Ryt@k>gl}&~䒂=W1hdދYه_]BErrB6QnCǯLETs$;LV\b.1`Q{@O!ZP7o_h8[B9mi:jy0 EW1YSvSKQ@w_t bX41_Mh*~YGgo>8N90;U̕X?h>V,ݴRg@4oKp#@>We;2 l Yfz}!~U|[a\U tjz@8N[-~nQ6Hi|h+l$v$!*rDCg5-{ސ}n#N̲~J=D=ިa !5tX{86Sґ5XjddnlG:+y1l='0z+~Jd7U=L)xw҆RgTt䬮E&|aeΘvz]DCXT o6C-R#73,Yu0Ցx$iF'cN\q[ҼZĐ{ɮã "ջa!#U-\>AQ1rÅ,SJ)F7"o FM"x\}TsU.rJ-tKvͶ +2+C|@_LO*C휥2ķ2&UߓIxj9\7g>~͐*/KOU'O#iGq"WP $3nn`mpEy)-3NQYuSA`$%{LAmD)&g5 {Yy1JRC.\&ђGP$^bL ;?MO3 5H]g%4VymT3|7 5 r0.mFO\gP qO$!(acqBд|%LJjl~Ev˗(,[!ELK'U٨+i%HT찱6/9T+i +Fb0S9b3 ).0J%/PõËj]wǭ&bF߭;(ag5y R37շu!0 ǪlPvdbAP&MG[9}{0@Nzw'?@[%=?~q!~wUаu4c_nQ8:ؐlץfz"У#T"Er5>H?rL4#2B>6!9^U;AytDdG'Bzi<6ˎ̧in$X[a d-^U+ r 7m z%`rps}o0Ot@{0,}I'V/(R@M7FhN4{KMz):v`Go LO$mI? džCpOzrvNtR:N(Գt@-(37>u缯:}N7M3 I3hה0Ma,׏X+4j,YYyԹ ?4M0`TzNUm')B3G~ ^_=z'w23]-:]o[]GĊ܂.o5eOgjq=iWz8Ópqtn-Ծ`k%P%Y}}|]Q܇?t"*tΔNH͵2ٵS?w)D?,>:r6T.y4l#pAB9ߥ^ҧ7Ƅ޻RoȘq+j^Т#G5rUXVc{+_X@r@"MU"X"֦$SʊL]{I DnQ}" #eo-@; ctֳ^\ܡR'* @Rw60/ѺPzž}x@dh/{LK=y׹*3&W%.r)O(Qf|u!q$g[`ޑsT_ ECrn̶^~ބ-:=nq,#pQ)&9#FX43څr)%2J&>)kmaŠeZ{S>EDM \e=a6l2^'fAG'#[F1 atJQ3+&ᆮh@bέSV"k>jj=YhY5l.=fpAs9bJ7$duz۸̊U$ "D={.dV󑶭3j1a~7F"CHZ\4f l:FJjVUZcH\Ed 9}n*Lf?\Hg{RIʵ4N>ق"IIcB-Z߇KC,≸d%9x._I{:<̿uelGBbGǓUS+Blܘ>;jmy'(5c7[!se;䤍83'/JiOd%b0'c|VGa$ [k&q3%P!HǴ$?=qb3^IBD'ΗfywKa2^nzrxp_ ġFZ%C5>蜛.XB[ QJX/o- logda endstream endobj 12 0 obj << /Type/FontDescriptor /CapHeight 850 /Ascent 850 /Descent -200 /FontBBox[-301 -250 1164 946] /FontName/AWUTTI+CMBX10 /ItalicAngle 0 /StemV 114 /FontFile 11 0 R /Flags 4 >> endobj 11 0 obj << /Filter[/FlateDecode] /Length1 721 /Length2 2664 /Length3 533 /Length 3205 >> stream xy<%#H[ceȘy0Ec4QB,ɖ,eɞl99yu2vz8hD&Q puB 0>DFƀbx2C8@ާS@doM?Tj`z=,ؑxz`?) NK<@/<  E$jq@I* q$B=!~ olnO Xb?/u O]A&SA `AƁҟNopd_ڠG"T7!? gPsrG~U1x>??c?P/{+?u;C’qx`GŐp R/+#T\U@*^W D*0LM,֟BIԟ7aoĞ` X@0syǡ[ij;SƂN4 >l>;7jzZ>"-,jĨ-:rZ(-)otx*:t5ъ\ߝ/;Q6[PZ{]= 6oj[wiQ>kS8$~ASZ6S6z|L8R$`vgj$wPcΖ0)?A'*-EW{R$y,䳙,Qf[ V?BX9/^rfl̘wEygw}Yg~Y2aו0ј{}l{*M խjݾg jW-\'钵^3sR$G` Ql=91'q-Y.9z"s YZfFቛO$O@ycW>Wx13ȑgWO*1ДV娓t.֬} A8ou!}/_ ]]6M)]<1(tz6OldW,lPJ?BʲZĦCB4ьsv3{U]ڔ0@//(vP E]%w[HXlx(\b3GOnԿ$th]?L87Lt"ڧf&o[XmXq@zy 4iqC|b@tyyX9 yD5jJV~*G |rh`Obx˵f72^xnpikuX71GwtIe(sz3&$KUJ~Sg6-v,?~2QitX|,,ݬoBf+YQjf+CR(!q3of771z*ZY 6=P(jIF;G<ͽcT&X0BpKo#p*ρ;Ka_FK 7U"]cn l+!ox|J[+ߪb~>V͛ͯ:6Y&D1b+gf5]8U wH=<@%V=x]͹\ɪ8|%sFcK쌡ٰJ^Z:akn9]7_toi>s$ :ye?~EݵβS|jzk_| ߈l'&)B1AZh:6(l>m1V(+YxA-r`w[*x6dMizXIN<|#ꓻ1.“9KuR4؉/"w6`LvT;؋%ʷ&"KnUGl;О)R-ģ* #\3-r4l/ʣ4_4pm#YX#$V'L? Jgٮh= }w?fYyƮV0_nI]yS|%dGgsK,qE$<~P.g^EgE#>ȯ~2]Oqᄩ[Zރ}&cP/tT({h^ا.8b+@AO5soX{VAeQ-oxv\1OAsޗKɬWpB‡+2Wp8ի2e鸚3%Chs_Mn(V h&K,FEhT3.ț /njZ;*p$$Ay1s MNKRΨ2rN}g1Tɼ b4~GЧtVou.67f4=oť&xJ{p.W3dIihJ]Žү^YO\,HFj*N SWW߱>lҫmң3М@Vu] E?T)ggJ9{;K;s&sSI6>2Rd7,`!n[;T?j;e.PC7U)QLaQpH$r,uԻӱB-;1`mwϼ}QՎO*)( $_**j \Z%W?_P5qEP4, H\A^L;=GL=4*iN2Pt}p3ujЇ)3SvoK؏ocCĭbtD 2)h|BAJfNH's\>LDn0]-p UҒpe6eЇ 㝾+zWtȋiRZj 62; ,Pd"C endstream endobj 15 0 obj << /Type/FontDescriptor /CapHeight 850 /Ascent 850 /Descent -200 /FontBBox[-53 -251 1139 750] /FontName/QADBYN+CMBX12 /ItalicAngle 0 /StemV 109 /FontFile 14 0 R /Flags 4 >> endobj 14 0 obj << /Filter[/FlateDecode] /Length1 716 /Length2 2094 /Length3 533 /Length 2627 >> stream x{8T]"F[ܶ0CQ&ߊИY̘.ƶPD"˶crO%亱rT}>w?w-C0S$005;Zp9 dC  L83=l< d JjO.}4`!X p&c D" pi 5iA #`/G A?AYd@ |mT. v)qd@ *$?ov )NєX;Ы^͟OC|Ѳ$@zCTY~9 5 Gֽ Ck< a\ `2d7\RtHVoWue^$,^!*(=c0rӉkŧ'M-yv6~4I8Lds5([x΀\9ԊiTcVVRt^We89ҟdN[)>aJiR7 *寳ZP| *ZZڊ&.NJtOIF(eI/!mn%^NۋI=:7YP5/D~h( M}g<U̮vm+mt)O/A|Xb$T*s^G~P6"z8i|2=ڒ=(Ly~, /NVlP ~#8:8ZnmhDΎ<1&&Gy%0S嚍L-gOUcH~#]2.)BZrx ԡ&q |#Sˇo>sՌknMl6H7s&U.\-L-)hT84mԤ{xJ-/QG?&*Rˤ>C 2iYeRirF~v#Y6eS#:\ADΟ/~ج?SwC(P!!QN.ЧҠ%"Cci9i>1 w\qgT#,oN\ u* B?~?%¼kh4N.69ntkZt]WϪ~|;|{٥,~f]٣٬䴶&DBt쀭<@c_b:]\Ri qz22QL$z*g7Z2}dӆnhЈ^xP.Hyxմ1ig}( i; Om}[QNPN5ؗyӰd JLbP`HQq lNXdR'o_|Ei tNw_Cwm/ڈMbAժضz^+1;,TR[CYpD ;vsXI䚌Ht; dLܐ[!}ܷu׆Tˈ//'DC0Գ?M endstream endobj 18 0 obj << /Type/FontDescriptor /CapHeight 850 /Ascent 850 /Descent -200 /FontBBox[-58 -250 1195 750] /FontName/SBJCEJ+CMBX9 /ItalicAngle 0 /StemV 117 /FontFile 17 0 R /Flags 4 >> endobj 17 0 obj << /Filter[/FlateDecode] /Length1 713 /Length2 3449 /Length3 533 /Length 3993 >> stream xy<ǭAvH샱2fgfӌX&I4V!ɨd %%J(&d)KY⧞<u\sJm P+h$Ri!@@BBD#HABkA APY RRQR@LxyҐ\@4D70mH DV p8Wh41R@ $0x/&(ޓTSF D҇灇(GОE+4!뿡{IgkOh#|08>$4hI@[p%!p *)aM0hCBz=8oGpkm f?pO%;w p9DL0YIAI thܳ$XjC ӹF``R5a|ӥ,1fʹB֞cs\d//\PG ~4 =T[JTT;ta/ qΔ}Nkڲ>OOAqS[S8̩jUׯ}pNvzq?&MO)Rt)eK9HC Fj*#I7m;C*H[wxZ>!xCJo(P w P܈p) UCƗhVnwڪ!X$m)duc@;*Ǧ>~/#_T|b.l媝v* =$[/?iS\2F6>VmmI5Qtşm'XhmGTa YK}͆l+8uH Ɯكy~)G(m2ZVbA &,R40jW'g3d}^lFj8'~*3Jci_!܄;do9uVoU_CleQILUOOfUJ>\hW;}jSpږ$?;\@o%FkTz*a tG&>>;JƇ-?g{ʆ+"[r+φqԺꘀL,%h:z '+-G/X9H@nwP_CMG'_)yJ j_r׍nn飲W.Y<~3e=[ p 3wp;.KF)ȇ?S։0n#i8~JV'1c20sُM 9*4Bk-:OX Y3Lh=y/uzXi,]Do gZwγǗ\JrC&CV98L;% vDwo2Nѳq׌ 8c]IdLy7FcX>![A%?K92vf0γ:y>!yfGڕn̞@roVTbV8iՓo!q:cccu>W3ikTݛ쪞LF߆hwsn>m/4d(A^#/6lEVa.hV*/_C%ԙe~)7޵1,U(SΑfE>HM:!=lc4|엎y8|4Qxd @*E/ri;jKHAf"#I}QmeȒ(kr)Շ~q7 oL NـS85{wIhM$7&"9Z0+ &ځ3eɫ,'`\4[DϬD$|[<΁J gn80C$٨Lx RƖXhZ!B /gI`K9ԭ$#^)]6^{yaVx%%Of}ǑⶅY!cƛ bZ/$kU gX|>SrrhmVL#na(1:<SX~wJ-.<360G@*[-s$J> ¢f8~Luzxrz%Z5)? p;ʻ5lM:/d>fgÉ8caw %+=`x,XCO^,\t`~뇯=x,ܼ/ bg*苙=8_B6 }$d= )ZsQH%a eyѶnw C=ժ}DǠ9^ގc,IBiSceX<'2|0Ș^?/63HجW}%3ѻu>F<"RwOx1rv n|WTB.J&ar#^;7UJ vIp >F͗O)*blF%;mWjWYi֎g$YƯNpiZRsjiڨXT RTJ2fHh#җkuIICuvdF#(8'-AS3Ud-lj{]ゑsː$ >" endstream endobj 1 0 obj << /Creator( TeX output 2004.10.19:1439) /Producer(dvipdfm 0.13.2c, Copyright \251 1998, by Mark A. Wicks) /CreationDate(D:20041019143940+01'00') >> endobj 5 0 obj << /Type/Page /Resources 6 0 R /Contents[20 0 R 4 0 R 21 0 R 22 0 R] /Parent 3 0 R >> endobj 3 0 obj << /Type/Pages /Count 1 /Kids[5 0 R] /MediaBox[0 0 595 842] >> endobj 20 0 obj << /Length 1 >> stream endstream endobj 22 0 obj << /Length 1 >> stream endstream endobj 4 0 obj << /Length 33 >> stream 1.00028 0 0 1.00028 72 769.82 cm endstream endobj 24 0 obj << >> endobj 25 0 obj null endobj 26 0 obj << >> endobj 2 0 obj << /Type/Catalog /Pages 3 0 R /Outlines 24 0 R /Threads 25 0 R /Names 26 0 R >> endobj xref 0 27 0000000000 65535 f 0000029587 00000 n 0000030177 00000 n 0000029852 00000 n 0000030030 00000 n 0000029751 00000 n 0000006431 00000 n 0000000009 00000 n 0000006678 00000 n 0000006492 00000 n 0000000913 00000 n 0000019043 00000 n 0000018853 00000 n 0000001829 00000 n 0000022551 00000 n 0000022362 00000 n 0000002765 00000 n 0000025480 00000 n 0000025292 00000 n 0000003711 00000 n 0000029930 00000 n 0000004710 00000 n 0000029980 00000 n 0000006365 00000 n 0000030112 00000 n 0000030134 00000 n 0000030155 00000 n trailer << /Size 27 /Root 2 0 R /Info 1 0 R >> startxref 30272 %%EOF cb2bib-2.0.1/testPDFImport/PaxHeaders.5700/metadata_bibtex.pdf0000644000000000000000000000007414011522151020616 xustar0030 atime=1613145424.838620334 30 ctime=1613145424.306620349 cb2bib-2.0.1/testPDFImport/metadata_bibtex.pdf0000644000175000001440000015660714011522151022227 0ustar00constansusers00000000000000%PDF-1.2 7 0 obj << /Type/Encoding /Differences[0/Gamma/Delta/Theta/Lambda/Xi/Pi/Sigma/Upsilon/Phi/Psi/Omega/ff/fi/fl/ffi/ffl/dotlessi/dotlessj/grave/acute/caron/breve/macron/ring/cedilla/germandbls/ae/oe/oslash/AE/OE/Oslash/suppress/exclam/quotedblright/numbersign/dollar/percent/ampersand/quoteright/parenleft/parenright/asterisk/plus/comma/hyphen/period/slash/zero/one/two/three/four/five/six/seven/eight/nine/colon/semicolon/exclamdown/equal/questiondown/question/at/A/B/C/D/E/F/G/H/I/J/K/L/M/N/O/P/Q/R/S/T/U/V/W/X/Y/Z/bracketleft/quotedblleft/bracketright/circumflex/dotaccent/quoteleft/a/b/c/d/e/f/g/h/i/j/k/l/m/n/o/p/q/r/s/t/u/v/w/x/y/z/endash/emdash/hungarumlaut/tilde/dieresis/suppress 160/space/Gamma/Delta/Theta/Lambda/Xi/Pi/Sigma/Upsilon/Phi/Psi 173/Omega/ff/fi/fl/ffi/ffl/dotlessi/dotlessj/grave/acute/caron/breve/macron/ring/cedilla/germandbls/ae/oe/oslash/AE/OE/Oslash/suppress/dieresis] >> endobj 10 0 obj << /Encoding 7 0 R /Type/Font /Subtype/Type1 /Name/F1 /FontDescriptor 9 0 R /BaseFont/SRPUXN+CMR10 /FirstChar 33 /LastChar 196 /Widths[277.8 500 833.3 500 833.3 777.8 277.8 388.9 388.9 500 777.8 277.8 333.3 277.8 500 500 500 500 500 500 500 500 500 500 500 277.8 277.8 277.8 777.8 472.2 472.2 777.8 750 708.3 722.2 763.9 680.6 652.8 784.7 750 361.1 513.9 777.8 625 916.7 750 777.8 680.6 777.8 736.1 555.6 722.2 750 750 1027.8 750 750 611.1 277.8 500 277.8 500 277.8 277.8 500 555.6 444.4 555.6 444.4 305.6 500 555.6 277.8 305.6 527.8 277.8 833.3 555.6 500 555.6 527.8 391.7 394.4 388.9 555.6 527.8 722.2 527.8 527.8 444.4 500 1000 500 500 500 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 625 833.3 777.8 694.4 666.7 750 722.2 777.8 722.2 777.8 0 0 722.2 583.3 555.6 555.6 833.3 833.3 277.8 305.6 500 500 500 500 500 750 444.4 500 722.2 777.8 500 902.8 1013.9 777.8 277.8 500] >> endobj 13 0 obj << /Encoding 7 0 R /Type/Font /Subtype/Type1 /Name/F2 /FontDescriptor 12 0 R /BaseFont/XHPQKW+CMBX10 /FirstChar 33 /LastChar 196 /Widths[350 602.8 958.3 575 958.3 894.4 319.4 447.2 447.2 575 894.4 319.4 383.3 319.4 575 575 575 575 575 575 575 575 575 575 575 319.4 319.4 350 894.4 543.1 543.1 894.4 869.4 818.1 830.6 881.9 755.6 723.6 904.2 900 436.1 594.4 901.4 691.7 1091.7 900 863.9 786.1 863.9 862.5 638.9 800 884.7 869.4 1188.9 869.4 869.4 702.8 319.4 602.8 319.4 575 319.4 319.4 559 638.9 511.1 638.9 527.1 351.4 575 638.9 319.4 351.4 606.9 319.4 958.3 638.9 575 638.9 606.9 473.6 453.6 447.2 638.9 606.9 830.6 606.9 606.9 511.1 575 1150 575 575 575 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 691.7 958.3 894.4 805.6 766.7 900 830.6 894.4 830.6 894.4 0 0 830.6 670.8 638.9 638.9 958.3 958.3 319.4 351.4 575 575 575 575 575 869.4 511.1 597.2 830.6 894.4 575 1041.7 1169.4 894.4 319.4 575] >> endobj 16 0 obj << /Encoding 7 0 R /Type/Font /Subtype/Type1 /Name/F3 /FontDescriptor 15 0 R /BaseFont/CYZVRG+CMBX12 /FirstChar 33 /LastChar 196 /Widths[342.6 581 937.5 562.5 937.5 875 312.5 437.5 437.5 562.5 875 312.5 375 312.5 562.5 562.5 562.5 562.5 562.5 562.5 562.5 562.5 562.5 562.5 562.5 312.5 312.5 342.6 875 531.2 531.2 875 849.5 799.8 812.5 862.3 738.4 707.2 884.3 879.6 419 581 880.8 675.9 1067.1 879.6 844.9 768.5 844.9 839.1 625 782.4 864.6 849.5 1162 849.5 849.5 687.5 312.5 581 312.5 562.5 312.5 312.5 546.9 625 500 625 513.3 343.7 562.5 625 312.5 343.7 593.7 312.5 937.5 625 562.5 625 593.7 459.5 443.8 437.5 625 593.7 812.5 593.7 593.7 500 562.5 1125 562.5 562.5 562.5 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 675.9 937.5 875 787 750 879.6 812.5 875 812.5 875 0 0 812.5 656.2 625 625 937.5 937.5 312.5 343.7 562.5 562.5 562.5 562.5 562.5 849.5 500 574.1 812.5 875 562.5 1018.5 1143.5 875 312.5 562.5] >> endobj 19 0 obj << /Encoding 7 0 R /Type/Font /Subtype/Type1 /Name/F4 /FontDescriptor 18 0 R /BaseFont/NWSIIM+CMBX9 /FirstChar 33 /LastChar 196 /Widths[360.2 617.6 986.1 591.7 986.1 920.4 328.7 460.2 460.2 591.7 920.4 328.7 394.4 328.7 591.7 591.7 591.7 591.7 591.7 591.7 591.7 591.7 591.7 591.7 591.7 328.7 328.7 360.2 920.4 558.8 558.8 920.4 892.9 840.9 854.6 906.6 776.5 743.7 929.9 924.4 446.3 610.8 925.8 710.8 1121.6 924.4 888.9 808 888.9 886.7 657.4 823.1 908.6 892.9 1221.6 892.9 892.9 723.1 328.7 617.6 328.7 591.7 328.7 328.7 575.2 657.4 525.9 657.4 543 361.6 591.7 657.4 328.7 361.6 624.5 328.7 986.1 657.4 591.7 657.4 624.5 488.1 466.8 460.2 657.4 624.5 854.6 624.5 624.5 525.9 591.7 1183.3 591.7 591.7 591.7 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 710.8 986.1 920.4 827.2 788.9 924.4 854.6 920.4 854.6 920.4 0 0 854.6 690.3 657.4 657.4 986.1 986.1 328.7 361.6 591.7 591.7 591.7 591.7 591.7 892.9 525.9 616.8 854.6 920.4 591.7 1071 1202.5 920.4 328.7 591.7] >> endobj 21 0 obj << /Filter[/FlateDecode] /Length 1647 >> stream x�}WYs�6~���[ș�& ����&n:q�q�v:m ���� �n�_�=@Q��/�X����U�&i�Zn��ǫ�Y�$MG" �E��!2M��\$MF�T�wQ\�)���� 2�g2�R��A7�%Q�eu~�tww�5U�����*� .�ER���'Fʢ y-Cş�U~cVL�Gq^���gl�� {72AU��j�_g���l4 �1#��'d@�s �X�Ex���DJh;��r��� ��Cue�.��Ư^L���I=�Sv����b����>VX- �#��WX� �c�S���b'�W'K���e>��E�� <'�X$��,3��d���<_�����*LE8O2�_�\��2�ʊ��9���_԰���¥pɠX���Z1�����5�6z�;t�ϼ,#Y�!��4���������0B�Dž��BQq���M�*�p��(�R.�7���U��+�����g�?�:������p��5��>���Tu���bF�;�ݨ���TQ���G�T��I8��_�E�����S�W<ƃY����J��Q�Ljxg*�֖ {gڙ�����;>^�C���Ա��`R� ��M�]��Q����!f:AedR��< �n�ϓ�)��2O�l$����N#�7 �/���;*�$_P*$�O- M�iz�@̶w����w뙨.��v8�m,�����#��j��b3��JO����ڹ�����%_"�,�Xc�5�-%t�Q���u��vPe�f�M�p ON��V�ֿ�8���JDH\�h��W��:sa��4�ij�������*5�*]�0�6��e>Hs?>)&@��08�(�y�w��х��~��A�ӆ!S-��̠P�f#.�E��o�[8?a���!7�/�v:����-;��y!(�e �(g�w�y����ozp�O�e�w�"���{AU]`+�ɡ�݂���|��M���@��n�q�Bw���3�Iۖ?�k��̿8�@������n��A\�L����S�Xn1 �M�)9D���Ň�N9y�� 8!R�� �5;m�Pb��� mY��S�-��K�n��i�u$,������������<�3������Τ���"4��*��֊�#�ś�C�����.��J��"��a��O�h~�����7���*�OX&)�􈏏�:��>�/쎍�:�]�O׸���j�����~cTһ����*�7���e�Z endstream endobj 23 0 obj << /F1 10 0 R /F2 13 0 R /F3 16 0 R /F4 19 0 R >> endobj 6 0 obj << /ProcSet[/PDF/Text/ImageC] /Font 23 0 R >> endobj 9 0 obj << /Type/FontDescriptor /CapHeight 850 /Ascent 850 /Descent -200 /FontBBox[-251 -250 1009 969] /FontName/SRPUXN+CMR10 /ItalicAngle 0 /StemV 69 /FontFile 8 0 R /Flags 4 >> endobj 8 0 obj << /Filter[/FlateDecode] /Length1 720 /Length2 11638 /Length3 533 /Length 12196 >> stream x���ct&���c۶�ƶmolul۶�t:�ݱ�t�����s��;kΝ/��۬��U��{����j���JRe5FsGS����#  /���* ��� ���s��Y;:���yIXxxXI$��/^v^V88J1G'/kK+71���HD��.�f&$ &nV@��&f&v$j�f�@7/&;;�<�J� t�x͙��XXH̭��HL���p����q�p$��W����?K@׿\$4�$�%��i��`�Eb��cVt�;�/��1������%���M��a��^���������8�;��]H́.�.���Mhn�n��U7;k3K; �_)kWIkO����������+��y����C���?��T�5����Y�UT6�vpS�r�/�������o{\�=I����W���ϑ�M&�`�hn�`I��f�`n�b�_��%*�������B���w�<$<�<~��R����(#N��x���5swq:��s%�}���-��������(М�l`��j�h��+"���5�>�6���3�}�Ƅ6[l�|)�9�Z���վ}M�r3gM',����l�L&�z_k� +>��7ޭg����+��v̶k �%��2�"=k�k�E��*��7�D�)Q`*� u$.�U4��d���L���ߜZ����� U���}��_��G u�u����7X����a;��y�3���cֻ����sM�U��5��:ȦO������E�؉_�Ǹy�!��P��#?�΄|�4�w�����, Γ��ˢ۹�-���/��{������3��W"��6@��!ѳ��WR�o8�T?��G|�|�a�E����z^0��xNn��№YZIv�U�#NV�)Tc�����!�^�+��]�F`|� �5w��K��5W�w��Z��;�gz��XGkwR+�6^�A�-�����d��>L��1���>�{$�02�E0���a.!E $ǵ�rc�����Nz�e�̢S����1�Vr���ʲ"-h�۶�ՕӒ�I�,:˟��\��k��6��mDto���O���p�O��]Z�g��f�f����4x W�’��K�!?f�����0h ��ZMc�VKK� �J�O���E��Q�GR�}J�^�a�…�ͥ=�����L�ERM?l��s�v �H뱐9|�">dz���ôT�2e�rF]%q0?�}��&TXn}��I(o$�Z�>D�l���?���[ )��q3^"�u��טS����2������=��.��@��K��� �T1������2Kxu�t� ���ݞG���j�4P�JL\Lx�g"g_��V^��&5�*�6�)��<�s��������f�:�ҥ���iҢOCL,��:��+������$�ľͤ�6!/����v���E)��C;���w���N�[�k�����U_1|�@,8z��S5���q�te�����~Q�goF���M���n�M���jJ�+�z�(����̍�Ƀ�dI8f�C��0s�iD[� �95� N�k�?��Uv}U�kr�8?�[t(�U�Չ� ��cz 2��R����S ���Y�0�\ �7��a� \<�Ł�ҘI� UA���.��녔8��$K��E7y�K��ZՖTl �,��%�1�|�:e��S�bP(' �C�׳x]�'�:��ѳO�gLl������)h�E���b�;O�\��\ԘV�����܁�m���0�ߴ+������J�8�^��+̻��8 xߓ�J����T[4�o�&�"MJ1�&]�)�Α�*�F ��������Y%Lu����_��� -��膀�s|���ͤt�=!@e��n��"��75�U$3:�r��2�w�{h�^P�5k�f���/�2~����Us�%�}cc4���]f�a�F���mr�^�%n4������s�13��M5i!*�͚�k �e�~�(l��ws���ifQ�ę���Q�NX�8A��[�П����IUb�;f����8��]̨�yC�,�#%������������D!�}��\`/��W� b��9j']��rD���„R]h���y��.'FLh����J�:��8��|��o=�"B���D5Ǽ��3J�pv��|}�N���W�nH\,��w�’��6Pc�U40�Z�X�a;?=|=��~ �EN�,�J'I���� �3��)�cth&���>���PW���P^�s��~&��� ����ܘ�0�z?��j��Ǧ=t�3��P([�G=�0��ן��V��Gq����l����R^�R[IZ�)d��%Cxw��%O��m�[���c�p��*c�Q?��!}��T���¸�H <����w��˰�"� 7�z������/�:>���v�* �-�nnt�٠�.1��l�<=��[K�դ~�.�9�|��4�,��'�Q��������Ze��E�Iu�TO1c�G���4mV�2���lH�2��3��rN�)����g1�NL*N�5[hd�������+U_Ɛ���y�3Az����Q�88�����+�R�$d�Jfj�_�'7�y���� ����b? ���Ӹ�(�Yմ�%9�r�ѷ�~�*d�ٙS��s�3��H7y���a�B*�N�v=X��vD=�ď�@v��K�.�dǫ��>u�n��9>GhK� ��Ϸh?G���~�Y�e�z&��>�'!��wmh���x�a�x�~b>�4T��ä���[����^+*3�n�h��OK%��E�К�srD����v����?8+�.7db1��F�5xrO��xN���Y��~H�]����ȏ�a��j�MT��.����}���������1� ���z���5���X��w�y�)9�������������̚3�P����l�?��#�ȉ��mz�Kg>$7�T2f��E��p��[;���G���v6}d����9��Fc����7�n����!f�{yyUH����ɇ���2�`��������D8���k<��C8��S��P����B� AȂ�vxAӕ瀃N.����!��>���}2[��Q�@��O+� �g���7��jI<ۢ_���^�?�� =xW�4vB7b"1e>��)�����{�9Nf徥�j�2V�P㟍Z�?b�i�uYVQ��װ�k$AǾ�W�r��b{���Y�w=Z�N՛k���/�H�Τ��G��t;��ө\�_���j����q�3v�p��b#Tn6�͉9���L�(9p�DŽ �+)�z1c�Ay�<��A6��?8������೮�k�d� �OB�� \��+��6�d���g��#+^�OX6�5A�� ���\��;F�*�=g��gμ1-K��[�c��w��q��Ú"��K��ב5�M�N�?Tr��Z�a��X��6 �c?�l��!*� �-O%rZD��#���(�;�ޏ0m����R�3���3+//�&\(�@$* ��!r�ڞK` � ��A؈:j��� 8��AU:�-97�g�x8�w�����!��ބ>��T,3�?6��I՞��]��M����uPw��妾�������u�e���oD��YEٗ���Bt���9���K��=�`����ʠ�]p���Ѡ�����@4��m.���u+i� _�'����_�W����I6��ʛ��:#���z_�2X�b�A5��f���j��O�t�-ToMO��^�� ^��P;��73�Zk��h��pZ��;37�Bh�����g����1���i�)���+(�w������ӽ�M��gj����ݶ^��X��*鲜�aÒg�ަ(������Z��G>��J����u^�2�n�`����ZӲ��`. �X=s�_�~��<��3�aЅ�C�>�wiu��5�����ٺ����� ����a���˒���L�����`"]���x��߻�(ǥ��IQ���`Cl�Y{����x�qQ��� ���9'��c�=;�s[�3n�H#����MGFQ�Z�m�}}I����ϦW�yl���@&�0\0z���N����ĭQ�=�0|ϪVs�5I�&&�h�r"h�l� \�w"lǨ��Ցɉ��*m��r��Z�ι:�����"8�*�zF��4#]�8LB��g�ž�%�ƿ~���4� �p|��6��t}ϯ6f�IpX�h����ҎZ �����$ƛ��N��(�_2�xέ ����vOʷB%����4��Nj�[6����f�~�`�P u���ptd�&5���O����Ԧ=V5PI����HE��rc��Bp�`,���� �.��������e��ݭt����M�!b��nE� �����-��:���m�Ht�I�'����ָ��~g�n^��=60 @ےn}�'{ڜZ���M�Q�|���Pf�oF��\����`"a�8[G^O�����<���Y��@߰�#%A99�;���̑>D �����7�����0�\�����ީı8�>V��q�ٷ����k�g7l��ք [}��#\�w� U[�Iܢ,����y�Fs.���X+c�\�v86Izp��)��b��|j���W���<�� %�td� ��j8�]��U"E� []&�A�������|����%�8f��-��'����[X_��"���ncʉX{�̱kht'O�\���k��f7�#�n0c1�vF��_b��fd5��a��4%�sP�q���w�n���f:�,�FpfH<xIGU�/A'{V��I���@ �T1&�z�Qk�x'UKh�;ӟ�[�"g��j4Qu9.�!���(��(lJW��A�����"/M�D7��&��t��w��� Y�F� �����t�}j�0��DU��(^*I�x��pa#3 �ѐ�_��"1vQ=�8��r�oWI���`T��j��3+iWK+� �|J���Հc���\���.V���~\�>//�O��=MVĈ��X�+.��D�1lX�'%�k<d� IؾEU�M��8������rP\zr>���������������_>S���Y�8���&ֆS$�tz���D�PM�M�E�����.��#GQ�3�>U�5��S�mk\���V��*�S8��E~���@4�lGc'ק5��vQsl̷�$o��ܡ�/���H`}�$�>���J�sM�OJY�]�@�}�M^�k��W`e�w��סG�P�4�������G�K�5s���e*��)brT>�ڱ,;]h7Q��l���4V�����Qjp��|���y�mIy���N%J�����4����e( ���Ӝ�Z+ =2��7�����~e&�� bx���*� ���x�#�Wz]N�ޗS�]��S�h�����d���t=挴�̫�"4o��K�I*�~�!�F˯ǡ�ΖADl?�P�9;�Y%�[��k8;���u�&�/^�4]�N]��ӪdP��[�� P /���>:�T�cA�J�!3Ə���y�yn����Fkl�ޔs��(���0Yw���^?���yaXYT^�*LHE�{����c����'� n&�K���'�҇�k+\ȫ�I^�#�*�������T���Y$�!*�s ��}�A��c��jn�$H�8��,zQ8�M��xk�X��#.R��D�VW� ���� �K��@���u���3��,e)��g�t�$e��"��+7��;$D/��`k�ů E��yX)�o���^�=���������B��W�z�ka�O�I��p03�e����5$*.�Ӻ�iJ�9���Y�'1���J,�4���t��O�a��&C�m��^�jrN� ���H ���H8R��ڧ'��\-�?�UX~Wϰ}!�&M�� Y��}��ZF�� ���ڂ�om��٧�Y# yo22�up�� v,k o'$�A��'_m��L��DOt7s��������d�a� ���IK�,u ���Ļb����Q㍥�����7��L߿Ǐv��w���������TX?�Dt�17��εÈ&���&3�]=�tNl�$(�����_k����o4�^7N���9*VR��?p�x�������P����~�>�{-P�b�_)9��pqQ�(��?\ �����޼e����,�?ň�K(��n��γ��3N���nO�}�f��`[�P�.�[E �zZM�k{a��LJ�l���{�� aB�P�����r�M�o��^,}�/˩搗b���"��K���$('2�o�-���W�Mb}�h�Yˌ����d�RTs��P�2��dg[+��e0a��b�H��w��6(�5��)D]��C��Z~3T[� ��pm�����B��~�X6/p��6 �m�4���Wkz#�z�R] Z�H�e͐Kͻ�P��z<��3Q��h�y��'��0��q��J����N*��+ C��Q�kR��x�0�N6��~���gF��?HjC`���{�"��J{�����Pys@N�(�E'(�F��*�[�� ՜v��0��)���������-X��>m�e�@�X���KŚ��zZXԣ��u��AW�;�j� ������1�)�����"�d�����W�^]Cj����]/�����#����ਣK�[���� 6+�t� ��_n��u��0�*X-��)|t��`�gL~' ���N�I :�]�Y����6x��!JRu�ڮ�z�����'��vT+e���u ���b���eQ+�y���1�5����b'����Y�qf����$�~�2L��8�+��s��_0��n�;���O\Sߒ�~����$�0��<���_�����l�Y`cf����A?�����\v�U̲�CǫR֍���I.���j����i����K���R�Ί-f�W���s��q�Z���~�dP3ʢ�� $�P�-�����&�����E�\��#Λ$FwI񲡺z� b������e��!C s�M!YF�5��������W��./�$z���r�5��0�L/$p�۲���GR�Ž����!�MG#��hR���\[��vԮd\�W'i���K��^�b8��ʬ��T�_w.�}�a�� R�b��7EOTE�"��u8�\�om,n\8"iP�� �9�izP���Ir�iM�@fa`��[��G��r�s'KY֟��&�;aa��P Zf�_��$�c��t��2��[6���7�R��S�ގ��2�Q�~��ri��O.-A$v��X h�Ӻ ��C~9A���l��٭�i6�9��oV3��Hy��YұZ!}ӱ�����q3�.�uD�ʸ'��'U�f�W#O��N>^��V���a��J�6Y�����&[��gcRJiՊ� U�$�²�$T�:�j�B����d�ز��L,k��D3;H��G���oN����H�'��BT�e���o�z�Vg'kiĦG8:��o�P�6B۲��A ��˽�lZ�����S �:�~�A��P/T1��k��Y�!z6l�T�?�؉���ˤcԘ%$��\���ӱj�n���ɮ�/�S�J��c"C5�ߴ�������O�~���l�G�`]Py�EkW�+~� v���t�N 7��գ������ V�$��"�U�C��l^�.u��#�!���8Z�N�_�t����߱��^����;vw���C�e�|��-�1,=� �ƚ(\��h#Fڒ��5�9�['n���e�g�}�|�������ޒO���I����w|9�~t9��C��"��aH�w t�W��1n��Ŗ����(A��Yb=�v�����D�Q��9�S���;���0 �v�L�kOT�"2�ڭ�ѹ�::j���Zã���G��9d٨��I�Dee�&Y���QI<1&k����7_z���`�6�Μ��k�[�k�ٌ0�T&hM"=X����)TmZTC�1nv1Β���1��V�ݛ:�n�f�my� �yN6]�U=~�n$˧�9;q�|�$���Lq�a����{S��\�%����*(�2ra�X�Hl;4oX���k�nĥ|���sǙ�DFXTnuX7����,ٱθǦ.g��8 ʧ�{L�bL�)�\�b!.i7�绗���B�̙�У��[b�\sU�s$��G�g��o�u}K}L����׺7)]n�H��� qO��1�s�"?����Mp�>,��vu���D�ul.7Dz��� ��xu��F�D�vr�b�S�l��>䷑�An_Nx/�'�pW?�G��,1�vD��T��"P���?��l��.R���J!�L�I�?ɠ(]��J�����5�f��? ��N��?F|r�����o��WvJ.K�Z�R���ڃ��c�Z�ʻ�s?`o���o��mBtk�8��#R�b�P��Eǩoy�&�Er�T�._uB��k���1�F�,c�2"����" �o�nJѪP������ȿ���h8B����?c:�>���6��GP��R���6+�'QHǜ`���;��E���v)��o�@� NȴL<*ʙ��O�ZFȸ� ��/��}^��E-/�C�l���Od}�n�լp�R��H�1��gA����3&�F7�������ƕ�g�;����H�eEF�n%�.u�3%*�c�qi�cy,D{�Da@��"�0����z%�@c�Y�3�oG�Y���U�%�0�>'����YZ��HUn��˕���,2 uK����"91��`~8*إ8|e��֌���Lu2.� "o���Q~q-��"��`��b�|�Ƀo�h�q�\zl��o͆Fⶥ�fV�;������V�<��C]�D�j���ݧȼW'�.4��q1����o�r۞%}zBeꬱI��$��"�B:��^xh~fOWCЕ���ax&��[���2��6ݟ�]�VQ� _Ԯf���z��KO�,�����$SJ�+Bӱ�0�*���A��we5,�x�6�m�A�"6{�o�4��q.,\���6� ~L���}� k�/�İ3���c�X'L%��CW ��=<�=�:��;��s���e��J�[CP����H��2����^���V P�(�nu����0wU$R-����0�J襡�Q� �wB���f���CŐ�l�]I�M: >�C���l�[D���J,::@bl;3�j|�%8V��0�&�B��8���\Cw:n`@�,��{QI�e��b�[ڱs�s��<����6a� Qh�D��.2�k���I�!z7�ɑw�3k�\m}�O�ǹsB����I\Y%����@O����Ώ�e뜕+��-�`� l0׹i\4�DV��:�ێ��3|��P���0�W��iJAI\~�y�Wl�����}��Zk�4�џ6*7р��儃}OggfL؎7U����c��# �%} 5 Q�䏌7�I����������C��sg^���q�;��o�c7�0 �D�6雧x������Y*{֛Z��R^�Z�͜���� �p�e��� y���(�%#Ѯ�PP�h��v�渻�S��� �^TQ�dz~,����T�N��y�F!�y�1�қ�P}���aj��bQ�m�"����і�G�������]����k+e��2OK�Kf6K��K��v(P�O���?�]�]f��u��Eh�6n{L�������q�Y�5L��"ʽ �����ؗ��2�%�@��tƖ�ɡ�(��8t�YQ~�@��-6R�D ��&Nf6+���\1��}jEz�gH�3>;uz�����q���5g��x���)���{�s�[}� ��^�l)Cp8�u>�]�:B����x[7�!�,I��b!r�!�j]�G<�n�3,�Y�.����\!������-z���L8�33X}�: X�aAHYk���__�ԟa��,��v �O‎�f%�Mq�� ��&�g��b�!�� \�1��� .Qew���] s�]�w�O��n���y ��0��D|B3L�i^�P �$(=;D��e�c�c��ܵ��D�)�"��i�H!)�Ւ�G17$�~MV�"�|Q��z+�)���bHT�n�6l�ٍk����C�<��R���ü�u�C�i����p���Y%�+�d�S@��1��R�_#��Fe,q�,p��b�p=~poiŕ+ͩQ�y�7��A��B"��+*�B�������+J��i���DG���9����|q�1e����+�ў��Ji��6ff#��uG��-x%���)�Y��́�#2��Y5Yr�2�@ӭ�� �B'��d��=�7R,� Z�ʗ3�b�)L=[v� �r�׈��k��s0v�9d>���j�ni����;N0Mb��o�Ep�#��@53ٕ{i�$�z�&�x? 3�c�v6 F�^�[�Iح^A&� ���� ����@���m�K�S������js�.v!Z�/�� Ғ��tq�Pc�s�O*϶�-��v�G#�U��ٸW��]^���%k�:9���b`� u\P��{��Ǟ��hH�=�6� Ի�10W� �F=+;�=���o&���X)o/{QM�� ;y���D]���ց����>��Fc�7ؽ���xt��XN�y��{�rŘH�ڹo�(~��0� N�y��������ΝH���+lU���>���v���t'ɥ�g��w�]>u��嚔�>�(=i;�$3=J7j�,qP�TPh|c�B��Љd�Ĭ�g�}��fU�<+�Qă/n�M'�5H�zYދ ��SS�Y��uՍ���i �3���Y�o�W��� �������t��ri,0��� ���|�Mh����h=�T����[h�c�eo�̉�<^�ґƇDZ����?t �Q�/ ��c�E��%lmЕ�������\ތ�C>���,�*m ~+��ͦ:�j�l��� �6���������,�AC���_��v �C BI���&L��y��^��1���'���0OƢ�q?{���t;S¿Z�]!�I#��޿�;��H��]uKFҞ��ld��f��/�я<ԭ����'��R]h���a�!�v�fq�d��轐��o ����)��T���F����l#�8�� ���!� �^^L28 �b�٨�`�7�\���Þ3�}��³$P�$|���7�Y­�hJ���i� g@K�<�3�J1S�R��;�l��)�@ ������ ����g�6I0c��;[�|PI<����"F���252�M�~P`Qd�#$�g���Ӈ���A�AH�A~ YtZlv2eO)�L� ?�vA���xD�=���'õpM��<�2�X�Ţ���w>ƫt�b*��M�C6q3�S����m(x��9�|�[����1t{��kJ���>�d_~�U7���S��_p���� 3;��������-�:I�/ endstream endobj 12 0 obj << /Type/FontDescriptor /CapHeight 850 /Ascent 850 /Descent -200 /FontBBox[-301 -250 1164 946] /FontName/XHPQKW+CMBX10 /ItalicAngle 0 /StemV 114 /FontFile 11 0 R /Flags 4 >> endobj 11 0 obj << /Filter[/FlateDecode] /Length1 721 /Length2 2808 /Length3 533 /Length 3353 >> stream x���gXS���a� H�"x(Q���*��EABr�H �����1�HT�4A� E��RiR�*"��R.:3�>����}�o����{��?���ko�����.���$i995@�B�Q���`z(T�"I�I�9UUy�t;Z}jJ�j0e ����O �/�C���@"��H�'�;2A!��-�I�2���6?~�l@���e 99�A�7������2����h_�?K~ ��� �I*q� x�?��!����~���������/k�����9��Ց8 ����K����:�����kcBBb1(]�`��0>�2��ƐP��;��̃x�_��@���n� �DZ�^�Fb��K�����!���;>C.Î�+w$r������c>�J�k—�]顼�K�gV��䧉V7�gŋ�?Kj>n{��%U��dj��#Hԇ�A����юұHΜ������Wz�&ڕ*Í?�IpE�m|}-�j��T k�N&ݨ]���:S�u>o�Gi��f*����S�����In{;��_�Dw�9gr9b݈S�IGb�X}����\�^/�%�"���tQwߘj��� �߭ Q�3ѻ%~)Q���[L�y�����,�L���5���+)��Nõ�<&�#;؉/W׭�fh�alqC��������f ��*�����`����ك�"Ķ/�p��,=��}@��{�S���W� x���jf������� ;/���j2z�M������9���� ����߫W<�S���iH[���Rz&�y/,J���0�}/��}���'����K�;�*���m>�����3��f~�����x?h(sR��6�������v���oe�a�O/6w2�D5&�D��|���J������3�*�봋�\��oͯ�����qN��{o�%vO�����_����ʿÚfVJ��&o���`�S�1Rk�\,��츆sb���� ���vffK_tY�D敲|����c����Z�dc�r5a/�k�JG'8�!��<��ᇡ�2F���� �ŗ��� %Ƿ�# �J�)OQ. ��o q�p��h�勹�fOy�+�� �fΈT(U�l|y0y���c�����<���dD����l� �L�ݢbD��Pl�~��ȭ��Ѧg�D�b,����$�؈��e� ��� �0g|4�\����u��l�F���I�B�B�;_Rm9����D��ų�n:7I�ji4�`%�����y��}M^��r������H��Sr$v���+`�4�ϭ�Ƌ��[ J!��`������-���:3��`�n��.-S�~o����~��@��zY��s6�B�}.������5��[ȵ7����빶|mϐx@Hs�ȕ���O/���vv�V���Y6zt[>\�2�FJQ��Z����A\oD�������ݽ�/���H���mR��Y��*�� S,*�w���$1����k�9Nxnڈ9|y�\��n�|oս�ѹ ��*�;Y˪7�h �/8F�5nس$�dk^��|qj�Bz�4B��(�UM2�`�, 8�i��ڼ�QU _y�N�+t�p_4`NY8p�L�N��p|�5��Z�Qd�bϪ���Xl�M��l�t�~��K�u�Iu�`*�ܲ���������眰ַ�B/��j3Xw���;e�c�pO���+���-|1�AHb���A�^܉�*`~��lI�D��/����Y6�#�}���Ftt�Z���۳�ƶL���b�6[:�n8W=i.�桇�����ܣv� ��gG ���6������V��ޤ�%��� ���K I4���7�0����tфk���Z���?}R�-��a�CE"���iJ�Y^��% >�����2T4_M`0v��}�]ϱ�Mn��)q`(p�`�X­��(��1�ON~�OFW�M��M��9@Ӂ��e��tEw[@;W��2}��n(�`�e���f��J#Od5+.?jO_��r0c�/x|*}fKd:}g���E��5 zL�٬�4m��iA�[y'��:��T׵��{�i<�.>�P�������f!��5�jץ͸�׾U���4S�W�cýI}�x��q�i�x?g�J��O�JUa��l�J��n����bڿ:�vG����������^U�+�ۋQ)���9�w�.ƹe�L~����b�'��� �a\<�.Ag�W�LfJ((QkW�z�g��x����键_�f�u� d|�z���Fm8���{[{!�{?�|�A�#�a<�/|l��4����{cK3$�T&�(�QT!(h�PQ�)ټTQ���=��D1~6�M2���mw&0��DƭO��#����C����U����@�0yQ8*y�o�^�C ڜ>@k���� ��[*� ����� W���>פɫ��o?��Qےw{ev���vW9��EJڝ뷠w�JeY�Z*��Oꨙ8:�Ŗ o�U1���e�r}����A��s����7�;�\l6K�h�F�U!_ wIkd���G���j*Cx�� =��x͋"��9��?)�mo��FK�����\ю���ȩ'#Z�����>�"N��]4Tv+�S'z�rD��7��!plX3vF�r�x����7� 3Oܚ���k)/ԭ��Ap`�*�?�v)=��㰊ΐ�˳�b����z���LJce�e�4ҹ ��qXv72�>F���N�f����k?�uJ�� �ڶ���x��:+^�SSH&�(��W��=]Ųx�Jŕ�[����\7�}�i^/Z��-2��i�Wo�p�n�e].�{���ΰ������ "�$I��@� kl�K endstream endobj 15 0 obj << /Type/FontDescriptor /CapHeight 850 /Ascent 850 /Descent -200 /FontBBox[-53 -251 1139 750] /FontName/CYZVRG+CMBX12 /ItalicAngle 0 /StemV 109 /FontFile 14 0 R /Flags 4 >> endobj 14 0 obj << /Filter[/FlateDecode] /Length1 716 /Length2 2582 /Length3 533 /Length 3117 >> stream x���y<���C%Cv�c+��k��p�,�e����])� &h��a0���7ˤ�A ��o����x��~@0�B8�RD_-9�%�O�z����u����^�_����yA��C��� ��N��vsg�.���)�E��q0Nx����͖��f����kxɨ�҄v�D�'/�n���׫L���)�"q7������=Mgj_��xj�>�+���f���������\���f�����.ѕ8M>�����h���u�6p"A�c�����O������3�=J������?�uG����� ����|-����1T&���m�gޣYY�^�G�Uz\U4.޸hW��-�;�Az^������q�O6� T�]n�n6���HUBG�ijskѨ[��tP���.���M��7��%��@�n%|�Cu ƨ��7|S�M�=��:����pL��}n�P ������nH�zձ�����V�������l��B�t������-3����S�Σ��7��3����$n[#�#=3nA�#������G�򴀰��B0 tb��S���c�A��,C�z�l�1%��i���1{�:�*�H�d\�}[DM���Ѧq���jAե�x:k�Jo���S0�Vo�����ܓf�m�=N���TY�mo��cg��Ԍ=;e�$ËT���A�o�>f2:�m\���p�l5�G� �,�Ϗ�jJ9ufI������T��&��w�!�����X6�2"*�������i�&�8���8��68'AI{� ����Z�VtJl<��/A�2& ���\&�(Qf�Ľ=V��p KZbA�7��GRR�c���>��������'ϖ��U�7e!ɵ�a�( ���Ϛ�t6W݀�dA�nZ���[>�����x��~��]PP8?��M¿\�L�IB�3$gJWzI@�����r�ѣ��r�{��̊6�;%���tV����K1@��i��Gt�k2��5���}s�Q w̵���8��3�Ԝ�T�b ��l���Wr�����Ƴ6~��$��p�����wn������)�+��5��b��D�� �3ȟ�x>h�l�zN�� `[�����؋��vT�դ�'14��J���i��4Ֆ��P����)6�W�Kx��e��`P,����T�}Yq<������~���w{є�#�zP�v\��!�����,=�Yh���L]-+��ҲP��5�S��}.��8�e�9?on��X��ˁ�7�ϠT��p�b�@��.�)/E�9؜�{i���)>��#&Ã��ץ��YE����� G.%�Ȗ�����i�*J�G�8�=��_̋M��A[�_DF�i��#�[��7?���&�e�*��jZ�lor�d��M�Hs)��n�!����LSD�}�'�mg'f����ـ��I"g�ע)ؖ��YFt�!�����9[ �i蜌�ݫU;�\�O��U����p�bɝ���=I!����]N�L���{��~LW��RP��=��ǬuaJ�o�J�fLF�Y pX&x>�.^)=Xs�s߈{=,;{�c�����K�����k��{��+����I$^�3����Ե����D�_���t��ר0ÅV��t��r<�#^�4]t��d��g_K�{&/O�ph~|7���e�TVA���B�H�W�����r�� K<���^�~���y��@�镤D%T�������:p��>~��{���ZHL�(W>�mē��竏N�Tt�����s��Em�hb�v���{K��E;�Y�B[atØ� ��Q}3�c �~�W��˄���u%J�I'j�_cG:��_/�(�2nmK�[���RѾ�0�˟+Ҵtccwb_v,~�$�z�J���O�*� {”���W�p-��/�� vU�`W��s���ȘfiFC��)�[2<��S߳�׈%���~X��C�� �5�tZ�P�8f��Z8����r�����5TgJ L�'u�.�p��"k���$d�:��nI��~Qb�?�����~V�Y�j��|3_�u�l�}Ry�)�㶉��Ug�k{��J�s���]�TNTM�E?SM�e��g޸�>,a�xަ2P��SȪ r��jb�桐hasK���������"��#/�¡(�%iI)şx�C‰��������$�|�zj�B%�M�> endobj 17 0 obj << /Filter[/FlateDecode] /Length1 713 /Length2 3449 /Length3 533 /Length 3993 >> stream x���gTS{�Ʃ*���h)���$�DJ"]zLĄB(�Ҕ^D$�H� H�^�H/  ��4)‹޹יּw�̚o���/g?�9���}���p ��(��!O�ɂԁS=[5 HV * !�$ �� �Ձ 55���PARVWTVW�@�Lĸ����K�\*��h"��M$w��Q�Z�4�, ^�����^�����D_4J��( ���v��r���xWP�O���W�M�>�Jq^Q�x�B���G��G,�c�������>8���W��=��������a xx���D�)�&��n�A�ɦG��c ���a���n84P�O �m��G������y��h<��G[� gfc��J��C�l�<ɒ����_��5�?���1�@{yYyyБ������o� �H �wZ�x�����O(==�� X(�>:@ 50P,�_�Vx�����˫(��V�>D"O�}�>���s�4��d<���;K Im�l4�\�y�3 ��,����|}k�8f�w7#°��1��%xL���:�J�L5���Z�d��|��ݵ����E�4��Wv r+��jg�2)*8����w��Y��M��bo�MP�8��N��s��s�\�:r���8A*�y������>C.Q��U ;�Zו� *7���86��_�ϯ9�v-��ۖ&�s��q���k>�cd}�;v8!�c`|���@��,���õ�� �Q�F�����'о�W�,�Å�)a�I�/�Cl�k�Q�)H�j[T/��!.� �X���;�ba����;qшg2�9yYo�Ug����h���'͉�l���+k׾Dع�`�ݸ��uFg��)��Zq���Jn�$�~���Lզ��l���a5��[����x�;{��ã�����~��2��S�}��M�V�ې"t�;]u #G!�!͙#xH�zC���,�4b�d��P�:7����6��(a��0@kJ��+�ꁕ���'AV7��D�s�+B�H�N�uX�W}�'Oz�4�O��Z ~u�!�%�T���7���tC�1$�K[Խ�������%}�E��榩��aw;x2�2���A���- \�>ֱ� �n�ªS_�ao{d����@*Y;�rT6gͺcLb�|���a����~�!J�d��,���z�w���dHx� S�`Luto�e>sK[ �0i\aԇ^�h}3��9����q��ί�),7��F���vO�_��_��VU�,YY�����^���i�B=���v��a�O��T�c>�d�ib�/$�+.�F杳�8�����,���ӝ��J���Z!�G*-�c�ow�NF\��۹���"��y�Ν��v$⃗Bz_�L٣��=�I�2��q��]H���tM��h�K7Z�2��)�1'ϛL��̷�3����MP��ц%JӽV�Z?�_kz����u܌����^�@����L�C��[��FQ�V�&�����y�C�M�6�~���m� ��'��ul����m�/I{<�¬;7�3e�;����>7�KJR�֙���/ōM����l"������ꆚ)�8��>D�?�E�����,�7��Z�" ��������ߍ�����Q+.�a������ǚ�x���"쇱�q��$��8���~�����r��j�����ڤqt��I7��X�H�P#o���is������A����8��5�ӻ�Uˇ��0:��RJ�F�ݛ�ƶWI��KUyԒ1�`D� �s�j���=���b��3�����:�Rp���ӛ�΍�1� y jrߗ�ĝ���� ����~��y�@0��uw����/?g��6rIg�~3�J���c�2��rj�ՊN�y���u�ƹ���Y��68�bʟmIy�+jCN坘��4�s�YJ���0}���#s�ή��*����dx�˺�Ü�j)6�,��C1��4��$;�j\�Ƴ���Y�����$�˄$Q ������Ƈ<5멦�hgMD������u�b�`�|�{�"[������óĻM���)�I7Ye3k�� ��$��h��Uk����~1�u�&��&��{S��2.�kF�x�Sl��;7�u����J����o��ܸ0�a� ʩc�ԫU,t�vqZ�j��"��I�r�\O�ڞ�̉�J�)˓RìOY��B�םB����u�'��z�6�a�Q�\�U���-M��Ѩiۈ�����sb���bq�#s��"Ő���,�r�3BLKP���↚���;i��B�.M����)Wj5轌�b��i*�V:ǹϽ/�@LY�(��y�㠚9�sF��b簃�3R�6ص;���r\�Z�l�]����k&�d�U)#�J��,]�*���u+�li� [�����k�m��4 n~c:�����"���u�}��0}�Cd���X)Ix5��8vݧ�{c��|��ke��}���B��Y��{�ZG{�����}��!~�p�yFg���w&��RF��.���E���,m����� �0�cyVdz٥�k`t�Y��Ģ��w�ܨ̗��Q:��y�ez0d�YD�Ă�x ,9-Z��1Sr@�.mԐ�p���_�&^�h86:fjif(�h�1��vF���F�O�[��ͳQ��j� >�>��[X�Ҡ�\����t�uVoD����_�7�ݒ���=.Mc��W.4����������2_�՝��fq���y��RTo��~ M~(�?+$Nы��O�{��J�5�w�Js�+ْ���4�<���W��� ��L�-V��T���;�J� ���*Sdy1��r�ݻw�\m������b^�zI�P��݆4^oX �� y:Ќ*WC�U.,���b�=��>R��W�c}p�LA���c���r�L+ܖ+���tl:k΅��i����دm�Z����,kS��iz��n1�W7y��cI~��E�U�N�7��N�8w[��t����t�E�o9��5<:,�%x�ZS���$C�@���FTx�1b��A�#�|I{�"�`���DUq�E�o���㕽8�ʅ�h�ei�"91�H U�t ߠ3���ݚ.y fL^e:���P����,�i^!(&N�n�����ύu��乧1[{a�.�&(��&f3Ȓz�ʀ�R!%,q��JeR��q��d�7��O��*#M�Vj�f'Vz�vW��'w�AM�JܛC ���[q�^2k��xO�׽�e�L����l\f�SA�7k��,N��k�!&�#�gw�n_�.� �F/��<R��{bʱ�!�h�m�TK�dT����Kn���u�^���6�,�Y�2[s�X������k~�+Lj�c��ɩv��g���[��V��І[Y��P>�]�bqnЬG~E�!C�0�?C�vmNGK��o}p�7��~ Y!���!]6>��e��z"�f`���H����i�?_������Nû�x�'r����z�A<� }N 8�r�5}�����^��P��c ��Oc�.�;.����t*nv�h�ɮ��2`��ɇg�T��Q3'4 ͂u�u�����|l�@j��H6�-����?�~���އE>pK�y�5{������X�ͪy�vE6餠֨��]moRv�T0��`�E�e/���������;����~OA#�2��� ��-ӍDk$����$��(g�� \I��ǃp����>���[��- 5^?������U�|��}���iø��@��rk�VԀ �t��:-�4f�\�C}�bnjǔ�����/�ֆ�Ë��͝Ƨ"f�6�@�a������5ٔf�f�`����i�rs;�Te��9#%�o v�/�vv��ڴ����������O qh�D�@�����B endstream endobj 1 0 obj << /Creator( TeX output 2004.10.19:1439) /Producer(dvipdfm 0.13.2c, Copyright \251 1998, by Mark A. Wicks) /CreationDate(D:20041019143951+01'00') >> endobj 5 0 obj << /Type/Page /Resources 6 0 R /Contents[20 0 R 4 0 R 21 0 R 22 0 R] /Parent 3 0 R >> endobj 3 0 obj << /Type/Pages /Count 1 /Kids[5 0 R] /MediaBox[0 0 595 842] >> endobj 20 0 obj << /Length 1 >> stream endstream endobj 22 0 obj << /Length 1 >> stream endstream endobj 4 0 obj << /Length 33 >> stream 1.00028 0 0 1.00028 72 769.82 cm endstream endobj 24 0 obj << >> endobj 25 0 obj null endobj 26 0 obj << >> endobj 2 0 obj << /Type/Catalog /Pages 3 0 R /Outlines 24 0 R /Threads 25 0 R /Names 26 0 R >> endobj xref 0 27 0000000000 65535 f 0000030427 00000 n 0000031017 00000 n 0000030692 00000 n 0000030870 00000 n 0000030591 00000 n 0000006497 00000 n 0000000009 00000 n 0000006744 00000 n 0000006558 00000 n 0000000913 00000 n 0000019245 00000 n 0000019055 00000 n 0000001829 00000 n 0000022901 00000 n 0000022712 00000 n 0000002765 00000 n 0000026320 00000 n 0000026132 00000 n 0000003711 00000 n 0000030770 00000 n 0000004710 00000 n 0000030820 00000 n 0000006431 00000 n 0000030952 00000 n 0000030974 00000 n 0000030995 00000 n trailer << /Size 27 /Root 2 0 R /Info 1 0 R >> startxref 31112 %%EOF %BeginExifToolUpdate 1 0 obj << /Creator ( TeX output 2004.10.19:1439) /Producer (dvipdfm 0.13.2c, Copyright \251 1998, by Mark A. Wicks) /CreationDate (D:20041019143951+01'00') /Author (R. Llull) /Title (Llibre de les meravelles) >> endobj 2 0 obj << /Type /Catalog /Pages 3 0 R /Outlines 24 0 R /Threads 25 0 R /Names 26 0 R /Metadata 27 0 R >> endobj 27 0 obj << /Type /Metadata /Subtype /XML /Length 3807 >> stream This is a cb2Bib pdf import example. Llibre de les meravelles A short summary here. Llibre de les meravelles A short summary here. Llibre de les meravelles A short summary here. Llibre de les meravelles A short summary here. R. Llull Ars Magna 1243 - 1249 Llibre de les meravelles article http://ca.wikipedia.org/wiki/Llull 74 1287 Llibre de les meravelles article R. Llull endstream endobj xref 0 3 0000000000 65535 f 0000031752 00000 n 0000031972 00000 n 27 1 0000032085 00000 n trailer << /Size 28 /Root 2 0 R /Info 1 0 R /Prev 31112 >> startxref 35976 %%EOF %EndExifToolUpdate 31731

    aqC]AbБdRl1SdB.m:ٚg)Mϧ ErajN-q{ܸKDG 8)n J#!Ϝr5N> stream x\I$ׯ@"Z ɞ1}oO'e:+c-Q&/".&vYy۬|?\pvلm|w"y~5Pw6ի)W~W[))1oq7L)RwQk:M~]}͟.hW<}HdÝV mś5k7,_ Q ݩPdcw*ɿ~Ǘ9=Nq?IP+m^F\_7!B %T vO:V\<DUd duH\cW:IrQtSS<%Zhzږ %8ZcZnzlީ脓b29 (J2!9\txJh4-#q $ Z:XPNr."-o&h"KX#!~޽,|!%!*oy-u)ADJ+\{dՋ',XKؿ"n״?E\嗋\M_uSg&z 0E`'[-q<),tKN J,{I ,ጥ tFܫfKִ)tJ 78~ɻ1fkwu[{G×nR+!oC^HNMz;H۶v&YNB]+F`*d"I/$JX2ԆN=~_`Z'1+W%O+!w*~7ݫ>ĥlψ?Uwoj%`)w-ZeP6z G41 s-]sXvU|'궂Am&&SׅEfVFGNHc9NExYԛZGYi` dSs&tQ$ ;+vaA8w0MO7@(QG[ qDVϦn;Ha~`?6 yZʆt7邷 ԲVvHȂ7E)OcoiEzBAZ.:"dIQl3Zvs,񶙿TE M u3SJ&}+tqXMR*@59F;CaD儆j Dek=aSod?6 @uteibQ!fԱb2nW R"d|bmXMy`|cX$9q?hk:K# NOhĥ{PR5 \[4YC+?R U᫴Dm.P;C-5jzsg'sGpC[,a,&o%iZZ[ ʥMm J}vj@tc\$8;Op*)K Y3IXihwLm^92rTls3̯j( m%ϊNX_""tHH"J񎸘BU(R+` 蔭=߬tj֏DvfXL-ĉ dE+ sPk]%AIW ߉D~G;n g:eCں@7\]a,s',и}O(-@ݟ%u&$' gGkv _x\Zmu_ ۲\tݛWMkT5څt*WoR +Var4Ɍצ'@ɹ>̙0H cOwɒVe}דuepp^xԜXOGSSU3!(<OdY7!U1^ /rRx!cf2>5 <r+9!X V^ۃH٢a-mU!-0AMbKz zh,h%%Є_9ی/]ByTb庌SRCrI|MwON|L3Г1^ʣy)Qqx xVb;ש(a] .9-1ލ8V*T)Co,RI'K6U-X@J{]NSuB=*`<0rxG2W@*qZVR68,cG{ޟ(t%TU+@Uf77ROa9.--BSǗ`0O# _U$ knsIk@gw40–;7Gw WZ0.$<F"q&7)X6$k_ĻIR/JE*"V`}5ap5()L Uo=AQ 6n l$< (CnIff̍QcY)4f%H16~n#܋`w1Rd^@?~[ͣgE7}ZR+J=H\rKrs`{Rf.NW~ܾ{Rvl˩d,s]7Ef,lj)\ӖXtv;ہQ(}@fdaulhj=ՖG֌^.RgbVb. ;|JTvDcڼ?ʐBXpEjo+ASomu^ >V("CA,v`J%\<=7=7i_k8v\9AЎ70?jź rjKIe=sb$#H2 zi4'_ D( endstream endobj 148 0 obj 3576 endobj 150 0 obj <> stream x\I, @c~]ndwP,bɬf~YDHOKח\ELBI-9|?\ gex^V!y.a/R]>~UU۫5n*ft@U^a/1wϕJ꛾Js{WqzvǵuW>cˏn2,X^bˋ˯q;\~H& p yuZuRi:Y7bJa [ѷ[~z)p\QOnUkQ*v)̴Sh?$QL_QT" HjWU(-xJr6?~pNIY,T虍iRf51ulȕ nT6vKJMI8C;n@KKx? iH*^fg9,1@-%yY\UF눫 X3@A{\5emd[20˚` a( Me`]Q餔(`5t'@vmc'Sk*K#@=X"y啛,^XЖۼL,JlN۪Bg;X)QU y(`ƒƎ0Td2/C)QkzPjdgPNeBYҜ7$WIYR݁XhgFRfp;$Uq4D9(T.=?6-["I2bܕlB<'R.c^üp[O(-GgAԂۣ GAN(x|ىчH /:M5'`>DKD0Fߺ8X`{dgi# S-tJr mGIj6ԬYZ4yO`+z΃Gq}m) FhW&n?< c+Z93xl {ZDf"E H@$DwpVCרjᗛ)NL)<-9tԥJMd =I&[ΨA|VC 5ᰣhR0!GJnьL2P 2/ۗ"_( %%.Nv<k>xkb)˻vtG8Hai*pft&eqmF,dyiP0:f?ઔ0VmNGՌjxD$Z #K *L`[Z8@B}bldpA4\êT4hFڡ d[>c1W:W.iD_Y%UN#,2h җ兼dG"!kqkX+=C1HDZdx+FR#nCKu)sd VT88A'"*DKn8`-zͺ5`F+\yk^XbOs̅~ѱ-K^ {]r^DL 짤]%*(2L9c\9cVXf+ _λrcmkRSnSOBn&n~A`ACkǛ -/W`\=YrVP 7z VzVHpJ:5C ˝dԴBT0ROn\+gy)7&Ȼf5ϴ; u-yGcyY*CnۉK T#Aݯٱ@1oQZZnfJkytD(٫i$m0Ń@oj u + PMsʸ%2^i.Cĝ#CSl" j)|vDjf*28 f0aSLB:<:M>ӁwInwaʹ55֮'6Zލn3[N s*ɢJ>Q<̻b_ID#'.@R%-8K>afwȱqғ?sMF6F~TFw5a5B3UDu`xpAmULHr>T-ߎ#Jm SH ";m*|VPJr] D^uCEV6 5+41J۳֣!u3$OgY>ݜ1Fxzf9S$ u1>=!>h%C. ,&qk'^1W"u2LGxa Q>5sn<`ƻ93r[lPy0#Vq;gI`t-5Z"K29꿣Bq:@hutFfD=:4R tZMJ3&n6GIrQ~sH>JGo9ጄo+N{vpo\D>$- ɃAdpڸ hz<(;GO^׎ސcWY&1xVJ80R;ſntn֔[mT%p5X&)qҪp&(T"-Z?itcrp#[mJ-GO`^ݽG9w==ӂ3G^;|CږȠ(8QaD_/v R|Y5KQͺZ~KryK%նHiۡSWeٻZG%aP*Y՝iϥrMdx0&iqc$6o$zԅFQy;Qz9I(5]O@AO.aUt oL|ߎ|CZ|lvǠLJ'Æ0FwPG> stream x\I4@MAUW||=1x.-)iYTw̦Ck^A~%I`ߊwZ @tŠ˭IvZ@g=üumea(pI"ͮ9" k4y1izWP[Uٲ% Ƌһq|{\Ec\a|hZjuԜ,uɺLIWnPrx} u:{_ߣt“+#>_K@̴H7= +u?h~ZGEwkeUT@#Ir22L7`8j͆WpAdෲ֦2d@= sީQuƂHWLs7m ŋCݺHwl_2!:U֩ $z-Ƃ}j*.1b TQ kJLz"2:E҂ɤ+pa : MЍSr %}I^yG.ʼK6oa=0 a< ,NLe0EG_$;:6^ DSqf_L*viuPA.jrD[߬ٗK$7w\p!:ɛx U!VJܜ7_+>;%{r:2f $o5A*^mP-H>o^3 ߣ xȫ̉]9ХPE4,$#p ~ϟ4D,/bW:J'.ҪIӗ]ēXƖH7C )F,!, IJFf/a("dJLȯ-_3B][B݂:&4ޯ{$jK&db'cRpUZ4?g{jb(餗 9=$%?\e@kZ^.V4v3IJŒi(#JcETV =qUH"Pv [8 lU+6:\j|YKTyү\/}f};0xa5Usv9YxЅ'd•H -sWRj5ã%h $hi)Aׯ yRO{H>JhO ML.B(FגJC# W._3ףi mҖB>0҄9Z|-FQAw(,\wXSyw2=Ӊ|Њ{GKˬ݁{u#J.vY-xFJÃR#(paǻ{+ A[۠IH^O><At\Z}B|A9hY;%.eVN֥ )> j'ݺW1l14ZWn s^aE]s5'`CEó+=ik[)\c+@sLkOs}sn<8=[Gx l9v, fRs7ք Yx%np9'*Z_dkؘD]³sQcy V=ʣ^PS_ ͰoM[݅e0&v1fG> |sHͿM8Ŝg<#AoYy't0:;꺙IfUc/.JR:kysqCɻlő*J>YxT:dɹN[Cٲ\Xb4Ն3QMQ>g]_š\)M|jXAc`. SS<-\-{nBC$B&"~giAW]Grll~_rd17pd|VaCa R_?v{1i؋qSRäFWEv"}YO(@YBs֤V|)Qri_;,]"|)5aݗyFeȑ녫EWHd[Q$!= q3߉)ii(4Ihe_N8XxW=xܽkxQPDm!#MD۾_eKf8S.hE_-+sHӽsv91)R*JCIRvc̶]rdQ0nPqQz~Y2QVv۪wMn#_8T%/>@;vCcXnܫˀXv#6TN&9V@݇3]m;D \՞ϥ5,%ݴrRGz2ԭڸyS ~ܐ:jӍ)sag)IrVԵAyTrq+Ci="ݠT5U .R%Z I]ۆI.m*} c=@C]͏z `-bCGZ6J7;,GTS>0>pr+&U@{KS>q۲tQ\.&bJnC[КP܉q km!ŎXE ps܊#F#ח._n$t$){mpdoKy]ll[k4W.h՗rJ,r"Rbl {fBT>ruf<b3e1cŢpm\=;<Bg{(#&4W酽ODUUX7CVuq;AgQ|X5Aj ybxjWs3M)Qjwc? wTE쏞*J?sa̶~lñ|h@p&- {vEfu> stream xn,u Lk4|s" $`d~d,잧g?XVd )6_'6 7E)>;çyqL.Sh3I83jqw0yj6ϲ7ruխ+._ueܶWz0{ONn4݊v𙏦]ꖬ:L ;"~De>U1}*ޘ*`l*xEw.'F [a'^ #9&(kWƮaHXw%&]>pa*gax\z̊e" YӦPQq-0 u= Ei~-ap 姡`K`.6g>3Qs\?9ֺ(ҋ<3uj-Xg֟ &9l ?maz"2#ssrJ9DXYnb'=h }\+aadW۸#-7o sVmVE\Dn $=ŚT.dJ7 agp2.u\ 'O}$5Okబ-+R_^xOޅS[!ڍQ#ֻݮP2*ҍK):Ҕ/6!yx;(ʴ8UYD%{9\į~Q*@u}=N=`kpwȉ~/U s zuJ^1,HC5EJYȨx4Rxo<dҸDE&QfOy Ge'ffAnhXX[oFl IQ︜č\U TIpA[.vo\+IMz+U`+,nZ&6Yb< F/\᧺bqgCŠ]^eZkla%i*ԛG?1 Kր aBSm+"fQ!{ZJr[kٵ۬jLhZE؅{InѰ뼱(& }:q@s{2}&ƒ/I;4qؚt9bY&hq+'|flVwY SHP,(+qѡ*ߊI&UNp-UYLE@89nh&iusb_"$~'\.Y(ql@%Sv3QlCS1Sڧʖ a>UË;/~a+1q-fwk0o2UNdi %xr;%d OLR6_M>ŊԴ:{fK԰x\bߺVy&z&2ƁGd:Eucj+qP2e;]bm N>eOp۾[ӆI Aر$ʩYl$Zn<|J{e@š8@4kkVX:cP;9sR!{ķqՓ /=Oh± GΪk errzSERH[Pg22W(Ԃ@lð-ȉݚc74*m駬r@Dg%JR.ftSn֖Mla>$]+^$na)|ۖdž3R>Ray\P R)(b 9A0-90Z{J (CjCp(wjY|VK$韊Ȝ\X򒫫 ;~m B7y #zJwEkdD8^+dSLġQY:nܸ ]*!ms?\d1Yo>;$R`ӖPzڊrCp x*ϝibnt >!ugҨAoc՞GSc4jÒ\L$HIKR^fTm# ^5I2BUMgRu9YJ9J>_Wfd7Tb5,\ܹQ|^YmR`˩[N.r%l th  I {sHu}Ixs-ڹ@TǔFC]3!0sLM'YqCݣ$LPNVD͆mIZRa} lx3lH'Z"TJ&XU]J mWSTR>%ܫ|IjyJV)eS.$4=ěyj+ȃqK,RTo; oن b{LFLN-35t r59O-y?}M,i4ewqT+qqݑ=9؎wӞ|򔄱a^Fg,0ɍ|Up/1ouO#nX:`{yMVvWmi8S/`a'o"E="f;9f3UfaA2 0E3 Xe6%2ưpУ};UpԣV VsS4ϻ] endstream endobj 157 0 obj 3892 endobj 159 0 obj <> stream x\ˊWzdK( ލ} <f~ߙ׉HIݞ½UR*2uD莃xQ/AX5,򯗿~wOǗǷ7 eaZ˷^4/~MƷF}W7e:nnzƏc%9}U{ç_} GfO?ʢ~]AOۏo 3lcA*w5܌RwwSfۖu "l)ׂ(U_KCC9IƿǷ%΋t( ]7L3jՔɂa(w(Jg0Dᒊ;o3lPmܞiLqXѬn{8haue]~.8pK4ܤsh|ըբ^Yuݿ$\׫-KS=L)T#6}Wjw&c>*zcHLGtd 9,h453meꙺ:R&LAUtp,Pw}zq z\N{> Ni, P1Hڎ&emC#jTk"/zsLKTk9$Ȱy|m> " H@Ld>(8qpqdLTk94 ttC"~$LEP0͂'/\N$<1ոRC{߰ERڮwO,,<O@,o7uBl6@Ψfxh9=Lg+ۉ`^u2D.ǏC=N٧3HL[ڝ5U]-MnuX@b i T9n4f[?cMs%.Ж;!IRh[[ٶ[KHex ey[ѵڪY*=32D{6~ R8Jh7'SC86u)b!YK\CkZOz\ SaH#hWJK-'haj{2j+W6͡"e OͼAc,G˕$ZاT?U=tx"9*`'UΎ\ ,@M_[T}~(&c!o)#Īfh蓱$iߪb.5QVY!ng$R^CHg^h[GJu:i'6BH_JZsdIƚa28’)j:iXHc=@h-6c(/rn rȥ]; SlxfSGg䓛U6G!az= ;д7!X$n˷]m6e*juy89wÁwUk|M6 6UbtGHJƧwqpc|EL'@W kpvX\8`\1)ZjYb4_^'h)L:~YգGcV}PIQyQؙ:A F@By4G.S8psM>_e' +Ջ9' bct9e42'EPLڗ+Q#6i^ӌ? $?-(*.؞Wɖ nMPqBM@ɂ9״?e\`/?_Ӄ5f Z˃@ aAh +hP&EOs)]|HK.ݐ"Scbݵh%޸ %y+>,)CE ,V,$҈Z/xeRh< J=%Lf/fHQDCHCMw>NRDxp[Kҙ'xk{qϭƉucaIC)P,53.s2@waI[' 7,Vv<ܴǩ jhJN[7Fgjau:b8=+M0K"nŖZgpPP|&cZoK$P.;xÝPc=x,c\3# O$x#Eޝ)A0Q8ni\)W- á] hg_uqYȟ}ySL/@ll?g Wt; 02IRPO\L}֍vފԜ׆ X장cqK$o||1| m#Q {:WZ_ ` %=QBCA}+4)~l@ÎQv(blhPC8PG[R;"՜LL@+! :J!7b$IA s%xɮ) -u/C]5Fmo{eF)(M""Wc  ģ!3bj # %KC: z{*]ndϟH,8.μܜ&NLJC͆1Jkh.k:fzܙoꋙPRetx9P9w6ѝ|LJb)c>LxWl`2==O-7ɱ^CwI?e yU'M":DΏE56KCX(nר7b}z94;QI6CohbccۯqRnHʧcUSvbT5Ou,D5 =>^Kowzq YydXagMuڭVXY0__?je46 # rKXX> stream xYK6y =m@2TÆY-U261aI=X';?{^<26v^~xOWWyuW.]<\֑ÍWu,<[g8@\%6cYJ.W^+$ w d8םyeE!¡l[GׅU^T1B܋UdhpGm9*^hs^L&k΂?-^_/{&q? #̎~ThȺ9sD$@`pVV*s {AKî[Eɣe#Ӆ2%db 1HvVf'ۦyk\ JENR*r7Q۸7^&;- z[^b< u =$3i)B%O[ hyO0 &&0RUdG$-S8K4݄J%cB˩grΒDg 8_ ͗jZvK4hS4#-O^N z)՝7%5NZJ J#CNFrfC,PʨRGM[ /䖣Vt! ,Id @}YdHdx-l0vźǻ;ɢEQ$i#E9rQ/RW<nL)Hf?Dx'y2"kx Gcr!$XPԐBr<7QP[{ Ev?>yc? W!jm(5!uC㇂u^4E;?hdB,3A*JTOg6Pܹ.e j =&6ခgHKI;jt8 ;KHw.!'!!Kլۥ3C)cđ]v&A?8|:> stream xVo[Wҥ]ۥǻ֑,:FY3F/7ʩA࿂ˬKn7*U7'ob'e,j^ /Hݽ9gʵ捛!:Sˀbǐ@P@Y=}|4az?zݵxX.F*}TD,ޠoWJ-0=G: ]"h+z@їM~@ <}E;?Nŧ2] ^A^;14Lc§FRGc¯WHdHc"KӨ4>Gg'q>EEpy_Px奘[O7]E%#~~a8&+2o S)ӳ2Fj\OG|lG;ExTr|Xt _ԦͫՎ м/Mۚ I"M' h4whRf-zux5ns`yRZ[T[3ADN1'oq/ 夙WDQD+mE%xJX9%XbbQ*/r*&"6'6q,Ll30 ^GwcXCLZ&eL]4hx|+q|+H[~I%zLc){y\S;$OY#DZъ;1;,; 'ys⏜: Knٵ4{aޱZs Y;pg{EOQb/>{'N=+4wJzA)IwOw7|2<.]y8H-4Y!exQ8}G=pǛCW <ײ|:FӪ5x. u/$I>%4R%ޱ峭jŲj53dr -r˓Ծb^\>cVJ'R6KᩏyY 7Vfvw\QGwt٬ZE>4n=Y/:tה!떝ۨ:լUjUMwGtH|^,gi @9jy*XsɡmjE5o&+CMK4CIx10'ɀnNqFxFZTE KE[ VQ'qMy)F/#GДR8*ʺBA*^jM )TL)ûz3bU-وRW:x<ƚТ'ot?{޻Gנ)L*x 0hozC I&q2kl_ۂ_|Cbm%YKT i7u~;iGŕuMt:륂STv+!ʻ:uG.Blj4X#}m ;ՁvV)w 4.{}*8N.Y;o{% ]vK}Hbf~kZ} XVrF endstream endobj 418 0 obj 1772 endobj 419 0 obj <> endobj 420 0 obj <> stream x]AO 96&f&=?´؁L)VM<@x7kQ13.qe0H|pPewMJ oKƹ16ү-78=8Y;{@ޯ~Mg j[8=O6=u.;"_mKd USU-4[? }Xd-ISSNc2K2{?'ŴSe}~my endstream endobj 421 0 obj <> endobj 422 0 obj <> stream xͼ X[י0|{ bt1H`6`0$6q81ҬN8m2ML:%͗i661+y_{9ܳ{49>5ThQ$?O@66xm9"Ccd~{D;'BH u6 d,ٙP P3UOݰer]ɯk l]ׯ /c?B1ҿeL O cm(-`{>6>8o`L @XrD*+*F&s`KLJ;)TwZzFf';'כ_+,*.)-+ 5Kje M˛-+WutvuY׿vk>\92]]FV; Y"z=Nw!?V=]S-z݆^GAgݨWOQ=LQD73w;ͽiDϣ݀==;Sh\_냬Iy!aiⷡq܍ (6\V] 5u~/!?Y0ڊQkN0oIJ Jcu"M78z*!r =8F,h MHu}0Ah- OQm+Z[˛ՇuKjuUeEyYiIqQ~77';#=͝Jqڭ&NQ+rTs`psi}s\+ayW?_U7瀢u}b5ǵ59t]M!ZSXuJTsԹgpWKosu:.&1ͥ5dNxns>G`.mL;TԺj9B I%2\cqF5$#P~ u;G݁pKGtvdi\u#T+69'M:as3ѡ}Հkuwgh`f3骛++|p.UVZi%:csq]ݵ%[9b wf&rgf\^r\3U@;3_=l 9ۀc 6[;;%w9KmN}B{&~Bfn#wtΑ>s;{2d>fÊ9]? M|Ȗ¥t2oXvixS+3:1sv 24 }mЀ#'{..}[ǜP ?Fy^xhN\9klZlX+Lso]9oErtEO:l/P!cj3Cs>Pڐ:a;] B;mhXjh( $5ǹ5EebPQ $\K*:'u UT:: -Ԇae:uz,M7vnd8"簫>D5p .Sr?+G%\ pN]5G.|;hR{#oR.Bi )$:MY1ϊJ.U>YOԻzgqDR} |q0t03QP*!\)pxb;ANgW*(f"&tZ >.ʼybW.}a.I%S ,ٻU:YV |budk,zLY7u#‘7J'׷ZյuI4qAyQap P\ٙ9IS;ST$=`"١UCvgԤBӗ+.+(R} P䤡|L(; :>XL+BC~Gwfw*Nn ɲS2TRrIQa5I 3%i[,+P=6޷aݵNҸ/\YAIHVشwԜzoȏn?ýmpڊl5"NF:d:&Tʛ#C~PU|S9-rb>ɜ), ] 5愆h4 K%A5xr\F % mI8Ů kfy9$y" xp|?@gSzA`Dd`T]W){OCz(#bO d}סuU3˺k\Xb$4tt{֯PJy,&ЙgދL:M4n8Bd T XYA6ypC$iqiqN\!;!JҾLYKa@ TU<# -|Q I*dz0\#HC nI{FJVZx € \?SEk\pPғGpB#͍R?$i&Exk)V7zHh:3P2Hu63iwɔl(*Kf۬픍ٰ͖n\Zadlci9vJ-9dY8M+(g(T*yϲV&"z56تE1"J/pݽ+owA9SNo>S^7~<]Tj[{d#jo\S`Gay+. $%́'mld[|L# I;uOiiI#v_FFeoɈL2 #F#KKN2u N +ya@=@1 :aQ5_#iz(& 'uf}mK+{3raэ_^ycwelɕy=3k9wL뿄dk!"3|>vmrr%bnO9x'v:=SĘNHڜLXSIKwK]մh$JjrB)#pyOOΫ%K6gd'I*ʵ %N{(L*K F~#s?}{sc2{.Gj$)R)qrJ1 1kJ$ ˴ SstQg8 '?n "дE>3O|,d{|Ή|~Б(G/ȵ!Ǚ ru(,:7Ce/yr:Û^oE*:5Z_M>T&:5VI)Ԯ3jjQ߅s[ԙ[ N,~aqK=qHzbT<gai:_cNs;VSVZb4o4ozniHi͓Eo}ABꣃh'O+-rNj SVDL\H6YqJ6p#Nק:;a)uVa&.ý`XIʵ|VA?1=Ts x؉ yO|/QZZ x吅lx"|4U>I-YIXA(fɨOOG!^W(!dﳏ٧ks)$##E PDŝiLhPbZj$.!RX4 ZX)Z1{Ǜ UE kׅ2}; UGm{o95jϵUoԤ(5yUYF}F@]O&L9Nսei6.+w1D!)S=|RONo1ǝxznB7È֣NDg.*d(!uu69q)[J:%R-A&xwAև8"˴<⢪ =])%n 'o'oeiwF'??_'w^f` "=9/ rU( ] IN{=dD0CNKXox-f1eƒ˼/1iLa0bfi&u/FIR!2.Y+oKm8vgQJxj*^Ӡ8`Ed2&9B ]%1W9DmGE< \LȘeBLTˀjMnB%.T QRP:ԅ$:0،Rjא60 P> m#?>~tG=2T7:@ӣ_JxH*xt8^&N)`PtAO !r^޸0 Qnx^KҋsIZh`zLx;7֎=禅oX;M~.5/`arre3XFVX`X%HR.&EHg\Vʏ˹fy|$?,X.W9Y@`OXQ!`&xl^]ӯhd} CCK"K;|ؗ+ˡ,gr5 g -EX"cWHV,"5"Ur7)xBp(Q 9'UF"1qjdHN%qi1/Hb֘2}? "MDf"??4}@qO&$D8breHz(k7^<RH1LI6!SD5>߂o++9<>@5ErW}7Ylƾ'qt>ci/5 z#8qh;1DGb:DQJљ_a/xhܕ0Z(ng>2N?Cl,D/i5Sԓ}jN4_z_TξdZ{/-]W՚Aԟz'w/"%Ii LojfE>?;Ig&?D}@l,U06e܃`>YWWҨowjc>ZgDU\DA (]>rP}ff ltY LdeTfVYQ `uJMM^D&j5&VD]"Id&XFN59(1RYNчR$h̶ʼ>ς5.By<;Os0-G"ŕh.MOK$c>c2 Skk=)hu2<'.[XȚJim Eᗵ|kIe^aΰ1>XҲx/^qq迋1_ tuTL(C]z2X%dDf5QM//3 _gQFObOÈg^Sdgn?Ǐ<6Q9S4;CؘMV]BTPB+ؖwEW=,ύ819׋E(+ o`5)c;|gcE8a0)Z&BqD.-8y|H$ͤW|?$!L^bjl5}sތB/WqOySt#fˌ(y2k-v~\g{YD g22ш` 2a)'yEsn  5/+.|f1gz,7sM_Z- ^8xz_+˷'32뗎7{"%Ǘ.} +~ ȟ?݅EpON?[E'Fd?gpǹS[ C\C0c e00Q#yydȩ^ATa$$Kqtݬ{!;ynEg(z+]]]t})4P^BjWe9]9!;$ڲm6j1)7Ϲ?rS<;rTqBAتW\TpQ9pZ'`|bl[4EݺVʦK4mP37Uڶ-'ohY-'F+_I m 26.YJo<{Sƺ3ɵ#a{wK?[=~bSX8Y&tڲI4DU,؟Ar+!;dIdgʡpl  exTpl2ß0sUIHSuډ&q ; IS=/O] PļQǔ퉘Ź`K72o`qEY6䖉G M۪qCC%zWbрoY1Zwݱj+N9Mu@QM}e} ڪTm+y[+]V5h-sivv[1,+a_Ȇ=._|Av:/ ay:s:mJ20YWlf D$.q:kGqq>X!1\\3\)Kqbc ƴ0C7"w-;^^޶KEl]5`'o_̪7j知|ʨZw/[QP=dD굝a-E]{N+~-jm&iv'ds2N&5 r}d{T*u&A=.36|iaL ~Wo>lN_[s<ˆkGs*%7$u'M:ܧ“dU@%l$J}KMI.)>LN23Hl4k]{d ]Zffer y].:'w '.RM굞zʦ0]K2mDL=kޞWq]Кm3, o^TԽ3P2sIoP~T[y?Qҫҋklvʼnβ9 ƞU:"?#7q[ kgӢ Ʀhyڮ4Z+e&w2#AJ;w.RNƉMN37;u8>7zMFY_/3_:]%e8W8-o]KZw~AS[K*'j_*zyMܫZGkAyjL[Z>\~ >i2k!M588*p![Lwk,` ^QFUoi7&ߊ3&&͡oPZ4As3GӠHu4 q+U5o0V0H%&DX*rbkdR5VKYs]Y2`P'u1x R';8oR'Z-{xwd/5j`JU\t|4g!'Eۅ19 0!}ʻTģ`6C"M!ETSR3]9 '1d&&fz4sa?A<+e==WܰQz)^da^tۑ7D23ӵځ[:r#ޏ2rz/aEM>|Y| ƕ-y骭$cSw^7GYB$RF;/y9")BuEIAoi_SUxBƔqVœ,) ՜lW$!KتՅyF> -׫x;w]:Q)'g97~9]ũcjQ×j$_/7ݼoojoMܒ"s\Ѫ%ªbxUcY tzЩeq:E-"RbIlJ87wl;3;`yp}:2aOb֟|ѣmO CSb]T*-z.C|3Ž^nmѩtdeu[}#~OfۯN #Y7eY1[h恨*_~`|o;RT*"G;`}9-FuT+re#: /)Xcn0Q}#|U؞2nkA:,=_^ 9 Y$).)-JpNԠ(9QhLrxٓbVz7?0 .#|u}}}P4Gk1uFEaiH1y!7Қۛ#X?o3ME6l c'{|Tza8c?A?3J.,lw-|;}{Pg+mDq!,V& %ѡD\LÞg',c!$R9Pgf]B"ԝga3Ef +7HBO1ӊB! WT= * =ˬnO"a0Dgݲ?\n>:}gfѦ{Zӷ|Paa &?Kjr;s/:Ԍj"RsSYȶd[ʁ2;dqԻ3v=hKz.J^ .]_Mݥ㧶O?b2v˞Dpgm @蘠Qs`PV3IDEuA @VÎ!d ˪`{o<:,^hIa$$Q<@dQ_xoBU? ։,';[tx.scǙ˟2)Q E n $T絛Ϋy">oSL&ѰU y.~z(s3C<׿2/g,g:qfNhhol |wmK2-nA 1h,e=^va*DR&[}=̢XLr:_N1!|r+:E^^fcmy\ҕ+<<|SfVyV l[W7~r{uݲ,鎄U<45GHϮ/JN[u>}CI_Z2 ip-ĺFw\W݀tʠx'wշwzzMO*?Tr)qY5[AKd WץӢ8-̦B)19zxxst]˜G`;ή+;(]~Qq1f X~Ȉv*ׇд#y=s"=Yzԇc2|vƻ0X%R!HfX h|a'>NK@qDbOr=9iHFnZ`fpLޗL+Ijra2Ibf25t4 'hjRaaJItxS iRbNbU"U&lmPjBf%h4`5kΚScH=ޯ Y` cQT@{kVQĸF$UcܚJjb'Inte6d!SrI֔5/feek@411.3KGZWT8H#0'Wd%rz]0M/ KJ0%a*-}agLؖgt*]_?+3ɕr7)+PR7JrBR9l}=Õ?bm[7"LK]]+I58DJe̎1.-Z 跋~n9/DU5>БS77-2:)l}7ȥ|4%ihɰl쐌+0`[fO|#x7WaJnZUjTEgUTDʋ܊L<":tP+ YhAlULټ][G95Y%+2=+j2?^0JVVXsasȓe ȩ)<07?OjQܙy(&W!.<7vaz7+Dik^w{ͺOۍ_{AԊ@Xfo,yHtAWf#X_QwKFM'uI)&GX~=8܈{r`فexYpVX0rzeU#uE!<>?#H@gQPBTj(<A ,kz| Pv6X"tOH>y'>i3]N`1v!\A7:J!PkX D(>[ t>Lh!Kټ2!]oCrOa)|?>?~C?f \AntBCOcy=h0n8"˰t.tYHn$)p˔4bv:`f`ٜWm!'ș D7N*/9{D1Z, b襋 Ө5_aZʌ`(8ޒ|k(2IyG ?M<{C{WМP+7ztnU"akTnd[e2wSvNOWO1Ʉ4uHSb_NⒺ"=M-5Hklr>I=X,HaEFCR)w+T} gvnv=}2oEm:~kqNu ;wJGvȟ"[8|];/v! @H/AmRŅ4jip5XЀSInP=EE_؎(ם6Gg:d=b&fmz#h v!~㣜DQ/:2GB\r*sit3{lOpoOx(ơ6 ^EJBJV uZP||Sc8SSMa{ګ&=XTCc>Lk̀7/ƣޑ(R#J_41" !dr[xT >rr"~ϱoD>Jխ2 &)9ʓPDX7U+BY(l. ݅dһK$r3f7rujWCz닋C맹R$W(ɽ/N_ymlK2|Ý۟s׏.k̓ǻ(t^_zIu]EqK:t\_~䕫6Fy~*:uw?wr8s65v9>&p,1|-; F^14GgPd$n z2Jug𥩯Iny$d ^ P/0$FËnнa~ɨdJDBƢ/:J|IE,bדT|} rg-#FAPEB:0N_dNzԔ/>Dࡍ)VS&PBu`/1 E&+P5g !YCF^@Nh\,Trlcgg!$5TP Ք`Zc4ؿG@\PPh{SSzShJJBzNM zL -Q> u_4琱ۢ݇Þk? m+Ƭ;G!S>kZ^oK7~7Ȕ ch3?c/"2 xz%̿s<{ :I iȥL)]B':S/VNhU%T@aԇQ rVK\ r-vOA)I%xx4w;iwPrV`9".6_ED|y@H0bG8Ģsfӽ2[H7=)22}bTfN} Ak )̇2\\\4)CPq/؃| z8$RWߠa6"nnmS$zyҝٴn@zFlӻgߦ lh]RQQv%JʒӖV\sKdft@=BBsC=ܓD'7 #^يY.)$d}NKb Q9-@H~0'Mw3b`Q+jb<6| ʪ7wT&jSZ g7ʲrTy6-t>)Y_qsdww~j[_FVqR81b۹+`TYE&ڋ R3wp=Ϡi`3x9 >t7Gg"3AFt#B_3 ^M h t?5DV 7$~΢Y܌6_ Glt;z7FXϐB:W^rܧn?$?K7J#B&\%_+Tq)oD9|_z@ڤPU?~Gӥy\֡}TS>}X!CZ㫦D ӋfΜf~>ָsq,kQG_$,5>MqRbұSN I뇩7t-DZ2W$.hy[\[ pX h:GciXZbi)څ^eȄbi9XZ cX x"VQH,ADL8Nsdy,Q2ihv,MQ!-93K(KK T,-E2(;K+Q)w)V|a,F?tdvtl uG#?Yټ!VpN ou4/ ִ7/w O8[79F}qxx舣itdupu#uˮ`ܼ܂+? F~xbrp G+rIGȀm桡ub~<:ƹqj|xb`xm"wqc16hꟜ099Vn߾=?Vy]7M^?0es# hd>%dX:َAk~n\7;:޻}xӰ7zfX+~F@}c@hZ|5(J Պ(F6ʅT p„ ܷﲚ̭Nua~?|'v?D[>6A(#V=a>OzjuP2"1rQӕⓉ|X.o[?DV&Ŷ5Ŷۡ VX|AaRmD7zd2qg0Rs$-BzC 6= F qt>Iس bn _.ԹuvsI1*Ј BSW1 eA״Vٻ H' 1Eh犥9C[+~4 cv>_MC7>€rp EÿngagݟmrQ6xfWU_*ڕq>hw<V؄cWU?mF@Eh|s8U\q= z u6?*v?~~&q4d{}wϻѷMf8>&v7؛o׉u룯zϥg΄ό>Ë=zƘԽ_~en :=τsGܹ9ss=G''gg>z԰#W榁)ic% 3;6vO`=^^NdɺG~vٮoMq6A]޻w볻xL\wl(;GG=G :f)k1kM :!ͷ>z;ͻ ko潍 A[X UӂbBkB|{7ܻn,0s dk)>"pn`kfr ZJB;#a܈I`>mB^ gA2qv=ֶ #lk^-zQceei)(<>n[4^nms*tInC]1>ҹђs}I sXbqhIƱإp3.`9ɉX IϔxLL/bm@QIoM ށbbp_3!v!Dt 5_P> endstream endobj 423 0 obj 19211 endobj 424 0 obj <> endobj 425 0 obj <> stream x]n0нBtXr0 $~^:GS,_ݹ"MGfwxiiO]ߎzMGgmLdq:?]l}:᥽Oئ?| ïtNj4|ias7%&݇=46]cceQnRs%qԢe5g\)r`#> endobj 427 0 obj <> stream x8kxSב3!?$W\mH01b[Ž!~'2E’[%Ccq:Ph$+tnJC&M$h&%ݴIM6! M6nms%Cv~+sg̙33g76<j` +yL^CynS_d`$q}ܾy ?;2#$ci?_9f  c^a|X-,O1|0=xL`(ro 9 Gc/@4xd8yp>A61H?v40ѐj4-p,Yﯹ ;fc3ߴ"Y1W:r (L8rc J0E<x ~RI t: ߇7 O:߄=9Lxa|D8*!t-beg_3Q{,.051\7wK |~ <=H֝E؉i+c)*g}8a'퟇ 6gǷ5346uuvܼnmMMkj57^liJPYhr3mV9͘dC((^5Xil` B`D^ˣ~MS%ξ88zr TE^hP \#x_-k:NbI#n'A/{41SPjE9 4**Գb4V<4MYiЇ^$]136[imri!\iheLjsU=DM,*e(]K $("e`;6Ud,013Iظ4񐇡G&f@֬~\XYhӸ" k{O 9A>Pa!h/˰$βn󳑳#Y]ldtvtBliBQSP h(P(V2n:LV5dM,&Ь(Sؔ1Mb[\&ǣx\ Wkew45gI3~ @>ͩDLj%1Mˬߛ9= L7M`6ߓ9?D.x K1gS^{|>MiɾvS_%yhyRg5j\}Cin[[0$> E(J9-(Yq|71Z { PjגY:j]>MfhdO!k,gJr UQѰPL3Sg"DHNbe9/ҭ˚ckcѽpD:8vE35oY\jkt*xp<4w1JB =4`).軟gML;Zcr?۶cJSpLTA.Jfl(bV7qt=iٞNIz]x!YS9FeD a I TFQA'xNK!NpquMT.Rn?G?f9*j9IKUBuQcZF DXQ~ǘգ\έ`G\.:M'cYs2IpL k5'y@YdIG5'6n7pt!>0/v 챋[,KLJ50rFcuꈈ'RL" e=ΞIsrq%:%ev3YiR:knZiuk?߿j8˻\~;\LkA(P:3it~)6C:N2ŷFZ _s|Mj~)x >z;Mq<ǝxJ 1}}:{.nSl*Ž-3'׏%&YShBq*55kjyGzEd\wlH*+/ $tzf5}ț/}[~>ZX_ݴ;lq T2 v^@g8 ɂU_/sh"†3s=ngO;z\B{2+s=lws+3lY! w_~zۺ`7;Ɛ M1˄)Td}[?x` `P]44lF̼- Nd Hfd0Trj"fOKe9rՒβIv ==3cvĎ%"{oz47=mdn^M;JD|]?򳨨жF+EN˶fKmVȦeeVԛdfSnnqcZG;m k2 )Oyfl]3}OUse7 gbJ?FjK9|^(YٖG؝0ҵ.k5?>6]b jN">D̦1yi/`tWy4Ln鐉22 2o^Z3J-XfAY+*-i&nEcܣ[zNnoWCxwg,V d,YJ |jߘz7O\0 hL 6,ɷMt*wh˰-OWg2knn#%&aE1_vN7%lŕڳ^ȅxN2ZiP$% bnzōETȲpjZ- IJ79JZYDQ+gCwuw1Ϟ;wu -`U0?s>g(9sF4sbSKbRIvےbrmْ^,?lurw,$TZ /T?÷ۺsQϕS|rS}UJUTo}hӕ6oNM[a6fq?CF›q+4_y+?,# xCfyxU X,  XL/`'`eŷp!W'0cW6 Wv:pWN0OfX#(v[ d~ya&`JI"㿞 P?bNRD!a('`&p.~;.}1w쪬\&rc V.7 :۶:CTECCAӾfy *p  o}_;)4 up]x[pu74 u2$-(#,vT.s>` M *6Dca" ]br`((w^7҉Xñ~2{@48˴EWWS6tBC@,c sǎ@xA팄!Z?6m-4%Gtd\zCmqr9 L|dZd8%s7;w lp mv~,IIfC=a1z( *鷌vA7RQ AjF?yv}.\KCVC'-p3Qtq7tD Cߟտou=Ld[E;D+Cnϟ+_E^XL19ȓ$cVB_y(ͺ.;9"U|ӵ \4|я9{u1'F'7(iذ _ݺu:=ױv?\+7!סC?㽙xw2)kȜ5}rЫ;i5rXdٝ͝>OZ0={ۡS7k4> rz/u󉓐/'\j [#MygKK\{㜿%J]]O d$?=/E."{ȻbjwsQ\tإjV6u>_z|׻}%uu|.tܑNj$͗g3rh?L4rFAiP.%)ԮSO O=/< rEvE(ZÓdtptuwwQR}:E$NU-Y`]t0%W"}h+X{d`96 8=fIƍP;ʥRi$'ŨE[ӥbf0OKj<;d<~Z-"^6DI]yܮ$7eٴP PSؚ'ETǹOy P6oaKZ͗2\]"]d^ K;Ȫvjm ^iJjh']jiZkj[Foƛ!Y3^a^+ەeCKe]ֲѲ"X,NK%loy2cI%% Olz;eeI3ZJ hEWk=tGR탺͚çw7kAT`? uX46R_++E/Nt@!( FEXldd!#4FDE酞Sia c#e$6_Q/A endstream endobj 428 0 obj 5532 endobj 429 0 obj <> endobj 430 0 obj <> stream x]n E|t;ɲ8E0vj0^ CJ]0U͵QFof-XK% b8HR!}Ti9oFSQfkV9'Fn>,IYR !B׶-u?}@Sp> 5`q\ҢKJ%yt=dI'X:N<_> endobj 432 0 obj <> stream x{y@T3g3;032  Q3P0dkj[jk) ^sfjby]v]ngf߿~3}ϻ<~ M 5H#t L?3V97cv嬚k!n]ƦiCd@}O m"O a9^!(UjV FbG{EFE;1ޱq}&&럜N90k!C >"'7od~AaѨc+_Z6މ&=7#f0wl>2 u~Ekݟ~(Sǣu~!텖0 !-A-h=Zh ֣<#'M/WR c[HnK !ї%9c)wt plƗ؂jW.p|uoTЮT0.ѧt dTT9|\0 FzCrECvX `td`:O+"76 &pPZ@SXn{J2%}f.RrƗC|>TQKΕʑR W~ ;ޞɍґ7v-m)拮WMs۝>$uxn+JiyxWѸn;qӀXQ؉:ȃk)bD`JwG9Po ×ȭ &:*3":~I vej~)!~ȗ(/è;]5.ӽQ\2CyPVz0 ؄p;T%{27RwU]h\E[(/!ž A:D0i٠[=j̵$!ro' еmx +O,?&B_YZ~̈pVH+Z3@EۏyZ,e^u#MaTu <;l'ԛ6!жXn_툲̣+=@peYeA0LKX-J*-^jl ?î@L^SjԮ=gyڮV }jr'#✽E7JY? 4`r%BinNvg&\IAǑZ~ /uSÝGV<\b:#a^^t^ 0caW4`-f^aa f49eF\Ct.nXGK?ޔ6v ߩ_pj;|C{UYgJr._0˿ɪ+CBvqW=ry *ƢAj=)ǀ@j$=)j+xBk롁} ԧ@6'de 803dl#lo4+Ugbc4Qjy"Oy^t%3AτL%fOc_,}h͜.]>~^Yn|g]Ye3o_S8,鮁#O/AozAnHlfQ#Z,}"rQYVNc3eՒ9f}d(xJ;)q %<1t|w;]y%If^g;%9K.JJ;ponnZPj8x *!D5(G,VBSpy^BO(nJb@Wu\WFf dn=+МX3e";ECG]ˢ [JJj,Ƭn@? 붹 `v /{uI٦i!6M zV14 1H/MϛeMI34AGOqWs}k;;ީc1>XxNQh|,tRTËR8`䭦xF`SS3ڇioڪjq஦®4( MH@p$'"&NDRL! dJuxi33L^ fמ(-zwe%3 e{jV1Ū^oE^^݌6АKw˼gn[=:u66/̶uO?m[R1AʧoX,]K~< Xs7'K>HcBQTF^^תy$Mt/ C< }uUb:i܄ (oo{ tp-zP;!J%x!HLɯ­LI g |;>${$۔}/_U+'ڶno۸}ۦp;i_?.{9 <e1FjYm8 pѤW"#; F0MCPwH%7>~G[@occ-]z,'P-3@/\%QYArd ĵ@P `OEYV fSDH#(ϫ>mx6@un`I%aҙ;*]ҙ)Z"e~!-/Ae6y> 1*XmiiDnmR&ܘDKpoǚ?U`(hdxqlab<ؘ+QǠx`Ama>a\勤%Ď?KKL*c&\Eh+1|`&z(j&+:6\5|D/}>#+ U}^ˌ#ZZARdP_'- k0SF.(ό&ZH6|JMQ8J⦾Yܲ{?zmBdؼҹ[^ćCl~]kȧO %n^6Vo0g ׵gW̷w{3ɐy_ ȡb,bXCV`1RsH/H/° ;ɬϘ sɄ%K:|(=:BUiF#83w^T~'[[UMQ?z eNzj{L,K1Ā \D J?K})f5?m:€# 9?9]sacV_ !˔ϟbDDgݦjM&E$j!cPu<3u c[_Umo^xj>jm~ P"\++ңU N$#vty#U0)FvJZd`/'/`d|Sc _=A11mh'W0T{Ux7O&[䧎K!KRfuƾ)ţdYPh+X- tǷD-n>&dvx(t7ayZ&ƫpn~LrN&ʨX-b=dTLDeF+hU \k]@)mϷk? 6Be1n81*9 *9e8u[DXXxֶ6sC̫++D2]0f"t^ؕh2oiwd?ȟWi#-/1k)&8֫V:n&]Kt<["v?3QX&8A5XO͂F^vd(lXFy-"/Xu?1x(4+ҏS{EZuϓ2Gb^&Icn݉"3[j 10Ga1\=p$3o"."ppoqE^HVE^[y:-5P~ꇛw>X͠ˤ7qQ:-}8ޱ`鑧5y?_497bz{6v:aTݠ{?}l ѽ,YihFNͪL&52 8cc1 g g1*'0U)@Ռh$1pa5`Akl&`=~!?}K.2L s+)_n"_pl.*.,~9җ8du N-]^ppY*_"ZKC(z- *Y 9GD!fBjeГ#Ζ zޞ1, o1eYsO}5}tիi5L6\]LiOKW>8=d> fߙg\TSIp* G:]8G-s屡X4c7ĨR $.^5ګ6tV5+h/sq 9?0c![} XmSN񴯿Wk27Ǯ'xdӤ%H^Gy}y?OUȳNgoJ" i+zw?i(ڵ迊B0b*~1+jaw4$WOe[r_̀5jO A FI$R$SxC#QMH Mh&F{*H#,У3Y|rGB! {27Xf/:pZ}_Zwyl9pݼ'?{?/8|‰[kƼXKZ[GzUO~x5>2; "̣l^ qa kLrS*it':176UɈ7FXY9 Jr׎p[W77hŽB,I#1+Ma]6ʅe C cBob; j:x/<{%G?m6+O&ΩOl+zGl2>:lʥ{qK1i,&I bT8!Ju?d% '3 ե`k͠CɲF9WA`k.M3 -u?~28~ 3qQA\aɇx,Ο;lt՗?i4ozI?/ܸafo&f.~3>^O[?ZP􃵈ʕ9A(ڧWLL>Osmt)|JXxl¤@EAwTUqHנ֞w/on}t6n؁[ KKKK uOJRH"˴R\7^~}{{~߳v߮]89pb÷=9y=!#eaeLg$*FA&ㄵ==5t߃p"jd?G>v9G%4mDS FG5P6A F\1>= 8SQ<;œc Zdg/sdh ?-䳐HDpn f0:hFc?r[sلJZ*ZF22f *k(52SWg s]h;Gi+ږ5i6Nd7 }"^%"7p{h!7 O g|37'&T^J6wvw3Ղ vx_Ɖx&~όda+"KƎcױಸb3?Pܯ8VpIQ᪒(O*[5V\uDڤP?~WƤIҔhjhNk-ڡjV1]nnUO7o6Yl_3 J N8'[&iiYٜan7nmy,Uh8 Ă(Mf |ҽ.=ĠY2hxLP*Y3=XH_4k:7k48WVWN#ʹ)={0=yfgcc(Ձ6֡&@50E5z%QܫZh/\i(R Ħ@)%AH=̈́yh`4矃f m5Pr>5fW }AKܣ>_?~= ΔiԤF irPPߚN|h@%x/A~Jj~*65\'V%Pn3`O rj[#k6uxd4_~ /fA&kӡo9gwFɻws}4A?ʩa0O% nC5Ni ) `i xy*2*'eQXB]=].ź{:lg4O: p6qnMdevczeV̀e[_׏3zF3;~zM+}lvy]GƗ"_5v+mlLLԜH_MM=_r5l  endstream endobj 433 0 obj 10956 endobj 434 0 obj <> endobj 435 0 obj <> stream x]n0E -E`ib081Ep$:P˂,՝;M.\Qvim44姮otM_kgmLdq:?]Vl}~w[~i//S:i0?ކw:~ʋlt|>_細Uv~MyDŽ!b%QKñIM٪(j[go{\rj~yj9O-r=g,Z90 r+r9Vrmk/7#-#!8legdX[ Y9\~@&U# ;!e68l/W~^B!YP!!C8_<"{l?:DClwcK})TDQ uUz?XzUzؔQzVzBV71_u5ɯ[ 8W]^X]:My:́ӡ6n:ƣ;;)?3=v8HNO`MWjudsktIpMo`< WԿWa޼| knOwp N endstream endobj 436 0 obj <> endobj 437 0 obj <> stream x9{|չnf_y,!͋lB Ylބ@dl / K)ZH'1HV)m-Z^z-]߯If;9;|gEj4hht ! uLgX?ckz: A:6}s#]}4%D#]Nt+Cݭfy>MM=ܝ?\6٠}!=}5IR=me<:MьU"".Fo0̱q iӓ8k2?#%},[F&yFjcW).T #5Қ|JF$n|*퐚,P_hF{ѽ mZGFհ~钺ŵj*+˜%ŷ;޶`¹sgdgefIqVR 0D.;ywEfff8fss"TBFnkTxE\󭑎H͑X-@ <'^,qܸR^dx 3r#V+̐"rNlo <ѨF#HL{FqB,Ts(TdYuK\R*dfTTB%2I-2IьvPKM=U.v!94S3Rq斏@r:EZ:ՓKbQ㹡/vV;aSt_"T䲔xly=l9?4V8Aݨ$?eQeKEÒ.J)|nokS?u#P (4l5 ;P 4%`C-ȑmD15p<ض5$2) v-]kaxb1\a 倫JO;'*RAI0k2eH'74__Y`=WB;C|q@EW؂%:JpCsd w3T6Fu [z<%4M454Kvq9K,Z׋`4<$T˳FLjx p.Ut`awyvXdd_Y檮竗4 vrL[dx%HPT8eW_2E.c/\؂£ q&Ƒ-DĝJ*X:%` ^tsa("i :T%228=⽼8Q"Z)CyVniMQ Y; lfŷ+ܐ"AWcnE$yȽBZQo!Wzzy4UeřڊGykɨot=~2 S% s!䐱$ipA(-JoyсР:SqSA.PQ{ TAܠQDTT8T,NPD`tRef-xp4a  &nhtT#&?abrذ89q;P@ 4E/3 V-Fb1/&"/ YWb3`:XBHr [tK TtB H}efg1ҕ7^Q'v*ƮW#TeLi U-(qBP bаZ B:?/OfisfedHoym~aO ^\1=߫nA=*]ʃBטR}(:QB1V L|h9XG1|rjN?)Yd4suL<)>ŝ=_;JMX?%;?>%&8/S8"8A F0h%KEl;9 [ <}Rqj'.~W.g9bZc'>ŵ \{͍\<#qg^UHeTДmR`UJ2~!w"nQ)}Ta;Us‰:|>hɟ׵O#])PCT QQJV4T J:TՈ 1XgvJ;qOv'۾OU4Θ8 ѧU(%TqL6 )eRe2=G Ȃ 0b>5Wf,0)6:At|o[ю֦}ym?[ݳ򎍧.m?# n\_ GzdqDkZeB `Dd(FjĹJ⾬ljWR_y+onȊ6fMo%E2${0pM 1G<Ո*# 'd=qhvUv {>|!~NO>4 0쵺=NYa(bC1Deh<$Ab9,Am?~|}Ofi_9= {(Cf&0|GUHm2e!D{PVÜ`qNЬJcy6WVfcR|E5pHJn,N4Ê*RXq:td &Q&S=A_IKN@u*{/e:xGn\{,\sC<'޶9hV1pzOQPà;&^o*Z y2tg礄 "ʮ*4ɞ;[i^h)my 4ƍQ:qdEbe`}c$F ʄՆ2Af β?cv/Î@xGldGφ{}M=+}'41ZWf?دڶ}w=[*_Db!00; /aEےr[~]i֜E+# ! )P FtBlαc;*5* Gɜ }{HjqhW./-8CP]GJx lVA,0i 42A]^k'P[ϭV46lVyŦG}6Llk~+ƞs7OIo=E"o;ԡ|T)0[wj.PT*Hxoq{^y?wI+> *|Gߐ~+q׮ ĂoD!#EFQ& <$=}Txcj| y9HP#fz$61qmD]c;:io(r-XWU3-*7uV7Pk/5n/7/_|}4UȥO.{ڍKijփ,* \FH- *(V,$"LL]?4ۼOoGW_Rhze8\KԂlvBc*~JLݬ0)7C+$W0X||;.`{}ŋF>#}zJ(VLA/3Nν ̻i4gH5RiI|QJJd|Yy̓ r=O YǏ0]~{o|.JM|{dGU@/-AaoX]qı[HtBH@|Lfȴ,鈍SX 11q EdPY[G^PrJC:\1BG>YC,c/Jto+ϭ=xjG^{/\|gsf<&~c3KoK.nzҗ{M8;z[9B{m["HZq2J)rcJ>țtQ܅cyAqlqim;ΎAa&BC8gTx#Z;.\q;N*$Nw%CLbU@f C0VXjLZ'\^>`-Aj9sMi,gHA+ CwW-?e5~@z͡BwųoR-?׺uؼjɡISM3j7]\nؼҮfg-uF-gTx+QBPwQ866&bRዠ%9sjofN)BC'@R5/BxKsjٸcn"(ZJff_7ɹ@eV#e2CqfsAHخ',9jDogZ^l(Kiq|oJV9npT>kBT'LÔ,| GW_?xٛZ{^l_1NdcD{-{ ZH{@~0P ,{+M-} ZY?VW}ZW:I$P+tD!RKj;h|^Лl*Cz8&"^^f7ⴱbua j}ogTYq"9 ,&)cìNHAͫC BV>2Rwc@ YJ\xe}ιWF26#O{B2c{~Tf[{[o^:J= Lɿo5Iw#$?U2~v("֊_dN,B0Ogbd7/|`YEt!5ܛQ[QٔE- gBNFBF_@9x -AR`>Pm 2 JcZiZZk@p{Wh>#7Ӎ_;\GqS:-P [ t8gGTSz5!c3 BT\b-lceERZCyYVTkUTG < ]&eU֠=& xa."U]ƠL8(U`u`RBrOVџCp_pB8L_f K|ŏ`>SHM4rB08jKV8`ftDV#ԯC ҏ`5ZE6GUL]op͵vlmogܜ9wwuxޞ^+kqwwUz<^.7;'=˽}@5[#]ɡ}=Nw:{MwtoZ\1ڻVo }Vo_MH{egoܸ1nެϿuY>?0=Vxz2Y9Siˣ{۲;#k*KL ~ߎýy2uʣ|3p44*nt88vüw.ŀġzw>T)#Zn=QpYD_?@2sr~_/2+Kyˬ.?NxuFkA7nY>N-2m25[j2ly{~@wۂyF/ o%C0Y{d`lY2NN,W$(90hvq֭s'~۶BQ ׀Mr<a8> endobj 440 0 obj <> stream x]n0<= li)')^Դ@`tbCyzw[ g5z9 cYБ:i69ݝ)cvqwM-@%Rw}\gUdMz:>Oܞ)]vK~﷉J7tڎBO-Qlñ׆1Zi"p\-6k 5w•k%_d+yd6`q"r^߮_5h;o\ #s?+v3o NzrN/&/?߿ ;v3/6?;9+cH4<!<}8q> endobj 442 0 obj <> stream x{y|T9nfI&˝,D I [l$$$1&@$H E4/Uk)jJՉ,FB˫ XysNTp{kBym sPHw{_ݿ?qO,A]v޾uDuC<c$Oa9^ F9"Zmv厎'$J$99%5mBusr} /2uE%e*fWVUA?~xr{5w{Z#4z殼}C/FO);FO*Ħ4Ѕ>AA@;iL @OZ0?0vn͜JKgfL6uJy9Y23&$IhUDN9!eHAZdR$ky\&UdfHeѝerykPjæjZ`*+n kZ-c-(MC|TFfHo/RK5=GMj zTQj`Me@#6JCf6!iTp;'jL(2LLkJ=^o 3cv0J.UP:d/ R%m3sDDZ'A 2e[։t4hXyG0C.- NVՏSueJRDYr/O_]Ҧ)7&$뛽)^R``E$ʃ&`o6#n N<%-*h[$)Rg"{kkS}{ Fhdy -4J@dj`s`b 0D@nP7OzT T\54W͓7_ñ)e #7{XL;([=ޠAOK"`FEOB! ʳy֠{6xѹl W5gf,u~|E noh~`RZNRZH3Б!S{ڨֲj_I蓙3EryP_fl,c hUF0Qe, 0&Ctv $^"""yӶR }q̅/.}kEׯZr=[q )_{tzB<""$-HE&G)/EP`SjF[!%AGM"y;0O=w2Vߴ?†{ްs)^kn$O>mjR>hl[rxޥW`Z; @V9os*z) |w.\ߎK>{+;"*+mgE8eFq"L061 P[t;Vj j쵻v/&\z.Rؖ+Z hYrQJlޱ-tpPXk-,*3\7sՎa{Ui<땏 l ̶j駼 8LQiA'!AaFg kɾ\'3shh޼!m00-S Bx y}a1̌xhO`:)7قueDygoJx6QĵYhƼ~6 L'h"KE-=BV3ˊ:1:ھ[ 蕭>[t^|-yFr8~r> ;u~,n3!.IDYtz(=eX:W<̙*AxY}:>EyRU.e%*w+v?kGğQ(1 1 "x EєpIi+;_ <I q?+ }d $pӥL+RTraٹmwø)=`a6=E@m~:xLgjjͬ\=ʙ)*=nK̓7c6'th?}:mtAbe̲ű]vX3x.fdSv?GVkl˶}sL*Zzz~5);偲]CT(qF5k+^A\ ]@ 6CM&?q543y%@SB<<$!mPA y=q {WܵfŦSj*^^X޾c'@SÞ[P4P?Cp8X66hLcc-NcL"63hAņ{w7^B'8UMyG˸Ǭ_mrBCGoyՍ܁ÛZ r鯙0;tDټ@XkTiG`E(*bq5- P\t-hgk-!}-ʫlN_CD|U~%2FcTdqUx@w#P݀ThŗJu&iaro{ƹ_L5w.[lXρs۱ oO?o4?߃@&V]-To9ƟcjkeFŜG^9'9;j9JSD lT2:1P :FW2԰9gCWVL7I`Sm&$%EG't)*`2q<I"X~em֫ j3!MЇfTݜG7෗^xv>nr}nV5_}uovJMxmi]Gدo^dX)I*㷨GMvzz.TO1:ŲXEuCu9E6Cp 3W ;k+ ])Ԑw<(dzꂙukln]dIp b5%3ÈF!A0,e&t2FAMu M5z^K=,IjϰB)O'|Hٙ>*q.VACW (3 H4b09Q:̐ 3:3SiGy1jWaXX:ZpnefY!%t;ZGh-Ҽ UQ?vV .g Fc]oB9&"2d|G%Fk"qZRJT"70L;w<t탸*[qeWy\Z:xM $GSUjL.QKbؘ$=(Xے2l¬M4Apj~=URQKܚHc +-geLy0Q4s|e(eʓ{,B>aǷӗ5P h?a:#.IQÐdl8Żi!Q䏉umGb{kC9^wejo奀'xQy?qD XMӋh'5E%Xv`'5]bNOE'u܁KZo|F=@,=^?ZshiyPj2!g 8Ǹ:dExrՂcCpCCCtx DWOVT"+Ї#ePR"kf3QFX|c2à+[8vm>86Jw~a$OVr}܇RnL##ð083$_;2 &4F~|L;?<3@Sq7AQDE.wڈFBMŔ/掋 i,-(h*2fdeޮCx>{r1镭zeP3HlJ?g#v\C@K<*'(:0DјgLł *EV~eRI8ZƧv+5|(m8w9.~]nuFCYàt3B>Sx]~ࣺ+*ngP?E^aNHwxkJлnя?;rڥ): Ҭ.$Sq+_%7Z,WURܒ:7v~܌9Kf <#;8}za# |7RdN'^o PgfXQG8=YջG:Ƒ\|O) OyF#$*4qtb=^Q*Ha L A9ʝh?A1mka.Q0"Feh zW#R+Q.:!V.(=t5 kfN:fڝNϙVZ@~l :؈> u\藜V^UZxW4|L/1Ǽce8@hdX00{U1ЏՍ,+l p NσfeVtax fNg0Xꢢd@Ejҥ<;BJ,q<,u,z\fc54hpѰTH8G%=:/Ŕ;?U"*: n!1*eLe4>X:ρo 㽤 Xz<ƆJc̗r٦ݱsiob!J&<bt((nqF6Ź؆x o`ö'VnVʣ~oo-c_l[r &-x^V38Q;{Ed4m&SR![J%6`8g܀3f8T*aN/yq Pτ\0+pώ͋_ _f".^eҍ{-r}KmY|5Q^ TW1ꭰM&YRm@+vn%0Z~<*ɹ1 Vs=RTrڈTSvZҰWLSv=lt?o m] LR4E]p.xW-RNn^_K{KT]cJX@I~s5O6ʵF/Dy-{zDJpY;zL3maêΰl8I_/R.0g@p1R ȶ/~m{kiB1IhO G:El^oz sюa}qSދֻjZ,]>r4eߘWc@Ez0f߉c%nη|KD"vpf9Udz0XĬ9$r 0%\xe7^&Y<8ee7H[cݑ!(VtC{=k7a.aϡ\1ͬEYh!s-[|;cMVF#l<nd 8`gA5\+xxDuvh.jXz6P!hTtaw;Q }@`=(mϣݔ^v=d'N*jJ3iigjPd+vWS !^ԣ"dXϼkB;PXE]2Z~>ƩHYG@ 2WQ!s?gsQ/<"|ݦH./n0shΧD YMm=h%ysR+Q?{fu{{iMiJQؾI_]uoʟumnCˡܵhS$"KTRg[P)`}jvx/g?ݼ)ٲ@$b$5 -`:T/aORTPW^qvS3a6h]݇"Z ٪% R 1Mv%ΝӞXSݞ:YlL%7Gv49 ոܜh9;-LU寕PȾ8s6ZQYl >؃nAOw7̛8jD kyo 1+evT_̝UvH.T觿OtZ endstream endobj 443 0 obj 9922 endobj 444 0 obj <> endobj 445 0 obj <> stream x]͎@<aLZ,yC~oAaI*v448ox>&xpi5=os$[rOo2I}ywGmsd_6N]M~Nc[4O6zRbYvy͏%_c(X7qkLyIׇ&}߻d%XBfNuy7hЁV/=xHz$6p=<@zCA4> endobj 447 0 obj <> stream x8{tSe޼67}-z%EHWh 4MH$m"mS SG0Ygp<܂aT|a1{gYEgpwǮ(Rԙ;wrѭQ0FW-WH~]QĀ=?20Jf/wXt/acP'9(_C3zD|~l(u9-?x`".vs:+B7'A_8?>wC@Î$~1PJ#ё⃯!~ƈz@PaUjV7sL9?]B(#oUQE`.BV?s&1Q?̱/ ]v9--a=8ɬs=]k;׬^ookmy<+ݍ+Z~岥Kj*W,(J ͜)/7Ǡi5j%J7BW:+xoIY|ATBkLBrf%!J% /ԅK'~ Yy aU"bJcioc$9&)jpV!+qr "e r[Hkf&:+ڤ]-y. 'ϱ?XsآY>c>dSqA 5¼uW-c4ba-y|}O8{R;s\w\V.q4/n޵_ozXp4IB%]`2s Bh6ETO.kV w^PDC[P 42.Mkc1YJ