What it does
- this fast.
What to expect:
> Because we’re parsing a web page, and not reading information from a database, the retrieval process is certainly not perfect, but I believe it’s good enough to often be useful, saving the time and potential inaccuracies associated with manually typing in a particular quotation.
{:quote-from:notenik.app||article|Importing a Quotation from WikiQuote|https://notenik.app|https://notenik.app/adventures/importing-a-quotation-from-wikiquote.html}
The logic:
> $SELECTION
{:quote-from:$AUTHOR_OR_WEBSITE_OR_NIL|$YEAR_OR_NIL|article|$WEB_PAGE_TITLE|$ROOT_URL|$PAGE_URL}
- Where if the value is
NILit returns an empty string. - I chose
articleas a placeholder but you can change that to whatever you want
The code
javascript:(function(){function escapeMarkdown(text){return text.replace(/^/gm,'> ').replace(/`/g,'\\`')}function extractAuthor(){const authorMeta=document.querySelector('meta[name="author"], meta[property="article:author"], meta[name="twitter:creator"], meta[property="og:article:author"]');if(authorMeta&&authorMeta.content){return authorMeta.content.trim()}const authorSelectors=['.author-name','.by-author','.author','.byline','[rel="author"]','[itemprop="author"]','.post-author','.entry-author','.article-author','.content-author'];for(const selector of authorSelectors){const element=document.querySelector(selector);if(element){const text=element.textContent.trim();return text.replace(/^(by|written by|author:)\s*/i,'').trim()}}return ''}function extractYear(){const dateMeta=document.querySelector('meta[property="article:published_time"], meta[name="publish_date"], meta[name="publication_date"], meta[property="og:article:published_time"], time[datetime], [itemprop="datePublished"]');if(dateMeta){const dateContent=dateMeta.content||dateMeta.getAttribute('datetime')||dateMeta.textContent;if(dateContent){const yearMatch=dateContent.match(/(\d{4})/);if(yearMatch){return yearMatch[1]}}}const urlYearMatch=location.href.match(/\/(\d{4})\//);if(urlYearMatch){const year=parseInt(urlYearMatch[1]);if(year>=1990&&year<=new Date().getFullYear()){return urlYearMatch[1]}}const dateSelectors=['.post-date','.entry-date','.publish-date','.article-date','.date'];for(const selector of dateSelectors){const element=document.querySelector(selector);if(element){const yearMatch=element.textContent.match(/(\d{4})/);if(yearMatch){const year=parseInt(yearMatch[1]);if(year>=1990&&year<=new Date().getFullYear()){return yearMatch[1]}}}}return ''}function getWebsiteName(){const ogSiteName=document.querySelector('meta[property="og:site_name"]');if(ogSiteName&&ogSiteName.content){return ogSiteName.content.trim()}const appName=document.querySelector('meta[name="application-name"]');if(appName&&appName.content){return appName.content.trim()}return location.hostname.replace(/^www\./,'')}function getRootUrl(){return location.protocol+'//'+location.hostname}function cleanTitle(title){return title.replace(/\s*[\|–—-]\s*.*$/,'').trim()}const selection=window.getSelection().toString().trim();if(!selection){alert('Please select some text first.');return}const author=extractAuthor();const year=extractYear();const websiteName=author||getWebsiteName();const pageTitle=cleanTitle(document.title);const rootUrl=getRootUrl();const pageUrl=location.href;const citation=`{:quote-from:${ websiteName }|${ year }|article|${ pageTitle }|${ rootUrl }|${ pageUrl }}`;const md=`${escapeMarkdown(selection)}\n\n${ citation }`;if(navigator.clipboard&&navigator.clipboard.writeText){navigator.clipboard.writeText(md).then(()=>{const toast=document.createElement('div');toast.textContent='Markdown quote copied!';toast.style.cssText=`
position: fixed;
top: 20px;
right: 20px;
background: #4CAF50;
color: white;
padding: 12px 24px;
border-radius: 4px;
z-index: 999999;
font-family: system-ui, -apple-system, sans-serif;
font-size: 14px;
box-shadow: 0 2px 5px rgba(0,0,0,0.2);
`;document.body.appendChild(toast);setTimeout(()=>document.body.removeChild(toast),2000)},(err)=>{console.error('Copy failed',err);prompt('Copy the Markdown quote manually:',md)})}else{const textarea=document.createElement('textarea');textarea.value=md;textarea.style.cssText='position:absolute;left:-9999px';document.body.appendChild(textarea);textarea.select();try{const successful=document.execCommand('copy');if(successful){alert('Markdown quote copied to clipboard!')}else{throw new Error('Copy command failed')}}catch(err){console.error('Copy failed',err);prompt('Copy the Markdown quote manually:',md)}document.body.removeChild(textarea)}})();
- Full disclosure: I used Claude to generate this Javascript.
You should check out the un-minified code here: Notenik Quote-From Bookmarklet · GitHub.
In practice
- Add to Bookmarks in your Browser
- Or use whatever fancy automated method of your liking
- Select text, click the Bookmark
- You should see a green confirmation window that indicates the selection was successfully copied
- Or you have to copy it manually from a text window
Moving forward
Craftier minds may figure out how to enhance this code to query for indicators to anticipate the Work Type according to semantic hints.
I wonder if there are any other ways we can automate or manipulate the rest of Notenik’s exotic formatting commands.