├── .all-contributorsrc ├── CHANGELOG.md ├── LICENSE ├── README.md └── copy-markdown-url-and-title.js /.all-contributorsrc: -------------------------------------------------------------------------------- 1 | { 2 | "files": [ 3 | "README.md" 4 | ], 5 | "imageSize": 100, 6 | "commit": false, 7 | "commitType": "docs", 8 | "commitConvention": "angular", 9 | "contributors": [ 10 | { 11 | "login": "mattstein", 12 | "name": "Matt Stein", 13 | "avatar_url": "https://avatars.githubusercontent.com/u/2488775?v=4", 14 | "profile": "https://mattstein.com", 15 | "contributions": [ 16 | "doc" 17 | ] 18 | } 19 | ], 20 | "contributorsPerLine": 7, 21 | "skipCi": true, 22 | "repoType": "github", 23 | "repoHost": "https://github.com", 24 | "projectName": "copy-markdown-url-and-title", 25 | "projectOwner": "chodorowicz" 26 | } 27 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | 📆 2024-12-12 2 | - added support for [Zen Browser](https://zen-browser.app/) 3 | 4 | 📆 2023-07-29 5 | version 1.1 6 | - addded support for [Arc](https://arc.net/) 7 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022 Jakub Chodorowicz 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Copy Markdown URL and Title 2 | 3 | [![All Contributors](https://img.shields.io/badge/all_contributors-1-orange.svg?style=flat-square)](#contributors-) 4 | 5 | 6 | - This script is written using JavaScript automation for macOS. 7 | - It copies URL and title from the current browser in a markdown format - `[Title of Page](https://url.of.page.com)`. 8 | - It has [Raycast](https://www.raycast.com/) specific metadata, but you can use it in any application or context where JavaScript automation is supported. 9 | 10 | ## Currently supported browsers: 11 | - Chromium based browsers 12 | - Google Chrome, 13 | - Chromium, 14 | - Brave Browser, 15 | - Opera, 16 | - Vivaldi, 17 | - Microsoft Edge 18 | - Arc 19 | - Safari 20 | - Firefox based browsers 21 | - Firefox integration is the *worst* since Firefox doesn't support direct AppleScript automation, and the script uses System Events and keystrokes in that case. 22 | - Zen Browser 23 | 24 | ## Contributors 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 |
Matt Stein
Matt Stein

📖
36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /copy-markdown-url-and-title.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env osascript -l JavaScript 2 | 3 | // Required parameters: 4 | // @raycast.schemaVersion 1 5 | // @raycast.title Copy Markdown URL and Title 6 | // @raycast.mode silent 7 | // 8 | // Optional parameters: 9 | // @raycast.packageName Copy Markdown URL and Title 10 | // @raycast.icon 🔗 11 | // 12 | // Documentation: 13 | // @raycast.description Copy URL and title from the current browser as markdown. 14 | // @raycast.author Jakub Chodorowicz 15 | // @raycast.authorURL https://github.com/chodorowicz 16 | // script version 1.1 17 | 18 | const systemEvents = Application("System Events"); 19 | const frontProcess = systemEvents.processes.whose({ frontmost: true })[0]; 20 | const appName = frontProcess.displayedName(); 21 | const app = Application.currentApplication(); 22 | app.includeStandardAdditions = true; 23 | 24 | let url = undefined; 25 | let title = undefined; 26 | 27 | const chromiumBrowsers = [ 28 | "Google Chrome", 29 | "Chromium", 30 | "Brave Browser", 31 | "Opera", 32 | "Vivaldi", 33 | ]; 34 | const webkitBrowser = ["Safari", "Webkit"]; 35 | // Arc fails when trying to run JXA automation on it (📆 2023-07-29) 36 | // Firefox based browser also need to use the JXA approach 37 | const theRest = ["Firefox", "Arc", "Zen"]; 38 | 39 | if (chromiumBrowsers.includes(appName)) { 40 | const activeWindow = Application(appName).windows[0]; 41 | const activeTab = activeWindow.activeTab(); 42 | url = activeTab.url(); 43 | title = activeTab.name(); 44 | } 45 | 46 | // Microsoft Edge doesn't work properly with activeWindow.activeTab() 47 | if (appName === "Microsoft Edge") { 48 | const activeWindow = Application(appName).windows[0]; 49 | const activeTabIndex = activeWindow.activeTabIndex() - 1; 50 | const activeTab = activeWindow.tabs[activeTabIndex]; 51 | url = activeTab.url(); 52 | title = activeTab.name(); 53 | } 54 | 55 | if (webkitBrowser.includes(appName)) { 56 | url = Application(appName).documents[0].url(); 57 | title = Application(appName).documents[0].name(); 58 | } 59 | 60 | if (theRest.includes(appName)) { 61 | systemEvents.keystroke("l", { using: "command down" }); 62 | delay(0.2); 63 | systemEvents.keystroke("c", { using: "command down" }); 64 | delay(0.2); 65 | /// escape clear the selection of address bar 66 | systemEvents.keyCode(53); 67 | url = app.theClipboard(); 68 | title = frontProcess 69 | .windows() 70 | .find((window) => window.attributes.byName("AXMain").value() === true) 71 | .attributes.byName("AXTitle") 72 | .value(); 73 | } 74 | 75 | if (title === undefined && url === undefined) { 76 | console.log("Could not copy URL or title."); 77 | } else { 78 | app.setTheClipboardTo(`[${title}](${url})`); 79 | console.log(`Copied URL and title from ${appName}.`); 80 | } 81 | --------------------------------------------------------------------------------