- Sep 2023
-
github.com github.com
-
Undocumented Hypothes.is Badge API (used by Chrome extension):
```python """ Return the number of public annotations on a given page.
This is for the number that's displayed on the Chrome extension's badge.
Certain pages are blocklisted so that the badge never shows a number on those pages. The Chrome extension is oblivious to this, we just tell it that there are 0 annotations. """ ```
https://hypothes.is/api/badge?uri=*
same ashttps://hypothes.is/api/search?limit=0&uri=*
.
-
-
-
Add a new, undocumented separate_replies=True option to the search API. If separate_replies=True option is _not_ given to the search API, then it reverts to its previous behaviour: _do_ include replies in the "rows" list returned. This is the same behaviour that the search API had befor: it returns both top-level annotations and replies in the one "rows" list, but without any guarantee that if some annotations/replies from a given thread are in the list then all annotations/replies from that thread will be in it. If separate_replies=True _is_ given then the API follows the new behaviour: "rows" contains top-level annotations only, and a separate "replies" list containing all replies to the annotations in rows is also inserted into the result.
-
- Jun 2023
-
storymaps.arcgis.com storymaps.arcgis.com
- Apr 2023
-
www.cen.umontreal.ca www.cen.umontreal.ca
Tags
Annotators
URL
-
- Feb 2023
- Nov 2022
- Aug 2022
-
web.hypothes.is web.hypothes.is
-
-
In line with the much-requested (and long-longed-for) feature of highlights in different colors (an exhaustive list given in #198), I would like to suggest allowing (automatic) coloring of highlights based on tags with designated patterns (like code:critiques, code:non-ergodicity in psychology, etc.), or alternatively, all tags (i.e., without specific patterns).
-
-
-
Made a quick strawman mockup of what it could look like from the editor side:
-
-
tomcritchlow.com tomcritchlow.com
Tags
Annotators
URL
-
-
github.com github.com
-
github.com github.com
-
```js / Adapted from: https://github.com/openannotation/annotator/blob/v1.2.x/src/plugin/document.coffee Annotator v1.2.10 https://github.com/openannotation/annotator Copyright 2015, the Annotator project contributors. Dual licensed under the MIT and GPLv3 licenses. https://github.com/openannotation/annotator/blob/master/LICENSE /
/* * nb. The
DocumentMetadata
type is renamed to avoid a conflict with the *DocumentMetadata
class below. * * @typedef {import('../../types/annotator').DocumentMetadata} Metadata /import { normalizeURI } from '../util/url';
/* * @typedef Link * @prop {string} link.href * @prop {string} [link.rel] * @prop {string} [link.type] /
/* * Extension of the
Metadata
type with non-optional fields fordc
,eprints
etc. * * @typedef HTMLDocumentMetadata * @prop {string} title * @prop {Link[]} link * @prop {Record<string, string[]>} dc * @prop {Record<string, string[]>} eprints * @prop {Record<string, string[]>} facebook * @prop {Record<string, string[]>} highwire * @prop {Record<string, string[]>} prism * @prop {Record<string, string[]>} twitter * @prop {string} [favicon] * @prop {string} [documentFingerprint] // * HTMLMetadata reads metadata/links from the current HTML document. */ export class HTMLMetadata { / * @param {object} [options] * @param {Document} [options.document] */ constructor(options = {}) { this.document = options.document || document; }
/* * Returns the primary URI for the document being annotated * * @return {string} / uri() { let uri = decodeURIComponent(this._getDocumentHref());
// Use the `link[rel=canonical]` element's href as the URL if present. const links = this._getLinks(); for (let link of links) { if (link.rel === 'canonical') { uri = link.href; } } return uri;
}
/ * Return metadata for the current page. * * @return {HTMLDocumentMetadata} */ getDocumentMetadata() { / @type {HTMLDocumentMetadata} */ const metadata = { title: document.title, link: [],
dc: this._getMetaTags('name', 'dc.'), eprints: this._getMetaTags('name', 'eprints.'), facebook: this._getMetaTags('property', 'og:'), highwire: this._getMetaTags('name', 'citation_'), prism: this._getMetaTags('name', 'prism.'), twitter: this._getMetaTags('name', 'twitter:'), }; const favicon = this._getFavicon(); if (favicon) { metadata.favicon = favicon; } metadata.title = this._getTitle(metadata); metadata.link = this._getLinks(metadata); const dcLink = metadata.link.find(link => link.href.startsWith('urn:x-dc')); if (dcLink) { metadata.documentFingerprint = dcLink.href; } return metadata;
}
/ * Return an array of all the
content
values of<meta>
tags on the page * where the value of the attribute begins with<prefix>
. * * @param {string} attribute * @param {string} prefix - it is interpreted as a regex * @return {Record<string,string[]>} */ _getMetaTags(attribute, prefix) { / @type {Record<string,string[]>} */ const tags = {}; for (let meta of Array.from(this.document.querySelectorAll('meta'))) { const name = meta.getAttribute(attribute); const { content } = meta; if (name && content) { const match = name.match(RegExp(^${prefix}(.+)$
, 'i')); if (match) { const key = match[1].toLowerCase(); if (tags[key]) { tags[key].push(content); } else { tags[key] = [content]; } } } } return tags; }/* @param {HTMLDocumentMetadata} metadata / _getTitle(metadata) { if (metadata.highwire.title) { return metadata.highwire.title[0]; } else if (metadata.eprints.title) { return metadata.eprints.title[0]; } else if (metadata.prism.title) { return metadata.prism.title[0]; } else if (metadata.facebook.title) { return metadata.facebook.title[0]; } else if (metadata.twitter.title) { return metadata.twitter.title[0]; } else if (metadata.dc.title) { return metadata.dc.title[0]; } else { return this.document.title; } }
/ * Get document URIs from
<link>
and<meta>
elements on the page. * * @param {Pick<HTMLDocumentMetadata, 'highwire'|'dc'>} [metadata] - * Dublin Core and Highwire metadata parsed from<meta>
tags. * @return {Link[]} */ _getLinks(metadata = { dc: {}, highwire: {} }) { / @type {Link[]} */ const links = [{ href: this._getDocumentHref() }];// Extract links from `<link>` tags with certain `rel` values. const linkElements = Array.from(this.document.querySelectorAll('link')); for (let link of linkElements) { if ( !['alternate', 'canonical', 'bookmark', 'shortlink'].includes(link.rel) ) { continue; } if (link.rel === 'alternate') { // Ignore RSS feed links. if (link.type && link.type.match(/^application\/(rss|atom)\+xml/)) { continue; } // Ignore alternate languages. if (link.hreflang) { continue; } } try { const href = this._absoluteUrl(link.href); links.push({ href, rel: link.rel, type: link.type }); } catch (e) { // Ignore URIs which cannot be parsed. } } // Look for links in scholar metadata for (let name of Object.keys(metadata.highwire)) { const values = metadata.highwire[name]; if (name === 'pdf_url') { for (let url of values) { try { links.push({ href: this._absoluteUrl(url), type: 'application/pdf', }); } catch (e) { // Ignore URIs which cannot be parsed. } } } // Kind of a hack to express DOI identifiers as links but it's a // convenient place to look them up later, and somewhat sane since // they don't have a type. if (name === 'doi') { for (let doi of values) { if (doi.slice(0, 4) !== 'doi:') { doi = `doi:${doi}`; } links.push({ href: doi }); } } } // Look for links in Dublin Core data for (let name of Object.keys(metadata.dc)) { const values = metadata.dc[name]; if (name === 'identifier') { for (let id of values) { if (id.slice(0, 4) === 'doi:') { links.push({ href: id }); } } } } // Look for a link to identify the resource in Dublin Core metadata const dcRelationValues = metadata.dc['relation.ispartof']; const dcIdentifierValues = metadata.dc.identifier; if (dcRelationValues && dcIdentifierValues) { const dcUrnRelationComponent = dcRelationValues[dcRelationValues.length - 1]; const dcUrnIdentifierComponent = dcIdentifierValues[dcIdentifierValues.length - 1]; const dcUrn = 'urn:x-dc:' + encodeURIComponent(dcUrnRelationComponent) + '/' + encodeURIComponent(dcUrnIdentifierComponent); links.push({ href: dcUrn }); } return links;
}
_getFavicon() { let favicon = null; for (let link of Array.from(this.document.querySelectorAll('link'))) { if (['shortcut icon', 'icon'].includes(link.rel)) { try { favicon = this._absoluteUrl(link.href); } catch (e) { // Ignore URIs which cannot be parsed. } } } return favicon; }
/* * Convert a possibly relative URI to an absolute one. This will throw an * exception if the URL cannot be parsed. * * @param {string} url / _absoluteUrl(url) { return normalizeURI(url, this.document.baseURI); }
// Get the true URI record when it's masked via a different protocol. // This happens when an href is set with a uri using the 'blob:' protocol // but the document can set a different uri through a <base> tag. _getDocumentHref() { const { href } = this.document.location; const allowedSchemes = ['http:', 'https:', 'file:'];
// Use the current document location if it has a recognized scheme. const scheme = new URL(href).protocol; if (allowedSchemes.includes(scheme)) { return href; } // Otherwise, try using the location specified by the <base> element. if ( this.document.baseURI && allowedSchemes.includes(new URL(this.document.baseURI).protocol) ) { return this.document.baseURI; } // Fall back to returning the document URI, even though the scheme is not // in the allowed list. return href;
} } ```
-
-
github.com github.com
-
yaml definitions: Annotation: type: object required: - user - uri properties: id: type: string description: Unique ID for this Annotation. uri: type: string description: URI which is the target of this Annotation. target: type: array items: - type: object properties: scope: type: array items: - type: string selector: type: array items: - type: object properties: type: description: Type of Selector--see Web Annotation Data Model. type: string source: type: string user: type: string description: User URI in the form of an `acct` prefixed URI. document: type: object description: Target document metadata schema: $ref: '#/definitions/DocumentMetadata' permissions: type: object description: Permissions for this Annotation. created: type: string format: date-time updated: type: string format: date-time AnnotationList: type: object properties: total: type: number rows: type: array items: $ref: '#/definitions/Annotation' DocumentMetadata: type: object properties: eprints: type: object title: type: string twitter: type: object properties: image:src: type: array items: type: string title: type: array items: type: string description: type: array items: type: string card: type: array items: type: string site: type: array items: type: string dc: type: object favicon: type: string prism: type: object highwire: type: object link: type: array items: type: object properties: href: type: string facebook: type: object properties: site_name: type: array items: type: string description: type: array items: type: string title: type: array items: type: string url: type: array items: type: string image: type: array items: type: string type: type: array items: type: string
-
- Jun 2022
-
github.com github.com
- May 2022
-
github.com github.com
-
The new lines you mention really are present in the text content of the element. HTML tags are not being replaced by new lines, they just get omitted entirely. If you look at the textContent property of the <p> element you selected in the browser console, and you'll see the same new lines. Also if you select the text and run window.getSelection().getRangeAt(0).toString() in the browser console you'll see the same new lines. In summary, this is working as it is currently expected to. What I think may have been surprising here is that the captured text is not the same as what would be copied to the clipboard. When copying to the clipboard, new lines in the source get replaced with spaces, and <br> tags get converted to new lines. Browser specifications distinguish the original text content of HTML "in the source" as returned by element.textContent from the text content "as rendered" returned by element.innerText. Hypothesis has always captured quotes from and searched for quotes in the "source" text content rather than the "rendered" text. This behavior causes issues with line breaks as well. It might make sense for us to look at capturing the rendered text (as copied to the clipboard) rather than the source text in future. We'd need to be careful to handle all the places where this distinction comes up, and also make sure that all existing annotations anchor properly. Also we should talk to other parties interested in the Web Annotations specifications to discuss how this impacts interoperability.
What I think may have been surprising here is that the captured text is not the same as what would be copied to the clipboard. When <mark>copying to the clipboard, <mark style="background-color: #8000314f">new lines in the source</mark> get <mark style="background-color:#00800030">replaced with spaces</mark>, and <br> tags get converted to new lines</mark>. </br> <mark>Browser specifications distinguish <mark style="background-color: #00800036">the original text content of HTML "in the source"</mark> as returned by <mark style="background-color: #00800036"/>element.textContent</mark> from <mark style="background-color: #ffa500a1">the text content "as rendered" returned by element.innerText.</mark></mark> Hypothesis has always captured quotes from and searched for quotes in the "source" text content rather than the "rendered" text.
-
-
www.youtube.com www.youtube.com
Tags
Annotators
URL
-
-
www.w3.org www.w3.org
Tags
Annotators
URL
-
-
blog.ubiquitypress.com blog.ubiquitypress.com
-
web.hypothes.is web.hypothes.is
-
github.com github.com
-
<details open> <summary>
Nanotate Annotations Samples
</summary> ```json [ { "id":"d5JrdABbEeuatj9X3vvoXw", "authority":"__world__", "url":"https://protocolexchange.researchsquare.com/article/pex-1069/v1", "created":"2020-09-27T00:50:41.265044+00:00", "updated":"2020-09-27T00:50:41.265044+00:00", "title":[ "Sample preparation and imaging procedures for fast and multiplexed superresolution microscopy with DNA-PAINT-ERS" ], "refs":[ ], "isReply":false, "isPagenote":false, "user":"acct:miguel.ruano@hypothes.is", "displayName":null, "text":"", "prefix":"for 10 minutes. Wash with PBS3. ", "exact":"Add imaging buffer with desired ratios of Buffer C (500 mM), ethylene carbonate, and IS-CF660R at 1-2 nM final concentration. The exact concentration of IS may need to be adjusted depending on the target and based on the imaging kinetics.", "suffix":"", "start":15158, "end":15396, "tags":[ "step" ], "group":"__world__", "ontologies":[ ] }, { "id":"FrhgjABcEeu5B4dnXgvb_A", "authority":"__world__", "url":"https://protocolexchange.researchsquare.com/article/pex-1069/v1", "created":"2020-09-27T00:55:08.276888+00:00", "updated":"2020-10-05T14:15:00.764415+00:00", "title":[ "Sample preparation and imaging procedures for fast and multiplexed superresolution microscopy with DNA-PAINT-ERS" ], "refs":[ ], "isReply":false, "isPagenote":false, "user":"acct:miguel.ruano@hypothes.is", "displayName":null, "text":"my other text modificate", "prefix":"ed ratios of Buffer C (500 mM), ", "exact":"ethylene carbonate", "suffix":"", "start":15219, "end":15237, "tags":[ "reagent" ], "group":"__world__", "ontologies":[ "CHEBI" ], "settings":{ "bio_annotations":[ "" ] } }, { "id":"7Z1sugBbEeu9_wtvk1iAjw", "authority":"__world__", "url":"https://protocolexchange.researchsquare.com/article/pex-1069/v1", "created":"2020-09-27T00:53:59.317703+00:00", "updated":"2020-09-30T00:39:50.822216+00:00", "title":[ "Sample preparation and imaging procedures for fast and multiplexed superresolution microscopy with DNA-PAINT-ERS" ], "refs":[ ], "isReply":false, "isPagenote":false, "user":"acct:miguel.ruano@hypothes.is", "displayName":null, "text":"", "prefix":"10 minutes. Wash with PBS3. Add ", "exact":"imaging buffer", "suffix":"", "start":15162, "end":15176, "tags":[ "reagent" ], "group":"__world__", "ontologies":[ "CHEBI" ], "settings":{ "bio_annotations":[ "http://purl.obolibrary.org/obo/CHEBI_35225" ] } } ] </summary>
-
-
nanotate.bitsfetch.com nanotate.bitsfetch.comNanotate1
-
Tool for the generation of 'nanopublications' based on hypothesis annotations
-
-
cris.maastrichtuniversity.nl cris.maastrichtuniversity.nl
-
robertknight.github.io robertknight.github.io
Tags
Annotators
URL
-
- Apr 2022
-
anno-rep.org anno-rep.org
-
-
info.orcid.org info.orcid.org
-
orcid.figshare.com orcid.figshare.com
-
www.slideshare.net www.slideshare.net
- Mar 2022
-
web.hypothes.is web.hypothes.is
Tags
Annotators
URL
-
- Feb 2022
- Jan 2022
-
web.hypothes.is web.hypothes.is
-
Here’s an even more magical trick. Download that PDF to your file system, load it into a third tab, and annotate again. Now you’ll see all three annotations in all three tabs!
Since Hypothesis doesn’t know that the local copy of the PDF came from http://journals.plos.org/plosone/article/file?id=10.1371/journal.pone.0168597&type=printable, or that it’s related to http://journals.plos.org/plosone/article?id=10.1371/journal.pone.0168597, how is that possible?
The answer is that the PDF standard defines a unique identifier, or “fingerprint,” that authoring tools encode into the PDFs they create. When you use the Hypothesis client to annotate web-hosted PDF, it captures the fingerprint and sends it to the server.
-
It was already the case that you could search Hypothesis for the DOI, like so:
-
First, here’s a magic trick you might not realize Hypothesis has up its sleeve. Consider this PLOS One article. Annotate it in one tab, then open a second tab and annotate the PDF version there. You’ll see both annotations in both tabs. How is that possible?
The answer is that when scholarly publishers provide HTML versions of articles, they typically include metadata that points to PDF versions of the same articles. Here’s one way that happens:
<meta name=”citation_pdf_url” content=”http://journals.plos.org/plosone/article/file?id=10.1371/journal.pone.0168597&type=printable”>
Hypothesis remembers the correspondence between the HTML and PDF versions, and coalesces annotations across them.
-
Tags
Annotators
URL
-
-
blog.jonudell.net blog.jonudell.net
-
www.programmableweb.com www.programmableweb.com
Tags
Annotators
URL
-
-
-
-
blog.jonudell.net blog.jonudell.net
- Dec 2021
-
-
{ "@context": { "oa": "http://www.w3.org/ns/oa#", "dc": "http://purl.org/dc/elements/1.1/", "dcterms": "http://purl.org/dc/terms/", "dctypes": "http://purl.org/dc/dcmitype/", "foaf": "http://xmlns.com/foaf/0.1/", "rdf": "http://www.w3.org/1999/02/22-rdf-syntax-ns#", "rdfs": "http://www.w3.org/2000/01/rdf-schema#", "skos": "http://www.w3.org/2004/02/skos/core#", "text": { "@id": "oa:hasBody" }, "target": { "@type": "@id", "@id": "oa:hasTarget" }, "source": { "@type": "@id", "@id": "oa:hasSource" }, "selector": { "@type": "@id", "@id": "oa:hasSelector" }, "state": { "@type": "@id", "@id": "oa:hasState" }, "scope": { "@type": "@id", "@id": "oa:hasScope" }, "user": { "@type": "@id", "@id": "oa:annotatedBy" }, "serializedBy": { "@type": "@id", "@id": "oa:serializedBy" }, "motivation": { "@type": "@id", "@id": "oa:motivatedBy" }, "stylesheet": { "@type": "@id", "@id": "oa:styledBy" }, "cached": { "@type": "@id", "@id": "oa:cachedSource" }, "conformsTo": { "@type": "@id", "@id": "dcterms:conformsTo" }, "members": { "@type": "@id", "@id": "oa:membershipList", "@container": "@list" }, "item": { "@type": "@id", "@id": "oa:item" }, "related": { "@type": "@id", "@id": "skos:related" }, "format": "dc:format", "language": "dc:language", "created": "oa:annotatedAt", "updated": "oa:serializedAt", "when": "oa:when", "value": "rdf:value", "start": "oa:start", "end": "oa:end", "exact": "oa:exact", "prefix": "oa:prefix", "suffix": "oa:suffix", "label": "rdfs:label", "name": "foaf:name", "mbox": "foaf:mbox", "nick": "foaf:nick", "styleClass": "oa:styleClass", "@base": "http://hypothes.is/api/annotations/", "id": "@id", "tags": "oa:Tag" }, "updated": "2014-09-18T21:43:16.353744+00:00", "target": [ { "source": "http://faculty.georgetown.edu/irvinem/theory/Berners-Lee-HTTP-proposal.pdf", "pos": { "top": 549.5, "height": 17 }, "selector": [ { "type": "RangeSelector", "startContainer": "/div[1]/div[2]/div[4]/div[1]/div[1]/div[2]/div[16]", "endContainer": "/div[1]/div[2]/div[4]/div[1]/div[1]/div[2]/div[16]", "startOffset": 0, "endOffset": 7 }, { "start": 397, "end": 404, "type": "TextPositionSelector" }, { "type": "TextQuoteSelector", "prefix": "information Hypermedia CERNDOC", "exact": "ENQUIRE", "suffix": "Tim Berners-Lee section group C" } ] } ], "created": "2014-09-18T21:32:13.492351+00:00", "text": "As featured in \"Weaving the Web\" by Tim Berners-Lee", "tags": [ "web", "history" ], "uri": "http://faculty.georgetown.edu/irvinem/theory/Berners-Lee-HTTP-proposal.pdf", "user": "acct:BigBlueHat@hypothes.is", "document": { "eprints": {}, "title": "Berners-Lee-HTTP-proposal.pdf", "twitter": {}, "dc": {}, "prism": {}, "highwire": {}, "facebook": {}, "reply_to": [], "link": [ { "href": "http://faculty.georgetown.edu/irvinem/theory/Berners-Lee-HTTP-proposal.pdf" } ] }, "consumer": "00000000-0000-0000-0000-000000000000", "id": "Gk_TW9d_SyCG5cFH4UCy9A", "permissions": { "admin": [ "acct:BigBlueHat@hypothes.is" ], "read": [ "acct:BigBlueHat@hypothes.is", "group:__world__" ], "update": [ "acct:BigBlueHat@hypothes.is" ], "delete": [ "acct:BigBlueHat@hypothes.is" ] } }
-
-
www.youtube.com www.youtube.comYouTube1
-
- Nov 2021
-
jmeunierp8.github.io jmeunierp8.github.io
- Oct 2021
-
web.hypothes.is web.hypothes.is
-
social annotation
Had I known about Hypothesis at the time of my collaboration with Ilaria Forte, I likely would have suggested this as a tool for documenting the stream of consciousness, collecting stories in the context of the media that people are experiencing on the web.
-
-
www.programmableweb.com www.programmableweb.com
-
Hypothesis REST API
The Hypothesis API integrates annotations into web services. Available to send HTTP requests and JSON responses, it aims to be useful for researchers, scientists, and educators.
-
- Jun 2021
-
material-ui.com material-ui.com
- Aug 2020
-
misinfocon.com misinfocon.com
-
Grundlegender Artikel über die Verwendung von Web Annotations zum fact checking. Deses Konzept wurde von Climate Feedback – A Scientific Reference to Reliable Information on Climate Change umgesetzt. Interessant ist auch die Verbindung der Annotations mit unterschiedlichsten Arten von Metadaten.
-
- Feb 2019
-
arxiv.org arxiv.org
-
Great paper on orphaned annotations in H.
Tags
Annotators
URL
-
- Feb 2017
-
0-quod.lib.umich.edu.mercury.concordia.ca 0-quod.lib.umich.edu.mercury.concordia.ca
-
That was the way I learned
We learn by doing. (And annotations do work on the text version. Neat!)
-
-
0-quod.lib.umich.edu.mercury.concordia.ca 0-quod.lib.umich.edu.mercury.concordia.ca
-
»
Didn’t expect to find [h] embedded here. Problem is, it doesn’t allow for annotations of the actual content.
-