www

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | Submodules | README | LICENSE

commit 4e5d4281f1b197dcdf1368e6d879735f861243b4
parent bf53fe8825328d6ec05bfcce1e155740306a21d8
Author: Simon Kornblith <simon@simonster.com>
Date:   Sat, 26 May 2012 18:24:52 -0400

Merge branch '3.0'

Diffstat:
Mchrome/content/zotero/about.xul | 3++-
Mchrome/content/zotero/preferences/preferences.js | 2+-
Mchrome/content/zotero/preferences/preferences.xul | 1+
Mchrome/content/zotero/standalone/standalone.js | 2+-
Mchrome/content/zotero/xpcom/citeproc.js | 29++++++++++++++++-------------
Mchrome/content/zotero/xpcom/connector/typeSchemaData.js | 4++--
Mchrome/content/zotero/xpcom/data/cachedTypes.js | 11++++++++++-
Mchrome/content/zotero/xpcom/integration.js | 2+-
Dchrome/content/zotero/xpcom/rdf.js | 6------
Mchrome/content/zotero/xpcom/rdf/identity.js | 805+++++++++++++++++++++++++++++++++++--------------------------------------------
Achrome/content/zotero/xpcom/rdf/init.js | 33+++++++++++++++++++++++++++++++++
Mchrome/content/zotero/xpcom/rdf/match.js | 241++++++++++++++++++++++++++++++++++---------------------------------------------
Mchrome/content/zotero/xpcom/rdf/n3parser.js | 2152+++++++++++++++++++++++++++++++++++++++----------------------------------------
Mchrome/content/zotero/xpcom/rdf/rdfparser.js | 978++++++++++++++++++++++++++++++++++++++++---------------------------------------
Mchrome/content/zotero/xpcom/rdf/serialize.js | 1307++++++++++++++++++++++++++++++++++++++++++++-----------------------------------
Mchrome/content/zotero/xpcom/rdf/term.js | 492++++++++++++++++++++++++++++++++++++++++++-------------------------------------
Mchrome/content/zotero/xpcom/rdf/uri.js | 227+++++++++++++++++++++++++++++++++++++++++--------------------------------------
Mchrome/content/zotero/xpcom/sync.js | 4++++
Mchrome/content/zotero/xpcom/translation/translate.js | 75++++++++++++++++++++++++++++++++++++---------------------------------------
Mchrome/content/zotero/xpcom/translation/translate_firefox.js | 4++--
Mchrome/content/zotero/xpcom/translation/translate_item.js | 17++---------------
Mchrome/locale/af-ZA/zotero/zotero.dtd | 4++++
Mchrome/locale/af-ZA/zotero/zotero.properties | 10+++++++++-
Mchrome/locale/ar/zotero/zotero.dtd | 4++++
Mchrome/locale/ar/zotero/zotero.properties | 8++++++++
Mchrome/locale/bg-BG/zotero/zotero.dtd | 4++++
Mchrome/locale/bg-BG/zotero/zotero.properties | 10+++++++++-
Mchrome/locale/ca-AD/zotero/zotero.dtd | 4++++
Mchrome/locale/ca-AD/zotero/zotero.properties | 8++++++++
Mchrome/locale/cs-CZ/zotero/zotero.dtd | 4++++
Mchrome/locale/cs-CZ/zotero/zotero.properties | 10+++++++++-
Mchrome/locale/da-DK/zotero/zotero.dtd | 4++++
Mchrome/locale/da-DK/zotero/zotero.properties | 8++++++++
Mchrome/locale/de/zotero/zotero.dtd | 4++++
Mchrome/locale/de/zotero/zotero.properties | 8++++++++
Mchrome/locale/el-GR/zotero/zotero.dtd | 4++++
Mchrome/locale/el-GR/zotero/zotero.properties | 10+++++++++-
Mchrome/locale/es-ES/zotero/zotero.dtd | 4++++
Mchrome/locale/es-ES/zotero/zotero.properties | 10+++++++++-
Mchrome/locale/et-EE/zotero/zotero.dtd | 4++++
Mchrome/locale/et-EE/zotero/zotero.properties | 8++++++++
Mchrome/locale/eu-ES/zotero/zotero.dtd | 4++++
Mchrome/locale/eu-ES/zotero/zotero.properties | 10+++++++++-
Mchrome/locale/fa/zotero/zotero.dtd | 4++++
Mchrome/locale/fa/zotero/zotero.properties | 8++++++++
Mchrome/locale/fi-FI/zotero/zotero.dtd | 4++++
Mchrome/locale/fi-FI/zotero/zotero.properties | 8++++++++
Mchrome/locale/fr-FR/zotero/zotero.dtd | 4++++
Mchrome/locale/fr-FR/zotero/zotero.properties | 8++++++++
Mchrome/locale/gl-ES/zotero/zotero.dtd | 4++++
Mchrome/locale/gl-ES/zotero/zotero.properties | 10+++++++++-
Mchrome/locale/he-IL/zotero/zotero.dtd | 4++++
Mchrome/locale/he-IL/zotero/zotero.properties | 10+++++++++-
Mchrome/locale/hr-HR/zotero/zotero.dtd | 4++++
Mchrome/locale/hr-HR/zotero/zotero.properties | 10+++++++++-
Mchrome/locale/hu-HU/zotero/zotero.dtd | 4++++
Mchrome/locale/hu-HU/zotero/zotero.properties | 10+++++++++-
Mchrome/locale/is-IS/zotero/zotero.dtd | 4++++
Mchrome/locale/is-IS/zotero/zotero.properties | 10+++++++++-
Mchrome/locale/it-IT/zotero/zotero.dtd | 4++++
Mchrome/locale/it-IT/zotero/zotero.properties | 8++++++++
Mchrome/locale/ja-JP/zotero/zotero.dtd | 4++++
Mchrome/locale/ja-JP/zotero/zotero.properties | 8++++++++
Mchrome/locale/km/zotero/zotero.dtd | 4++++
Mchrome/locale/km/zotero/zotero.properties | 8++++++++
Mchrome/locale/ko-KR/zotero/zotero.dtd | 4++++
Mchrome/locale/ko-KR/zotero/zotero.properties | 10+++++++++-
Mchrome/locale/mn-MN/zotero/zotero.dtd | 4++++
Mchrome/locale/mn-MN/zotero/zotero.properties | 10+++++++++-
Mchrome/locale/nb-NO/zotero/zotero.dtd | 4++++
Mchrome/locale/nb-NO/zotero/zotero.properties | 10+++++++++-
Mchrome/locale/nl-NL/zotero/zotero.dtd | 4++++
Mchrome/locale/nl-NL/zotero/zotero.properties | 8++++++++
Mchrome/locale/nn-NO/zotero/zotero.dtd | 4++++
Mchrome/locale/nn-NO/zotero/zotero.properties | 8++++++++
Mchrome/locale/pl-PL/zotero/zotero.dtd | 4++++
Mchrome/locale/pl-PL/zotero/zotero.properties | 8++++++++
Mchrome/locale/pt-BR/zotero/zotero.dtd | 4++++
Mchrome/locale/pt-BR/zotero/zotero.properties | 8++++++++
Mchrome/locale/pt-PT/zotero/zotero.dtd | 4++++
Mchrome/locale/pt-PT/zotero/zotero.properties | 8++++++++
Mchrome/locale/ro-RO/zotero/zotero.dtd | 4++++
Mchrome/locale/ro-RO/zotero/zotero.properties | 8++++++++
Mchrome/locale/ru-RU/zotero/zotero.dtd | 4++++
Mchrome/locale/ru-RU/zotero/zotero.properties | 8++++++++
Mchrome/locale/sk-SK/zotero/zotero.dtd | 4++++
Mchrome/locale/sk-SK/zotero/zotero.properties | 8++++++++
Mchrome/locale/sl-SI/zotero/zotero.dtd | 4++++
Mchrome/locale/sl-SI/zotero/zotero.properties | 10+++++++++-
Mchrome/locale/sr-RS/zotero/zotero.dtd | 4++++
Mchrome/locale/sr-RS/zotero/zotero.properties | 10+++++++++-
Mchrome/locale/sv-SE/zotero/zotero.dtd | 4++++
Mchrome/locale/sv-SE/zotero/zotero.properties | 8++++++++
Mchrome/locale/th-TH/zotero/zotero.dtd | 4++++
Mchrome/locale/th-TH/zotero/zotero.properties | 8++++++++
Mchrome/locale/tr-TR/zotero/zotero.dtd | 4++++
Mchrome/locale/tr-TR/zotero/zotero.properties | 8++++++++
Mchrome/locale/vi-VN/zotero/zotero.dtd | 4++++
Mchrome/locale/vi-VN/zotero/zotero.properties | 10+++++++++-
Mchrome/locale/zh-CN/zotero/zotero.dtd | 4++++
Mchrome/locale/zh-CN/zotero/zotero.properties | 10+++++++++-
Mchrome/locale/zh-TW/zotero/zotero.dtd | 4++++
Mchrome/locale/zh-TW/zotero/zotero.properties | 8++++++++
Mchrome/skin/default/zotero/treeitem-audioRecording.png | 0
Cchrome/skin/default/zotero/treeitem-manuscript.png -> chrome/skin/default/zotero/treeitem-bill.png | 0
Mchrome/skin/default/zotero/treeitem-blogPost.png | 0
Achrome/skin/default/zotero/treeitem-case.png | 0
Achrome/skin/default/zotero/treeitem-dictionaryEntry.png | 0
Achrome/skin/default/zotero/treeitem-document.png | 0
Mchrome/skin/default/zotero/treeitem-email.png | 0
Achrome/skin/default/zotero/treeitem-encyclopediaArticle.png | 0
Mchrome/skin/default/zotero/treeitem-forumPost.png | 0
Achrome/skin/default/zotero/treeitem-hearing.png | 0
Achrome/skin/default/zotero/treeitem-instantMessage.png | 0
Mchrome/skin/default/zotero/treeitem-magazineArticle.png | 0
Mchrome/skin/default/zotero/treeitem-manuscript.png | 0
Achrome/skin/default/zotero/treeitem-patent.png | 0
Mchrome/skin/default/zotero/treeitem-podcast.png | 0
Achrome/skin/default/zotero/treeitem-presentation.png | 0
Achrome/skin/default/zotero/treeitem-statute.png | 0
Mchrome/skin/default/zotero/treeitem-thesis.png | 0
Mchrome/skin/default/zotero/treeitem-videoRecording.png | 0
Mchrome/skin/default/zotero/treeitem-webpage.png | 0
Mcomponents/zotero-autocomplete.js | 7++++++-
Mcomponents/zotero-service.js | 8++++----
Mresource/schema/repotime.txt | 2+-
126 files changed, 3739 insertions(+), 3201 deletions(-)

diff --git a/chrome/content/zotero/about.xul b/chrome/content/zotero/about.xul @@ -278,7 +278,8 @@ </vbox> <label class="subhead" value="&zotero.about.additionalSoftware;"/> <vbox class="subcontent"> - <label class="zotero-text-link" href="http://www.famfamfam.com/lab/icons/silk/" value="famfamfam (small icons)"/> + <label class="zotero-text-link" href="http://www.famfamfam.com/lab/icons/silk/" value="Silk icons (by Mark James)"/> + <label class="zotero-text-link" href="http://p.yusukekamiyamane.com/" value="Fugue icons (by Yusuke Kamiyamane)"/> <label class="zotero-text-link" href="http://simile.mit.edu/timeline/" value="SIMILE Project (Timeline)"/> <label class="zotero-text-link" href="http://www.w3.org/2005/ajar/tab" value="Tabulator (RDF parser)"/> <label class="zotero-text-link" href="http://tango.freedesktop.org/Tango_Desktop_Project" value="Tango Desktop Project (pref icons)"/> diff --git a/chrome/content/zotero/preferences/preferences.js b/chrome/content/zotero/preferences/preferences.js @@ -1936,7 +1936,7 @@ function openInViewer(uri, newTab) { win.loadURI(uri); } else { window.openDialog("chrome://zotero/content/standalone/basicViewer.xul", - "basicViewer", "chrome,resizable,centerscreen", uri); + "basicViewer", "chrome,resizable,centerscreen,menubar,scrollbars", uri); } } else { var win = wm.getMostRecentWindow("navigator:browser"); diff --git a/chrome/content/zotero/preferences/preferences.xul b/chrome/content/zotero/preferences/preferences.xul @@ -339,6 +339,7 @@ To add a new preference: <separator class="thin"/> <vbox> + <label class="zotero-text-link" style="margin-top:.3em; margin-left: 0" value="&zotero.preferences.sync.fileSyncing.about;" href="http://www.zotero.org/support/sync#file_syncing"/> <hbox id="storage-terms" style="margin-top: .4em" align="center"> <label>&zotero.preferences.sync.fileSyncing.tos1;</label> <label class="zotero-text-link" href="http://www.digitalscholar.org/z_terms" value="&zotero.preferences.sync.fileSyncing.tos2;"/> diff --git a/chrome/content/zotero/standalone/standalone.js b/chrome/content/zotero/standalone/standalone.js @@ -128,7 +128,7 @@ const ZoteroStandalone = new function() { win.loadURI(uri); } else { window.openDialog("chrome://zotero/content/standalone/basicViewer.xul", - "basicViewer", "chrome,resizable,centerscreen", uri); + "basicViewer", "chrome,resizable,centerscreen,menubar,scrollbars", uri); } } diff --git a/chrome/content/zotero/xpcom/citeproc.js b/chrome/content/zotero/xpcom/citeproc.js @@ -2189,7 +2189,7 @@ CSL.DateParser = function () { }; CSL.Engine = function (sys, style, lang, forceLang) { var attrs, langspec, localexml, locale; - this.processor_version = "1.0.328"; + this.processor_version = "1.0.329"; this.csl_version = "1.0"; this.sys = sys; this.sys.xml = new CSL.System.Xml.Parsing(); @@ -2620,7 +2620,6 @@ CSL.Engine.prototype.remapSectionVariable = function (inputList) { var value = false; if (["bill","gazette","legislation"].indexOf(Item.type) > -1) { if (!Item.section - && !Item.page && this.opt.development_extensions.clobber_locator_if_no_statute_section) { item.locator = undefined; item.label = undefined; @@ -6025,16 +6024,18 @@ CSL.NameOutput.prototype._clearValues = function (values) { } }; CSL.NameOutput.prototype._checkNickname = function (name) { - var author = ""; - author = CSL.Util.Names.getRawName(name); - if (author && this.state.sys.getAbbreviation && !(this.item && this.item["suppress-author"])) { - this.state.transform.loadAbbreviation("default", "nickname", author); - var myLocalName = this.state.transform.abbrevs["default"].nickname[author]; - if (myLocalName) { - if (myLocalName === "{suppress}") { - name = false; - } else { - name = {family:myLocalName,given:''}; + if (["interview", "personal_communication"].indexOf(this.Item.type) > -1) { + var author = ""; + author = CSL.Util.Names.getRawName(name); + if (author && this.state.sys.getAbbreviation && !(this.item && this.item["suppress-author"])) { + this.state.transform.loadAbbreviation("default", "nickname", author); + var myLocalName = this.state.transform.abbrevs["default"].nickname[author]; + if (myLocalName) { + if (myLocalName === "{suppress}") { + name = false; + } else { + name = {family:myLocalName,given:''}; + } } } } @@ -12473,7 +12474,9 @@ CSL.Disambiguation.prototype.getCiteData = function(Item, base) { } }; CSL.Disambiguation.prototype.captureStepToBase = function() { - this.betterbase.givens[this.gnameset][this.gname] = this.base.givens[this.gnameset][this.gname]; + if (this.state.opt["givenname-disambiguation-rule"] === "by-cite") { + this.betterbase.givens[this.gnameset][this.gname] = this.base.givens[this.gnameset][this.gname]; + } this.betterbase.names[this.gnameset] = this.base.names[this.gnameset]; }; CSL.Registry.CitationReg = function (state) { diff --git a/chrome/content/zotero/xpcom/connector/typeSchemaData.js b/chrome/content/zotero/xpcom/connector/typeSchemaData.js @@ -1 +1 @@ -Zotero.Connector_Types.schema = {"itemTypes":{"1":["note","Note",[false],[],{},"treeitem-note.png"],"2":["book","Book",[1,2,3,5,4],[110,90,3,30,4,45,6,7,8,14,118,87,11,116,1,27,123,19,62,18,2,22],{},"treeitem-book.png"],"3":["bookSection","Book Section",[1,29,2,3,5,4],[110,90,115,3,30,4,45,6,7,8,14,10,87,11,116,1,27,123,19,62,18,2,22],{"115":12},"treeitem-bookSection.png"],"4":["journalArticle","Journal Article",[1,2,3,27,4],[110,90,12,4,5,10,14,3,28,29,25,87,26,13,116,1,27,123,19,62,18,2,22],{},"treeitem-journalArticle.png"],"5":["magazineArticle","Magazine Article",[1,2,27,4],[110,90,12,4,5,14,10,87,13,116,1,27,123,19,62,18,2,22],{},"treeitem-magazineArticle.png"],"6":["newspaperArticle","Newspaper Article",[1,2,27,4],[110,90,12,7,6,14,15,10,87,116,13,1,27,123,19,62,18,2,22],{},"treeitem-newspaperArticle.png"],"7":["thesis","Thesis",[1,2],[110,90,69,89,7,14,118,87,116,1,27,123,19,62,18,2,22],{"69":108,"89":8},"treeitem-thesis.png"],"8":["letter","Letter",[1,2,16],[110,90,65,14,87,116,1,27,123,19,62,18,2,22],{"65":108},"treeitem-letter.png"],"9":["manuscript","Manuscript",[1,2,4],[110,90,66,7,14,118,87,116,1,27,123,19,62,18,2,22],{"66":108},"treeitem-manuscript.png"],"10":["interview","Interview",[6,2,7,4],[110,90,14,64,87,116,1,27,123,19,62,18,2,22],{"64":109},"treeitem-interview.png"],"11":["film","Film",[8,2,10,9],[110,90,21,14,122,63,77,87,116,1,27,123,19,62,18,2,22],{"21":8,"122":108,"63":109},"treeitem-film.png"],"12":["artwork","Artwork",[22,2],[110,90,59,61,14,87,116,123,19,62,18,1,27,2,22],{"59":109},"treeitem-artwork.png"],"13":["webpage","Web Page",[1,2,4],[110,90,91,70,14,116,1,27,87,2,22],{"91":12,"70":108},"treeitem-webpage.png"],"14":["attachment","Attachment",[false],[110,27,1],{},"treeitem.png"],"15":["report","Report",[1,2,5,4],[110,90,92,32,28,7,31,14,10,87,116,1,27,123,19,62,18,2,22],{"92":60,"32":108,"31":8},"treeitem-report.png"],"16":["bill","Bill",[12,2,28],[110,90,93,36,94,15,95,41,40,42,14,87,1,27,116,2,22],{"93":60,"94":4,"95":10},"treeitem.png"],"17":["case","Case",[1,2,13],[111,90,43,97,44,117,98,42,96,87,116,1,27,2,22],{"111":110,"97":4,"117":60,"98":10,"96":14},"treeitem.png"],"18":["hearing","Hearing",[2],[110,90,46,7,8,45,99,10,41,40,42,14,87,116,1,27,2,22],{"99":60},"treeitem.png"],"19":["patent","Patent",[14,15,2],[110,90,7,102,48,120,50,121,10,103,51,52,53,54,87,116,1,27,2,22],{"50":60,"52":14},"treeitem.png"],"20":["statute","Statute",[1,2],[112,90,36,55,101,100,10,15,40,42,87,116,1,27,2,22],{"112":110,"101":60,"100":14},"treeitem.png"],"21":["email","E-mail",[1,2,16],[113,90,14,116,1,27,87,2,22],{"113":110},"treeitem-email.png"],"22":["map","Map",[20,2,5],[110,90,67,68,28,6,7,8,14,87,11,116,1,27,123,19,62,18,2,22],{"67":108},"treeitem-map.png"],"23":["blogPost","Blog Post",[1,23,2],[110,90,107,70,14,1,27,87,116,2,22],{"107":12,"70":108},"treeitem-blogPost.png"],"24":["instantMessage","Instant Message",[1,2,16],[110,90,14,87,116,1,27,2,22],{},"treeitem.png"],"25":["forumPost","Forum Post",[1,2],[110,90,104,79,14,87,116,1,27,2,22],{"104":12,"79":108},"treeitem-forumPost.png"],"26":["audioRecording","Audio Recording",[17,18,2,19],[110,90,71,28,4,45,7,72,14,77,87,11,116,123,19,62,18,1,27,2,22],{"71":109,"72":8},"treeitem-audioRecording.png"],"27":["presentation","Presentation",[24,2],[110,90,74,14,7,75,1,27,87,116,2,22],{"74":108},"treeitem.png"],"28":["videoRecording","Video Recording",[8,11,2,10,9],[110,90,63,28,4,45,7,76,14,77,87,11,116,1,27,123,19,62,18,2,22],{"63":109,"76":8},"treeitem-videoRecording.png"],"29":["tvBroadcast","TV Broadcast",[8,11,2,25,10,9],[110,90,119,105,63,7,78,14,77,87,116,1,27,123,19,62,18,2,22],{"119":12,"105":60,"63":109,"78":8},"treeitem-tvBroadcast.png"],"30":["radioBroadcast","Radio Broadcast",[8,11,2,25,10,9],[110,90,119,105,71,7,78,14,77,87,116,1,27,123,19,62,18,2,22],{"119":12,"105":60,"71":109,"78":8},"treeitem-radioBroadcast.png"],"31":["podcast","Podcast",[26,2,25],[110,90,28,105,80,77,1,27,87,116,2,22],{"105":60,"80":109},"treeitem-podcast.png"],"32":["computerProgram","Computer Program",[21,2],[110,90,28,81,14,82,7,83,88,11,116,1,2,123,19,62,18,27,22],{"83":8},"treeitem-computerProgram.png"],"33":["conferencePaper","Conference Paper",[1,2,3,5,4],[110,90,14,114,84,7,8,4,10,3,87,26,11,116,1,27,123,19,62,18,2,22],{"114":12},"treeitem-conferencePaper.png"],"34":["document","Document",[1,2,3,27,4],[110,90,8,14,87,116,1,27,123,19,62,18,2,22],{},"treeitem.png"],"35":["encyclopediaArticle","Encyclopedia Article",[1,2,3,5,4],[110,90,85,3,30,4,45,6,7,8,14,10,11,116,1,27,87,123,19,62,18,2,22],{"85":12},"treeitem.png"],"36":["dictionaryEntry","Dictionary Entry",[1,2,3,5,4],[110,90,86,3,30,4,45,6,7,8,14,10,87,11,116,1,27,123,19,62,18,2,22],{"86":12},"treeitem.png"]},"creatorTypes":{"1":["author","Author"],"2":["contributor","Contributor"],"3":["editor","Editor"],"4":["translator","Translator"],"5":["seriesEditor","Series Editor"],"6":["interviewee","Interview With"],"7":["interviewer","Interviewer"],"8":["director","Director"],"9":["scriptwriter","Scriptwriter"],"10":["producer","Producer"],"11":["castMember","Cast Member"],"12":["sponsor","Sponsor"],"13":["counsel","Counsel"],"14":["inventor","Inventor"],"15":["attorneyAgent","Attorney/Agent"],"16":["recipient","Recipient"],"17":["performer","Performer"],"18":["composer","Composer"],"19":["wordsBy","Words By"],"20":["cartographer","Cartographer"],"21":["programmer","Programmer"],"22":["artist","Artist"],"23":["commenter","Commenter"],"24":["presenter","Presenter"],"25":["guest","Guest"],"26":["podcaster","Podcaster"],"27":["reviewedAuthor","Reviewed Author"],"28":["cosponsor","Cosponsor"],"29":["bookAuthor","Book Author"]},"fields":{"1":["url"],"2":["rights"],"3":["series"],"4":["volume"],"5":["issue"],"6":["edition"],"7":["place"],"8":["publisher"],"10":["pages"],"11":["ISBN"],"12":["publicationTitle"],"13":["ISSN"],"14":["date"],"15":["section"],"18":["callNumber"],"19":["archiveLocation"],"21":["distributor"],"22":["extra"],"25":["journalAbbreviation"],"26":["DOI"],"27":["accessDate"],"28":["seriesTitle"],"29":["seriesText"],"30":["seriesNumber"],"31":["institution"],"32":["reportType"],"36":["code"],"40":["session"],"41":["legislativeBody"],"42":["history"],"43":["reporter"],"44":["court"],"45":["numberOfVolumes"],"46":["committee"],"48":["assignee"],"50":["patentNumber"],"51":["priorityNumbers"],"52":["issueDate"],"53":["references"],"54":["legalStatus"],"55":["codeNumber"],"59":["artworkMedium"],"60":["number"],"61":["artworkSize"],"62":["libraryCatalog"],"63":["videoRecordingFormat"],"64":["interviewMedium"],"65":["letterType"],"66":["manuscriptType"],"67":["mapType"],"68":["scale"],"69":["thesisType"],"70":["websiteType"],"71":["audioRecordingFormat"],"72":["label"],"74":["presentationType"],"75":["meetingName"],"76":["studio"],"77":["runningTime"],"78":["network"],"79":["postType"],"80":["audioFileType"],"81":["version"],"82":["system"],"83":["company"],"84":["conferenceName"],"85":["encyclopediaTitle"],"86":["dictionaryTitle"],"87":["language"],"88":["programmingLanguage"],"89":["university"],"90":["abstractNote"],"91":["websiteTitle"],"92":["reportNumber"],"93":["billNumber"],"94":["codeVolume"],"95":["codePages"],"96":["dateDecided"],"97":["reporterVolume"],"98":["firstPage"],"99":["documentNumber"],"100":["dateEnacted"],"101":["publicLawNumber"],"102":["country"],"103":["applicationNumber"],"104":["forumTitle"],"105":["episodeNumber"],"107":["blogTitle"],"108":["type"],"109":["medium"],"110":["title"],"111":["caseName"],"112":["nameOfAct"],"113":["subject"],"114":["proceedingsTitle"],"115":["bookTitle"],"116":["shortTitle"],"117":["docketNumber"],"118":["numPages"],"119":["programTitle"],"120":["issuingAuthority"],"121":["filingDate"],"122":["genre"],"123":["archive"]}} -\ No newline at end of file +Zotero.Connector_Types.schema = {"itemTypes":{"1":["note","Note",[false],[],{},"treeitem-note.png"],"2":["book","Book",[1,2,3,5,4],[110,90,3,30,4,45,6,7,8,14,118,87,11,116,1,27,123,19,62,18,2,22],{},"treeitem-book.png"],"3":["bookSection","Book Section",[1,29,2,3,5,4],[110,90,115,3,30,4,45,6,7,8,14,10,87,11,116,1,27,123,19,62,18,2,22],{"115":12},"treeitem-bookSection.png"],"4":["journalArticle","Journal Article",[1,2,3,27,4],[110,90,12,4,5,10,14,3,28,29,25,87,26,13,116,1,27,123,19,62,18,2,22],{},"treeitem-journalArticle.png"],"5":["magazineArticle","Magazine Article",[1,2,27,4],[110,90,12,4,5,14,10,87,13,116,1,27,123,19,62,18,2,22],{},"treeitem-magazineArticle.png"],"6":["newspaperArticle","Newspaper Article",[1,2,27,4],[110,90,12,7,6,14,15,10,87,116,13,1,27,123,19,62,18,2,22],{},"treeitem-newspaperArticle.png"],"7":["thesis","Thesis",[1,2],[110,90,69,89,7,14,118,87,116,1,27,123,19,62,18,2,22],{"69":108,"89":8},"treeitem-thesis.png"],"8":["letter","Letter",[1,2,16],[110,90,65,14,87,116,1,27,123,19,62,18,2,22],{"65":108},"treeitem-letter.png"],"9":["manuscript","Manuscript",[1,2,4],[110,90,66,7,14,118,87,116,1,27,123,19,62,18,2,22],{"66":108},"treeitem-manuscript.png"],"10":["interview","Interview",[6,2,7,4],[110,90,14,64,87,116,1,27,123,19,62,18,2,22],{"64":109},"treeitem-interview.png"],"11":["film","Film",[8,2,10,9],[110,90,21,14,122,63,77,87,116,1,27,123,19,62,18,2,22],{"21":8,"122":108,"63":109},"treeitem-film.png"],"12":["artwork","Artwork",[22,2],[110,90,59,61,14,87,116,123,19,62,18,1,27,2,22],{"59":109},"treeitem-artwork.png"],"13":["webpage","Web Page",[1,2,4],[110,90,91,70,14,116,1,27,87,2,22],{"91":12,"70":108},"treeitem-webpage.png"],"14":["attachment","Attachment",[false],[110,27,1],{},"treeitem.png"],"15":["report","Report",[1,2,5,4],[110,90,92,32,28,7,31,14,10,87,116,1,27,123,19,62,18,2,22],{"92":60,"32":108,"31":8},"treeitem-report.png"],"16":["bill","Bill",[12,2,28],[110,90,93,36,94,15,95,41,40,42,14,87,1,27,116,2,22],{"93":60,"94":4,"95":10},"treeitem-bill.png"],"17":["case","Case",[1,2,13],[111,90,43,97,44,117,98,42,96,87,116,1,27,2,22],{"111":110,"97":4,"117":60,"98":10,"96":14},"treeitem-case.png"],"18":["hearing","Hearing",[2],[110,90,46,7,8,45,99,10,41,40,42,14,87,116,1,27,2,22],{"99":60},"treeitem-hearing.png"],"19":["patent","Patent",[14,15,2],[110,90,7,102,48,120,50,121,10,103,51,52,53,54,87,116,1,27,2,22],{"50":60,"52":14},"treeitem-patent.png"],"20":["statute","Statute",[1,2],[112,90,36,55,101,100,10,15,40,42,87,116,1,27,2,22],{"112":110,"101":60,"100":14},"treeitem-statute.png"],"21":["email","E-mail",[1,2,16],[113,90,14,116,1,27,87,2,22],{"113":110},"treeitem-email.png"],"22":["map","Map",[20,2,5],[110,90,67,68,28,6,7,8,14,87,11,116,1,27,123,19,62,18,2,22],{"67":108},"treeitem-map.png"],"23":["blogPost","Blog Post",[1,23,2],[110,90,107,70,14,1,27,87,116,2,22],{"107":12,"70":108},"treeitem-blogPost.png"],"24":["instantMessage","Instant Message",[1,2,16],[110,90,14,87,116,1,27,2,22],{},"treeitem-instantMessage.png"],"25":["forumPost","Forum Post",[1,2],[110,90,104,79,14,87,116,1,27,2,22],{"104":12,"79":108},"treeitem-forumPost.png"],"26":["audioRecording","Audio Recording",[17,18,2,19],[110,90,71,28,4,45,7,72,14,77,87,11,116,123,19,62,18,1,27,2,22],{"71":109,"72":8},"treeitem-audioRecording.png"],"27":["presentation","Presentation",[24,2],[110,90,74,14,7,75,1,27,87,116,2,22],{"74":108},"treeitem-presentation.png"],"28":["videoRecording","Video Recording",[8,11,2,10,9],[110,90,63,28,4,45,7,76,14,77,87,11,116,1,27,123,19,62,18,2,22],{"63":109,"76":8},"treeitem-videoRecording.png"],"29":["tvBroadcast","TV Broadcast",[8,11,2,25,10,9],[110,90,119,105,63,7,78,14,77,87,116,1,27,123,19,62,18,2,22],{"119":12,"105":60,"63":109,"78":8},"treeitem-tvBroadcast.png"],"30":["radioBroadcast","Radio Broadcast",[8,11,2,25,10,9],[110,90,119,105,71,7,78,14,77,87,116,1,27,123,19,62,18,2,22],{"119":12,"105":60,"71":109,"78":8},"treeitem-radioBroadcast.png"],"31":["podcast","Podcast",[26,2,25],[110,90,28,105,80,77,1,27,87,116,2,22],{"105":60,"80":109},"treeitem-podcast.png"],"32":["computerProgram","Computer Program",[21,2],[110,90,28,81,14,82,7,83,88,11,116,1,2,123,19,62,18,27,22],{"83":8},"treeitem-computerProgram.png"],"33":["conferencePaper","Conference Paper",[1,2,3,5,4],[110,90,14,114,84,7,8,4,10,3,87,26,11,116,1,27,123,19,62,18,2,22],{"114":12},"treeitem-conferencePaper.png"],"34":["document","Document",[1,2,3,27,4],[110,90,8,14,87,116,1,27,123,19,62,18,2,22],{},"treeitem-document.png"],"35":["encyclopediaArticle","Encyclopedia Article",[1,2,3,5,4],[110,90,85,3,30,4,45,6,7,8,14,10,11,116,1,27,87,123,19,62,18,2,22],{"85":12},"treeitem-encyclopediaArticle.png"],"36":["dictionaryEntry","Dictionary Entry",[1,2,3,5,4],[110,90,86,3,30,4,45,6,7,8,14,10,87,11,116,1,27,123,19,62,18,2,22],{"86":12},"treeitem-dictionaryEntry.png"]},"creatorTypes":{"1":["author","Author"],"2":["contributor","Contributor"],"3":["editor","Editor"],"4":["translator","Translator"],"5":["seriesEditor","Series Editor"],"6":["interviewee","Interview With"],"7":["interviewer","Interviewer"],"8":["director","Director"],"9":["scriptwriter","Scriptwriter"],"10":["producer","Producer"],"11":["castMember","Cast Member"],"12":["sponsor","Sponsor"],"13":["counsel","Counsel"],"14":["inventor","Inventor"],"15":["attorneyAgent","Attorney/Agent"],"16":["recipient","Recipient"],"17":["performer","Performer"],"18":["composer","Composer"],"19":["wordsBy","Words By"],"20":["cartographer","Cartographer"],"21":["programmer","Programmer"],"22":["artist","Artist"],"23":["commenter","Commenter"],"24":["presenter","Presenter"],"25":["guest","Guest"],"26":["podcaster","Podcaster"],"27":["reviewedAuthor","Reviewed Author"],"28":["cosponsor","Cosponsor"],"29":["bookAuthor","Book Author"]},"fields":{"1":["url"],"2":["rights"],"3":["series"],"4":["volume"],"5":["issue"],"6":["edition"],"7":["place"],"8":["publisher"],"10":["pages"],"11":["ISBN"],"12":["publicationTitle"],"13":["ISSN"],"14":["date"],"15":["section"],"18":["callNumber"],"19":["archiveLocation"],"21":["distributor"],"22":["extra"],"25":["journalAbbreviation"],"26":["DOI"],"27":["accessDate"],"28":["seriesTitle"],"29":["seriesText"],"30":["seriesNumber"],"31":["institution"],"32":["reportType"],"36":["code"],"40":["session"],"41":["legislativeBody"],"42":["history"],"43":["reporter"],"44":["court"],"45":["numberOfVolumes"],"46":["committee"],"48":["assignee"],"50":["patentNumber"],"51":["priorityNumbers"],"52":["issueDate"],"53":["references"],"54":["legalStatus"],"55":["codeNumber"],"59":["artworkMedium"],"60":["number"],"61":["artworkSize"],"62":["libraryCatalog"],"63":["videoRecordingFormat"],"64":["interviewMedium"],"65":["letterType"],"66":["manuscriptType"],"67":["mapType"],"68":["scale"],"69":["thesisType"],"70":["websiteType"],"71":["audioRecordingFormat"],"72":["label"],"74":["presentationType"],"75":["meetingName"],"76":["studio"],"77":["runningTime"],"78":["network"],"79":["postType"],"80":["audioFileType"],"81":["version"],"82":["system"],"83":["company"],"84":["conferenceName"],"85":["encyclopediaTitle"],"86":["dictionaryTitle"],"87":["language"],"88":["programmingLanguage"],"89":["university"],"90":["abstractNote"],"91":["websiteTitle"],"92":["reportNumber"],"93":["billNumber"],"94":["codeVolume"],"95":["codePages"],"96":["dateDecided"],"97":["reporterVolume"],"98":["firstPage"],"99":["documentNumber"],"100":["dateEnacted"],"101":["publicLawNumber"],"102":["country"],"103":["applicationNumber"],"104":["forumTitle"],"105":["episodeNumber"],"107":["blogTitle"],"108":["type"],"109":["medium"],"110":["title"],"111":["caseName"],"112":["nameOfAct"],"113":["subject"],"114":["proceedingsTitle"],"115":["bookTitle"],"116":["shortTitle"],"117":["docketNumber"],"118":["numPages"],"119":["programTitle"],"120":["issuingAuthority"],"121":["filingDate"],"122":["genre"],"123":["archive"]}} +\ No newline at end of file diff --git a/chrome/content/zotero/xpcom/data/cachedTypes.js b/chrome/content/zotero/xpcom/data/cachedTypes.js @@ -336,7 +336,6 @@ Zotero.ItemTypes = new function() { } } - // DEBUG: only have icons for some types so far switch (itemType) { case 'attachment-file': case 'attachment-link': @@ -345,14 +344,21 @@ Zotero.ItemTypes = new function() { case 'attachment-pdf': case 'artwork': case 'audioRecording': + case 'bill': case 'blogPost': case 'book': case 'bookSection': + case 'case': case 'computerProgram': case 'conferencePaper': + case 'dictionaryEntry': + case 'document': case 'email': + case 'encyclopediaArticle': case 'film': case 'forumPost': + case 'hearing': + case 'instantMessage': case 'interview': case 'journalArticle': case 'letter': @@ -361,9 +367,12 @@ Zotero.ItemTypes = new function() { case 'map': case 'newspaperArticle': case 'note': + case 'patent': case 'podcast': + case 'presentation': case 'radioBroadcast': case 'report': + case 'statute': case 'thesis': case 'tvBroadcast': case 'videoRecording': diff --git a/chrome/content/zotero/xpcom/integration.js b/chrome/content/zotero/xpcom/integration.js @@ -653,7 +653,7 @@ Zotero.Integration = new function() { if(!message && typeof(e) == "object") message = "\n\n"+e.toString(); - if(message != "\n\nExceptionAlreadyDisplayed") { + if(message.indexOf("ExceptionAlreadyDisplayed") !== -1) { displayError = Zotero.getString("integration.error.generic")+message; } Zotero.debug(e); diff --git a/chrome/content/zotero/xpcom/rdf.js b/chrome/content/zotero/xpcom/rdf.js @@ -1,6 +0,0 @@ -// Tweaks to get the Tabulator RDF library to work without Tabulator. All of this happens in the -// Zotero.RDF.AJAW namespace. -var kb = new RDFIndexedFormula(); -var tabulator = {log:{debug:function(arg) { - Zotero.debug(arg, 4); -}}}; diff --git a/chrome/content/zotero/xpcom/rdf/identity.js b/chrome/content/zotero/xpcom/rdf/identity.js @@ -1,6 +1,6 @@ // Identity management and indexing for RDF // -// This file provides RDFIndexedFormula a formula (set of triples) which +// This file provides IndexedFormula a formula (set of triples) which // indexed by predicate, subject and object. // // It "smushes" (merges into a single node) things which are identical @@ -12,582 +12,484 @@ // 2007 Changed so as not to munge statements from documents when smushing // // - -/*jsl:option explicit*/ // Turn on JavaScriptLint variable declaration checking - -owl_ns = "http://www.w3.org/2002/07/owl#"; -link_ns = "http://www.w3.org/2006/link#"; - -/* hashString functions are used as array indeces. This is done to avoid -** conflict with existing properties of arrays such as length and map. -** See issue 139. -*/ -RDFLiteral.prototype.hashString = RDFLiteral.prototype.toNT; -RDFSymbol.prototype.hashString = RDFSymbol.prototype.toNT; -RDFBlankNode.prototype.hashString = RDFBlankNode.prototype.toNT; -RDFCollection.prototype.hashString = RDFCollection.prototype.toNT; - -RDFIndexedFormula.prototype = new RDFFormula(); -RDFIndexedFormula.prototype.constructor = RDFIndexedFormula; -// RDFIndexedFormula.superclass = RDFFormula.prototype; -RDFIndexedFormula.SuperClass = RDFFormula; - -RDFArrayRemove = function(a, x) { //removes all elements equal to x from a - for(var i=0; i<a.length; i++) { - if (a[i] == x) { - a.splice(i,1); - return; - } - } - throw "RDFArrayRemove: Array did not contain " + x; -}; - - - -//Stores an associative array that maps URIs to functions -function RDFIndexedFormula(features) { - this.statements = []; // As in RDFFormula +/*jsl:option explicit*/ +// Turn on JavaScriptLint variable declaration checking +$rdf.IndexedFormula = function () { + + var owl_ns = "http://www.w3.org/2002/07/owl#"; + // var link_ns = "http://www.w3.org/2007/ont/link#"; + /* hashString functions are used as array indeces. This is done to avoid + ** conflict with existing properties of arrays such as length and map. + ** See issue 139. + */ + $rdf.Literal.prototype.hashString = $rdf.Literal.prototype.toNT; + $rdf.Symbol.prototype.hashString = $rdf.Symbol.prototype.toNT; + $rdf.BlankNode.prototype.hashString = $rdf.BlankNode.prototype.toNT; + $rdf.Collection.prototype.hashString = $rdf.Collection.prototype.toNT; + + + //Stores an associative array that maps URIs to functions + $rdf.IndexedFormula = function (features) { + this.statements = []; // As in Formula this.optional = []; this.propertyActions = []; // Array of functions to call when getting statement with {s X o} //maps <uri> to [f(F,s,p,o),...] - this.classActions = []; // Array of functions to call when adding { s type X } - this.redirections = []; // redirect to lexically smaller equivalent symbol - this.aliases = []; // reverse mapping to redirection: aliases for this + this.classActions = []; // Array of functions to call when adding { s type X } + this.redirections = []; // redirect to lexically smaller equivalent symbol + this.aliases = []; // reverse mapping to redirection: aliases for this this.HTTPRedirects = []; // redirections we got from HTTP - this.subjectIndex = []; // Array of statements with this X as subject - this.predicateIndex = []; // Array of statements with this X as subject - this.objectIndex = []; // Array of statements with this X as object - this.whyIndex = []; // Array of statements with X as provenance - this.index = [ this.subjectIndex, this.predicateIndex, this.objectIndex, this.whyIndex ]; + this.subjectIndex = []; // Array of statements with this X as subject + this.predicateIndex = []; // Array of statements with this X as subject + this.objectIndex = []; // Array of statements with this X as object + this.whyIndex = []; // Array of statements with X as provenance + this.index = [this.subjectIndex, this.predicateIndex, this.objectIndex, this.whyIndex]; this.namespaces = {} // Dictionary of namespace prefixes - if (features == undefined) features = ["sameAs", - "InverseFunctionalProperty", "FunctionalProperty"]; -// this.features = features - + if(features === undefined) features = ["sameAs", + "InverseFunctionalProperty", "FunctionalProperty"]; + // this.features = features // Callbackify? - function handleRDFType(formula, subj, pred, obj, why) { - if (formula.typeCallback != undefined) - formula.typeCallback(formula, obj, why); - - var x = formula.classActions[obj.hashString()]; - var done = false; - if (x) { - for (var i=0; i<x.length; i++) { - done = done || x[i](formula, subj, pred, obj, why); - } + if(formula.typeCallback != undefined) + formula.typeCallback(formula, obj, why); + + var x = formula.classActions[obj.hashString()]; + var done = false; + if(x) { + for(var i = 0; i < x.length; i++) { + done = done || x[i](formula, subj, pred, obj, why); } - return done; // statement given is not needed if true + } + return done; // statement given is not needed if true } //handleRDFType - //If the predicate is #type, use handleRDFType to create a typeCallback on the object - this.propertyActions[ - '<http://www.w3.org/1999/02/22-rdf-syntax-ns#type>'] = [ handleRDFType ]; + this.propertyActions['<http://www.w3.org/1999/02/22-rdf-syntax-ns#type>'] = [handleRDFType]; // Assumption: these terms are not redirected @@fixme - if (features.indexOf("sameAs") >=0) - this.propertyActions['<http://www.w3.org/2002/07/owl#sameAs>'] = [ - function(formula, subj, pred, obj, why) { - formula.equate(subj,obj); - return true; // true if statement given is NOT needed in the store - }]; //sameAs -> equate & don't add to index -/* - function newPropertyAction(formula, pred, action) { - tabulator.log.debug("newPropertyAction: "+pred); - if (formula.propertyActions[pred] == undefined) - formula.propertyActions[pred] = []; - formula.propertyActions[pred].push(action); - // Now apply the function to to statements already in the store - var toBeFixed = formula.statementsMatching(undefined, pred, undefined); - var i; - for (i=0; i<toBeFixed.length; i++) { // NOT optimized - sort toBeFixed etc - if (action(formula, toBeFixed[i].subject, pred, toBeFixed[i].object)) { - tabulator.log.debug("newPropertyAction: NOT removing "+toBeFixed[i]); - } - } - return false; - } -*/ - if (features.indexOf("InverseFunctionalProperty") >= 0) - this.classActions["<"+owl_ns+"InverseFunctionalProperty>"] = [ - function(formula, subj, pred, obj, addFn) { - return formula.newPropertyAction(subj, handle_IFP); // yes subj not pred! - }]; //IFP -> handle_IFP, do add to index - - if (features.indexOf("FunctionalProperty") >= 0) - this.classActions["<"+owl_ns+"FunctionalProperty>"] = [ - function(formula, subj, proj, obj, addFn) { - return formula.newPropertyAction(subj, handle_FP); - }]; //FP => handleFP, do add to index - - function handle_IFP(formula, subj, pred, obj) { - var s1 = formula.any(undefined, pred, obj); - if (s1 == undefined) return false; // First time with this value - formula.equate(s1, subj); - return true; + if($rdf.Util.ArrayIndexOf(features, "sameAs") >= 0) + this.propertyActions['<http://www.w3.org/2002/07/owl#sameAs>'] = [ + function (formula, subj, pred, obj, why) { + // tabulator.log.warn("Equating "+subj.uri+" sameAs "+obj.uri); //@@ + formula.equate(subj, obj); + return true; // true if statement given is NOT needed in the store + }]; //sameAs -> equate & don't add to index + if($rdf.Util.ArrayIndexOf(features, "InverseFunctionalProperty") >= 0) + this.classActions["<" + owl_ns + "InverseFunctionalProperty>"] = [ + function (formula, subj, pred, obj, addFn) { + return formula.newPropertyAction(subj, handle_IFP); // yes subj not pred! + }]; //IFP -> handle_IFP, do add to index + if($rdf.Util.ArrayIndexOf(features, "FunctionalProperty") >= 0) + this.classActions["<" + owl_ns + "FunctionalProperty>"] = [ + function (formula, subj, proj, obj, addFn) { + return formula.newPropertyAction(subj, handle_FP); + } + ]; //FP => handleFP, do add to index + function handle_IFP(formula, subj, pred, obj) { + var s1 = formula.any(undefined, pred, obj); + if(s1 == undefined) return false; // First time with this value + // tabulator.log.warn("Equating "+s1.uri+" and "+subj.uri + " because IFP "+pred.uri); //@@ + formula.equate(s1, subj); + return true; } //handle_IFP - - function handle_FP(formula, subj, pred, obj) { - var o1 = formula.any(subj, pred, undefined); - if (o1 == undefined) return false; // First time with this value - formula.equate(o1, obj); - return true ; + function handle_FP(formula, subj, pred, obj) { + var o1 = formula.any(subj, pred, undefined); + if(o1 == undefined) return false; // First time with this value + // tabulator.log.warn("Equating "+o1.uri+" and "+obj.uri + " because FP "+pred.uri); //@@ + formula.equate(o1, obj); + return true; } //handle_FP - -} /* end RDFIndexedFormula */ + } /* end IndexedFormula */ + $rdf.IndexedFormula.prototype = new $rdf.Formula(); + $rdf.IndexedFormula.prototype.constructor = $rdf.IndexedFormula; + $rdf.IndexedFormula.SuperClass = $rdf.Formula; - - -RDFIndexedFormula.prototype.newPropertyAction = function newPropertyAction(pred, action) { - tabulator.log.debug("newPropertyAction: "+pred); + $rdf.IndexedFormula.prototype.newPropertyAction = function newPropertyAction(pred, action) { + //$rdf.log.debug("newPropertyAction: "+pred); var hash = pred.hashString(); - if (this.propertyActions[hash] == undefined) - this.propertyActions[hash] = []; + if(this.propertyActions[hash] == undefined) + this.propertyActions[hash] = []; this.propertyActions[hash].push(action); // Now apply the function to to statements already in the store var toBeFixed = this.statementsMatching(undefined, pred, undefined); - done = false; - for (var i=0; i<toBeFixed.length; i++) { // NOT optimized - sort toBeFixed etc - done = done || action(this, toBeFixed[i].subject, pred, toBeFixed[i].object); + var done = false; + for(var i = 0; i < toBeFixed.length; i++) { // NOT optimized - sort toBeFixed etc + done = done || action(this, toBeFixed[i].subject, pred, toBeFixed[i].object); } return done; -} - + } - - -RDFPlainFormula = function() { return RDFIndexedFormula([]); } // No features - - -RDFIndexedFormula.prototype.setPrefixForURI = function(prefix, nsuri) { + $rdf.IndexedFormula.prototype.setPrefixForURI = function (prefix, nsuri) { //TODO:This is a hack for our own issues, which ought to be fixed post-release - //See http://dig.csail.mit.edu/cgi-bin/roundup.cgi/tabulator/issue227 - if(prefix=="tab" && this.namespaces["tab"]) { - return; + //See http://dig.csail.mit.edu/cgi-bin/roundup.cgi/$rdf/issue227 + if(prefix == "tab" && this.namespaces["tab"]) { + return; } this.namespaces[prefix] = nsuri -} + } -// Deprocated ... name too generic -RDFIndexedFormula.prototype.register = function(prefix, nsuri) { + // Deprocated ... name too generic + $rdf.IndexedFormula.prototype.register = function (prefix, nsuri) { this.namespaces[prefix] = nsuri -} + } -/** simplify graph in store when we realize two identifiers are equal + /** simplify graph in store when we realize two identifiers are equivalent We replace the bigger with the smaller. */ -RDFIndexedFormula.prototype.equate = function(u1, u2) { - tabulator.log.debug("Equating "+u1+" and "+u2) - + $rdf.IndexedFormula.prototype.equate = function (u1, u2) { + // tabulator.log.warn("Equating "+u1+" and "+u2); // @@ + //@@JAMBO Must canonicalize the uris to prevent errors from a=b=c + //03-21-2010 + u1 = this.canon(u1); + u2 = this.canon(u2); var d = u1.compareTerm(u2); - if (!d) return true; // No information in {a = a} + if(!d) return true; // No information in {a = a} var big, small; - if (d < 0) { // u1 less than u2 - return this.replaceWith(u2, u1); + if(d < 0) { // u1 less than u2 + return this.replaceWith(u2, u1); } else { - return this.replaceWith(u1, u2); + return this.replaceWith(u1, u2); } -} + } -// Replace big with small, obsoleted with obsoleting. -// -RDFIndexedFormula.prototype.replaceWith = function(big, small) { - tabulator.log.debug("Replacing "+big+" with "+small) // @@ + // Replace big with small, obsoleted with obsoleting. + // + $rdf.IndexedFormula.prototype.replaceWith = function (big, small) { + //$rdf.log.debug("Replacing "+big+" with "+small) // @@ var oldhash = big.hashString(); var newhash = small.hashString(); - var moveIndex = function(ix) { + var moveIndex = function (ix) { var oldlist = ix[oldhash]; - if (oldlist == undefined) return; // none to move + if(oldlist == undefined) return; // none to move var newlist = ix[newhash]; - if (newlist == undefined) { - ix[newhash] = newlist; + if(newlist == undefined) { + ix[newhash] = oldlist; } else { - ix[newhash] = oldlist.concat(newlist); + ix[newhash] = oldlist.concat(newlist); } - delete ix[oldhash]; - } - - // the canonical one carries all the indexes - for (var i=0; i<4; i++) { - moveIndex(this.index[i]); + delete ix[oldhash]; + } + + // the canonical one carries all the indexes + for(var i = 0; i < 4; i++) { + moveIndex(this.index[i]); } this.redirections[oldhash] = small; - if (big.uri) { - if (this.aliases[newhash] == undefined) - this.aliases[newhash] = []; - this.aliases[newhash].push(big); // Back link - - this.add(small, this.sym('http://www.w3.org/2006/link#uri'), big.uri) - - // If two things are equal, and one is requested, we should request the other. - if (this.sf) { - this.sf.nowKnownAs(big, small) - } - + if(big.uri) { + //@@JAMBO: must update redirections,aliases from sub-items, too. + if(this.aliases[newhash] == undefined) + this.aliases[newhash] = []; + this.aliases[newhash].push(big); // Back link + if(this.aliases[oldhash]) { + for(var i = 0; i < this.aliases[oldhash].length; i++) { + this.redirections[this.aliases[oldhash][i].hashString()] = small; + this.aliases[newhash].push(this.aliases[oldhash][i]); + } + } + + //this.add(small, this.sym('http://www.w3.org/2007/ont/link#uri'), big.uri) + + // If two things are equal, and one is requested, we should request the other. + if(this.sf) { + this.sf.nowKnownAs(big, small) + } } - + moveIndex(this.classActions); moveIndex(this.propertyActions); - tabulator.log.debug("Equate done. "+big+" to be known as "+small) - return true; // true means the statement does not need to be put in -}; + $rdf.log.debug("Equate done. "+big+" now links to "+small) + return true; // true means the statement does not need to be put in + }; -// Return the symbol with canonical URI as smushed -RDFIndexedFormula.prototype.canon = function(term) { - if (term == undefined) return term; + // Return the symbol with canonical URI as smushed + $rdf.IndexedFormula.prototype.canon = function (term) { + if(term == undefined) return term; var y = this.redirections[term.hashString()]; - if (y == undefined) return term; + if(y == undefined) return term; return y; -} + } -// Compare by canonical URI as smushed -RDFIndexedFormula.prototype.sameThings = function(x, y) { - if (x.sameTerm(y)) return true; + // Compare by canonical URI as smushed + $rdf.IndexedFormula.prototype.sameThings = function (x, y) { + if(x.sameTerm(y)) return true; var x1 = this.canon(x); -// alert('x1='+x1); - if (x1 == undefined) return false; + // alert('x1='+x1); + if(x1 == undefined) return false; var y1 = this.canon(y); -// alert('y1='+y1); //@@ - if (y1 == undefined) return false; - return (x1.uri == y1.uri); -} + // alert('y1='+y1); //@@ + if(y1 == undefined) return false; + return(x1.uri == y1.uri); + } -// A list of all the URIs by which this thing is known -RDFIndexedFormula.prototype.uris = function(term) { + // A list of all the URIs by which this thing is known + $rdf.IndexedFormula.prototype.uris = function (term) { var cterm = this.canon(term) var terms = this.aliases[cterm.hashString()]; - if (!cterm.uri) return [] - var res = [ cterm.uri ] - if (terms != undefined) { - for (var i=0; i<terms.length; i++) { - res.push(terms[i].uri) - } + if(!cterm.uri) return [] + var res = [cterm.uri] + if(terms != undefined) { + for(var i = 0; i < terms.length; i++) { + res.push(terms[i].uri) + } } return res -} - -// On input parameters, convert constants to terms -// -function RDFMakeTerm(formula,val, canonicalize) { - if (typeof val != 'object') { - if (typeof val == 'string') - return new RDFLiteral(val); - if (typeof val == 'number') - return new RDFLiteral(val); // @@ differet types - if (typeof val == 'boolean') - return new RDFLiteral(val?"1":"0", undefined, - RDFSymbol.prototype.XSDboolean); - else if (typeof val == 'number') - return new RDFLiteral(''+val); // @@ datatypes - else if (typeof val == 'undefined') - return undefined; - else // @@ add converting of dates and numbers - throw "Can't make Term from " + val + " of type " + typeof val; + } + + // On input parameters, convert constants to terms + // + function RDFMakeTerm(formula, val, canonicalize) { + if(typeof val != 'object') { + if(typeof val == 'string') + return new $rdf.Literal(val); + if(typeof val == 'number') + return new $rdf.Literal(val); // @@ differet types + if(typeof val == 'boolean') + return new $rdf.Literal(val ? "1" : "0", undefined, $rdf.Symbol.prototype.XSDboolean); + if(typeof val == 'undefined') + return undefined; + else // @@ add converting of dates and numbers + throw "Can't make Term from " + val + " of type " + typeof val; } return val; -} - -// add a triple to the store -RDFIndexedFormula.prototype.add = function(subj, pred, obj, why) { + } + + // Add a triple to the store + // + // Returns the statement added + // (would it be better to return the original formula for chaining?) + // + $rdf.IndexedFormula.prototype.add = function (subj, pred, obj, why) { var actions, st; - if (why == undefined) why = this.fetcher ? this.fetcher.appNode: kb.sym("chrome:theSession"); //system generated - //defined in source.js, is this OK with identity.js only user? + if(why == undefined) why = this.fetcher ? this.fetcher.appNode : this.sym("chrome:theSession"); //system generated + //defined in source.js, is this OK with identity.js only user? subj = RDFMakeTerm(this, subj); pred = RDFMakeTerm(this, pred); obj = RDFMakeTerm(this, obj); why = RDFMakeTerm(this, why); - - var hash = [ this.canon(subj).hashString(), this.canon(pred).hashString(), - this.canon(obj).hashString(), this.canon(why).hashString()]; - -/* // Removed TimBL 2007-01-06 - // Check we don't already know it -- esp when working with dbview - // db view has many documents with the same triple - a waste. - // but is we want to be able to edit documents, we must maintain the original - // triples from each one. We might occasionally want to mutiple provences too - // for a full Truth Management System. Maybe this should be run-time option. - st = this.anyStatementMatching(subj,pred,obj) // @@@@@@@ temp fix <====WATCH OUT! - It is general necessary to know when data has come from >1 place. - Maybe this should be a mode? -*/ - // This is wasting time and shouldn't happen at all - //st = this.anyStatementMatching(subj,pred,obj,why) // Avoid duplicates - //if (st != undefined) return; // already in store - - - - // tabulator.log.debug("\nActions for "+s+" "+p+" "+o+". size="+this.statements.length) - if (this.predicateCallback != undefined) - this.predicateCallback(this, pred, why); - + + if(this.predicateCallback != undefined) + this.predicateCallback(this, pred, why); + // Action return true if the statement does not need to be added - var actions = this.propertyActions[hash[1]]; // Predicate hash + var actions = this.propertyActions[this.canon(pred).hashString()]; var done = false; - if (actions) { - // alert('type: '+typeof actions +' @@ actions='+actions); - for (var i=0; i<actions.length; i++) { - done = done || actions[i](this, subj, pred, obj, why); - } + if(actions) { + // alert('type: '+typeof actions +' @@ actions='+actions); + for(var i = 0; i < actions.length; i++) { + done = done || actions[i](this, subj, pred, obj, why); + } } - + //If we are tracking provenanance, every thing should be loaded into the store - //if (done) return new RDFStatement(subj, pred, obj, why); // Don't put it in the store - // still return this statement for owl:sameAs input - var st = new RDFStatement(subj, pred, obj, why); - for (var i=0; i<4; i++) { - var ix = this.index[i]; - var h = hash[i]; - if (ix[h] == undefined) ix[h] = []; - ix[h].push(st); // Set of things with this as subject + //if (done) return new Statement(subj, pred, obj, why); // Don't put it in the store + // still return this statement for owl:sameAs input + var hash = [this.canon(subj).hashString(), this.canon(pred).hashString(), + this.canon(obj).hashString(), this.canon(why).hashString()]; + var st = new $rdf.Statement(subj, pred, obj, why); + for(var i = 0; i < 4; i++) { + var ix = this.index[i]; + var h = hash[i]; + if(ix[h] == undefined) ix[h] = []; + ix[h].push(st); // Set of things with this as subject, etc } - - tabulator.log.debug("ADDING {"+subj+" "+pred+" "+obj+"} "+why); + + //tabulator.log.debug("ADDING {"+subj+" "+pred+" "+obj+"} "+why); this.statements.push(st); return st; -}; //add - - -// Find out whether a given URI is used as symbol in the formula -RDFIndexedFormula.prototype.mentionsURI = function(uri) { + }; //add + // Find out whether a given URI is used as symbol in the formula + $rdf.IndexedFormula.prototype.mentionsURI = function (uri) { var hash = '<' + uri + '>'; - return (!!this.subjectIndex[hash] || !!this.objectIndex[hash] - || !!this.predicateIndex[hash]); -} - -// Find an unused id for a file being edited: return a symbol -// (Note: Slow iff a lot of them -- could be O(log(k)) ) -RDFIndexedFormula.prototype.nextSymbol = function(doc) { - for(var i=0;;i++) { - var uri = doc.uri + '#n' + i; - if (!this.mentionsURI(uri)) return kb.sym(uri); + return (!!this.subjectIndex[hash] + || !!this.objectIndex[hash] + || !!this.predicateIndex[hash]); + } + + // Find an unused id for a file being edited: return a symbol + // (Note: Slow iff a lot of them -- could be O(log(k)) ) + $rdf.IndexedFormula.prototype.nextSymbol = function (doc) { + for(var i = 0;; i++) { + var uri = doc.uri + '#n' + i; + if(!this.mentionsURI(uri)) return this.sym(uri); } -} + } -RDFIndexedFormula.prototype.anyStatementMatching = function(subj,pred,obj,why) { - var x = this.statementsMatching(subj,pred,obj,why,true); - if (!x || x == []) return undefined; + $rdf.IndexedFormula.prototype.anyStatementMatching = function (subj, pred, obj, why) { + var x = this.statementsMatching(subj, pred, obj, why, true); + if(!x || x == []) return undefined; return x[0]; -}; + }; -// Return statements matching a pattern -// ALL CONVENIENCE LOOKUP FUNCTIONS RELY ON THIS! -RDFIndexedFormula.prototype.statementsMatching = function(subj,pred,obj,why,justOne) { - tabulator.log.debug("Matching {"+subj+" "+pred+" "+obj+"}"); - - var pat = [ subj, pred, obj, why ]; + // Return statements matching a pattern + // ALL CONVENIENCE LOOKUP FUNCTIONS RELY ON THIS! + $rdf.IndexedFormula.prototype.statementsMatching = function (subj, pred, obj, why, justOne) { + //$rdf.log.debug("Matching {"+subj+" "+pred+" "+obj+"}"); + var pat = [subj, pred, obj, why]; var pattern = []; var hash = []; var wild = []; // wildcards var given = []; // Not wild - for (var p=0; p<4; p++) { - pattern[p] = this.canon(RDFMakeTerm(this, pat[p])); - if (pattern[p] == undefined) { - wild.push(p); - } else { - given.push(p); - hash[p] = pattern[p].hashString(); - } + for(var p = 0; p < 4; p++) { + pattern[p] = this.canon(RDFMakeTerm(this, pat[p])); + if(pattern[p] == undefined) { + wild.push(p); + } else { + given.push(p); + hash[p] = pattern[p].hashString(); + } + } + if(given.length == 0) { + return this.statements; } - if (given.length == 0) return this.statements; // Easy - if (given.length == 1) { // Easy too, we have an index for that - var p = given[0]; - var list = this.index[p][hash[p]]; - return list == undefined ? [] : list; + if(given.length == 1) { // Easy too, we have an index for that + var p = given[0]; + var list = this.index[p][hash[p]]; + if(list && justOne) { + if(list.length > 1) + list = list.slice(0, 1); + } + return list == undefined ? [] : list; } - + // Now given.length is 2, 3 or 4. // We hope that the scale-free nature of the data will mean we tend to get // a short index in there somewhere! - var best = 1e10; // really bad var best_i; - for (var i=0; i<given.length; i++) { - var p = given[i]; // Which part we are dealing with - var list = this.index[p][hash[p]]; - if (list == undefined) return []; // No occurrences - if (list.length < best) { - best = list.length; - best_i = i; // (not p!) - } + for(var i = 0; i < given.length; i++) { + var p = given[i]; // Which part we are dealing with + var list = this.index[p][hash[p]]; + if(list == undefined) return []; // No occurrences + if(list.length < best) { + best = list.length; + best_i = i; // (not p!) + } } - + // Ok, we have picked the shortest index but now we have to filter it var best_p = given[best_i]; var possibles = this.index[best_p][hash[best_p]]; - var check = given.slice(0, best_i).concat(given.slice(best_i+1)) // remove best_i + var check = given.slice(0, best_i).concat(given.slice(best_i + 1)) // remove best_i var results = []; - var parts = [ 'subject', 'predicate', 'object', 'why']; - for (var j=0; j<possibles.length; j++) { - var st = possibles[j]; - for (var i=0; i <check.length; i++) { // for each position to be checked - var p = check[i]; - if (!this.canon(st[parts[p]]).sameTerm(pattern[p])) { - st = null; - break; - } + var parts = ['subject', 'predicate', 'object', 'why']; + for(var j = 0; j < possibles.length; j++) { + var st = possibles[j]; + for(var i = 0; i < check.length; i++) { // for each position to be checked + var p = check[i]; + if(!this.canon(st[parts[p]]).sameTerm(pattern[p])) { + st = null; + break; } - if (st != null) results.push(st); + } + if(st != null) { + results.push(st); + if(justOne) + break; + } } return results; -}; // statementsMatching - - -/** remove a particular statement from the bank **/ -RDFIndexedFormula.prototype.remove = function (st) { - tabulator.log.debug("entering remove w/ st=" + st); - var term = [ st.subject, st.predicate, st.object, st.why]; - for (var p=0; p<4; p++) { - var c = this.canon(term[p]); - var h = c.hashString(); - if (this.index[p][h] == undefined) { - tabulator.log.warn ("Statement removal: no index '+p+': "+st); - } else { - RDFArrayRemove(this.index[p][h], st); - } + }; // statementsMatching + /** remove a particular statement from the bank **/ + $rdf.IndexedFormula.prototype.remove = function (st) { + //$rdf.log.debug("entering remove w/ st=" + st); + var term = [st.subject, st.predicate, st.object, st.why]; + for(var p = 0; p < 4; p++) { + var c = this.canon(term[p]); + var h = c.hashString(); + if(this.index[p][h] == undefined) { + //$rdf.log.warn ("Statement removal: no index '+p+': "+st); + } else { + $rdf.Util.RDFArrayRemove(this.index[p][h], st); + } } - RDFArrayRemove(this.statements, st); -}; //remove - -/** remove all statements matching args (within limit) **/ -RDFIndexedFormula.prototype.removeMany = function (subj, pred, obj, why, limit) { - tabulator.log.debug("entering removeMany w/ subj,pred,obj,why,limit = " + subj +", "+ pred+", " + obj+", " + why+", " + limit); - var sts = this.statementsMatching (subj, pred, obj, why, false); + $rdf.Util.RDFArrayRemove(this.statements, st); + }; //remove + /** remove all statements matching args (within limit) **/ + $rdf.IndexedFormula.prototype.removeMany = function (subj, pred, obj, why, limit) { + //$rdf.log.debug("entering removeMany w/ subj,pred,obj,why,limit = " + subj +", "+ pred+", " + obj+", " + why+", " + limit); + var sts = this.statementsMatching(subj, pred, obj, why, false); //This is a subtle bug that occcured in updateCenter.js too. //The fact is, this.statementsMatching returns this.whyIndex instead of a copy of it //but for perfromance consideration, it's better to just do that //so make a copy here. var statements = []; - for (var i=0;i<sts.length;i++) statements.push(sts[i]); - if (limit) statements = statements.slice(0, limit); - for (var st in statements) this.remove(statements[st]); -}; //removeMany - -/** Load a resorce into the store **/ - -RDFIndexedFormula.prototype.load = function(url) { - // get the XML - var xhr = Util.XMLHTTPFactory(); // returns a new XMLHttpRequest, or ActiveX XMLHTTP object - if (xhr.overrideMimeType) { - xhr.overrideMimeType("text/xml"); - } - - // Get privileges for cross-domain web access - if(!isExtension) { - try { - Util.enablePrivilege("UniversalXPConnect UniversalBrowserRead") - } catch(e) { - throw ("Failed to get privileges: (see http://dig.csail.mit.edu/2005/ajar/ajaw/Privileges.html)" + e) - } - } - - xhr.open("GET", url, false); // Synchronous - xhr.send(""); - - // Get XML DOM Tree - - var nodeTree = xhr.responseXML; - if (nodeTree === null && xhr.responseText !== null) { - // Only if the server fails to set Content-Type: text/xml AND xmlhttprequest doesn't have the overrideMimeType method - nodeTree = (new DOMParser()).parseFromString(xhr.responseText, 'text/xml'); - } - - // Get RDF statements fromm XML - - // must be an XML document node tree - var parser = new RDFParser(this); - parser.parse(nodeTree,url); -} - - -/** Utility**/ - -/* @method: copyTo - @discription: replace @template with @target and add appropriate triples (no triple removed) + for(var i = 0; i < sts.length; i++) statements.push(sts[i]); + if(limit) statements = statements.slice(0, limit); + for(var i = 0; i < statements.length; i++) this.remove(statements[i]); + }; //removeMany + /** Utility**/ + + /* @method: copyTo + @description: replace @template with @target and add appropriate triples (no triple removed) one-direction replication -*/ -RDFIndexedFormula.prototype.copyTo = function(template,target,flags){ - if (!flags) flags=[]; - var statList=this.statementsMatching(template); - if (flags.indexOf('two-direction')!=-1) - statList.concat(this.statementsMatching(undefined,undefined,template)); - for (var i=0;i<statList.length;i++){ - var st=statList[i]; - switch (st.object.termType){ - case 'symbol': - this.add(target,st.predicate,st.object); - break; - case 'literal': - case 'bnode': - case 'collection': - this.add(target,st.predicate,st.object.copy(this)); - } - if (flags.indexOf('delete')!=-1) this.remove(st); +*/ + $rdf.IndexedFormula.prototype.copyTo = function (template, target, flags) { + if(!flags) flags = []; + var statList = this.statementsMatching(template); + if($rdf.Util.ArrayIndexOf(flags, 'two-direction') != -1) + statList.concat(this.statementsMatching(undefined, undefined, template)); + for(var i = 0; i < statList.length; i++) { + var st = statList[i]; + switch(st.object.termType) { + case 'symbol': + this.add(target, st.predicate, st.object); + break; + case 'literal': + case 'bnode': + case 'collection': + this.add(target, st.predicate, st.object.copy(this)); + } + if($rdf.Util.ArrayIndexOf(flags, 'delete') != -1) this.remove(st); } -}; -//for the case when you alter this.value (text modified in userinput.js) -RDFLiteral.prototype.copy = function(){ - return new RDFLiteral(this.value,this.lang,this.datatype); -}; -RDFBlankNode.prototype.copy = function(formula){ //depends on the formula - var bnodeNew=new RDFBlankNode(); - formula.copyTo(this,bnodeNew); + }; + //for the case when you alter this.value (text modified in userinput.js) + $rdf.Literal.prototype.copy = function () { + return new $rdf.Literal(this.value, this.lang, this.datatype); + }; + $rdf.BlankNode.prototype.copy = function (formula) { //depends on the formula + var bnodeNew = new $rdf.BlankNode(); + formula.copyTo(this, bnodeNew); return bnodeNew; -} -/** Full N3 bits -- placeholders only to allow parsing, no functionality! **/ + } + /** Full N3 bits -- placeholders only to allow parsing, no functionality! **/ -RDFIndexedFormula.prototype.newUniversal = function(uri) { + $rdf.IndexedFormula.prototype.newUniversal = function (uri) { var x = this.sym(uri); - if (!this._universalVariables) this._universalVariables = []; + if(!this._universalVariables) this._universalVariables = []; this._universalVariables.push(x); return x; -} + } -RDFIndexedFormula.prototype.newExistential = function(uri) { - if (!uri) return this.bnode(); + $rdf.IndexedFormula.prototype.newExistential = function (uri) { + if(!uri) return this.bnode(); var x = this.sym(uri); return this.declareExistential(x); -} + } -RDFIndexedFormula.prototype.declareExistential = function(x) { - if (!this._existentialVariables) this._existentialVariables = []; + $rdf.IndexedFormula.prototype.declareExistential = function (x) { + if(!this._existentialVariables) this._existentialVariables = []; this._existentialVariables.push(x); return x; -} + } -RDFIndexedFormula.prototype.formula = function(features) { - return new RDFIndexedFormula(features); -} + $rdf.IndexedFormula.prototype.formula = function (features) { + return new $rdf.IndexedFormula(features); + } -RDFIndexedFormula.prototype.close = function() { + $rdf.IndexedFormula.prototype.close = function () { return this; -} - -RDFIndexedFormula.prototype.hashString = RDFIndexedFormula.prototype.toNT; - -///////////////////////////// Provenance tracking -// -// Where did this statement come from? -// - -/* -RDFStatement.prototype.original = function() { - for (var st = this;; st = st.why.premis[0]) { - if (st.why.termType && st.why.termType== 'symbol') - return this; // This statement came from a document - } -} -*/ - + } + $rdf.IndexedFormula.prototype.hashString = $rdf.IndexedFormula.prototype.toNT; -// ends + return $rdf.IndexedFormula; +}(); +// ends +\ No newline at end of file diff --git a/chrome/content/zotero/xpcom/rdf/init.js b/chrome/content/zotero/xpcom/rdf/init.js @@ -0,0 +1,33 @@ +/* Set up the environment before loading the rest of the files into Zotero */ +var $rdf = { + Util: { + ArrayIndexOf: function (arr, item, i) { + //supported in all browsers except IE<9 + return arr.indexOf(item, i); + }, + RDFArrayRemove: function (a, x) { //removes all statements equal to x from a + for (var i = 0; i < a.length; i++) { + //TODO: This used to be the following, which didnt always work..why + //if(a[i] == x) + if (a[i].subject.sameTerm(x.subject) && a[i].predicate.sameTerm(x.predicate) && a[i].object.sameTerm(x.object) && a[i].why.sameTerm(x.why)) { + a.splice(i, 1); + return; + } + } + throw "RDFArrayRemove: Array did not contain " + x; + } + }, + log: { + debug: Zotero.debug, + warn: Zotero.debug + } +}; + +if(Zotero.RDF) { + Zotero.RDF.AJAW = $rdf; +} else { + Zotero.RDF = {AJAW:$rdf}; +} + +var tabulator = {log: $rdf.log}; +var alert = $rdf.log.warn; diff --git a/chrome/content/zotero/xpcom/rdf/match.js b/chrome/content/zotero/xpcom/rdf/match.js @@ -5,76 +5,42 @@ // // We retpresent a set as an associative array whose value for // each member is set to true. - -/* Not used, bogus. See identity.js for the ones really used. -RDFFormula.prototype.statementsMatching = function(s,p,o,w) { - var results = [] - var i - var ls = this.statements.length - for (i=0; i<ls; i++) { - var st = this.statements[i] - if (RDFTermMatch(p, st.predicate) && // first as simplest - RDFTermMatch(s, st.subject) && - RDFTermMatch(o, st.object) && - RDFTermMatch(w, st.why)) { - results[st] = true @@@@ sould use numeric indexed array - } - - } - return results -} - -RDFFormula.prototype.anyStatementMatching = function(s,p,o,w) { - var ls = this.statements.length - var i - for (i=0; i<ls; i++) { - var st = this.statements[i] - if (RDFTermMatch(p, st.predicate) && // first as simplest - RDFTermMatch(s, st.subject) && - RDFTermMatch(o, st.object) && - RDFTermMatch(w, st.why)) { - return st - } - - } - return undefined -} - -*/ - -function RDFTermMatch(pattern, term) { - if (typeof pattern == 'undefined') return true; - return pattern.sameTerm(term) -} - -RDFSymbol.prototype.sameTerm = function(other) { - if (!other) { return false } - return ((this.termType == other.termType) && (this.uri == other.uri)) +$rdf.Symbol.prototype.sameTerm = function (other) { + if(!other) { + return false + } + return((this.termType == other.termType) && (this.uri == other.uri)) } -RDFBlankNode.prototype.sameTerm = function(other) { - if (!other) { return false } - return ((this.termType == other.termType) && (this.id == other.id)) +$rdf.BlankNode.prototype.sameTerm = function (other) { + if(!other) { + return false + } + return((this.termType == other.termType) && (this.id == other.id)) } -RDFLiteral.prototype.sameTerm = function(other) { - if (!other) { return false } - return ((this.termType == other.termType) - && (this.value == other.value) - && (this.lang == other.lang) && - ((!this.datatype && !other.datatype) - || this.datatype.sameTerm(other.datatype))) +$rdf.Literal.prototype.sameTerm = function (other) { + if(!other) { + return false + } + return((this.termType == other.termType) + && (this.value == other.value) + && (this.lang == other.lang) + && ((!this.datatype && !other.datatype) + || (this.datatype && this.datatype.sameTerm(other.datatype)))) } -RDFVariable.prototype.sameTerm = function (other) { - if (!other) { return false } - return((this.termType == other.termType) && (this.uri == other.uri)) +$rdf.Variable.prototype.sameTerm = function (other) { + if(!other) { + return false + } + return((this.termType == other.termType) && (this.uri == other.uri)) } -RDFCollection.prototype.sameTerm = RDFBlankNode.prototype.sameTerm +$rdf.Collection.prototype.sameTerm = $rdf.BlankNode.prototype.sameTerm -RDFFormula.prototype.sameTerm = function (other) { - return this.hashString() == other.hashString(); +$rdf.Formula.prototype.sameTerm = function (other) { + return this.hashString() == other.hashString(); } // Comparison for ordering // @@ -84,95 +50,95 @@ RDFFormula.prototype.sameTerm = function (other) { // When we smush nodes we take the lowest value. This is not // arbitrary: we want the value actually used to be the literal // (or list or formula). - -RDFLiteral.prototype.classOrder = 1 -// RDFList.prototype.classOrder = 2 -// RDFSet.prototype.classOrder = 3 -RDFCollection.prototype.classOrder = 3 -RDFFormula.prototype.classOrder = 4 -RDFSymbol.prototype.classOrder = 5 -RDFBlankNode.prototype.classOrder = 6 +$rdf.Literal.prototype.classOrder = 1 +$rdf.Collection.prototype.classOrder = 3 +$rdf.Formula.prototype.classOrder = 4 +$rdf.Symbol.prototype.classOrder = 5 +$rdf.BlankNode.prototype.classOrder = 6 // Compaisons return sign(self - other) // Literals must come out before terms for smushing +$rdf.Literal.prototype.compareTerm = function (other) { + if(this.classOrder < other.classOrder) return -1 + if(this.classOrder > other.classOrder) return +1 + if(this.value < other.value) return -1 + if(this.value > other.value) return +1 + return 0 +} -RDFLiteral.prototype.compareTerm = function(other) { - if (this.classOrder < other.classOrder) return -1 - if (this.classOrder > other.classOrder) return +1 - if (this.value < other.value) return -1 - if (this.value > other.value) return +1 - return 0 -} - -RDFSymbol.prototype.compareTerm = function(other) { - if (this.classOrder < other.classOrder) return -1 - if (this.classOrder > other.classOrder) return +1 - if (this.uri < other.uri) return -1 - if (this.uri > other.uri) return +1 - return 0 -} - -RDFBlankNode.prototype.compareTerm = function(other) { - if (this.classOrder < other.classOrder) return -1 - if (this.classOrder > other.classOrder) return +1 - if (this.id < other.id) return -1 - if (this.id > other.id) return +1 - return 0 -} - -RDFCollection.prototype.compareTerm = RDFBlankNode.prototype.compareTerm +$rdf.Symbol.prototype.compareTerm = function (other) { + if(this.classOrder < other.classOrder) return -1 + if(this.classOrder > other.classOrder) return +1 + if(this.uri < other.uri) return -1 + if(this.uri > other.uri) return +1 + return 0 +} -// Convenience routines +$rdf.BlankNode.prototype.compareTerm = function (other) { + if(this.classOrder < other.classOrder) return -1 + if(this.classOrder > other.classOrder) return +1 + if(this.id < other.id) return -1 + if(this.id > other.id) return +1 + return 0 +} +$rdf.Collection.prototype.compareTerm = $rdf.BlankNode.prototype.compareTerm + +// Convenience routines // Only one of s p o can be undefined, and w is optional. -RDFFormula.prototype.each = function(s,p,o,w) { - var results = [] - var st, sts = this.statementsMatching(s,p,o,w) - var i, n=sts.length - if (typeof s == 'undefined') { - for (i=0; i<n; i++) {st=sts[i]; results.push(st.subject)} - } else if (typeof p == 'undefined') { - for (i=0; i<n; i++) {st=sts[i]; results.push(st.predicate)} - } else if (typeof o == 'undefined') { - for (i=0; i<n; i++) {st=sts[i]; results.push(st.object)} - } else if (typeof w == 'undefined') { - for (i=0; i<n; i++) {st=sts[i]; results.push(st.why)} +$rdf.Formula.prototype.each = function (s, p, o, w) { + var results = [] + var st, sts = this.statementsMatching(s, p, o, w, false) + var i, n = sts.length + if(typeof s == 'undefined') { + for(i = 0; i < n; i++) { + st = sts[i]; + results.push(st.subject) + } + } else if(typeof p == 'undefined') { + for(i = 0; i < n; i++) { + st = sts[i]; + results.push(st.predicate) } - return results + } else if(typeof o == 'undefined') { + for(i = 0; i < n; i++) { + st = sts[i]; + results.push(st.object) + } + } else if(typeof w == 'undefined') { + for(i = 0; i < n; i++) { + st = sts[i]; + results.push(st.why) + } + } + return results } -RDFFormula.prototype.any = function(s,p,o,w) { - var st = this.anyStatementMatching(s,p,o,w) - if (typeof st == 'undefined') return undefined; - - if (typeof s == 'undefined') return st.subject; - if (typeof p == 'undefined') return st.predicate; - if (typeof o == 'undefined') return st.object; +$rdf.Formula.prototype.any = function (s, p, o, w) { + var st = this.anyStatementMatching(s, p, o, w) + if(typeof st == 'undefined') return undefined; - return undefined -} + if(typeof s == 'undefined') return st.subject; + if(typeof p == 'undefined') return st.predicate; + if(typeof o == 'undefined') return st.object; -RDFFormula.prototype.the = function(s,p,o,w) { - // the() should contain a check there is only one - var x = this.any(s,p,o,w) - if (typeof x == 'undefined') - tabulator.log.error("No value found for the(){" + s + " " + p + " " + o + "}.") - return x + return undefined } -RDFFormula.prototype.whether = function(s,p,o,w) { - return this.statementsMatching(s,p,o,w).length; +$rdf.Formula.prototype.holds = function (s, p, o, w) { + var st = this.anyStatementMatching(s, p, o, w) + if(typeof st == 'undefined') return false; + return true; } - -// Not a method. For use in sorts -function RDFComparePredicateObject(self, other) { - var x = self.predicate.compareTerm(other.predicate) - if (x !=0) return x - return self.object.compareTerm(other.object) -} -function RDFComparePredicateSubject(self, other) { - var x = self.predicate.compareTerm(other.predicate) - if (x !=0) return x - return self.subject.compareTerm(other.subject) + +$rdf.Formula.prototype.the = function (s, p, o, w) { + // the() should contain a check there is only one + var x = this.any(s, p, o, w) + if(typeof x == 'undefined') + $rdf.log.error("No value found for the(){" + s + " " + p + " " + o + "}.") + return x } -// ends + +$rdf.Formula.prototype.whether = function (s, p, o, w) { + return this.statementsMatching(s, p, o, w, false).length; +} +\ No newline at end of file diff --git a/chrome/content/zotero/xpcom/rdf/n3parser.js b/chrome/content/zotero/xpcom/rdf/n3parser.js @@ -1,89 +1,98 @@ -// Things we need to define to make converted pythn code work in js -// environment of tabulator +$rdf.N3Parser = function () { -var RDFSink_forSomeSym = "http://www.w3.org/2000/10/swap/log#forSome"; -var RDFSink_forAllSym = "http://www.w3.org/2000/10/swap/log#forAll"; -var Logic_NS = "http://www.w3.org/2000/10/swap/log#"; + function hexify(str) { // also used in parser + return encodeURI(str); + } -// pyjs seems to reference runtime library which I didn't find + // Things we need to define to make converted pythn code work in js + // environment of $rdf + var RDFSink_forSomeSym = "http://www.w3.org/2000/10/swap/log#forSome"; + var RDFSink_forAllSym = "http://www.w3.org/2000/10/swap/log#forAll"; + var Logic_NS = "http://www.w3.org/2000/10/swap/log#"; -pyjslib_Tuple = function(theList) { return theList }; + // pyjs seems to reference runtime library which I didn't find + var pyjslib_Tuple = function (theList) { + return theList + }; -pyjslib_List = function(theList) { return theList }; + var pyjslib_List = function (theList) { + return theList + }; -pyjslib_Dict = function(listOfPairs) { - if (listOfPairs.length > 0) - throw "missing.js: oops nnonempty dict not imp"; - return []; -} - -pyjslib_len = function(s) { return s.length } - -pyjslib_slice = function(str, i, j) { - if (typeof str.slice == 'undefined') - throw '@@ mising.js: No .slice function for '+str+' of type '+(typeof str) - if ((typeof j == 'undefined') || (j ==null)) return str.slice(i); - return str.slice(i, j) // @ exactly the same spec? -} -StopIteration = Error('dummy error stop iteration') - -pyjslib_Iterator = function(theList) { - this.last = 0; - this.li = theList; - this.next = function() { - if (this.last == this.li.length) throw StopIteration; - return this.li[this.last++]; + var pyjslib_Dict = function (listOfPairs) { + if(listOfPairs.length > 0) + throw "missing.js: oops nnonempty dict not imp"; + return []; } - return this; -} -ord = function(str) { - return str.charCodeAt(0) -} + var pyjslib_len = function (s) { + return s.length + } -string_find = function(str, s) { - return str.indexOf(s) -} + var pyjslib_slice = function (str, i, j) { + if(typeof str.slice == 'undefined') + throw '@@ mising.js: No .slice function for ' + str + ' of type ' + (typeof str) + if((typeof j == 'undefined') || (j == null)) return str.slice(i); + return str.slice(i, j) // @ exactly the same spec? + } + var StopIteration = Error('dummy error stop iteration'); -assertFudge = function(condition, desc) { - if (condition) return; - if (desc) throw "python Assertion failed: "+desc; - throw "(python) Assertion failed."; -} + var pyjslib_Iterator = function (theList) { + this.last = 0; + this.li = theList; + this.next = function () { + if(this.last == this.li.length) throw StopIteration; + return this.li[this.last++]; + } + return this; + }; + var ord = function (str) { + return str.charCodeAt(0) + } -stringFromCharCode = function(uesc) { - return String.fromCharCode(uesc); -} + var string_find = function (str, s) { + return str.indexOf(s) + } + var assertFudge = function (condition, desc) { + if(condition) return; + if(desc) throw "python Assertion failed: " + desc; + throw "(python) Assertion failed."; + } -uripath_join = function(base, given) { - return Util.uri.join(given, base) // sad but true -} + var stringFromCharCode = function (uesc) { + return String.fromCharCode(uesc); + } -var becauseSubexpression = null; // No reason needed -var diag_tracking = 0; -var diag_chatty_flag = 0; -diag_progress = function(str) { tabulator.log.debug(str); } + var uripath_join = function (base, given) { + return $rdf.Util.uri.join(given, base) // sad but true + } -// why_BecauseOfData = function(doc, reason) { return doc }; + var becauseSubexpression = null; // No reason needed + var diag_tracking = 0; + var diag_chatty_flag = 0; + var diag_progress = function (str) { + /*$rdf.log.debug(str);*/ + } + // why_BecauseOfData = function(doc, reason) { return doc }; -RDF_type_URI = "http://www.w3.org/1999/02/22-rdf-syntax-ns#type"; -DAML_sameAs_URI = "http://www.w3.org/2002/07/owl#sameAs"; + var RDF_type_URI = "http://www.w3.org/1999/02/22-rdf-syntax-ns#type"; + var DAML_sameAs_URI = "http://www.w3.org/2002/07/owl#sameAs"; -/* + /* function SyntaxError(details) { return new __SyntaxError(details); } */ -function __SyntaxError(details) { + function __SyntaxError(details) { this.details = details -} + } -/* + /* $Id: n3parser.js 14561 2008-02-23 06:37:26Z kennyluck $ @@ -113,49 +122,51 @@ the module, including tests and test harness. */ -var ADDED_HASH = "#"; -var LOG_implies_URI = "http://www.w3.org/2000/10/swap/log#implies"; -var INTEGER_DATATYPE = "http://www.w3.org/2001/XMLSchema#integer"; -var FLOAT_DATATYPE = "http://www.w3.org/2001/XMLSchema#double"; -var DECIMAL_DATATYPE = "http://www.w3.org/2001/XMLSchema#decimal"; -var BOOLEAN_DATATYPE = "http://www.w3.org/2001/XMLSchema#boolean"; -var option_noregen = 0; -var _notQNameChars = "\t\r\n !\"#$%&'()*.,+/;<=>?@[\\]^`{|}~"; -var _notNameChars = ( _notQNameChars + ":" ) ; -var _rdfns = "http://www.w3.org/1999/02/22-rdf-syntax-ns#"; -var N3CommentCharacter = "#"; -var eol = new RegExp("^[ \\t]*(#[^\\n]*)?\\r?\\n", 'g'); -var eof = new RegExp("^[ \\t]*(#[^\\n]*)?$", 'g'); -var ws = new RegExp("^[ \\t]*", 'g'); -var signed_integer = new RegExp("^[-+]?[0-9]+", 'g'); -var number_syntax = new RegExp("^([-+]?[0-9]+)(\\.[0-9]+)?(e[-+]?[0-9]+)?", 'g'); -var digitstring = new RegExp("^[0-9]+", 'g'); -var interesting = new RegExp("[\\\\\\r\\n\\\"]", 'g'); -var langcode = new RegExp("^[a-zA-Z0-9]+(-[a-zA-Z0-9]+)?", 'g'); -function SinkParser(store, openFormula, thisDoc, baseURI, genPrefix, metaURI, flags, why) { + var ADDED_HASH = "#"; + var LOG_implies_URI = "http://www.w3.org/2000/10/swap/log#implies"; + var INTEGER_DATATYPE = "http://www.w3.org/2001/XMLSchema#integer"; + var FLOAT_DATATYPE = "http://www.w3.org/2001/XMLSchema#double"; + var DECIMAL_DATATYPE = "http://www.w3.org/2001/XMLSchema#decimal"; + var BOOLEAN_DATATYPE = "http://www.w3.org/2001/XMLSchema#boolean"; + var option_noregen = 0; + var _notQNameChars = "\t\r\n !\"#$%&'()*.,+/;<=>?@[\\]^`{|}~"; + var _notNameChars = (_notQNameChars + ":"); + var _rdfns = "http://www.w3.org/1999/02/22-rdf-syntax-ns#"; + var N3CommentCharacter = "#"; + var eol = new RegExp("^[ \\t]*(#[^\\n]*)?\\r?\\n", 'g'); + var eof = new RegExp("^[ \\t]*(#[^\\n]*)?$", 'g'); + var ws = new RegExp("^[ \\t]*", 'g'); + var signed_integer = new RegExp("^[-+]?[0-9]+", 'g'); + var number_syntax = new RegExp("^([-+]?[0-9]+)(\\.[0-9]+)?(e[-+]?[0-9]+)?", 'g'); + var digitstring = new RegExp("^[0-9]+", 'g'); + var interesting = new RegExp("[\\\\\\r\\n\\\"]", 'g'); + var langcode = new RegExp("^[a-zA-Z0-9]+(-[a-zA-Z0-9]+)?", 'g'); + + function SinkParser(store, openFormula, thisDoc, baseURI, genPrefix, metaURI, flags, why) { return new __SinkParser(store, openFormula, thisDoc, baseURI, genPrefix, metaURI, flags, why); -} -function __SinkParser(store, openFormula, thisDoc, baseURI, genPrefix, metaURI, flags, why) { - if (typeof openFormula == 'undefined') openFormula=null; - if (typeof thisDoc == 'undefined') thisDoc=""; - if (typeof baseURI == 'undefined') baseURI=null; - if (typeof genPrefix == 'undefined') genPrefix=""; - if (typeof metaURI == 'undefined') metaURI=null; - if (typeof flags == 'undefined') flags=""; - if (typeof why == 'undefined') why=null; + } + + function __SinkParser(store, openFormula, thisDoc, baseURI, genPrefix, metaURI, flags, why) { + if(typeof openFormula == 'undefined') openFormula = null; + if(typeof thisDoc == 'undefined') thisDoc = ""; + if(typeof baseURI == 'undefined') baseURI = null; + if(typeof genPrefix == 'undefined') genPrefix = ""; + if(typeof metaURI == 'undefined') metaURI = null; + if(typeof flags == 'undefined') flags = ""; + if(typeof why == 'undefined') why = null; /* note: namespace names should *not* end in #; the # will get added during qname processing */ - + this._bindings = new pyjslib_Dict([]); this._flags = flags; - if ((thisDoc != "")) { - assertFudge((thisDoc.indexOf(":") >= 0), ( "Document URI not absolute: " + thisDoc ) ); - this._bindings[""] = ( ( thisDoc + "#" ) ); + if((thisDoc != "")) { + assertFudge((thisDoc.indexOf(":") >= 0), ("Document URI not absolute: " + thisDoc)); + this._bindings[""] = ((thisDoc + "#")); } this._store = store; - if (genPrefix) { - store.setGenPrefix(genPrefix); + if(genPrefix) { + store.setGenPrefix(genPrefix); } this._thisDoc = thisDoc; this.source = store.sym(thisDoc); @@ -171,61 +182,56 @@ function __SinkParser(store, openFormula, thisDoc, baseURI, genPrefix, metaURI, this._parentVariables = new pyjslib_Dict([]); this._reason = why; this._reason2 = null; - if (diag_tracking) { - this._reason2 = why_BecauseOfData(store.sym(thisDoc), this._reason); - } - if (baseURI) { - this._baseURI = baseURI; - } - else { - if (thisDoc) { - this._baseURI = thisDoc; - } - else { - this._baseURI = null; - } + if(diag_tracking) { + this._reason2 = why_BecauseOfData(store.sym(thisDoc), this._reason); + } + if(baseURI) { + this._baseURI = baseURI; + } else { + if(thisDoc) { + this._baseURI = thisDoc; + } else { + this._baseURI = null; + } } assertFudge(!(this._baseURI) || (this._baseURI.indexOf(":") >= 0)); - if (!(this._genPrefix)) { - if (this._thisDoc) { - this._genPrefix = ( this._thisDoc + "#_g" ) ; - } - else { - this._genPrefix = RDFSink_uniqueURI(); - } - } - if ((openFormula == null)) { - if (this._thisDoc) { - this._formula = store.formula( ( thisDoc + "#_formula" ) ); - } - else { - this._formula = store.formula(); - } - } - else { - this._formula = openFormula; + if(!(this._genPrefix)) { + if(this._thisDoc) { + this._genPrefix = (this._thisDoc + "#_g"); + } else { + this._genPrefix = RDFSink_uniqueURI(); + } + } + if((openFormula == null)) { + if(this._thisDoc) { + this._formula = store.formula((thisDoc + "#_formula")); + } else { + this._formula = store.formula(); + } + } else { + this._formula = openFormula; } this._context = this._formula; this._parentContext = null; -} -__SinkParser.prototype.here = function(i) { - return ( ( ( ( this._genPrefix + "_L" ) + this.lines ) + "C" ) + ( ( i - this.startOfLine ) + 1 ) ) ; -}; -__SinkParser.prototype.formula = function() { + } + __SinkParser.prototype.here = function (i) { + return((((this._genPrefix + "_L") + this.lines) + "C") + ((i - this.startOfLine) + 1)); + }; + __SinkParser.prototype.formula = function () { return this._formula; -}; -__SinkParser.prototype.loadStream = function(stream) { + }; + __SinkParser.prototype.loadStream = function (stream) { return this.loadBuf(stream.read()); -}; -__SinkParser.prototype.loadBuf = function(buf) { + }; + __SinkParser.prototype.loadBuf = function (buf) { /* Parses a buffer and returns its top level formula*/ - + this.startDoc(); this.feed(buf); return this.endDoc(); -}; -__SinkParser.prototype.feed = function(octets) { + }; + __SinkParser.prototype.feed = function (octets) { /* Feed an octet stream tothe parser @@ -234,220 +240,212 @@ __SinkParser.prototype.feed = function(octets) { remainder after any statements have been parsed. So if there is more data to feed to the parser, it should be straightforward to recover.*/ - + var str = octets; var i = 0; - while ((i >= 0)) { - var j = this.skipSpace(str, i); - if ((j < 0)) { - return; - } - var i = this.directiveOrStatement(str, j); - if ((i < 0)) { - throw BadSyntax(this._thisDoc, this.lines, str, j, "expected directive or statement"); - } - } -}; -__SinkParser.prototype.directiveOrStatement = function(str, h) { + while((i >= 0)) { + var j = this.skipSpace(str, i); + if((j < 0)) { + return; + } + var i = this.directiveOrStatement(str, j); + if((i < 0)) { + throw BadSyntax(this._thisDoc, this.lines, str, j, "expected directive or statement"); + } + } + }; + __SinkParser.prototype.directiveOrStatement = function (str, h) { var i = this.skipSpace(str, h); - if ((i < 0)) { - return i; + if((i < 0)) { + return i; } var j = this.directive(str, i); - if ((j >= 0)) { - return this.checkDot(str, j); + if((j >= 0)) { + return this.checkDot(str, j); } var j = this.statement(str, i); - if ((j >= 0)) { - return this.checkDot(str, j); + if((j >= 0)) { + return this.checkDot(str, j); } return j; -}; -__SinkParser.prototype.tok = function(tok, str, i) { + }; + __SinkParser.prototype.tok = function (tok, str, i) { /* Check for keyword. Space must have been stripped on entry and we must not be at end of file.*/ - var whitespace = "\t\n\v\f\r "; - if ((pyjslib_slice(str, i, ( i + 1 ) ) == "@")) { - var i = ( i + 1 ) ; - } - else { - if ((this.keywords.indexOf(tok) < 0)) { - return -1; - } - } - var k = ( i + pyjslib_len(tok) ) ; - if ((pyjslib_slice(str, i, k) == tok) && (_notQNameChars.indexOf(str[k]) >= 0)) { - return k; - } - else { + if((pyjslib_slice(str, i, (i + 1)) == "@")) { + var i = (i + 1); + } else { + if(($rdf.Util.ArrayIndexOf(this.keywords, tok) < 0)) { return -1; + } + } + var k = (i + pyjslib_len(tok)); + if((pyjslib_slice(str, i, k) == tok) && (_notQNameChars.indexOf(str.charAt(k)) >= 0)) { + return k; + } else { + return -1; } -}; -__SinkParser.prototype.directive = function(str, i) { + }; + __SinkParser.prototype.directive = function (str, i) { var j = this.skipSpace(str, i); - if ((j < 0)) { - return j; + if((j < 0)) { + return j; } var res = new pyjslib_List([]); var j = this.tok("bind", str, i); - if ((j > 0)) { - throw BadSyntax(this._thisDoc, this.lines, str, i, "keyword bind is obsolete: use @prefix"); + if((j > 0)) { + throw BadSyntax(this._thisDoc, this.lines, str, i, "keyword bind is obsolete: use @prefix"); } var j = this.tok("keywords", str, i); - if ((j > 0)) { - var i = this.commaSeparatedList(str, j, res, false); - if ((i < 0)) { - throw BadSyntax(this._thisDoc, this.lines, str, i, "'@keywords' needs comma separated list of words"); - } - this.setKeywords(pyjslib_slice(res, null, null)); - if ((diag_chatty_flag > 80)) { - diag_progress("Keywords ", this.keywords); - } - return i; + if((j > 0)) { + var i = this.commaSeparatedList(str, j, res, false); + if((i < 0)) { + throw BadSyntax(this._thisDoc, this.lines, str, i, "'@keywords' needs comma separated list of words"); + } + this.setKeywords(pyjslib_slice(res, null, null)); + if((diag_chatty_flag > 80)) { + diag_progress("Keywords ", this.keywords); + } + return i; } var j = this.tok("forAll", str, i); - if ((j > 0)) { - var i = this.commaSeparatedList(str, j, res, true); - if ((i < 0)) { - throw BadSyntax(this._thisDoc, this.lines, str, i, "Bad variable list after @forAll"); + if((j > 0)) { + var i = this.commaSeparatedList(str, j, res, true); + if((i < 0)) { + throw BadSyntax(this._thisDoc, this.lines, str, i, "Bad variable list after @forAll"); + } + + var __x = new pyjslib_Iterator(res); + try { + while(true) { + var x = __x.next(); + + + if($rdf.Util.ArrayIndexOf(this._variables, x) < 0 || ($rdf.Util.ArrayIndexOf(this._parentVariables, x) >= 0)) { + this._variables[x] = (this._context.newUniversal(x)); + } + } - - var __x = new pyjslib_Iterator(res); - try { - while (true) { - var x = __x.next(); - - - if ((this._variables.indexOf(x) < 0) || (this._parentVariables.indexOf(x) >= 0)) { - this._variables[x] = ( this._context.newUniversal(x)); - } - - } - } catch (e) { - if (e != StopIteration) { - throw e; - } + } catch(e) { + if(e != StopIteration) { + throw e; } - - return i; + } + + return i; } var j = this.tok("forSome", str, i); - if ((j > 0)) { - var i = this.commaSeparatedList(str, j, res, this.uri_ref2); - if ((i < 0)) { - throw BadSyntax(this._thisDoc, this.lines, str, i, "Bad variable list after @forSome"); + if((j > 0)) { + var i = this.commaSeparatedList(str, j, res, this.uri_ref2); + if((i < 0)) { + throw BadSyntax(this._thisDoc, this.lines, str, i, "Bad variable list after @forSome"); + } + + var __x = new pyjslib_Iterator(res); + try { + while(true) { + var x = __x.next(); + + + this._context.declareExistential(x); + } - - var __x = new pyjslib_Iterator(res); - try { - while (true) { - var x = __x.next(); - - - this._context.declareExistential(x); - - } - } catch (e) { - if (e != StopIteration) { - throw e; - } + } catch(e) { + if(e != StopIteration) { + throw e; } - - return i; + } + + return i; } var j = this.tok("prefix", str, i); - if ((j >= 0)) { - var t = new pyjslib_List([]); - var i = this.qname(str, j, t); - if ((i < 0)) { - throw BadSyntax(this._thisDoc, this.lines, str, j, "expected qname after @prefix"); - } - var j = this.uri_ref2(str, i, t); - if ((j < 0)) { - throw BadSyntax(this._thisDoc, this.lines, str, i, "expected <uriref> after @prefix _qname_"); - } - var ns = t[1].uri; - if (this._baseURI) { - var ns = uripath_join(this._baseURI, ns); - } - else { - assertFudge((ns.indexOf(":") >= 0), "With no base URI, cannot handle relative URI for NS"); - } - assertFudge((ns.indexOf(":") >= 0)); - this._bindings[t[0][0]] = ( ns); - - this.bind(t[0][0], hexify(ns)); - return j; + if((j >= 0)) { + var t = new pyjslib_List([]); + var i = this.qname(str, j, t); + if((i < 0)) { + throw BadSyntax(this._thisDoc, this.lines, str, j, "expected qname after @prefix"); + } + var j = this.uri_ref2(str, i, t); + if((j < 0)) { + throw BadSyntax(this._thisDoc, this.lines, str, i, "expected <uriref> after @prefix _qname_"); + } + var ns = t[1].uri; + if(this._baseURI) { + var ns = uripath_join(this._baseURI, ns); + } else { + assertFudge((ns.indexOf(":") >= 0), "With no base URI, cannot handle relative URI for NS"); + } + assertFudge((ns.indexOf(":") >= 0)); + this._bindings[t[0][0]] = (ns); + + this.bind(t[0][0], hexify(ns)); + return j; } var j = this.tok("base", str, i); - if ((j >= 0)) { - var t = new pyjslib_List([]); - var i = this.uri_ref2(str, j, t); - if ((i < 0)) { - throw BadSyntax(this._thisDoc, this.lines, str, j, "expected <uri> after @base "); - } - var ns = t[0].uri; - if (this._baseURI) { - var ns = uripath_join(this._baseURI, ns); - } - else { - throw BadSyntax(this._thisDoc, this.lines, str, j, ( ( "With no previous base URI, cannot use relative URI in @base <" + ns ) + ">" ) ); - } - assertFudge((ns.indexOf(":") >= 0)); - this._baseURI = ns; - return i; + if((j >= 0)) { + var t = new pyjslib_List([]); + var i = this.uri_ref2(str, j, t); + if((i < 0)) { + throw BadSyntax(this._thisDoc, this.lines, str, j, "expected <uri> after @base "); + } + var ns = t[0].uri; + if(this._baseURI) { + var ns = uripath_join(this._baseURI, ns); + } else { + throw BadSyntax(this._thisDoc, this.lines, str, j, (("With no previous base URI, cannot use relative URI in @base <" + ns) + ">")); + } + assertFudge((ns.indexOf(":") >= 0)); + this._baseURI = ns; + return i; } return -1; -}; -__SinkParser.prototype.bind = function(qn, uri) { - if ((qn == "")) { - } - else { - this._store.setPrefixForURI(qn, uri); - } -}; -__SinkParser.prototype.setKeywords = function(k) { + }; + __SinkParser.prototype.bind = function (qn, uri) { + if((qn == "")) { + } else { + this._store.setPrefixForURI(qn, uri); + } + }; + __SinkParser.prototype.setKeywords = function (k) { /* Takes a list of strings*/ - - if ((k == null)) { - this.keywordsSet = 0; - } - else { - this.keywords = k; - this.keywordsSet = 1; - } -}; -__SinkParser.prototype.startDoc = function() { -}; -__SinkParser.prototype.endDoc = function() { + + if((k == null)) { + this.keywordsSet = 0; + } else { + this.keywords = k; + this.keywordsSet = 1; + } + }; + __SinkParser.prototype.startDoc = function () {}; + __SinkParser.prototype.endDoc = function () { /* Signal end of document and stop parsing. returns formula*/ - + return this._formula; -}; -__SinkParser.prototype.makeStatement = function(quad) { + }; + __SinkParser.prototype.makeStatement = function (quad) { quad[0].add(quad[2], quad[1], quad[3], this.source); this.statementCount += 1; -}; -__SinkParser.prototype.statement = function(str, i) { + }; + __SinkParser.prototype.statement = function (str, i) { var r = new pyjslib_List([]); var i = this.object(str, i, r); - if ((i < 0)) { - return i; + if((i < 0)) { + return i; } var j = this.property_list(str, i, r[0]); - if ((j < 0)) { - throw BadSyntax(this._thisDoc, this.lines, str, i, "expected propertylist"); + if((j < 0)) { + throw BadSyntax(this._thisDoc, this.lines, str, i, "expected propertylist"); } return j; -}; -__SinkParser.prototype.subject = function(str, i, res) { + }; + __SinkParser.prototype.subject = function (str, i, res) { return this.item(str, i, res); -}; -__SinkParser.prototype.verb = function(str, i, res) { + }; + __SinkParser.prototype.verb = function (str, i, res) { /* has _prop_ is _prop_ of @@ -457,398 +455,392 @@ __SinkParser.prototype.verb = function(str, i, res) { >- prop -> <- prop -< _operator_*/ - + var j = this.skipSpace(str, i); - if ((j < 0)) { - return j; + if((j < 0)) { + return j; } var r = new pyjslib_List([]); var j = this.tok("has", str, i); - if ((j >= 0)) { - var i = this.prop(str, j, r); - if ((i < 0)) { - throw BadSyntax(this._thisDoc, this.lines, str, j, "expected property after 'has'"); - } - res.push(new pyjslib_Tuple(["->", r[0]])); - return i; + if((j >= 0)) { + var i = this.prop(str, j, r); + if((i < 0)) { + throw BadSyntax(this._thisDoc, this.lines, str, j, "expected property after 'has'"); + } + res.push(new pyjslib_Tuple(["->", r[0]])); + return i; } var j = this.tok("is", str, i); - if ((j >= 0)) { - var i = this.prop(str, j, r); - if ((i < 0)) { - throw BadSyntax(this._thisDoc, this.lines, str, j, "expected <property> after 'is'"); - } - var j = this.skipSpace(str, i); - if ((j < 0)) { - throw BadSyntax(this._thisDoc, this.lines, str, i, "End of file found, expected property after 'is'"); - return j; - } - var i = j; - var j = this.tok("of", str, i); - if ((j < 0)) { - throw BadSyntax(this._thisDoc, this.lines, str, i, "expected 'of' after 'is' <prop>"); - } - res.push(new pyjslib_Tuple(["<-", r[0]])); + if((j >= 0)) { + var i = this.prop(str, j, r); + if((i < 0)) { + throw BadSyntax(this._thisDoc, this.lines, str, j, "expected <property> after 'is'"); + } + var j = this.skipSpace(str, i); + if((j < 0)) { + throw BadSyntax(this._thisDoc, this.lines, str, i, "End of file found, expected property after 'is'"); return j; + } + var i = j; + var j = this.tok("of", str, i); + if((j < 0)) { + throw BadSyntax(this._thisDoc, this.lines, str, i, "expected 'of' after 'is' <prop>"); + } + res.push(new pyjslib_Tuple(["<-", r[0]])); + return j; } var j = this.tok("a", str, i); - if ((j >= 0)) { - res.push(new pyjslib_Tuple(["->", this._store.sym(RDF_type_URI)])); - return j; - } - if ((pyjslib_slice(str, i, ( i + 2 ) ) == "<=")) { - res.push(new pyjslib_Tuple(["<-", this._store.sym( ( Logic_NS + "implies" ) )])); - return ( i + 2 ) ; - } - if ((pyjslib_slice(str, i, ( i + 1 ) ) == "=")) { - if ((pyjslib_slice(str, ( i + 1 ) , ( i + 2 ) ) == ">")) { - res.push(new pyjslib_Tuple(["->", this._store.sym( ( Logic_NS + "implies" ) )])); - return ( i + 2 ) ; - } - res.push(new pyjslib_Tuple(["->", this._store.sym(DAML_sameAs_URI)])); - return ( i + 1 ) ; - } - if ((pyjslib_slice(str, i, ( i + 2 ) ) == ":=")) { - res.push(new pyjslib_Tuple(["->", ( Logic_NS + "becomes" ) ])); - return ( i + 2 ) ; + if((j >= 0)) { + res.push(new pyjslib_Tuple(["->", this._store.sym(RDF_type_URI)])); + return j; + } + if((pyjslib_slice(str, i, (i + 2)) == "<=")) { + res.push(new pyjslib_Tuple(["<-", this._store.sym((Logic_NS + "implies"))])); + return(i + 2); + } + if((pyjslib_slice(str, i, (i + 1)) == "=")) { + if((pyjslib_slice(str, (i + 1), (i + 2)) == ">")) { + res.push(new pyjslib_Tuple(["->", this._store.sym((Logic_NS + "implies"))])); + return(i + 2); + } + res.push(new pyjslib_Tuple(["->", this._store.sym(DAML_sameAs_URI)])); + return(i + 1); + } + if((pyjslib_slice(str, i, (i + 2)) == ":=")) { + res.push(new pyjslib_Tuple(["->", (Logic_NS + "becomes")])); + return(i + 2); } var j = this.prop(str, i, r); - if ((j >= 0)) { - res.push(new pyjslib_Tuple(["->", r[0]])); - return j; + if((j >= 0)) { + res.push(new pyjslib_Tuple(["->", r[0]])); + return j; } - if ((pyjslib_slice(str, i, ( i + 2 ) ) == ">-") || (pyjslib_slice(str, i, ( i + 2 ) ) == "<-")) { - throw BadSyntax(this._thisDoc, this.lines, str, j, ">- ... -> syntax is obsolete."); + if((pyjslib_slice(str, i, (i + 2)) == ">-") || (pyjslib_slice(str, i, (i + 2)) == "<-")) { + throw BadSyntax(this._thisDoc, this.lines, str, j, ">- ... -> syntax is obsolete."); } return -1; -}; -__SinkParser.prototype.prop = function(str, i, res) { + }; + __SinkParser.prototype.prop = function (str, i, res) { return this.item(str, i, res); -}; -__SinkParser.prototype.item = function(str, i, res) { + }; + __SinkParser.prototype.item = function (str, i, res) { return this.path(str, i, res); -}; -__SinkParser.prototype.blankNode = function(uri) { + }; + __SinkParser.prototype.blankNode = function (uri) { return this._context.bnode(uri, this._reason2); -}; -__SinkParser.prototype.path = function(str, i, res) { + }; + __SinkParser.prototype.path = function (str, i, res) { /* Parse the path production. */ - + var j = this.nodeOrLiteral(str, i, res); - if ((j < 0)) { - return j; - } - while (("!^.".indexOf(pyjslib_slice(str, j, ( j + 1 ) )) >= 0)) { - var ch = pyjslib_slice(str, j, ( j + 1 ) ); - if ((ch == ".")) { - var ahead = pyjslib_slice(str, ( j + 1 ) , ( j + 2 ) ); - if (!(ahead) || (_notNameChars.indexOf(ahead) >= 0) && (":?<[{(".indexOf(ahead) < 0)) { - break; - } - } - var subj = res.pop(); - var obj = this.blankNode(this.here(j)); - var j = this.node(str, ( j + 1 ) , res); - if ((j < 0)) { - throw BadSyntax(this._thisDoc, this.lines, str, j, "EOF found in middle of path syntax"); - } - var pred = res.pop(); - if ((ch == "^")) { - this.makeStatement(new pyjslib_Tuple([this._context, pred, obj, subj])); - } - else { - this.makeStatement(new pyjslib_Tuple([this._context, pred, subj, obj])); - } - res.push(obj); + if((j < 0)) { + return j; + } + while(("!^.".indexOf(pyjslib_slice(str, j, (j + 1))) >= 0)) { + var ch = pyjslib_slice(str, j, (j + 1)); + if((ch == ".")) { + var ahead = pyjslib_slice(str, (j + 1), (j + 2)); + if(!(ahead) || (_notNameChars.indexOf(ahead) >= 0) && (":?<[{(".indexOf(ahead) < 0)) { + break; + } + } + var subj = res.pop(); + var obj = this.blankNode(this.here(j)); + var j = this.node(str, (j + 1), res); + if((j < 0)) { + throw BadSyntax(this._thisDoc, this.lines, str, j, "EOF found in middle of path syntax"); + } + var pred = res.pop(); + if((ch == "^")) { + this.makeStatement(new pyjslib_Tuple([this._context, pred, obj, subj])); + } else { + this.makeStatement(new pyjslib_Tuple([this._context, pred, subj, obj])); + } + res.push(obj); } return j; -}; -__SinkParser.prototype.anonymousNode = function(ln) { + }; + __SinkParser.prototype.anonymousNode = function (ln) { /* Remember or generate a term for one of these _: anonymous nodes*/ - + var term = this._anonymousNodes[ln]; - if (term) { - return term; + if(term) { + return term; } var term = this._store.bnode(this._context, this._reason2); - this._anonymousNodes[ln] = ( term); + this._anonymousNodes[ln] = (term); return term; -}; -__SinkParser.prototype.node = function(str, i, res, subjectAlready) { - if (typeof subjectAlready == 'undefined') subjectAlready=null; + }; + __SinkParser.prototype.node = function (str, i, res, subjectAlready) { + if(typeof subjectAlready == 'undefined') subjectAlready = null; /* Parse the <node> production. Space is now skipped once at the beginning instead of in multipe calls to self.skipSpace(). */ - + var subj = subjectAlready; var j = this.skipSpace(str, i); - if ((j < 0)) { - return j; + if((j < 0)) { + return j; } var i = j; - var ch = pyjslib_slice(str, i, ( i + 1 ) ); - if ((ch == "[")) { - var bnodeID = this.here(i); - var j = this.skipSpace(str, ( i + 1 ) ); - if ((j < 0)) { - throw BadSyntax(this._thisDoc, this.lines, str, i, "EOF after '['"); - } - if ((pyjslib_slice(str, j, ( j + 1 ) ) == "=")) { - var i = ( j + 1 ) ; - var objs = new pyjslib_List([]); - var j = this.objectList(str, i, objs); - - if ((j >= 0)) { - var subj = objs[0]; - if ((pyjslib_len(objs) > 1)) { - - var __obj = new pyjslib_Iterator(objs); - try { - while (true) { - var obj = __obj.next(); - - - this.makeStatement(new pyjslib_Tuple([this._context, this._store.sym(DAML_sameAs_URI), subj, obj])); - - } - } catch (e) { - if (e != StopIteration) { - throw e; - } - } - - } - var j = this.skipSpace(str, j); - if ((j < 0)) { - throw BadSyntax(this._thisDoc, this.lines, str, i, "EOF when objectList expected after [ = "); - } - if ((pyjslib_slice(str, j, ( j + 1 ) ) == ";")) { - var j = ( j + 1 ) ; - } - } - else { - throw BadSyntax(this._thisDoc, this.lines, str, i, "objectList expected after [= "); - } - } - if ((subj == null)) { - var subj = this.blankNode(bnodeID); - } - var i = this.property_list(str, j, subj); - if ((i < 0)) { - throw BadSyntax(this._thisDoc, this.lines, str, j, "property_list expected"); - } - var j = this.skipSpace(str, i); - if ((j < 0)) { - throw BadSyntax(this._thisDoc, this.lines, str, i, "EOF when ']' expected after [ <propertyList>"); - } - if ((pyjslib_slice(str, j, ( j + 1 ) ) != "]")) { - throw BadSyntax(this._thisDoc, this.lines, str, j, "']' expected"); - } - res.push(subj); - return ( j + 1 ) ; - } - if ((ch == "{")) { - var ch2 = pyjslib_slice(str, ( i + 1 ) , ( i + 2 ) ); - if ((ch2 == "$")) { - i += 1; - var j = ( i + 1 ) ; - var mylist = new pyjslib_List([]); - var first_run = true; - while (1) { - var i = this.skipSpace(str, j); - if ((i < 0)) { - throw BadSyntax(this._thisDoc, this.lines, str, i, "needed '$}', found end."); - } - if ((pyjslib_slice(str, i, ( i + 2 ) ) == "$}")) { - var j = ( i + 2 ) ; - break; - } - if (!(first_run)) { - if ((pyjslib_slice(str, i, ( i + 1 ) ) == ",")) { - i += 1; - } - else { - throw BadSyntax(this._thisDoc, this.lines, str, i, "expected: ','"); - } - } - else { - var first_run = false; - } - var item = new pyjslib_List([]); - var j = this.item(str, i, item); - if ((j < 0)) { - throw BadSyntax(this._thisDoc, this.lines, str, i, "expected item in set or '$}'"); - } - mylist.push(item[0]); - } - res.push(this._store.newSet(mylist, this._context)); - return j; - } - else { - var j = ( i + 1 ) ; - var oldParentContext = this._parentContext; - this._parentContext = this._context; - var parentAnonymousNodes = this._anonymousNodes; - var grandParentVariables = this._parentVariables; - this._parentVariables = this._variables; - this._anonymousNodes = new pyjslib_Dict([]); - this._variables = this._variables.slice(); - var reason2 = this._reason2; - this._reason2 = becauseSubexpression; - if ((subj == null)) { - var subj = this._store.formula(); - } - this._context = subj; - while (1) { - var i = this.skipSpace(str, j); - if ((i < 0)) { - throw BadSyntax(this._thisDoc, this.lines, str, i, "needed '}', found end."); - } - if ((pyjslib_slice(str, i, ( i + 1 ) ) == "}")) { - var j = ( i + 1 ) ; - break; - } - var j = this.directiveOrStatement(str, i); - if ((j < 0)) { - throw BadSyntax(this._thisDoc, this.lines, str, i, "expected statement or '}'"); - } + var ch = pyjslib_slice(str, i, (i + 1)); + if((ch == "[")) { + var bnodeID = this.here(i); + var j = this.skipSpace(str, (i + 1)); + if((j < 0)) { + throw BadSyntax(this._thisDoc, this.lines, str, i, "EOF after '['"); + } + if((pyjslib_slice(str, j, (j + 1)) == "=")) { + var i = (j + 1); + var objs = new pyjslib_List([]); + var j = this.objectList(str, i, objs); + + if((j >= 0)) { + var subj = objs[0]; + if((pyjslib_len(objs) > 1)) { + + var __obj = new pyjslib_Iterator(objs); + try { + while(true) { + var obj = __obj.next(); + + + this.makeStatement(new pyjslib_Tuple([this._context, this._store.sym(DAML_sameAs_URI), subj, obj])); + + } + } catch(e) { + if(e != StopIteration) { + throw e; + } } - this._anonymousNodes = parentAnonymousNodes; - this._variables = this._parentVariables; - this._parentVariables = grandParentVariables; - this._context = this._parentContext; - this._reason2 = reason2; - this._parentContext = oldParentContext; - res.push(subj.close()); - return j; - } - } - if ((ch == "(")) { - var thing_type = this._store.list; - var ch2 = pyjslib_slice(str, ( i + 1 ) , ( i + 2 ) ); - if ((ch2 == "$")) { - var thing_type = this._store.newSet; - i += 1; - } - var j = ( i + 1 ) ; + + } + var j = this.skipSpace(str, j); + if((j < 0)) { + throw BadSyntax(this._thisDoc, this.lines, str, i, "EOF when objectList expected after [ = "); + } + if((pyjslib_slice(str, j, (j + 1)) == ";")) { + var j = (j + 1); + } + } else { + throw BadSyntax(this._thisDoc, this.lines, str, i, "objectList expected after [= "); + } + } + if((subj == null)) { + var subj = this.blankNode(bnodeID); + } + var i = this.property_list(str, j, subj); + if((i < 0)) { + throw BadSyntax(this._thisDoc, this.lines, str, j, "property_list expected"); + } + var j = this.skipSpace(str, i); + if((j < 0)) { + throw BadSyntax(this._thisDoc, this.lines, str, i, "EOF when ']' expected after [ <propertyList>"); + } + if((pyjslib_slice(str, j, (j + 1)) != "]")) { + throw BadSyntax(this._thisDoc, this.lines, str, j, "']' expected"); + } + res.push(subj); + return(j + 1); + } + if((ch == "{")) { + var ch2 = pyjslib_slice(str, (i + 1), (i + 2)); + if((ch2 == "$")) { + i += 1; + var j = (i + 1); var mylist = new pyjslib_List([]); - while (1) { - var i = this.skipSpace(str, j); - if ((i < 0)) { - throw BadSyntax(this._thisDoc, this.lines, str, i, "needed ')', found end."); - } - if ((pyjslib_slice(str, i, ( i + 1 ) ) == ")")) { - var j = ( i + 1 ) ; - break; - } - var item = new pyjslib_List([]); - var j = this.item(str, i, item); - if ((j < 0)) { - throw BadSyntax(this._thisDoc, this.lines, str, i, "expected item in list or ')'"); + var first_run = true; + while(1) { + var i = this.skipSpace(str, j); + if((i < 0)) { + throw BadSyntax(this._thisDoc, this.lines, str, i, "needed '$}', found end."); + } + if((pyjslib_slice(str, i, (i + 2)) == "$}")) { + var j = (i + 2); + break; + } + if(!(first_run)) { + if((pyjslib_slice(str, i, (i + 1)) == ",")) { + i += 1; + } else { + throw BadSyntax(this._thisDoc, this.lines, str, i, "expected: ','"); } - mylist.push(item[0]); - } - res.push(thing_type(mylist, this._context)); + } else { + var first_run = false; + } + var item = new pyjslib_List([]); + var j = this.item(str, i, item); + if((j < 0)) { + throw BadSyntax(this._thisDoc, this.lines, str, i, "expected item in set or '$}'"); + } + mylist.push(item[0]); + } + res.push(this._store.newSet(mylist, this._context)); return j; + } else { + var j = (i + 1); + var oldParentContext = this._parentContext; + this._parentContext = this._context; + var parentAnonymousNodes = this._anonymousNodes; + var grandParentVariables = this._parentVariables; + this._parentVariables = this._variables; + this._anonymousNodes = new pyjslib_Dict([]); + this._variables = this._variables.slice(); + var reason2 = this._reason2; + this._reason2 = becauseSubexpression; + if((subj == null)) { + var subj = this._store.formula(); + } + this._context = subj; + while(1) { + var i = this.skipSpace(str, j); + if((i < 0)) { + throw BadSyntax(this._thisDoc, this.lines, str, i, "needed '}', found end."); + } + if((pyjslib_slice(str, i, (i + 1)) == "}")) { + var j = (i + 1); + break; + } + var j = this.directiveOrStatement(str, i); + if((j < 0)) { + throw BadSyntax(this._thisDoc, this.lines, str, i, "expected statement or '}'"); + } + } + this._anonymousNodes = parentAnonymousNodes; + this._variables = this._parentVariables; + this._parentVariables = grandParentVariables; + this._context = this._parentContext; + this._reason2 = reason2; + this._parentContext = oldParentContext; + res.push(subj.close()); + return j; + } + } + if((ch == "(")) { + var thing_type = this._store.list; + var ch2 = pyjslib_slice(str, (i + 1), (i + 2)); + if((ch2 == "$")) { + var thing_type = this._store.newSet; + i += 1; + } + var j = (i + 1); + var mylist = new pyjslib_List([]); + while(1) { + var i = this.skipSpace(str, j); + if((i < 0)) { + throw BadSyntax(this._thisDoc, this.lines, str, i, "needed ')', found end."); + } + if((pyjslib_slice(str, i, (i + 1)) == ")")) { + var j = (i + 1); + break; + } + var item = new pyjslib_List([]); + var j = this.item(str, i, item); + if((j < 0)) { + throw BadSyntax(this._thisDoc, this.lines, str, i, "expected item in list or ')'"); + } + mylist.push(item[0]); + } + res.push(thing_type(mylist, this._context)); + return j; } var j = this.tok("this", str, i); - if ((j >= 0)) { - throw BadSyntax(this._thisDoc, this.lines, str, i, "Keyword 'this' was ancient N3. Now use @forSome and @forAll keywords."); - res.push(this._context); - return j; + if((j >= 0)) { + throw BadSyntax(this._thisDoc, this.lines, str, i, "Keyword 'this' was ancient N3. Now use @forSome and @forAll keywords."); + res.push(this._context); + return j; } var j = this.tok("true", str, i); - if ((j >= 0)) { - res.push(true); - return j; + if((j >= 0)) { + res.push(true); + return j; } var j = this.tok("false", str, i); - if ((j >= 0)) { - res.push(false); - return j; + if((j >= 0)) { + res.push(false); + return j; } - if ((subj == null)) { - var j = this.uri_ref2(str, i, res); - if ((j >= 0)) { - return j; - } + if((subj == null)) { + var j = this.uri_ref2(str, i, res); + if((j >= 0)) { + return j; + } } return -1; -}; -__SinkParser.prototype.property_list = function(str, i, subj) { + }; + __SinkParser.prototype.property_list = function (str, i, subj) { /* Parse property list Leaves the terminating punctuation in the buffer */ - - while (1) { - var j = this.skipSpace(str, i); - if ((j < 0)) { - throw BadSyntax(this._thisDoc, this.lines, str, i, "EOF found when expected verb in property list"); - return j; - } - if ((pyjslib_slice(str, j, ( j + 2 ) ) == ":-")) { - var i = ( j + 2 ) ; - var res = new pyjslib_List([]); - var j = this.node(str, i, res, subj); - if ((j < 0)) { - throw BadSyntax(this._thisDoc, this.lines, str, i, "bad {} or () or [] node after :- "); - } - var i = j; - continue; + + while(1) { + var j = this.skipSpace(str, i); + if((j < 0)) { + throw BadSyntax(this._thisDoc, this.lines, str, i, "EOF found when expected verb in property list"); + return j; + } + if((pyjslib_slice(str, j, (j + 2)) == ":-")) { + var i = (j + 2); + var res = new pyjslib_List([]); + var j = this.node(str, i, res, subj); + if((j < 0)) { + throw BadSyntax(this._thisDoc, this.lines, str, i, "bad {} or () or [] node after :- "); } var i = j; - var v = new pyjslib_List([]); - var j = this.verb(str, i, v); - if ((j <= 0)) { - return i; - } - var objs = new pyjslib_List([]); - var i = this.objectList(str, j, objs); - if ((i < 0)) { - throw BadSyntax(this._thisDoc, this.lines, str, j, "objectList expected"); - } - - var __obj = new pyjslib_Iterator(objs); - try { - while (true) { - var obj = __obj.next(); - - - var pairFudge = v[0]; - var dir = pairFudge[0]; - var sym = pairFudge[1]; - if ((dir == "->")) { - this.makeStatement(new pyjslib_Tuple([this._context, sym, subj, obj])); - } - else { - this.makeStatement(new pyjslib_Tuple([this._context, sym, obj, subj])); - } - - } - } catch (e) { - if (e != StopIteration) { - throw e; - } - } - - var j = this.skipSpace(str, i); - if ((j < 0)) { - throw BadSyntax(this._thisDoc, this.lines, str, j, "EOF found in list of objects"); - return j; + continue; + } + var i = j; + var v = new pyjslib_List([]); + var j = this.verb(str, i, v); + if((j <= 0)) { + return i; + } + var objs = new pyjslib_List([]); + var i = this.objectList(str, j, objs); + if((i < 0)) { + throw BadSyntax(this._thisDoc, this.lines, str, j, "objectList expected"); + } + + var __obj = new pyjslib_Iterator(objs); + try { + while(true) { + var obj = __obj.next(); + + + var pairFudge = v[0]; + var dir = pairFudge[0]; + var sym = pairFudge[1]; + if((dir == "->")) { + this.makeStatement(new pyjslib_Tuple([this._context, sym, subj, obj])); + } else { + this.makeStatement(new pyjslib_Tuple([this._context, sym, obj, subj])); + } + } - if ((pyjslib_slice(str, i, ( i + 1 ) ) != ";")) { - return i; + } catch(e) { + if(e != StopIteration) { + throw e; } - var i = ( i + 1 ) ; + } + + var j = this.skipSpace(str, i); + if((j < 0)) { + throw BadSyntax(this._thisDoc, this.lines, str, j, "EOF found in list of objects"); + return j; + } + if((pyjslib_slice(str, i, (i + 1)) != ";")) { + return i; + } + var i = (i + 1); } -}; -__SinkParser.prototype.commaSeparatedList = function(str, j, res, ofUris) { + }; + __SinkParser.prototype.commaSeparatedList = function (str, j, res, ofUris) { /* return value: -1 bad syntax; >1 new position in str res has things found appended @@ -856,86 +848,84 @@ __SinkParser.prototype.commaSeparatedList = function(str, j, res, ofUris) { Used to use a final value of the function to be called, e.g. this.bareWord but passing the function didn't work fo js converion pyjs */ - + var i = this.skipSpace(str, j); - if ((i < 0)) { - throw BadSyntax(this._thisDoc, this.lines, str, i, "EOF found expecting comma sep list"); - return i; + if((i < 0)) { + throw BadSyntax(this._thisDoc, this.lines, str, i, "EOF found expecting comma sep list"); + return i; } - if ((str[i] == ".")) { - return j; - } - if (ofUris) { - var i = this.uri_ref2(str, i, res); + if((str.charAt(i) == ".")) { + return j; } - else { - var i = this.bareWord(str, i, res); + if(ofUris) { + var i = this.uri_ref2(str, i, res); + } else { + var i = this.bareWord(str, i, res); } - if ((i < 0)) { - return -1; + if((i < 0)) { + return -1; } - while (1) { - var j = this.skipSpace(str, i); - if ((j < 0)) { - return j; - } - var ch = pyjslib_slice(str, j, ( j + 1 ) ); - if ((ch != ",")) { - if ((ch != ".")) { - return -1; - } - return j; - } - if (ofUris) { - var i = this.uri_ref2(str, ( j + 1 ) , res); - } - else { - var i = this.bareWord(str, ( j + 1 ) , res); - } - if ((i < 0)) { - throw BadSyntax(this._thisDoc, this.lines, str, i, "bad list content"); - return i; + while(1) { + var j = this.skipSpace(str, i); + if((j < 0)) { + return j; + } + var ch = pyjslib_slice(str, j, (j + 1)); + if((ch != ",")) { + if((ch != ".")) { + return -1; } + return j; + } + if(ofUris) { + var i = this.uri_ref2(str, (j + 1), res); + } else { + var i = this.bareWord(str, (j + 1), res); + } + if((i < 0)) { + throw BadSyntax(this._thisDoc, this.lines, str, i, "bad list content"); + return i; + } } -}; -__SinkParser.prototype.objectList = function(str, i, res) { + }; + __SinkParser.prototype.objectList = function (str, i, res) { var i = this.object(str, i, res); - if ((i < 0)) { - return -1; + if((i < 0)) { + return -1; } - while (1) { - var j = this.skipSpace(str, i); - if ((j < 0)) { - throw BadSyntax(this._thisDoc, this.lines, str, j, "EOF found after object"); - return j; - } - if ((pyjslib_slice(str, j, ( j + 1 ) ) != ",")) { - return j; - } - var i = this.object(str, ( j + 1 ) , res); - if ((i < 0)) { - return i; - } + while(1) { + var j = this.skipSpace(str, i); + if((j < 0)) { + throw BadSyntax(this._thisDoc, this.lines, str, j, "EOF found after object"); + return j; + } + if((pyjslib_slice(str, j, (j + 1)) != ",")) { + return j; + } + var i = this.object(str, (j + 1), res); + if((i < 0)) { + return i; + } } -}; -__SinkParser.prototype.checkDot = function(str, i) { + }; + __SinkParser.prototype.checkDot = function (str, i) { var j = this.skipSpace(str, i); - if ((j < 0)) { - return j; + if((j < 0)) { + return j; } - if ((pyjslib_slice(str, j, ( j + 1 ) ) == ".")) { - return ( j + 1 ) ; + if((pyjslib_slice(str, j, (j + 1)) == ".")) { + return(j + 1); } - if ((pyjslib_slice(str, j, ( j + 1 ) ) == "}")) { - return j; + if((pyjslib_slice(str, j, (j + 1)) == "}")) { + return j; } - if ((pyjslib_slice(str, j, ( j + 1 ) ) == "]")) { - return j; + if((pyjslib_slice(str, j, (j + 1)) == "]")) { + return j; } throw BadSyntax(this._thisDoc, this.lines, str, j, "expected '.' or '}' or ']' at end of statement"); return i; -}; -__SinkParser.prototype.uri_ref2 = function(str, i, res) { + }; + __SinkParser.prototype.uri_ref2 = function (str, i, res) { /* Generate uri from n3 representation. @@ -943,481 +933,452 @@ __SinkParser.prototype.uri_ref2 = function(str, i, res) { NS and local name is now used though I prefer inserting a '#' to make the namesapces look more like what XML folks expect. */ - + var qn = new pyjslib_List([]); var j = this.qname(str, i, qn); - if ((j >= 0)) { - var pairFudge = qn[0]; - var pfx = pairFudge[0]; - var ln = pairFudge[1]; - if ((pfx == null)) { - assertFudge(0, "not used?"); - var ns = ( this._baseURI + ADDED_HASH ) ; - } - else { - var ns = this._bindings[pfx]; - if (!(ns)) { - if ((pfx == "_")) { - res.push(this.anonymousNode(ln)); - return j; - } - throw BadSyntax(this._thisDoc, this.lines, str, i, ( ( "Prefix " + pfx ) + " not bound." ) ); - } - } - var symb = this._store.sym( ( ns + ln ) ); - if ((this._variables.indexOf(symb) >= 0)) { - res.push(this._variables[symb]); - } - else { - res.push(symb); - } - return j; - } - var i = this.skipSpace(str, i); - if ((i < 0)) { - return -1; - } - if ((str[i] == "?")) { - var v = new pyjslib_List([]); - var j = this.variable(str, i, v); - if ((j > 0)) { - res.push(v[0]); + if((j >= 0)) { + var pairFudge = qn[0]; + var pfx = pairFudge[0]; + var ln = pairFudge[1]; + if((pfx == null)) { + assertFudge(0, "not used?"); + var ns = (this._baseURI + ADDED_HASH); + } else { + var ns = this._bindings[pfx]; + if(!(ns)) { + if((pfx == "_")) { + res.push(this.anonymousNode(ln)); return j; - } - return -1; - } - else if ((str[i] == "<")) { - var i = ( i + 1 ) ; - var st = i; - while ((i < pyjslib_len(str))) { - if ((str[i] == ">")) { - var uref = pyjslib_slice(str, st, i); - if (this._baseURI) { - var uref = uripath_join(this._baseURI, uref); - } - else { - assertFudge((uref.indexOf(":") >= 0), "With no base URI, cannot deal with relative URIs"); - } - if ((pyjslib_slice(str, ( i - 1 ) , i) == "#") && !((pyjslib_slice(uref, -1, null) == "#"))) { - var uref = ( uref + "#" ) ; - } - var symb = this._store.sym(uref); - if ((this._variables.indexOf(symb) >= 0)) { - res.push(this._variables[symb]); - } - else { - res.push(symb); - } - return ( i + 1 ) ; - } - var i = ( i + 1 ) ; - } - throw BadSyntax(this._thisDoc, this.lines, str, j, "unterminated URI reference"); + } + throw BadSyntax(this._thisDoc, this.lines, str, i, (("Prefix " + pfx) + " not bound.")); + } + } + var symb = this._store.sym((ns + ln)); + if(($rdf.Util.ArrayIndexOf(this._variables, symb) >= 0)) { + res.push(this._variables[symb]); + } else { + res.push(symb); + } + return j; } - else if (this.keywordsSet) { - var v = new pyjslib_List([]); - var j = this.bareWord(str, i, v); - if ((j < 0)) { - return -1; - } - if ((this.keywords.indexOf(v[0]) >= 0)) { - throw BadSyntax(this._thisDoc, this.lines, str, i, ( ( "Keyword \"" + v[0] ) + "\" not allowed here." ) ); - } - res.push(this._store.sym( ( this._bindings[""] + v[0] ) )); + var i = this.skipSpace(str, i); + if((i < 0)) { + return -1; + } + if((str.charAt(i) == "?")) { + var v = new pyjslib_List([]); + var j = this.variable(str, i, v); + if((j > 0)) { + res.push(v[0]); return j; - } - else { + } + return -1; + } else if((str.charAt(i) == "<")) { + var i = (i + 1); + var st = i; + while((i < pyjslib_len(str))) { + if((str.charAt(i) == ">")) { + var uref = pyjslib_slice(str, st, i); + if(this._baseURI) { + var uref = uripath_join(this._baseURI, uref); + } else { + assertFudge((uref.indexOf(":") >= 0), "With no base URI, cannot deal with relative URIs"); + } + if((pyjslib_slice(str, (i - 1), i) == "#") && !((pyjslib_slice(uref, -1, null) == "#"))) { + var uref = (uref + "#"); + } + var symb = this._store.sym(uref); + if(($rdf.Util.ArrayIndexOf(this._variables, symb) >= 0)) { + res.push(this._variables[symb]); + } else { + res.push(symb); + } + return(i + 1); + } + var i = (i + 1); + } + throw BadSyntax(this._thisDoc, this.lines, str, j, "unterminated URI reference"); + } else if(this.keywordsSet) { + var v = new pyjslib_List([]); + var j = this.bareWord(str, i, v); + if((j < 0)) { return -1; - } -}; -__SinkParser.prototype.skipSpace = function(str, i) { + } + if(($rdf.Util.ArrayIndexOf(this.keywords, v[0]) >= 0)) { + throw BadSyntax(this._thisDoc, this.lines, str, i, (("Keyword \"" + v[0]) + "\" not allowed here.")); + } + res.push(this._store.sym((this._bindings[""] + v[0]))); + return j; + } else { + return -1; + } + }; + __SinkParser.prototype.skipSpace = function (str, i) { /* Skip white space, newlines and comments. return -1 if EOF, else position of first non-ws character*/ - - while (1) { - eol.lastIndex = 0; - var m = eol.exec(str.slice(i)); - if ((m == null)) { - break; - } - this.lines = ( this.lines + 1 ) ; - i += eol.lastIndex; - this.previousLine = this.startOfLine; - this.startOfLine = i; - tabulator.log.debug( ( ( ( "N3 line " + this.lines ) + " " ) + str.slice(this.previousLine, this.startOfLine) ) ); - } - ws.lastIndex = 0; - var m = ws.exec(str.slice(i)); - if ((m != null) && (m[0] != "")) { - i += ws.lastIndex; - } - if ((i == pyjslib_len(str))) { - return -1; - } - return i; -}; -__SinkParser.prototype.variable = function(str, i, res) { + var tmp = str; + var whitespace = ' \n\r\t\f\x0b\xa0\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u200b\u2028\u2029\u3000'; + for(var j = (i ? i : 0); j < str.length; j++) { + if(whitespace.indexOf(str.charAt(j)) === -1) { + if(str.charAt(j) === '#') { + str = str.slice(i).replace(/^[^\n]*\n/, ""); + i = 0; + j = -1; + } else { + break; + } + } + } + var val = (tmp.length - str.length) + j; + if(val === tmp.length) { + return -1; + } + return val; + }; + __SinkParser.prototype.variable = function (str, i, res) { /* ?abc -> variable(:abc) */ - + var j = this.skipSpace(str, i); - if ((j < 0)) { - return -1; + if((j < 0)) { + return -1; } - if ((pyjslib_slice(str, j, ( j + 1 ) ) != "?")) { - return -1; + if((pyjslib_slice(str, j, (j + 1)) != "?")) { + return -1; } - var j = ( j + 1 ) ; + var j = (j + 1); var i = j; - if (("0123456789-".indexOf(str[j]) >= 0)) { - throw BadSyntax(this._thisDoc, this.lines, str, j, ( ( "Varible name can't start with '" + str[j] ) + "s'" ) ); - return -1; + if(("0123456789-".indexOf(str.charAt(j)) >= 0)) { + throw BadSyntax(this._thisDoc, this.lines, str, j, (("Varible name can't start with '" + str.charAt(j)) + "s'")); + return -1; } - while ((i < pyjslib_len(str)) && (_notNameChars.indexOf(str[i]) < 0)) { - var i = ( i + 1 ) ; + while((i < pyjslib_len(str)) && (_notNameChars.indexOf(str.charAt(i)) < 0)) { + var i = (i + 1); } - if ((this._parentContext == null)) { - throw BadSyntax(this._thisDoc, this.lines, str, j, ( "Can't use ?xxx syntax for variable in outermost level: " + pyjslib_slice(str, ( j - 1 ) , i) ) ); + if((this._parentContext == null)) { + throw BadSyntax(this._thisDoc, this.lines, str, j, ("Can't use ?xxx syntax for variable in outermost level: " + pyjslib_slice(str, (j - 1), i))); } res.push(this._store.variable(pyjslib_slice(str, j, i))); return i; -}; -__SinkParser.prototype.bareWord = function(str, i, res) { + }; + __SinkParser.prototype.bareWord = function (str, i, res) { /* abc -> :abc */ - + var j = this.skipSpace(str, i); - if ((j < 0)) { - return -1; + if((j < 0)) { + return -1; } - var ch = str[j]; - if (("0123456789-".indexOf(ch) >= 0)) { - return -1; + var ch = str.charAt(j); + if(("0123456789-".indexOf(ch) >= 0)) { + return -1; } - if ((_notNameChars.indexOf(ch) >= 0)) { - return -1; + if((_notNameChars.indexOf(ch) >= 0)) { + return -1; } var i = j; - while ((i < pyjslib_len(str)) && (_notNameChars.indexOf(str[i]) < 0)) { - var i = ( i + 1 ) ; + while((i < pyjslib_len(str)) && (_notNameChars.indexOf(str.charAt(i)) < 0)) { + var i = (i + 1); } res.push(pyjslib_slice(str, j, i)); return i; -}; -__SinkParser.prototype.qname = function(str, i, res) { + }; + __SinkParser.prototype.qname = function (str, i, res) { /* xyz:def -> ('xyz', 'def') If not in keywords and keywordsSet: def -> ('', 'def') :def -> ('', 'def') */ - + var i = this.skipSpace(str, i); - if ((i < 0)) { - return -1; - } - var c = str[i]; - if (("0123456789-+".indexOf(c) >= 0)) { - return -1; - } - if ((_notNameChars.indexOf(c) < 0)) { - var ln = c; - var i = ( i + 1 ) ; - while ((i < pyjslib_len(str))) { - var c = str[i]; - if ((_notNameChars.indexOf(c) < 0)) { - var ln = ( ln + c ) ; - var i = ( i + 1 ) ; - } - else { - break; - } - } - } - else { - var ln = ""; - } - if ((i < pyjslib_len(str)) && (str[i] == ":")) { - var pfx = ln; - var i = ( i + 1 ) ; - var ln = ""; - while ((i < pyjslib_len(str))) { - var c = str[i]; - if ((_notNameChars.indexOf(c) < 0)) { - var ln = ( ln + c ) ; - var i = ( i + 1 ) ; - } - else { - break; - } - } - res.push(new pyjslib_Tuple([pfx, ln])); + if((i < 0)) { + return -1; + } + var c = str.charAt(i); + if(("0123456789-+".indexOf(c) >= 0)) { + return -1; + } + if((_notNameChars.indexOf(c) < 0)) { + var ln = c; + var i = (i + 1); + while((i < pyjslib_len(str))) { + var c = str.charAt(i); + if((_notNameChars.indexOf(c) < 0)) { + var ln = (ln + c); + var i = (i + 1); + } else { + break; + } + } + } else { + var ln = ""; + } + if((i < pyjslib_len(str)) && (str.charAt(i) == ":")) { + var pfx = ln; + var i = (i + 1); + var ln = ""; + while((i < pyjslib_len(str))) { + var c = str.charAt(i); + if((_notNameChars.indexOf(c) < 0)) { + var ln = (ln + c); + var i = (i + 1); + } else { + break; + } + } + res.push(new pyjslib_Tuple([pfx, ln])); + return i; + } else { + if(ln && this.keywordsSet && ($rdf.Util.ArrayIndexOf(this.keywords, ln) < 0)) { + res.push(new pyjslib_Tuple(["", ln])); return i; + } + return -1; } - else { - if (ln && this.keywordsSet && (this.keywords.indexOf(ln) < 0)) { - res.push(new pyjslib_Tuple(["", ln])); - return i; - } - return -1; - } -}; -__SinkParser.prototype.object = function(str, i, res) { + }; + __SinkParser.prototype.object = function (str, i, res) { var j = this.subject(str, i, res); - if ((j >= 0)) { + if((j >= 0)) { + return j; + } else { + var j = this.skipSpace(str, i); + if((j < 0)) { + return -1; + } else { + var i = j; + } + if((str.charAt(i) == "\"")) { + if((pyjslib_slice(str, i, (i + 3)) == "\"\"\"")) { + var delim = "\"\"\""; + } else { + var delim = "\""; + } + var i = (i + pyjslib_len(delim)); + var pairFudge = this.strconst(str, i, delim); + var j = pairFudge[0]; + var s = pairFudge[1]; + res.push(this._store.literal(s)); + diag_progress("New string const ", s, j); return j; + } else { + return -1; + } } - else { - var j = this.skipSpace(str, i); - if ((j < 0)) { - return -1; - } - else { - var i = j; - } - if ((str[i] == "\"")) { - if ((pyjslib_slice(str, i, ( i + 3 ) ) == "\"\"\"")) { - var delim = "\"\"\""; - } - else { - var delim = "\""; - } - var i = ( i + pyjslib_len(delim) ) ; - var pairFudge = this.strconst(str, i, delim); - var j = pairFudge[0]; - var s = pairFudge[1]; - res.push(this._store.literal(s)); - diag_progress("New string const ", s, j); - return j; - } - else { - return -1; - } - } -}; -__SinkParser.prototype.nodeOrLiteral = function(str, i, res) { + }; + __SinkParser.prototype.nodeOrLiteral = function (str, i, res) { var j = this.node(str, i, res); - if ((j >= 0)) { - return j; - } - else { - var j = this.skipSpace(str, i); - if ((j < 0)) { - return -1; - } - else { - var i = j; - } - var ch = str[i]; - if (("-+0987654321".indexOf(ch) >= 0)) { - number_syntax.lastIndex = 0; - var m = number_syntax.exec(str.slice(i)); - if ((m == null)) { - throw BadSyntax(this._thisDoc, this.lines, str, i, "Bad number syntax"); - } - var j = ( i + number_syntax.lastIndex ) ; - var val = pyjslib_slice(str, i, j); - if ((val.indexOf("e") >= 0)) { - res.push(this._store.literal(parseFloat(val), undefined, kb.sym(FLOAT_DATATYPE))); - } - else if ((pyjslib_slice(str, i, j).indexOf(".") >= 0)) { - res.push(this._store.literal(parseFloat(val), undefined, kb.sym(DECIMAL_DATATYPE))); - } - else { - res.push(this._store.literal(parseInt(val), undefined, kb.sym(INTEGER_DATATYPE))); - } - return j; + if((j >= 0)) { + return j; + } else { + var j = this.skipSpace(str, i); + if((j < 0)) { + return -1; + } else { + var i = j; + } + var ch = str.charAt(i); + if(("-+0987654321".indexOf(ch) >= 0)) { + number_syntax.lastIndex = 0; + var m = number_syntax.exec(str.slice(i)); + if((m == null)) { + throw BadSyntax(this._thisDoc, this.lines, str, i, "Bad number syntax"); + } + var j = (i + number_syntax.lastIndex); + var val = pyjslib_slice(str, i, j); + if((val.indexOf("e") >= 0)) { + res.push(this._store.literal(parseFloat(val), undefined, this._store.sym(FLOAT_DATATYPE))); + } else if((pyjslib_slice(str, i, j).indexOf(".") >= 0)) { + res.push(this._store.literal(parseFloat(val), undefined, this._store.sym(DECIMAL_DATATYPE))); + } else { + res.push(this._store.literal(parseInt(val), undefined, this._store.sym(INTEGER_DATATYPE))); } - if ((str[i] == "\"")) { - if ((pyjslib_slice(str, i, ( i + 3 ) ) == "\"\"\"")) { - var delim = "\"\"\""; - } - else { - var delim = "\""; - } - var i = ( i + pyjslib_len(delim) ) ; - var dt = null; - var pairFudge = this.strconst(str, i, delim); - var j = pairFudge[0]; - var s = pairFudge[1]; - var lang = null; - if ((pyjslib_slice(str, j, ( j + 1 ) ) == "@")) { - langcode.lastIndex = 0; - - var m = langcode.exec(str.slice( ( j + 1 ) )); - if ((m == null)) { - throw BadSyntax(this._thisDoc, startline, str, i, "Bad language code syntax on string literal, after @"); - } - var i = ( ( langcode.lastIndex + j ) + 1 ) ; - - var lang = pyjslib_slice(str, ( j + 1 ) , i); - var j = i; - } - if ((pyjslib_slice(str, j, ( j + 2 ) ) == "^^")) { - var res2 = new pyjslib_List([]); - var j = this.uri_ref2(str, ( j + 2 ) , res2); - var dt = res2[0]; - } - res.push(this._store.literal(s, lang, dt)); - return j; + return j; + } + if((str.charAt(i) == "\"")) { + if((pyjslib_slice(str, i, (i + 3)) == "\"\"\"")) { + var delim = "\"\"\""; + } else { + var delim = "\""; + } + var i = (i + pyjslib_len(delim)); + var dt = null; + var pairFudge = this.strconst(str, i, delim); + var j = pairFudge[0]; + var s = pairFudge[1]; + var lang = null; + if((pyjslib_slice(str, j, (j + 1)) == "@")) { + langcode.lastIndex = 0; + + var m = langcode.exec(str.slice((j + 1))); + if((m == null)) { + throw BadSyntax(this._thisDoc, startline, str, i, "Bad language code syntax on string literal, after @"); + } + var i = ((langcode.lastIndex + j) + 1); + + var lang = pyjslib_slice(str, (j + 1), i); + var j = i; } - else { - return -1; + if((pyjslib_slice(str, j, (j + 2)) == "^^")) { + var res2 = new pyjslib_List([]); + var j = this.uri_ref2(str, (j + 2), res2); + var dt = res2[0]; } + res.push(this._store.literal(s, lang, dt)); + return j; + } else { + return -1; + } } -}; -__SinkParser.prototype.strconst = function(str, i, delim) { + }; + __SinkParser.prototype.strconst = function (str, i, delim) { /* parse an N3 string constant delimited by delim. return index, val */ - + var j = i; var ustr = ""; var startline = this.lines; - while ((j < pyjslib_len(str))) { - var i = ( j + pyjslib_len(delim) ) ; - if ((pyjslib_slice(str, j, i) == delim)) { - return new pyjslib_Tuple([i, ustr]); - } - if ((str[j] == "\"")) { - var ustr = ( ustr + "\"" ) ; - var j = ( j + 1 ) ; - continue; - } - interesting.lastIndex = 0; - var m = interesting.exec(str.slice(j)); - if (!(m)) { - throw BadSyntax(this._thisDoc, startline, str, j, ( ( ( "Closing quote missing in string at ^ in " + pyjslib_slice(str, ( j - 20 ) , j) ) + "^" ) + pyjslib_slice(str, j, ( j + 20 ) ) ) ); - } - var i = ( ( j + interesting.lastIndex ) - 1 ) ; - var ustr = ( ustr + pyjslib_slice(str, j, i) ) ; - var ch = str[i]; - if ((ch == "\"")) { - var j = i; - continue; - } - else if ((ch == "\r")) { - var j = ( i + 1 ) ; - continue; - } - else if ((ch == "\n")) { - if ((delim == "\"")) { - throw BadSyntax(this._thisDoc, startline, str, i, "newline found in string literal"); - } - this.lines = ( this.lines + 1 ) ; - var ustr = ( ustr + ch ) ; - var j = ( i + 1 ) ; - this.previousLine = this.startOfLine; - this.startOfLine = j; - } - else if ((ch == "\\")) { - var j = ( i + 1 ) ; - var ch = pyjslib_slice(str, j, ( j + 1 ) ); - if (!(ch)) { - throw BadSyntax(this._thisDoc, startline, str, i, "unterminated string literal (2)"); - } - var k = string_find("abfrtvn\\\"", ch); - if ((k >= 0)) { - var uch = "\a\b\f\r\t\v\n\\\""[k]; - var ustr = ( ustr + uch ) ; - var j = ( j + 1 ) ; - } - else if ((ch == "u")) { - var pairFudge = this.uEscape(str, ( j + 1 ) , startline); - var j = pairFudge[0]; - var ch = pairFudge[1]; - var ustr = ( ustr + ch ) ; - } - else if ((ch == "U")) { - var pairFudge = this.UEscape(str, ( j + 1 ) , startline); - var j = pairFudge[0]; - var ch = pairFudge[1]; - var ustr = ( ustr + ch ) ; - } - else { - throw BadSyntax(this._thisDoc, this.lines, str, i, "bad escape"); - } - } + while((j < pyjslib_len(str))) { + var i = (j + pyjslib_len(delim)); + if((pyjslib_slice(str, j, i) == delim)) { + return new pyjslib_Tuple([i, ustr]); + } + if((str.charAt(j) == "\"")) { + var ustr = (ustr + "\""); + var j = (j + 1); + continue; + } + interesting.lastIndex = 0; + var m = interesting.exec(str.slice(j)); + if(!(m)) { + throw BadSyntax(this._thisDoc, startline, str, j, ((("Closing quote missing in string at ^ in " + pyjslib_slice(str, (j - 20), j)) + "^") + pyjslib_slice(str, j, (j + 20)))); + } + var i = ((j + interesting.lastIndex) - 1); + var ustr = (ustr + pyjslib_slice(str, j, i)); + var ch = str.charAt(i); + if((ch == "\"")) { + var j = i; + continue; + } else if((ch == "\r")) { + var j = (i + 1); + continue; + } else if((ch == "\n")) { + if((delim == "\"")) { + throw BadSyntax(this._thisDoc, startline, str, i, "newline found in string literal"); + } + this.lines = (this.lines + 1); + var ustr = (ustr + ch); + var j = (i + 1); + this.previousLine = this.startOfLine; + this.startOfLine = j; + } else if((ch == "\\")) { + var j = (i + 1); + var ch = pyjslib_slice(str, j, (j + 1)); + if(!(ch)) { + throw BadSyntax(this._thisDoc, startline, str, i, "unterminated string literal (2)"); + } + var k = string_find("abfrtvn\\\"", ch); + if((k >= 0)) { + var uch = "\a\b\f\r\t\v\n\\\"".charAt(k); + var ustr = (ustr + uch); + var j = (j + 1); + } else if((ch == "u")) { + var pairFudge = this.uEscape(str, (j + 1), startline); + var j = pairFudge[0]; + var ch = pairFudge[1]; + var ustr = (ustr + ch); + } else if((ch == "U")) { + var pairFudge = this.UEscape(str, (j + 1), startline); + var j = pairFudge[0]; + var ch = pairFudge[1]; + var ustr = (ustr + ch); + } else { + throw BadSyntax(this._thisDoc, this.lines, str, i, "bad escape"); + } + } } throw BadSyntax(this._thisDoc, this.lines, str, i, "unterminated string literal"); -}; -__SinkParser.prototype.uEscape = function(str, i, startline) { + }; + __SinkParser.prototype.uEscape = function (str, i, startline) { var j = i; var count = 0; var value = 0; - while ((count < 4)) { - var chFudge = pyjslib_slice(str, j, ( j + 1 ) ); - var ch = chFudge.toLowerCase(); - var j = ( j + 1 ) ; - if ((ch == "")) { - throw BadSyntax(this._thisDoc, startline, str, i, "unterminated string literal(3)"); - } - var k = string_find("0123456789abcdef", ch); - if ((k < 0)) { - throw BadSyntax(this._thisDoc, startline, str, i, "bad string literal hex escape"); - } - var value = ( ( value * 16 ) + k ) ; - var count = ( count + 1 ) ; + while((count < 4)) { + var chFudge = pyjslib_slice(str, j, (j + 1)); + var ch = chFudge.toLowerCase(); + var j = (j + 1); + if((ch == "")) { + throw BadSyntax(this._thisDoc, startline, str, i, "unterminated string literal(3)"); + } + var k = string_find("0123456789abcdef", ch); + if((k < 0)) { + throw BadSyntax(this._thisDoc, startline, str, i, "bad string literal hex escape"); + } + var value = ((value * 16) + k); + var count = (count + 1); } var uch = String.fromCharCode(value); return new pyjslib_Tuple([j, uch]); -}; -__SinkParser.prototype.UEscape = function(str, i, startline) { + }; + __SinkParser.prototype.UEscape = function (str, i, startline) { var j = i; var count = 0; var value = "\\U"; - while ((count < 8)) { - var chFudge = pyjslib_slice(str, j, ( j + 1 ) ); - var ch = chFudge.toLowerCase(); - var j = ( j + 1 ) ; - if ((ch == "")) { - throw BadSyntax(this._thisDoc, startline, str, i, "unterminated string literal(3)"); - } - var k = string_find("0123456789abcdef", ch); - if ((k < 0)) { - throw BadSyntax(this._thisDoc, startline, str, i, "bad string literal hex escape"); - } - var value = ( value + ch ) ; - var count = ( count + 1 ) ; - } - var uch = stringFromCharCode( ( ( "0x" + pyjslib_slice(value, 2, 10) ) - 0 ) ); + while((count < 8)) { + var chFudge = pyjslib_slice(str, j, (j + 1)); + var ch = chFudge.toLowerCase(); + var j = (j + 1); + if((ch == "")) { + throw BadSyntax(this._thisDoc, startline, str, i, "unterminated string literal(3)"); + } + var k = string_find("0123456789abcdef", ch); + if((k < 0)) { + throw BadSyntax(this._thisDoc, startline, str, i, "bad string literal hex escape"); + } + var value = (value + ch); + var count = (count + 1); + } + var uch = stringFromCharCode((("0x" + pyjslib_slice(value, 2, 10)) - 0)); return new pyjslib_Tuple([j, uch]); -}; + }; -function BadSyntax(uri, lines, str, i, why) { - return ( ( ( ( ( ( ( ( "Line " + ( lines + 1 ) ) + " of <" ) + uri ) + ">: Bad syntax: " ) + why ) + "\nat: \"" ) + pyjslib_slice(str, i, ( i + 30 ) ) ) + "\"" ) ; -} + function BadSyntax(uri, lines, str, i, why) { + return(((((((("Line " + (lines + 1)) + " of <") + uri) + ">: Bad syntax: ") + why) + "\nat: \"") + pyjslib_slice(str, i, (i + 30))) + "\""); + } -function stripCR(str) { + function stripCR(str) { var res = ""; - + var __ch = new pyjslib_Iterator(str); try { - while (true) { - var ch = __ch.next(); - - - if ((ch != "\r")) { - var res = ( res + ch ) ; - } - - } - } catch (e) { - if (e != StopIteration) { - throw e; + while(true) { + var ch = __ch.next(); + + + if((ch != "\r")) { + var res = (res + ch); } + + } + } catch(e) { + if(e != StopIteration) { + throw e; + } } - + return res; -} + } -function dummyWrite(x) { -} + function dummyWrite(x) { + } + return SinkParser; +}(); +\ No newline at end of file diff --git a/chrome/content/zotero/xpcom/rdf/rdfparser.js b/chrome/content/zotero/xpcom/rdf/rdfparser.js @@ -61,502 +61,504 @@ * @constructor * @param {RDFStore} store An RDFStore object */ -function RDFParser(store) { - /** Standard namespaces that we know how to handle @final - * @member RDFParser - */ - RDFParser['ns'] = {'RDF': - "http://www.w3.org/1999/02/22-rdf-syntax-ns#", - 'RDFS': - "http://www.w3.org/2000/01/rdf-schema#"} - /** DOM Level 2 node type magic numbers @final - * @member RDFParser - */ - RDFParser['nodeType'] = {'ELEMENT': 1, 'ATTRIBUTE': 2, 'TEXT': 3, - 'CDATA_SECTION': 4, 'ENTITY_REFERENCE': 5, - 'ENTITY': 6, 'PROCESSING_INSTRUCTION': 7, - 'COMMENT': 8, 'DOCUMENT': 9, 'DOCUMENT_TYPE': 10, - 'DOCUMENT_FRAGMENT': 11, 'NOTATION': 12} - - /** - * Frame class for namespace and base URI lookups - * Base lookups will always resolve because the parser knows - * the default base. - * - * @private - */ - this['frameFactory'] = function (parser, parent, element) { - return {'NODE': 1, - 'ARC': 2, - 'parent': parent, - 'parser': parser, - 'store': parser['store'], - 'element': element, - 'lastChild': 0, - 'base': null, - 'lang': null, - 'node': null, - 'nodeType': null, - 'listIndex': 1, - 'rdfid': null, - 'datatype': null, - 'collection': false, - - /** Terminate the frame and notify the store that we're done */ - 'terminateFrame': function () { - if (this['collection']) { - this['node']['close']() - } - }, - - /** Add a symbol of a certain type to the this frame */ - 'addSymbol': function (type, uri) { - uri = Util.uri.join(uri, this['base']) - this['node'] = this['store']['sym'](uri) - this['nodeType'] = type - }, - - /** Load any constructed triples into the store */ - 'loadTriple': function () { - if (this['parent']['parent']['collection']) { - this['parent']['parent']['node']['append'](this['node']) - } - else { - this['store']['add'](this['parent']['parent']['node'], - this['parent']['node'], - this['node'], - this['parser']['why']) - } - if (this['parent']['rdfid'] != null) { // reify - var triple = this['store']['sym']( - Util.uri.join("#"+this['parent']['rdfid'], - this['base'])) - this['store']['add'](triple, - this['store']['sym']( - RDFParser['ns']['RDF'] - +"type"), - this['store']['sym']( - RDFParser['ns']['RDF'] - +"Statement"), - this['parser']['why']) - this['store']['add'](triple, - this['store']['sym']( - RDFParser['ns']['RDF'] - +"subject"), - this['parent']['parent']['node'], - this['parser']['why']) - this['store']['add'](triple, - this['store']['sym']( - RDFParser['ns']['RDF'] - +"predicate"), - this['parent']['node'], - this['parser']['why']) - this['store']['add'](triple, - this['store']['sym']( - RDFParser['ns']['RDF'] - +"object"), - this['node'], - this['parser']['why']) - } - }, - - /** Check if it's OK to load a triple */ - 'isTripleToLoad': function () { - return (this['parent'] != null - && this['parent']['parent'] != null - && this['nodeType'] == this['NODE'] - && this['parent']['nodeType'] == this['ARC'] - && this['parent']['parent']['nodeType'] - == this['NODE']) - }, - - /** Add a symbolic node to this frame */ - 'addNode': function (uri) { - this['addSymbol'](this['NODE'],uri) - if (this['isTripleToLoad']()) { - this['loadTriple']() - } - }, - - /** Add a collection node to this frame */ - 'addCollection': function () { - this['nodeType'] = this['NODE'] - this['node'] = this['store']['collection']() - this['collection'] = true - if (this['isTripleToLoad']()) { - this['loadTriple']() - } - }, - - /** Add a collection arc to this frame */ - 'addCollectionArc': function () { - this['nodeType'] = this['ARC'] - }, - - /** Add a bnode to this frame */ - 'addBNode': function (id) { - if (id != null) { - if (this['parser']['bnodes'][id] != null) { - this['node'] = this['parser']['bnodes'][id] - } else { - this['node'] = this['parser']['bnodes'][id] = this['store']['bnode']() - } - } else { this['node'] = this['store']['bnode']() } - - this['nodeType'] = this['NODE'] - if (this['isTripleToLoad']()) { - this['loadTriple']() - } - }, - - /** Add an arc or property to this frame */ - 'addArc': function (uri) { - if (uri == RDFParser['ns']['RDF']+"li") { - uri = RDFParser['ns']['RDF']+"_"+this['parent']['listIndex']++ - } - this['addSymbol'](this['ARC'], uri) - }, - - /** Add a literal to this frame */ - 'addLiteral': function (value) { - if (this['parent']['datatype']) { - this['node'] = this['store']['literal']( - value, "", this['store']['sym']( - this['parent']['datatype'])) - } - else { - this['node'] = this['store']['literal']( - value, this['lang']) - } - this['nodeType'] = this['NODE'] - if (this['isTripleToLoad']()) { - this['loadTriple']() - } - } - } +$rdf.RDFParser = function (store) { + var RDFParser = {}; + + /** Standard namespaces that we know how to handle @final + * @member RDFParser + */ + RDFParser['ns'] = { + 'RDF': "http://www.w3.org/1999/02/22-rdf-syntax-ns#", + 'RDFS': "http://www.w3.org/2000/01/rdf-schema#" + } + /** DOM Level 2 node type magic numbers @final + * @member RDFParser + */ + RDFParser['nodeType'] = { + 'ELEMENT': 1, + 'ATTRIBUTE': 2, + 'TEXT': 3, + 'CDATA_SECTION': 4, + 'ENTITY_REFERENCE': 5, + 'ENTITY': 6, + 'PROCESSING_INSTRUCTION': 7, + 'COMMENT': 8, + 'DOCUMENT': 9, + 'DOCUMENT_TYPE': 10, + 'DOCUMENT_FRAGMENT': 11, + 'NOTATION': 12 + } + + /** + * Frame class for namespace and base URI lookups + * Base lookups will always resolve because the parser knows + * the default base. + * + * @private + */ + this['frameFactory'] = function (parser, parent, element) { + return { + 'NODE': 1, + 'ARC': 2, + 'parent': parent, + 'parser': parser, + 'store': parser['store'], + 'element': element, + 'lastChild': 0, + 'base': null, + 'lang': null, + 'node': null, + 'nodeType': null, + 'listIndex': 1, + 'rdfid': null, + 'datatype': null, + 'collection': false, + + /** Terminate the frame and notify the store that we're done */ + 'terminateFrame': function () { + if(this['collection']) { + this['node']['close']() + } + }, + + /** Add a symbol of a certain type to the this frame */ + 'addSymbol': function (type, uri) { + uri = $rdf.Util.uri.join(uri, this['base']) + this['node'] = this['store']['sym'](uri) + this['nodeType'] = type + }, + + /** Load any constructed triples into the store */ + 'loadTriple': function () { + if(this['parent']['parent']['collection']) { + this['parent']['parent']['node']['append'](this['node']) + } else { + this['store']['add'](this['parent']['parent']['node'], + this['parent']['node'], + this['node'], + this['parser']['why']) + } + if(this['parent']['rdfid'] != null) { // reify + var triple = this['store']['sym']( + $rdf.Util.uri.join("#" + this['parent']['rdfid'], this['base'])) + this['store']['add'](triple, + this['store']['sym'](RDFParser['ns']['RDF'] + "type"), + this['store']['sym'](RDFParser['ns']['RDF'] + "Statement"), + this['parser']['why']) + this['store']['add'](triple, + this['store']['sym'](RDFParser['ns']['RDF'] + "subject"), + this['parent']['parent']['node'], + this['parser']['why']) + this['store']['add'](triple, + this['store']['sym'](RDFParser['ns']['RDF'] + "predicate"), + this['parent']['node'], + this['parser']['why']) + this['store']['add'](triple, + this['store']['sym'](RDFParser['ns']['RDF'] + "object"), + this['node'], + this['parser']['why']) + } + }, + + /** Check if it's OK to load a triple */ + 'isTripleToLoad': function () { + return (this['parent'] != null + && this['parent']['parent'] != null + && this['nodeType'] == this['NODE'] + && this['parent']['nodeType'] == this['ARC'] + && this['parent']['parent']['nodeType'] == this['NODE']) + }, + + /** Add a symbolic node to this frame */ + 'addNode': function (uri) { + this['addSymbol'](this['NODE'], uri) + if(this['isTripleToLoad']()) { + this['loadTriple']() + } + }, + + /** Add a collection node to this frame */ + 'addCollection': function () { + this['nodeType'] = this['NODE'] + this['node'] = this['store']['collection']() + this['collection'] = true + if(this['isTripleToLoad']()) { + this['loadTriple']() + } + }, + + /** Add a collection arc to this frame */ + 'addCollectionArc': function () { + this['nodeType'] = this['ARC'] + }, + + /** Add a bnode to this frame */ + 'addBNode': function (id) { + if(id != null) { + if(this['parser']['bnodes'][id] != null) { + this['node'] = this['parser']['bnodes'][id] + } else { + this['node'] = this['parser']['bnodes'][id] = this['store']['bnode']() + } + } else { + this['node'] = this['store']['bnode']() + } + + this['nodeType'] = this['NODE'] + if(this['isTripleToLoad']()) { + this['loadTriple']() + } + }, + + /** Add an arc or property to this frame */ + 'addArc': function (uri) { + if(uri == RDFParser['ns']['RDF'] + "li") { + uri = RDFParser['ns']['RDF'] + "_" + this['parent']['listIndex']++ + } + this['addSymbol'](this['ARC'], uri) + }, + + /** Add a literal to this frame */ + 'addLiteral': function (value) { + if(this['parent']['datatype']) { + this['node'] = this['store']['literal']( + value, "", this['store']['sym']( + this['parent']['datatype'])) + } else { + this['node'] = this['store']['literal']( + value, this['lang']) + } + this['nodeType'] = this['NODE'] + if(this['isTripleToLoad']()) { + this['loadTriple']() + } + } + } + } + + //from the OpenLayers source .. needed to get around IE problems. + this['getAttributeNodeNS'] = function (node, uri, name) { + var attributeNode = null; + if(node.getAttributeNodeNS) { + attributeNode = node.getAttributeNodeNS(uri, name); + } else { + var attributes = node.attributes; + var potentialNode, fullName; + for(var i = 0; i < attributes.length; ++i) { + potentialNode = attributes[i]; + if(potentialNode.namespaceURI == uri) { + fullName = (potentialNode.prefix) ? (potentialNode.prefix + ":" + name) : name; + if(fullName == potentialNode.nodeName) { + attributeNode = potentialNode; + break; + } + } + } } + return attributeNode; + } + + /** Our triple store reference @private */ + this['store'] = store + /** Our identified blank nodes @private */ + this['bnodes'] = {} + /** A context for context-aware stores @private */ + this['why'] = null + /** Reification flag */ + this['reify'] = false + + /** + * Build our initial scope frame and parse the DOM into triples + * @param {DOMTree} document The DOM to parse + * @param {String} base The base URL to use + * @param {Object} why The context to which this resource belongs + */ + this['parse'] = function (document, base, why) { + // alert('parse base:'+base); + var children = document['childNodes'] + + // clean up for the next run + this['cleanParser']() + + // figure out the root element + //var root = document.documentElement; //this is faster, I think, cross-browser issue? well, DOM 2 + if(document['nodeType'] == RDFParser['nodeType']['DOCUMENT']) { + for(var c = 0; c < children['length']; c++) { + if(children[c]['nodeType'] == RDFParser['nodeType']['ELEMENT']) { + var root = children[c] + break + } + } + } else if(document['nodeType'] == RDFParser['nodeType']['ELEMENT']) { + var root = document + } else { + throw new Error("RDFParser: can't find root in " + base + ". Halting. ") + return false + } + + this['why'] = why + - /** Our triple store reference @private */ - this['store'] = store - /** Our identified blank nodes @private */ + // our topmost frame + var f = this['frameFactory'](this) + this['base'] = base + f['base'] = base + f['lang'] = '' + + this['parseDOM'](this['buildFrame'](f, root)) + return true + } + this['parseDOM'] = function (frame) { + // a DOM utility function used in parsing + var elementURI = function (el) { + var result = ""; + if(el['namespaceURI'] == null) { + throw new Error("RDF/XML syntax error: No namespace for " + + el['localName'] + " in " + this.base) + } + if(el['namespaceURI']) { + result = result + el['namespaceURI']; + } + if(el['localName']) { + result = result + el['localName']; + } else if(el['nodeName']) { + if(el['nodeName'].indexOf(":") >= 0) + result = result + el['nodeName'].split(":")[1]; + else + result = result + el['nodeName']; + } + return result; + } + var dig = true // if we'll dig down in the tree on the next iter + while(frame['parent']) { + var dom = frame['element'] + var attrs = dom['attributes'] + + if(dom['nodeType'] == RDFParser['nodeType']['TEXT'] + || dom['nodeType'] == RDFParser['nodeType']['CDATA_SECTION']) { + //we have a literal + frame['addLiteral'](dom['nodeValue']) + } else if(elementURI(dom) != RDFParser['ns']['RDF'] + "RDF") { + // not root + if(frame['parent'] && frame['parent']['collection']) { + // we're a collection element + frame['addCollectionArc']() + frame = this['buildFrame'](frame, frame['element']) + frame['parent']['element'] = null + } + if(!frame['parent'] || !frame['parent']['nodeType'] + || frame['parent']['nodeType'] == frame['ARC']) { + // we need a node + var about = this['getAttributeNodeNS'](dom, RDFParser['ns']['RDF'], "about") + var rdfid = this['getAttributeNodeNS'](dom, RDFParser['ns']['RDF'], "ID") + if(about && rdfid) { + throw new Error("RDFParser: " + dom['nodeName'] + + " has both rdf:id and rdf:about." + " Halting. Only one of these" + + " properties may be specified on a" + " node."); + } + if(about == null && rdfid) { + frame['addNode']("#" + rdfid['nodeValue']) + dom['removeAttributeNode'](rdfid) + } else if(about == null && rdfid == null) { + var bnid = this['getAttributeNodeNS'](dom, RDFParser['ns']['RDF'], "nodeID") + if(bnid) { + frame['addBNode'](bnid['nodeValue']) + dom['removeAttributeNode'](bnid) + } else { + frame['addBNode']() + } + } else { + frame['addNode'](about['nodeValue']) + dom['removeAttributeNode'](about) + } + + // Typed nodes + var rdftype = this['getAttributeNodeNS'](dom, RDFParser['ns']['RDF'], "type") + if(RDFParser['ns']['RDF'] + "Description" != elementURI(dom)) { + rdftype = { + 'nodeValue': elementURI(dom) + } + } + if(rdftype != null) { + this['store']['add'](frame['node'], + this['store']['sym'](RDFParser['ns']['RDF'] + "type"), + this['store']['sym']( + $rdf.Util.uri.join( + rdftype['nodeValue'], + frame['base'])), + this['why']) + if(rdftype['nodeName']) { + dom['removeAttributeNode'](rdftype) + } + } + + // Property Attributes + for(var x = attrs['length'] - 1; x >= 0; x--) { + this['store']['add'](frame['node'], + this['store']['sym'](elementURI(attrs[x])), + this['store']['literal']( + attrs[x]['nodeValue'], + frame['lang']), + this['why']) + } + } else { + // we should add an arc (or implicit bnode+arc) + frame['addArc'](elementURI(dom)) + + // save the arc's rdf:ID if it has one + if(this['reify']) { + var rdfid = this['getAttributeNodeNS'](dom, RDFParser['ns']['RDF'], "ID") + if(rdfid) { + frame['rdfid'] = rdfid['nodeValue'] + dom['removeAttributeNode'](rdfid) + } + } + + var parsetype = this['getAttributeNodeNS'](dom, RDFParser['ns']['RDF'], "parseType") + var datatype = this['getAttributeNodeNS'](dom, RDFParser['ns']['RDF'], "datatype") + if(datatype) { + frame['datatype'] = datatype['nodeValue'] + dom['removeAttributeNode'](datatype) + } + + if(parsetype) { + var nv = parsetype['nodeValue'] + if(nv == "Literal") { + frame['datatype'] = RDFParser['ns']['RDF'] + "XMLLiteral" + // (this.buildFrame(frame)).addLiteral(dom) + // should work but doesn't + frame = this['buildFrame'](frame) + frame['addLiteral'](dom) + dig = false + } else if(nv == "Resource") { + frame = this['buildFrame'](frame, frame['element']) + frame['parent']['element'] = null + frame['addBNode']() + } else if(nv == "Collection") { + frame = this['buildFrame'](frame, frame['element']) + frame['parent']['element'] = null + frame['addCollection']() + } + dom['removeAttributeNode'](parsetype) + } + + if(attrs['length'] != 0) { + var resource = this['getAttributeNodeNS'](dom, RDFParser['ns']['RDF'], "resource") + var bnid = this['getAttributeNodeNS'](dom, RDFParser['ns']['RDF'], "nodeID") + + frame = this['buildFrame'](frame) + if(resource) { + frame['addNode'](resource['nodeValue']) + dom['removeAttributeNode'](resource) + } else { + if(bnid) { + frame['addBNode'](bnid['nodeValue']) + dom['removeAttributeNode'](bnid) + } else { + frame['addBNode']() + } + } + + for(var x = attrs['length'] - 1; x >= 0; x--) { + var f = this['buildFrame'](frame) + f['addArc'](elementURI(attrs[x])) + if(elementURI(attrs[x]) == RDFParser['ns']['RDF'] + "type") { + (this['buildFrame'](f))['addNode']( + attrs[x]['nodeValue']) + } else { + (this['buildFrame'](f))['addLiteral']( + attrs[x]['nodeValue']) + } + } + } else if(dom['childNodes']['length'] == 0) { + (this['buildFrame'](frame))['addLiteral']("") + } + } + } // rdf:RDF + // dig dug + dom = frame['element'] + while(frame['parent']) { + var pframe = frame + while(dom == null) { + frame = frame['parent'] + dom = frame['element'] + } + var candidate = dom['childNodes'][frame['lastChild']] + if(candidate == null || !dig) { + frame['terminateFrame']() + if(!(frame = frame['parent'])) { + break + } // done + dom = frame['element'] + dig = true + } else if((candidate['nodeType'] != RDFParser['nodeType']['ELEMENT'] + && candidate['nodeType'] != RDFParser['nodeType']['TEXT'] + && candidate['nodeType'] != RDFParser['nodeType']['CDATA_SECTION']) + || ((candidate['nodeType'] == RDFParser['nodeType']['TEXT'] + || candidate['nodeType'] == RDFParser['nodeType']['CDATA_SECTION']) + && dom['childNodes']['length'] != 1)) { + frame['lastChild']++ + } else { + // not a leaf + frame['lastChild']++; + frame = this['buildFrame'](pframe, dom['childNodes'][frame['lastChild'] - 1]) + break + } + } + } // while + } + + /** + * Cleans out state from a previous parse run + * @private + */ + this['cleanParser'] = function () { this['bnodes'] = {} - /** A context for context-aware stores @private */ this['why'] = null - /** Reification flag */ - this['reify'] = false - - /** - * Build our initial scope frame and parse the DOM into triples - * @param {DOMTree} document The DOM to parse - * @param {String} base The base URL to use - * @param {Object} why The context to which this resource belongs - */ - this['parse'] = function (document, base, why) { - // alert('parse base:'+base); - var children = document['childNodes'] - - // clean up for the next run - this['cleanParser']() - - // figure out the root element - var root = document.documentElement; //this is faster, I think, cross-browser issue? well, DOM 2 - /* - if (document['nodeType'] == RDFParser['nodeType']['DOCUMENT']) { - for (var c=0; c<children['length']; c++) { - if (children[c]['nodeType'] - == RDFParser['nodeType']['ELEMENT']) { - var root = children[c] - break - } - } - } - else if (document['nodeType'] == RDFParser['nodeType']['ELEMENT']) { - var root = document - } - else { - throw new Error("RDFParser: can't find root in " + base - + ". Halting. ") - return false - } - */ - - this['why'] = why - - - // our topmost frame - - var f = this['frameFactory'](this) - this['base'] = base - f['base'] = base - f['lang'] = '' - - this['parseDOM'](this['buildFrame'](f,root)) - return true + } + + /** + * Builds scope frame + * @private + */ + this['buildFrame'] = function (parent, element) { + var frame = this['frameFactory'](this, parent, element) + if(parent) { + frame['base'] = parent['base'] + frame['lang'] = parent['lang'] } - this['parseDOM'] = function (frame) { - // a DOM utility function used in parsing - var elementURI = function (el) { - if (el['namespaceURI'] == null) { - throw new Error("RDF/XML syntax error: No namespace for " - +el['localName']+" in "+this.base) - } - return el['namespaceURI'] + el['localName'] - } - var dig = true // if we'll dig down in the tree on the next iter - - while (frame['parent']) { - var dom = frame['element'] - var attrs = dom['attributes'] - - if (dom['nodeType'] - == RDFParser['nodeType']['TEXT'] - || dom['nodeType'] - == RDFParser['nodeType']['CDATA_SECTION']) {//we have a literal - frame['addLiteral'](dom['nodeValue']) - } - else if (elementURI(dom) - != RDFParser['ns']['RDF']+"RDF") { // not root - if (frame['parent'] && frame['parent']['collection']) { - // we're a collection element - frame['addCollectionArc']() - frame = this['buildFrame'](frame,frame['element']) - frame['parent']['element'] = null - } - if (!frame['parent'] || !frame['parent']['nodeType'] - || frame['parent']['nodeType'] == frame['ARC']) { - // we need a node - var about =dom['getAttributeNodeNS']( - RDFParser['ns']['RDF'],"about") - var rdfid =dom['getAttributeNodeNS']( - RDFParser['ns']['RDF'],"ID") - if (about && rdfid) { - throw new Error("RDFParser: " + dom['nodeName'] - + " has both rdf:id and rdf:about." - + " Halting. Only one of these" - + " properties may be specified on a" - + " node."); - } - if (about == null && rdfid) { - frame['addNode']("#"+rdfid['nodeValue']) - dom['removeAttributeNode'](rdfid) - } - else if (about == null && rdfid == null) { - var bnid = dom['getAttributeNodeNS']( - RDFParser['ns']['RDF'],"nodeID") - if (bnid) { - frame['addBNode'](bnid['nodeValue']) - dom['removeAttributeNode'](bnid) - } else { frame['addBNode']() } - } - else { - frame['addNode'](about['nodeValue']) - dom['removeAttributeNode'](about) - } - - // Typed nodes - var rdftype = dom['getAttributeNodeNS']( - RDFParser['ns']['RDF'],"type") - if (RDFParser['ns']['RDF']+"Description" - != elementURI(dom)) { - rdftype = {'nodeValue': elementURI(dom)} - } - if (rdftype != null) { - this['store']['add'](frame['node'], - this['store']['sym']( - RDFParser['ns']['RDF']+"type"), - this['store']['sym']( - Util.uri.join( - rdftype['nodeValue'], - frame['base'])), - this['why']) - if (rdftype['nodeName']){ - dom['removeAttributeNode'](rdftype) - } - } - - // Property Attributes - for (var x = attrs['length']-1; x >= 0; x--) { - this['store']['add'](frame['node'], - this['store']['sym']( - elementURI(attrs[x])), - this['store']['literal']( - attrs[x]['nodeValue'], - frame['lang']), - this['why']) - } - } - else { // we should add an arc (or implicit bnode+arc) - frame['addArc'](elementURI(dom)) - - // save the arc's rdf:ID if it has one - if (this['reify']) { - var rdfid = dom['getAttributeNodeNS']( - RDFParser['ns']['RDF'],"ID") - if (rdfid) { - frame['rdfid'] = rdfid['nodeValue'] - dom['removeAttributeNode'](rdfid) - } - } - - var parsetype = dom['getAttributeNodeNS']( - RDFParser['ns']['RDF'],"parseType") - var datatype = dom['getAttributeNodeNS']( - RDFParser['ns']['RDF'],"datatype") - if (datatype) { - frame['datatype'] = datatype['nodeValue'] - dom['removeAttributeNode'](datatype) - } - - if (parsetype) { - var nv = parsetype['nodeValue'] - if (nv == "Literal") { - frame['datatype'] - = RDFParser['ns']['RDF']+"XMLLiteral" - // (this.buildFrame(frame)).addLiteral(dom) - // should work but doesn't - frame = this['buildFrame'](frame) - frame['addLiteral'](dom) - dig = false - } - else if (nv == "Resource") { - frame = this['buildFrame'](frame,frame['element']) - frame['parent']['element'] = null - frame['addBNode']() - } - else if (nv == "Collection") { - frame = this['buildFrame'](frame,frame['element']) - frame['parent']['element'] = null - frame['addCollection']() - } - dom['removeAttributeNode'](parsetype) - } - - if (attrs['length'] != 0) { - var resource = dom['getAttributeNodeNS']( - RDFParser['ns']['RDF'],"resource") - var bnid = dom['getAttributeNodeNS']( - RDFParser['ns']['RDF'],"nodeID") - - frame = this['buildFrame'](frame) - if (resource) { - frame['addNode'](resource['nodeValue']) - dom['removeAttributeNode'](resource) - } else { - if (bnid) { - frame['addBNode'](bnid['nodeValue']) - dom['removeAttributeNode'](bnid) - } else { frame['addBNode']() } - } - - for (var x = attrs['length']-1; x >= 0; x--) { - var f = this['buildFrame'](frame) - f['addArc'](elementURI(attrs[x])) - if (elementURI(attrs[x]) - ==RDFParser['ns']['RDF']+"type"){ - (this['buildFrame'](f))['addNode']( - attrs[x]['nodeValue']) - } else { - (this['buildFrame'](f))['addLiteral']( - attrs[x]['nodeValue']) - } - } - } - else if (dom['childNodes']['length'] == 0) { - (this['buildFrame'](frame))['addLiteral']("") - } - } - } // rdf:RDF - - // dig dug - dom = frame['element'] - while (frame['parent']) { - var pframe = frame - while (dom == null) { - frame = frame['parent'] - dom = frame['element'] - } - var candidate = dom['childNodes'][frame['lastChild']] - if (candidate == null || !dig) { - frame['terminateFrame']() - if (!(frame = frame['parent'])) { break } // done - dom = frame['element'] - dig = true - } - else if ((candidate['nodeType'] - != RDFParser['nodeType']['ELEMENT'] - && candidate['nodeType'] - != RDFParser['nodeType']['TEXT'] - && candidate['nodeType'] - != RDFParser['nodeType']['CDATA_SECTION']) - || ((candidate['nodeType'] - == RDFParser['nodeType']['TEXT'] - || candidate['nodeType'] - == RDFParser['nodeType']['CDATA_SECTION']) - && dom['childNodes']['length'] != 1)) { - frame['lastChild']++ - } - else { // not a leaf - frame['lastChild']++ - frame = this['buildFrame'](pframe, - dom['childNodes'][frame['lastChild']-1]) - break - } - } - } // while + if(element == null + || element['nodeType'] == RDFParser['nodeType']['TEXT'] + || element['nodeType'] == RDFParser['nodeType']['CDATA_SECTION']) { + return frame } - /** - * Cleans out state from a previous parse run - * @private - */ - this['cleanParser'] = function () { - this['bnodes'] = {} - this['why'] = null + var attrs = element['attributes'] + + var base = element['getAttributeNode']("xml:base") + if(base != null) { + frame['base'] = base['nodeValue'] + element['removeAttribute']("xml:base") + } + var lang = element['getAttributeNode']("xml:lang") + if(lang != null) { + frame['lang'] = lang['nodeValue'] + element['removeAttribute']("xml:lang") } - /** - * Builds scope frame - * @private - */ - this['buildFrame'] = function (parent, element) { - var frame = this['frameFactory'](this,parent,element) - if (parent) { - frame['base'] = parent['base'] - frame['lang'] = parent['lang'] - } - if (element == null - || element['nodeType'] == RDFParser['nodeType']['TEXT'] - || element['nodeType'] == RDFParser['nodeType']['CDATA_SECTION']) { - return frame - } - - var attrs = element['attributes'] - - var base = element['getAttributeNode']("xml:base") - if (base != null) { - frame['base'] = base['nodeValue'] - element['removeAttribute']("xml:base") - } - var lang = element['getAttributeNode']("xml:lang") - if (lang != null) { - frame['lang'] = lang['nodeValue'] - element['removeAttribute']("xml:lang") - } - - // remove all extraneous xml and xmlns attributes - for (var x = attrs['length']-1; x >= 0; x--) { - if (attrs[x]['nodeName']['substr'](0,3) == "xml") { - if (attrs[x].name.slice(0,6)=='xmlns:') { - var uri = attrs[x].nodeValue; - // alert('base for namespac attr:'+this.base); - if (this.base) uri = Util.uri.join(uri, this.base); - this.store.setPrefixForURI(attrs[x].name.slice(6), - uri); - } -// alert('rdfparser: xml atribute: '+attrs[x].name) //@@ - element['removeAttributeNode'](attrs[x]) - } - } - return frame + // remove all extraneous xml and xmlns attributes + for(var x = attrs['length'] - 1; x >= 0; x--) { + if(attrs[x]['nodeName']['substr'](0, 3) == "xml") { + if(attrs[x].name.slice(0, 6) == 'xmlns:') { + var uri = attrs[x].nodeValue; + // alert('base for namespac attr:'+this.base); + if(this.base) uri = $rdf.Util.uri.join(uri, this.base); + this.store.setPrefixForURI(attrs[x].name.slice(6), uri); + } + // alert('rdfparser: xml atribute: '+attrs[x].name) //@@ + element['removeAttributeNode'](attrs[x]) + } } + return frame + } } \ No newline at end of file diff --git a/chrome/content/zotero/xpcom/rdf/serialize.js b/chrome/content/zotero/xpcom/rdf/serialize.js @@ -1,732 +1,868 @@ /* Serialization of RDF Graphs -** -** Tim Berners-Lee 2006 -** This is or was http://dig.csail.mit.edu/2005/ajar/ajaw/js/rdf/serialize.js -** -** Bug: can't serialize http://data.semanticweb.org/person/abraham-bernstein/rdf -** in XML (from mhausenblas) -*/ - -__Serializer = function(){ - this.flags = ""; - this.base = null; - this.prefixes = []; - this.keywords = ['a']; // The only one we generate at the moment - this.prefixchars = "abcdefghijklmnopqustuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; - this.incoming = null; // Array not calculated yet - this.formulas = []; // remebering original formulae from hashes + ** + ** Tim Berners-Lee 2006 + ** This is or was http://dig.csail.mit.edu/2005/ajar/ajaw/js/rdf/serialize.js + ** + ** Bug: can't serialize http://data.semanticweb.org/person/abraham-bernstein/rdf + ** in XML (from mhausenblas) + */ +// @@@ Check the whole toStr thing tosee whetehr it still makes sense -- tbl +// +$rdf.Serializer = function () { + + var __Serializer = function (store) { + this.flags = ""; + this.base = null; + this.prefixes = []; + this.keywords = ['a']; // The only one we generate at the moment + this.prefixchars = "abcdefghijklmnopqustuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; + this.incoming = null; // Array not calculated yet + this.formulas = []; // remebering original formulae from hashes + this.store = store; + + /* pass */ + } - /* pass */ -} + var Serializer = function (store) { + return new __Serializer(store) + }; -Serializer = function() {return new __Serializer()}; + __Serializer.prototype.setBase = function (base) { + this.base = base + }; -__Serializer.prototype.setBase = function(base) - { this.base = base }; + __Serializer.prototype.setFlags = function (flags) { + this.flags = flags ? flags : '' + }; -__Serializer.prototype.setFlags = function(flags) - { this.flags = flags?flags: '' }; + __Serializer.prototype.toStr = function (x) { + var s = x.toNT(); + if(x.termType == 'formula') { + this.formulas[s] = x; // remember as reverse does not work + } + return s; + }; + + __Serializer.prototype.fromStr = function (s) { + if(s[0] == '{') { + var x = this.formulas[s]; + if(!x) alert('No formula object for ' + s) + return x; + } + return this.store.fromNT(s); + }; -__Serializer.prototype.toStr = function(x) { - var s = x.toNT(); - if (x.termType == 'formula') { - this.formulas[s] = x; // remember as reverse does not work - } - return s; -}; - -__Serializer.prototype.fromStr = function(s) { - if (s[0] == '{') { - var x = this.formulas[s]; - if (!x) alert('No formula object for '+s) - return x; - } - return kb.fromNT(s); -}; - -/* Accumulate Namespaces -** -** These are only hints. If two overlap, only one gets used -** There is therefore no guarantee in general. -*/ + /* Accumulate Namespaces + ** + ** These are only hints. If two overlap, only one gets used + ** There is therefore no guarantee in general. + */ -__Serializer.prototype.suggestPrefix = function(prefix, uri) { + __Serializer.prototype.suggestPrefix = function (prefix, uri) { this.prefixes[uri] = prefix; -} + } -// Takes a namespace -> prefix map -__Serializer.prototype.suggestNamespaces = function(namespaces) { - for (var px in namespaces) { - this.prefixes[namespaces[px]] = px; + // Takes a namespace -> prefix map + __Serializer.prototype.suggestNamespaces = function (namespaces) { + for(var px in namespaces) { + this.prefixes[namespaces[px]] = px; } -} + } -// Make up an unused prefix for a random namespace -__Serializer.prototype.makeUpPrefix = function(uri) { + // Make up an unused prefix for a random namespace + __Serializer.prototype.makeUpPrefix = function (uri) { var p = uri; var namespaces = []; var pok; var sz = this; - + function canUse(pp) { - if (namespaces[pp]) return false; // already used - sz.prefixes[uri] = pp; - pok = pp; - return true + if(namespaces[pp]) return false; // already used + sz.prefixes[uri] = pp; + pok = pp; + return true + } + for(var ns in sz.prefixes) { + namespaces[sz.prefixes[ns]] = ns; // reverse index } - for (var ns in sz.prefixes) namespaces[sz.prefixes[ns]] = ns; // reverse index - if ('#/'.indexOf(p[p.length-1]) >= 0) p = p.slice(0, -1); + if('#/'.indexOf(p[p.length - 1]) >= 0) p = p.slice(0, -1); var slash = p.lastIndexOf('/'); - if (slash >= 0) p = p.slice(slash+1); + if(slash >= 0) p = p.slice(slash + 1); var i = 0; - while (i < p.length) - if (sz.prefixchars.indexOf(p[i])) i++; else break; - p = p.slice(0,i); - if (p.length < 6 && canUse(p)) return pok; // exact i sbest - if (canUse(p.slice(0,3))) return pok; - if (canUse(p.slice(0,2))) return pok; - if (canUse(p.slice(0,4))) return pok; - if (canUse(p.slice(0,1))) return pok; - if (canUse(p.slice(0,5))) return pok; - for (var i=0;; i++) if (canUse(p.slice(0,3)+i)) return pok; -} - - -/* The scan is to find out which nodes will have to be the roots of trees -** in the serialized form. This will be any symbols, and any bnodes -** which hve more or less than one incoming arc, and any bnodes which have -** one incoming arc but it is an uninterrupted loop of such nodes back to itself. -** This should be kept linear time with repect to the number of statements. -** Note it does not use any indexing. -*/ - - -// Todo: -// - Sort the statements by subject, pred, object -// - do stuff about the docu first and then (or first) about its primary topic. - -__Serializer.prototype.rootSubjects = function(sts) { + while(i < p.length) + if(sz.prefixchars.indexOf(p[i])) + i++; + else + break; + p = p.slice(0, i); + if(p.length < 6 && canUse(p)) return pok; // exact i sbest + if(canUse(p.slice(0, 3))) return pok; + if(canUse(p.slice(0, 2))) return pok; + if(canUse(p.slice(0, 4))) return pok; + if(canUse(p.slice(0, 1))) return pok; + if(canUse(p.slice(0, 5))) return pok; + for(var i = 0;; i++) if(canUse(p.slice(0, 3) + i)) return pok; + } + + + + // Todo: + // - Sort the statements by subject, pred, object + // - do stuff about the docu first and then (or first) about its primary topic. + __Serializer.prototype.rootSubjects = function (sts) { var incoming = {}; var subjects = {}; var sz = this; - - for (var i = 0; i<sts.length; i++) { - var x = sts[i].object; - if (!incoming[x]) incoming[x] = []; - incoming[x].push(sts[i].subject) // List of things which will cause this to be printed - var ss = subjects[sz.toStr(sts[i].subject)]; // Statements with this as subject - if (!ss) ss = []; - ss.push(sts[i]); - subjects[this.toStr(sts[i].subject)] = ss; // Make hash. @@ too slow for formula? - tabulator.log.debug(' sz potential subject: '+sts[i].subject) + var allBnodes = {}; + + /* This scan is to find out which nodes will have to be the roots of trees + ** in the serialized form. This will be any symbols, and any bnodes + ** which hve more or less than one incoming arc, and any bnodes which have + ** one incoming arc but it is an uninterrupted loop of such nodes back to itself. + ** This should be kept linear time with repect to the number of statements. + ** Note it does not use any indexing of the store. + */ + + + tabulator.log.debug('serialize.js Find bnodes with only one incoming arc\n') + for(var i = 0; i < sts.length; i++) { + var st = sts[i]; + [st.subject, st.predicate, st.object].map(function (y) { + if(y.termType == 'bnode') { + allBnodes[y.toNT()] = true + } + }); + var x = sts[i].object; + if(!incoming[x]) incoming[x] = []; + incoming[x].push(st.subject) // List of things which will cause this to be printed + var ss = subjects[sz.toStr(st.subject)]; // Statements with this as subject + if(!ss) ss = []; + ss.push(st); + subjects[this.toStr(st.subject)] = ss; // Make hash. @@ too slow for formula? + //$rdf.log.debug(' sz potential subject: '+sts[i].subject) } var roots = []; - var loopBreakers = {}; - - function accountedFor(x, start) { - if (x.termType != 'bnode') return true; // will be subject - var zz = incoming[x]; - if (!zz || zz.length != 1) return true; - if (loopBreakers[x]) return true; - if (zz[0] == start) return false; - return accountedFor(zz[0], start); - } - for (var xNT in subjects) { - var x = sz.fromStr(xNT); - if ((x.termType != 'bnode') || !incoming[x] || (incoming[x].length != 1)){ - roots.push(x); - tabulator.log.debug(' sz actual subject -: ' + x) - continue; + for(var xNT in subjects) { + var x = sz.fromStr(xNT); + if((x.termType != 'bnode') || !incoming[x] || (incoming[x].length != 1)) { + roots.push(x); + //$rdf.log.debug(' sz actual subject -: ' + x) + continue; + } + } + this.incoming = incoming; // Keep for serializing @@ Bug for nested formulas + //////////// New bit for CONNECTED bnode loops:frootshash + // This scans to see whether the serialization is gpoing to lead to a bnode loop + // and at the same time accumulates a list of all bnodes mentioned. + // This is in fact a cut down N3 serialization + /* + tabulator.log.debug('serialize.js Looking for connected bnode loops\n') + for (var i=0; i<sts.length; i++) { // @@TBL + // dump('\t'+sts[i]+'\n'); + } + var doneBnodesNT = {}; + function dummyPropertyTree(subject, subjects, rootsHash) { + // dump('dummyPropertyTree('+subject+'...)\n'); + var sts = subjects[sz.toStr(subject)]; // relevant statements + for (var i=0; i<sts.length; i++) { + dummyObjectTree(sts[i].object, subjects, rootsHash); } - if (accountedFor(incoming[x][0]), x) { - continue; + } + + // Convert a set of statements into a nested tree of lists and strings + // @param force, "we know this is a root, do it anyway. It isn't a loop." + function dummyObjectTree(obj, subjects, rootsHash, force) { + // dump('dummyObjectTree('+obj+'...)\n'); + if (obj.termType == 'bnode' && (subjects[sz.toStr(obj)] && + (force || (rootsHash[obj.toNT()] == undefined )))) {// and there are statements + if (doneBnodesNT[obj.toNT()]) { // Ah-ha! a loop + throw "Serializer: Should be no loops "+obj; + } + doneBnodesNT[obj.toNT()] = true; + return dummyPropertyTree(obj, subjects, rootsHash); + } + return dummyTermToN3(obj, subjects, rootsHash); + } + + // Scan for bnodes nested inside lists too + function dummyTermToN3(expr, subjects, rootsHash) { + if (expr.termType == 'bnode') doneBnodesNT[expr.toNT()] = true; + tabulator.log.debug('serialize: seen '+expr); + if (expr.termType == 'collection') { + for (i=0; i<expr.elements.length; i++) { + if (expr.elements[i].termType == 'bnode') + dummyObjectTree(expr.elements[i], subjects, rootsHash); + } + return; } - roots.push(x); - tabulator.log.debug(' sz potential subject *: '+sts[i].subject) - loopBreakers[x] = 1; } - this.incoming = incoming; // Keep for serializing - return [roots, subjects]; -} -//////////////////////////////////////////////////////// + // The tree for a subject + function dummySubjectTree(subject, subjects, rootsHash) { + // dump('dummySubjectTree('+subject+'...)\n'); + if (subject.termType == 'bnode' && !incoming[subject]) + return dummyObjectTree(subject, subjects, rootsHash, true); // Anonymous bnode subject + dummyTermToN3(subject, subjects, rootsHash); + dummyPropertyTree(subject, subjects, rootsHash); + } +*/ + // Now do the scan using existing roots + tabulator.log.debug('serialize.js Dummy serialize to check for missing nodes') + var rootsHash = {}; + for(var i = 0; i < roots.length; i++) rootsHash[roots[i].toNT()] = true; + /* + for (var i=0; i<roots.length; i++) { + var root = roots[i]; + dummySubjectTree(root, subjects, rootsHash); + } + // dump('Looking for mising bnodes...\n') + +// Now in new roots for anythig not acccounted for +// Now we check for any bndoes which have not been covered. +// Such bnodes must be in isolated rings of pure bnodes. +// They each have incoming link of 1. + + tabulator.log.debug('serialize.js Looking for connected bnode loops\n') + for (;;) { + var bnt; + var found = null; + for (bnt in allBnodes) { // @@ Note: not repeatable. No canonicalisation + if (doneBnodesNT[bnt]) continue; + found = bnt; // Ah-ha! not covered + break; + } + if (found == null) break; // All done - no bnodes left out/ + // dump('Found isolated bnode:'+found+'\n'); + doneBnodesNT[bnt] = true; + var root = this.store.fromNT(found); + roots.push(root); // Add a new root + rootsHash[found] = true; + tabulator.log.debug('isolated bnode:'+found+', subjects[found]:'+subjects[found]+'\n'); + if (subjects[found] == undefined) { + for (var i=0; i<sts.length; i++) { + // dump('\t'+sts[i]+'\n'); + } + throw "Isolated node should be a subject" +found; + } + dummySubjectTree(root, subjects, rootsHash); // trace out the ring + } + // dump('Done bnode adjustments.\n') +*/ + return { + 'roots': roots, + 'subjects': subjects, + 'rootsHash': rootsHash, + 'incoming': incoming + }; + } -__Serializer.prototype.toN3 = function(f) { + //////////////////////////////////////////////////////// + __Serializer.prototype.toN3 = function (f) { return this.statementsToN3(f.statements); -} + } -__Serializer.prototype._notQNameChars = "\t\r\n !\"#$%&'()*.,+/;<=>?@[\\]^`{|}~"; -__Serializer.prototype._notNameChars = - ( __Serializer.prototype._notQNameChars + ":" ) ; + __Serializer.prototype._notQNameChars = "\t\r\n !\"#$%&'()*.,+/;<=>?@[\\]^`{|}~"; + __Serializer.prototype._notNameChars = (__Serializer.prototype._notQNameChars + ":"); - -__Serializer.prototype.statementsToN3 = function(sts) { + + __Serializer.prototype.statementsToN3 = function (sts) { var indent = 4; var width = 80; - // var subjects = null; // set later var sz = this; var namespaceCounts = []; // which have been used - - predMap = { - 'http://www.w3.org/2002/07/owl#sameAs': '=', - 'http://www.w3.org/2000/10/swap/log#implies': '=>', - 'http://www.w3.org/1999/02/22-rdf-syntax-ns#type': 'a' + var predMap = { + 'http://www.w3.org/2002/07/owl#sameAs': '=', + 'http://www.w3.org/2000/10/swap/log#implies': '=>', + 'http://www.w3.org/1999/02/22-rdf-syntax-ns#type': 'a' } - - - - ////////////////////////// Arrange the bits of text - var spaces=function(n) { - var s=''; - for(var i=0; i<n; i++) s+=' '; + + + ////////////////////////// Arrange the bits of text + var spaces = function (n) { + var s = ''; + for(var i = 0; i < n; i++) s += ' '; return s - } + } - treeToLine = function(tree) { + var treeToLine = function (tree) { var str = ''; - for (var i=0; i<tree.length; i++) { - var branch = tree[i]; - var s2 = (typeof branch == 'string') ? branch : treeToLine(branch); - if (i!=0 && s2 != ',' && s2 != ';' && s2 != '.') str += ' '; - str += s2; + for(var i = 0; i < tree.length; i++) { + var branch = tree[i]; + var s2 = (typeof branch == 'string') ? branch : treeToLine(branch); + if(i != 0 && s2 != ',' && s2 != ';' && s2 != '.') str += ' '; + str += s2; } return str; - } - - // Convert a nested tree of lists and strings to a string - treeToString = function(tree, level) { + } + + // Convert a nested tree of lists and strings to a string + var treeToString = function (tree, level) { var str = ''; var lastLength = 100000; - if (!level) level = 0; - for (var i=0; i<tree.length; i++) { - var branch = tree[i]; - if (typeof branch != 'string') { - var substr = treeToString(branch, level +1); - if ( - substr.length < 10*(width-indent*level) - && substr.indexOf('"""') < 0) {// Don't mess up multiline strings - var line = treeToLine(branch); - if (line.length < (width-indent*level)) { - branch = ' '+line; // @@ Hack: treat as string below - substr = '' - } - } - if (substr) lastLength = 10000; - str += substr; + if(!level) level = 0; + for(var i = 0; i < tree.length; i++) { + var branch = tree[i]; + if(typeof branch != 'string') { + var substr = treeToString(branch, level + 1); + if(substr.length < 10 * (width - indent * level) + && substr.indexOf('"""') < 0) { + // Don't mess up multiline strings + var line = treeToLine(branch); + if(line.length < (width - indent * level)) { + branch = ' ' + line; // @@ Hack: treat as string below + substr = '' + } } - if (typeof branch == 'string') { - if (branch.length == '1' && str.slice(-1) == '\n') { - if (",.;".indexOf(branch) >=0) { - str = str.slice(0,-1) + branch + '\n'; // slip punct'n on end - lastLength += 1; - continue; - } else if ("])}".indexOf(branch) >=0) { - str = str.slice(0,-1) + ' ' + branch + '\n'; - lastLength += 2; - continue; - } - } - if (lastLength < (indent*level+4)) { // continue - str = str.slice(0,-1) + ' ' + branch + '\n'; - lastLength += branch.length + 1; - } else { - var line = spaces(indent*level) +branch; - str += line +'\n'; - lastLength = line.length; - } - - } else { // not string + if(substr) lastLength = 10000; + str += substr; + } + if(typeof branch == 'string') { + if(branch.length == '1' && str.slice(-1) == '\n') { + if(",.;".indexOf(branch) >= 0) { + str = str.slice(0, -1) + branch + '\n'; // slip punct'n on end + lastLength += 1; + continue; + } else if("])}".indexOf(branch) >= 0) { + str = str.slice(0, -1) + ' ' + branch + '\n'; + lastLength += 2; + continue; + } + } + if(lastLength < (indent * level + 4)) { // continue + str = str.slice(0, -1) + ' ' + branch + '\n'; + lastLength += branch.length + 1; + } else { + var line = spaces(indent * level) + branch; + str += line + '\n'; + lastLength = line.length; } + + } else { // not string + } } return str; - }; + }; ////////////////////////////////////////////// Structure for N3 - - + + // Convert a set of statements into a nested tree of lists and strings function statementListToTree(statements) { - // print('Statement tree for '+statements.length); - var res = []; - var pair = sz.rootSubjects(statements); - var roots = pair[0]; - // print('Roots: '+roots) - var subjects = pair[1]; - var results = [] - for (var i=0; i<roots.length; i++) { - var root = roots[i]; - results.push(subjectTree(root, subjects)) - } - return results; + // print('Statement tree for '+statements.length); + var res = []; + var stats = sz.rootSubjects(statements); + var roots = stats.roots; + var results = [] + for(var i = 0; i < roots.length; i++) { + var root = roots[i]; + results.push(subjectTree(root, stats)) + } + return results; } - + // The tree for a subject - function subjectTree(subject, subjects) { - if (subject.termType == 'bnode' && !sz.incoming[subject]) - return objectTree(subject, subjects).concat(["."]); // Anonymous bnode subject - return [ termToN3(subject, subjects) ].concat([propertyTree(subject, subjects)]).concat(["."]); + function subjectTree(subject, stats) { + if(subject.termType == 'bnode' && !stats.incoming[subject]) + return objectTree(subject, stats, true).concat(["."]); // Anonymous bnode subject + return [termToN3(subject, stats)].concat([propertyTree(subject, stats)]).concat(["."]); } - + // The property tree for a single subject or anonymous node - function propertyTree(subject, subjects) { - // print('Proprty tree for '+subject); - var results = [] - var lastPred = null; - var sts = subjects[sz.toStr(subject)]; // relevant statements - if (typeof sts == 'undefined') { - alert('Cant find statements for '+subject); - } - sts.sort(); - var objects = []; - for (var i=0; i<sts.length; i++) { - var st = sts[i]; - if (st.predicate.uri == lastPred) { - objects.push(','); - } else { - if (lastPred) { - results=results.concat([objects]).concat([';']); - objects = []; - } - results.push(predMap[st.predicate.uri] ? - predMap[st.predicate.uri] : termToN3(st.predicate, subjects)); - } - lastPred = st.predicate.uri; - objects.push(objectTree(st.object, subjects)); + function propertyTree(subject, stats) { + // print('Proprty tree for '+subject); + var results = [] + var lastPred = null; + var sts = stats.subjects[sz.toStr(subject)]; // relevant statements + if(typeof sts == 'undefined') { + throw('Cant find statements for ' + subject); + } + sts.sort(); + var objects = []; + for(var i = 0; i < sts.length; i++) { + var st = sts[i]; + if(st.predicate.uri == lastPred) { + objects.push(','); + } else { + if(lastPred) { + results = results.concat([objects]).concat([';']); + objects = []; + } + results.push(predMap[st.predicate.uri] ? + predMap[st.predicate.uri] : + termToN3(st.predicate, stats)); } - results=results.concat([objects]); - return results; + lastPred = st.predicate.uri; + objects.push(objectTree(st.object, stats)); + } + results = results.concat([objects]); + return results; } - // Convert a set of statements into a nested tree of lists and strings - function objectTree(obj, subjects) { - if (obj.termType == 'bnode' && subjects[sz.toStr(obj)]) // and there are statements - return ['['].concat(propertyTree(obj, subjects)).concat([']']); - return termToN3(obj, subjects); + function objectTree(obj, stats, force) { + if(obj.termType == 'bnode' + && stats.subjects[sz.toStr(obj)] + // and there are statements + && (force || stats.rootsHash[obj.toNT()] == undefined)) // and not a root + return ['['].concat(propertyTree(obj, stats)).concat([']']); + return termToN3(obj, stats); } - - ////////////////////////////////////////////// Atomic Terms - - // Deal with term level things and nesting with no bnode structure - - function termToN3(expr, subjects) { - switch(expr.termType) { - case 'bnode': - case 'variable': return expr.toNT(); - case 'literal': - var str = stringToN3(expr.value); - if (expr.lang) str+= '@' + expr.lang; - if (expr.dt) str+= '^^' + termToN3(expr.dt, subjects); - return str; - case 'symbol': - return symbolToN3(expr.uri); - case 'formula': - var res = ['{']; - res = res.concat(statementListToTree(expr.statements)); - return res.concat(['}']); - case 'collection': - var res = ['(']; - for (i=0; i<expr.elements.length; i++) { - res.push( [ objectTree(expr.elements[i], subjects) ]); - } - res.push(')'); - return res; - - default: - throw "Internal: termToN3 cannot handle "+expr+" of termType+"+expr.termType - return ''+expr; + + function termToN3(expr, stats) { + switch(expr.termType) { + case 'bnode': + case 'variable': + return expr.toNT(); + case 'literal': + var str = stringToN3(expr.value); + if(expr.lang) str += '@' + expr.lang; + if(expr.datatype) str += '^^' + termToN3(expr.datatype, stats); + return str; + case 'symbol': + return symbolToN3(expr.uri); + case 'formula': + var res = ['{']; + res = res.concat(statementListToTree(expr.statements)); + return res.concat(['}']); + case 'collection': + var res = ['(']; + for(i = 0; i < expr.elements.length; i++) { + res.push([objectTree(expr.elements[i], stats)]); } + res.push(')'); + return res; + + default: + throw "Internal: termToN3 cannot handle " + expr + " of termType+" + expr.termType + return '' + expr; + } } - - function symbolToN3(uri) { // c.f. symbolString() in notation3.py - var j = uri.indexOf('#'); - if (j<0 && sz.flags.indexOf('/') < 0) { - j = uri.lastIndexOf('/'); + + ////////////////////////////////////////////// Atomic Terms + // Deal with term level things and nesting with no bnode structure + function symbolToN3(uri) { // c.f. symbolString() in notation3.py + var j = uri.indexOf('#'); + if(j < 0 && sz.flags.indexOf('/') < 0) { + j = uri.lastIndexOf('/'); + } + if(j >= 0 && sz.flags.indexOf('p') < 0) { // Can split at namespace + var canSplit = true; + for(var k = j + 1; k < uri.length; k++) { + if(__Serializer.prototype._notNameChars.indexOf(uri[k]) >= 0) { + canSplit = false; + break; + } } - if (j >= 0 && sz.flags.indexOf('p') < 0) { // Can split at namespace - var canSplit = true; - for (var k=j+1; k<uri.length; k++) { - if (__Serializer.prototype._notNameChars.indexOf(uri[k]) >=0) { - canSplit = false; break; - } - } - if (canSplit) { - var localid = uri.slice(j+1); - var namesp = uri.slice(0,j+1); - if (sz.defaultNamespace && sz.defaultNamespace == namesp - && sz.flags.indexOf('d') < 0) {// d -> suppress default - if (sz.flags.indexOf('k') >= 0 && - sz.keyords.indexOf(localid) <0) - return localid; - return ':' + localid; - } - var prefix = sz.prefixes[namesp]; - if (prefix) { - namespaceCounts[namesp] = true; - return prefix + ':' + localid; - } - if (uri.slice(0, j) == sz.base) - return '<#' + localid + '>'; - // Fall though if can't do qname - } + if(canSplit) { + var localid = uri.slice(j + 1); + var namesp = uri.slice(0, j + 1); + if(sz.defaultNamespace + && sz.defaultNamespace == namesp + && sz.flags.indexOf('d') < 0) { // d -> suppress default + if(sz.flags.indexOf('k') >= 0 + && sz.keyords.indexOf(localid) < 0) + return localid; + return ':' + localid; + } + var prefix = sz.prefixes[namesp]; + if(prefix) { + namespaceCounts[namesp] = true; + return prefix + ':' + localid; + } + if(uri.slice(0, j) == sz.base) + return '<#' + localid + '>'; + // Fall though if can't do qname } - if (sz.flags.indexOf('r') < 0 && sz.base) - uri = Util.uri.refTo(sz.base, uri); - else if (sz.flags.indexOf('u') >= 0) - uri = backslashUify(uri); - else uri = hexify(uri); - return '<'+uri+'>'; + } + if(sz.flags.indexOf('r') < 0 && sz.base) + uri = $rdf.Util.uri.refTo(sz.base, uri); + else if(sz.flags.indexOf('u') >= 0) + uri = backslashUify(uri); + else uri = hexify(uri); + return '<' + uri + '>'; } - + function prefixDirectives() { - str = ''; - if (sz.defaultNamespace) - str += '@prefix : <'+sz.defaultNamespace+'>.\n'; - for (var ns in namespaceCounts) { - str += '@prefix ' + sz.prefixes[ns] + ': <'+ns+'>.\n'; - } - return str + '\n'; + var str = ''; + if(sz.defaultNamespace) + str += '@prefix : <' + sz.defaultNamespace + '>.\n'; + for(var ns in namespaceCounts) { + str += '@prefix ' + sz.prefixes[ns] + ': <' + ns + '>.\n'; + } + return str + '\n'; } - + // stringToN3: String escaping for N3 // var forbidden1 = new RegExp(/[\\"\b\f\r\v\t\n\u0080-\uffff]/gm); var forbidden3 = new RegExp(/[\\"\b\f\r\v\u0080-\uffff]/gm); + function stringToN3(str, flags) { - if (!flags) flags = "e"; - var res = '', i=0, j=0; - var delim; - var forbidden; - if (str.length > 20 // Long enough to make sense - && str.slice(-1) != '"' // corner case' - && flags.indexOf('n') <0 // Force single line - && (str.indexOf('\n') >0 || str.indexOf('"') > 0)) { - delim = '"""'; - forbidden = forbidden3; + if(!flags) flags = "e"; + var res = '', i = 0, j = 0; + var delim; + var forbidden; + if(str.length > 20 // Long enough to make sense + && str.slice(-1) != '"' // corner case' + && flags.indexOf('n') < 0 // Force single line + && (str.indexOf('\n') > 0 || str.indexOf('"') > 0)) { + delim = '"""'; + forbidden = forbidden3; + } else { + delim = '"'; + forbidden = forbidden1; + } + for(i = 0; i < str.length;) { + forbidden.lastIndex = 0; + var m = forbidden.exec(str.slice(i)); + if(m == null) break; + j = i + forbidden.lastIndex - 1; + res += str.slice(i, j); + var ch = str[j]; + if(ch == '"' && delim == '"""' && str.slice(j, j + 3) != '"""') { + res += ch; } else { - delim = '"'; - forbidden = forbidden1; - } - for(i=0; i<str.length;) { - forbidden.lastIndex = 0; - var m = forbidden.exec(str.slice(i)); - if (m == null) break; - j = i + forbidden.lastIndex -1; - res += str.slice(i,j); - var ch = str[j]; - if (ch=='"' && delim == '"""' && str.slice(j,j+3) != '"""') { - res += ch; - } else { - var k = '\b\f\r\t\v\n\\"'.indexOf(ch); // No escaping of bell (7)? - if (k >= 0) { - res += "\\" + 'bfrtvn\\"'[k]; - } else { - if (flags.indexOf('e')>=0) { - res += '\\u' + ('000'+ - ch.charCodeAt(0).toString(16).toLowerCase()).slice(-4) - } else { // no 'e' flag - res += ch; - } - } + var k = '\b\f\r\t\v\n\\"'.indexOf(ch); // No escaping of bell (7)? + if(k >= 0) { + res += "\\" + 'bfrtvn\\"' [k]; + } else { + if(flags.indexOf('e') >= 0) { + res += '\\u' + ('000' + ch.charCodeAt(0).toString(16).toLowerCase()).slice(-4) + } else { // no 'e' flag + res += ch; } - i = j+1; + } } - return delim + res + str.slice(i) + delim + i = j + 1; + } + return delim + res + str.slice(i) + delim } // Body of toN3: - var tree = statementListToTree(sts); return prefixDirectives() + treeToString(tree, -1); - -} - -// String ecaping utilities - -function hexify(str) { // also used in parser -// var res = ''; -// for (var i=0; i<str.length; i++) { -// k = str.charCodeAt(i); -// if (k>126 || k<33) -// res += '%' + ('0'+n.toString(16)).slice(-2); // convert to upper? -// else -// res += str[i]; -// } -// return res; - return encodeURI(str); -} - - -function backslashUify(str) { - var res = ''; - for (var i=0; i<str.length; i++) { - k = str.charCodeAt(i); - if (k>65535) - res += '\\U' + ('00000000'+n.toString(16)).slice(-8); // convert to upper? - else if (k>126) - res += '\\u' + ('0000'+n.toString(16)).slice(-4); - else - res += str[i]; + + } + + // String ecaping utilities + function hexify(str) { // also used in parser + // var res = ''; + // for (var i=0; i<str.length; i++) { + // k = str.charCodeAt(i); + // if (k>126 || k<33) + // res += '%' + ('0'+n.toString(16)).slice(-2); // convert to upper? + // else + // res += str[i]; + // } + // return res; + return encodeURI(str); + } + + + function backslashUify(str) { + var res = '', k; + for(var i = 0; i < str.length; i++) { + k = str.charCodeAt(i); + if(k > 65535) + res += '\\U' + ('00000000' + n.toString(16)).slice(-8); // convert to upper? + else if(k > 126) + res += '\\u' + ('0000' + n.toString(16)).slice(-4); + else + res += str[i]; } return res; -} - + } -//////////////////////////////////////////////// XML serialization -__Serializer.prototype.statementsToXML = function(sts) { + //////////////////////////////////////////////// XML serialization + __Serializer.prototype.statementsToXML = function (sts) { var indent = 4; var width = 80; - // var subjects = null; // set later var sz = this; var namespaceCounts = []; // which have been used namespaceCounts['http://www.w3.org/1999/02/22-rdf-syntax-ns#'] = true; ////////////////////////// Arrange the bits of XML text - - var spaces=function(n) { - var s=''; - for(var i=0; i<n; i++) s+=' '; + var spaces = function (n) { + var s = ''; + for(var i = 0; i < n; i++) s += ' '; return s - } + } - XMLtreeToLine = function(tree) { + var XMLtreeToLine = function (tree) { var str = ''; - for (var i=0; i<tree.length; i++) { - var branch = tree[i]; - var s2 = (typeof branch == 'string') ? branch : XMLtreeToLine(branch); - str += s2; + for(var i = 0; i < tree.length; i++) { + var branch = tree[i]; + var s2 = (typeof branch == 'string') ? branch : XMLtreeToLine(branch); + str += s2; } return str; - } - - // Convert a nested tree of lists and strings to a string - XMLtreeToString = function(tree, level) { + } + + // Convert a nested tree of lists and strings to a string + var XMLtreeToString = function (tree, level) { var str = ''; var lastLength = 100000; - if (!level) level = 0; - for (var i=0; i<tree.length; i++) { - var branch = tree[i]; - if (typeof branch != 'string') { - var substr = XMLtreeToString(branch, level +1); - if ( - substr.length < 10*(width-indent*level) - && substr.indexOf('"""') < 0) {// Don't mess up multiline strings - var line = XMLtreeToLine(branch); - if (line.length < (width-indent*level)) { - branch = ' '+line; // @@ Hack: treat as string below - substr = '' - } - } - if (substr) lastLength = 10000; - str += substr; + if(!level) level = 0; + for(var i = 0; i < tree.length; i++) { + var branch = tree[i]; + if(typeof branch != 'string') { + var substr = XMLtreeToString(branch, level + 1); + if(substr.length < 10 * (width - indent * level) + && substr.indexOf('"""') < 0) { + // Don't mess up multiline strings + var line = XMLtreeToLine(branch); + if(line.length < (width - indent * level)) { + branch = ' ' + line; // @@ Hack: treat as string below + substr = '' + } } - if (typeof branch == 'string') { - if (lastLength < (indent*level+4)) { // continue - str = str.slice(0,-1) + ' ' + branch + '\n'; - lastLength += branch.length + 1; - } else { - var line = spaces(indent*level) +branch; - str += line +'\n'; - lastLength = line.length; - } - - } else { // not string + if(substr) lastLength = 10000; + str += substr; + } + if(typeof branch == 'string') { + if(lastLength < (indent * level + 4)) { // continue + str = str.slice(0, -1) + ' ' + branch + '\n'; + lastLength += branch.length + 1; + } else { + var line = spaces(indent * level) + branch; + str += line + '\n'; + lastLength = line.length; } + + } else { // not string + } } return str; - }; + }; function statementListToXMLTree(statements) { - sz.suggestPrefix('rdf', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#'); - var res = []; - var pair = sz.rootSubjects(statements); - var roots = pair[0]; - var subjects = pair[1]; - results = [] - for (var i=0; i<roots.length; i++) { - root = roots[i]; - results.push(subjectXMLTree(root, subjects)) - } - return results; + sz.suggestPrefix('rdf', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#'); + var stats = sz.rootSubjects(statements); + var roots = stats.roots; + var results = [], root; + for(var i = 0; i < roots.length; i++) { + root = roots[i]; + results.push(subjectXMLTree(root, stats)) + } + return results; } - + function escapeForXML(str) { - if (typeof str == 'undefined') return '@@@undefined@@@@'; - return str.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/"/g, '&quot;'); + if(typeof str == 'undefined') return '@@@undefined@@@@'; + return str.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/"/g, '&quot;'); } function relURI(term) { - return escapeForXML((sz.base) ? Util.uri.refTo(this.base, term.uri) : term.uri); + return escapeForXML((sz.base) ? $rdf.Util.uri.refTo(this.base, term.uri) : term.uri); } // The tree for a subject - function subjectXMLTree(subject, subjects, referenced) { - const liPrefix = 'http://www.w3.org/1999/02/22-rdf-syntax-ns#_'; - - var type = null; - - var results = [] - var sts = subjects[sz.toStr(subject)]; // relevant statements - // Sort only on the predicate, leave the order at object - // level undisturbed. This leaves multilingual content in - // the order of entry (for partner literals), which helps - // readability. - // - // For the predicate sort, we attempt to split the uri - // as a hint to the sequence, as sequenced items seems - // to be of the form http://example.com#_1, http://example.com#_2, - // et cetera. Probably not the most optimal of fixes, but - // it does work. - sts.sort(function(a,b){ - var aa = a.predicate.uri.split('#_'); - var bb = a.predicate.uri.split('#_'); - if (aa[0] > bb[0]) { - return 1; - } else if (aa[0] < bb[0]) { - return -1; - } else { - if ("undefined" !== typeof aa[1] && "undefined" !== typeof bb[1]) { - if (parseInt(aa[1], 10) > parseInt(bb[1], 10)) { - return 1; - } else if (parseInt(aa[1], 10) < parseInt(bb[1], 10)) { - return -1; - } - } - } - return 0; - }); - for (var i=0; i<sts.length; i++) { - var st = sts[i]; - - if(st.predicate.uri == 'http://www.w3.org/1999/02/22-rdf-syntax-ns#type' && !type && st.object.termType == "symbol") { - // look for a type - type = st.object; - } else { - // see whether predicate can be replaced with "li" - if(st.predicate.uri.substr(0, liPrefix.length) == liPrefix) { - var number = st.predicate.uri.substr(liPrefix.length); - - // make sure these are actually numeric list items - var intNumber = parseInt(number); - if(number == intNumber.toString()) { - // was numeric; don't need to worry about ordering since we've already - // sorted the statements - st.predicate = RDFSymbol('http://www.w3.org/1999/02/22-rdf-syntax-ns#li'); - } - } - - switch (st.object.termType) { - case 'bnode': - if(sz.incoming[st.object].length == 1) { - results = results.concat(['<'+qname(st.predicate)+'>', - subjectXMLTree(st.object, subjects, true), - '</'+qname(st.predicate)+'>']); - } else { - results = results.concat(['<'+qname(st.predicate)+' rdf:nodeID="' - +st.object.toNT().slice(2)+'"/>']); - } - break; - case 'symbol': - results = results.concat(['<'+qname(st.predicate)+' rdf:resource="' - + relURI(st.object)+'"/>']); - break; - case 'literal': - results = results.concat(['<'+qname(st.predicate) - + (st.object.dt ? ' rdf:datatype="'+escapeForXML(st.object.dt.uri)+'"' : '') - + (st.object.lang ? ' xml:lang="'+st.object.lang+'"' : '') - + '>' + escapeForXML(st.object.value) - + '</'+qname(st.predicate)+'>']); - break; - case 'collection': - results = results.concat(['<'+qname(st.predicate)+' rdf:parseType="Collection">', - collectionXMLTree(st.object, subjects), - '</'+qname(st.predicate)+'>']); - break; - default: - throw "Can't serialize object of type "+st.object.termType +" into XML"; - - } // switch - } + function subjectXMLTree(subject, stats) { + const liPrefix = 'http://www.w3.org/1999/02/22-rdf-syntax-ns#_'; + var results = []; + var type = null, t, st; + var sts = stats.subjects[sz.toStr(subject)]; // relevant statements + // Sort only on the predicate, leave the order at object + // level undisturbed. This leaves multilingual content in + // the order of entry (for partner literals), which helps + // readability. + // + // For the predicate sort, we attempt to split the uri + // as a hint to the sequence, as sequenced items seems + // to be of the form http://example.com#_1, http://example.com#_2, + // et cetera. Probably not the most optimal of fixes, but + // it does work. + sts.sort(function (a, b) { + var aa = a.predicate.uri.split('#_'); + var bb = a.predicate.uri.split('#_'); + if(aa[0] > bb[0]) { + return 1; + } else if(aa[0] < bb[0]) { + return -1; + } else if("undefined" !== typeof aa[1] && "undefined" !== typeof bb[1]) { + if(parseInt(aa[1], 10) > parseInt(bb[1], 10)) { + return 1; + } else if(parseInt(aa[1], 10) < parseInt(bb[1], 10)) { + return -1; + } } - - var tag = type ? qname(type) : 'rdf:Description'; - - attrs = ''; - if (subject.termType == 'bnode') { - if(!referenced || sz.incoming[subject].length != 1) { // not an anonymous bnode - attrs = ' rdf:nodeID="'+subject.toNT().slice(2)+'"'; - } + return 0; + }); + + for(var i = 0; i < sts.length; i++) { + st = sts[i]; + if(st.predicate.uri == 'http://www.w3.org/1999/02/22-rdf-syntax-ns#type' && !type && st.object.termType == "symbol") { + // look for a type + type = st.object; } else { - attrs = ' rdf:about="'+ relURI(subject)+'"'; + // see whether predicate can be replaced with "li" + if(st.predicate.uri.substr(0, liPrefix.length) == liPrefix) { + var number = st.predicate.uri.substr(liPrefix.length); + // make sure these are actually numeric list items + var intNumber = parseInt(number); + if(number == intNumber.toString()) { + // was numeric; don't need to worry about ordering since we've already + // sorted the statements + st.predicate = $rdf.Symbol('http://www.w3.org/1999/02/22-rdf-syntax-ns#li'); + } + } + t = qname(st.predicate); + switch(st.object.termType) { + case 'bnode': + if(sz.incoming[st.object].length == 1) { + results = results.concat(['<' + t + '>', + subjectXMLTree(st.object, stats), + '</' + t + '>']); + } else { + results = results.concat(['<' + t + ' rdf:nodeID="' + + st.object.toNT().slice(2) + '"/>']); + } + break; + case 'symbol': + results = results.concat(['<' + t + ' rdf:resource="' + + relURI(st.object) + '"/>']); + break; + case 'literal': + results = results.concat(['<' + t + + (st.object.dt ? ' rdf:datatype="' + escapeForXML(st.object.dt.uri) + '"' : '') + + (st.object.lang ? ' xml:lang="' + st.object.lang + '"' : '') + + '>' + escapeForXML(st.object.value) + + '</' + t + '>']); + break; + case 'collection': + results = results.concat(['<' + t + ' rdf:parseType="Collection">', + collectionXMLTree(st.object, stats), + '</' + t + '>']); + break; + default: + throw "Can't serialize object of type " + st.object.termType + " into XML"; + } // switch } + } - return [ '<' + tag + attrs + '>' ].concat([results]).concat(["</"+ tag +">"]); - } - - function collectionXMLTree(subject, subjects) { - res = [] - for (var i=0; i< subject.elements.length; i++) { - res.push(subjectXMLTree(subject.elements[i], subjects)); - } - return res; + var tag = type ? qname(type) : 'rdf:Description'; + + var attrs = ''; + if(subject.termType == 'bnode') { + if(sz.incoming[subject].length != 1) { // not an anonymous bnode + attrs = ' rdf:nodeID="' + subject.toNT().slice(2) + '"'; + } + } else { + attrs = ' rdf:about="' + relURI(subject) + '"'; + } + + return ['<' + tag + attrs + '>'].concat([results]).concat(["</" + tag + ">"]); } - function qname(term) { - var uri = term.uri; + function collectionXMLTree(subject, stats) { + var res = [] + for(var i = 0; i < subject.elements.length; i++) { + res.push(subjectXMLTree(subject.elements[i], stats)); + } + return res; + } - var j = uri.indexOf('#'); - if (j<0 && sz.flags.indexOf('/') < 0) { - j = uri.lastIndexOf('/'); - } - if (j < 0) throw ("Cannot make qname out of <"+uri+">") + // The property tree for a single subject or anonymos node + function propertyXMLTree(subject, stats) { + var results = [] + var sts = stats.subjects[sz.toStr(subject)]; // relevant statements + if(sts == undefined) return results; // No relevant statements + sts.sort(); + for(var i = 0; i < sts.length; i++) { + var st = sts[i]; + switch(st.object.termType) { + case 'bnode': + if(stats.rootsHash[st.object.toNT()]) { // This bnode has been done as a root -- no content here @@ what bout first time + results = results.concat(['<' + qname(st.predicate) + ' rdf:nodeID="' + st.object.toNT().slice(2) + '">', + '</' + qname(st.predicate) + '>']); + } else { + results = results.concat(['<' + qname(st.predicate) + ' rdf:parseType="Resource">', + propertyXMLTree(st.object, stats), + '</' + qname(st.predicate) + '>']); + } + break; + case 'symbol': + results = results.concat(['<' + qname(st.predicate) + ' rdf:resource="' + + relURI(st.object) + '"/>']); + break; + case 'literal': + results = results.concat(['<' + qname(st.predicate) + + (st.object.datatype ? ' rdf:datatype="' + escapeForXML(st.object.datatype.uri) + '"' : '') + + (st.object.lang ? ' xml:lang="' + st.object.lang + '"' : '') + + '>' + escapeForXML(st.object.value) + + '</' + qname(st.predicate) + '>']); + break; + case 'collection': + results = results.concat(['<' + qname(st.predicate) + ' rdf:parseType="Collection">', + collectionXMLTree(st.object, stats), + '</' + qname(st.predicate) + '>']); + break; + default: + throw "Can't serialize object of type " + st.object.termType + " into XML"; + + } // switch + } + return results; + } - var canSplit = true; - for (var k=j+1; k<uri.length; k++) { - if (__Serializer.prototype._notNameChars.indexOf(uri[k]) >=0) { - throw ('Invalid character "'+uri[k] +'" cannot be in XML qname for URI: '+uri); - } - } - var localid = uri.slice(j+1); - var namesp = uri.slice(0,j+1); - if (sz.defaultNamespace && sz.defaultNamespace == namesp - && sz.flags.indexOf('d') < 0) {// d -> suppress default - return localid; + function qname(term) { + var uri = term.uri; + + var j = uri.indexOf('#'); + if(j < 0 && sz.flags.indexOf('/') < 0) { + j = uri.lastIndexOf('/'); + } + if(j < 0) throw("Cannot make qname out of <" + uri + ">") + + var canSplit = true; + for(var k = j + 1; k < uri.length; k++) { + if(__Serializer.prototype._notNameChars.indexOf(uri[k]) >= 0) { + throw('Invalid character "' + uri[k] + '" cannot be in XML qname for URI: ' + uri); } - var prefix = sz.prefixes[namesp]; - if (!prefix) prefix = sz.makeUpPrefix(namesp); - namespaceCounts[namesp] = true; - return prefix + ':' + localid; -// throw ('No prefix for namespace "'+namesp +'" for XML qname for '+uri+', namespaces: '+sz.prefixes+' sz='+sz); + } + var localid = uri.slice(j + 1); + var namesp = uri.slice(0, j + 1); + if(sz.defaultNamespace + && sz.defaultNamespace == namesp + && sz.flags.indexOf('d') < 0) { // d -> suppress default + return localid; + } + var prefix = sz.prefixes[namesp]; + if(!prefix) prefix = sz.makeUpPrefix(namesp); + namespaceCounts[namesp] = true; + return prefix + ':' + localid; + // throw ('No prefix for namespace "'+namesp +'" for XML qname for '+uri+', namespaces: '+sz.prefixes+' sz='+sz); } // Body of toXML: - var tree = statementListToXMLTree(sts); var str = '<rdf:RDF'; - if (sz.defaultNamespace) - str += ' xmlns="'+escapeForXML(sz.defaultNamespace)+'"'; - for (var ns in namespaceCounts) { - str += '\n xmlns:' + sz.prefixes[ns] + '="'+escapeForXML(ns)+'"'; + if(sz.defaultNamespace) + str += ' xmlns="' + escapeForXML(sz.defaultNamespace) + '"'; + for(var ns in namespaceCounts) { + str += '\n xmlns:' + sz.prefixes[ns] + '="' + escapeForXML(ns) + '"'; } str += '>'; - var tree2 = [str, tree, '</rdf:RDF>']; //@@ namespace declrations + var tree2 = [str, tree, '</rdf:RDF>']; //@@ namespace declrations return XMLtreeToString(tree2, -1); -} // End @@ body + } // End @@ body + return Serializer; +}(); +\ No newline at end of file diff --git a/chrome/content/zotero/xpcom/rdf/term.js b/chrome/content/zotero/xpcom/rdf/term.js @@ -7,139 +7,161 @@ // // W3C open source licence 2005. // - -RDFTracking = 0 // Are we requiring reasons for statements? - -//takes in an object and makes it an object if it's a literal -function makeTerm(val) { - // tabulator.log.debug("Making term from " + val) - if (typeof val == 'object') return val; - if (typeof val == 'string') return new RDFLiteral(val); - if (typeof val == 'number') return new RDFLiteral(val); // @@ differet types - if (typeof val == 'boolean') return new RDFLiteral(val?"1":"0", undefined, - RDFSymbol.prototype.XSDboolean); - if (typeof val == 'undefined') return undefined; - alert("Can't make term from " + val + " of type " + typeof val); -} - - // Symbol +$rdf.Empty = function () { + return this; +}; -function RDFEmpty() { - return this; -} -RDFEmpty.prototype.termType = 'empty' -RDFEmpty.prototype.toString = function () { return "()" } -RDFEmpty.prototype.toNT = function () { return "@@" } - -function RDFSymbol_toNT(x) { - return ("<" + x.uri + ">") -} - -function toNT() { - return RDFSymbol_toNT(this) -} +$rdf.Empty.prototype.termType = 'empty'; +$rdf.Empty.prototype.toString = function () { + return "()" +}; +$rdf.Empty.prototype.toNT = $rdf.Empty.prototype.toString; -function RDFSymbol(uri) { - this.uri = uri - return this +$rdf.Symbol = function (uri) { + this.uri = uri; + this.value = uri; // -- why? -tim + return this; } - -RDFSymbol.prototype.termType = 'symbol' -RDFSymbol.prototype.toString = toNT -RDFSymbol.prototype.toNT = toNT - -// Some precalculaued symbols - -RDFSymbol.prototype.XSDboolean = new RDFSymbol('http://www.w3.org/2001/XMLSchema#boolean'); -RDFSymbol.prototype.integer = new RDFSymbol('http://www.w3.org/2001/XMLSchema#integer'); - +$rdf.Symbol.prototype.termType = 'symbol'; +$rdf.Symbol.prototype.toString = function () { + return("<" + this.uri + ">"); +}; +$rdf.Symbol.prototype.toNT = $rdf.Symbol.prototype.toString; + +// Some precalculated symbols +$rdf.Symbol.prototype.XSDboolean = new $rdf.Symbol('http://www.w3.org/2001/XMLSchema#boolean'); +$rdf.Symbol.prototype.XSDdecimal = new $rdf.Symbol('http://www.w3.org/2001/XMLSchema#decimal'); +$rdf.Symbol.prototype.XSDfloat = new $rdf.Symbol('http://www.w3.org/2001/XMLSchema#float'); +$rdf.Symbol.prototype.XSDinteger = new $rdf.Symbol('http://www.w3.org/2001/XMLSchema#integer'); +$rdf.Symbol.prototype.XSDdateTime = new $rdf.Symbol('http://www.w3.org/2001/XMLSchema#dateTime'); +$rdf.Symbol.prototype.integer = new $rdf.Symbol('http://www.w3.org/2001/XMLSchema#integer'); // Used? // Blank Node +if(typeof $rdf.NextId != 'undefined') { + $rdf.log.error('Attempt to re-zero existing blank node id counter at ' + $rdf.NextId); +} else { + $rdf.NextId = 0; // Global genid +} +$rdf.NTAnonymousNodePrefix = "_:n"; -var RDFNextId = 0; // Gobal genid -RDFGenidPrefix = "genid:" -NTAnonymousNodePrefix = "_:n" - -function RDFBlankNode(id) { - /*if (id) +$rdf.BlankNode = function (id) { + /*if (id) this.id = id; else*/ - this.id = RDFNextId++ - return this -} - -RDFBlankNode.prototype.termType = 'bnode' + this.id = $rdf.NextId++; + this.value = id ? id : this.id.toString(); + return this +}; -RDFBlankNode.prototype.toNT = function() { - return NTAnonymousNodePrefix + this.id -} -RDFBlankNode.prototype.toString = RDFBlankNode.prototype.toNT +$rdf.BlankNode.prototype.termType = 'bnode'; +$rdf.BlankNode.prototype.toNT = function () { + return $rdf.NTAnonymousNodePrefix + this.id +}; +$rdf.BlankNode.prototype.toString = $rdf.BlankNode.prototype.toNT; // Literal +$rdf.Literal = function (value, lang, datatype) { + this.value = value + if(lang == "" || lang == null) this.lang = undefined; + else this.lang = lang; // string + if(datatype == null) this.datatype = undefined; + else this.datatype = datatype; // term + return this; +} + +$rdf.Literal.prototype.termType = 'literal' +$rdf.Literal.prototype.toString = function () { + return '' + this.value; +}; +$rdf.Literal.prototype.toNT = function () { + var str = this.value + if(typeof str != 'string') { + if(typeof str == 'number') return '' + str; + throw Error("Value of RDF literal is not string: " + str) + } + str = str.replace(/\\/g, '\\\\'); // escape backslashes + str = str.replace(/\"/g, '\\"'); // escape quotes + str = str.replace(/\n/g, '\\n'); // escape newlines + str = '"' + str + '"' //'; + if(this.datatype) { + str = str + '^^' + this.datatype.toNT() + } + if(this.lang) { + str = str + "@" + this.lang; + } + return str; +}; -function RDFLiteral(value, lang, datatype) { - this.value = value - this.lang=lang; // string - this.datatype=datatype; // term - this.toString = RDFLiteralToString - this.toNT = RDFLiteral_toNT - return this -} +$rdf.Collection = function () { + this.id = $rdf.NextId++; // Why need an id? For hashstring. + this.elements = []; + this.closed = false; +}; -RDFLiteral.prototype.termType = 'literal' +$rdf.Collection.prototype.termType = 'collection'; -function RDFLiteral_toNT() { - var str = this.value - if (typeof str != 'string') { - if (typeof str == 'number') return ''+str; - throw Error("Value of RDF literal is not string: "+str) - } - str = str.replace(/\\/g, '\\\\'); // escape - str = str.replace(/\"/g, '\\"'); - str = '"' + str + '"' //' +$rdf.Collection.prototype.toNT = function () { + return $rdf.NTAnonymousNodePrefix + this.id +}; - if (this.datatype){ - str = str + '^^' + this.datatype//.toNT() - } - if (this.lang) { - str = str + "@" + this.lang - } - return str -} +$rdf.Collection.prototype.toString = function () { + var str = '('; + for(var i = 0; i < this.elements.length; i++) + str += this.elements[i] + ' '; + return str + ')'; +}; -function RDFLiteralToString() { - return ''+this.value +$rdf.Collection.prototype.append = function (el) { + this.elements.push(el) } - -RDFLiteral.prototype.toString = RDFLiteralToString -RDFLiteral.prototype.toNT = RDFLiteral_toNT - -function RDFCollection() { - this.id = RDFNextId++ - this.elements = [] - this.closed = false +$rdf.Collection.prototype.unshift = function (el) { + this.elements.unshift(el); } - -RDFCollection.prototype.termType = 'collection' - -RDFCollection.prototype.toNT = function() { - return NTAnonymousNodePrefix + this.id +$rdf.Collection.prototype.shift = function () { + return this.elements.shift(); } -RDFCollection.prototype.toString = RDFCollection.prototype.toNT -RDFCollection.prototype.append = function (el) { - this.elements.push(el) -} -RDFCollection.prototype.unshift=function(el){ - this.elements.unshift(el); +$rdf.Collection.prototype.close = function () { + this.closed = true } -RDFCollection.prototype.shift=function(){ - return this.elements.shift(); -} - -RDFCollection.prototype.close = function () { - this.closed = true + + +// Convert Javascript representation to RDF term object +// +$rdf.term = function (val) { + if(typeof val == 'object') + if(val instanceof Date) { + var d2 = function (x) { + return('' + (100 + x)).slice(1, 3) + }; // format as just two digits + return new $rdf.Literal('' + val.getUTCFullYear() + '-' + d2(val.getUTCMonth() + 1) + + '-' + d2(val.getUTCDate()) + 'T' + d2(val.getUTCHours()) + ':' + + d2(val.getUTCMinutes()) + ':' + d2(val.getUTCSeconds()) + 'Z', + undefined, + $rdf.Symbol.prototype.XSDdateTime); + + } else if(val instanceof Array) { + var x = new $rdf.Collection(); + for(var i = 0; i < val.length; i++) + x.append($rdf.term(val[i])); + return x; + } else + return val; + if(typeof val == 'string') + return new $rdf.Literal(val); + if(typeof val == 'number') { + var dt; + if(('' + val).indexOf('e') >= 0) dt = $rdf.Symbol.prototype.XSDfloat; + else if(('' + val).indexOf('.') >= 0) dt = $rdf.Symbol.prototype.XSDdecimal; + else dt = $rdf.Symbol.prototype.XSDinteger; + return new $rdf.Literal(val, undefined, dt); + } + if(typeof val == 'boolean') + return new $rdf.Literal(val ? "1" : "0", undefined, $rdf.Symbol.prototype.XSDboolean); + if(typeof val == 'undefined') + return undefined; + throw("Can't make term from " + val + " of type " + typeof val); } // Statement @@ -148,144 +170,133 @@ RDFCollection.prototype.close = function () { // // The reason can point to provenece or inference // -function RDFStatement_toNT() { - return (this.subject.toNT() + " " - + this.predicate.toNT() + " " - + this.object.toNT() +" .") -} +$rdf.Statement = function (subject, predicate, object, why) { + this.subject = $rdf.term(subject) + this.predicate = $rdf.term(predicate) + this.object = $rdf.term(object) + if(typeof why != 'undefined') { + this.why = why; + } + return this; +} + +$rdf.st = function (subject, predicate, object, why) { + return new $rdf.Statement(subject, predicate, object, why); +}; -function RDFStatement(subject, predicate, object, why) { - this.subject = makeTerm(subject) - this.predicate = makeTerm(predicate) - this.object = makeTerm(object) - if (typeof why !='undefined') { - this.why = why - } else if (RDFTracking) { - tabulator.log.debug("WARNING: No reason on "+subject+" "+predicate+" "+object) - } - return this -} +$rdf.Statement.prototype.toNT = function () { + return (this.subject.toNT() + " " + this.predicate.toNT() + " " + this.object.toNT() + " ."); +}; -RDFStatement.prototype.toNT = RDFStatement_toNT -RDFStatement.prototype.toString = RDFStatement_toNT - +$rdf.Statement.prototype.toString = $rdf.Statement.prototype.toNT; // Formula // // Set of statements. +$rdf.Formula = function () { + this.statements = [] + this.constraints = [] + this.initBindings = [] + this.optional = [] + return this; +}; -function RDFFormula() { - this.statements = [] - this.constraints = [] - this.initBindings = [] - this.optional = [] - this.superFormula = null; - return this -} - -function RDFFormula_toNT() { - // throw 'Who called me?'; - return "{" + this.statements.join('\n') + "}" -} -//RDFQueryFormula.prototype = new RDFFormula() -//RDFQueryFormula.termType = 'queryFormula' -RDFFormula.prototype.termType = 'formula' -RDFFormula.prototype.toNT = RDFFormula_toNT -RDFFormula.prototype.toString = RDFFormula_toNT +$rdf.Formula.prototype.termType = 'formula'; +$rdf.Formula.prototype.toNT = function () { + return "{" + this.statements.join('\n') + "}" +}; +$rdf.Formula.prototype.toString = $rdf.Formula.prototype.toNT; -RDFFormula.prototype.add = function(subj, pred, obj, why) { - this.statements.push(new RDFStatement(subj, pred, obj, why)) +$rdf.Formula.prototype.add = function (subj, pred, obj, why) { + this.statements.push(new $rdf.Statement(subj, pred, obj, why)) } // Convenience methods on a formula allow the creation of new RDF terms: - -RDFFormula.prototype.sym = function(uri,name) { - if (name != null) { - if (!tabulator.ns[uri]) throw 'The prefix "'+uri+'" is not set in the API'; - uri = tabulator.ns[uri] + name - } - return new RDFSymbol(uri) +$rdf.Formula.prototype.sym = function (uri, name) { + if(name != null) { + throw "This feature (kb.sym with 2 args) is removed. Do not assume prefix mappings." + if(!$rdf.ns[uri]) throw 'The prefix "' + uri + '" is not set in the API'; + uri = $rdf.ns[uri] + name + } + return new $rdf.Symbol(uri) } -RDFFormula.prototype.literal = function(val, lang, dt) { - return new RDFLiteral(val.toString(), lang, dt) -} +$rdf.sym = function (uri) { + return new $rdf.Symbol(uri); +}; -RDFFormula.prototype.bnode = function(id) { - return new RDFBlankNode(id) +$rdf.Formula.prototype.literal = function (val, lang, dt) { + return new $rdf.Literal(val.toString(), lang, dt) } +$rdf.lit = $rdf.Formula.prototype.literal; -RDFFormula.prototype.formula = function() { - return new RDFFormula() +$rdf.Formula.prototype.bnode = function (id) { + return new $rdf.BlankNode(id) } -RDFFormula.prototype.collection = function () { // obsolete - return new RDFCollection() +$rdf.Formula.prototype.formula = function () { + return new $rdf.Formula() } -RDFFormula.prototype.list = function (values) { - li = new RDFCollection(); - if (values) { - for(var i = 0; i<values.length; i++) { - li.append(values[i]); - } - } - return li; +$rdf.Formula.prototype.collection = function () { // obsolete + return new $rdf.Collection() } -RDFFormula.instances={}; -RDFFormula.prototype.registerFormula = function(accesskey){ - var superFormula = this.superFormula || this; - RDFFormula.instances[accesskey] = this; - var formulaTerm = superFormula.bnode(); - superFormula.add(formulaTerm, tabulator.ns.rdf('type'),superFormula.sym("http://www.w3.org/2000/10/swap/log#Formula")); - superFormula.add(formulaTerm, tabulator.ns.foaf('name'), superFormula.literal(accesskey)); - superFormula.add(formulaTerm, tabulator.ns.link('accesskey'), superFormula.literal(accesskey)); - //RDFFormula.instances.push("accesskey"); +$rdf.Formula.prototype.list = function (values) { + var li = new $rdf.Collection(); + if(values) { + for(var i = 0; i < values.length; i++) { + li.append(values[i]); + } + } + return li; } - /* Variable -** -** Variables are placeholders used in patterns to be matched. -** In cwm they are symbols which are the formula's list of quantified variables. -** In sparl they are not visibily URIs. Here we compromise, by having -** a common special base URI for variables. -*/ - -RDFVariableBase = "varid:"; // We deem variabe x to be the symbol varid:x - -function RDFVariable(rel) { - this.uri = URIjoin(rel, RDFVariableBase); - return this; -} - -RDFVariable.prototype.termType = 'variable'; -RDFVariable.prototype.toNT = function() { - if (this.uri.slice(0, RDFVariableBase.length) == RDFVariableBase) { - return '?'+ this.uri.slice(RDFVariableBase.length);} // @@ poor man's refTo - return '?' + this.uri; + ** + ** Variables are placeholders used in patterns to be matched. + ** In cwm they are symbols which are the formula's list of quantified variables. + ** In sparl they are not visibily URIs. Here we compromise, by having + ** a common special base URI for variables. Their names are uris, + ** but the ? nottaion has an implicit base uri of 'varid:' + */ + +$rdf.Variable = function (rel) { + this.base = "varid:"; // We deem variabe x to be the symbol varid:x + this.uri = $rdf.Util.uri.join(rel, this.base); + return this; +} + +$rdf.Variable.prototype.termType = 'variable'; +$rdf.Variable.prototype.toNT = function () { + if(this.uri.slice(0, this.base.length) == this.base) { + return '?' + this.uri.slice(this.base.length); + } // @@ poor man's refTo + return '?' + this.uri; }; -RDFVariable.prototype.toString = RDFVariable.prototype.toNT; -RDFVariable.prototype.classOrder = 7; +$rdf.Variable.prototype.toString = $rdf.Variable.prototype.toNT; +$rdf.Variable.prototype.classOrder = 7; -RDFFormula.prototype.variable = function(name) { - return new RDFVariable(name); +$rdf.variable = $rdf.Formula.prototype.variable = function (name) { + return new $rdf.Variable(name); }; -RDFVariable.prototype.hashString = RDFVariable.prototype.toNT; +$rdf.Variable.prototype.hashString = $rdf.Variable.prototype.toNT; // The namespace function generator - -function RDFNamespace(nsuri) { - return function(ln) { return new RDFSymbol(nsuri+(ln===undefined?'':ln)) } +$rdf.Namespace = function (nsuri) { + return function (ln) { + return new $rdf.Symbol(nsuri + (ln === undefined ? '' : ln)) + } } -RDFFormula.prototype.ns = function(nsuri) { - return function(ln) { return new RDFSymbol(nsuri+(ln===undefined?'':ln)) } +$rdf.Formula.prototype.ns = function (nsuri) { + return function (ln) { + return new $rdf.Symbol(nsuri + (ln === undefined ? '' : ln)) + } } @@ -293,21 +304,43 @@ RDFFormula.prototype.ns = function(nsuri) { // // The bnode bit should not be used on program-external values; designed // for internal work such as storing a bnode id in an HTML attribute. -// Not coded for literals. - -RDFFormula.prototype.fromNT = function(str) { - var len = str.length - var ch = str.slice(0,1) - if (ch == '<') return this.sym(str.slice(1,len-1)) - if (ch == '_') { - var x = new RDFBlankNode(); - x.id = parseInt(str.slice(3)); - RDFNextId-- - return x +// This will only parse the strings generated by the vaious toNT() methods. +$rdf.Formula.prototype.fromNT = function (str) { + var len = str.length + var ch = str.slice(0, 1) + if(ch == '<') return $rdf.sym(str.slice(1, len - 1)) + if(ch == '"') { + var lang = undefined; + var dt = undefined; + var k = str.lastIndexOf('"'); + if(k < len - 1) { + if(str[k + 1] == '@') lang = str.slice(k + 2, len); + else if(str.slice(k + 1, k + 3) == '^^') dt = $rdf.fromNT(str.slice(k + 3, len)); + else throw "Can't convert string from NT: " + str } - throw "Can't convert from NT"+str; - - //alert("Can't yet convert from NT: '"+str+"', "+str[0]) -} + var str = (str.slice(1, k)); + str = str.replace(/\\"/g, '"'); // unescape quotes ' + str = str.replace(/\\n/g, '\n'); // unescape newlines + str = str.replace(/\\\\/g, '\\'); // unescape backslashes + return $rdf.lit(str, lang, dt); + } + if(ch == '_') { + var x = new $rdf.BlankNode(); + x.id = parseInt(str.slice(3)); + $rdf.NextId-- + return x + } + if(ch == '?') { + var x = new $rdf.Variable(str.slice(1)); + return x; + } + throw "Can't convert from NT: " + str; + +} +$rdf.fromNT = $rdf.Formula.prototype.fromNT; // Not for inexpert user +// Convenience - and more conventional name: +$rdf.graph = function () { + return new $rdf.IndexedFormula(); +}; -// ends +// ends +\ No newline at end of file diff --git a/chrome/content/zotero/xpcom/rdf/uri.js b/chrome/content/zotero/xpcom/rdf/uri.js @@ -11,133 +11,139 @@ // // See also http://www.w3.org/2000/10/swap/uripath.py // +if(typeof $rdf.Util.uri == "undefined") { + $rdf.Util.uri = {}; +}; -if (typeof Util == "undefined") { Util = {}} -if (typeof Util.uri == "undefined") { Util.uri = {}} - -Util.uri.join = function (given, base) { - // if (typeof tabulator.log.debug != 'undefined') tabulator.log.debug(" URI given="+given+" base="+base) - var baseHash = base.indexOf('#') - if (baseHash > 0) base = base.slice(0, baseHash) - if (given.length==0) return base // before chopping its filename off - if (given.indexOf('#')==0) return base + given - var colon = given.indexOf(':') - if (colon >= 0) return given // Absolute URI form overrides base URI - var baseColon = base.indexOf(':') - if (base == "") return given; - if (baseColon < 0) { - alert("Invalid base: "+ base + ' in join with ' +given); - return given +$rdf.Util.uri.join = function (given, base) { + // if (typeof $rdf.log.debug != 'undefined') $rdf.log.debug(" URI given="+given+" base="+base) + var baseHash = base.indexOf('#') + if(baseHash > 0) base = base.slice(0, baseHash) + if(given.length == 0) return base // before chopping its filename off + if(given.indexOf('#') == 0) return base + given + var colon = given.indexOf(':') + if(colon >= 0) return given // Absolute URI form overrides base URI + var baseColon = base.indexOf(':') + if(base == "") return given; + if(baseColon < 0) { + alert("Invalid base: " + base + ' in join with ' + given); + return given + } + var baseScheme = base.slice(0, baseColon + 1) // eg http: + if(given.indexOf("//") == 0) // Starts with // + return baseScheme + given; + if(base.indexOf('//', baseColon) == baseColon + 1) { // Any hostpart? + var baseSingle = base.indexOf("/", baseColon + 3) + if(baseSingle < 0) { + if(base.length - baseColon - 3 > 0) { + return base + "/" + given + } else { + return baseScheme + given + } } - var baseScheme = base.slice(0,baseColon+1) // eg http: - if (given.indexOf("//") == 0) // Starts with // - return baseScheme + given; - if (base.indexOf('//', baseColon)==baseColon+1) { // Any hostpart? - var baseSingle = base.indexOf("/", baseColon+3) - if (baseSingle < 0) { - if (base.length-baseColon-3 > 0) { - return base + "/" + given - } else { - return baseScheme + given - } - } - } else { - var baseSingle = base.indexOf("/", baseColon+1) - if (baseSingle < 0) { - if (base.length-baseColon-1 > 0) { - return base + "/" + given - } else { - return baseScheme + given - } - } + } else { + var baseSingle = base.indexOf("/", baseColon + 1) + if(baseSingle < 0) { + if(base.length - baseColon - 1 > 0) { + return base + "/" + given + } else { + return baseScheme + given + } } + } + + if(given.indexOf('/') == 0) // starts with / but not // + return base.slice(0, baseSingle) + given - if (given.indexOf('/') == 0) // starts with / but not // - return base.slice(0, baseSingle) + given - - var path = base.slice(baseSingle) - var lastSlash = path.lastIndexOf("/") - if (lastSlash <0) return baseScheme + given - if ((lastSlash >=0) && (lastSlash < (path.length-1))) - path = path.slice(0, lastSlash+1) // Chop trailing filename from base - - path = path + given - while (path.match(/[^\/]*\/\.\.\//)) // must apply to result of prev - path = path.replace( /[^\/]*\/\.\.\//, '') // ECMAscript spec 7.8.5 - path = path.replace( /\.\//g, '') // spec vague on escaping - path = path.replace( /\/\.$/, '/' ) - return base.slice(0, baseSingle) + path + var path = base.slice(baseSingle) + var lastSlash = path.lastIndexOf("/") + if(lastSlash < 0) return baseScheme + given + if((lastSlash >= 0) + && (lastSlash < (path.length - 1))) + path = path.slice(0, lastSlash + 1) // Chop trailing filename from base + path = path + given + while(path.match(/[^\/]*\/\.\.\//)) // must apply to result of prev + path = path.replace(/[^\/]*\/\.\.\//, '') // ECMAscript spec 7.8.5 + path = path.replace(/\.\//g, '') // spec vague on escaping + path = path.replace(/\/\.$/, '/') + return base.slice(0, baseSingle) + path } -var tIOService; -if (typeof( isExtension ) != "undefined" && isExtension) { - tIOService = Components.classes['@mozilla.org/network/io-service;1'] - .getService(Components.interfaces.nsIIOService); - Util.uri.join2 = function (given, base){ - var baseURI = tIOService.newURI(base, null, null); - return tIOService.newURI(baseURI.resolve(given), null, null).spec; - } +if(typeof tabulator != 'undefined' && tabulator.isExtension) { + $rdf.Util.uri.join2 = function (given, base) { + var tIOService = Components.classes['@mozilla.org/network/io-service;1'] + .getService(Components.interfaces.nsIIOService); + + var baseURI = tIOService.newURI(base, null, null); + return tIOService.newURI(baseURI.resolve(given), null, null).spec; + } } else - Util.uri.join2 = Util.uri.join; - + $rdf.Util.uri.join2 = $rdf.Util.uri.join; + // refTo: Make a URI relative to a given base // // based on code in http://www.w3.org/2000/10/swap/uripath.py // -Util.uri.commonHost = new RegExp("^[-_a-zA-Z0-9.]+:(//[^/]*)?/[^/]*$"); -Util.uri.refTo = function(base, uri) { - if (!base) return uri; - if (base == uri) return ""; - var i =0; // How much are they identical? - while (i<uri.length && i < base.length) - if (uri[i] == base[i]) i++; - else break; - if (base.slice(0,i).match(Util.uri.commonHost)) { - var k = uri.indexOf('//'); - if (k<0) k=-2; // no host - var l = uri.indexOf('/', k+2); // First *single* slash - if (uri.slice(l+1, l+2) != '/' && base.slice(l+1, l+2) != '/' - && uri.slice(0,l) == base.slice(0,l)) // common path to single slash - return uri.slice(l); // but no other common path segments - } - // fragment of base? - if (uri.slice(i, i+1) == '#' && base.length == i) return uri.slice(i); - while (i>0 && uri[i-1] != '/') i--; +$rdf.Util.uri.commonHost = new RegExp("^[-_a-zA-Z0-9.]+:(//[^/]*)?/[^/]*$"); + +$rdf.Util.uri.hostpart = function (u) { + var m = /[^\/]*\/\/([^\/]*)\//.exec(u); + return m ? m[1] : '' +}; - if (i<3) return uri; // No way - if ((base.indexOf('//', i-2) > 0) || uri.indexOf('//', i-2) > 0) - return uri; // an unshared '//' - if (base.indexOf(':', i) >0) return uri; // unshared ':' - var n = 0; - for (var j=i; j<base.length; j++) if (base[j]=='/') n++; - if (n==0 && i < uri.length && uri[i] =='#') return './' + uri.slice(i); - if (n==0 && i == uri.length) return './'; - var str = ''; - for (var j=0; j<n; j++) str+= '../'; - return str + uri.slice(i); +$rdf.Util.uri.refTo = function (base, uri) { + if(!base) return uri; + if(base == uri) return ""; + var i = 0; // How much are they identical? + while(i < uri.length && i < base.length) + if(uri[i] == base[i]) i++; + else break; + if(base.slice(0, i).match($rdf.Util.uri.commonHost)) { + var k = uri.indexOf('//'); + if(k < 0) k = -2; // no host + var l = uri.indexOf('/', k + 2); // First *single* slash + if(uri.slice(l + 1, l + 2) != '/' + && base.slice(l + 1, l + 2) != '/' + && uri.slice(0, l) == base.slice(0, l)) + // common path to single slash + return uri.slice(l); // but no other common path segments + } + // fragment of base? + if(uri.slice(i, i + 1) == '#' && base.length == i) return uri.slice(i); + while(i > 0 && uri[i - 1] != '/') i--; + + if(i < 3) return uri; // No way + if((base.indexOf('//', i - 2) > 0) + || uri.indexOf('//', i - 2) > 0) + return uri; // an unshared '//' + if(base.indexOf(':', i) > 0) return uri; // unshared ':' + var n = 0; + for(var j = i; j < base.length; j++) if(base[j] == '/') n++; + if(n == 0 && i < uri.length && uri[i] == '#') return './' + uri.slice(i); + if(n == 0 && i == uri.length) return './'; + var str = ''; + for(var j = 0; j < n; j++) str += '../'; + return str + uri.slice(i); } /** returns URI without the frag **/ -Util.uri.docpart = function (uri) { - var i = uri.indexOf("#") - if (i < 0) return uri - return uri.slice(0,i) -} +$rdf.Util.uri.docpart = function (uri) { + var i = uri.indexOf("#") + if(i < 0) return uri + return uri.slice(0, i) +} + +/** The document in which something a thing defined **/ +$rdf.Util.uri.document = function (x) { + return $rdf.sym($rdf.Util.uri.docpart(x.uri)); +} /** return the protocol of a uri **/ /** return null if there isn't one **/ -Util.uri.protocol = function (uri) { - var index = uri.indexOf(':'); - if (index >= 0) - return uri.slice(0, index); - else - return null; +$rdf.Util.uri.protocol = function (uri) { + var index = uri.indexOf(':'); + if(index >= 0) return uri.slice(0, index); + else return null; } //protocol - -URIjoin = Util.uri.join -uri_docpart = Util.uri.docpart -uri_protocol = Util.uri.protocol - - -//ends +//ends +\ No newline at end of file diff --git a/chrome/content/zotero/xpcom/sync.js b/chrome/content/zotero/xpcom/sync.js @@ -1655,6 +1655,10 @@ Zotero.Sync.Server = new function () { } ); + try { + gen.next(); + } + catch (e if e.toString() === "[object StopIteration]") {} Zotero.pumpGenerator(gen, false, errorHandler); } catch (e) { diff --git a/chrome/content/zotero/xpcom/translation/translate.js b/chrome/content/zotero/xpcom/translation/translate.js @@ -1054,12 +1054,8 @@ Zotero.Translate.Base.prototype = { try { this._sandboxManager.sandbox["do"+this._entryFunctionSuffix].apply(null, this._getParameters()); } catch(e) { - if(this._parentTranslator) { - throw(e); - } else { - this.complete(false, e); - return false; - } + this.complete(false, e); + return false; } this.decrementAsyncProcesses("Zotero.Translate#translate()"); @@ -2147,7 +2143,7 @@ Zotero.Translate.IO.String.prototype = { "_initRDF":function(callback) { Zotero.debug("Translate: Initializing RDF data store"); - this._dataStore = new Zotero.RDF.AJAW.RDFIndexedFormula(); + this._dataStore = new Zotero.RDF.AJAW.IndexedFormula(); this.RDF = new Zotero.Translate.IO._RDFSandbox(this._dataStore); if(this.contentLength) { @@ -2258,9 +2254,9 @@ Zotero.Translate.IO.String.prototype = { /** * @class An API for handling RDF from the sandbox. This is exposed to translators as Zotero.RDF. * - * @property {Zotero.RDF.AJAW.RDFIndexedFormula} _dataStore + * @property {Zotero.RDF.AJAW.IndexedFormula} _dataStore * @property {Integer[]} _containerCounts - * @param {Zotero.RDF.AJAW.RDFIndexedFormula} dataStore + * @param {Zotero.RDF.AJAW.IndexedFormula} dataStore */ Zotero.Translate.IO._RDFSandbox = function(dataStore) { this._dataStore = dataStore; @@ -2281,16 +2277,17 @@ Zotero.Translate.IO._RDFSandbox.prototype = { "getArcsOut":"r", "getSources":"r", "getTargets":"r", - "getStatementsMatching":"r" + "getStatementsMatching":"r", + "serialize":"r" }, /** - * Gets a resource as a Zotero.RDF.AJAW.RDFSymbol, rather than a string - * @param {String|Zotero.RDF.AJAW.RDFSymbol} about - * @return {Zotero.RDF.AJAW.RDFSymbol} + * Gets a resource as a Zotero.RDF.AJAW.Symbol, rather than a string + * @param {String|Zotero.RDF.AJAW.Symbol} about + * @return {Zotero.RDF.AJAW.Symbol} */ "_getResource":function(about) { - return (typeof about == "object" ? about : new Zotero.RDF.AJAW.RDFSymbol(about)); + return (typeof about == "object" ? about : new Zotero.RDF.AJAW.Symbol(about)); }, /** @@ -2307,7 +2304,7 @@ Zotero.Translate.IO._RDFSandbox.prototype = { * Serializes the current RDF to a string */ "serialize":function(dataMode) { - var serializer = Serializer(); + var serializer = Zotero.RDF.AJAW.Serializer(this._dataStore); for(var prefix in this._dataStore.namespaces) { serializer.suggestPrefix(prefix, this._dataStore.namespaces[prefix]); @@ -2323,9 +2320,9 @@ Zotero.Translate.IO._RDFSandbox.prototype = { /** * Adds an RDF triple - * @param {String|Zotero.RDF.AJAW.RDFSymbol} about - * @param {String|Zotero.RDF.AJAW.RDFSymbol} relation - * @param {String|Zotero.RDF.AJAW.RDFSymbol} value + * @param {String|Zotero.RDF.AJAW.Symbol} about + * @param {String|Zotero.RDF.AJAW.Symbol} relation + * @param {String|Zotero.RDF.AJAW.Symbol} value * @param {Boolean} literal Whether value should be treated as a literal (true) or a resource * (false) */ @@ -2352,16 +2349,16 @@ Zotero.Translate.IO._RDFSandbox.prototype = { /** * Creates a new anonymous resource - * @return {Zotero.RDF.AJAW.RDFSymbol} + * @return {Zotero.RDF.AJAW.Symbol} */ "newResource":function() { - return new Zotero.RDF.AJAW.RDFBlankNode(); + return new Zotero.RDF.AJAW.BlankNode(); }, /** * Creates a new container resource * @param {String} type The type of the container ("bag", "seq", or "alt") - * @param {String|Zotero.RDF.AJAW.RDFSymbol} about The URI of the resource + * @param {String|Zotero.RDF.AJAW.Symbol} about The URI of the resource * @return {Zotero.Translate.RDF.prototype.newContainer */ "newContainer":function(type, about) { @@ -2382,8 +2379,8 @@ Zotero.Translate.IO._RDFSandbox.prototype = { /** * Adds a new element to a container - * @param {String|Zotero.RDF.AJAW.RDFSymbol} about The container - * @param {String|Zotero.RDF.AJAW.RDFSymbol} element The element to add to the container + * @param {String|Zotero.RDF.AJAW.Symbol} about The container + * @param {String|Zotero.RDF.AJAW.Symbol} element The element to add to the container * @param {Boolean} literal Whether element should be treated as a literal (true) or a resource * (false) */ @@ -2391,13 +2388,13 @@ Zotero.Translate.IO._RDFSandbox.prototype = { const rdf = "http://www.w3.org/1999/02/22-rdf-syntax-ns#"; var about = this._getResource(about); - this._dataStore.add(about, new Zotero.RDF.AJAW.RDFSymbol(rdf+"_"+(this._containerCounts[about.toNT()]++)), element, literal); + this._dataStore.add(about, new Zotero.RDF.AJAW.Symbol(rdf+"_"+(this._containerCounts[about.toNT()]++)), element, literal); }, /** * Gets all elements within a container - * @param {String|Zotero.RDF.AJAW.RDFSymbol} about The container - * @return {Zotero.RDF.AJAW.RDFSymbol[]} + * @param {String|Zotero.RDF.AJAW.Symbol} about The container + * @return {Zotero.RDF.AJAW.Symbol[]} */ "getContainerElements":function(about) { const liPrefix = "http://www.w3.org/1999/02/22-rdf-syntax-ns#_"; @@ -2435,7 +2432,7 @@ Zotero.Translate.IO._RDFSandbox.prototype = { /** * Gets the URI a specific resource - * @param {String|Zotero.RDF.AJAW.RDFSymbol} resource + * @param {String|Zotero.RDF.AJAW.Symbol} resource * @return {String} */ "getResourceURI":function(resource) { @@ -2447,7 +2444,7 @@ Zotero.Translate.IO._RDFSandbox.prototype = { /** * Gets all resources in the RDF data store - * @return {Zotero.RDF.AJAW.RDFSymbol[]} + * @return {Zotero.RDF.AJAW.Symbol[]} */ "getAllResources":function() { var returnArray = []; @@ -2459,7 +2456,7 @@ Zotero.Translate.IO._RDFSandbox.prototype = { /** * Gets all arcs (predicates) into a resource - * @return {Zotero.RDF.AJAW.RDFSymbol[]} + * @return {Zotero.RDF.AJAW.Symbol[]} * @deprecated Since 2.1. Use {@link Zotero.Translate.IO["rdf"]._RDFBase#getStatementsMatching} */ "getArcsIn":function(resource) { @@ -2475,7 +2472,7 @@ Zotero.Translate.IO._RDFSandbox.prototype = { /** * Gets all arcs (predicates) out of a resource - * @return {Zotero.RDF.AJAW.RDFSymbol[]} + * @return {Zotero.RDF.AJAW.Symbol[]} * @deprecated Since 2.1. Use {@link Zotero.Translate.IO["rdf"]._RDFBase#getStatementsMatching} */ "getArcsOut":function(resource) { @@ -2491,9 +2488,9 @@ Zotero.Translate.IO._RDFSandbox.prototype = { /** * Gets all subjects whose predicates point to a resource - * @param {String|Zotero.RDF.AJAW.RDFSymbol} resource Subject that predicates should point to - * @param {String|Zotero.RDF.AJAW.RDFSymbol} property Predicate - * @return {Zotero.RDF.AJAW.RDFSymbol[]} + * @param {String|Zotero.RDF.AJAW.Symbol} resource Subject that predicates should point to + * @param {String|Zotero.RDF.AJAW.Symbol} property Predicate + * @return {Zotero.RDF.AJAW.Symbol[]} * @deprecated Since 2.1. Use {@link Zotero.Translate.IO["rdf"]._RDFBase#getStatementsMatching} */ "getSources":function(resource, property) { @@ -2509,9 +2506,9 @@ Zotero.Translate.IO._RDFSandbox.prototype = { /** * Gets all objects of a given subject with a given predicate - * @param {String|Zotero.RDF.AJAW.RDFSymbol} resource Subject - * @param {String|Zotero.RDF.AJAW.RDFSymbol} property Predicate - * @return {Zotero.RDF.AJAW.RDFSymbol[]} + * @param {String|Zotero.RDF.AJAW.Symbol} resource Subject + * @param {String|Zotero.RDF.AJAW.Symbol} property Predicate + * @return {Zotero.RDF.AJAW.Symbol[]} * @deprecated Since 2.1. Use {@link Zotero.Translate.IO["rdf"]._RDFBase#getStatementsMatching} */ "getTargets":function(resource, property) { @@ -2528,9 +2525,9 @@ Zotero.Translate.IO._RDFSandbox.prototype = { /** * Gets statements matching a certain pattern * - * @param {String|Zotero.RDF.AJAW.RDFSymbol} subj Subject - * @param {String|Zotero.RDF.AJAW.RDFSymbol} predicate Predicate - * @param {String|Zotero.RDF.AJAW.RDFSymbol} obj Object + * @param {String|Zotero.RDF.AJAW.Symbol} subj Subject + * @param {String|Zotero.RDF.AJAW.Symbol} predicate Predicate + * @param {String|Zotero.RDF.AJAW.Symbol} obj Object * @param {Boolean} objLiteral Whether the object is a literal (as * opposed to a URI) * @param {Boolean} justOne Whether to stop when a single result is diff --git a/chrome/content/zotero/xpcom/translation/translate_firefox.js b/chrome/content/zotero/xpcom/translation/translate_firefox.js @@ -684,7 +684,7 @@ Zotero.Translate.IO.Read.prototype = { var baseURI = fileHandler.getURLSpecFromFile(this.file); Zotero.debug("Translate: Initializing RDF data store"); - this._dataStore = new Zotero.RDF.AJAW.RDFIndexedFormula(); + this._dataStore = new Zotero.RDF.AJAW.IndexedFormula(); var parser = new Zotero.RDF.AJAW.RDFParser(this._dataStore); try { var nodes = Zotero.Translate.IO.parseDOMXML(this._rawStream, this._charset, this.file.fileSize); @@ -786,7 +786,7 @@ Zotero.Translate.IO.Write.prototype = { "_initRDF":function() { Zotero.debug("Translate: Initializing RDF data store"); - this._dataStore = new Zotero.RDF.AJAW.RDFIndexedFormula(); + this._dataStore = new Zotero.RDF.AJAW.IndexedFormula(); this.RDF = new Zotero.Translate.IO._RDFSandbox(this._dataStore); }, diff --git a/chrome/content/zotero/xpcom/translation/translate_item.js b/chrome/content/zotero/xpcom/translation/translate_item.js @@ -239,22 +239,9 @@ Zotero.Translate.ItemSaver.prototype = { var newItem = Zotero.Items.get(myID); } else { var file = this._parsePath(attachment.path); - if(!file) return; + if(!file || !file.exists()) return; - if (!file.exists()) { - // use attachment title if possible, or else file leaf name - var title = attachment.title; - if(!title) { - title = file.leafName; - } - - var myID = Zotero.Attachments.createMissingAttachment( - attachment.url ? Zotero.Attachments.LINK_MODE_IMPORTED_URL - : Zotero.Attachments.LINK_MODE_IMPORTED_FILE, - file, attachment.url ? attachment.url : null, title, - attachment.mimeType, attachment.charset, parentID); - } - else if (attachment.url) { + if (attachment.url) { var myID = Zotero.Attachments.importSnapshotFromFile(file, attachment.url, attachment.title, attachment.mimeType, attachment.charset, parentID); diff --git a/chrome/locale/af-ZA/zotero/zotero.dtd b/chrome/locale/af-ZA/zotero/zotero.dtd @@ -68,6 +68,10 @@ <!ENTITY zotero.items.menu.restoreToLibrary "Restore to Library"> <!ENTITY zotero.items.menu.duplicateItem "Duplicate Selected Item"> +<!ENTITY zotero.items.menu.mergeItems "Merge Items…"> + +<!ENTITY zotero.duplicatesMerge.versionSelect "Choose the version of the item to use as the master item:"> +<!ENTITY zotero.duplicatesMerge.fieldSelect "Select fields to keep from other versions of the item:"> <!ENTITY zotero.toolbar.newItem.label "New Item"> <!ENTITY zotero.toolbar.moreItemTypes.label "More"> diff --git a/chrome/locale/af-ZA/zotero/zotero.properties b/chrome/locale/af-ZA/zotero/zotero.properties @@ -36,6 +36,7 @@ general.enable=Enable general.disable=Disable general.remove=Remove general.openDocumentation=Open Documentation +general.numMore=%S more… general.operationInProgress=A Zotero operation is currently in progress. general.operationInProgress.waitUntilFinished=Please wait until it has finished. @@ -80,7 +81,7 @@ app.firefox=Zotero for Firefox startupError=There was an error starting Zotero. startupError.databaseInUse=Your Zotero database is currently in use. Only one instance of Zotero using the same database may be opened simultaneously at this time. -startupError.closeStandalone=If Zotero Standalone is open, please close it and restart Firefox. +startupError.closeStandalone=If Zotero Standalone is open, please close it and restart %S. startupError.closeFirefox=If Firefox with the Zotero extension is open, please close it and restart Zotero Standalone. startupError.databaseCannotBeOpened=The Zotero database cannot be opened. startupError.checkPermissions=Make sure you have read and write permissions to all files in the Zotero data directory. @@ -112,6 +113,7 @@ pane.collections.library=My Library pane.collections.trash=Trash pane.collections.untitled=Untitled pane.collections.unfiled=Unfiled Items +pane.collections.duplicate=Duplicate Items pane.collections.menu.rename.collection=Rename Collection... pane.collections.menu.edit.savedSearch=Edit Saved Search @@ -170,6 +172,10 @@ pane.items.interview.manyParticipants=Interview by %S et al. pane.item.selected.zero=No items selected pane.item.selected.multiple=%S items selected +pane.item.unselected.zero=No items in this view +pane.item.unselected.singular=%S item in this view +pane.item.unselected.plural=%S items in this view +pane.item.selectToMerge=Select items to merge pane.item.changeType.title=Change Item Type pane.item.changeType.text=Are you sure you want to change the item type?\n\nThe following fields will be lost: @@ -178,6 +184,8 @@ pane.item.defaultLastName=last pane.item.defaultFullName=full name pane.item.switchFieldMode.one=Switch to single field pane.item.switchFieldMode.two=Switch to two fields +pane.item.creator.moveUp=Move Up +pane.item.creator.moveDown=Move Down pane.item.notes.untitled=Untitled Note pane.item.notes.delete.confirm=Are you sure you want to delete this note? pane.item.notes.count.zero=%S notes: diff --git a/chrome/locale/ar/zotero/zotero.dtd b/chrome/locale/ar/zotero/zotero.dtd @@ -68,6 +68,10 @@ <!ENTITY zotero.items.menu.restoreToLibrary "Restore to Library"> <!ENTITY zotero.items.menu.duplicateItem "تكرار العنصر المحدد"> +<!ENTITY zotero.items.menu.mergeItems "Merge Items…"> + +<!ENTITY zotero.duplicatesMerge.versionSelect "Choose the version of the item to use as the master item:"> +<!ENTITY zotero.duplicatesMerge.fieldSelect "Select fields to keep from other versions of the item:"> <!ENTITY zotero.toolbar.newItem.label "عنصر جديد"> <!ENTITY zotero.toolbar.moreItemTypes.label "المزيد"> diff --git a/chrome/locale/ar/zotero/zotero.properties b/chrome/locale/ar/zotero/zotero.properties @@ -36,6 +36,7 @@ general.enable=تمكين general.disable=تعطيل general.remove=حذف general.openDocumentation=Open Documentation +general.numMore=%S more… general.operationInProgress=عملية زوتيرو حاليا في التقدم. general.operationInProgress.waitUntilFinished=يرجى الانتظار لحين انتهاء. @@ -112,6 +113,7 @@ pane.collections.library=مكتبتي pane.collections.trash=سلة المحذوفات pane.collections.untitled=بدون عنوان pane.collections.unfiled=العناصر الغير مصنفة +pane.collections.duplicate=Duplicate Items pane.collections.menu.rename.collection=إعادة تسمية مجموعة العناصر... pane.collections.menu.edit.savedSearch=تحرير البحث المخزن @@ -170,6 +172,10 @@ pane.items.interview.manyParticipants=مقابلة بواسطة %S، وآخ. pane.item.selected.zero=لا توجد عناصر محددة pane.item.selected.multiple=%S عنصر محدد +pane.item.unselected.zero=No items in this view +pane.item.unselected.singular=%S item in this view +pane.item.unselected.plural=%S items in this view +pane.item.selectToMerge=Select items to merge pane.item.changeType.title=تغيير نوع العنصر pane.item.changeType.text=هل ترغب في تغيير نوع العنصر؟\n\nستفقد الحقول التالية: @@ -178,6 +184,8 @@ pane.item.defaultLastName=الاسم الأخير pane.item.defaultFullName=الاسم الكامل pane.item.switchFieldMode.one=تحويل لحقل أحادي pane.item.switchFieldMode.two=تحويل لحقل ثنائي +pane.item.creator.moveUp=Move Up +pane.item.creator.moveDown=Move Down pane.item.notes.untitled=ملاحظة بدون عنوان pane.item.notes.delete.confirm=هل ترغب في حذف هذه الملاحظة؟ pane.item.notes.count.zero=لا توجد ملاحظات: diff --git a/chrome/locale/bg-BG/zotero/zotero.dtd b/chrome/locale/bg-BG/zotero/zotero.dtd @@ -68,6 +68,10 @@ <!ENTITY zotero.items.menu.restoreToLibrary "Restore to Library"> <!ENTITY zotero.items.menu.duplicateItem "Дуплицира избраните записи"> +<!ENTITY zotero.items.menu.mergeItems "Merge Items…"> + +<!ENTITY zotero.duplicatesMerge.versionSelect "Choose the version of the item to use as the master item:"> +<!ENTITY zotero.duplicatesMerge.fieldSelect "Select fields to keep from other versions of the item:"> <!ENTITY zotero.toolbar.newItem.label "Нов запис"> <!ENTITY zotero.toolbar.moreItemTypes.label "Още"> diff --git a/chrome/locale/bg-BG/zotero/zotero.properties b/chrome/locale/bg-BG/zotero/zotero.properties @@ -36,6 +36,7 @@ general.enable=Включва general.disable=Изключва general.remove=Remove general.openDocumentation=Open Documentation +general.numMore=%S more… general.operationInProgress=Операция на Зотеро е активна в момента. general.operationInProgress.waitUntilFinished=Моля изчакайте докато приключи. @@ -80,7 +81,7 @@ app.firefox=Zotero for Firefox startupError=Появи се грешка при стартирането на Зотеро. startupError.databaseInUse=Your Zotero database is currently in use. Only one instance of Zotero using the same database may be opened simultaneously at this time. -startupError.closeStandalone=If Zotero Standalone is open, please close it and restart Firefox. +startupError.closeStandalone=If Zotero Standalone is open, please close it and restart %S. startupError.closeFirefox=If Firefox with the Zotero extension is open, please close it and restart Zotero Standalone. startupError.databaseCannotBeOpened=Базата дани на зотеро не може да бъде отворена. startupError.checkPermissions=Убедете се, че имате разрешение да четете и записвате във всички файлове намиращи се в папката с дани на Зотеро. @@ -112,6 +113,7 @@ pane.collections.library=Моята библиотека pane.collections.trash=Кошче за боклук pane.collections.untitled=Без име pane.collections.unfiled=Unfiled Items +pane.collections.duplicate=Duplicate Items pane.collections.menu.rename.collection=Преименува колекцията... pane.collections.menu.edit.savedSearch=Редактира записаното търсене @@ -170,6 +172,10 @@ pane.items.interview.manyParticipants=Интервю на %S и други pane.item.selected.zero=Няма избрани записи pane.item.selected.multiple=Избрани са %S записа +pane.item.unselected.zero=No items in this view +pane.item.unselected.singular=%S item in this view +pane.item.unselected.plural=%S items in this view +pane.item.selectToMerge=Select items to merge pane.item.changeType.title=Променя типа на записа pane.item.changeType.text=Сигурни ли сте, че искате да промените типа на записа?\n\nСледните полета ще бъдат загубени: @@ -178,6 +184,8 @@ pane.item.defaultLastName=последен pane.item.defaultFullName=пълно име pane.item.switchFieldMode.one=Превключва към единично поле pane.item.switchFieldMode.two=Превключва към две полета +pane.item.creator.moveUp=Move Up +pane.item.creator.moveDown=Move Down pane.item.notes.untitled=Бележка без име pane.item.notes.delete.confirm=Сигурни ли сте, че искате да изтриете тази бележка? pane.item.notes.count.zero=%S бележки: diff --git a/chrome/locale/ca-AD/zotero/zotero.dtd b/chrome/locale/ca-AD/zotero/zotero.dtd @@ -68,6 +68,10 @@ <!ENTITY zotero.items.menu.restoreToLibrary "Restaura a la Biblioteca"> <!ENTITY zotero.items.menu.duplicateItem "Duplica l&apos;element seleccionat"> +<!ENTITY zotero.items.menu.mergeItems "Merge Items…"> + +<!ENTITY zotero.duplicatesMerge.versionSelect "Choose the version of the item to use as the master item:"> +<!ENTITY zotero.duplicatesMerge.fieldSelect "Select fields to keep from other versions of the item:"> <!ENTITY zotero.toolbar.newItem.label "Nou element"> <!ENTITY zotero.toolbar.moreItemTypes.label "Més"> diff --git a/chrome/locale/ca-AD/zotero/zotero.properties b/chrome/locale/ca-AD/zotero/zotero.properties @@ -36,6 +36,7 @@ general.enable=Activa general.disable=Desactiva general.remove=Elimina general.openDocumentation=Obre la documentació +general.numMore=%S more… general.operationInProgress=Una operació de Zotero està actualment en curs. general.operationInProgress.waitUntilFinished=Si us plau, espereu fins que hagi acabat. @@ -112,6 +113,7 @@ pane.collections.library=La meva llibreria pane.collections.trash=Paperera pane.collections.untitled=Sense títol pane.collections.unfiled=Ítems sense arxivar +pane.collections.duplicate=Duplicate Items pane.collections.menu.rename.collection=Canvia el nom de la col·lecció... pane.collections.menu.edit.savedSearch=Edita la cerca desada @@ -170,6 +172,10 @@ pane.items.interview.manyParticipants=Entrevista per %S i altres pane.item.selected.zero=Cap element seleccionat pane.item.selected.multiple=%S elements seleccionats +pane.item.unselected.zero=No items in this view +pane.item.unselected.singular=%S item in this view +pane.item.unselected.plural=%S items in this view +pane.item.selectToMerge=Select items to merge pane.item.changeType.title=Canvia el tipus d'element pane.item.changeType.text=Estàs segur que vols canviar el tipus d'element?\n\n Es perdran els següents camps: @@ -178,6 +184,8 @@ pane.item.defaultLastName=últim pane.item.defaultFullName=Nom complet pane.item.switchFieldMode.one=Canvia a un sol camp pane.item.switchFieldMode.two=Canvia a dos camps +pane.item.creator.moveUp=Move Up +pane.item.creator.moveDown=Move Down pane.item.notes.untitled=Nota sense títol pane.item.notes.delete.confirm=Estàs segur que vols eliminar aquesta nota? pane.item.notes.count.zero=Cap nota: diff --git a/chrome/locale/cs-CZ/zotero/zotero.dtd b/chrome/locale/cs-CZ/zotero/zotero.dtd @@ -68,6 +68,10 @@ <!ENTITY zotero.items.menu.restoreToLibrary "Restore to Library"> <!ENTITY zotero.items.menu.duplicateItem "Duplikovat vybranou položku"> +<!ENTITY zotero.items.menu.mergeItems "Merge Items…"> + +<!ENTITY zotero.duplicatesMerge.versionSelect "Choose the version of the item to use as the master item:"> +<!ENTITY zotero.duplicatesMerge.fieldSelect "Select fields to keep from other versions of the item:"> <!ENTITY zotero.toolbar.newItem.label "Nová položka"> <!ENTITY zotero.toolbar.moreItemTypes.label "Více"> diff --git a/chrome/locale/cs-CZ/zotero/zotero.properties b/chrome/locale/cs-CZ/zotero/zotero.properties @@ -36,6 +36,7 @@ general.enable=Povolit general.disable=Zakázat general.remove=Remove general.openDocumentation=Open Documentation +general.numMore=%S more… general.operationInProgress=Právě probíhá operace se Zoterem. general.operationInProgress.waitUntilFinished=Počkejte prosím, dokud neskončí. @@ -80,7 +81,7 @@ app.firefox=Zotero for Firefox startupError=Při spouštění aplikace Zotero nastala chyba. startupError.databaseInUse=Your Zotero database is currently in use. Only one instance of Zotero using the same database may be opened simultaneously at this time. -startupError.closeStandalone=If Zotero Standalone is open, please close it and restart Firefox. +startupError.closeStandalone=If Zotero Standalone is open, please close it and restart %S. startupError.closeFirefox=If Firefox with the Zotero extension is open, please close it and restart Zotero Standalone. startupError.databaseCannotBeOpened=Databáze Zotera nemohla být otevřena. startupError.checkPermissions=Ujistěte se, že máte všechna práva pro čtení a zápis souborů do datového adresáře Zotera. @@ -112,6 +113,7 @@ pane.collections.library=Moje knihovna pane.collections.trash=Koš pane.collections.untitled=Nepojmenované pane.collections.unfiled=Unfiled Items +pane.collections.duplicate=Duplicate Items pane.collections.menu.rename.collection=Přejmenovat kolekci... pane.collections.menu.edit.savedSearch=Editovat Uložené hledání @@ -170,6 +172,10 @@ pane.items.interview.manyParticipants=Rozhovor - %S a další pane.item.selected.zero=Nebyly vybrány žádné položky pane.item.selected.multiple=vybráno %S položek +pane.item.unselected.zero=No items in this view +pane.item.unselected.singular=%S item in this view +pane.item.unselected.plural=%S items in this view +pane.item.selectToMerge=Select items to merge pane.item.changeType.title=Změnit typ položky pane.item.changeType.text=Jste si jisti, že chcete změnit typ této položky?\n\nNásledující pole budou ztracena: @@ -178,6 +184,8 @@ pane.item.defaultLastName=poslední pane.item.defaultFullName=plné jméno pane.item.switchFieldMode.one=Přepnout na jedno pole pane.item.switchFieldMode.two=Přepnout na více polí +pane.item.creator.moveUp=Move Up +pane.item.creator.moveDown=Move Down pane.item.notes.untitled=Nepojmenovaná poznámka pane.item.notes.delete.confirm=Jste si jistý, že chcete smazat tuto poznámku? pane.item.notes.count.zero=%S poznámek: diff --git a/chrome/locale/da-DK/zotero/zotero.dtd b/chrome/locale/da-DK/zotero/zotero.dtd @@ -68,6 +68,10 @@ <!ENTITY zotero.items.menu.restoreToLibrary "Restore to Library"> <!ENTITY zotero.items.menu.duplicateItem "Duplicate Selected Item"> +<!ENTITY zotero.items.menu.mergeItems "Merge Items…"> + +<!ENTITY zotero.duplicatesMerge.versionSelect "Choose the version of the item to use as the master item:"> +<!ENTITY zotero.duplicatesMerge.fieldSelect "Select fields to keep from other versions of the item:"> <!ENTITY zotero.toolbar.newItem.label "New Item"> <!ENTITY zotero.toolbar.moreItemTypes.label "More"> diff --git a/chrome/locale/da-DK/zotero/zotero.properties b/chrome/locale/da-DK/zotero/zotero.properties @@ -36,6 +36,7 @@ general.enable=Slå til general.disable=Slå fra general.remove=Fjern general.openDocumentation=Open Documentation +general.numMore=%S more… general.operationInProgress=En Zotero-operation er ved at blive udført. general.operationInProgress.waitUntilFinished=Vent venligst til den er færdig. @@ -112,6 +113,7 @@ pane.collections.library=Mit Bibliotek pane.collections.trash=Papirkurv pane.collections.untitled=Uden navn pane.collections.unfiled=Elementer som ikke er gemt. +pane.collections.duplicate=Duplicate Items pane.collections.menu.rename.collection=Omdøb en Samling... pane.collections.menu.edit.savedSearch=Revider en gemt Søgning @@ -170,6 +172,10 @@ pane.items.interview.manyParticipants=Interview ved %S mfl. pane.item.selected.zero=Ingen Elementer valgt pane.item.selected.multiple=%S Elementer valgt +pane.item.unselected.zero=No items in this view +pane.item.unselected.singular=%S item in this view +pane.item.unselected.plural=%S items in this view +pane.item.selectToMerge=Select items to merge pane.item.changeType.title=Henfør Elementet til en ny type pane.item.changeType.text=Er du sikker på at du vil ændre Elementets Type?\n\nFølgende felter går tabt: @@ -178,6 +184,8 @@ pane.item.defaultLastName=Efternavn pane.item.defaultFullName=Udelt navn pane.item.switchFieldMode.one=Skift til udelt navnefelt pane.item.switchFieldMode.two=Skift til delt navnefelt +pane.item.creator.moveUp=Move Up +pane.item.creator.moveDown=Move Down pane.item.notes.untitled=Note uden titel pane.item.notes.delete.confirm=Er du sikker på at du vil slette denne Note? pane.item.notes.count.zero=%S Noter: diff --git a/chrome/locale/de/zotero/zotero.dtd b/chrome/locale/de/zotero/zotero.dtd @@ -68,6 +68,10 @@ <!ENTITY zotero.items.menu.restoreToLibrary "In der Bibliothek wiederherstellen"> <!ENTITY zotero.items.menu.duplicateItem "Ausgewählten Eintrag duplizieren"> +<!ENTITY zotero.items.menu.mergeItems "Merge Items…"> + +<!ENTITY zotero.duplicatesMerge.versionSelect "Choose the version of the item to use as the master item:"> +<!ENTITY zotero.duplicatesMerge.fieldSelect "Select fields to keep from other versions of the item:"> <!ENTITY zotero.toolbar.newItem.label "Neuer Eintrag"> <!ENTITY zotero.toolbar.moreItemTypes.label "Mehr"> diff --git a/chrome/locale/de/zotero/zotero.properties b/chrome/locale/de/zotero/zotero.properties @@ -36,6 +36,7 @@ general.enable=Aktivieren general.disable=Deaktivieren general.remove=Entfernen general.openDocumentation=Dokumentation öffnen +general.numMore=%S more… general.operationInProgress=Zotero ist beschäftigt. general.operationInProgress.waitUntilFinished=Bitte warten Sie, bis der Vorgang abgeschlossen ist. @@ -112,6 +113,7 @@ pane.collections.library=Meine Bibliothek pane.collections.trash=Papierkorb pane.collections.untitled=Ohne Titel pane.collections.unfiled=Einträge ohne Sammlung +pane.collections.duplicate=Duplicate Items pane.collections.menu.rename.collection=Sammlung umbenennen... pane.collections.menu.edit.savedSearch=Gespeicherte Suche bearbeiten @@ -170,6 +172,10 @@ pane.items.interview.manyParticipants=Interview von %S et al. pane.item.selected.zero=Keine Einträge ausgewählt pane.item.selected.multiple=%S Einträge ausgewählt +pane.item.unselected.zero=No items in this view +pane.item.unselected.singular=%S item in this view +pane.item.unselected.plural=%S items in this view +pane.item.selectToMerge=Select items to merge pane.item.changeType.title=Eintragstyp ändern pane.item.changeType.text=Sind Sie sicher, dass Sie den Eintragstyp ändern wollen?\n\nDie folgenden Felder werden dabei verloren gehen: @@ -178,6 +184,8 @@ pane.item.defaultLastName=Name pane.item.defaultFullName=vollständiger Name pane.item.switchFieldMode.one=Zu einfachem Feld wechseln pane.item.switchFieldMode.two=Zu zwei Feldern wechseln +pane.item.creator.moveUp=Move Up +pane.item.creator.moveDown=Move Down pane.item.notes.untitled=Notiz ohne Titel pane.item.notes.delete.confirm=Sind Sie sicher, dass Sie diese Notiz löschen möchten? pane.item.notes.count.zero=%S Notizen: diff --git a/chrome/locale/el-GR/zotero/zotero.dtd b/chrome/locale/el-GR/zotero/zotero.dtd @@ -68,6 +68,10 @@ <!ENTITY zotero.items.menu.restoreToLibrary "Restore to Library"> <!ENTITY zotero.items.menu.duplicateItem "Duplicate Selected Item"> +<!ENTITY zotero.items.menu.mergeItems "Merge Items…"> + +<!ENTITY zotero.duplicatesMerge.versionSelect "Choose the version of the item to use as the master item:"> +<!ENTITY zotero.duplicatesMerge.fieldSelect "Select fields to keep from other versions of the item:"> <!ENTITY zotero.toolbar.newItem.label "New Item"> <!ENTITY zotero.toolbar.moreItemTypes.label "More"> diff --git a/chrome/locale/el-GR/zotero/zotero.properties b/chrome/locale/el-GR/zotero/zotero.properties @@ -36,6 +36,7 @@ general.enable=Enable general.disable=Disable general.remove=Remove general.openDocumentation=Open Documentation +general.numMore=%S more… general.operationInProgress=A Zotero operation is currently in progress. general.operationInProgress.waitUntilFinished=Please wait until it has finished. @@ -80,7 +81,7 @@ app.firefox=Zotero for Firefox startupError=There was an error starting Zotero. startupError.databaseInUse=Your Zotero database is currently in use. Only one instance of Zotero using the same database may be opened simultaneously at this time. -startupError.closeStandalone=If Zotero Standalone is open, please close it and restart Firefox. +startupError.closeStandalone=If Zotero Standalone is open, please close it and restart %S. startupError.closeFirefox=If Firefox with the Zotero extension is open, please close it and restart Zotero Standalone. startupError.databaseCannotBeOpened=The Zotero database cannot be opened. startupError.checkPermissions=Make sure you have read and write permissions to all files in the Zotero data directory. @@ -112,6 +113,7 @@ pane.collections.library=My Library pane.collections.trash=Trash pane.collections.untitled=Untitled pane.collections.unfiled=Unfiled Items +pane.collections.duplicate=Duplicate Items pane.collections.menu.rename.collection=Rename Collection... pane.collections.menu.edit.savedSearch=Edit Saved Search @@ -170,6 +172,10 @@ pane.items.interview.manyParticipants=Interview by %S et al. pane.item.selected.zero=No items selected pane.item.selected.multiple=%S items selected +pane.item.unselected.zero=No items in this view +pane.item.unselected.singular=%S item in this view +pane.item.unselected.plural=%S items in this view +pane.item.selectToMerge=Select items to merge pane.item.changeType.title=Change Item Type pane.item.changeType.text=Are you sure you want to change the item type?\n\nThe following fields will be lost: @@ -178,6 +184,8 @@ pane.item.defaultLastName=last pane.item.defaultFullName=full name pane.item.switchFieldMode.one=Switch to single field pane.item.switchFieldMode.two=Switch to two fields +pane.item.creator.moveUp=Move Up +pane.item.creator.moveDown=Move Down pane.item.notes.untitled=Untitled Note pane.item.notes.delete.confirm=Are you sure you want to delete this note? pane.item.notes.count.zero=%S notes: diff --git a/chrome/locale/es-ES/zotero/zotero.dtd b/chrome/locale/es-ES/zotero/zotero.dtd @@ -68,6 +68,10 @@ <!ENTITY zotero.items.menu.restoreToLibrary "Restore to Library"> <!ENTITY zotero.items.menu.duplicateItem "Duplicar el ítem seleccionado"> +<!ENTITY zotero.items.menu.mergeItems "Merge Items…"> + +<!ENTITY zotero.duplicatesMerge.versionSelect "Choose the version of the item to use as the master item:"> +<!ENTITY zotero.duplicatesMerge.fieldSelect "Select fields to keep from other versions of the item:"> <!ENTITY zotero.toolbar.newItem.label "Nuevo ítem"> <!ENTITY zotero.toolbar.moreItemTypes.label "Más"> diff --git a/chrome/locale/es-ES/zotero/zotero.properties b/chrome/locale/es-ES/zotero/zotero.properties @@ -36,6 +36,7 @@ general.enable=Activar general.disable=Desactivar general.remove=Remove general.openDocumentation=Open Documentation +general.numMore=%S more… general.operationInProgress=Una operación de Zotero se encuentra en progreso. general.operationInProgress.waitUntilFinished=Espera hasta que termine. @@ -80,7 +81,7 @@ app.firefox=Zotero for Firefox startupError=Hubo un error al iniciar Zotero. startupError.databaseInUse=Your Zotero database is currently in use. Only one instance of Zotero using the same database may be opened simultaneously at this time. -startupError.closeStandalone=If Zotero Standalone is open, please close it and restart Firefox. +startupError.closeStandalone=If Zotero Standalone is open, please close it and restart %S. startupError.closeFirefox=If Firefox with the Zotero extension is open, please close it and restart Zotero Standalone. startupError.databaseCannotBeOpened=No puedo abrir la base de datos de Zotero. startupError.checkPermissions=Asegúrate de tener permiso de lectura y escritura en el directorio de datos de Zotero. @@ -112,6 +113,7 @@ pane.collections.library=Mi biblioteca pane.collections.trash=Trash pane.collections.untitled=Sin título pane.collections.unfiled=Unfiled Items +pane.collections.duplicate=Duplicate Items pane.collections.menu.rename.collection=Renombrar la colección... pane.collections.menu.edit.savedSearch=Modificar la carpeta de búsqueda @@ -170,6 +172,10 @@ pane.items.interview.manyParticipants=Entrevista por %S et al. pane.item.selected.zero=Ningún ítem seleccionado pane.item.selected.multiple=%S ítems seleccionados +pane.item.unselected.zero=No items in this view +pane.item.unselected.singular=%S item in this view +pane.item.unselected.plural=%S items in this view +pane.item.selectToMerge=Select items to merge pane.item.changeType.title=Cambiar el tipo de ítem pane.item.changeType.text=¿Seguro que quieres cambiar el tipo de ítem?\n\nLos siguientes campos se perderán: @@ -178,6 +184,8 @@ pane.item.defaultLastName=último pane.item.defaultFullName=nombre completo pane.item.switchFieldMode.one=Cambiar a campo simple pane.item.switchFieldMode.two=Cambiar a dos campos +pane.item.creator.moveUp=Move Up +pane.item.creator.moveDown=Move Down pane.item.notes.untitled=Nota sin título pane.item.notes.delete.confirm=¿Seguro que quieres borrar esta nota? pane.item.notes.count.zero=Ninguna nota. diff --git a/chrome/locale/et-EE/zotero/zotero.dtd b/chrome/locale/et-EE/zotero/zotero.dtd @@ -68,6 +68,10 @@ <!ENTITY zotero.items.menu.restoreToLibrary "Taasta raamatukokku"> <!ENTITY zotero.items.menu.duplicateItem "Valitud kirje duplitseerimine"> +<!ENTITY zotero.items.menu.mergeItems "Merge Items…"> + +<!ENTITY zotero.duplicatesMerge.versionSelect "Choose the version of the item to use as the master item:"> +<!ENTITY zotero.duplicatesMerge.fieldSelect "Select fields to keep from other versions of the item:"> <!ENTITY zotero.toolbar.newItem.label "Uus kirje"> <!ENTITY zotero.toolbar.moreItemTypes.label "Veel"> diff --git a/chrome/locale/et-EE/zotero/zotero.properties b/chrome/locale/et-EE/zotero/zotero.properties @@ -36,6 +36,7 @@ general.enable=Lubada general.disable=Keelata general.remove=Eemaldada general.openDocumentation=Dokumentatsiooni avamine +general.numMore=%S more… general.operationInProgress=Zotero parajasti toimetab. general.operationInProgress.waitUntilFinished=Palun oodake kuni see lõpeb. @@ -112,6 +113,7 @@ pane.collections.library=Minu raamatukogu pane.collections.trash=Praht pane.collections.untitled=Nimeta pane.collections.unfiled=Teemata kirjed +pane.collections.duplicate=Duplicate Items pane.collections.menu.rename.collection=Teema ümbernimetamine... pane.collections.menu.edit.savedSearch=Salvestatud otsingu toimetamine @@ -170,6 +172,10 @@ pane.items.interview.manyParticipants=Intervjueerijad %S et al. pane.item.selected.zero=Kirjeid ei ole valitud pane.item.selected.multiple=%S kirjet valitud +pane.item.unselected.zero=No items in this view +pane.item.unselected.singular=%S item in this view +pane.item.unselected.plural=%S items in this view +pane.item.selectToMerge=Select items to merge pane.item.changeType.title=Kirje tüübi muutmine pane.item.changeType.text=Soovite kindlasti selle kirje tüüpi muutma?\n\nJärgnevad väljad kustutatakse: @@ -178,6 +184,8 @@ pane.item.defaultLastName=Perekonnanimi pane.item.defaultFullName=Täisnimi pane.item.switchFieldMode.one=Ühendväli pane.item.switchFieldMode.two=Eraldi väljad +pane.item.creator.moveUp=Move Up +pane.item.creator.moveDown=Move Down pane.item.notes.untitled=Nimeta märkus pane.item.notes.delete.confirm=Soovite kindlasti seda märkust kustutada? pane.item.notes.count.zero=%S märkust: diff --git a/chrome/locale/eu-ES/zotero/zotero.dtd b/chrome/locale/eu-ES/zotero/zotero.dtd @@ -68,6 +68,10 @@ <!ENTITY zotero.items.menu.restoreToLibrary "Restore to Library"> <!ENTITY zotero.items.menu.duplicateItem "Hautatutako itema bikoiztu"> +<!ENTITY zotero.items.menu.mergeItems "Merge Items…"> + +<!ENTITY zotero.duplicatesMerge.versionSelect "Choose the version of the item to use as the master item:"> +<!ENTITY zotero.duplicatesMerge.fieldSelect "Select fields to keep from other versions of the item:"> <!ENTITY zotero.toolbar.newItem.label "Item berria"> <!ENTITY zotero.toolbar.moreItemTypes.label "Gehiago"> diff --git a/chrome/locale/eu-ES/zotero/zotero.properties b/chrome/locale/eu-ES/zotero/zotero.properties @@ -36,6 +36,7 @@ general.enable=Gaitu general.disable=Ezgaitu general.remove=Remove general.openDocumentation=Open Documentation +general.numMore=%S more… general.operationInProgress=Zotero lanean ari da. general.operationInProgress.waitUntilFinished=Itxaren ezazu bukatu arte. @@ -80,7 +81,7 @@ app.firefox=Zotero for Firefox startupError=Errore bat gertatu da Zotero abiatzekotan. startupError.databaseInUse=Your Zotero database is currently in use. Only one instance of Zotero using the same database may be opened simultaneously at this time. -startupError.closeStandalone=If Zotero Standalone is open, please close it and restart Firefox. +startupError.closeStandalone=If Zotero Standalone is open, please close it and restart %S. startupError.closeFirefox=If Firefox with the Zotero extension is open, please close it and restart Zotero Standalone. startupError.databaseCannotBeOpened=Zotero datu-basea ezin izan da ireki. startupError.checkPermissions=Egiaztatu zure irakur eta idazteko baimenak Zotero fitxategiei dagokionez. @@ -112,6 +113,7 @@ pane.collections.library=Nire Liburutegia pane.collections.trash=Zaborra pane.collections.untitled=Titulu gabe pane.collections.unfiled=Unfiled Items +pane.collections.duplicate=Duplicate Items pane.collections.menu.rename.collection=Aldatu bildumaren izena... pane.collections.menu.edit.savedSearch=Editatu gordetako bilaketa @@ -170,6 +172,10 @@ pane.items.interview.manyParticipants=Elkarrizketa %S eta besteek egina pane.item.selected.zero=Ez da ezer hautatu. pane.item.selected.multiple=%S hautaturiko item +pane.item.unselected.zero=No items in this view +pane.item.unselected.singular=%S item in this view +pane.item.unselected.plural=%S items in this view +pane.item.selectToMerge=Select items to merge pane.item.changeType.title=Aldatu item mota pane.item.changeType.text=Benetan item mota alduatu?\n\nOndorengo eremuak galduko dira: @@ -178,6 +184,8 @@ pane.item.defaultLastName=Abizena pane.item.defaultFullName=Izen osoa pane.item.switchFieldMode.one=Eremu bakarra ezarri pane.item.switchFieldMode.two=Eremu bikoitza ezarri +pane.item.creator.moveUp=Move Up +pane.item.creator.moveDown=Move Down pane.item.notes.untitled=Izengabeko oharra pane.item.notes.delete.confirm=Benetan ezabatu ohar hau? pane.item.notes.count.zero=%S ohar: diff --git a/chrome/locale/fa/zotero/zotero.dtd b/chrome/locale/fa/zotero/zotero.dtd @@ -68,6 +68,10 @@ <!ENTITY zotero.items.menu.restoreToLibrary "Restore to Library"> <!ENTITY zotero.items.menu.duplicateItem "ساخت رونوشت از این آیتم"> +<!ENTITY zotero.items.menu.mergeItems "Merge Items…"> + +<!ENTITY zotero.duplicatesMerge.versionSelect "Choose the version of the item to use as the master item:"> +<!ENTITY zotero.duplicatesMerge.fieldSelect "Select fields to keep from other versions of the item:"> <!ENTITY zotero.toolbar.newItem.label "آیتم‌ جدید"> <!ENTITY zotero.toolbar.moreItemTypes.label "بیشتر"> diff --git a/chrome/locale/fa/zotero/zotero.properties b/chrome/locale/fa/zotero/zotero.properties @@ -36,6 +36,7 @@ general.enable=فعال general.disable=غیرفعال general.remove=حذف general.openDocumentation=Open Documentation +general.numMore=%S more… general.operationInProgress=زوترو در حال انجام کاری است. general.operationInProgress.waitUntilFinished=لطفا تا زمان اتمام آن صبر کنید. @@ -112,6 +113,7 @@ pane.collections.library=کتابخانه pane.collections.trash=سطل بازیافت pane.collections.untitled=بدون عنوان pane.collections.unfiled=آیتم‌های دسته‌بندی نشده +pane.collections.duplicate=Duplicate Items pane.collections.menu.rename.collection=تغییر نام مجموعه... pane.collections.menu.edit.savedSearch=ویرایش جستجوی ذخیره شده @@ -170,6 +172,10 @@ pane.items.interview.manyParticipants=مصاحبه توسط %S و دیگران pane.item.selected.zero=هیچ آیتمی انتخاب نشده است pane.item.selected.multiple=%S آیتم‌ انتخاب شده +pane.item.unselected.zero=No items in this view +pane.item.unselected.singular=%S item in this view +pane.item.unselected.plural=%S items in this view +pane.item.selectToMerge=Select items to merge pane.item.changeType.title=تغییر نوع آیتم‌ pane.item.changeType.text=آیا واقعا می‌خواهید نوع آیتم‌ را عوض کنید؟\n\nاین فیلد‌ها از بین خواهند رفت: @@ -178,6 +184,8 @@ pane.item.defaultLastName=نام خانوادگی pane.item.defaultFullName=نام کامل pane.item.switchFieldMode.one=تعویض به تک فیلدی pane.item.switchFieldMode.two=تعویض به دو فیلدی +pane.item.creator.moveUp=Move Up +pane.item.creator.moveDown=Move Down pane.item.notes.untitled=یادداشت بی‌عنوان pane.item.notes.delete.confirm=آیا واقعا می‌خواهید این یادداشت را حذف کنید؟ pane.item.notes.count.zero=بدون یادداشت: diff --git a/chrome/locale/fi-FI/zotero/zotero.dtd b/chrome/locale/fi-FI/zotero/zotero.dtd @@ -69,6 +69,10 @@ <!ENTITY zotero.items.menu.restoreToLibrary "Palauta kirjastoon"> <!ENTITY zotero.items.menu.duplicateItem "Monista valittu nimike"> +<!ENTITY zotero.items.menu.mergeItems "Merge Items…"> + +<!ENTITY zotero.duplicatesMerge.versionSelect "Choose the version of the item to use as the master item:"> +<!ENTITY zotero.duplicatesMerge.fieldSelect "Select fields to keep from other versions of the item:"> <!ENTITY zotero.toolbar.newItem.label "Uusi nimike"> <!ENTITY zotero.toolbar.moreItemTypes.label "Lisää"> diff --git a/chrome/locale/fi-FI/zotero/zotero.properties b/chrome/locale/fi-FI/zotero/zotero.properties @@ -36,6 +36,7 @@ general.enable=Laita päälle general.disable=Ota pois päältä general.remove=Poista general.openDocumentation=Avaa käyttöohje +general.numMore=%S more… general.operationInProgress=Zoteron toimenpide on käynnissä. general.operationInProgress.waitUntilFinished=Odota, kunnes se valmis. @@ -112,6 +113,7 @@ pane.collections.library=Oma Kirjasto pane.collections.trash=Roskakori pane.collections.untitled=Nimetön pane.collections.unfiled=Lajittelemattomat nimikkeet +pane.collections.duplicate=Duplicate Items pane.collections.menu.rename.collection=Nimeä kokoelma uudelleen... pane.collections.menu.edit.savedSearch=Muokkaa tallennettua hakua @@ -170,6 +172,10 @@ pane.items.interview.manyParticipants=Haastattelu, tehneet %S ym. pane.item.selected.zero=Ei valittuja kohteita pane.item.selected.multiple=%S kohdetta valittuna +pane.item.unselected.zero=No items in this view +pane.item.unselected.singular=%S item in this view +pane.item.unselected.plural=%S items in this view +pane.item.selectToMerge=Select items to merge pane.item.changeType.title=Vaihda kohteen tyyppi pane.item.changeType.text=Haluatko varmasti vaihtaa kohteen tyypin?\n\nSeuraavat kentät menetetään: @@ -178,6 +184,8 @@ pane.item.defaultLastName=suku pane.item.defaultFullName=koko nimi pane.item.switchFieldMode.one=Käytä vain yhtä kenttää pane.item.switchFieldMode.two=Käytä kahta kenttää +pane.item.creator.moveUp=Move Up +pane.item.creator.moveDown=Move Down pane.item.notes.untitled=Otsikoimaton muistio pane.item.notes.delete.confirm=Haluatko varmasti poistaa tämän muistion? pane.item.notes.count.zero=%S muistiota: diff --git a/chrome/locale/fr-FR/zotero/zotero.dtd b/chrome/locale/fr-FR/zotero/zotero.dtd @@ -68,6 +68,10 @@ <!ENTITY zotero.items.menu.restoreToLibrary "Restaurer vers la bibliothèque"> <!ENTITY zotero.items.menu.duplicateItem "Dupliquer le document sélectionné"> +<!ENTITY zotero.items.menu.mergeItems "Merge Items…"> + +<!ENTITY zotero.duplicatesMerge.versionSelect "Choose the version of the item to use as the master item:"> +<!ENTITY zotero.duplicatesMerge.fieldSelect "Select fields to keep from other versions of the item:"> <!ENTITY zotero.toolbar.newItem.label "Nouveau document"> <!ENTITY zotero.toolbar.moreItemTypes.label "Plus"> diff --git a/chrome/locale/fr-FR/zotero/zotero.properties b/chrome/locale/fr-FR/zotero/zotero.properties @@ -36,6 +36,7 @@ general.enable=Activer general.disable=Désactiver general.remove=Supprimer general.openDocumentation=Consulter la documentation +general.numMore=%S more… general.operationInProgress=Une opération Zotero est actuellement en cours. general.operationInProgress.waitUntilFinished=Veuillez attendre jusqu'à ce qu'elle soit terminée. @@ -112,6 +113,7 @@ pane.collections.library=Ma bibliothèque pane.collections.trash=Corbeille pane.collections.untitled=Sans titre pane.collections.unfiled=Non classés +pane.collections.duplicate=Duplicate Items pane.collections.menu.rename.collection=Renommer la collection… pane.collections.menu.edit.savedSearch=Modifier la recherche enregistrée @@ -170,6 +172,10 @@ pane.items.interview.manyParticipants=Interview par %S et coll. pane.item.selected.zero=Aucun document sélectionné pane.item.selected.multiple=%S documents sélectionnés +pane.item.unselected.zero=No items in this view +pane.item.unselected.singular=%S item in this view +pane.item.unselected.plural=%S items in this view +pane.item.selectToMerge=Select items to merge pane.item.changeType.title=Changer le type du document pane.item.changeType.text=Voulez-vous vraiment changer le type du document ?\n\nLes champs suivants seront perdus : @@ -178,6 +184,8 @@ pane.item.defaultLastName=Nom pane.item.defaultFullName=Nom complet pane.item.switchFieldMode.one=Afficher un champ unique pane.item.switchFieldMode.two=Afficher deux champs +pane.item.creator.moveUp=Move Up +pane.item.creator.moveDown=Move Down pane.item.notes.untitled=Note sans titre pane.item.notes.delete.confirm=Voulez-vous vraiment supprimer cette note ? pane.item.notes.count.zero=%S note : diff --git a/chrome/locale/gl-ES/zotero/zotero.dtd b/chrome/locale/gl-ES/zotero/zotero.dtd @@ -68,6 +68,10 @@ <!ENTITY zotero.items.menu.restoreToLibrary "Restore to Library"> <!ENTITY zotero.items.menu.duplicateItem "Duplicar Elementos Seleccionados"> +<!ENTITY zotero.items.menu.mergeItems "Merge Items…"> + +<!ENTITY zotero.duplicatesMerge.versionSelect "Choose the version of the item to use as the master item:"> +<!ENTITY zotero.duplicatesMerge.fieldSelect "Select fields to keep from other versions of the item:"> <!ENTITY zotero.toolbar.newItem.label "Novo Elemento"> <!ENTITY zotero.toolbar.moreItemTypes.label "Máis"> diff --git a/chrome/locale/gl-ES/zotero/zotero.properties b/chrome/locale/gl-ES/zotero/zotero.properties @@ -36,6 +36,7 @@ general.enable=Activar general.disable=Desactivar general.remove=Remove general.openDocumentation=Open Documentation +general.numMore=%S more… general.operationInProgress=Está en marcha unha operación Zotero general.operationInProgress.waitUntilFinished=Por favor, agarde ata que teña acabado. @@ -80,7 +81,7 @@ app.firefox=Zotero for Firefox startupError=Produciuse un erro ao iniciar Zotero. startupError.databaseInUse=Your Zotero database is currently in use. Only one instance of Zotero using the same database may be opened simultaneously at this time. -startupError.closeStandalone=If Zotero Standalone is open, please close it and restart Firefox. +startupError.closeStandalone=If Zotero Standalone is open, please close it and restart %S. startupError.closeFirefox=If Firefox with the Zotero extension is open, please close it and restart Zotero Standalone. startupError.databaseCannotBeOpened=Non pode abrirse a base de datos Zotero. startupError.checkPermissions=Asegúrese de ter permisos de lectura e escritura para todos os ficheiros no directorio de datos Zotero. @@ -112,6 +113,7 @@ pane.collections.library=A Miña Biblioteca pane.collections.trash=Lixo pane.collections.untitled=Sen título pane.collections.unfiled=Unfiled Items +pane.collections.duplicate=Duplicate Items pane.collections.menu.rename.collection=Cambiar o Nome da Colección: pane.collections.menu.edit.savedSearch=Editar Procura Gravada @@ -170,6 +172,10 @@ pane.items.interview.manyParticipants=Entrevista realizada por %S et al. pane.item.selected.zero=Non hai elementos seleccionados pane.item.selected.multiple=%S elementos seleccionados +pane.item.unselected.zero=No items in this view +pane.item.unselected.singular=%S item in this view +pane.item.unselected.plural=%S items in this view +pane.item.selectToMerge=Select items to merge pane.item.changeType.title=Cambiar Tipo de Elemento pane.item.changeType.text=Está seguro de que quere cambiar o tipo de elemento?\n\nPerderanse os campos seguintes : @@ -178,6 +184,8 @@ pane.item.defaultLastName=último pane.item.defaultFullName=Nome completo pane.item.switchFieldMode.one=Cambiar a un só campo pane.item.switchFieldMode.two=Cambiar a dous campos +pane.item.creator.moveUp=Move Up +pane.item.creator.moveDown=Move Down pane.item.notes.untitled=Nota sen título pane.item.notes.delete.confirm=Seguro que desexa eliminar esta nota? pane.item.notes.count.zero=%S notas: diff --git a/chrome/locale/he-IL/zotero/zotero.dtd b/chrome/locale/he-IL/zotero/zotero.dtd @@ -68,6 +68,10 @@ <!ENTITY zotero.items.menu.restoreToLibrary "Restore to Library"> <!ENTITY zotero.items.menu.duplicateItem "Duplicate Selected Item"> +<!ENTITY zotero.items.menu.mergeItems "Merge Items…"> + +<!ENTITY zotero.duplicatesMerge.versionSelect "Choose the version of the item to use as the master item:"> +<!ENTITY zotero.duplicatesMerge.fieldSelect "Select fields to keep from other versions of the item:"> <!ENTITY zotero.toolbar.newItem.label "פריט חדש"> <!ENTITY zotero.toolbar.moreItemTypes.label "More"> diff --git a/chrome/locale/he-IL/zotero/zotero.properties b/chrome/locale/he-IL/zotero/zotero.properties @@ -36,6 +36,7 @@ general.enable=Enable general.disable=Disable general.remove=Remove general.openDocumentation=Open Documentation +general.numMore=%S more… general.operationInProgress=A Zotero operation is currently in progress. general.operationInProgress.waitUntilFinished=Please wait until it has finished. @@ -80,7 +81,7 @@ app.firefox=Zotero for Firefox startupError=.Zotero התרחשה שגיאה בעת הפעלת startupError.databaseInUse=Your Zotero database is currently in use. Only one instance of Zotero using the same database may be opened simultaneously at this time. -startupError.closeStandalone=If Zotero Standalone is open, please close it and restart Firefox. +startupError.closeStandalone=If Zotero Standalone is open, please close it and restart %S. startupError.closeFirefox=If Firefox with the Zotero extension is open, please close it and restart Zotero Standalone. startupError.databaseCannotBeOpened=The Zotero database cannot be opened. startupError.checkPermissions=Make sure you have read and write permissions to all files in the Zotero data directory. @@ -112,6 +113,7 @@ pane.collections.library=הספרייה שלי pane.collections.trash=Trash pane.collections.untitled=ללא שם pane.collections.unfiled=Unfiled Items +pane.collections.duplicate=Duplicate Items pane.collections.menu.rename.collection=שנה שם אוסף pane.collections.menu.edit.savedSearch=ערוך חיפושים שמורים @@ -170,6 +172,10 @@ pane.items.interview.manyParticipants=Interview by %S et al. pane.item.selected.zero=לא נבחרו פריטים pane.item.selected.multiple=%S items selected +pane.item.unselected.zero=No items in this view +pane.item.unselected.singular=%S item in this view +pane.item.unselected.plural=%S items in this view +pane.item.selectToMerge=Select items to merge pane.item.changeType.title=שנה סוג פריט pane.item.changeType.text=Are you sure you want to change the item type?\n\nThe following fields will be lost: @@ -178,6 +184,8 @@ pane.item.defaultLastName=שם משפחה pane.item.defaultFullName=שם מלא pane.item.switchFieldMode.one=החלף לשדה בודד pane.item.switchFieldMode.two=החלף לשני שדות +pane.item.creator.moveUp=Move Up +pane.item.creator.moveDown=Move Down pane.item.notes.untitled=Untitled Note pane.item.notes.delete.confirm=Are you sure you want to delete this note? pane.item.notes.count.zero=%S notes: diff --git a/chrome/locale/hr-HR/zotero/zotero.dtd b/chrome/locale/hr-HR/zotero/zotero.dtd @@ -68,6 +68,10 @@ <!ENTITY zotero.items.menu.restoreToLibrary "Restore to Library"> <!ENTITY zotero.items.menu.duplicateItem "Duplicate Selected Item"> +<!ENTITY zotero.items.menu.mergeItems "Merge Items…"> + +<!ENTITY zotero.duplicatesMerge.versionSelect "Choose the version of the item to use as the master item:"> +<!ENTITY zotero.duplicatesMerge.fieldSelect "Select fields to keep from other versions of the item:"> <!ENTITY zotero.toolbar.newItem.label "New Item"> <!ENTITY zotero.toolbar.moreItemTypes.label "More"> diff --git a/chrome/locale/hr-HR/zotero/zotero.properties b/chrome/locale/hr-HR/zotero/zotero.properties @@ -36,6 +36,7 @@ general.enable=Enable general.disable=Disable general.remove=Remove general.openDocumentation=Open Documentation +general.numMore=%S more… general.operationInProgress=A Zotero operation is currently in progress. general.operationInProgress.waitUntilFinished=Please wait until it has finished. @@ -80,7 +81,7 @@ app.firefox=Zotero for Firefox startupError=There was an error starting Zotero. startupError.databaseInUse=Your Zotero database is currently in use. Only one instance of Zotero using the same database may be opened simultaneously at this time. -startupError.closeStandalone=If Zotero Standalone is open, please close it and restart Firefox. +startupError.closeStandalone=If Zotero Standalone is open, please close it and restart %S. startupError.closeFirefox=If Firefox with the Zotero extension is open, please close it and restart Zotero Standalone. startupError.databaseCannotBeOpened=The Zotero database cannot be opened. startupError.checkPermissions=Make sure you have read and write permissions to all files in the Zotero data directory. @@ -112,6 +113,7 @@ pane.collections.library=My Library pane.collections.trash=Trash pane.collections.untitled=Untitled pane.collections.unfiled=Unfiled Items +pane.collections.duplicate=Duplicate Items pane.collections.menu.rename.collection=Rename Collection... pane.collections.menu.edit.savedSearch=Edit Saved Search @@ -170,6 +172,10 @@ pane.items.interview.manyParticipants=Interview by %S et al. pane.item.selected.zero=No items selected pane.item.selected.multiple=%S items selected +pane.item.unselected.zero=No items in this view +pane.item.unselected.singular=%S item in this view +pane.item.unselected.plural=%S items in this view +pane.item.selectToMerge=Select items to merge pane.item.changeType.title=Change Item Type pane.item.changeType.text=Are you sure you want to change the item type?\n\nThe following fields will be lost: @@ -178,6 +184,8 @@ pane.item.defaultLastName=last pane.item.defaultFullName=full name pane.item.switchFieldMode.one=Switch to single field pane.item.switchFieldMode.two=Switch to two fields +pane.item.creator.moveUp=Move Up +pane.item.creator.moveDown=Move Down pane.item.notes.untitled=Untitled Note pane.item.notes.delete.confirm=Are you sure you want to delete this note? pane.item.notes.count.zero=%S notes: diff --git a/chrome/locale/hu-HU/zotero/zotero.dtd b/chrome/locale/hu-HU/zotero/zotero.dtd @@ -68,6 +68,10 @@ <!ENTITY zotero.items.menu.restoreToLibrary "Restore to Library"> <!ENTITY zotero.items.menu.duplicateItem "Kiválasztott elem duplikálása"> +<!ENTITY zotero.items.menu.mergeItems "Merge Items…"> + +<!ENTITY zotero.duplicatesMerge.versionSelect "Choose the version of the item to use as the master item:"> +<!ENTITY zotero.duplicatesMerge.fieldSelect "Select fields to keep from other versions of the item:"> <!ENTITY zotero.toolbar.newItem.label "Új elem"> <!ENTITY zotero.toolbar.moreItemTypes.label "Egyéb..."> diff --git a/chrome/locale/hu-HU/zotero/zotero.properties b/chrome/locale/hu-HU/zotero/zotero.properties @@ -36,6 +36,7 @@ general.enable=Bekapcsolás general.disable=Kikapcsolás general.remove=Remove general.openDocumentation=Open Documentation +general.numMore=%S more… general.operationInProgress=A Zotero dolgozik. general.operationInProgress.waitUntilFinished=Kérjük várjon, amíg a művelet befejeződik. @@ -80,7 +81,7 @@ app.firefox=Zotero for Firefox startupError=Hiba a Zotero indítása közben. startupError.databaseInUse=Your Zotero database is currently in use. Only one instance of Zotero using the same database may be opened simultaneously at this time. -startupError.closeStandalone=If Zotero Standalone is open, please close it and restart Firefox. +startupError.closeStandalone=If Zotero Standalone is open, please close it and restart %S. startupError.closeFirefox=If Firefox with the Zotero extension is open, please close it and restart Zotero Standalone. startupError.databaseCannotBeOpened=The Zotero database cannot be opened. startupError.checkPermissions=Győződjön meg róla, hogy a Zotero az adatkönyvtár valamennyi fájlját írni és olvasni tudja. @@ -112,6 +113,7 @@ pane.collections.library=Teljes könyvtár pane.collections.trash=Trash pane.collections.untitled=cím nélkül pane.collections.unfiled=Unfiled Items +pane.collections.duplicate=Duplicate Items pane.collections.menu.rename.collection=Gyűjtemény átnevezése... pane.collections.menu.edit.savedSearch=Mentett keresés szerkesztése @@ -170,6 +172,10 @@ pane.items.interview.manyParticipants=Interjú (készítette: %S et al.) pane.item.selected.zero=Nincs kiválasztva elem pane.item.selected.multiple=%S elem kiválasztva +pane.item.unselected.zero=No items in this view +pane.item.unselected.singular=%S item in this view +pane.item.unselected.plural=%S items in this view +pane.item.selectToMerge=Select items to merge pane.item.changeType.title=Elem típusának módosítása pane.item.changeType.text=Az elemtípus módosításának megerősítése?\n\nA következő mezők elvesznek. @@ -178,6 +184,8 @@ pane.item.defaultLastName=vezetéknév pane.item.defaultFullName=teljes név pane.item.switchFieldMode.one=Váltás egy mezőre pane.item.switchFieldMode.two=Váltás két mezőre +pane.item.creator.moveUp=Move Up +pane.item.creator.moveDown=Move Down pane.item.notes.untitled=Cím nélküli jegyzet pane.item.notes.delete.confirm=Jegyzet törlésének megerősítése? pane.item.notes.count.zero=%S jegyzet: diff --git a/chrome/locale/is-IS/zotero/zotero.dtd b/chrome/locale/is-IS/zotero/zotero.dtd @@ -68,6 +68,10 @@ <!ENTITY zotero.items.menu.restoreToLibrary "Restore to Library"> <!ENTITY zotero.items.menu.duplicateItem "Duplicate Selected Item"> +<!ENTITY zotero.items.menu.mergeItems "Merge Items…"> + +<!ENTITY zotero.duplicatesMerge.versionSelect "Choose the version of the item to use as the master item:"> +<!ENTITY zotero.duplicatesMerge.fieldSelect "Select fields to keep from other versions of the item:"> <!ENTITY zotero.toolbar.newItem.label "New Item"> <!ENTITY zotero.toolbar.moreItemTypes.label "More"> diff --git a/chrome/locale/is-IS/zotero/zotero.properties b/chrome/locale/is-IS/zotero/zotero.properties @@ -36,6 +36,7 @@ general.enable=Enable general.disable=Disable general.remove=Remove general.openDocumentation=Open Documentation +general.numMore=%S more… general.operationInProgress=A Zotero operation is currently in progress. general.operationInProgress.waitUntilFinished=Please wait until it has finished. @@ -80,7 +81,7 @@ app.firefox=Zotero for Firefox startupError=There was an error starting Zotero. startupError.databaseInUse=Your Zotero database is currently in use. Only one instance of Zotero using the same database may be opened simultaneously at this time. -startupError.closeStandalone=If Zotero Standalone is open, please close it and restart Firefox. +startupError.closeStandalone=If Zotero Standalone is open, please close it and restart %S. startupError.closeFirefox=If Firefox with the Zotero extension is open, please close it and restart Zotero Standalone. startupError.databaseCannotBeOpened=The Zotero database cannot be opened. startupError.checkPermissions=Make sure you have read and write permissions to all files in the Zotero data directory. @@ -112,6 +113,7 @@ pane.collections.library=Mitt safn pane.collections.trash=Trash pane.collections.untitled=Enginn titill pane.collections.unfiled=Unfiled Items +pane.collections.duplicate=Duplicate Items pane.collections.menu.rename.collection=Endurnefna safn pane.collections.menu.edit.savedSearch=Breyta vistaðri leit @@ -170,6 +172,10 @@ pane.items.interview.manyParticipants=Interview by %S et al. pane.item.selected.zero=Engar færslur valdar pane.item.selected.multiple=%S færslur valdar +pane.item.unselected.zero=No items in this view +pane.item.unselected.singular=%S item in this view +pane.item.unselected.plural=%S items in this view +pane.item.selectToMerge=Select items to merge pane.item.changeType.title=Change Item Type pane.item.changeType.text=Are you sure you want to change the item type?\n\nThe following fields will be lost: @@ -178,6 +184,8 @@ pane.item.defaultLastName=síðasta pane.item.defaultFullName=fullt nafn pane.item.switchFieldMode.one=Switch to single field pane.item.switchFieldMode.two=Switch to two fields +pane.item.creator.moveUp=Move Up +pane.item.creator.moveDown=Move Down pane.item.notes.untitled=Untitled Note pane.item.notes.delete.confirm=Are you sure you want to delete this note? pane.item.notes.count.zero=%S notes: diff --git a/chrome/locale/it-IT/zotero/zotero.dtd b/chrome/locale/it-IT/zotero/zotero.dtd @@ -68,6 +68,10 @@ <!ENTITY zotero.items.menu.restoreToLibrary "Ripristina nella biblioteca"> <!ENTITY zotero.items.menu.duplicateItem "Duplica elemento selezionato"> +<!ENTITY zotero.items.menu.mergeItems "Merge Items…"> + +<!ENTITY zotero.duplicatesMerge.versionSelect "Choose the version of the item to use as the master item:"> +<!ENTITY zotero.duplicatesMerge.fieldSelect "Select fields to keep from other versions of the item:"> <!ENTITY zotero.toolbar.newItem.label "Nuovo elemento"> <!ENTITY zotero.toolbar.moreItemTypes.label "Altro"> diff --git a/chrome/locale/it-IT/zotero/zotero.properties b/chrome/locale/it-IT/zotero/zotero.properties @@ -36,6 +36,7 @@ general.enable=Attiva general.disable=Disattiva general.remove=Rimuovi general.openDocumentation=Open Documentation +general.numMore=%S more… general.operationInProgress=A Zotero operation is currently in progress. general.operationInProgress.waitUntilFinished=Attendere sino al completamento @@ -112,6 +113,7 @@ pane.collections.library=Libreria personale pane.collections.trash=Cestino pane.collections.untitled=Senza titolo pane.collections.unfiled=Unfiled Items +pane.collections.duplicate=Duplicate Items pane.collections.menu.rename.collection=Rinomina collezione... pane.collections.menu.edit.savedSearch=Modifica ricerca salvata @@ -170,6 +172,10 @@ pane.items.interview.manyParticipants=Intervista di %S e altri pane.item.selected.zero=Nessun elemento selezionato pane.item.selected.multiple=%S elementi selezionati +pane.item.unselected.zero=No items in this view +pane.item.unselected.singular=%S item in this view +pane.item.unselected.plural=%S items in this view +pane.item.selectToMerge=Select items to merge pane.item.changeType.title=Modifica tipo di elemento pane.item.changeType.text=Modificare il tipo di elemento? I seguenti campi andranno persi: @@ -178,6 +184,8 @@ pane.item.defaultLastName=cognome pane.item.defaultFullName=nome completo pane.item.switchFieldMode.one=Passa a campo unico pane.item.switchFieldMode.two=Passa a campo doppio +pane.item.creator.moveUp=Move Up +pane.item.creator.moveDown=Move Down pane.item.notes.untitled=Nota senza titolo pane.item.notes.delete.confirm=Cancellare questa nota? pane.item.notes.count.zero=%S note diff --git a/chrome/locale/ja-JP/zotero/zotero.dtd b/chrome/locale/ja-JP/zotero/zotero.dtd @@ -68,6 +68,10 @@ <!ENTITY zotero.items.menu.restoreToLibrary "ライブラリへ復帰させる"> <!ENTITY zotero.items.menu.duplicateItem "選択されたアイテムを複製"> +<!ENTITY zotero.items.menu.mergeItems "Merge Items…"> + +<!ENTITY zotero.duplicatesMerge.versionSelect "Choose the version of the item to use as the master item:"> +<!ENTITY zotero.duplicatesMerge.fieldSelect "Select fields to keep from other versions of the item:"> <!ENTITY zotero.toolbar.newItem.label "新規アイテム"> <!ENTITY zotero.toolbar.moreItemTypes.label "その他"> diff --git a/chrome/locale/ja-JP/zotero/zotero.properties b/chrome/locale/ja-JP/zotero/zotero.properties @@ -36,6 +36,7 @@ general.enable=有効化 general.disable=無効化 general.remove=取り除く general.openDocumentation=ヘルプを開く +general.numMore=%S more… general.operationInProgress=既に Zotero 処理が進行中です。 general.operationInProgress.waitUntilFinished=完了するまでお待ちください。 @@ -112,6 +113,7 @@ pane.collections.library=マイ・ライブラリー pane.collections.trash=ゴミ箱 pane.collections.untitled=無題 pane.collections.unfiled=未整理のアイテム +pane.collections.duplicate=Duplicate Items pane.collections.menu.rename.collection=コレクション名の変更... pane.collections.menu.edit.savedSearch=保存済み検索条件を編集する @@ -170,6 +172,10 @@ pane.items.interview.manyParticipants=%S et al. によるインタビュー pane.item.selected.zero=アイテムが選択されていません pane.item.selected.multiple=%S 個のアイテムが選択されています +pane.item.unselected.zero=No items in this view +pane.item.unselected.singular=%S item in this view +pane.item.unselected.plural=%S items in this view +pane.item.selectToMerge=Select items to merge pane.item.changeType.title=アイテムの種類を変更 pane.item.changeType.text=アイテムの種類を変更してよろしいですか?\n\n以下のフィールドが失われます: @@ -178,6 +184,8 @@ pane.item.defaultLastName=姓 pane.item.defaultFullName=氏名 pane.item.switchFieldMode.one=単独のフィールドに変更 pane.item.switchFieldMode.two=二つのフィールドに変更 +pane.item.creator.moveUp=Move Up +pane.item.creator.moveDown=Move Down pane.item.notes.untitled=無題のメモ pane.item.notes.delete.confirm=このメモを削除してもよろしいですか? pane.item.notes.count.zero=メモ(%S): diff --git a/chrome/locale/km/zotero/zotero.dtd b/chrome/locale/km/zotero/zotero.dtd @@ -69,6 +69,10 @@ <!ENTITY zotero.items.menu.restoreToLibrary "ស្តារទៅកាន់បណ្ណាល័យវិញ"> <!ENTITY zotero.items.menu.duplicateItem "ជ្រើសរើសឯកសារត្រួត"> +<!ENTITY zotero.items.menu.mergeItems "Merge Items…"> + +<!ENTITY zotero.duplicatesMerge.versionSelect "Choose the version of the item to use as the master item:"> +<!ENTITY zotero.duplicatesMerge.fieldSelect "Select fields to keep from other versions of the item:"> <!ENTITY zotero.toolbar.newItem.label "ឯកសារថ្មី"> <!ENTITY zotero.toolbar.moreItemTypes.label "ជម្រើសប្រភេទឯកសារ"> diff --git a/chrome/locale/km/zotero/zotero.properties b/chrome/locale/km/zotero/zotero.properties @@ -36,6 +36,7 @@ general.enable=អាចដំណើរការ general.disable=មិនអាចដំណើរការ general.remove=លុបចោល general.openDocumentation=បើកឯកសារ +general.numMore=%S more… general.operationInProgress=ហ្ស៊ូតេរ៉ូកំពុងដំណើរការឥលូវនេះ។ general.operationInProgress.waitUntilFinished=សូមរង់ចាំរហូតដល់ដំណើរការបានបញ្ចប់។ @@ -112,6 +113,7 @@ pane.collections.library=ស្វ័យបណ្ណាល័យ pane.collections.trash=ធុងសំរាម pane.collections.untitled=ចំណងជើងកម្រងឯកសារ pane.collections.unfiled=ឯកសារមិនទាន់បានតម្កល់ទុក +pane.collections.duplicate=Duplicate Items pane.collections.menu.rename.collection=ប្តូរឈ្មោះកម្រងឯកសារ... pane.collections.menu.edit.savedSearch=កែតម្រូវការស្រាវជ្រាវដែលបានរក្សាទុក @@ -170,6 +172,10 @@ pane.items.interview.manyParticipants=សម្ភាសន៍ដោយ %S ។ pane.item.selected.zero=សូមធ្វើការជ្រើសរើសឯកសារណាមួយដែលអ្នកចង់បាន pane.item.selected.multiple=%S ឯកសារត្រូវបានជ្រើសរើស +pane.item.unselected.zero=No items in this view +pane.item.unselected.singular=%S item in this view +pane.item.unselected.plural=%S items in this view +pane.item.selectToMerge=Select items to merge pane.item.changeType.title=ផ្លាស់ប្តូរប្រភទឯកសារ pane.item.changeType.text=តើអ្នកចង់ផ្លាស់ប្តូរប្រភេទឯកសារ? វិស័យទាំងអស់នេះនឹងត្រូវបាត់បង់ៈ @@ -178,6 +184,8 @@ pane.item.defaultLastName=ត្រកូល pane.item.defaultFullName=អត្តនាម និង​ ត្រកូល pane.item.switchFieldMode.one=ប្តូរទៅវិស័យមួយ pane.item.switchFieldMode.two=ប្តូរទៅវិស័យពីរ +pane.item.creator.moveUp=Move Up +pane.item.creator.moveDown=Move Down pane.item.notes.untitled=កំណត់ចំណាំគ្មានចំណងជើង pane.item.notes.delete.confirm=តើអ្នកចង់លុបកំណត់ចំណាំនេះ? pane.item.notes.count.zero=%S កំណត់ចំណាំ: diff --git a/chrome/locale/ko-KR/zotero/zotero.dtd b/chrome/locale/ko-KR/zotero/zotero.dtd @@ -68,6 +68,10 @@ <!ENTITY zotero.items.menu.restoreToLibrary "Restore to Library"> <!ENTITY zotero.items.menu.duplicateItem "선택된 항목 복제"> +<!ENTITY zotero.items.menu.mergeItems "Merge Items…"> + +<!ENTITY zotero.duplicatesMerge.versionSelect "Choose the version of the item to use as the master item:"> +<!ENTITY zotero.duplicatesMerge.fieldSelect "Select fields to keep from other versions of the item:"> <!ENTITY zotero.toolbar.newItem.label "새 항목"> <!ENTITY zotero.toolbar.moreItemTypes.label "더 보기"> diff --git a/chrome/locale/ko-KR/zotero/zotero.properties b/chrome/locale/ko-KR/zotero/zotero.properties @@ -36,6 +36,7 @@ general.enable=사용 general.disable=사용안함 general.remove=Remove general.openDocumentation=Open Documentation +general.numMore=%S more… general.operationInProgress=Zotero 작업이 현재 진행중입니다. general.operationInProgress.waitUntilFinished=끝날때까지 기다려주세요. @@ -80,7 +81,7 @@ app.firefox=Zotero for Firefox startupError=Zotero 시작중 오류가 존재 합니다. startupError.databaseInUse=Your Zotero database is currently in use. Only one instance of Zotero using the same database may be opened simultaneously at this time. -startupError.closeStandalone=If Zotero Standalone is open, please close it and restart Firefox. +startupError.closeStandalone=If Zotero Standalone is open, please close it and restart %S. startupError.closeFirefox=If Firefox with the Zotero extension is open, please close it and restart Zotero Standalone. startupError.databaseCannotBeOpened=Zotero 데이터베이스를 열 수 없습니다. startupError.checkPermissions=Zotero 자료 디렉토리 내 모든 파일을 읽고 쓸 수 있는 권한을 가지고 있는지 확실하게 확인하세요. @@ -112,6 +113,7 @@ pane.collections.library=내 라이브러리 pane.collections.trash=휴지통 pane.collections.untitled=제목없음 pane.collections.unfiled=Unfiled Items +pane.collections.duplicate=Duplicate Items pane.collections.menu.rename.collection=수집품 이름변경... pane.collections.menu.edit.savedSearch=저장된 검색 목록 편집 @@ -170,6 +172,10 @@ pane.items.interview.manyParticipants=회견자: %S 외. pane.item.selected.zero=선택된 항목이 없습니다 pane.item.selected.multiple=%s개의 아이템이 선택되었습니다 +pane.item.unselected.zero=No items in this view +pane.item.unselected.singular=%S item in this view +pane.item.unselected.plural=%S items in this view +pane.item.selectToMerge=Select items to merge pane.item.changeType.title=항목 형식 변경 pane.item.changeType.text=정말로 항목 형식을 변경하길 원하십니까?\n\n다음 필드들을 잃을 수 도 있습니다. @@ -178,6 +184,8 @@ pane.item.defaultLastName=성 pane.item.defaultFullName=전체 이름 pane.item.switchFieldMode.one=한 칸으로 전환 pane.item.switchFieldMode.two=두 칸으로 전환 +pane.item.creator.moveUp=Move Up +pane.item.creator.moveDown=Move Down pane.item.notes.untitled=무제 노트 pane.item.notes.delete.confirm=이 노트를 삭제하길 원하는게 맞습니까? pane.item.notes.count.zero=%S 노트: diff --git a/chrome/locale/mn-MN/zotero/zotero.dtd b/chrome/locale/mn-MN/zotero/zotero.dtd @@ -68,6 +68,10 @@ <!ENTITY zotero.items.menu.restoreToLibrary "Restore to Library"> <!ENTITY zotero.items.menu.duplicateItem "Duplicate Selected Item"> +<!ENTITY zotero.items.menu.mergeItems "Merge Items…"> + +<!ENTITY zotero.duplicatesMerge.versionSelect "Choose the version of the item to use as the master item:"> +<!ENTITY zotero.duplicatesMerge.fieldSelect "Select fields to keep from other versions of the item:"> <!ENTITY zotero.toolbar.newItem.label "Шинэ бүтээл"> <!ENTITY zotero.toolbar.moreItemTypes.label "Бусад"> diff --git a/chrome/locale/mn-MN/zotero/zotero.properties b/chrome/locale/mn-MN/zotero/zotero.properties @@ -36,6 +36,7 @@ general.enable=Enable general.disable=Disable general.remove=Remove general.openDocumentation=Open Documentation +general.numMore=%S more… general.operationInProgress=A Zotero operation is currently in progress. general.operationInProgress.waitUntilFinished=Please wait until it has finished. @@ -80,7 +81,7 @@ app.firefox=Zotero for Firefox startupError=There was an error starting Zotero. startupError.databaseInUse=Your Zotero database is currently in use. Only one instance of Zotero using the same database may be opened simultaneously at this time. -startupError.closeStandalone=If Zotero Standalone is open, please close it and restart Firefox. +startupError.closeStandalone=If Zotero Standalone is open, please close it and restart %S. startupError.closeFirefox=If Firefox with the Zotero extension is open, please close it and restart Zotero Standalone. startupError.databaseCannotBeOpened=The Zotero database cannot be opened. startupError.checkPermissions=Make sure you have read and write permissions to all files in the Zotero data directory. @@ -112,6 +113,7 @@ pane.collections.library=Миний номын сан pane.collections.trash=Trash pane.collections.untitled=Гарчиггүй pane.collections.unfiled=Unfiled Items +pane.collections.duplicate=Duplicate Items pane.collections.menu.rename.collection=Rename Collection... pane.collections.menu.edit.savedSearch=Edit Saved Search @@ -170,6 +172,10 @@ pane.items.interview.manyParticipants=Interview by %S et al. pane.item.selected.zero=No items selected pane.item.selected.multiple=%S items selected +pane.item.unselected.zero=No items in this view +pane.item.unselected.singular=%S item in this view +pane.item.unselected.plural=%S items in this view +pane.item.selectToMerge=Select items to merge pane.item.changeType.title=Change Item Type pane.item.changeType.text=Are you sure you want to change the item type?\n\nThe following fields will be lost: @@ -178,6 +184,8 @@ pane.item.defaultLastName=Сүүлийн pane.item.defaultFullName=Бүтэн нэр pane.item.switchFieldMode.one=Switch to single field pane.item.switchFieldMode.two=Switch to two fields +pane.item.creator.moveUp=Move Up +pane.item.creator.moveDown=Move Down pane.item.notes.untitled=Гарчиггүй тэмдэглэл pane.item.notes.delete.confirm=Are you sure you want to delete this note? pane.item.notes.count.zero=%S тэмдэглэлүүд: diff --git a/chrome/locale/nb-NO/zotero/zotero.dtd b/chrome/locale/nb-NO/zotero/zotero.dtd @@ -68,6 +68,10 @@ <!ENTITY zotero.items.menu.restoreToLibrary "Restore to Library"> <!ENTITY zotero.items.menu.duplicateItem "Dupliser det valgte elementet"> +<!ENTITY zotero.items.menu.mergeItems "Merge Items…"> + +<!ENTITY zotero.duplicatesMerge.versionSelect "Choose the version of the item to use as the master item:"> +<!ENTITY zotero.duplicatesMerge.fieldSelect "Select fields to keep from other versions of the item:"> <!ENTITY zotero.toolbar.newItem.label "Nytt element"> <!ENTITY zotero.toolbar.moreItemTypes.label "Mer"> diff --git a/chrome/locale/nb-NO/zotero/zotero.properties b/chrome/locale/nb-NO/zotero/zotero.properties @@ -36,6 +36,7 @@ general.enable=Enable general.disable=Disable general.remove=Remove general.openDocumentation=Open Documentation +general.numMore=%S more… general.operationInProgress=A Zotero operation is currently in progress. general.operationInProgress.waitUntilFinished=Please wait until it has finished. @@ -80,7 +81,7 @@ app.firefox=Zotero for Firefox startupError=Det oppstod en feil ved oppstarten av Zotero. startupError.databaseInUse=Your Zotero database is currently in use. Only one instance of Zotero using the same database may be opened simultaneously at this time. -startupError.closeStandalone=If Zotero Standalone is open, please close it and restart Firefox. +startupError.closeStandalone=If Zotero Standalone is open, please close it and restart %S. startupError.closeFirefox=If Firefox with the Zotero extension is open, please close it and restart Zotero Standalone. startupError.databaseCannotBeOpened=The Zotero database cannot be opened. startupError.checkPermissions=Make sure you have read and write permissions to all files in the Zotero data directory. @@ -112,6 +113,7 @@ pane.collections.library=Mitt bibliotek pane.collections.trash=Trash pane.collections.untitled=Uten tittel pane.collections.unfiled=Unfiled Items +pane.collections.duplicate=Duplicate Items pane.collections.menu.rename.collection=Gi samlingen nytt navn... pane.collections.menu.edit.savedSearch=Rediger lagret søk @@ -170,6 +172,10 @@ pane.items.interview.manyParticipants=Intervju av %S mfl. pane.item.selected.zero=Ingen elementer er valgt pane.item.selected.multiple=%S elementer er valgt +pane.item.unselected.zero=No items in this view +pane.item.unselected.singular=%S item in this view +pane.item.unselected.plural=%S items in this view +pane.item.selectToMerge=Select items to merge pane.item.changeType.title=Endre elementtype pane.item.changeType.text=Vil du virkelig forandre elementtypen?\n\nDe følgende feltene vil bli slettet: @@ -178,6 +184,8 @@ pane.item.defaultLastName=sist pane.item.defaultFullName=fullt navn pane.item.switchFieldMode.one=Bytt til ett felt pane.item.switchFieldMode.two=Bytt til to felt +pane.item.creator.moveUp=Move Up +pane.item.creator.moveDown=Move Down pane.item.notes.untitled=Notat uten tittel pane.item.notes.delete.confirm=Er du sikker på at du vil slette dette notatet? pane.item.notes.count.zero=%S notater: diff --git a/chrome/locale/nl-NL/zotero/zotero.dtd b/chrome/locale/nl-NL/zotero/zotero.dtd @@ -68,6 +68,10 @@ <!ENTITY zotero.items.menu.restoreToLibrary "Terugzetten in bibliotheek"> <!ENTITY zotero.items.menu.duplicateItem "Kopie maken van geselecteerd object"> +<!ENTITY zotero.items.menu.mergeItems "Merge Items…"> + +<!ENTITY zotero.duplicatesMerge.versionSelect "Choose the version of the item to use as the master item:"> +<!ENTITY zotero.duplicatesMerge.fieldSelect "Select fields to keep from other versions of the item:"> <!ENTITY zotero.toolbar.newItem.label "Nieuw object"> <!ENTITY zotero.toolbar.moreItemTypes.label "Meer"> diff --git a/chrome/locale/nl-NL/zotero/zotero.properties b/chrome/locale/nl-NL/zotero/zotero.properties @@ -36,6 +36,7 @@ general.enable=Aanzetten general.disable=Uitzetten general.remove=Verwijderen general.openDocumentation=Documentatie openen +general.numMore=%S more… general.operationInProgress=Zotero is bezig. general.operationInProgress.waitUntilFinished=Wacht tot Zotero klaar is. @@ -112,6 +113,7 @@ pane.collections.library=Mijn Bibliotheek pane.collections.trash=Prullenbak pane.collections.untitled=Zonder Titel pane.collections.unfiled=Ongesorteerde objecten +pane.collections.duplicate=Duplicate Items pane.collections.menu.rename.collection=Naam verzameling wijzigen… pane.collections.menu.edit.savedSearch=Bewaarde zoekopdracht bewerken @@ -170,6 +172,10 @@ pane.items.interview.manyParticipants=Interview door %S en anderen pane.item.selected.zero=Geen objecten geselecteerd pane.item.selected.multiple=%S objecten geselecteerd +pane.item.unselected.zero=No items in this view +pane.item.unselected.singular=%S item in this view +pane.item.unselected.plural=%S items in this view +pane.item.selectToMerge=Select items to merge pane.item.changeType.title=Object-type veranderen pane.item.changeType.text=Wilt u het object-type veranderen?\n\nDe volgende velden zullen verloren gaan: @@ -178,6 +184,8 @@ pane.item.defaultLastName=achternaam pane.item.defaultFullName=volledige naam pane.item.switchFieldMode.one=Omschakelen naar één veld pane.item.switchFieldMode.two=Omschakelen naar twee velden +pane.item.creator.moveUp=Move Up +pane.item.creator.moveDown=Move Down pane.item.notes.untitled=Aantekening zonder titel pane.item.notes.delete.confirm=Wilt u deze aantekening verwijderen? pane.item.notes.count.zero=%S aantekeningen: diff --git a/chrome/locale/nn-NO/zotero/zotero.dtd b/chrome/locale/nn-NO/zotero/zotero.dtd @@ -68,6 +68,10 @@ <!ENTITY zotero.items.menu.restoreToLibrary "Gjenopprett til bibliotek"> <!ENTITY zotero.items.menu.duplicateItem "Dupliser det valde elementet"> +<!ENTITY zotero.items.menu.mergeItems "Merge Items…"> + +<!ENTITY zotero.duplicatesMerge.versionSelect "Choose the version of the item to use as the master item:"> +<!ENTITY zotero.duplicatesMerge.fieldSelect "Select fields to keep from other versions of the item:"> <!ENTITY zotero.toolbar.newItem.label "Nytt element"> <!ENTITY zotero.toolbar.moreItemTypes.label "Meir"> diff --git a/chrome/locale/nn-NO/zotero/zotero.properties b/chrome/locale/nn-NO/zotero/zotero.properties @@ -36,6 +36,7 @@ general.enable=Slå på general.disable=Slå av general.remove=Fjern general.openDocumentation=Open Documentation +general.numMore=%S more… general.operationInProgress=Ei Zotero-handling foregår general.operationInProgress.waitUntilFinished=Please wait until it vert hatt finished. @@ -112,6 +113,7 @@ pane.collections.library=Biblioteket mitt pane.collections.trash=Trash pane.collections.untitled=Utan tittel pane.collections.unfiled=Unfiled Items +pane.collections.duplicate=Duplicate Items pane.collections.menu.rename.collection=Gje samlinga nytt namn … pane.collections.menu.edit.savedSearch=Rediger lagra søk @@ -170,6 +172,10 @@ pane.items.interview.manyParticipants=Intervju av %S mfl. pane.item.selected.zero=Ingen element er valde pane.item.selected.multiple=%S element er valde +pane.item.unselected.zero=No items in this view +pane.item.unselected.singular=%S item in this view +pane.item.unselected.plural=%S items in this view +pane.item.selectToMerge=Select items to merge pane.item.changeType.title=Endre elementtype pane.item.changeType.text=Vil du verkeleg forandra elementtypen?\n\nDei følgjande vil bli sletta: @@ -178,6 +184,8 @@ pane.item.defaultLastName=sist pane.item.defaultFullName=fullt namn pane.item.switchFieldMode.one=Byt til eitt felt pane.item.switchFieldMode.two=Byt til to felt +pane.item.creator.moveUp=Move Up +pane.item.creator.moveDown=Move Down pane.item.notes.untitled=Notat utan tittel pane.item.notes.delete.confirm=Er du sikker på at du vil sletta dette notatet? pane.item.notes.count.zero=%S notat: diff --git a/chrome/locale/pl-PL/zotero/zotero.dtd b/chrome/locale/pl-PL/zotero/zotero.dtd @@ -68,6 +68,10 @@ <!ENTITY zotero.items.menu.restoreToLibrary "Przywróć do biblioteki"> <!ENTITY zotero.items.menu.duplicateItem "Duplikuj zaznaczony element"> +<!ENTITY zotero.items.menu.mergeItems "Merge Items…"> + +<!ENTITY zotero.duplicatesMerge.versionSelect "Choose the version of the item to use as the master item:"> +<!ENTITY zotero.duplicatesMerge.fieldSelect "Select fields to keep from other versions of the item:"> <!ENTITY zotero.toolbar.newItem.label "Nowy element"> <!ENTITY zotero.toolbar.moreItemTypes.label "Więcej"> diff --git a/chrome/locale/pl-PL/zotero/zotero.properties b/chrome/locale/pl-PL/zotero/zotero.properties @@ -36,6 +36,7 @@ general.enable=Włącz general.disable=Wyłącz general.remove=Usuń general.openDocumentation=Open Documentation +general.numMore=%S more… general.operationInProgress=Operacja Zotero jest aktualnie w trakcie. general.operationInProgress.waitUntilFinished=Proszę poczekać na zakończenie. @@ -112,6 +113,7 @@ pane.collections.library=Moja biblioteka pane.collections.trash=Kosz pane.collections.untitled=Bez nazwy pane.collections.unfiled=Niepowiązane elementy +pane.collections.duplicate=Duplicate Items pane.collections.menu.rename.collection=Zmień nazwę kolekcji pane.collections.menu.edit.savedSearch=Edytuj wynik wyszukiwania @@ -170,6 +172,10 @@ pane.items.interview.manyParticipants=Prowadzący wywiad %S et al. pane.item.selected.zero=Nie wybrano elementu pane.item.selected.multiple=Wybrano %S elementy(ów) +pane.item.unselected.zero=No items in this view +pane.item.unselected.singular=%S item in this view +pane.item.unselected.plural=%S items in this view +pane.item.selectToMerge=Select items to merge pane.item.changeType.title=Zmień typ elementu pane.item.changeType.text=Czy na pewno chcesz zmienić typ elementu?\n\nZostaną utracone następujące pola: @@ -178,6 +184,8 @@ pane.item.defaultLastName=Nazwisko pane.item.defaultFullName=Imię i nazwisko pane.item.switchFieldMode.one=Przełącz na pojedyncze pole pane.item.switchFieldMode.two=Przełącz na dwa pola +pane.item.creator.moveUp=Move Up +pane.item.creator.moveDown=Move Down pane.item.notes.untitled=Notatka bez tytułu pane.item.notes.delete.confirm=Czy na pewno chcesz usunąć tę notatkę? pane.item.notes.count.zero=Brak notatek diff --git a/chrome/locale/pt-BR/zotero/zotero.dtd b/chrome/locale/pt-BR/zotero/zotero.dtd @@ -68,6 +68,10 @@ <!ENTITY zotero.items.menu.restoreToLibrary "Restaurar para biblioteca"> <!ENTITY zotero.items.menu.duplicateItem "Duplicar item selecionado"> +<!ENTITY zotero.items.menu.mergeItems "Merge Items…"> + +<!ENTITY zotero.duplicatesMerge.versionSelect "Choose the version of the item to use as the master item:"> +<!ENTITY zotero.duplicatesMerge.fieldSelect "Select fields to keep from other versions of the item:"> <!ENTITY zotero.toolbar.newItem.label "Confirmar"> <!ENTITY zotero.toolbar.moreItemTypes.label "Mais"> diff --git a/chrome/locale/pt-BR/zotero/zotero.properties b/chrome/locale/pt-BR/zotero/zotero.properties @@ -36,6 +36,7 @@ general.enable=Habilitar general.disable=Desabilitar general.remove=Remover general.openDocumentation=Abrir documentação +general.numMore=%S more… general.operationInProgress=Uma operação Zotero está atualmente em progresso. general.operationInProgress.waitUntilFinished=Por favor, aguarde até que ela termine. @@ -112,6 +113,7 @@ pane.collections.library=Minha biblioteca pane.collections.trash=Lixeira pane.collections.untitled=Sem título pane.collections.unfiled=Documentos sem coleção +pane.collections.duplicate=Duplicate Items pane.collections.menu.rename.collection=Renomear coleção... pane.collections.menu.edit.savedSearch=Editar pesquisa salva @@ -170,6 +172,10 @@ pane.items.interview.manyParticipants=Entrevista de %S et al. pane.item.selected.zero=Nenhum item selecionado pane.item.selected.multiple=%S itens selecionados +pane.item.unselected.zero=No items in this view +pane.item.unselected.singular=%S item in this view +pane.item.unselected.plural=%S items in this view +pane.item.selectToMerge=Select items to merge pane.item.changeType.title=Mudar tipo do item pane.item.changeType.text=Tem certeza de que deseja mudar o tipo do item?\n\nOs campos abaixo serão perdidos: @@ -178,6 +184,8 @@ pane.item.defaultLastName=último pane.item.defaultFullName=nome completo pane.item.switchFieldMode.one=Mudar para campo único pane.item.switchFieldMode.two=Mudar para dois campos +pane.item.creator.moveUp=Move Up +pane.item.creator.moveDown=Move Down pane.item.notes.untitled=Nota sem título pane.item.notes.delete.confirm=Tem certeza de que deseja excluir esta nota? pane.item.notes.count.zero=%S notas: diff --git a/chrome/locale/pt-PT/zotero/zotero.dtd b/chrome/locale/pt-PT/zotero/zotero.dtd @@ -68,6 +68,10 @@ <!ENTITY zotero.items.menu.restoreToLibrary "Restaurar para a Biblioteca"> <!ENTITY zotero.items.menu.duplicateItem "Duplicar o Item Seleccionado"> +<!ENTITY zotero.items.menu.mergeItems "Merge Items…"> + +<!ENTITY zotero.duplicatesMerge.versionSelect "Choose the version of the item to use as the master item:"> +<!ENTITY zotero.duplicatesMerge.fieldSelect "Select fields to keep from other versions of the item:"> <!ENTITY zotero.toolbar.newItem.label "Novo Item"> <!ENTITY zotero.toolbar.moreItemTypes.label "Mais"> diff --git a/chrome/locale/pt-PT/zotero/zotero.properties b/chrome/locale/pt-PT/zotero/zotero.properties @@ -36,6 +36,7 @@ general.enable=Activar general.disable=Desactivar general.remove=Remover general.openDocumentation=Abrir Documentação +general.numMore=%S more… general.operationInProgress=Está em curso uma operação do Zotero. general.operationInProgress.waitUntilFinished=Por favor espere que termine. @@ -112,6 +113,7 @@ pane.collections.library=A minha Biblioteca pane.collections.trash=Lixo pane.collections.untitled=Sem título pane.collections.unfiled=Se estiver aberto o Firefox com a extensão Zotero, por favor feche-o e reinicie o Zotero Autónomo. +pane.collections.duplicate=Duplicate Items pane.collections.menu.rename.collection=Alterar Nome da Colecção... pane.collections.menu.edit.savedSearch=Editar Procura Guardada @@ -170,6 +172,10 @@ pane.items.interview.manyParticipants=Entrevista por %S et al. pane.item.selected.zero=Nenhum item seleccionado pane.item.selected.multiple=%S itens seleccionados +pane.item.unselected.zero=No items in this view +pane.item.unselected.singular=%S item in this view +pane.item.unselected.plural=%S items in this view +pane.item.selectToMerge=Select items to merge pane.item.changeType.title=Alterar Tipo de Item pane.item.changeType.text=Quer mesmo alterar o tipo de item?\n\nPerder-se-á os seguintes campos: @@ -178,6 +184,8 @@ pane.item.defaultLastName=último pane.item.defaultFullName=nome completo pane.item.switchFieldMode.one=Trocar para um só campo pane.item.switchFieldMode.two=Trocar para dois campos +pane.item.creator.moveUp=Move Up +pane.item.creator.moveDown=Move Down pane.item.notes.untitled=Nota Sem Título pane.item.notes.delete.confirm=Quer mesmo remover esta nota? pane.item.notes.count.zero=%S notas: diff --git a/chrome/locale/ro-RO/zotero/zotero.dtd b/chrome/locale/ro-RO/zotero/zotero.dtd @@ -68,6 +68,10 @@ <!ENTITY zotero.items.menu.restoreToLibrary "Restore to Library"> <!ENTITY zotero.items.menu.duplicateItem "Fă un duplicat înregistrării selectate"> +<!ENTITY zotero.items.menu.mergeItems "Merge Items…"> + +<!ENTITY zotero.duplicatesMerge.versionSelect "Choose the version of the item to use as the master item:"> +<!ENTITY zotero.duplicatesMerge.fieldSelect "Select fields to keep from other versions of the item:"> <!ENTITY zotero.toolbar.newItem.label "Înregistrare nouă"> <!ENTITY zotero.toolbar.moreItemTypes.label "Mai mult"> diff --git a/chrome/locale/ro-RO/zotero/zotero.properties b/chrome/locale/ro-RO/zotero/zotero.properties @@ -36,6 +36,7 @@ general.enable=Activare general.disable=Dezactivare general.remove=Șterge general.openDocumentation=Open Documentation +general.numMore=%S more… general.operationInProgress=O operațiune Zotero este în momentul de față în desfășurare. general.operationInProgress.waitUntilFinished=Te rog să aștepți până se încheie. @@ -112,6 +113,7 @@ pane.collections.library=Biblioteca mea pane.collections.trash=Coș de gunoi pane.collections.untitled=Fără titlu pane.collections.unfiled=Înregistrări neîndosariate +pane.collections.duplicate=Duplicate Items pane.collections.menu.rename.collection=Redenumește colecția... pane.collections.menu.edit.savedSearch=Editează căutarea salvată @@ -170,6 +172,10 @@ pane.items.interview.manyParticipants=Interviu de %S și alții. pane.item.selected.zero=Nicio înregistrare selectată pane.item.selected.multiple=%S înregistrări selectate +pane.item.unselected.zero=No items in this view +pane.item.unselected.singular=%S item in this view +pane.item.unselected.plural=%S items in this view +pane.item.selectToMerge=Select items to merge pane.item.changeType.title=Schimbă tipul înregistrării pane.item.changeType.text=Ești sigur că vrei să schimbi tipul înregistrării?\n\nUrmătoarele câmpuri vor fi pierdute: @@ -178,6 +184,8 @@ pane.item.defaultLastName=nume pane.item.defaultFullName=nume complet pane.item.switchFieldMode.one=Comută la un singur câmp pane.item.switchFieldMode.two=Comută la două câmpuri +pane.item.creator.moveUp=Move Up +pane.item.creator.moveDown=Move Down pane.item.notes.untitled=Notă fără titlu pane.item.notes.delete.confirm=Sigur vrei să ștergi această notă? pane.item.notes.count.zero=%S note: diff --git a/chrome/locale/ru-RU/zotero/zotero.dtd b/chrome/locale/ru-RU/zotero/zotero.dtd @@ -68,6 +68,10 @@ <!ENTITY zotero.items.menu.restoreToLibrary "Восстановить в библиотеке"> <!ENTITY zotero.items.menu.duplicateItem "Сделать дубликат выбранного документа"> +<!ENTITY zotero.items.menu.mergeItems "Merge Items…"> + +<!ENTITY zotero.duplicatesMerge.versionSelect "Choose the version of the item to use as the master item:"> +<!ENTITY zotero.duplicatesMerge.fieldSelect "Select fields to keep from other versions of the item:"> <!ENTITY zotero.toolbar.newItem.label "Новый документ"> <!ENTITY zotero.toolbar.moreItemTypes.label "Далее"> diff --git a/chrome/locale/ru-RU/zotero/zotero.properties b/chrome/locale/ru-RU/zotero/zotero.properties @@ -36,6 +36,7 @@ general.enable=Включить general.disable=Выключить general.remove=Убрать general.openDocumentation=Open Documentation +general.numMore=%S more… general.operationInProgress=В настоящий момент Zotero выполняет действие. general.operationInProgress.waitUntilFinished=Пожалуйста, подождите, пока оно закончится. @@ -112,6 +113,7 @@ pane.collections.library=Моя библиотека pane.collections.trash=Корзина pane.collections.untitled=Неназванные pane.collections.unfiled=Неподшитые +pane.collections.duplicate=Duplicate Items pane.collections.menu.rename.collection=Переименовать подборку… pane.collections.menu.edit.savedSearch=Редактировать сохраненный поиск @@ -170,6 +172,10 @@ pane.items.interview.manyParticipants=Интервью %S и др. pane.item.selected.zero=Нет выбранных документов pane.item.selected.multiple=Выбрано %S документа(-ов). +pane.item.unselected.zero=No items in this view +pane.item.unselected.singular=%S item in this view +pane.item.unselected.plural=%S items in this view +pane.item.selectToMerge=Select items to merge pane.item.changeType.title=Изменить тип документа pane.item.changeType.text=Вы уверены, что хотите изменить тип документа?\n\nСледующие поля будут утрачены: @@ -178,6 +184,8 @@ pane.item.defaultLastName=фамилия pane.item.defaultFullName=полное имя pane.item.switchFieldMode.one=Переключиться на одно поле pane.item.switchFieldMode.two=Переключиться на два поля +pane.item.creator.moveUp=Move Up +pane.item.creator.moveDown=Move Down pane.item.notes.untitled=Заметка без названия pane.item.notes.delete.confirm=Вы уверены, что хотите удалить эту заметку? pane.item.notes.count.zero=%S заметок: diff --git a/chrome/locale/sk-SK/zotero/zotero.dtd b/chrome/locale/sk-SK/zotero/zotero.dtd @@ -68,6 +68,10 @@ <!ENTITY zotero.items.menu.restoreToLibrary "Vrátiť do knižnice"> <!ENTITY zotero.items.menu.duplicateItem "Duplikovať vybranú položku"> +<!ENTITY zotero.items.menu.mergeItems "Merge Items…"> + +<!ENTITY zotero.duplicatesMerge.versionSelect "Choose the version of the item to use as the master item:"> +<!ENTITY zotero.duplicatesMerge.fieldSelect "Select fields to keep from other versions of the item:"> <!ENTITY zotero.toolbar.newItem.label "Nová položka"> <!ENTITY zotero.toolbar.moreItemTypes.label "Viac"> diff --git a/chrome/locale/sk-SK/zotero/zotero.properties b/chrome/locale/sk-SK/zotero/zotero.properties @@ -36,6 +36,7 @@ general.enable=Povoliť general.disable=Zakázať general.remove=Odstrániť general.openDocumentation=Otvoriť dokumentáciu +general.numMore=%S more… general.operationInProgress=Zotero práve vykonáva operáciu. general.operationInProgress.waitUntilFinished=Prosím počkajte, kým sa neukončí. @@ -112,6 +113,7 @@ pane.collections.library=Moja knižnica pane.collections.trash=Kôš pane.collections.untitled=Bez názvu pane.collections.unfiled=Nezaradené položky +pane.collections.duplicate=Duplicate Items pane.collections.menu.rename.collection=Premenovať kolekciu... pane.collections.menu.edit.savedSearch=Upraviť uložené vyhľadávanie @@ -170,6 +172,10 @@ pane.items.interview.manyParticipants=Rozhovor - %S et al. pane.item.selected.zero=Nie sú vybrané žiadne položky pane.item.selected.multiple=%S vybraných položiek +pane.item.unselected.zero=No items in this view +pane.item.unselected.singular=%S item in this view +pane.item.unselected.plural=%S items in this view +pane.item.selectToMerge=Select items to merge pane.item.changeType.title=Zmeniť typ položky pane.item.changeType.text=Naozaj chcete zmeniť typ položky?\n\nNasledujúce polia sa stratia: @@ -178,6 +184,8 @@ pane.item.defaultLastName=priezvisko pane.item.defaultFullName=celé meno pane.item.switchFieldMode.one=Spoločné pole pre meno pane.item.switchFieldMode.two=Samostatné polia pre meno +pane.item.creator.moveUp=Move Up +pane.item.creator.moveDown=Move Down pane.item.notes.untitled=Nepomenovaná poznámka pane.item.notes.delete.confirm=Naozaj chcete vymazať túto poznámku? pane.item.notes.count.zero=Žiadne poznámky: diff --git a/chrome/locale/sl-SI/zotero/zotero.dtd b/chrome/locale/sl-SI/zotero/zotero.dtd @@ -68,6 +68,10 @@ <!ENTITY zotero.items.menu.restoreToLibrary "Restore to Library"> <!ENTITY zotero.items.menu.duplicateItem "Podvoji izbrani vnos"> +<!ENTITY zotero.items.menu.mergeItems "Merge Items…"> + +<!ENTITY zotero.duplicatesMerge.versionSelect "Choose the version of the item to use as the master item:"> +<!ENTITY zotero.duplicatesMerge.fieldSelect "Select fields to keep from other versions of the item:"> <!ENTITY zotero.toolbar.newItem.label "Nov vnos"> <!ENTITY zotero.toolbar.moreItemTypes.label "Dodatno"> diff --git a/chrome/locale/sl-SI/zotero/zotero.properties b/chrome/locale/sl-SI/zotero/zotero.properties @@ -36,6 +36,7 @@ general.enable=Omogoči general.disable=Onemogoči general.remove=Remove general.openDocumentation=Open Documentation +general.numMore=%S more… general.operationInProgress=Trenutno je v teku operacija Zotero. general.operationInProgress.waitUntilFinished=Počakajte, da se dokonča. @@ -80,7 +81,7 @@ app.firefox=Zotero for Firefox startupError=Pri zagonu Zotera je prišlo do napake. startupError.databaseInUse=Your Zotero database is currently in use. Only one instance of Zotero using the same database may be opened simultaneously at this time. -startupError.closeStandalone=If Zotero Standalone is open, please close it and restart Firefox. +startupError.closeStandalone=If Zotero Standalone is open, please close it and restart %S. startupError.closeFirefox=If Firefox with the Zotero extension is open, please close it and restart Zotero Standalone. startupError.databaseCannotBeOpened=Zbirke podatkov Zotero ni mogoče odpreti. startupError.checkPermissions=Preverite, da imate pravice branja in pisanja za vse datoteke v podatkovni mapi Zotera. @@ -112,6 +113,7 @@ pane.collections.library=Moja knjižnica pane.collections.trash=Trash pane.collections.untitled=Neimenovano pane.collections.unfiled=Unfiled Items +pane.collections.duplicate=Duplicate Items pane.collections.menu.rename.collection=Preimenuj zbirko ... pane.collections.menu.edit.savedSearch=Uredi shranjeno iskanje @@ -170,6 +172,10 @@ pane.items.interview.manyParticipants=Intervju opravili %S idr. pane.item.selected.zero=Noben vnos ni izbran pane.item.selected.multiple=%S izbranih vnosov +pane.item.unselected.zero=No items in this view +pane.item.unselected.singular=%S item in this view +pane.item.unselected.plural=%S items in this view +pane.item.selectToMerge=Select items to merge pane.item.changeType.title=Spremeni vrsto vnosa pane.item.changeType.text=Ste prepričani, da želite spremeniti vrsto vnosa?\n\nIzgubljena bodo naslednja polja: @@ -178,6 +184,8 @@ pane.item.defaultLastName=priimek pane.item.defaultFullName=polno ime pane.item.switchFieldMode.one=Preklopi na enojno polje pane.item.switchFieldMode.two=Preklopi na obe polji +pane.item.creator.moveUp=Move Up +pane.item.creator.moveDown=Move Down pane.item.notes.untitled=Neimenovana opomba pane.item.notes.delete.confirm=Ste prepričani, da želite izbrisati to opombo? pane.item.notes.count.zero=%S opomb: diff --git a/chrome/locale/sr-RS/zotero/zotero.dtd b/chrome/locale/sr-RS/zotero/zotero.dtd @@ -68,6 +68,10 @@ <!ENTITY zotero.items.menu.restoreToLibrary "Restore to Library"> <!ENTITY zotero.items.menu.duplicateItem "Умножи изабрану ставку"> +<!ENTITY zotero.items.menu.mergeItems "Merge Items…"> + +<!ENTITY zotero.duplicatesMerge.versionSelect "Choose the version of the item to use as the master item:"> +<!ENTITY zotero.duplicatesMerge.fieldSelect "Select fields to keep from other versions of the item:"> <!ENTITY zotero.toolbar.newItem.label "Нова ставка"> <!ENTITY zotero.toolbar.moreItemTypes.label "Више"> diff --git a/chrome/locale/sr-RS/zotero/zotero.properties b/chrome/locale/sr-RS/zotero/zotero.properties @@ -36,6 +36,7 @@ general.enable=Укључи general.disable=Искључи general.remove=Remove general.openDocumentation=Open Documentation +general.numMore=%S more… general.operationInProgress=Зотерова операција се обавља. general.operationInProgress.waitUntilFinished=Сачекајте док се не заврши. @@ -80,7 +81,7 @@ app.firefox=Zotero for Firefox startupError=Дошло је до грешке приликом покретања Зотера. startupError.databaseInUse=Your Zotero database is currently in use. Only one instance of Zotero using the same database may be opened simultaneously at this time. -startupError.closeStandalone=If Zotero Standalone is open, please close it and restart Firefox. +startupError.closeStandalone=If Zotero Standalone is open, please close it and restart %S. startupError.closeFirefox=If Firefox with the Zotero extension is open, please close it and restart Zotero Standalone. startupError.databaseCannotBeOpened=The Zotero database cannot be opened. startupError.checkPermissions=Make sure you have read and write permissions to all files in the Zotero data directory. @@ -112,6 +113,7 @@ pane.collections.library=Моја библиотека pane.collections.trash=Избрисано pane.collections.untitled=Безимено pane.collections.unfiled=Unfiled Items +pane.collections.duplicate=Duplicate Items pane.collections.menu.rename.collection=Преименуј збирку... pane.collections.menu.edit.savedSearch=Уреди сачувану претрагу @@ -170,6 +172,10 @@ pane.items.interview.manyParticipants=Интервју %S и осталих pane.item.selected.zero=Ни једна ставка није изабрана pane.item.selected.multiple=%S изабраних ставки +pane.item.unselected.zero=No items in this view +pane.item.unselected.singular=%S item in this view +pane.item.unselected.plural=%S items in this view +pane.item.selectToMerge=Select items to merge pane.item.changeType.title=Промени врсту ставке pane.item.changeType.text=Да ли сте сигурни да желите променити врсту ставке?\n\nСледећа поља ће бити изгубљена: @@ -178,6 +184,8 @@ pane.item.defaultLastName=задњи pane.item.defaultFullName=пуно име pane.item.switchFieldMode.one=Промени на једно поље pane.item.switchFieldMode.two=Промени на два поља +pane.item.creator.moveUp=Move Up +pane.item.creator.moveDown=Move Down pane.item.notes.untitled=Безимена белешка pane.item.notes.delete.confirm=Да ли сте сигурни да желите избрисати ову белешку? pane.item.notes.count.zero=%S белешки: diff --git a/chrome/locale/sv-SE/zotero/zotero.dtd b/chrome/locale/sv-SE/zotero/zotero.dtd @@ -69,6 +69,10 @@ <!ENTITY zotero.items.menu.restoreToLibrary "Restore to Library"> <!ENTITY zotero.items.menu.duplicateItem "Duplicera vald post"> +<!ENTITY zotero.items.menu.mergeItems "Merge Items…"> + +<!ENTITY zotero.duplicatesMerge.versionSelect "Choose the version of the item to use as the master item:"> +<!ENTITY zotero.duplicatesMerge.fieldSelect "Select fields to keep from other versions of the item:"> <!ENTITY zotero.toolbar.newItem.label "Ny post"> <!ENTITY zotero.toolbar.moreItemTypes.label "Mer"> diff --git a/chrome/locale/sv-SE/zotero/zotero.properties b/chrome/locale/sv-SE/zotero/zotero.properties @@ -36,6 +36,7 @@ general.enable=Sätt på general.disable=Stäng av general.remove=Ta bort general.openDocumentation=Open Documentation +general.numMore=%S more… general.operationInProgress=Zotero arbetar just nu. general.operationInProgress.waitUntilFinished=Vänta till åtgärden är klar. @@ -112,6 +113,7 @@ pane.collections.library=Mitt bibliotek pane.collections.trash=Papperskorg pane.collections.untitled=Utan titel pane.collections.unfiled=Oregistrerade källor +pane.collections.duplicate=Duplicate Items pane.collections.menu.rename.collection=Ändra namn på samling... pane.collections.menu.edit.savedSearch=Redigera sparad sökning @@ -170,6 +172,10 @@ pane.items.interview.manyParticipants=Intervju av %S m.fl. pane.item.selected.zero=Inga källor valda pane.item.selected.multiple=%S källor valda +pane.item.unselected.zero=No items in this view +pane.item.unselected.singular=%S item in this view +pane.item.unselected.plural=%S items in this view +pane.item.selectToMerge=Select items to merge pane.item.changeType.title=Ändra källtyp pane.item.changeType.text=Är du säker på att du vill ändra källtyp?\n\nFöljande fält kommer att försvinna: @@ -178,6 +184,8 @@ pane.item.defaultLastName=Efternamn pane.item.defaultFullName=Fullständigt namn pane.item.switchFieldMode.one=Växla till ett fält pane.item.switchFieldMode.two=Växla till två fält +pane.item.creator.moveUp=Move Up +pane.item.creator.moveDown=Move Down pane.item.notes.untitled=Anteckning utan titel pane.item.notes.delete.confirm=Är du säker på att du vill ta bort den här anteckningen? pane.item.notes.count.zero=%S anteckningar: diff --git a/chrome/locale/th-TH/zotero/zotero.dtd b/chrome/locale/th-TH/zotero/zotero.dtd @@ -68,6 +68,10 @@ <!ENTITY zotero.items.menu.restoreToLibrary "เรียกคืนกลับไลบรารี่"> <!ENTITY zotero.items.menu.duplicateItem "ทำซ้ำรายการที่เลือก"> +<!ENTITY zotero.items.menu.mergeItems "Merge Items…"> + +<!ENTITY zotero.duplicatesMerge.versionSelect "Choose the version of the item to use as the master item:"> +<!ENTITY zotero.duplicatesMerge.fieldSelect "Select fields to keep from other versions of the item:"> <!ENTITY zotero.toolbar.newItem.label "รายการใหม่"> <!ENTITY zotero.toolbar.moreItemTypes.label "มากกว่า"> diff --git a/chrome/locale/th-TH/zotero/zotero.properties b/chrome/locale/th-TH/zotero/zotero.properties @@ -36,6 +36,7 @@ general.enable=ใช้งาน general.disable=ไม่ใช้งาน general.remove=ลบออก general.openDocumentation=เปิดการทำเอกสาร +general.numMore=%S more… general.operationInProgress=Zotero กำลังดำเนินการอยู่ general.operationInProgress.waitUntilFinished=กรุณารอจนกว่าจะเสร็จ @@ -112,6 +113,7 @@ pane.collections.library=ไลบรารีของฉัน pane.collections.trash=ถังขยะ pane.collections.untitled=ยังไม่ตั้งชื่อเรื่อง pane.collections.unfiled=รายการที่ไม่จัดกลุ่ม +pane.collections.duplicate=Duplicate Items pane.collections.menu.rename.collection=เปลี่ยนชื่อคอลเล็กชั่น... pane.collections.menu.edit.savedSearch=แก้ไขบันทึกผลการค้นหา @@ -170,6 +172,10 @@ pane.items.interview.manyParticipants=สัมภาษณ์โดย %S แ pane.item.selected.zero=ไม่มีรายการที่ถูกเลือก pane.item.selected.multiple=เลือกไว้ %S รายการ +pane.item.unselected.zero=No items in this view +pane.item.unselected.singular=%S item in this view +pane.item.unselected.plural=%S items in this view +pane.item.selectToMerge=Select items to merge pane.item.changeType.title=เปลี่ยนประเภทรายการ pane.item.changeType.text=คุณต้องการเปลี่ยนประเภทรายการใช่หรือไม่?\n\nฟีลด์ต่อไปนี้จะสูญหาย: @@ -178,6 +184,8 @@ pane.item.defaultLastName=อันดับสุดท้าย pane.item.defaultFullName=ชื่อเต็ม pane.item.switchFieldMode.one=สลับเป็นเขตข้อมูลเดียว pane.item.switchFieldMode.two=สลับเป็นสองเขตข้อมูล +pane.item.creator.moveUp=Move Up +pane.item.creator.moveDown=Move Down pane.item.notes.untitled=หมายเหตุไม่มีชื่อเรื่อง pane.item.notes.delete.confirm=คุณต้องการลบหมายเหตุนี้ใช่หรือไม่? pane.item.notes.count.zero=%S หมายเหตุ: diff --git a/chrome/locale/tr-TR/zotero/zotero.dtd b/chrome/locale/tr-TR/zotero/zotero.dtd @@ -68,6 +68,10 @@ <!ENTITY zotero.items.menu.restoreToLibrary "Kitaplığa geri yükle"> <!ENTITY zotero.items.menu.duplicateItem "Seçili Eseri Çoğalt"> +<!ENTITY zotero.items.menu.mergeItems "Merge Items…"> + +<!ENTITY zotero.duplicatesMerge.versionSelect "Choose the version of the item to use as the master item:"> +<!ENTITY zotero.duplicatesMerge.fieldSelect "Select fields to keep from other versions of the item:"> <!ENTITY zotero.toolbar.newItem.label "Yeni Eser"> <!ENTITY zotero.toolbar.moreItemTypes.label "Daha Fazla"> diff --git a/chrome/locale/tr-TR/zotero/zotero.properties b/chrome/locale/tr-TR/zotero/zotero.properties @@ -36,6 +36,7 @@ general.enable=Seçilir Kıl: general.disable=Seçilemez Kıl general.remove=Kaldır general.openDocumentation=Bilgilemeyi Aç +general.numMore=%S more… general.operationInProgress=Zotero işlemi çalışıyor. general.operationInProgress.waitUntilFinished=Lütfen bitene kadar bekleyiniz. @@ -112,6 +113,7 @@ pane.collections.library=Kitaplığım pane.collections.trash=Çöp pane.collections.untitled=İsimsiz pane.collections.unfiled=Dosyalanmamış Eserler +pane.collections.duplicate=Duplicate Items pane.collections.menu.rename.collection=Dermeyi yeniden adlandır... pane.collections.menu.edit.savedSearch=Kaydedilen Aramayı Düzenle @@ -170,6 +172,10 @@ pane.items.interview.manyParticipants=Görüşme %S ve tümü pane.item.selected.zero=Hiçbir Eser Seçilmedi pane.item.selected.multiple=%S Eser seçildi +pane.item.unselected.zero=No items in this view +pane.item.unselected.singular=%S item in this view +pane.item.unselected.plural=%S items in this view +pane.item.selectToMerge=Select items to merge pane.item.changeType.title=Eser tipini değiştir pane.item.changeType.text=Eser tipini değiştirmek istediğinize emin misiniz?\n\nAşağıdaki alanlar kaybedilecek: @@ -178,6 +184,8 @@ pane.item.defaultLastName=son pane.item.defaultFullName=tam isim pane.item.switchFieldMode.one=Tek alana geç pane.item.switchFieldMode.two=İki alana geç +pane.item.creator.moveUp=Move Up +pane.item.creator.moveDown=Move Down pane.item.notes.untitled=Başlıksız Not pane.item.notes.delete.confirm=Bu notu silmek istediğinize emin misiniz? pane.item.notes.count.zero=%S not: diff --git a/chrome/locale/vi-VN/zotero/zotero.dtd b/chrome/locale/vi-VN/zotero/zotero.dtd @@ -68,6 +68,10 @@ <!ENTITY zotero.items.menu.restoreToLibrary "Restore to Library"> <!ENTITY zotero.items.menu.duplicateItem "Sao chép Biểu ghi vừa chọn"> +<!ENTITY zotero.items.menu.mergeItems "Merge Items…"> + +<!ENTITY zotero.duplicatesMerge.versionSelect "Choose the version of the item to use as the master item:"> +<!ENTITY zotero.duplicatesMerge.fieldSelect "Select fields to keep from other versions of the item:"> <!ENTITY zotero.toolbar.newItem.label "Biểu ghi mới"> <!ENTITY zotero.toolbar.moreItemTypes.label "Khác"> diff --git a/chrome/locale/vi-VN/zotero/zotero.properties b/chrome/locale/vi-VN/zotero/zotero.properties @@ -36,6 +36,7 @@ general.enable=Enable general.disable=Disable general.remove=Remove general.openDocumentation=Open Documentation +general.numMore=%S more… general.operationInProgress=A Zotero operation is currently in progress. general.operationInProgress.waitUntilFinished=Please wait until it has finished. @@ -80,7 +81,7 @@ app.firefox=Zotero for Firefox startupError=Đã có một lỗi khi đang khởi động Zotero. startupError.databaseInUse=Your Zotero database is currently in use. Only one instance of Zotero using the same database may be opened simultaneously at this time. -startupError.closeStandalone=If Zotero Standalone is open, please close it and restart Firefox. +startupError.closeStandalone=If Zotero Standalone is open, please close it and restart %S. startupError.closeFirefox=If Firefox with the Zotero extension is open, please close it and restart Zotero Standalone. startupError.databaseCannotBeOpened=The Zotero database cannot be opened. startupError.checkPermissions=Make sure you have read and write permissions to all files in the Zotero data directory. @@ -112,6 +113,7 @@ pane.collections.library=Thư viện của Tôi pane.collections.trash=Trash pane.collections.untitled=Vô danh pane.collections.unfiled=Unfiled Items +pane.collections.duplicate=Duplicate Items pane.collections.menu.rename.collection=Đổi tên Bộ sưu tập... pane.collections.menu.edit.savedSearch=Soạn thảo Tìm kiếm Định sẵn @@ -170,6 +172,10 @@ pane.items.interview.manyParticipants=Phỏng vấn bởi %S và cs pane.item.selected.zero=Chưa chọn biểu ghi nào pane.item.selected.multiple=Chọn %S biểu ghi +pane.item.unselected.zero=No items in this view +pane.item.unselected.singular=%S item in this view +pane.item.unselected.plural=%S items in this view +pane.item.selectToMerge=Select items to merge pane.item.changeType.title=Đổi Kiểu cho Biểu ghi pane.item.changeType.text=Bạn có chắc bạn muốn đổi kiểu cho biểu ghi này?\n\nCác trường dữ liệu sau sẽ bị mất: @@ -178,6 +184,8 @@ pane.item.defaultLastName=họ pane.item.defaultFullName=tên đầy đủ pane.item.switchFieldMode.one=Chuyển thành một trường đơn pane.item.switchFieldMode.two=Chuyển thành hai trường +pane.item.creator.moveUp=Move Up +pane.item.creator.moveDown=Move Down pane.item.notes.untitled=Ghi chép Vô danh pane.item.notes.delete.confirm=Bạn có chắc bạn muốn xóa ghi chép này? pane.item.notes.count.zero=%S ghi chép: diff --git a/chrome/locale/zh-CN/zotero/zotero.dtd b/chrome/locale/zh-CN/zotero/zotero.dtd @@ -68,6 +68,10 @@ <!ENTITY zotero.items.menu.restoreToLibrary "还原"> <!ENTITY zotero.items.menu.duplicateItem "生成所选条目复件"> +<!ENTITY zotero.items.menu.mergeItems "Merge Items…"> + +<!ENTITY zotero.duplicatesMerge.versionSelect "Choose the version of the item to use as the master item:"> +<!ENTITY zotero.duplicatesMerge.fieldSelect "Select fields to keep from other versions of the item:"> <!ENTITY zotero.toolbar.newItem.label "新建条目"> <!ENTITY zotero.toolbar.moreItemTypes.label "更多"> diff --git a/chrome/locale/zh-CN/zotero/zotero.properties b/chrome/locale/zh-CN/zotero/zotero.properties @@ -36,6 +36,7 @@ general.enable=激活 general.disable=禁用 general.remove=移除 general.openDocumentation=Open Documentation +general.numMore=%S more… general.operationInProgress=另一个Zotero操作正在处理中。 general.operationInProgress.waitUntilFinished=请耐心等待,直到它完成。 @@ -80,7 +81,7 @@ app.firefox=Zotero for Firefox startupError=Zotero启动时遇到一个错误. startupError.databaseInUse=您的Zotero数据库正在使用中。只有一个使用同一数据库的Zotero实例可以同时打开。 -startupError.closeStandalone=If Zotero Standalone is open, please close it and restart Firefox. +startupError.closeStandalone=If Zotero Standalone is open, please close it and restart %S. startupError.closeFirefox=If Firefox with the Zotero extension is open, please close it and restart Zotero Standalone. startupError.databaseCannotBeOpened=The Zotero database cannot be opened. startupError.checkPermissions=Make sure you have read and write permissions to all files in the Zotero data directory. @@ -112,6 +113,7 @@ pane.collections.library=我的书库 pane.collections.trash=Trash pane.collections.untitled=未命名 pane.collections.unfiled=Unfiled Items +pane.collections.duplicate=Duplicate Items pane.collections.menu.rename.collection=重命名分类... pane.collections.menu.edit.savedSearch=编辑可存搜索 @@ -170,6 +172,10 @@ pane.items.interview.manyParticipants=Interview by %S et al. pane.item.selected.zero=无选中的条目 pane.item.selected.multiple=%S 项选中 +pane.item.unselected.zero=No items in this view +pane.item.unselected.singular=%S item in this view +pane.item.unselected.plural=%S items in this view +pane.item.selectToMerge=Select items to merge pane.item.changeType.title=更改条目类型 pane.item.changeType.text=确信要更改条目类型?\n\n如下字段将会丢失: @@ -178,6 +184,8 @@ pane.item.defaultLastName=姓 pane.item.defaultFullName=全名 pane.item.switchFieldMode.one=Switch to single field pane.item.switchFieldMode.two=Switch to two fields +pane.item.creator.moveUp=Move Up +pane.item.creator.moveDown=Move Down pane.item.notes.untitled=未命名便笺 pane.item.notes.delete.confirm=确实要删除此便笺吗? pane.item.notes.count.zero=%S 条便笺: diff --git a/chrome/locale/zh-TW/zotero/zotero.dtd b/chrome/locale/zh-TW/zotero/zotero.dtd @@ -69,6 +69,10 @@ <!ENTITY zotero.items.menu.restoreToLibrary "還原到圖書館中"> <!ENTITY zotero.items.menu.duplicateItem "為選取的項目建立副本"> +<!ENTITY zotero.items.menu.mergeItems "Merge Items…"> + +<!ENTITY zotero.duplicatesMerge.versionSelect "Choose the version of the item to use as the master item:"> +<!ENTITY zotero.duplicatesMerge.fieldSelect "Select fields to keep from other versions of the item:"> <!ENTITY zotero.toolbar.newItem.label "新增項目"> <!ENTITY zotero.toolbar.moreItemTypes.label "更多"> diff --git a/chrome/locale/zh-TW/zotero/zotero.properties b/chrome/locale/zh-TW/zotero/zotero.properties @@ -36,6 +36,7 @@ general.enable=啟用 general.disable=停用 general.remove=移除 general.openDocumentation=開啟說明文件 +general.numMore=%S more… general.operationInProgress=Zotero 有動作正在進行中。 general.operationInProgress.waitUntilFinished=請稍候,直到動作完成。 @@ -112,6 +113,7 @@ pane.collections.library=我的圖書館 pane.collections.trash=垃圾筒 pane.collections.untitled=未命名 pane.collections.unfiled=未歸檔項目 +pane.collections.duplicate=Duplicate Items pane.collections.menu.rename.collection=重新命名這個收集… pane.collections.menu.edit.savedSearch=編輯存留搜尋 @@ -170,6 +172,10 @@ pane.items.interview.manyParticipants=%S 等人所作的訪問 pane.item.selected.zero=沒有選取的項目 pane.item.selected.multiple=選取了 %S 個項目 +pane.item.unselected.zero=No items in this view +pane.item.unselected.singular=%S item in this view +pane.item.unselected.plural=%S items in this view +pane.item.selectToMerge=Select items to merge pane.item.changeType.title=改變項目類型 pane.item.changeType.text=你確定要改變項目的類型嗎?\n\n下列的欄位資料將會消失: @@ -178,6 +184,8 @@ pane.item.defaultLastName=姓 pane.item.defaultFullName=全名 pane.item.switchFieldMode.one=切換成單一欄位 pane.item.switchFieldMode.two=切換成兩個欄位 +pane.item.creator.moveUp=Move Up +pane.item.creator.moveDown=Move Down pane.item.notes.untitled=未命名的筆記 pane.item.notes.delete.confirm=你確定要刪除這則筆記嗎? pane.item.notes.count.zero=%S 則筆記: diff --git a/chrome/skin/default/zotero/treeitem-audioRecording.png b/chrome/skin/default/zotero/treeitem-audioRecording.png Binary files differ. diff --git a/chrome/skin/default/zotero/treeitem-manuscript.png b/chrome/skin/default/zotero/treeitem-bill.png Binary files differ. diff --git a/chrome/skin/default/zotero/treeitem-blogPost.png b/chrome/skin/default/zotero/treeitem-blogPost.png Binary files differ. diff --git a/chrome/skin/default/zotero/treeitem-case.png b/chrome/skin/default/zotero/treeitem-case.png Binary files differ. diff --git a/chrome/skin/default/zotero/treeitem-dictionaryEntry.png b/chrome/skin/default/zotero/treeitem-dictionaryEntry.png Binary files differ. diff --git a/chrome/skin/default/zotero/treeitem-document.png b/chrome/skin/default/zotero/treeitem-document.png Binary files differ. diff --git a/chrome/skin/default/zotero/treeitem-email.png b/chrome/skin/default/zotero/treeitem-email.png Binary files differ. diff --git a/chrome/skin/default/zotero/treeitem-encyclopediaArticle.png b/chrome/skin/default/zotero/treeitem-encyclopediaArticle.png Binary files differ. diff --git a/chrome/skin/default/zotero/treeitem-forumPost.png b/chrome/skin/default/zotero/treeitem-forumPost.png Binary files differ. diff --git a/chrome/skin/default/zotero/treeitem-hearing.png b/chrome/skin/default/zotero/treeitem-hearing.png Binary files differ. diff --git a/chrome/skin/default/zotero/treeitem-instantMessage.png b/chrome/skin/default/zotero/treeitem-instantMessage.png Binary files differ. diff --git a/chrome/skin/default/zotero/treeitem-magazineArticle.png b/chrome/skin/default/zotero/treeitem-magazineArticle.png Binary files differ. diff --git a/chrome/skin/default/zotero/treeitem-manuscript.png b/chrome/skin/default/zotero/treeitem-manuscript.png Binary files differ. diff --git a/chrome/skin/default/zotero/treeitem-patent.png b/chrome/skin/default/zotero/treeitem-patent.png Binary files differ. diff --git a/chrome/skin/default/zotero/treeitem-podcast.png b/chrome/skin/default/zotero/treeitem-podcast.png Binary files differ. diff --git a/chrome/skin/default/zotero/treeitem-presentation.png b/chrome/skin/default/zotero/treeitem-presentation.png Binary files differ. diff --git a/chrome/skin/default/zotero/treeitem-statute.png b/chrome/skin/default/zotero/treeitem-statute.png Binary files differ. diff --git a/chrome/skin/default/zotero/treeitem-thesis.png b/chrome/skin/default/zotero/treeitem-thesis.png Binary files differ. diff --git a/chrome/skin/default/zotero/treeitem-videoRecording.png b/chrome/skin/default/zotero/treeitem-videoRecording.png Binary files differ. diff --git a/chrome/skin/default/zotero/treeitem-webpage.png b/chrome/skin/default/zotero/treeitem-webpage.png Binary files differ. diff --git a/components/zotero-autocomplete.js b/components/zotero-autocomplete.js @@ -90,7 +90,7 @@ ZoteroAutoComplete.prototype.startSearch = function(searchString, searchParam, p var resultsCallback = function (results) { var collation = self._zotero.getLocaleCollation(); results.sort(function(a, b) { - return collation.compareString(1, a, b); + return collation.compareString(1, a.val, b.val); }); } break; @@ -208,6 +208,11 @@ ZoteroAutoComplete.prototype.startSearch = function(searchString, searchParam, p // Disable asynchronous until we figure out the hangs if (true) { var rows = this._zotero.DB.query(sql, sqlParams); + + if (resultsCallback) { + resultsCallback(rows); + } + var results = []; var comments = []; for each(var row in rows) { diff --git a/components/zotero-service.js b/components/zotero-service.js @@ -238,20 +238,20 @@ function makeZoteroContext(isConnector) { // Load RDF files into Zotero.RDF.AJAW namespace (easier than modifying all of the references) const rdfXpcomFiles = [ + 'rdf/init', 'rdf/uri', 'rdf/term', 'rdf/identity', 'rdf/match', 'rdf/n3parser', 'rdf/rdfparser', - 'rdf/serialize', - 'rdf' + 'rdf/serialize' ]; - zContext.Zotero.RDF = {AJAW:{Zotero:zContext.Zotero}}; + zContext.Zotero.RDF = {Zotero:zContext.Zotero}; for (var i=0; i<rdfXpcomFiles.length; i++) { Cc["@mozilla.org/moz/jssubscript-loader;1"] .getService(Ci.mozIJSSubScriptLoader) - .loadSubScript("chrome://zotero/content/xpcom/" + rdfXpcomFiles[i] + ".js", zContext.Zotero.RDF.AJAW); + .loadSubScript("chrome://zotero/content/xpcom/" + rdfXpcomFiles[i] + ".js", zContext.Zotero.RDF); } if(isStandalone()) { diff --git a/resource/schema/repotime.txt b/resource/schema/repotime.txt @@ -1 +1 @@ -2012-05-01 04:55:00 +2012-05-04 03:15:00