├── .gitignore
├── Blockquote.popclipext
├── Config.plist
├── README.md
├── blockquote.png
└── blockquote.rb
├── BulletList.popclipext
├── Config.plist
├── README.md
├── bulletlist.pl
└── bulletlist.png
├── CHANGELOG.md
├── CheckURLs.popclipext
├── Config.plist
├── PreviewURL.workflow
│ └── Contents
│ │ ├── Info.plist
│ │ ├── QuickLook
│ │ └── Thumbnail.png
│ │ ├── Resources
│ │ ├── background.color
│ │ └── workflowCustomImage.png
│ │ └── document.wflow
├── README.md
├── script.rb
└── urlcheck.png
├── Code.popclipext
├── Config.plist
├── README.md
├── code.png
└── code.rb
├── Comment.popclipext
├── Config.plist
├── README.md
├── comment.png
└── comment.rb
├── CopyCleanLinks.popclipext
├── Config.plist
├── README.md
├── icon.png
└── script.rb
├── CopyPlus.popclipext
├── Config.plist
├── README.md
├── copyplus.png
└── copyplus.sh
├── CopyURLS.popclipext
├── Config.plist
├── README.md
├── icon.png
└── script.rb
├── CriticMarkup.popclipext
├── Config.plist
├── README.md
├── icon.png
└── script.rb
├── DefineAbbr.popclipext
├── Config.plist
├── README.md
└── script.rb
├── Editor.popclipext
├── Config.plist
├── README.md
├── icon.png
└── script.rb
├── FixPoorlyObscuredEmail.popclipext
├── Config.plist
├── README.md
└── script.rb
├── HardWrap.popclipext
├── Config.plist
├── README.md
├── hardwrap.png
└── hardwrap.rb
├── IncrementTemplated.popclipext
├── Config.plist
├── README.md
├── increment.png
└── script.rb
├── LinkCleaner.popclipext
├── Config.plist
├── README.md
├── icon.png
└── script.rb
├── Markdown2Mindmap.popclipext
├── Config.plist
├── README.md
├── md2mm.png
└── md2mm.rb
├── NumberedList.popclipext
├── Config.plist
├── README.md
├── numberlist.pl
└── numberlist.png
├── OpenURLS.popclipext
├── Config.plist
├── README.md
├── openurls.png
└── openurls.rb
├── Outdent.popclipext
├── Config.plist
├── README.md
├── outdent.png
└── outdent.rb
├── PoorText.popclipext
├── Config.plist
├── README.md
├── icon.png
└── script.sh
├── README.md
├── SearchLink.popclipext
├── Config.plist
├── README.md
├── searchlink.png
└── searchlink.rb
├── SkypeCall.popclipext
├── Config.plist
├── README.md
├── skypecall.png
└── skypecall.rb
├── Slugify.popclipext
├── Config.plist
├── README.md
├── hyphen.png
└── slugger.rb
├── Sum.popclipext
├── Config.plist
├── README.md
├── icon.png
└── script.rb
├── Twitterify.popclipext
├── Config.plist
├── README.md
├── icon.png
└── script.rb
├── URLEncode.popclipext
├── Config.plist
├── README.md
└── urlencode.rb
├── VERSION
├── WebMarkdown.popclipext
├── Config.plist
├── README.md
├── download.applescript
└── process.sh
├── Wrappers.popclipext
├── Config.plist
├── README.md
├── script.rb
└── wrapped.png
├── increment.gif
├── markdownify.popclipext
├── Config.plist
├── README.md
└── markdownify.py
├── mise.toml
└── nvUltra.popclipext
├── Config.plist
├── README.md
├── _Signature.plist
├── nvUltra.rb
└── rocket.png
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | build.sh
3 | *.bak
4 | buildnotes.md
5 |
--------------------------------------------------------------------------------
/Blockquote.popclipext/Config.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Actions
6 |
7 |
8 | Image File
9 | blockquote.png
10 | Script Interpreter
11 | /usr/bin/ruby
12 | Shell Script File
13 | blockquote.rb
14 | Title
15 | Quote
16 | After
17 | paste-result
18 | Requirements
19 |
20 | paste
21 |
22 |
23 |
24 | Credits
25 |
26 | Name
27 | Brett Terpstra
28 | Link
29 | http://brettterpstra.com
30 |
31 | Extension Description
32 | Turn indented text into nested Markdown blockquote.
33 | Extension Identifier
34 | com.brettterpstra.popclip.extension.blockquote
35 | Extension Name
36 | Blockquote
37 | Version
38 | 2
39 |
40 |
41 |
--------------------------------------------------------------------------------
/Blockquote.popclipext/README.md:
--------------------------------------------------------------------------------
1 | ### Blockquote
2 |
3 | Turn indented text (or any text) into nested Markdown blockquotes.
4 |
5 | * Clicking adds a ">" for each indentation level in the selected text
6 | * Command-click to decrease quote level
7 | * Command-Option-click key to remove all quoting
8 |
9 | When adding quote levels, multiple line breaks between lines creates separate block quotes (by design). If there's a single blank line between to paragraphs, they'll be joined together as paragraphs within a blockquote. More than one starts a new quote.
10 |
--------------------------------------------------------------------------------
/Blockquote.popclipext/blockquote.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ttscoff/popclipextensions/81a97925c317a804ad731e348c57b3cf7a635b22/Blockquote.popclipext/blockquote.png
--------------------------------------------------------------------------------
/Blockquote.popclipext/blockquote.rb:
--------------------------------------------------------------------------------
1 | #!/usr/bin/ruby
2 |
3 | if ARGV[0] =~ /\-?d(ebug)?/
4 | input = STDIN.read
5 | # ENV['POPCLIP_MODIFIER_FLAGS'] = 1048576.to_s
6 | else
7 | input = ENV['POPCLIP_TEXT']
8 | end
9 |
10 | def trailing_whitespace(input)
11 | out = []
12 | input.reverse.each {|line|
13 | if line =~ /^([\s\t])*$/
14 | out.push("#{$1}")
15 | else
16 | break
17 | end
18 | }
19 | out.reverse.join("\n")
20 | end
21 |
22 | def quote_block(input)
23 | while input[-1] =~ /^\s*$/
24 | input.pop
25 | end
26 | output = ""
27 | input.each do |line|
28 | quote = ">"
29 | tabs = line.match(/^([\s\t]+)/)
30 |
31 | unless tabs.nil?
32 | count = tabs[1].gsub(/\t/," ").length / 4
33 | count.times do
34 | quote += " >"
35 | end
36 | end
37 |
38 | # don't quote reference definitions
39 | unless line =~ /^\s*\[.*?\]: .*/
40 | output += line =~ /^\s*$/ ? "#{quote}\n" : "#{quote} #{line.sub(/^[\s\t]*/,'')}\n"
41 | else
42 | output += line
43 | end
44 | end
45 | output
46 | end
47 |
48 | trail_match = input.match(/(?i-m)[\s\n\t]++$/)
49 | trailing = trail_match.nil? ? "" : trail_match[0]
50 |
51 | input = input.split("\n")
52 | output = []
53 |
54 | case ENV['POPCLIP_MODIFIER_FLAGS'].to_i
55 | when 1048576 # Command (remove one level of blockquoting)
56 | input.each do |line|
57 | output.push(line.sub(/^(\s*)>\s*/,'\1'))
58 | end
59 | when 1572864 # Option-Command (remove all blockquoting)
60 | input.each do |line|
61 | output.push(line.sub(/^(\s*)(>\s*)*/,'\1'))
62 | end
63 | else # Increase quote level by one
64 | block = []
65 | skipping = false
66 | input.each_with_index do |line, i|
67 | if line =~ /\S/ && skipping
68 | skipping = false
69 | block = [line]
70 | elsif line =~ /^\s*$/ && (input[i+1] =~ /^\s*$/ || i == input.length - 1) && !skipping
71 | skipping = true
72 | output.push(quote_block(block)) unless block.empty?
73 | block = []
74 | elsif line =~ /^\s*$/ && skipping
75 | next
76 | else
77 | block.push(line)
78 | end
79 | end
80 | output.push(quote_block(block)) unless block.empty?
81 | end
82 |
83 | print output.join("\n") + trailing #.sub(/\n$/s,'')
84 |
85 |
--------------------------------------------------------------------------------
/BulletList.popclipext/Config.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Actions
6 |
7 |
8 | Image File
9 | bulletlist.png
10 | Script Interpreter
11 | /usr/bin/perl
12 | Shell Script File
13 | bulletlist.pl
14 | Title
15 | Bullet List
16 | After
17 | paste-result
18 | Requirements
19 |
20 | paste
21 |
22 |
23 |
24 | Options
25 |
26 |
27 | Option Identifier
28 | bulletprefix
29 | Option Type
30 | multiple
31 | Option Default Value
32 | *
33 | Option Label
34 | Bullet Prefix
35 | Option Values
36 |
37 | *
38 | +
39 | -
40 |
41 |
42 |
43 | Credits
44 |
45 | Name
46 | Brett Terpstra
47 | Link
48 | http://brettterpstra.com
49 |
50 | Extension Description
51 | Turn lines into a Markdown bullet list. Hold option for numbered list.
52 | Extension Identifier
53 | com.brettterpstra.popclip.extension.bulletlist
54 | Extension Name
55 | BulletList
56 | Version
57 | 2
58 |
59 |
60 |
--------------------------------------------------------------------------------
/BulletList.popclipext/README.md:
--------------------------------------------------------------------------------
1 | ### BulletList
2 |
3 | PopClip extension to turn lines of text into Markdown bullet items. Indentation is handled as nested lists and existing markers are overwritten (numbered list becomes bullet list).
4 |
5 | #### Numbered lists
6 |
7 | Holding Option (⌥) while clicking the button for the extension in the PopClip bar will create/update a numbered list instead. When the list is already a numbered list, it will be re-numbered to fix any gaps or out-of-order numbering within nest levels.
8 |
9 | #### Clear list formatting
10 |
11 | Holding Command (⌘) while clicking will remove all list prefixes.
12 |
13 | #### Bullet format
14 |
15 | When you install this extension, you'll get an options page where you can select the type of bullet you prefer for unordered lists. This can be accessed again later by clicking the pencil button at the bottom of the list, then clicking the gear button next to the BulletList extension.
16 |
--------------------------------------------------------------------------------
/BulletList.popclipext/bulletlist.pl:
--------------------------------------------------------------------------------
1 | #!/usr/bin/perl
2 |
3 | # ThisService Perl service script example
4 | # Service type: Filter.
5 | # Revision 1.
6 |
7 | # Perl practices:
8 | # Enables strict mode, requiring that variables are first declared with 'my'.
9 | # This, along with specifying '-w' in the magic first line, is widely
10 | # considered good Perl practice.
11 | use strict;
12 |
13 | # Unicode considerations:
14 | # '-CIO' in the magic first line enables Perl to consider STDIN to always
15 | # contain UTF-8, and to always output to STDOUT in UTF-8.
16 |
17 | my $result = "";
18 | my %last_marker = (); # Store last marker used for each list depth
19 | $last_marker{0} = "";
20 |
21 | my $last_leading_space = "";
22 | my $g_tab_width = 4;
23 | my $g_list_level = 0;
24 |
25 | my $line;
26 | my $marker;
27 | my $item;
28 | my $leading_space;
29 | my $prefix = $ENV{"POPCLIP_OPTION_BULLETPREFIX"};
30 |
31 | my @resultLines = split /\n/, $ENV{"POPCLIP_TEXT"};
32 | foreach my $line (@resultLines) {
33 | next if $line =~ /^[\s\t]*$/;
34 | if ( $ENV{"POPCLIP_MODIFIER_FLAGS"} == 524288 ) { # Option, use numbered list
35 | $line =~ s/^([ \t]*)(\d+\. |[\*\+\-] )?/${1}1. /;
36 | } elsif ( $ENV{"POPCLIP_MODIFIER_FLAGS"} == 1572864 ) { # Command-option, clear list
37 | $line =~ s/^([ \t]*)(\d+\. |[\*\+\-] )?\s*(.*)/${1}${3}\n\n/;
38 | } else {
39 | $line =~ s/^([ \t]*)(\d+\. |[\*\+\-] )?/${1}$prefix /; # None, use bullet list
40 | }
41 | $line =~ /^([ \t]*)([\*\+\-]|\d+\.)(\.?\s*)(.*)/;
42 | $leading_space = $1;
43 | $marker = $2;
44 | $item = " " . $4;
45 |
46 | $leading_space =~ s/\t/ /g; # Convert tabs to spaces
47 |
48 | if ( $line !~ /^([ \t]*)([\*\+\-]|\d+\.)/) {
49 | #$result .= "a";
50 | # not a list line
51 | $result .= $line;
52 | $marker = $last_marker{$g_list_level};
53 | } elsif (length($leading_space) > length($last_leading_space)+3) {
54 | # New list level
55 | #$result .= "b";
56 | $g_list_level++;
57 |
58 | $marker =~ s{
59 | (\d+)
60 | }{
61 | # Reset count
62 | "1";
63 | }ex;
64 |
65 | $last_leading_space = $leading_space;
66 |
67 | $result .= "\t" x $g_list_level;
68 | $result .= $marker . $item . "\n";
69 | } elsif (length($leading_space)+3 < length($last_leading_space)) {
70 | #$result .= "c";
71 | # back to prior list level
72 | $g_list_level = length($leading_space) / 4;
73 |
74 | # update marker
75 | $marker = $last_marker{$g_list_level};
76 | $marker =~ s{
77 | (\d+)
78 | }{
79 | $1+1;
80 | }ex;
81 |
82 | $last_leading_space = $leading_space;
83 |
84 | $result .= "\t" x $g_list_level;
85 | $result .= $marker . $item . "\n";
86 | } else {
87 | # No change in level
88 | #$result .= "d";
89 |
90 | # update marker if it exists
91 | if ($last_marker{$g_list_level} ne "") {
92 | $marker = $last_marker{$g_list_level};
93 | $marker =~ s{
94 | (\d+)
95 | }{
96 | $1+1;
97 | }ex;
98 | }
99 |
100 |
101 | $last_leading_space = $leading_space;
102 |
103 | $result .= "\t" x $g_list_level;
104 | $result .= $marker . $item . "\n";
105 | }
106 |
107 | $last_marker{$g_list_level} = $marker;
108 | }
109 |
110 | $result =~ s/\n$//;
111 | print $result;
112 |
--------------------------------------------------------------------------------
/BulletList.popclipext/bulletlist.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ttscoff/popclipextensions/81a97925c317a804ad731e348c57b3cf7a635b22/BulletList.popclipext/bulletlist.png
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | ### 1.45.5
2 |
3 | 2024-12-18 05:40
4 |
5 | ### 1.45.4
6 |
7 | 2024-12-18 05:38
8 |
9 | ### 1.45.3
10 |
11 | 2024-12-18 05:04
12 |
13 | ### 1.44.8
14 |
15 | 2023-02-06 11:19
16 |
17 | ### 1.44.7
18 |
19 | 2023-02-06 11:14
20 |
21 | #### IMPROVED
22 |
23 | - Allow string arrays in template modifiers for Increment Templated
24 |
25 | ### 1.44.6
26 |
27 | 2023-02-06 11:01
28 |
29 | #### IMPROVED
30 |
31 | - Allow string arrays in template modifiers for Increment Templated
32 |
33 | ### 1.44.5
34 |
35 | 2023-02-06 10:21
36 |
37 | #### IMPROVED
38 |
39 | - Using extension READMEs to generate main README
40 | - Updated READMEs
41 | - Allow more complex mathematical equations with i and x in Increment Templated
42 |
43 | ### 1.44.4
44 |
45 | 2023-01-31 08:07
46 |
47 | #### IMPROVED
48 |
49 | - Using extension READMEs to generate main README
50 | - Updated READMEs
51 |
52 | ### 1.44
53 |
54 | * Fix SearchLink extension
55 |
56 | ### 1.43
57 |
58 | * If SearchLink isn't installed, install it when running the SearchLink extension
59 |
60 | ### 1.42
61 |
62 | * Fix nvUltra extension
63 | * Add SearchLink extension
64 |
65 | ### 1.41
66 |
67 | * Update WebMarkdown to allow for gather installs in /opt/homebrew/bin.
68 |
69 | ### 1.40
70 |
71 | * Remove the popcliphtml2text CLI from WebMarkdown that was causing "malicious software" warnings. Now offers to download and install using the signed and notarized package.
72 |
73 | ### 1.38
74 |
75 | * Fix a couple of bugs and improve output of html2text for WebMarkdown
76 |
77 | ### 1.35
78 |
79 | * Convert WebMarkdown to use Swift-based HTML2Text, avoiding need for Python executable
80 |
81 | ### 1.34
82 |
83 | * Fix for WebMarkdown, change to python3 and update html2text
84 |
85 | ### 1.33
86 |
87 | * Fix for bad option default type in some of the plists.
88 |
89 | ### 1.31
90 |
91 | * Increment Templated updates/fixes
92 |
93 | ### 1.28
94 |
95 | * Add "Increment Templated" extension
96 |
97 | ### 1.27
98 |
99 | * Add "HardWrap" extension
100 |
101 | ### 1.25
102 |
103 | * Replace PreviewURL with CheckURLs
104 | * Allows results from preview navigation to modify selected text
105 | * Better icon
106 |
107 | ### 1.24
108 |
109 | * Updated PreviewURL
110 | * Ignore URLs without http(s) protocol
111 | * Handle multiple URLs
112 | * Center preview pane on display
113 |
114 | ### 1.19 --- 1.23
115 |
116 | * stupid commits because I'm having trouble with the build script. Don't mind me.
117 |
118 | ### 1.18
119 |
120 | * Quick little format stripper (PoorText)
121 |
122 | ### 1.17
123 |
124 | * Added "DefineAbbr" extension
125 |
126 | ### 1.16
127 |
128 | * Updated (rewritten) blockquote extension
129 |
130 | ### 1.15
131 |
132 | * Added "Sum" extension
133 |
134 | ### 1.14
135 |
136 | * Added LinkCleaner and CopyCleanLinks extensions
137 |
138 | ### 1.12
139 |
140 | * Added Twitterify extension.
141 |
142 | ### 1.11
143 |
144 | * Added the WebMarkdown extension.
145 |
146 | ### 1.10
147 |
148 | * Updated OpenURLS
149 | * Better regex for extracting URLs
150 | * Hold down Option to combine lines and fix broken urls
151 | * This can cause issues with full urls on consecutive lines, but is handy for a single broken link.
152 | * Leaves leading space on lines, so urls broken with an indent are still screwed. Ran into too many problems trying to parse around that.
153 |
154 | * Added CopyURLs
155 |
156 | Duplicate of OpenURLs, but copies a plain, newline-separated list to the clipboard
157 |
158 | * Added FixPoorlyObscuredEmails
159 | * Fixes "me AT here DOT com" style email obfuscations
160 | * Hold Option to compose new email for matched addresses
161 |
162 | ### 1.8
163 |
164 | * Blockquote:
165 | * Handle line breaks better
166 | * Command-click to decrease quote level
167 | * Command-Option-click key to remove all quoting
168 | * don't quote reference link definitions
169 | * BulletList: Bullet type configuration options, Command modifier to remove list formatting
170 | * CopyPlus: Option modifier to concatenate strings with no extra whitespace
171 | * Credits block for all extensions
172 | * URLEncode extension (also available at [Pilot Moon](http://pilotmoon.com/popclip/extensions/page/URLEncode))
173 |
174 | ### 1.7
175 |
176 | * Outdent: Command-click to outdent all lines fully
177 | * Too Many Wrappers: Removed Shift-click options as they were breaking stuff.
178 | * CopyPlus: Command-click to add extra linebreak between entries
179 |
--------------------------------------------------------------------------------
/CheckURLs.popclipext/Config.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Actions
6 |
7 |
8 | Image File
9 | urlcheck.png
10 | Script Interpreter
11 | /usr/bin/ruby
12 | Shell Script File
13 | script.rb
14 | Title
15 | Check
16 | Regular Expression
17 | (?si)(.*)?((http|https):\/\/)?[\w\-_]+(\.[\w\-_]+)+([\w\-\.,@?^=%&:/~\+#\(\)_]*[\w\-\@^=%&/~\+#])?(.*)?
18 | After
19 | paste-result
20 | Requirements
21 |
22 | paste
23 |
24 |
25 |
26 | Credits
27 |
28 | Name
29 | Brett Terpstra
30 | Link
31 | http://brettterpstra.com
32 |
33 | Extension Description
34 | Preview and update all URLs in selection.
35 | Extension Identifier
36 | com.brettterpstra.popclip.extension.checkurls
37 | Extension Name
38 | CheckURLs
39 | Version
40 | 2
41 |
42 |
43 |
--------------------------------------------------------------------------------
/CheckURLs.popclipext/PreviewURL.workflow/Contents/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | NSServices
6 |
7 |
8 | NSBackgroundColorName
9 | background
10 | NSBackgroundSystemColorName
11 | systemBlueColor
12 | NSIconName
13 | workflowCustomImage
14 | NSMenuItem
15 |
16 | default
17 | Preview URL
18 |
19 | NSMessage
20 | runWorkflowAsService
21 | NSRequiredContext
22 |
23 | NSTextContent
24 | URL
25 |
26 | NSSendTypes
27 |
28 | public.utf8-plain-text
29 |
30 |
31 |
32 |
33 |
34 |
--------------------------------------------------------------------------------
/CheckURLs.popclipext/PreviewURL.workflow/Contents/QuickLook/Thumbnail.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ttscoff/popclipextensions/81a97925c317a804ad731e348c57b3cf7a635b22/CheckURLs.popclipext/PreviewURL.workflow/Contents/QuickLook/Thumbnail.png
--------------------------------------------------------------------------------
/CheckURLs.popclipext/PreviewURL.workflow/Contents/Resources/background.color:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ttscoff/popclipextensions/81a97925c317a804ad731e348c57b3cf7a635b22/CheckURLs.popclipext/PreviewURL.workflow/Contents/Resources/background.color
--------------------------------------------------------------------------------
/CheckURLs.popclipext/PreviewURL.workflow/Contents/Resources/workflowCustomImage.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ttscoff/popclipextensions/81a97925c317a804ad731e348c57b3cf7a635b22/CheckURLs.popclipext/PreviewURL.workflow/Contents/Resources/workflowCustomImage.png
--------------------------------------------------------------------------------
/CheckURLs.popclipext/PreviewURL.workflow/Contents/document.wflow:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | AMApplicationBuild
6 | 492
7 | AMApplicationVersion
8 | 2.10
9 | AMDocumentVersion
10 | 2
11 | actions
12 |
13 |
14 | action
15 |
16 | AMAccepts
17 |
18 | Container
19 | List
20 | Optional
21 |
22 | Types
23 |
24 | com.apple.cocoa.url
25 |
26 |
27 | AMActionVersion
28 | 2.0.1
29 | AMApplication
30 |
31 | Safari
32 |
33 | AMParameterProperties
34 |
35 | outputTypeTag
36 |
37 | positionTag
38 |
39 | sizeFormatTag
40 |
41 | targetSizeX
42 |
43 | targetSizeY
44 |
45 | userAgentTag
46 |
47 |
48 | AMProvides
49 |
50 | Container
51 | List
52 | Types
53 |
54 | com.apple.cocoa.string
55 |
56 |
57 | ActionBundlePath
58 | /System/Library/Automator/Website Popup.action
59 | ActionName
60 | Website Popup
61 | ActionParameters
62 |
63 | outputTypeTag
64 | 3
65 | positionTag
66 | 0
67 | sizeFormatTag
68 | 99
69 | targetSizeX
70 | 600
71 | targetSizeY
72 | 800
73 | userAgentTag
74 | 0
75 |
76 | BundleIdentifier
77 | com.apple.Automator.WebsitePopup
78 | CFBundleVersion
79 | 2.0.1
80 | CanShowSelectedItemsWhenRun
81 |
82 | CanShowWhenRun
83 |
84 | Category
85 |
86 | AMCategoryInternet
87 |
88 | Class Name
89 | AMWebsitePoppupAction
90 | InputUUID
91 | 8BAAF496-518D-4618-867D-6EBE459A9513
92 | Keywords
93 |
94 | OutputUUID
95 | 9BBAA1F5-1D86-4B6F-A699-2CF8751706F9
96 | UUID
97 | 09D90FBD-1B77-4B38-8148-E6B20C9D35EB
98 | UnlocalizedApplications
99 |
100 | Safari
101 |
102 | arguments
103 |
104 | 0
105 |
106 | default value
107 | 0
108 | name
109 | userAgentTag
110 | required
111 | 0
112 | type
113 | 0
114 | uuid
115 | 0
116 |
117 | 1
118 |
119 | default value
120 | 0
121 | name
122 | positionTag
123 | required
124 | 0
125 | type
126 | 0
127 | uuid
128 | 1
129 |
130 | 2
131 |
132 | default value
133 | 0
134 | name
135 | sizeFormatTag
136 | required
137 | 0
138 | type
139 | 0
140 | uuid
141 | 2
142 |
143 | 3
144 |
145 | default value
146 | 0.0
147 | name
148 | targetSizeY
149 | required
150 | 0
151 | type
152 | 0
153 | uuid
154 | 3
155 |
156 | 4
157 |
158 | default value
159 | 0
160 | name
161 | outputTypeTag
162 | required
163 | 0
164 | type
165 | 0
166 | uuid
167 | 4
168 |
169 | 5
170 |
171 | default value
172 | 0.0
173 | name
174 | targetSizeX
175 | required
176 | 0
177 | type
178 | 0
179 | uuid
180 | 5
181 |
182 |
183 | isViewVisible
184 |
185 | location
186 | 502.500000:322.000000
187 | nibPath
188 | /System/Library/Automator/Website Popup.action/Contents/Resources/Base.lproj/main.nib
189 |
190 | isViewVisible
191 |
192 |
193 |
194 | connectors
195 |
196 | workflowMetaData
197 |
198 | applicationBundleIDsByPath
199 |
200 | applicationPaths
201 |
202 | backgroundColor
203 |
204 | YnBsaXN0MDDUAQIDBAUGBwpYJHZlcnNpb25ZJGFyY2hpdmVyVCR0b3BYJG9i
205 | amVjdHMSAAGGoF8QD05TS2V5ZWRBcmNoaXZlctEICVRyb290gAGpCwwXGBki
206 | KCkwVSRudWxs1Q0ODxAREhMUFRZWJGNsYXNzW05TQ29sb3JOYW1lXE5TQ29s
207 | b3JTcGFjZV1OU0NhdGFsb2dOYW1lV05TQ29sb3KACIADEAaAAoAEVlN5c3Rl
208 | bV8QD3N5c3RlbUJsdWVDb2xvctUaGw8cDR0eHyASXE5TQ29tcG9uZW50c1VO
209 | U1JHQl8QEk5TQ3VzdG9tQ29sb3JTcGFjZUcwIDAgMSAxTxARMCAwIDAuOTk4
210 | MTg4OTcyNQAQAYAFgAjTIyQNJSYnVE5TSURVTlNJQ0MQB4AGgAdPEQxIAAAM
211 | SExpbm8CEAAAbW50clJHQiBYWVogB84AAgAJAAYAMQAAYWNzcE1TRlQAAAAA
212 | SUVDIHNSR0IAAAAAAAAAAAAAAAAAAPbWAAEAAAAA0y1IUCAgAAAAAAAAAAAA
213 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAARY3BydAAA
214 | AVAAAAAzZGVzYwAAAYQAAABsd3RwdAAAAfAAAAAUYmtwdAAAAgQAAAAUclhZ
215 | WgAAAhgAAAAUZ1hZWgAAAiwAAAAUYlhZWgAAAkAAAAAUZG1uZAAAAlQAAABw
216 | ZG1kZAAAAsQAAACIdnVlZAAAA0wAAACGdmlldwAAA9QAAAAkbHVtaQAAA/gA
217 | AAAUbWVhcwAABAwAAAAkdGVjaAAABDAAAAAMclRSQwAABDwAAAgMZ1RSQwAA
218 | BDwAAAgMYlRSQwAABDwAAAgMdGV4dAAAAABDb3B5cmlnaHQgKGMpIDE5OTgg
219 | SGV3bGV0dC1QYWNrYXJkIENvbXBhbnkAAGRlc2MAAAAAAAAAEnNSR0IgSUVD
220 | NjE5NjYtMi4xAAAAAAAAAAAAAAASc1JHQiBJRUM2MTk2Ni0yLjEAAAAAAAAA
221 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFhZ
222 | WiAAAAAAAADzUQABAAAAARbMWFlaIAAAAAAAAAAAAAAAAAAAAABYWVogAAAA
223 | AAAAb6IAADj1AAADkFhZWiAAAAAAAABimQAAt4UAABjaWFlaIAAAAAAAACSg
224 | AAAPhAAAts9kZXNjAAAAAAAAABZJRUMgaHR0cDovL3d3dy5pZWMuY2gAAAAA
225 | AAAAAAAAABZJRUMgaHR0cDovL3d3dy5pZWMuY2gAAAAAAAAAAAAAAAAAAAAA
226 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAZGVzYwAAAAAAAAAuSUVD
227 | IDYxOTY2LTIuMSBEZWZhdWx0IFJHQiBjb2xvdXIgc3BhY2UgLSBzUkdCAAAA
228 | AAAAAAAAAAAuSUVDIDYxOTY2LTIuMSBEZWZhdWx0IFJHQiBjb2xvdXIgc3Bh
229 | Y2UgLSBzUkdCAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGRlc2MAAAAAAAAALFJl
230 | ZmVyZW5jZSBWaWV3aW5nIENvbmRpdGlvbiBpbiBJRUM2MTk2Ni0yLjEAAAAA
231 | AAAAAAAAACxSZWZlcmVuY2UgVmlld2luZyBDb25kaXRpb24gaW4gSUVDNjE5
232 | NjYtMi4xAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB2aWV3AAAAAAATpP4A
233 | FF8uABDPFAAD7cwABBMLAANcngAAAAFYWVogAAAAAABMCVYAUAAAAFcf521l
234 | YXMAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAKPAAAAAnNpZyAAAAAAQ1JU
235 | IGN1cnYAAAAAAAAEAAAAAAUACgAPABQAGQAeACMAKAAtADIANwA7AEAARQBK
236 | AE8AVABZAF4AYwBoAG0AcgB3AHwAgQCGAIsAkACVAJoAnwCkAKkArgCyALcA
237 | vADBAMYAywDQANUA2wDgAOUA6wDwAPYA+wEBAQcBDQETARkBHwElASsBMgE4
238 | AT4BRQFMAVIBWQFgAWcBbgF1AXwBgwGLAZIBmgGhAakBsQG5AcEByQHRAdkB
239 | 4QHpAfIB+gIDAgwCFAIdAiYCLwI4AkECSwJUAl0CZwJxAnoChAKOApgCogKs
240 | ArYCwQLLAtUC4ALrAvUDAAMLAxYDIQMtAzgDQwNPA1oDZgNyA34DigOWA6ID
241 | rgO6A8cD0wPgA+wD+QQGBBMEIAQtBDsESARVBGMEcQR+BIwEmgSoBLYExATT
242 | BOEE8AT+BQ0FHAUrBToFSQVYBWcFdwWGBZYFpgW1BcUF1QXlBfYGBgYWBicG
243 | NwZIBlkGagZ7BowGnQavBsAG0QbjBvUHBwcZBysHPQdPB2EHdAeGB5kHrAe/
244 | B9IH5Qf4CAsIHwgyCEYIWghuCIIIlgiqCL4I0gjnCPsJEAklCToJTwlkCXkJ
245 | jwmkCboJzwnlCfsKEQonCj0KVApqCoEKmAquCsUK3ArzCwsLIgs5C1ELaQuA
246 | C5gLsAvIC+EL+QwSDCoMQwxcDHUMjgynDMAM2QzzDQ0NJg1ADVoNdA2ODakN
247 | ww3eDfgOEw4uDkkOZA5/DpsOtg7SDu4PCQ8lD0EPXg96D5YPsw/PD+wQCRAm
248 | EEMQYRB+EJsQuRDXEPURExExEU8RbRGMEaoRyRHoEgcSJhJFEmQShBKjEsMS
249 | 4xMDEyMTQxNjE4MTpBPFE+UUBhQnFEkUahSLFK0UzhTwFRIVNBVWFXgVmxW9
250 | FeAWAxYmFkkWbBaPFrIW1hb6Fx0XQRdlF4kXrhfSF/cYGxhAGGUYihivGNUY
251 | +hkgGUUZaxmRGbcZ3RoEGioaURp3Gp4axRrsGxQbOxtjG4obshvaHAIcKhxS
252 | HHscoxzMHPUdHh1HHXAdmR3DHeweFh5AHmoelB6+HukfEx8+H2kflB+/H+og
253 | FSBBIGwgmCDEIPAhHCFIIXUhoSHOIfsiJyJVIoIiryLdIwojOCNmI5QjwiPw
254 | JB8kTSR8JKsk2iUJJTglaCWXJccl9yYnJlcmhya3JugnGCdJJ3onqyfcKA0o
255 | PyhxKKIo1CkGKTgpaymdKdAqAio1KmgqmyrPKwIrNitpK50r0SwFLDksbiyi
256 | LNctDC1BLXYtqy3hLhYuTC6CLrcu7i8kL1ovkS/HL/4wNTBsMKQw2zESMUox
257 | gjG6MfIyKjJjMpsy1DMNM0YzfzO4M/E0KzRlNJ402DUTNU01hzXCNf02NzZy
258 | Nq426TckN2A3nDfXOBQ4UDiMOMg5BTlCOX85vDn5OjY6dDqyOu87LTtrO6o7
259 | 6DwnPGU8pDzjPSI9YT2hPeA+ID5gPqA+4D8hP2E/oj/iQCNAZECmQOdBKUFq
260 | QaxB7kIwQnJCtUL3QzpDfUPARANER0SKRM5FEkVVRZpF3kYiRmdGq0bwRzVH
261 | e0fASAVIS0iRSNdJHUljSalJ8Eo3Sn1KxEsMS1NLmkviTCpMcky6TQJNSk2T
262 | TdxOJU5uTrdPAE9JT5NP3VAnUHFQu1EGUVBRm1HmUjFSfFLHUxNTX1OqU/ZU
263 | QlSPVNtVKFV1VcJWD1ZcVqlW91dEV5JX4FgvWH1Yy1kaWWlZuFoHWlZaplr1
264 | W0VblVvlXDVchlzWXSddeF3JXhpebF69Xw9fYV+zYAVgV2CqYPxhT2GiYfVi
265 | SWKcYvBjQ2OXY+tkQGSUZOllPWWSZedmPWaSZuhnPWeTZ+loP2iWaOxpQ2ma
266 | afFqSGqfavdrT2una/9sV2yvbQhtYG25bhJua27Ebx5veG/RcCtwhnDgcTpx
267 | lXHwcktypnMBc11zuHQUdHB0zHUodYV14XY+dpt2+HdWd7N4EXhueMx5KnmJ
268 | eed6RnqlewR7Y3vCfCF8gXzhfUF9oX4BfmJ+wn8jf4R/5YBHgKiBCoFrgc2C
269 | MIKSgvSDV4O6hB2EgITjhUeFq4YOhnKG14c7h5+IBIhpiM6JM4mZif6KZIrK
270 | izCLlov8jGOMyo0xjZiN/45mjs6PNo+ekAaQbpDWkT+RqJIRknqS45NNk7aU
271 | IJSKlPSVX5XJljSWn5cKl3WX4JhMmLiZJJmQmfyaaJrVm0Kbr5wcnImc951k
272 | ndKeQJ6unx2fi5/6oGmg2KFHobaiJqKWowajdqPmpFakx6U4pammGqaLpv2n
273 | bqfgqFKoxKk3qamqHKqPqwKrdavprFys0K1ErbiuLa6hrxavi7AAsHWw6rFg
274 | sdayS7LCszizrrQltJy1E7WKtgG2ebbwt2i34LhZuNG5SrnCuju6tbsuu6e8
275 | IbybvRW9j74KvoS+/796v/XAcMDswWfB48JfwtvDWMPUxFHEzsVLxcjGRsbD
276 | x0HHv8g9yLzJOsm5yjjKt8s2y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7S
277 | P9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp22vvbgNwF3IrdEN2W
278 | 3hzeot8p36/gNuC94UThzOJT4tvjY+Pr5HPk/OWE5g3mlucf56noMui86Ubp
279 | 0Opb6uXrcOv77IbtEe2c7ijutO9A78zwWPDl8XLx//KM8xnzp/Q09ML1UPXe
280 | 9m32+/eK+Bn4qPk4+cf6V/rn+3f8B/yY/Sn9uv5L/tz/bf//0iorLC1aJGNs
281 | YXNzbmFtZVgkY2xhc3Nlc1xOU0NvbG9yU3BhY2WiLi9cTlNDb2xvclNwYWNl
282 | WE5TT2JqZWN00iorMTJXTlNDb2xvcqIxLwAIABEAGgAkACkAMgA3AEkATABR
283 | AFMAXQBjAG4AdQCBAI4AnACkAKYAqACqAKwArgC1AMcA0gDfAOUA+gECARYB
284 | GAEaARwBIwEoAS4BMAEyATQNgA2FDZANmQ2mDakNtg2/DcQNzAAAAAAAAAIB
285 | AAAAAAAAADMAAAAAAAAAAAAAAAAAAA3P
286 |
287 | backgroundColorName
288 | systemBlueColor
289 | customImageFileData
290 |
291 | iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAAXNSR0IArs4c
292 | 6QAABI9JREFUWAnNlnuIlUUYh7dMc71kambe2uMlWUOXMkpjDStsQ1qoJBJK
293 | MUjKcMHIMvonoiAwCoMKukBE/2iEQXfFSxt4KcOkwjYzcVdTy1XTKMu0tuc5
294 | fXOaM37Hdq0/+sGz3zvvO998M++8M2e7VZ2+uvNqNXSDE6c7zBldeHEofadA
295 | PYyGYdAbfoN22AWbYC20wH+m8Yz0AuwBP7ICjsEOmAefQAe8BdvgALwLDfCv
296 | 1Je3H4dDsA5mwSC4C/zIJFBmow0egT4wDV6DH7JnDc8uq8AbzeCq/bD7rcbC
297 | YZhvI9KN2D/D1Mh3FfZHYNauifz/aI6ix1Zw1SOj3tbLG7AaLLxUr+BwO3pG
298 | gV7Ybt8RuD7yVzT7EdkIzdAflB9WrsK0htTrD2BWFWA/3AHKWNASDGOXBkd4
299 | xp30PQ0LYDu4z2eBOgEjYAhshvQ9XFV/QB38AhZjeFe/9mXgllwHP0FR8UAe
300 | r/fgOXC2YQArfDjcA07Q2JmQyn6m/yFYDp9B6Ock1APgGIttxHIib8LbsTOy
301 | 52B/AXl7H3Urmqv4+0TqzNpNPHfD4DRei+MgTEsDWft1nhZTZ7SQTq6+R07n
302 | /vha4e4QCylqwNEOG0IgeprWi2F95DuVaRFbK9ZMKov4HbgFitsfJuCZ/RiO
303 | QqrzcZwLLWmgQnsnfq/nQoX4Svxm3HGLRWKxjQHPcJ683RywLS+Y4/P0/Aim
304 | O09ujwuvMejHe2d4PAZAXGhWrx37wYPg8QlZK6YwaXfQdu/94ZoHEyHcovY3
305 | fg6cl1GcgJNw0NHg/R8Gxiy+4MerYTIcgzhOs0zhI9aSC7kC9EmYOGbV+/CN
306 | hnJGNm6zkaMJ+FqhAF2RqxwFHrk4q06mJGflj8hhyKtaO4Yb0crujGbSaTV8
307 | CmZiM3wIHj23x20oyQn8DtvgkpK33HACMq7cfVLLrVoGL4JX+VywrmbBOngU
308 | PAHD4SQ5O7fB7cjTUpwv5QUyn4XmZfU1eOerRngGbreBLgKPullxsmWyAF3l
309 | 9DLv3407MT0+Fmye5uA8AnVZsImnR9Fic9zFoIbBbnjYRipXsAauhCkR9dh+
310 | wDqZDXHck2HWNsKToMzG5/CYDWQG9oFHXDm5HeDlViYH+xUsyr3wfYQDGDsO
311 | 30X+XdgzwOdUUFZ5I4wAU+0PkzXWB9RYcIxJNlI9j+NbsCAvhEKGgzlzX5wI
312 | NVAAU+qeH4BaiOUK3XNj3v1BXsGt0Bgc8XMQja2wDFxJLFO9He6LndhjoB0u
313 | T/xO0m27OfG7MDN8deIvNV2R/3S8DD1L3r+MBTwsIicaVI3RAvcGR/YczHMt
314 | jE/8N9F2S81eRdUT2QMrYGTUyyx8BU9FPk3PuIUVCk2ffT2GrjioB8Z6eDU4
315 | TvUcR7AZTJerGwjqBvDIxUVkzK1bDn1BnQ3zwStZ+fFnwTryTuiUetHrfrAw
316 | d8ISaIA1sAniC6WOttW+BW4FU+xHLbrp4Ha4tddCl3UBbzTBB2ANHIQOWASx
317 | /Bn2JLl9TtoJtYGrXgq1UKa00suCFRoeSSvcSZl2CzCVfSw+V38IvgRr5P+n
318 | PwGMsOq1VPo9GQAAAABJRU5ErkJggg==
319 |
320 | customImageFileExtension
321 | png
322 | inputTypeIdentifier
323 | com.apple.Automator.text.url
324 | outputTypeIdentifier
325 | com.apple.Automator.nothing
326 | presentationMode
327 | 11
328 | processesInput
329 | 1
330 | serviceInputTypeIdentifier
331 | com.apple.Automator.text.url
332 | serviceOutputTypeIdentifier
333 | com.apple.Automator.nothing
334 | serviceProcessesInput
335 | 1
336 | useAutomaticInputType
337 | 1
338 | workflowTypeIdentifier
339 | com.apple.Automator.servicesMenu
340 |
341 |
342 |
343 |
--------------------------------------------------------------------------------
/CheckURLs.popclipext/README.md:
--------------------------------------------------------------------------------
1 | ### CheckURLs
2 |
3 | PopClip extension to show a popup preview for each URL in selected text. Used for confirming the output of scripts like SearchLink without switching to the browser.
4 |
5 | Links are shown sequentially in the order they're found. If a URL is changed by following links in the preview and pressing "OK", the selected text will be updated with the final URL. Because of this, duplicate links in the text are all previewed so they can be modified individually.
6 |
--------------------------------------------------------------------------------
/CheckURLs.popclipext/script.rb:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env ruby
2 | debug = ARGV[0] =~ /(debug|-?d)/ ? true : false
3 |
4 | unless debug
5 | input = ENV['POPCLIP_TEXT']
6 | else
7 | input =</dev/null}.strip
29 | if new_url && new_url.length > 0
30 | output.sub!(/#{url}/,new_url)
31 | end
32 | end
33 | }
34 | print output
35 |
36 |
--------------------------------------------------------------------------------
/CheckURLs.popclipext/urlcheck.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ttscoff/popclipextensions/81a97925c317a804ad731e348c57b3cf7a635b22/CheckURLs.popclipext/urlcheck.png
--------------------------------------------------------------------------------
/Code.popclipext/Config.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Actions
6 |
7 |
8 | Image File
9 | code.png
10 | Script Interpreter
11 | /usr/bin/ruby
12 | Shell Script File
13 | code.rb
14 | Title
15 | <>
16 | After
17 | paste-result
18 | Requirements
19 |
20 | paste
21 |
22 |
23 |
24 | Credits
25 |
26 | Name
27 | Brett Terpstra
28 | Link
29 | http://brettterpstra.com
30 |
31 | Extension Description
32 | Convert to Markdown inline code or code block.
33 | Extension Identifier
34 | com.brettterpstra.popclip.extension.code
35 | Extension Name
36 | Code
37 | Version
38 | 2
39 |
40 |
41 |
--------------------------------------------------------------------------------
/Code.popclipext/README.md:
--------------------------------------------------------------------------------
1 | ### Code
2 |
3 | Turn selected text into Markdown inline code or a code block. This extension "toggles," so if the selection already contains code syntax (inline code or fenced code block) the syntax is removed.
4 |
5 | Detects whether there are multiple lines:
6 |
7 | * if not, it surrounds the input with single backticks
8 | * if so, it wraps the block in triple backticks (fenced)
9 |
10 | When creating an inline code block, it will also detect whitespace at the beginning and end of the selection and make sure that it's excluded from the surrounding backticks.
11 |
--------------------------------------------------------------------------------
/Code.popclipext/code.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ttscoff/popclipextensions/81a97925c317a804ad731e348c57b3cf7a635b22/Code.popclipext/code.png
--------------------------------------------------------------------------------
/Code.popclipext/code.rb:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env ruby
2 |
3 | input = ENV['POPCLIP_TEXT']
4 |
5 | if input =~ /(`+).*?\1/m
6 | print input.gsub(/(`+)\n?(.*?)\n?\1/m, '\2')
7 | else
8 | if input.split("\n").length > 1
9 | # output = ""
10 | # input.split("\n").each {|line|
11 | # output += "\t#{line}\n"
12 | # }
13 | # print output.sub(/\n$/s,'')
14 | ## Switching to using fenced code blocks
15 | print "```\n#{input}\n```\n"
16 | else
17 | head = input =~ /^(\s+)/ ? $1 : ''
18 | tail = input =~ /(\s+)$/ ? $1 : ''
19 | print "#{head}`#{input.strip}`#{tail}"
20 | end
21 | end
22 |
--------------------------------------------------------------------------------
/Comment.popclipext/Config.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Actions
6 |
7 |
8 | Image File
9 | comment.png
10 | Script Interpreter
11 | /usr/bin/ruby
12 | Shell Script File
13 | comment.rb
14 | Title
15 | <!--
16 | After
17 | paste-result
18 | Requirements
19 |
20 | paste
21 |
22 |
23 |
24 | Credits
25 |
26 | Name
27 | Brett Terpstra
28 | Link
29 | http://brettterpstra.com
30 |
31 | Extension Description
32 | Turn selected text into an HTML/code comment.
33 | Extension Identifier
34 | com.brettterpstra.popclip.extension.comment
35 | Extension Name
36 | Comment
37 | Version
38 | 2
39 |
40 |
41 |
--------------------------------------------------------------------------------
/Comment.popclipext/README.md:
--------------------------------------------------------------------------------
1 | ### Comment
2 |
3 | Turn selected text into an HTML or code comment.
4 |
5 | By default, it surrounds selected text with `` style comment tags. Hold various modifier keys to insert other types of comment markers:
6 |
7 | * **Option**: CSS Comment (`/* block of text */`)
8 | * **Command**: Hash Comment (`# before each line`)
9 | * **Command-Option**: Slash comment (`// before each line`)
10 |
--------------------------------------------------------------------------------
/Comment.popclipext/comment.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ttscoff/popclipextensions/81a97925c317a804ad731e348c57b3cf7a635b22/Comment.popclipext/comment.png
--------------------------------------------------------------------------------
/Comment.popclipext/comment.rb:
--------------------------------------------------------------------------------
1 | #!/usr/bin/ruby
2 |
3 | input = ENV['POPCLIP_TEXT']
4 | case ENV['POPCLIP_MODIFIER_FLAGS'].to_i
5 | when 1048576 # Command (Hash)
6 | print input.split("\n").map {|line|
7 | "# #{line}"
8 | }.join("\n")
9 | when 524288 # Option (CSS)
10 | space = input.match(/^((?:\n\s*)*)\S.*?((?:\n\s*)*)$/m)
11 | print "#{space[1]}/* #{input.strip} */#{space[2]}"
12 | when 1572864 # Option-Command (Slash)
13 | print input.split("\n").map {|line|
14 | "// #{line}"
15 | }.join("\n")
16 | else # none (HTML)
17 | space = input.match(/^([\s\n]*)\S.*?([\s\n]*)$/m)
18 | print "#{space[1]}#{space[2]}"
19 | end
20 |
--------------------------------------------------------------------------------
/CopyCleanLinks.popclipext/Config.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Actions
6 |
7 |
8 | Image File
9 | icon.png
10 | Script Interpreter
11 | /usr/bin/ruby
12 | Shell Script File
13 | script.rb
14 | Title
15 | CopyCleanLinks
16 | Regular Expression
17 | (?si)(.*)?((http|https):\/\/)?[\w\-_]+(\.[\w\-_]+)+([\w\-\.,@?^=%&:/~\+#\(\)_]*[\w\-\@^=%&/~\+#])?(.*)?
18 | After
19 | copy-result
20 |
21 |
22 | Credits
23 |
24 | Name
25 | Brett Terpstra
26 | Link
27 | http://brettterpstra.com
28 |
29 | Extension Description
30 | Copies "cleaned" links from selection.
31 | Extension Identifier
32 | com.brettterpstra.popclip.extension.copycleanlinks
33 | Extension Name
34 | CopyCleanLinks
35 | Version
36 | 2
37 |
38 |
39 |
--------------------------------------------------------------------------------
/CopyCleanLinks.popclipext/README.md:
--------------------------------------------------------------------------------
1 | ### CopyCleanLinks
2 |
3 | PopClip extension to lengthen and clean URLs. Duplicate of LinkCleaner, but only copies results to the clipboard.
4 |
5 | Option: clean all query strings (default: only clean Google UTM strings)
6 | Command: Output just the resulting URL(s)
7 | Command-Option: Output just URL(s) with query strings stripped
8 |
--------------------------------------------------------------------------------
/CopyCleanLinks.popclipext/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ttscoff/popclipextensions/81a97925c317a804ad731e348c57b3cf7a635b22/CopyCleanLinks.popclipext/icon.png
--------------------------------------------------------------------------------
/CopyCleanLinks.popclipext/script.rb:
--------------------------------------------------------------------------------
1 | #!/usr/bin/ruby
2 | require 'cgi'
3 | require 'open-uri'
4 | require 'net/http'
5 | require 'rexml/document'
6 | require 'shellwords'
7 |
8 | debug = ARGV[0] =~ /(debug|-?d)/ ? true : false
9 |
10 | # 1.0
11 | # 2014-03-06
12 |
13 |
14 | unless debug
15 | orig_input = ENV['POPCLIP_TEXT'].dup
16 | else
17 | orig_input = "Brought to you by http://bit.ly/1hQ92Iz and http://brettterpstra.com"
18 | end
19 |
20 | input = orig_input.dup
21 |
22 | strip_all_queries = false
23 | only_links = false
24 |
25 | case ENV['POPCLIP_MODIFIER_FLAGS'].to_i
26 | when 524288 # Option
27 | strip_all_queries = true
28 | when 1048576
29 | only_links = true
30 | when 1572864
31 | strip_all_queries = true
32 | only_links = true
33 | end
34 |
35 | class String
36 | def clean_google
37 | return self.gsub(/[?&]utm_[scm].+=[^&?\n\s\r!,.\)\]]++/,'')
38 | end
39 |
40 | def clean_queries
41 | return self.sub(/(.*?)\?\S+/,"\\1")
42 | end
43 | end
44 |
45 | begin
46 | o = []
47 | input.gsub!(/((?:(?:http|https):\/\/)?[\w\-_]+(\.[\w\-_]+)+([\w\-\.,@?^=%&:\/~\+#\(\)_]*[\w\-\@^=%&\/~\+#\(\)])?)/mi) {|url|
48 | if url =~ /https?:\/\/[\da-z]+\.[a-z]{2}\/[A-Za-z0-9]+/
49 | res = Net::HTTP.get(URI.parse("http://api.longurl.org/v2/expand?format=xml&url=#{CGI.escape(url)}"))
50 | doc = REXML::Document.new(res.strip)
51 | url = doc.elements["response/long-url"].text
52 | end
53 | url = url.clean_google
54 | url = url.clean_queries if strip_all_queries || debug
55 | o.push(url)
56 | url
57 | }
58 |
59 | # urls.each {|url|
60 | # if url.length == 3 && url.join("") !~ /^[\d\.]+$/
61 |
62 | # url = url[0]
63 |
64 | # if url =~ /\)/ && url !~ /\(/
65 | # url = url.sub(/\).*?$/,'')
66 | # end
67 |
68 | # target = url =~ /^http/ ? url : "http://#{url}"
69 | # o += target + "\n"
70 | # end
71 | # }
72 | if only_links
73 | puts o.join("\n")
74 | else
75 | print input
76 | end
77 | rescue Exception => e
78 | p e if debug
79 | end
80 |
--------------------------------------------------------------------------------
/CopyPlus.popclipext/Config.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Actions
6 |
7 |
8 | Image File
9 | copyplus.png
10 | Script Interpreter
11 | /bin/bash
12 | Shell Script File
13 | copyplus.sh
14 | Title
15 | CopyPLUS
16 |
17 |
18 | Credits
19 |
20 | Name
21 | Brett Terpstra
22 | Link
23 | http://brettterpstra.com
24 |
25 | Extension Description
26 | Append selection to clipboard.
27 | Extension Identifier
28 | com.brettterpstra.popclip.extension.copyplus
29 | Extension Name
30 | CopyPLUS
31 | Version
32 | 2
33 |
34 |
35 |
--------------------------------------------------------------------------------
/CopyPlus.popclipext/README.md:
--------------------------------------------------------------------------------
1 | ### CopyPLUS
2 |
3 | PopClip extension to append the selection to the current contents in the clipboard. *This is a duplicate of an existing extension (Append) with just slightly better UTF-8 handling, and modifier key handling for copying with and without linebreaks and whitespace.*
4 |
5 | * Hold Command (⌘) when clicking to add an extra line break between entries.
6 | * Hold Option (⌥) to append with no extra whitespace.
7 |
--------------------------------------------------------------------------------
/CopyPlus.popclipext/copyplus.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ttscoff/popclipextensions/81a97925c317a804ad731e348c57b3cf7a635b22/CopyPlus.popclipext/copyplus.png
--------------------------------------------------------------------------------
/CopyPlus.popclipext/copyplus.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | clipboard=`__CF_USER_TEXT_ENCODING=$UID:0x8000100:0x8000100 pbpaste`
4 |
5 | # Check for command key
6 | if [[ $POPCLIP_MODIFIER_FLAGS == 1048576 ]]; then
7 | __CF_USER_TEXT_ENCODING=$UID:0x8000100:0x8000100 pbcopy <
2 |
3 |
4 |
5 | Actions
6 |
7 |
8 | Image File
9 | icon.png
10 | Script Interpreter
11 | /usr/bin/ruby
12 | Shell Script File
13 | script.rb
14 | Title
15 | CopyURLS
16 | Regular Expression
17 | (?si)(.*)?((http|https):\/\/)?[\w\-_]+(\.[\w\-_]+)+([\w\-\.,@?^=%&:/~\+#\(\)_]*[\w\-\@^=%&/~\+#])?(.*)?
18 | After
19 | copy-result
20 |
21 |
22 | Credits
23 |
24 | Name
25 | Brett Terpstra
26 | Link
27 | http://brettterpstra.com
28 |
29 | Extension Description
30 | Copies only urls in selection to a list in the clipboard.
31 | Extension Identifier
32 | com.brettterpstra.popclip.extension.copyurls
33 | Extension Name
34 | CopyURLS
35 | Version
36 | 2
37 |
38 |
39 |
--------------------------------------------------------------------------------
/CopyURLS.popclipext/README.md:
--------------------------------------------------------------------------------
1 | ### CopyURLS
2 |
3 | PopClip extension to copy just the URLS in selection.
4 |
5 | Duplicate of OpenURLS, but copies urls to the clipboard, one link per line, instead of opening in browser.
6 |
--------------------------------------------------------------------------------
/CopyURLS.popclipext/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ttscoff/popclipextensions/81a97925c317a804ad731e348c57b3cf7a635b22/CopyURLS.popclipext/icon.png
--------------------------------------------------------------------------------
/CopyURLS.popclipext/script.rb:
--------------------------------------------------------------------------------
1 | #!/usr/bin/ruby
2 | debug = ARGV[0] =~ /(debug|-?d)/ ? true : false
3 |
4 | # 1.0
5 | # 2013-09-30
6 | #
7 | # Duplicate of OpenURLs, but copies a plain, newline-separated list to the clipboard
8 | # Better regex for extracting urls
9 | # Hold down Option to combine lines and fix broken urls
10 | # This can cause issues with full urls on consecutive lines, but is handy for a single broken link.
11 | # Leaves leading space on lines, so urls broken with an indent are still screwed. Ran into too many problems trying to parse around that.
12 |
13 | unless debug
14 | input = ENV['POPCLIP_TEXT']
15 | else
16 | input =<
24 |
25 | http://www.google.com/support/a/bin/answer.py?answer=37673
26 | http://www.google.com/search?client=safari&rls=en&q=share+multiple+links&ie=UTF-8&oe=UTF-8
27 |
28 | http://en.wikipedia.org/wiki/Ed_Roberts_(computer_engineer)
29 |
30 | www.google.com/support/a/bin/answer.py?answer=37673
31 |
32 | http://postable.weblogzinc.com/?blog=tuaw-we, http://postable.weblogzinc.com/?blog=tuaw-we
33 | (http://postable.weblogzinc.com/?blog=tuaw-we).
34 |
35 | ~@emmaboulton Talk to (http://www.premiumcollections.co.uk). They were good in getting me a result with one wanker who took the piss.
36 |
37 | Blog Post: Allan Haley Interviewed at Web 2.0 Expo SF 2010 About Web Fonts http://blog.fonts.com/?p=563 blog.fonts.com/?p=563
38 |
39 | Today's 9:30 Coffee Break: False Beginnings. More on the Blog - http://minnesota.publicradio.org/collections/special/columns/music_blog/archive/2010/05/monday_coffee_b_31.shtml
40 |
41 | Review: iHome+Sleep for iPhone "http://www.pheedcontent.com/click.phdo?i=24518775cad8deb8f509fd82f53afe9a&utm_source=mactweets&utm_medium=twitter"
42 | ENDINPUT
43 | end
44 |
45 | case ENV['POPCLIP_MODIFIER_FLAGS'].to_i
46 | when 524288 || debug # Option
47 | input = input.split(/[\n\r]/).map {|line|
48 | line.chomp!
49 | line =~ /^$/ ? "\n" : line
50 | }.join("")
51 | end
52 |
53 | o = ""
54 | urls = input.scan(/((?:(?:http|https):\/\/)?[\w\-_]+(\.[\w\-_]+)+([\w\-\.,@?^=%&:\/~\+#\(\)_]*[\w\-\@^=%&\/~\+#\(\)])?)/mi)
55 |
56 | urls.each {|url|
57 | if url.length == 3 && url.join("") !~ /^[\d\.]+$/
58 |
59 | url = url[0]
60 |
61 | if url =~ /\)/ && url !~ /\(/
62 | url = url.sub(/\).*?$/,'')
63 | end
64 |
65 | target = url =~ /^http/ ? url : "http://#{url}"
66 | o += target + "\n"
67 | end
68 | }
69 | print o
70 |
--------------------------------------------------------------------------------
/CriticMarkup.popclipext/Config.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Actions
6 |
7 |
8 | Image File
9 | icon.png
10 | Script Interpreter
11 | /usr/bin/ruby
12 | Shell Script File
13 | script.rb
14 | Title
15 | wrap
16 | After
17 | paste-result
18 | Requirements
19 |
20 | paste
21 |
22 |
23 |
24 | Options
25 |
26 |
27 | Option Identifier
28 | criticmarkupcomment
29 | Option Type
30 | string
31 | Option Label
32 | Signature
33 |
34 |
35 | Credits
36 |
37 | Name
38 | Brett Terpstra
39 | Link
40 | http://brettterpstra.com
41 |
42 | Extension Description
43 | Insert CriticMarkup
44 | Extension Identifier
45 | com.brettterpstra.popclip.extension.criticmarkup
46 | Extension Name
47 | CriticMarkup
48 | Version
49 | 2
50 |
51 |
52 |
--------------------------------------------------------------------------------
/CriticMarkup.popclipext/README.md:
--------------------------------------------------------------------------------
1 | ### CriticMarkup
2 |
3 | Allows the quick insertion of [CriticMarkup][] syntax. Optionally fill in a signature to have a comment included after every insert, deletion or change with your initials or name.
4 |
5 | - No modifier: Highlight
6 | - **Command**: Deletion
7 | - **Control**: Insertion
8 | - **Control-Option**: Change
9 | - **Option**: Comment
10 |
11 | [CriticMarkup]: http://criticmarkup.com/spec.php
12 |
13 | There _is_ a PopClip extension for CriticMarkup in the main download package, which I didn't realize when I whipped this one up. I may defer to that one eventually, but I'll wait until I figure out if mine adds anything worthwhile or not.
14 |
--------------------------------------------------------------------------------
/CriticMarkup.popclipext/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ttscoff/popclipextensions/81a97925c317a804ad731e348c57b3cf7a635b22/CriticMarkup.popclipext/icon.png
--------------------------------------------------------------------------------
/CriticMarkup.popclipext/script.rb:
--------------------------------------------------------------------------------
1 | #!/usr/bin/ruby
2 |
3 | # no modifier: highlight
4 | # command: delete
5 | # control: insert
6 | # control-command: change
7 | # shift: comment
8 |
9 | comment = ENV['POPCLIP_OPTION_CRITICMARKUPCOMMENT']
10 |
11 | commentmarkup = comment == '' ? '' : "{>>#{comment} - #{Time.now.strftime('%F %T')}<<}"
12 |
13 | ctrlcmdprefix = '{~~'
14 | ctrlcmdsuffix = '~> ~~}'
15 | ctrlprefix = '{++'
16 | ctrlsuffix = '++}'
17 | cmdprefix = '{--'
18 | cmdsuffix = '--}'
19 | shiftprefix = '{>>'
20 | shiftsuffix = '<<}'
21 | prefix = '{=='
22 | suffix = '==}'
23 |
24 | input = ENV['POPCLIP_TEXT']
25 |
26 | case ENV['POPCLIP_MODIFIER_FLAGS'].to_i
27 | when 1048576 # Command
28 | print "#{cmdprefix}#{input}#{cmdsuffix}#{commentmarkup}"
29 | when 131072 # Shift
30 | print "#{shiftprefix}#{comment}: #{input}#{shiftsuffix}"
31 | when 262144 # Control
32 | print "#{ctrlprefix}#{input}#{ctrlsuffix}#{commentmarkup}"
33 | when 1310720 # control-command
34 | print "#{ctrlcmdprefix}#{input}#{ctrlcmdsuffix}#{commentmarkup}"
35 | else # none
36 | print "#{prefix}#{input}#{suffix}#{commentmarkup}"
37 | end
38 |
--------------------------------------------------------------------------------
/DefineAbbr.popclipext/Config.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Actions
6 |
7 |
8 | Script Interpreter
9 | /usr/bin/ruby
10 | Shell Script File
11 | script.rb
12 | Title
13 | LOL
14 |
15 |
16 |
17 | Extension Description
18 | Define Abbr, made with PopMaker by Brett Terpstra
19 | Extension Identifier
20 | com.brettterpstra.popclip.extension.DefineAbbr
21 | Extension Name
22 | Define Abbr
23 | Version
24 | 2
25 |
26 |
27 |
--------------------------------------------------------------------------------
/DefineAbbr.popclipext/README.md:
--------------------------------------------------------------------------------
1 | ### DefineAbbr
2 |
3 | PopClip extension to search textingabbreviations.ca for the selected string.
4 |
--------------------------------------------------------------------------------
/DefineAbbr.popclipext/script.rb:
--------------------------------------------------------------------------------
1 | #!/System/Library/Frameworks/Ruby.framework/Versions/Current/usr/bin/ruby
2 |
3 | require 'cgi'
4 |
5 | url = "http://www.textingabbreviations.ca/{query}/"
6 | query = ENV['POPCLIP_TEXT']
7 | url.sub!(/\{query\}/,CGI.escape(query))
8 |
9 | %x{open "#{url}"}
10 |
--------------------------------------------------------------------------------
/Editor.popclipext/Config.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Actions
6 |
7 |
8 | Image File
9 | icon.png
10 | Script Interpreter
11 | /usr/bin/ruby
12 | Shell Script File
13 | script.rb
14 | Title
15 | edit
16 | After
17 | paste-result
18 | Requirements
19 |
20 | paste
21 |
22 |
23 |
24 | Options
25 |
26 |
27 | Option Identifier
28 | includedatetime
29 | Option Type
30 | boolean
31 | Option Label
32 | Include Datetime
33 | Option Default Value
34 |
35 |
36 |
37 | Credits
38 |
39 | Name
40 | Brett Terpstra
41 | Link
42 | http://brettterpstra.com
43 |
44 | Extension Description
45 | Adds ins, del and mark tags to text
46 | Extension Identifier
47 | com.brettterpstra.popclip.extension.editor
48 | Extension Name
49 | Editor
50 | Version
51 | 2
52 |
53 |
54 |
--------------------------------------------------------------------------------
/Editor.popclipext/README.md:
--------------------------------------------------------------------------------
1 | ### Editor
2 |
3 | Extension for adding HTML editor marks to text.
4 |
5 | - No modifier: `` (highlight)
6 | - **Control**: `` (insertion)
7 | - **Command**: `` (deletion)
8 | - **Option**: `` (comment)
9 |
--------------------------------------------------------------------------------
/Editor.popclipext/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ttscoff/popclipextensions/81a97925c317a804ad731e348c57b3cf7a635b22/Editor.popclipext/icon.png
--------------------------------------------------------------------------------
/Editor.popclipext/script.rb:
--------------------------------------------------------------------------------
1 | #!/usr/bin/ruby
2 |
3 | # no modifier:
4 | # control:
5 | # command:
6 | # option:
7 |
8 | include_datetime = ENV['POPCLIP_OPTION_INCLUDEDATETIME']
9 | date = include_datetime.to_i == 1 ? Time.now.strftime(' datetime="%FT%T%z"') : ""
10 | prefix = ""
11 | suffix = ""
12 | ctrlprefix = ""
13 | ctrlsuffix = ""
14 | cmdprefix = ""
15 | cmdsuffix = ""
16 | optprefix = ""
18 |
19 | input = ENV['POPCLIP_TEXT']
20 |
21 | space = input.match(/^([\s\n]*)\S.*?([\s\n]*)$/m)
22 | case ENV['POPCLIP_MODIFIER_FLAGS'].to_i
23 | when 1048576 # Command
24 | print "#{space[1]}#{cmdprefix}#{input.strip}#{cmdsuffix}#{space[2]}"
25 | when 524288 # Option
26 | print "#{space[1]}#{optprefix}#{input.strip}#{optsuffix}#{space[2]}"
27 | when 262144 # ctrl
28 | print "#{space[1]}#{ctrlprefix}#{input.strip}#{ctrlsuffix}#{space[2]}"
29 | else # none
30 | print "#{space[1]}#{prefix}#{input.strip}#{suffix}#{space[2]}"
31 | end
32 |
33 |
34 |
35 |
--------------------------------------------------------------------------------
/FixPoorlyObscuredEmail.popclipext/Config.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Version
6 | 2
7 | Extension Description
8 | Fix or open AT DOT obscured email addresses.
9 | Extension Name
10 | FixPoorlyObscuredEmail
11 | Extension Identifier
12 | com.brettterpstra.popclip.extension.fixemail
13 | Actions
14 |
15 |
16 | Shell Script File
17 | script.rb
18 | Script Interpreter
19 | /usr/bin/ruby
20 | Title
21 | DOT
22 | After
23 | paste-result
24 | Regular Expression
25 | (?si)(.*)AT\s+[a-z0-9]+\s+DOT(.*)
26 |
27 |
28 | Credits
29 |
30 | Name
31 | Brett Terpstra
32 | Link
33 | http://brettterpstra.com
34 |
35 |
36 |
37 |
--------------------------------------------------------------------------------
/FixPoorlyObscuredEmail.popclipext/README.md:
--------------------------------------------------------------------------------
1 | ### FixPoorlyObscuredEmails
2 |
3 | Fixes emails obscured in a "support AT mydomain DOT com" fashion.
4 |
5 | Hold Option to also open an email window for each matched address. This feature does not require edit capability in the current field.
6 |
--------------------------------------------------------------------------------
/FixPoorlyObscuredEmail.popclipext/script.rb:
--------------------------------------------------------------------------------
1 | #!/usr/bin/ruby
2 | debug = ARGV[0] =~ /(debug|-?d)/ ? true : false
3 |
4 | # 1.0
5 | # 2013-09-30
6 | #
7 | # Fixes emails obscured like "support AT mydomain DOT com"
8 | # Hold down Option to open also a mailto link for matched addresses
9 |
10 | unless debug
11 | input = ENV['POPCLIP_TEXT']
12 | else
13 | input =< e
40 | p e
41 | ensure # this way makes it easier to debug. Sue me.
42 | exit 0
43 | end
44 |
--------------------------------------------------------------------------------
/HardWrap.popclipext/Config.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Actions
6 |
7 |
8 | Image File
9 | hardwrap.png
10 | Script Interpreter
11 | /usr/bin/ruby
12 | Shell Script File
13 | hardwrap.rb
14 | Title
15 | Wrap
16 | After
17 | paste-result
18 | Requirements
19 |
20 | paste
21 |
22 |
23 |
24 | Options
25 |
26 |
27 | Option Identifier
28 | column
29 | Option Type
30 | string
31 | Option Label
32 | Column
33 | Option Default Value
34 | 80
35 |
36 |
37 | Option Identifier
38 | altcolumn
39 | Option Type
40 | string
41 | Option Label
42 | Alternate Column
43 | Option Default Value
44 | 70
45 |
46 |
47 | Credits
48 |
49 | Name
50 | Brett Terpstra
51 | Link
52 | http://brettterpstra.com
53 |
54 | Extension Description
55 | Add and remove hard wrapping of paragraphs.
56 | Extension Identifier
57 | com.brettterpstra.popclip.extension.hardwrap
58 | Extension Name
59 | HardWrap
60 | Version
61 | 2
62 |
63 |
64 |
--------------------------------------------------------------------------------
/HardWrap.popclipext/README.md:
--------------------------------------------------------------------------------
1 | ### HardWrap
2 |
3 | Add hard wrapping to paragraphs. Default wrap column is 80, hold down Option to wrap at an alternate column (modify both in the extension options). Hold down command to unwrap text, removing line breaks between lines but preserving multiple lines between paragraphs.
4 |
5 | * Clicking wraps at ruler, default 80 characters
6 | * Option-click to wrap to alternate width
7 | * Command-click to unwrap text
8 |
9 |
--------------------------------------------------------------------------------
/HardWrap.popclipext/hardwrap.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ttscoff/popclipextensions/81a97925c317a804ad731e348c57b3cf7a635b22/HardWrap.popclipext/hardwrap.png
--------------------------------------------------------------------------------
/HardWrap.popclipext/hardwrap.rb:
--------------------------------------------------------------------------------
1 | #!/usr/bin/ruby
2 |
3 | if ARGV[0] =~ /\-?d(ebug)?/
4 | input = STDIN.read
5 | # ENV['POPCLIP_MODIFIER_FLAGS'] = 1048576.to_s # Command
6 | # ENV['POPCLIP_MODIFIER_FLAGS'] = 524288.to_s # Option
7 | column = 80
8 | altcolumn = 60
9 | else
10 | input = ENV['POPCLIP_TEXT']
11 | column = ENV['POPCLIP_OPTION_COLUMN'].to_i
12 | altcolumn = ENV['POPCLIP_OPTION_ALTCOLUMN'].to_i
13 | end
14 |
15 |
16 | class String
17 | def wrap(col = 80)
18 | self.gsub(/(.{1,#{col}})( +|$)\n?|(.{#{col}})/, "\\1\\3\n").strip
19 | end
20 |
21 | def unwrap
22 | self.split(/\n{2,}/).map {|para| para.gsub(/(\S *)\n( *\S)/, '\1 \2')}.join("\n\n").strip
23 | end
24 | end
25 |
26 | trail_match = input.match(/(?i-m)[\s\n\t]++$/)
27 | trailing = trail_match.nil? ? "" : trail_match[0]
28 |
29 | output = []
30 |
31 | case ENV['POPCLIP_MODIFIER_FLAGS'].to_i
32 | when 1048576 # Command - Unwrap
33 | print input.unwrap
34 | when 524288 # Option - Wrap at alternate column
35 | print input.wrap(altcolumn)
36 | else # Wrap at default column
37 | print input.wrap(column)
38 | end
39 |
40 | print trailing
41 |
--------------------------------------------------------------------------------
/IncrementTemplated.popclipext/Config.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Actions
6 |
7 |
8 | Image File
9 | increment.png
10 | Script Interpreter
11 | /usr/bin/ruby
12 | Shell Script File
13 | script.rb
14 | Title
15 | Increment
16 | Regular Expression
17 | (?mis)^(.*?)##(\d+(\.\.\d+)?\.\.\d+|(.+,)+.+)##(.*)$
18 | After
19 | paste-result
20 | Requirements
21 |
22 | paste
23 |
24 |
25 |
26 | Credits
27 |
28 | Name
29 | Brett Terpstra
30 | Link
31 | http://brettterpstra.com
32 |
33 | Extension Description
34 | Repeat text by incrementing template values.
35 | Extension Identifier
36 | com.brettterpstra.popclip.extension.incrementtemplated
37 | Extension Name
38 | Increment Templated
39 | Version
40 | 2
41 |
42 |
43 |
--------------------------------------------------------------------------------
/IncrementTemplated.popclipext/README.md:
--------------------------------------------------------------------------------
1 | ### Increment Templated
2 |
3 | PopClip extension to increment and repeat templated text.
4 |
5 | Select and run on the following text:
6 |
7 | ```
8 | This is a numeric increment ##0..2##.
9 | ```
10 |
11 | Which will generate:
12 |
13 | ```
14 | This is a numeric increment 0.
15 | This is a numeric increment 1.
16 | ```
17 |
18 | Specify a value to increment by with `##START..INCREMENT..END##`, e.g. `##0..2..10##` would insert 0, 2, 4, 6, 8, and 10.
19 |
20 | 
21 |
22 | #### Placeholders
23 |
24 | You can use placeholders with basic math modification. `##x##` inserts the current element again. `##i##` inserts the 0-based index in the iteration. So if the template is `##5..7##`, on the second iteration `x` would hold `6` and `i` would hold `1`.
25 |
26 | Apply math functions to the placeholders using basic operator symbols (including `%` for mod). To insert the current value times 10, use `##x*10##`. More complex equations are allowed, e.g. `##(i+2)*10##`. Use `%` for modulus.
27 |
28 | You can include leading zeroes on math operations to pad the result. If you want to just pad the number without modifying, you would use `##x*0001##`, which would turn `5` into `0005` and `50` into `0050`. Including a 0 padding on any element of the equation will result in padded output.
29 |
30 |
31 | #### String Arrays
32 |
33 | You can also use arrays of strings or numbers:
34 |
35 | ```
36 | Hello ##mother,father,sister,brother##. And repeat with ##x##.
37 | ```
38 |
39 | Yields:
40 |
41 | ```
42 | Hello mother. And repeat with mother.
43 | Hello father. And repeat with father.
44 | Hello sister. And repeat with sister.
45 | Hello brother. And repeat with brother.
46 | ```
47 |
48 | The `##i##` placeholder (zero-based index) with math operators is also available in string array replacements. If you want the index to also refer to strings, add `#list,of,strings` after the index or equation, e.g. `##i%2#odd,even##` to insert `odd` and `even` alternately with each iteration.
49 |
50 | Example:
51 |
52 | ```
53 | .element-##one,two,three## {
54 | text-indent: ##i*10##px;
55 | }
56 | ```
57 |
58 | ```
59 | .element-one {
60 | text-indent: 0px;
61 | }
62 | .element-two {
63 | text-indent: 10px;
64 | }
65 | .element-three {
66 | text-indent: 20px;
67 | }
68 | ```
69 |
--------------------------------------------------------------------------------
/IncrementTemplated.popclipext/increment.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ttscoff/popclipextensions/81a97925c317a804ad731e348c57b3cf7a635b22/IncrementTemplated.popclipext/increment.png
--------------------------------------------------------------------------------
/IncrementTemplated.popclipext/script.rb:
--------------------------------------------------------------------------------
1 | #!/usr/bin/ruby
2 | # frozen_string_literal: true
3 |
4 | input = ENV['POPCLIP_TEXT']
5 |
6 | NUMERIC_RX = /(\?\:)?##(\d+)(?:\.\.(\d+))?\.\.(\d+)##/.freeze
7 | ARRAY_RX = /##(.*?)##/.freeze
8 |
9 | def get_modifiers(input)
10 | input.scan(%r{##(([ix0-9()+\-/*%]+)*)(#([^#]+))?##}).map do
11 | m = Regexp.last_match
12 | padding = if m[2].nil?
13 | '%d'
14 | else
15 | t = m[2].match(/\b(0+)([1-9]\d*)?/)
16 | t.nil? || m[2] =~ /^0$/ ? '%d' : "%0#{t[0].length}d"
17 | end
18 |
19 | options_array = m[3].nil? ? nil : m[4].split(/,/).map(&:strip)
20 |
21 | base = m[1].nil? ? 'x' : m[1]
22 | inc = m[2].nil? ? '' : m[2].gsub(/\b(0+\d+)/, &:to_i)
23 |
24 | [Regexp.escape(m[0]), inc, padding, base, options_array]
25 | end
26 | end
27 |
28 | def process_array(input)
29 | template = input.match(ARRAY_RX)
30 | replacements = template[1].split(/,/).map(&:strip)
31 | modified = get_modifiers(input)
32 | output = []
33 |
34 | replacements.each_with_index do |replacement, idx|
35 | out = input.sub(/#{Regexp.escape(template[0])}/, replacement)
36 | out.gsub!(/##[0x]##/, replacement)
37 | modified.each do |mod|
38 | next if mod.nil?
39 |
40 | equat = mod[3].gsub(/\b0+/, '').gsub(/x/, (idx + 1).to_s).gsub(/i/, idx.to_s)
41 | if mod[4]
42 | out.sub!(/#{mod[0]}/, mod[4][(mod[2] % (eval equat)).to_i] || '')
43 | else
44 | out.sub!(/#{mod[0]}/, (mod[2] % (eval equat).to_s))
45 | end
46 | end
47 |
48 | output.push(out)
49 | end
50 |
51 | output.join("\n")
52 | end
53 |
54 | def process_numeric(input)
55 | template = input.match(NUMERIC_RX)
56 | disp = template[1].nil? ? true : false
57 | inc = template[3].nil? ? 1 : template[3].to_i
58 |
59 | modified = get_modifiers(input)
60 |
61 | padding = template[2].match(/^(0+)([1-9](\d+)?)?/)
62 |
63 | padding = if padding.nil? || template[2] =~ /^0$/
64 | '%d'
65 | else
66 | "%0#{padding[0].length}d"
67 | end
68 |
69 | output = []
70 | idx = 0
71 | count_start = template[2].to_i
72 | count_end = template[4].to_i
73 |
74 | while (count_start <= count_end) do
75 | replacement = disp ? padding % count_start.to_i : ''
76 | out = input.sub(/#{Regexp.escape(template[0])}/, replacement)
77 | modified.each do |mod|
78 | next if mod.nil?
79 |
80 | equat = mod[3].gsub(/\b0+/, '').gsub(/x/, (idx + 1).to_s).gsub(/i/, idx.to_s)
81 |
82 | if mod[4]
83 | out.sub!(/#{mod[0]}/, mod[4][(mod[2] % (eval equat)).to_i] || '')
84 | else
85 | out.sub!(/#{mod[0]}/, (mod[2] % (eval equat).to_s))
86 | end
87 | end
88 | output << out
89 | count_start += inc
90 | idx += 1
91 | end
92 |
93 | output.join("\n")
94 | end
95 |
96 | if input =~ NUMERIC_RX
97 | input = process_numeric(input)
98 | elsif input =~ ARRAY_RX
99 | input = process_array(input)
100 | end
101 | print input
102 |
--------------------------------------------------------------------------------
/LinkCleaner.popclipext/Config.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Actions
6 |
7 |
8 | Image File
9 | icon.png
10 | Script Interpreter
11 | /usr/bin/ruby
12 | Shell Script File
13 | script.rb
14 | Title
15 | LinkCleaner
16 | Regular Expression
17 | (?si)(.*)?((http|https):\/\/)?[\w\-_]+(\.[\w\-_]+)+([\w\-\.,@?^=%&:/~\+#\(\)_]*[\w\-\@^=%&/~\+#])?(.*)?
18 | After
19 | paste-result
20 |
21 |
22 | Options
23 |
24 |
25 | Option Identifier
26 | gaonly
27 | Option Type
28 | boolean
29 | Option Default Value
30 |
31 | Option Label
32 | GA Only
33 |
34 |
35 | Credits
36 |
37 | Name
38 | Brett Terpstra
39 | Link
40 | http://brettterpstra.com
41 |
42 | Extension Description
43 | Lengthens and cleans urls in selection.
44 | Extension Identifier
45 | com.brettterpstra.popclip.extension.linkcleaner
46 | Extension Name
47 | LinkCleaner
48 | Version
49 | 2
50 |
51 |
52 |
--------------------------------------------------------------------------------
/LinkCleaner.popclipext/README.md:
--------------------------------------------------------------------------------
1 | ### LinkCleaner
2 |
3 | PopClip extension to lengthen and clean URLs.
4 |
5 | Use extension settings to determine whether it strips Google Analytics strings only, or _all_ query strings.
6 |
7 | - Option: force clean all query strings, ignore settings
8 | - Command: Output just the resulting URL(s)
9 | - Command-Option: Output just URL(s) with all query strings stripped
10 |
--------------------------------------------------------------------------------
/LinkCleaner.popclipext/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ttscoff/popclipextensions/81a97925c317a804ad731e348c57b3cf7a635b22/LinkCleaner.popclipext/icon.png
--------------------------------------------------------------------------------
/LinkCleaner.popclipext/script.rb:
--------------------------------------------------------------------------------
1 | #!/usr/bin/ruby
2 | require 'cgi'
3 | require 'open-uri'
4 | require 'net/http'
5 | require 'rexml/document'
6 | require 'shellwords'
7 |
8 | debug = ARGV[0] =~ /(debug|-?d)/ ? true : false
9 |
10 | # 1.0
11 | # 2014-03-06
12 |
13 |
14 | unless debug
15 | strip_all_queries = ENV['POPCLIP_OPTION_GAONLY'].to_i == 0
16 | orig_input = ENV['POPCLIP_TEXT'].dup
17 | else
18 | strip_all_queries = true
19 | orig_input = "Brought to you by http://bit.ly/1hQ92Iz and http://brettterpstra.com, https://clutchpoints.com/clippers-news-rajon-rondo-speaks-out-after-clippers-debut-vs-lakers/?fbclid=IwAR3epED82RKaRTrmL4X_uBCoVjU6mmFxFhZcAXshKwMzm17RuAT_oxxteiE"
20 | end
21 |
22 | input = orig_input.dup
23 |
24 | only_links = false
25 |
26 | case ENV['POPCLIP_MODIFIER_FLAGS'].to_i
27 | when 524288 # Option
28 | strip_all_queries = true
29 | when 1048576
30 | only_links = true
31 | when 1572864
32 | strip_all_queries = true
33 | only_links = true
34 | end
35 |
36 | class String
37 | def clean_google
38 | return self.gsub(/[?&]utm_[scm].+=[^&?\n\s\r!,.\)\]]++/,'')
39 | end
40 |
41 | def clean_queries
42 | return self.sub(/(.*?)\?\S+/,"\\1")
43 | end
44 | end
45 |
46 | begin
47 | o = []
48 | input.gsub!(/((?:(?:http|https):\/\/)?[\w\-_]+(\.[\w\-_]+)+([\w\-\.,@?^=%&:\/~\+#\(\)_]*[\w\-\@^=%&\/~\+#\(\)])?)/mi) {|url|
49 | url = url.clean_google
50 | url = url.clean_queries if strip_all_queries || debug
51 | o.push(url)
52 | url
53 | }
54 |
55 | if only_links
56 | puts o.join("\n")
57 | else
58 | print input
59 | end
60 | rescue Exception => e
61 | print orig_input
62 | end
63 |
--------------------------------------------------------------------------------
/Markdown2Mindmap.popclipext/Config.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Actions
6 |
7 |
8 | Image File
9 | md2mm.png
10 | Script Interpreter
11 | /usr/bin/ruby
12 | Shell Script File
13 | md2mm.rb
14 | Title
15 | md2mm
16 | After
17 | copy-result
18 |
19 |
20 | Credits
21 |
22 | Name
23 | Brett Terpstra
24 | Link
25 | http://brettterpstra.com
26 |
27 | Extension Description
28 | Convert text/outlines to tab-indented outlines for pasting into mind maps.
29 | Extension Identifier
30 | com.brettterpstra.popclip.extension.md2mm
31 | Extension Name
32 | md2mm
33 | Version
34 | 2
35 |
36 |
37 |
--------------------------------------------------------------------------------
/Markdown2Mindmap.popclipext/README.md:
--------------------------------------------------------------------------------
1 | ### Markdown to Mindmap
2 |
3 | Takes a selection of plain text containing markdown headlines, list items and paragraphs and converts it into a format ready for pasting into a mind mapping application (such as MindNode, MindManager or MindMeister) as separate nodes/topics.
4 |
--------------------------------------------------------------------------------
/Markdown2Mindmap.popclipext/md2mm.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ttscoff/popclipextensions/81a97925c317a804ad731e348c57b3cf7a635b22/Markdown2Mindmap.popclipext/md2mm.png
--------------------------------------------------------------------------------
/Markdown2Mindmap.popclipext/md2mm.rb:
--------------------------------------------------------------------------------
1 | #!/usr/bin/ruby
2 | require 'shellwords'
3 |
4 | input = ENV['POPCLIP_TEXT']
5 |
6 | def outdent(input)
7 | shortest = false
8 | input.scan(/^\s*/m).each do |leader|
9 | if shortest == false || leader.length < shortest.length
10 | shortest = leader
11 | end
12 | end
13 | input.gsub(/^#{shortest}/m,'').strip
14 | end
15 |
16 | # initial outdent and create array
17 | lines = outdent(input).split("\n")
18 |
19 |
20 | # Remove blank lines
21 | lines.delete_if {|line| line =~ /^\s*$/}
22 |
23 |
24 | # Handle converting headlines and lists to indented outline
25 | last_level = 0
26 | lines.map! {|line|
27 | if line =~ /^#\s/
28 | line.gsub!(/^# /,"")
29 | last_level = 1
30 | elsif line =~ /^## /
31 | line.gsub!(/^## /,"\t")
32 | last_level = 2
33 | elsif line =~ /^### /
34 | line.gsub!(/^### /,"\t\t")
35 | last_level = 3
36 | elsif line =~ /^#### /
37 | line.gsub!(/^#### /,"\t\t\t")
38 | last_level = 4
39 | elsif line =~ /^##### /
40 | line.gsub!(/^##### /,"\t\t\t\t")
41 | last_level = 5
42 | elsif line =~ /^###### /
43 | line.gsub!(/^###### /,"\t\t\t\t\t")
44 | last_level = 6
45 | else
46 | line.gsub!(/(\s*)(\d\.|[\-\*\+])\s/,"\\1")
47 | line.gsub!(/\s{4}/,"\t") unless line.nil?
48 | last_level.times do
49 | line = "\t" + line
50 | end
51 | end
52 | line.chomp
53 | }
54 |
55 | # Copy to cliipboard
56 | # %x{printf #{Shellwords.escape(outdent(lines.join("\n")).strip)}|pbcopy}
57 |
58 | print outdent(lines.join("\n")).strip
59 |
--------------------------------------------------------------------------------
/NumberedList.popclipext/Config.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Actions
6 |
7 |
8 | Image File
9 | numberlist.png
10 | Script Interpreter
11 | /usr/bin/perl
12 | Shell Script File
13 | numberlist.pl
14 | Title
15 | Numbered List
16 | After
17 | paste-result
18 | Requirements
19 |
20 | paste
21 |
22 |
23 |
24 | Credits
25 |
26 | Name
27 | Brett Terpstra
28 | Link
29 | http://brettterpstra.com
30 |
31 | Extension Description
32 | Turn lines into a Markdown numbered list.
33 | Extension Identifier
34 | com.brettterpstra.popclip.extension.numberedlist
35 | Extension Name
36 | NumberedList
37 | Version
38 | 2
39 |
40 |
41 |
--------------------------------------------------------------------------------
/NumberedList.popclipext/README.md:
--------------------------------------------------------------------------------
1 | ### NumberedList
2 |
3 | PopClip extension to turn lines of text into Markdown numbered items. Will sort and update an existing numbered list as well, and convert bullets on list items to numbers.
4 |
5 | This is only here if you want a separate button for numbered lists. Otherwise you can just use BulletList and hold down option to create an ordered list instead.
6 |
--------------------------------------------------------------------------------
/NumberedList.popclipext/numberlist.pl:
--------------------------------------------------------------------------------
1 | #!/usr/bin/perl
2 |
3 | # ThisService Perl service script example
4 | # Service type: Filter.
5 | # Revision 1.
6 |
7 | # Perl practices:
8 | # Enables strict mode, requiring that variables are first declared with 'my'.
9 | # This, along with specifying '-w' in the magic first line, is widely
10 | # considered good Perl practice.
11 | use strict;
12 |
13 | # Unicode considerations:
14 | # '-CIO' in the magic first line enables Perl to consider STDIN to always
15 | # contain UTF-8, and to always output to STDOUT in UTF-8.
16 |
17 | my $result = "";
18 | my %last_marker = (); # Store last marker used for each list depth
19 | $last_marker{0} = "";
20 |
21 | my $last_leading_space = "";
22 | my $g_tab_width = 4;
23 | my $g_list_level = 0;
24 |
25 | my $line;
26 | my $marker;
27 | my $item;
28 | my $leading_space;
29 |
30 | my @resultLines = split /\n/, $ENV{"POPCLIP_TEXT"};
31 | foreach my $line (@resultLines) {
32 | next if $line =~ /^[\s\t]*$/;
33 | $line =~ s/^([ \t]*)(\d+\. |[\*\+\-] )?/${1}1. /;
34 | $line =~ /^([ \t]*)([\*\+\-]|\d+\.)(\.?\s*)(.*)/;
35 | $leading_space = $1;
36 | $marker = $2;
37 | $item = " " . $4;
38 |
39 | $leading_space =~ s/\t/ /g; # Convert tabs to spaces
40 |
41 | if ( $line !~ /^([ \t]*)([\*\+\-]|\d+\.)/) {
42 | #$result .= "a";
43 | # not a list line
44 | $result .= $line;
45 | $marker = $last_marker{$g_list_level};
46 | } elsif (length($leading_space) > length($last_leading_space)+3) {
47 | # New list level
48 | #$result .= "b";
49 | $g_list_level++;
50 |
51 | $marker =~ s{
52 | (\d+)
53 | }{
54 | # Reset count
55 | "1";
56 | }ex;
57 |
58 | $last_leading_space = $leading_space;
59 |
60 | $result .= "\t" x $g_list_level;
61 | $result .= $marker . $item . "\n";
62 | } elsif (length($leading_space)+3 < length($last_leading_space)) {
63 | #$result .= "c";
64 | # back to prior list level
65 | $g_list_level = length($leading_space) / 4;
66 |
67 | # update marker
68 | $marker = $last_marker{$g_list_level};
69 | $marker =~ s{
70 | (\d+)
71 | }{
72 | $1+1;
73 | }ex;
74 |
75 | $last_leading_space = $leading_space;
76 |
77 | $result .= "\t" x $g_list_level;
78 | $result .= $marker . $item . "\n";
79 | } else {
80 | # No change in level
81 | #$result .= "d";
82 |
83 | # update marker if it exists
84 | if ($last_marker{$g_list_level} ne "") {
85 | $marker = $last_marker{$g_list_level};
86 | $marker =~ s{
87 | (\d+)
88 | }{
89 | $1+1;
90 | }ex;
91 | }
92 |
93 |
94 | $last_leading_space = $leading_space;
95 |
96 | $result .= "\t" x $g_list_level;
97 | $result .= $marker . $item . "\n";
98 | }
99 |
100 | $last_marker{$g_list_level} = $marker;
101 | }
102 |
103 | $result =~ s/\n$//;
104 | print $result;
105 |
--------------------------------------------------------------------------------
/NumberedList.popclipext/numberlist.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ttscoff/popclipextensions/81a97925c317a804ad731e348c57b3cf7a635b22/NumberedList.popclipext/numberlist.png
--------------------------------------------------------------------------------
/OpenURLS.popclipext/Config.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Actions
6 |
7 |
8 | Image File
9 | openurls.png
10 | Script Interpreter
11 | /usr/bin/ruby
12 | Shell Script File
13 | openurls.rb
14 | Title
15 | OpenURLS
16 | Regular Expression
17 | (?si)(.*)?((http|https):\/\/)?[\w\-_]+(\.[\w\-_]+)+([\w\-\.,@?^=%&:/~\+#\(\)_]*[\w\-\@^=%&/~\+#])?(.*)?
18 | After
19 | show-status
20 |
21 |
22 | Credits
23 |
24 | Name
25 | Brett Terpstra
26 | Link
27 | http://brettterpstra.com
28 |
29 | Extension Description
30 | Open all urls in selection.
31 | Extension Identifier
32 | com.brettterpstra.popclip.extension.openurls
33 | Extension Name
34 | OpenURLS
35 | Version
36 | 2
37 |
38 |
39 |
--------------------------------------------------------------------------------
/OpenURLS.popclipext/README.md:
--------------------------------------------------------------------------------
1 | ### OpenURLS
2 |
3 | PopClip extension to open all URLS in selection.
4 |
--------------------------------------------------------------------------------
/OpenURLS.popclipext/openurls.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ttscoff/popclipextensions/81a97925c317a804ad731e348c57b3cf7a635b22/OpenURLS.popclipext/openurls.png
--------------------------------------------------------------------------------
/OpenURLS.popclipext/openurls.rb:
--------------------------------------------------------------------------------
1 | #!/usr/bin/ruby
2 | debug = ARGV[0] =~ /(debug|-?d)/ ? true : false
3 |
4 | # 1.1
5 | # 2013-09-30
6 | #
7 | # Better regex for extracting urls
8 | # Hold down Option to combine lines and fix broken urls
9 | # This can cause issues with full urls on consecutive lines, but is handy for a single broken link.
10 | # Leaves leading space on lines, so urls broken with an indent are still screwed. Ran into too many problems trying to parse around that.
11 |
12 | unless debug
13 | input = ENV['POPCLIP_TEXT']
14 | else
15 | input =<
21 |
22 | http://www.google.com/support/a/bin/answer.py?answer=37673
23 | http://www.google.com/search?client=safari&rls=en&q=share+multiple+links&ie=UTF-8&oe=UTF-8
24 |
25 | http://en.wikipedia.org/wiki/Ed_Roberts_(computer_engineer)
26 |
27 | www.google.com/support/a/bin/answer.py?answer=37673
28 |
29 | http://postable.weblogzinc.com/?blog=tuaw-we, http://postable.weblogzinc.com/?blog=tuaw-we
30 | (http://postable.weblogzinc.com/?blog=tuaw-we).
31 |
32 | ~@emmaboulton Talk to (http://www.premiumcollections.co.uk). They were good in getting me a result with one wanker who took the piss.
33 |
34 | Blog Post: Allan Haley Interviewed at Web 2.0 Expo SF 2010 About Web Fonts http://blog.fonts.com/?p=563 blog.fonts.com/?p=563
35 |
36 | Today's 9:30 Coffee Break: False Beginnings. More on the Blog - http://minnesota.publicradio.org/collections/special/columns/music_blog/archive/2010/05/monday_coffee_b_31.shtml
37 |
38 | Review: iHome+Sleep for iPhone "http://www.pheedcontent.com/click.phdo?i=24518775cad8deb8f509fd82f53afe9a&utm_source=mactweets&utm_medium=twitter"
39 | ENDINPUT
40 | end
41 |
42 | case ENV['POPCLIP_MODIFIER_FLAGS'].to_i
43 | when 524288 || debug # Option
44 | input = input.split(/[\n\r]/).map {|line|
45 | line.chomp!
46 | line =~ /^$/ ? "\n" : line
47 | }.join("")
48 | end
49 |
50 | o = ""
51 | urls = input.scan(/((?:(?:http|https):\/\/)?[\w\-_]+(\.[\w\-_]+)+([\w\-\.,@?^=%&:\/~\+#\(\)_]*[\w\-\@^=%&\/~\+#\(\)])?)/mi)
52 |
53 | urls.each {|url|
54 | if url.length == 3
55 |
56 | url = url[0]
57 |
58 | if url =~ /\)/ && url !~ /\(/
59 | url = url.sub(/\).*?$/,'')
60 | end
61 |
62 | target = url =~ /^http/ ? url : "http://#{url}"
63 |
64 | unless debug
65 | %x{open '#{target}'}
66 | sleep 1
67 | else
68 | o += target + "\n"
69 | end
70 | end
71 | }
72 | print o if debug
73 |
--------------------------------------------------------------------------------
/Outdent.popclipext/Config.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Actions
6 |
7 |
8 | Image File
9 | outdent.png
10 | Script Interpreter
11 | /usr/bin/ruby
12 | Shell Script File
13 | outdent.rb
14 | Title
15 | |<
16 | After
17 | paste-result
18 | Requirements
19 |
20 | paste
21 |
22 |
23 |
24 | Credits
25 |
26 | Name
27 | Brett Terpstra
28 | Link
29 | http://brettterpstra.com
30 |
31 | Extension Description
32 | Outdent the selection.
33 | Extension Identifier
34 | com.brettterpstra.popclip.extension.outdent
35 | Extension Name
36 | Outdent
37 | Version
38 | 2
39 |
40 |
41 |
--------------------------------------------------------------------------------
/Outdent.popclipext/README.md:
--------------------------------------------------------------------------------
1 | ### Outdent
2 |
3 | Fully outdents the selection, maintaining nested indentation.
4 |
--------------------------------------------------------------------------------
/Outdent.popclipext/outdent.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ttscoff/popclipextensions/81a97925c317a804ad731e348c57b3cf7a635b22/Outdent.popclipext/outdent.png
--------------------------------------------------------------------------------
/Outdent.popclipext/outdent.rb:
--------------------------------------------------------------------------------
1 | #!/usr/bin/ruby
2 |
3 | input = ENV['POPCLIP_TEXT']
4 | # input =<
2 |
3 |
4 |
5 | Actions
6 |
7 |
8 | Image File
9 | icon.png
10 | Script Interpreter
11 | /bin/bash
12 | Shell Script File
13 | script.sh
14 | Title
15 | PoorText
16 | After
17 | paste-result
18 | Requirements
19 |
20 | paste
21 |
22 |
23 |
24 | Credits
25 |
26 | Name
27 | Brett Terpstra
28 | Link
29 | http://brettterpstra.com
30 |
31 | Extension Description
32 | Strip rich text formatting
33 | Extension Identifier
34 | com.brettterpstra.popclip.extension.poortext
35 | Extension Name
36 | PoorText
37 | Version
38 | 2
39 |
40 |
41 |
--------------------------------------------------------------------------------
/PoorText.popclipext/README.md:
--------------------------------------------------------------------------------
1 | ### PoorText
2 |
3 | Make rich text go broke.
4 |
5 | Strips rich text formatting from selection. There are probably multiple others that do this, but it's so easy I just made it myself.
6 |
--------------------------------------------------------------------------------
/PoorText.popclipext/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ttscoff/popclipextensions/81a97925c317a804ad731e348c57b3cf7a635b22/PoorText.popclipext/icon.png
--------------------------------------------------------------------------------
/PoorText.popclipext/script.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | logger "$POPCLIP_TEXT"
4 |
5 | echo -n "$POPCLIP_TEXT"|pbcopy|pbpaste
6 |
7 | logger $?
8 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | Brett's PopClip Extensions
2 | =================
3 |
4 | My growing collection of [PopClip][popclip] extensions.
5 |
6 | ## Installation
7 |
8 | This repository only includes these as source bundles
9 | (`.popclipext`), not packaged `.popclipextz` versions. To
10 | install, just make sure the extension of a folder is
11 | `.popclipext` and double click it in Finder. An up-to-date
12 | package of the bundled versions is [available on my
13 | site](http://brettterpstra.com/projects/bretts-popclip-extensions).
14 |
15 |
16 |
17 | _Current release version: **1.45.4**
18 | ([source
19 | code](https://github.com/ttscoff/popclipextensions/releases/tag/1.44.8))_
21 |
22 | > Many of these extensions have alternate behaviors when
23 | > holding modifier keys. Recent versions of PopClip override
24 | > these variations and provide specific actions when holding
25 | > modifiers, such as Shift to copy result and Option to
26 | > display the result in the bar. This means that the
27 | > variations in the plugins no longer function. A better
28 | > system may be available in the future, but for now, to
29 | > restore the modifier key functionality, you need to
30 | > disable the global interpretation of them. Open Terminal
31 | > and run this command:
32 | >
33 | > defaults write com.pilotmoon.popclip DisableAlternateActions -bool YES
34 | {:alert}
35 |
36 | ## Extensions
37 |
38 | The extensions currently included in the bundle. Some are
39 | available elsewhere as well, but this collection will always
40 | be the most up-to-date versions.
41 |
42 |
43 | ### Blockquote
44 |
45 | Turn indented text (or any text) into nested Markdown blockquotes.
46 |
47 | * Clicking adds a ">" for each indentation level in the selected text
48 | * Command-click to decrease quote level
49 | * Command-Option-click key to remove all quoting
50 |
51 | When adding quote levels, multiple line breaks between lines creates separate block quotes (by design). If there's a single blank line between to paragraphs, they'll be joined together as paragraphs within a blockquote. More than one starts a new quote.
52 |
53 |
54 | ### BulletList
55 |
56 | PopClip extension to turn lines of text into Markdown bullet items. Indentation is handled as nested lists and existing markers are overwritten (numbered list becomes bullet list).
57 |
58 | #### Numbered lists
59 |
60 | Holding Option (⌥) while clicking the button for the extension in the PopClip bar will create/update a numbered list instead. When the list is already a numbered list, it will be re-numbered to fix any gaps or out-of-order numbering within nest levels.
61 |
62 | #### Clear list formatting
63 |
64 | Holding Command (⌘) while clicking will remove all list prefixes.
65 |
66 | #### Bullet format
67 |
68 | When you install this extension, you'll get an options page where you can select the type of bullet you prefer for unordered lists. This can be accessed again later by clicking the pencil button at the bottom of the list, then clicking the gear button next to the BulletList extension.
69 |
70 |
71 | ### CheckURLs
72 |
73 | PopClip extension to show a popup preview for each URL in selected text. Used for confirming the output of scripts like SearchLink without switching to the browser.
74 |
75 | Links are shown sequentially in the order they're found. If a URL is changed by following links in the preview and pressing "OK", the selected text will be updated with the final URL. Because of this, duplicate links in the text are all previewed so they can be modified individually.
76 |
77 |
78 | ### Code
79 |
80 | Turn selected text into Markdown inline code or a code block. This extension "toggles," so if the selection already contains code syntax (inline code or fenced code block) the syntax is removed.
81 |
82 | Detects whether there are multiple lines:
83 |
84 | * if not, it surrounds the input with single backticks
85 | * if so, it wraps the block in triple backticks (fenced)
86 |
87 | When creating an inline code block, it will also detect whitespace at the beginning and end of the selection and make sure that it's excluded from the surrounding backticks.
88 |
89 |
90 | ### Comment
91 |
92 | Turn selected text into an HTML or code comment.
93 |
94 | By default, it surrounds selected text with `` style comment tags. Hold various modifier keys to insert other types of comment markers:
95 |
96 | * **Option**: CSS Comment (`/* block of text */`)
97 | * **Command**: Hash Comment (`# before each line`)
98 | * **Command-Option**: Slash comment (`// before each line`)
99 |
100 |
101 | ### CopyCleanLinks
102 |
103 | PopClip extension to lengthen and clean URLs. Duplicate of LinkCleaner, but only copies results to the clipboard.
104 |
105 | Option: clean all query strings (default: only clean Google UTM strings)
106 | Command: Output just the resulting URL(s)
107 | Command-Option: Output just URL(s) with query strings stripped
108 |
109 |
110 | ### CopyPLUS
111 |
112 | PopClip extension to append the selection to the current contents in the clipboard. *This is a duplicate of an existing extension (Append) with just slightly better UTF-8 handling, and modifier key handling for copying with and without linebreaks and whitespace.*
113 |
114 | * Hold Command (⌘) when clicking to add an extra line break between entries.
115 | * Hold Option (⌥) to append with no extra whitespace.
116 |
117 |
118 | ### CopyURLS
119 |
120 | PopClip extension to copy just the URLS in selection.
121 |
122 | Duplicate of OpenURLS, but copies urls to the clipboard, one link per line, instead of opening in browser.
123 |
124 |
125 | ### CriticMarkup
126 |
127 | Allows the quick insertion of [CriticMarkup][] syntax. Optionally fill in a signature to have a comment included after every insert, deletion or change with your initials or name.
128 |
129 | - No modifier: Highlight
130 | - **Command**: Deletion
131 | - **Control**: Insertion
132 | - **Control-Option**: Change
133 | - **Option**: Comment
134 |
135 | [CriticMarkup]: http://criticmarkup.com/spec.php
136 |
137 | There _is_ a PopClip extension for CriticMarkup in the main download package, which I didn't realize when I whipped this one up. I may defer to that one eventually, but I'll wait until I figure out if mine adds anything worthwhile or not.
138 |
139 |
140 | ### DefineAbbr
141 |
142 | PopClip extension to search textingabbreviations.ca for the selected string.
143 |
144 |
145 | ### Editor
146 |
147 | Extension for adding HTML editor marks to text.
148 |
149 | - No modifier: `` (highlight)
150 | - **Control**: `` (insertion)
151 | - **Command**: `` (deletion)
152 | - **Option**: `` (comment)
153 |
154 |
155 | ### FixPoorlyObscuredEmails
156 |
157 | Fixes emails obscured in a "support AT mydomain DOT com" fashion.
158 |
159 | Hold Option to also open an email window for each matched address. This feature does not require edit capability in the current field.
160 |
161 |
162 | ### HardWrap
163 |
164 | Add hard wrapping to paragraphs. Default wrap column is 80, hold down Option to wrap at an alternate column (modify both in the extension options). Hold down command to unwrap text, removing line breaks between lines but preserving multiple lines between paragraphs.
165 |
166 | * Clicking wraps at ruler, default 80 characters
167 | * Option-click to wrap to alternate width
168 | * Command-click to unwrap text
169 |
170 |
171 |
172 | ### Increment Templated
173 |
174 | PopClip extension to increment and repeat templated text.
175 |
176 | Select and run on the following text:
177 |
178 | ```
179 | This is a numeric increment ##0..2##.
180 | ```
181 |
182 | Which will generate:
183 |
184 | ```
185 | This is a numeric increment 0.
186 | This is a numeric increment 1.
187 | ```
188 |
189 | Specify a value to increment by with `##START..INCREMENT..END##`, e.g. `##0..2..10##` would insert 0, 2, 4, 6, 8, and 10.
190 |
191 | 
192 |
193 | #### Placeholders
194 |
195 | You can use placeholders with basic math modification. `##x##` inserts the current element again. `##i##` inserts the 0-based index in the iteration. So if the template is `##5..7##`, on the second iteration `x` would hold `6` and `i` would hold `1`.
196 |
197 | Apply math functions to the placeholders using basic operator symbols (including `%` for mod). To insert the current value times 10, use `##x*10##`. More complex equations are allowed, e.g. `##(i+2)*10##`. Use `%` for modulus.
198 |
199 | You can include leading zeroes on math operations to pad the result. If you want to just pad the number without modifying, you would use `##x*0001##`, which would turn `5` into `0005` and `50` into `0050`. Including a 0 padding on any element of the equation will result in padded output.
200 |
201 |
202 | #### String Arrays
203 |
204 | You can also use arrays of strings or numbers:
205 |
206 | ```
207 | Hello ##mother,father,sister,brother##. And repeat with ##x##.
208 | ```
209 |
210 | Yields:
211 |
212 | ```
213 | Hello mother. And repeat with mother.
214 | Hello father. And repeat with father.
215 | Hello sister. And repeat with sister.
216 | Hello brother. And repeat with brother.
217 | ```
218 |
219 | The `##i##` placeholder (zero-based index) with math operators is also available in string array replacements. If you want the index to also refer to strings, add `#list,of,strings` after the index or equation, e.g. `##i%2#odd,even##` to insert `odd` and `even` alternately with each iteration.
220 |
221 | Example:
222 |
223 | ```
224 | .element-##one,two,three## {
225 | text-indent: ##i*10##px;
226 | }
227 | ```
228 |
229 | ```
230 | .element-one {
231 | text-indent: 0px;
232 | }
233 | .element-two {
234 | text-indent: 10px;
235 | }
236 | .element-three {
237 | text-indent: 20px;
238 | }
239 | ```
240 |
241 |
242 | ### LinkCleaner
243 |
244 | PopClip extension to lengthen and clean URLs.
245 |
246 | Use extension settings to determine whether it strips Google Analytics strings only, or _all_ query strings.
247 |
248 | - Option: force clean all query strings, ignore settings
249 | - Command: Output just the resulting URL(s)
250 | - Command-Option: Output just URL(s) with all query strings stripped
251 |
252 |
253 | ### Markdown to Mindmap
254 |
255 | Takes a selection of plain text containing markdown headlines, list items and paragraphs and converts it into a format ready for pasting into a mind mapping application (such as MindNode, MindManager or MindMeister) as separate nodes/topics.
256 |
257 |
258 | ### Markdownify
259 |
260 | Turn HTML text into Markdown using html2text.
261 |
262 |
263 | ### NumberedList
264 |
265 | PopClip extension to turn lines of text into Markdown numbered items. Will sort and update an existing numbered list as well, and convert bullets on list items to numbers.
266 |
267 | This is only here if you want a separate button for numbered lists. Otherwise you can just use BulletList and hold down option to create an ordered list instead.
268 |
269 |
270 | ### nvUltra
271 |
272 | [nvUltra](https://nvultra.com) extension for PopClip. Add text as new note to frontmost notebook, or define a notebook in settings.
273 |
274 | #### Credits
275 |
276 | Originally created by Marc Abramowitz - see [https://github.com/msabramo/nvALT.popclipext](https://github.com/msabramo/nvALT.popclipext). Icon and minor modifications by Nick Moore.
277 |
278 |
279 | ### OpenURLS
280 |
281 | PopClip extension to open all URLS in selection.
282 |
283 |
284 | ### Outdent
285 |
286 | Fully outdents the selection, maintaining nested indentation.
287 |
288 |
289 | ### PoorText
290 |
291 | Make rich text go broke.
292 |
293 | Strips rich text formatting from selection. There are probably multiple others that do this, but it's so easy I just made it myself.
294 |
295 |
296 | ### BulletList
297 |
298 | PopClip extension to turn lines of text into Markdown bullet items. Indentation is handled as nested lists and existing markers are overwritten (numbered list becomes bullet list).
299 |
300 | #### Numbered lists
301 |
302 | Holding Option (⌥) while clicking the button for the extension in the PopClip bar will create/update a numbered list instead. When the list is already a numbered list, it will be re-numbered to fix any gaps or out-of-order numbering within nest levels.
303 |
304 | #### Clear list formatting
305 |
306 | Holding Command (⌘) while clicking will remove all list prefixes.
307 |
308 | #### Bullet format
309 |
310 | When you install this extension, you'll get an options page where you can select the type of bullet you prefer for unordered lists. This can be accessed again later by clicking the pencil button at the bottom of the list, then clicking the gear button next to the BulletList extension.
311 |
312 |
313 | ### SkypeCall
314 |
315 | PopClip extension to call a number with Skype.
316 |
317 |
318 | ### Slugify
319 |
320 | Turn selected text into a valid post slug, lowercasing, deleting non-alphanumeric characters, and replacing spaces with hyphens.
321 |
322 | ### Sum
323 |
324 | Detect all numbers in selection and total them. Allows decimal places (using `.` or `,` as separator) and negative numbers. Result is copied to clipboard.
325 |
326 | Use the options "Separator" and "Decimal Delimiter" to define characters used in your locale for separating thousands and decimal places, respectively.
327 |
328 |
329 | ### Twitterify
330 |
331 | Convert all @names and #tags to Markdown or HTML links. You can set the default link type in the extension's options, and manually switch to the other type by holding down Option when running it.
332 |
333 |
334 | ### URLEncode
335 |
336 | Just URL encodes (percent encoding) the selected text using the Ruby URI gem.
337 |
338 | *Also available at [Pilot Moon](http://pilotmoon.com/popclip/extensions/page/URLEncode), same extension.*
339 |
340 |
341 | ### WebMarkdown
342 |
343 | Also known as WebMD, this extension shows up when you select text on a web page. Clicking it will convert the selected headlines, text and links (including image links) to Markdown in your clipboard.
344 |
345 | This extension uses [Gather](https://brettterpstra.com/projects/gather-cli) to markdownify the selection. If you don't have the `gather` CLI installed, WebMarkdown will offer to download and install it for you the first time you run it.
346 |
347 |
348 | ### Too Many Wrappers
349 |
350 | [Get it?](https://www.youtube.com/watch?v=HNB8pNqwrKw)
351 |
352 | Allows the definition of three custom "wrappers," prefixes and suffixes that will surround selected text. They're triggered, respectively, by clicking with the Option key, Command key or no modifier key held down.
353 |
354 | Think of it as a custom version of the comments plugin. I find it quite handy for adding ``, `` and `` tags to text when editing for others.
355 |
356 | When installing the extension, the options will appear. They can be accessed again by going into edit mode in the plugins dropdown and clicking the gear icon next to "Wrappers."
357 |
358 |
359 | ## Download
360 |
361 |
362 |
363 | The GitHub repository for all of my extensions is
364 | [here][github].
365 |
366 | ## Changelog
367 |
368 |
369 |
370 |
371 | See [the changelog on
372 | GitHub](https://github.com/ttscoff/popclipextensions/blob/master/CHANGELOG.md)
373 |
374 |
375 | [popclip]: http://pilotmoon.com/popclip/
376 | [github]: https://github.com/ttscoff/popclipextensions
377 |
378 |
--------------------------------------------------------------------------------
/SearchLink.popclipext/Config.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Actions
6 |
7 |
8 | Image File
9 | searchlink.png
10 | Script Interpreter
11 | /usr/bin/ruby
12 | Shell Script File
13 | searchlink.rb
14 | Title
15 | SearchLink
16 | After
17 | paste-result
18 | Requirements
19 |
20 | paste
21 |
22 |
23 |
24 | Credits
25 |
26 | Name
27 | Brett Terpstra
28 | Link
29 | http://brettterpstra.com/projects/searchlink
30 |
31 | Extension Description
32 | Run SearchLink on selected text for inline searching while writing.
33 | Extension Identifier
34 | com.brettterpstra.popclip.extension.searchlink
35 | Extension Name
36 | SearchLink
37 | Version
38 | 2
39 |
40 |
41 |
--------------------------------------------------------------------------------
/SearchLink.popclipext/README.md:
--------------------------------------------------------------------------------
1 | ### BulletList
2 |
3 | PopClip extension to turn lines of text into Markdown bullet items. Indentation is handled as nested lists and existing markers are overwritten (numbered list becomes bullet list).
4 |
5 | #### Numbered lists
6 |
7 | Holding Option (⌥) while clicking the button for the extension in the PopClip bar will create/update a numbered list instead. When the list is already a numbered list, it will be re-numbered to fix any gaps or out-of-order numbering within nest levels.
8 |
9 | #### Clear list formatting
10 |
11 | Holding Command (⌘) while clicking will remove all list prefixes.
12 |
13 | #### Bullet format
14 |
15 | When you install this extension, you'll get an options page where you can select the type of bullet you prefer for unordered lists. This can be accessed again later by clicking the pencil button at the bottom of the list, then clicking the gear button next to the BulletList extension.
16 |
--------------------------------------------------------------------------------
/SearchLink.popclipext/searchlink.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ttscoff/popclipextensions/81a97925c317a804ad731e348c57b3cf7a635b22/SearchLink.popclipext/searchlink.png
--------------------------------------------------------------------------------
/SearchLink.popclipext/searchlink.rb:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env ruby
2 | # frozen_string_literal: true
3 |
4 | require 'shellwords'
5 |
6 | input = ENV['POPCLIP_TEXT']
7 |
8 | def install_searchlink
9 | user = `whoami`.strip
10 | unless File.exist?(File.expand_path("/Users/#{user}/Library/Services/SearchLink.workflow"))
11 | folder = File.expand_path("/Users/#{user}/Downloads")
12 | services = File.expand_path("/Users/#{user}/Library/Services")
13 | dl = File.join(folder, 'SearchLink.zip')
14 | `curl -SsL -o "#{dl}" https://github.com/ttscoff/searchlink/releases/latest/download/SearchLink.zip`
15 | Dir.chdir(folder)
16 | `unzip -qo #{dl} -d #{folder}`
17 | FileUtils.rm(dl)
18 |
19 | ['SearchLink.workflow', 'SearchLink File.workflow', 'Jump to SearchLink Error.workflow'].each do |wflow|
20 | src = File.join(folder, 'SearchLink Services', wflow)
21 | dest = File.join(services, wflow)
22 | FileUtils.rm_rf(dest) if File.exist?(dest)
23 | FileUtils.mv(src, dest, force: true)
24 | end
25 | FileUtils.rm_rf('SearchLink Services')
26 | end
27 | end
28 |
29 | install_searchlink
30 | user = `whoami`.strip
31 | res = `echo #{Shellwords.escape(input)} | automator -i - /Users/#{user}/Library/Services/SearchLink.workflow`.strip
32 |
33 | res.gsub!(/'/, "\\\\'")
34 | res.gsub!(/^\(/, '[')
35 | res.gsub!(/\)$/, ']')
36 | res.gsub!(/^ "/, "'")
37 | res.gsub!(/",? *$/, "',")
38 |
39 | data = eval(res)
40 |
41 | print data.join("\n")
42 |
--------------------------------------------------------------------------------
/SkypeCall.popclipext/Config.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Actions
6 |
7 |
8 | Image File
9 | skypecall.png
10 | Script Interpreter
11 | /usr/bin/ruby
12 | Shell Script File
13 | skypecall.rb
14 | Title
15 | SkypeCall
16 | Regular Expression
17 | (?:(?:\+?1\s*(?:[.-]\s*)?)?(?:\(\s*([2-9]1[02-9]|[2-9][02-8]1|[2-9][02-8][02-9])\s*\)|([2-9]1[02-9]|[2-9][02-8]1|[2-9][02-8][02-9]))\s*(?:[.-]\s*)?)?([2-9]1[02-9]|[2-9][02-9]1|[2-9][02-9]{2})\s*(?:[.-]\s*)?([0-9]{4})(?:\s*(?:#|x\.?|ext\.?|extension)\s*(\d+))?
18 |
19 |
20 | Credits
21 |
22 | Name
23 | Brett Terpstra
24 | Link
25 | http://brettterpstra.com
26 |
27 | Extension Description
28 | Call the first phone number in selection with Skype.
29 | Extension Identifier
30 | com.brettterpstra.popclip.extension.skypecall
31 | Extension Name
32 | SkypeCall
33 | Version
34 | 2
35 |
36 |
37 |
--------------------------------------------------------------------------------
/SkypeCall.popclipext/README.md:
--------------------------------------------------------------------------------
1 | ### SkypeCall
2 |
3 | PopClip extension to call a number with Skype.
4 |
--------------------------------------------------------------------------------
/SkypeCall.popclipext/skypecall.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ttscoff/popclipextensions/81a97925c317a804ad731e348c57b3cf7a635b22/SkypeCall.popclipext/skypecall.png
--------------------------------------------------------------------------------
/SkypeCall.popclipext/skypecall.rb:
--------------------------------------------------------------------------------
1 | #!/usr/bin/ruby
2 |
3 | input = ENV['POPCLIP_TEXT']
4 | # input = "This is a phone number 8075555486 and this 1 (807) 555-5487 and this 555-5488"
5 |
6 | phone_numbers = input.scan(/(?:(?:\+?1\s*(?:[.-]\s*)?)?(?:\(\s*([2-9]1[02-9]|[2-9][02-8]1|[2-9][02-8][02-9])\s*\)|([2-9]1[02-9]|[2-9][02-8]1|[2-9][02-8][02-9]))\s*(?:[.-]\s*)?)?([2-9]1[02-9]|[2-9][02-9]1|[2-9][02-9]{2})\s*(?:[.-]\s*)?([0-9]{4})(?:\s*(?:#|x\.?|ext\.?|extension)\s*(\d+))?/)
7 | %x{/usr/bin/osascript -e 'set _cmd to "CALL #{phone_numbers[0].join("")}"' -e 'tell application "Skype" to send command _cmd script name "PCDIALER"'}
8 |
--------------------------------------------------------------------------------
/Slugify.popclipext/Config.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Actions
6 |
7 |
8 | Image File
9 | hyphen.png
10 | Script Interpreter
11 | /usr/bin/ruby
12 | Shell Script File
13 | slugger.rb
14 | Title
15 | -
16 | After
17 | paste-result
18 | Requirements
19 |
20 | paste
21 |
22 |
23 |
24 | Credits
25 |
26 | Name
27 | Brett Terpstra
28 | Link
29 | http://brettterpstra.com
30 |
31 | Extension Description
32 | Turn selected text into a valid post slug.
33 | Extension Identifier
34 | com.brettterpstra.popclip.extension.slugify
35 | Extension Name
36 | Slugify
37 | Version
38 | 2
39 |
40 |
41 |
--------------------------------------------------------------------------------
/Slugify.popclipext/README.md:
--------------------------------------------------------------------------------
1 | ### Slugify
2 |
3 | Turn selected text into a valid post slug, lowercasing, deleting non-alphanumeric characters, and replacing spaces with hyphens.
--------------------------------------------------------------------------------
/Slugify.popclipext/hyphen.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ttscoff/popclipextensions/81a97925c317a804ad731e348c57b3cf7a635b22/Slugify.popclipext/hyphen.png
--------------------------------------------------------------------------------
/Slugify.popclipext/slugger.rb:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env ruby
2 |
3 | clip = ENV['POPCLIP_TEXT']
4 |
5 | print clip.downcase
6 | .gsub(/\./, '-dot-')
7 | .gsub(/\+/, '-plus-')
8 | .gsub(/[^a-z0-9 \-.]/i, '')
9 | .gsub(/\s+/, '-')
10 | .gsub(/-+/, '-')
11 | .gsub(/^-/, '')
12 | .gsub(/(^-|-$)/, '')
13 |
--------------------------------------------------------------------------------
/Sum.popclipext/Config.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Actions
6 |
7 |
8 | Image File
9 | icon.png
10 | Script Interpreter
11 | /usr/bin/ruby
12 | Shell Script File
13 | script.rb
14 | Title
15 | Sum
16 | Regular Expression
17 | (?s)(.*)?\d+(.*)?
18 | After
19 | preview-result
20 |
21 |
22 | Options
23 |
24 |
25 | Option Identifier
26 | separator
27 | Option Type
28 | string
29 | Option Label
30 | Separator
31 | Option Default Value
32 | ,
33 |
34 |
35 | Option Identifier
36 | delimiter
37 | Option Type
38 | string
39 | Option Label
40 | Decimal Delimiter
41 | Option Default Value
42 | .
43 |
44 |
45 | Option Identifier
46 | formatoutput
47 | Option Type
48 | boolean
49 | Option Label
50 | Format Output
51 | Option Default Value
52 |
53 |
54 |
55 | Credits
56 |
57 | Name
58 | Brett Terpstra
59 | Link
60 | http://brettterpstra.com
61 |
62 | Extension Description
63 | Totals all numbers found in selection.
64 | Extension Identifier
65 | com.brettterpstra.popclip.extension.sum
66 | Extension Name
67 | Sum
68 | Version
69 | 2
70 |
71 |
72 |
--------------------------------------------------------------------------------
/Sum.popclipext/README.md:
--------------------------------------------------------------------------------
1 | ### Sum
2 |
3 | Detect all numbers in selection and total them. Allows decimal places (using `.` or `,` as separator) and negative numbers. Result is copied to clipboard.
4 |
5 | Use the options "Separator" and "Decimal Delimiter" to define characters used in your locale for separating thousands and decimal places, respectively.
6 |
--------------------------------------------------------------------------------
/Sum.popclipext/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ttscoff/popclipextensions/81a97925c317a804ad731e348c57b3cf7a635b22/Sum.popclipext/icon.png
--------------------------------------------------------------------------------
/Sum.popclipext/script.rb:
--------------------------------------------------------------------------------
1 | #!/usr/bin/ruby
2 | require 'shellwords'
3 |
4 | # 1.0
5 | # 2014-04-09
6 | #
7 | # Sums all numbers found in selection
8 |
9 | debug = ARGV[0] =~ /(debug|-?d)/ ? true : false
10 | decimal = ENV['POPCLIP_OPTION_DELIMITER']
11 | separator = ENV['POPCLIP_OPTION_SEPARATOR']
12 |
13 | def esc(char)
14 | return "\\#{char}"
15 | end
16 |
17 | def fmt( st, decimal, separator )
18 | mynum = st.to_s.reverse.scan(/(?:\d*#{esc(decimal)})?\d{1,3}-?/).join(separator).reverse
19 | dec = mynum.split(decimal)
20 | mynum = dec[0].to_s + decimal + dec[1].to_s if dec[1]
21 | mynum
22 | end
23 |
24 | begin
25 | unless debug
26 | if RUBY_VERSION.to_f > 1.9
27 | Encoding.default_external = Encoding::UTF_8
28 | Encoding.default_internal = Encoding::UTF_8
29 | input = ENV['POPCLIP_TEXT'].dup.force_encoding('utf-8')
30 | else
31 | input = ENV['POPCLIP_TEXT'].dup
32 | end
33 | else
34 | input = STDIN.read
35 | end
36 |
37 | total = 0
38 | places = 0
39 |
40 | input.scan(/(\-?[\d#{esc(separator)}]+(#{esc(decimal)}\d+)?)\b/).each {|x|
41 | total += x[0].gsub(/#{esc(separator)}/,'').sub(/#{esc(decimal)}/,'.').to_f
42 | places = x[1].length - 1 if x[1] && x[1].length.to_i > places + 1
43 | }
44 |
45 | # minimum 2 decimal places if any
46 | places = 2 if places == 1
47 |
48 | out = "%.#{places.to_i}f" % total
49 | do_format = ENV['POPCLIP_OPTION_FORMATOUTPUT'].to_i == 1 ? true : false
50 | print do_format ? fmt(out.sub(/\./,decimal), decimal, separator) : out.sub(/\./,decimal)
51 | rescue Exception => e
52 | %x{logger #{Shellwords.escape(e.to_s)}}
53 | STDERR.puts e
54 | end
55 |
--------------------------------------------------------------------------------
/Twitterify.popclipext/Config.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Actions
6 |
7 |
8 | Image File
9 | icon.png
10 | Script Interpreter
11 | /usr/bin/ruby
12 | Shell Script File
13 | script.rb
14 | Title
15 | Twitterify
16 | Regular Expression
17 | (?si)(.*)?(?:\s|^)[@#]\w+(.*)?
18 | After
19 | paste-result
20 | Requirements
21 |
22 | paste
23 |
24 |
25 |
26 | Options
27 |
28 |
29 | Option Identifier
30 | usemarkdown
31 | Option Type
32 | boolean
33 | Option Label
34 | Markdown Links
35 | Option Default Value
36 |
37 |
38 |
39 | Credits
40 |
41 | Name
42 | Brett Terpstra
43 | Link
44 | http://brettterpstra.com
45 |
46 | Extension Description
47 | Converts @names and #hashtags to Twitter urls.
48 | Extension Identifier
49 | com.brettterpstra.popclip.extension.twitterify
50 | Extension Name
51 | Twitterify
52 | Version
53 | 2
54 |
55 |
56 |
--------------------------------------------------------------------------------
/Twitterify.popclipext/README.md:
--------------------------------------------------------------------------------
1 | ### Twitterify
2 |
3 | Convert all @names and #tags to Markdown or HTML links. You can set the default link type in the extension's options, and manually switch to the other type by holding down Option when running it.
4 |
--------------------------------------------------------------------------------
/Twitterify.popclipext/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ttscoff/popclipextensions/81a97925c317a804ad731e348c57b3cf7a635b22/Twitterify.popclipext/icon.png
--------------------------------------------------------------------------------
/Twitterify.popclipext/script.rb:
--------------------------------------------------------------------------------
1 | #!/usr/bin/ruby
2 | require 'shellwords'
3 |
4 | debug = ARGV[0] =~ /(debug|-?d)/ ? true : false
5 |
6 | # Convert @ttscoff to
7 | # [@ttscoff](https://twitter.com/ttscoff)
8 | # Convert #hashtag to
9 | # [#hashtag](https://twitter.com/search?q=%23hashtag&src=hash)
10 |
11 | unless debug
12 | input = ENV['POPCLIP_TEXT'].dup
13 | else
14 | input =<#{match}"
32 | elsif match[0] == "#"
33 | markdown ? "#{$1}[\\#{match}](https://twitter.com/search?q=%23#{match[1..-1]}&src=hash)" : "#{$1}#{match}"
34 | else
35 | "#{$1}#{match}"
36 | end
37 | }
38 | print input
39 | rescue Exception => e
40 | %x{logger #{Shellwords.escape(e.to_s)}}
41 | STDERR.puts e
42 | end
43 |
--------------------------------------------------------------------------------
/URLEncode.popclipext/Config.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Version
6 | 2
7 | Extension Description
8 | Percent encode selected text.
9 | Extension Name
10 | URLEncode
11 | Extension Identifier
12 | com.brettterpstra.popclip.extension.urlencode
13 | Actions
14 |
15 |
16 | Shell Script File
17 | urlencode.rb
18 | Script Interpreter
19 | /usr/bin/env ruby
20 | Title
21 | %
22 | After
23 | paste-result
24 | Requirements
25 |
26 | paste
27 |
28 |
29 |
30 | Credits
31 |
32 | Name
33 | Brett Terpstra
34 | Link
35 | http://brettterpstra.com
36 |
37 |
38 |
39 |
--------------------------------------------------------------------------------
/URLEncode.popclipext/README.md:
--------------------------------------------------------------------------------
1 | ### URLEncode
2 |
3 | Just URL encodes (percent encoding) the selected text using the Ruby URI gem.
4 |
5 | *Also available at [Pilot Moon](http://pilotmoon.com/popclip/extensions/page/URLEncode), same extension.*
6 |
--------------------------------------------------------------------------------
/URLEncode.popclipext/urlencode.rb:
--------------------------------------------------------------------------------
1 | #!/usr/bin/ruby
2 |
3 | require 'uri'
4 |
5 | print URI.encode(ENV['POPCLIP_TEXT'])
6 |
--------------------------------------------------------------------------------
/VERSION:
--------------------------------------------------------------------------------
1 | 1.44
2 |
--------------------------------------------------------------------------------
/WebMarkdown.popclipext/Config.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Actions
6 |
7 |
8 | Script Interpreter
9 | /bin/bash
10 | Shell Script File
11 | process.sh
12 | Title
13 | WebMD
14 | Pass HTML
15 |
16 | After
17 | copy-result
18 |
19 |
20 | Requirements
21 |
22 | html
23 |
24 | Credits
25 |
26 | Name
27 | Brett Terpstra
28 | Link
29 | http://brettterpstra.com
30 |
31 | Extension Description
32 | Converts text selected in a browser to Markdown in the clipboard.
33 | Extension Identifier
34 | com.brettterpstra.popclip.extension.webmarkdown
35 | Extension Name
36 | WebMarkdown
37 | Version
38 | 2
39 |
40 |
41 |
--------------------------------------------------------------------------------
/WebMarkdown.popclipext/README.md:
--------------------------------------------------------------------------------
1 | ### WebMarkdown
2 |
3 | Also known as WebMD, this extension shows up when you select text on a web page. Clicking it will convert the selected headlines, text and links (including image links) to Markdown in your clipboard.
4 |
5 | This extension uses [Gather](https://brettterpstra.com/projects/gather-cli) to markdownify the selection. If you don't have the `gather` CLI installed, WebMarkdown will offer to download and install it for you the first time you run it.
6 |
--------------------------------------------------------------------------------
/WebMarkdown.popclipext/download.applescript:
--------------------------------------------------------------------------------
1 | tell application "PopClip"
2 | activate
3 | set _res to display dialog "This extension requires gather-cli, would you like to install it now?" buttons {"Later", "Manual Install", "Automatic Install"} default button "Automatic Install"
4 | if button returned of _res is "Automatic Install" then
5 | set _res to display dialog "A package will be downloaded and you'll be presented an install dialog in a moment." buttons {"Cancel", "OK"} default button "OK"
6 | if button returned of _res is "OK" then
7 | do shell script "curl -SsL --output-dir /tmp -O https://cdn3.brettterpstra.com/downloads/gather-cli-latest.pkg && open -W /tmp/gather-cli-latest.pkg"
8 | display dialog "If all went well, you can now use WebMarkdown. If you ran into any trouble, run WebMarkdown again and choose Manual Install." buttons {"OK"} default button 1
9 | end if
10 | else if button returned of _res is "Manual Install" then
11 | display dialog "Your browser will now be directed to the download page. Please follow the install instructions there" buttons {"OK"} default button 1
12 | open location "https://brettterpstra.com/projects/gather-cli/"
13 | else
14 | display dialog "You won't be able to use WebMarkdown until you install the CLI." buttons {"Got it"} default button 1
15 | end if
16 | end tell
17 |
--------------------------------------------------------------------------------
/WebMarkdown.popclipext/process.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | GATHER=/usr/local/bin/gather
4 | if [[ ! -e $GATHER ]]; then
5 | GATHER=/opt/homebrew/bin/gather
6 | if [[ ! -e $GATHER ]]; then
7 | osascript download.applescript
8 | exit 1
9 | fi
10 | fi
11 |
12 | $GATHER --env POPCLIP_HTML --no-readability --html
13 |
--------------------------------------------------------------------------------
/Wrappers.popclipext/Config.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Actions
6 |
7 |
8 | Image File
9 | wrapped.png
10 | Script Interpreter
11 | /usr/bin/ruby
12 | Shell Script File
13 | script.rb
14 | Title
15 | wrap
16 | After
17 | paste-result
18 | Requirements
19 |
20 | paste
21 |
22 |
23 |
24 | Options
25 |
26 |
27 | Option Identifier
28 | popmakerprefix
29 | Option Type
30 | string
31 | Option Label
32 | Prefix
33 |
34 |
35 | Option Identifier
36 | popmakersuffix
37 | Option Type
38 | string
39 | Option Label
40 | Suffix
41 |
42 |
43 | Option Identifier
44 | popmakeroptprefix
45 | Option Type
46 | string
47 | Option Label
48 | ⌥ Prefix
49 |
50 |
51 | Option Identifier
52 | popmakeroptsuffix
53 | Option Type
54 | string
55 | Option Label
56 | ⌥ Suffix
57 |
58 |
59 | Option Identifier
60 | popmakercmdprefix
61 | Option Type
62 | string
63 | Option Label
64 | ⌘ Prefix
65 |
66 |
67 | Option Identifier
68 | popmakercmdsuffix
69 | Option Type
70 | string
71 | Option Label
72 | ⌘ Suffix
73 |
74 |
75 | Credits
76 |
77 | Name
78 | Brett Terpstra
79 | Link
80 | http://brettterpstra.com
81 |
82 | Extension Description
83 | Too many wrappers
84 | Extension Identifier
85 | com.brettterpstra.popclip.extension.wrapper
86 | Extension Name
87 | Wrappers
88 | Version
89 | 2
90 |
91 |
92 |
--------------------------------------------------------------------------------
/Wrappers.popclipext/README.md:
--------------------------------------------------------------------------------
1 | ### Too Many Wrappers
2 |
3 | [Get it?](https://www.youtube.com/watch?v=HNB8pNqwrKw)
4 |
5 | Allows the definition of three custom "wrappers," prefixes and suffixes that will surround selected text. They're triggered, respectively, by clicking with the Option key, Command key or no modifier key held down.
6 |
7 | Think of it as a custom version of the comments plugin. I find it quite handy for adding ``, `` and `` tags to text when editing for others.
8 |
9 | When installing the extension, the options will appear. They can be accessed again by going into edit mode in the plugins dropdown and clicking the gear icon next to "Wrappers."
10 |
--------------------------------------------------------------------------------
/Wrappers.popclipext/script.rb:
--------------------------------------------------------------------------------
1 | #!/usr/bin/ruby
2 |
3 | prefix = ENV['POPCLIP_OPTION_POPMAKERPREFIX']
4 | suffix = ENV['POPCLIP_OPTION_POPMAKERSUFFIX']
5 | optprefix = ENV['POPCLIP_OPTION_POPMAKEROPTPREFIX']# == "" ? prefix : ENV['POPCLIP_OPTION_POPMAKEROPTPREFIX']
6 | optsuffix = ENV['POPCLIP_OPTION_POPMAKEROPTSUFFIX']# == "" ? suffix : ENV['POPCLIP_OPTION_POPMAKEROPTSUFFIX']
7 | cmdprefix = ENV['POPCLIP_OPTION_POPMAKERCMDPREFIX']# == "" ? prefix : ENV['POPCLIP_OPTION_POPMAKERCMDPREFIX']
8 | cmdsuffix = ENV['POPCLIP_OPTION_POPMAKERCMDSUFFIX']# == "" ? suffix : ENV['POPCLIP_OPTION_POPMAKERCMDSUFFIX']
9 | ## Shift key is causing weirdness
10 | # shiftprefix = ENV['POPCLIP_OPTION_POPMAKERSHIFTPREFIX'] == "" ? prefix : ENV['POPCLIP_OPTION_POPMAKERSHIFTPREFIX']
11 | # shiftsuffix = ENV['POPCLIP_OPTION_POPMAKERSHIFTSUFFIX'] == "" ? suffix : ENV['POPCLIP_OPTION_POPMAKERSHIFTSUFFIX']
12 | input = ENV['POPCLIP_TEXT']
13 |
14 | # fixes = %w{prefix suffix optprefix optsuffix cmdprefix cmdsuffix shiftprefix shiftsuffix}
15 |
16 | # fixes.each {|var|
17 | # eval("#{var} ||= #{var} =~ /prefix/ ? prefix : suffix"
18 | # }
19 |
20 | space = input.match(/^([\s\n]*)\S.*?([\s\n]*)$/m)
21 | case ENV['POPCLIP_MODIFIER_FLAGS'].to_i
22 | when 1048576 # Command
23 | print "#{space[1]}#{cmdprefix}#{input.strip}#{cmdsuffix}#{space[2]}"
24 | when 524288 # Option
25 | print "#{space[1]}#{optprefix}#{input.strip}#{optsuffix}#{space[2]}"
26 | # when 131072 # Shift
27 | # print "#{space[1]}#{shiftprefix}#{input.strip}#{shiftsuffix}#{space[2]}"
28 | else # none
29 | print "#{space[1]}#{prefix}#{input.strip}#{suffix}#{space[2]}"
30 | end
31 |
32 |
33 |
34 |
--------------------------------------------------------------------------------
/Wrappers.popclipext/wrapped.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ttscoff/popclipextensions/81a97925c317a804ad731e348c57b3cf7a635b22/Wrappers.popclipext/wrapped.png
--------------------------------------------------------------------------------
/increment.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ttscoff/popclipextensions/81a97925c317a804ad731e348c57b3cf7a635b22/increment.gif
--------------------------------------------------------------------------------
/markdownify.popclipext/Config.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Version
6 | 2
7 | Extension Name
8 | Markdownify
9 | Extension Identifier
10 | com.brettterpstra.popclip.extension.markdownify
11 | Actions
12 |
13 |
14 | Shell Script File
15 | markdownify.py
16 | Script Interpreter
17 | /usr/bin/python
18 | Title
19 | 2MD
20 | After
21 | paste-result
22 | Requirements
23 |
24 | paste
25 |
26 |
27 |
28 | Credits
29 |
30 | Name
31 | Brett Terpstra
32 | Link
33 | http://brettterpstra.com
34 |
35 |
36 |
37 |
--------------------------------------------------------------------------------
/markdownify.popclipext/README.md:
--------------------------------------------------------------------------------
1 | ### Markdownify
2 |
3 | Turn HTML text into Markdown using html2text.
4 |
--------------------------------------------------------------------------------
/markdownify.popclipext/markdownify.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | """html2text: Turn HTML into equivalent Markdown-structured text."""
3 | __version__ = "3.200.3"
4 | __author__ = "Aaron Swartz (me@aaronsw.com)"
5 | __copyright__ = "(C) 2004-2008 Aaron Swartz. GNU GPL 3."
6 | __contributors__ = ["Martin 'Joey' Schulze", "Ricardo Reyes", "Kevin Jay North"]
7 |
8 | # TODO:
9 | # Support decoded entities with unifiable.
10 | import os
11 |
12 | try:
13 | True
14 | except NameError:
15 | setattr(__builtins__, 'True', 1)
16 | setattr(__builtins__, 'False', 0)
17 |
18 | def has_key(x, y):
19 | if hasattr(x, 'has_key'): return x.has_key(y)
20 | else: return y in x
21 |
22 | try:
23 | import htmlentitydefs
24 | import urlparse
25 | import HTMLParser
26 | except ImportError: #Python3
27 | import html.entities as htmlentitydefs
28 | import urllib.parse as urlparse
29 | import html.parser as HTMLParser
30 | try: #Python3
31 | import urllib.request as urllib
32 | except:
33 | import urllib
34 | import optparse, re, sys, codecs, types
35 |
36 | try: from textwrap import wrap
37 | except: pass
38 |
39 | # Use Unicode characters instead of their ascii psuedo-replacements
40 | UNICODE_SNOB = 0
41 |
42 | # Put the links after each paragraph instead of at the end.
43 | LINKS_EACH_PARAGRAPH = 0
44 |
45 | # Wrap long lines at position. 0 for no wrapping. (Requires Python 2.3.)
46 | BODY_WIDTH = 0
47 |
48 | # Don't show internal links (href="#local-anchor") -- corresponding link targets
49 | # won't be visible in the plain text file anyway.
50 | SKIP_INTERNAL_LINKS = True
51 |
52 | # Use inline, rather than reference, formatting for images and links
53 | INLINE_LINKS = False
54 |
55 | # Number of pixels Google indents nested lists
56 | GOOGLE_LIST_INDENT = 36
57 |
58 | IGNORE_ANCHORS = False
59 | IGNORE_IMAGES = False
60 | IGNORE_EMPHASIS = False
61 |
62 | ### Entity Nonsense ###
63 |
64 | def name2cp(k):
65 | if k == 'apos': return ord("'")
66 | if hasattr(htmlentitydefs, "name2codepoint"): # requires Python 2.3
67 | return htmlentitydefs.name2codepoint[k]
68 | else:
69 | k = htmlentitydefs.entitydefs[k]
70 | if k.startswith("") and k.endswith(";"): return int(k[2:-1]) # not in latin-1
71 | return ord(codecs.latin_1_decode(k)[0])
72 |
73 | unifiable = {'rsquo':"'", 'lsquo':"'", 'rdquo':'"', 'ldquo':'"',
74 | 'copy':'(C)', 'mdash':'--', 'nbsp':' ', 'rarr':'->', 'larr':'<-', 'middot':'*',
75 | 'ndash':'-', 'oelig':'oe', 'aelig':'ae',
76 | 'agrave':'a', 'aacute':'a', 'acirc':'a', 'atilde':'a', 'auml':'a', 'aring':'a',
77 | 'egrave':'e', 'eacute':'e', 'ecirc':'e', 'euml':'e',
78 | 'igrave':'i', 'iacute':'i', 'icirc':'i', 'iuml':'i',
79 | 'ograve':'o', 'oacute':'o', 'ocirc':'o', 'otilde':'o', 'ouml':'o',
80 | 'ugrave':'u', 'uacute':'u', 'ucirc':'u', 'uuml':'u',
81 | 'lrm':'', 'rlm':''}
82 |
83 | unifiable_n = {}
84 |
85 | for k in unifiable.keys():
86 | unifiable_n[name2cp(k)] = unifiable[k]
87 |
88 | ### End Entity Nonsense ###
89 |
90 | def onlywhite(line):
91 | """Return true if the line does only consist of whitespace characters."""
92 | for c in line:
93 | if c is not ' ' and c is not ' ':
94 | return c is ' '
95 | return line
96 |
97 | def hn(tag):
98 | if tag[0] == 'h' and len(tag) == 2:
99 | try:
100 | n = int(tag[1])
101 | if n in range(1, 10): return n
102 | except ValueError: return 0
103 |
104 | def dumb_property_dict(style):
105 | """returns a hash of css attributes"""
106 | return dict([(x.strip(), y.strip()) for x, y in [z.split(':', 1) for z in style.split(';') if ':' in z]]);
107 |
108 | def dumb_css_parser(data):
109 | """returns a hash of css selectors, each of which contains a hash of css attributes"""
110 | # remove @import sentences
111 | importIndex = data.find('@import')
112 | while importIndex != -1:
113 | data = data[0:importIndex] + data[data.find(';', importIndex) + 1:]
114 | importIndex = data.find('@import')
115 |
116 | # parse the css. reverted from dictionary compehension in order to support older pythons
117 | elements = [x.split('{') for x in data.split('}') if '{' in x.strip()]
118 | try:
119 | elements = dict([(a.strip(), dumb_property_dict(b)) for a, b in elements])
120 | except ValueError:
121 | elements = {} # not that important
122 |
123 | return elements
124 |
125 | def element_style(attrs, style_def, parent_style):
126 | """returns a hash of the 'final' style attributes of the element"""
127 | style = parent_style.copy()
128 | if 'class' in attrs:
129 | for css_class in attrs['class'].split():
130 | css_style = style_def['.' + css_class]
131 | style.update(css_style)
132 | if 'style' in attrs:
133 | immediate_style = dumb_property_dict(attrs['style'])
134 | style.update(immediate_style)
135 | return style
136 |
137 | def google_list_style(style):
138 | """finds out whether this is an ordered or unordered list"""
139 | if 'list-style-type' in style:
140 | list_style = style['list-style-type']
141 | if list_style in ['disc', 'circle', 'square', 'none']:
142 | return 'ul'
143 | return 'ol'
144 |
145 | def google_has_height(style):
146 | """check if the style of the element has the 'height' attribute explicitly defined"""
147 | if 'height' in style:
148 | return True
149 | return False
150 |
151 | def google_text_emphasis(style):
152 | """return a list of all emphasis modifiers of the element"""
153 | emphasis = []
154 | if 'text-decoration' in style:
155 | emphasis.append(style['text-decoration'])
156 | if 'font-style' in style:
157 | emphasis.append(style['font-style'])
158 | if 'font-weight' in style:
159 | emphasis.append(style['font-weight'])
160 | return emphasis
161 |
162 | def google_fixed_width_font(style):
163 | """check if the css of the current element defines a fixed width font"""
164 | font_family = ''
165 | if 'font-family' in style:
166 | font_family = style['font-family']
167 | if 'Courier New' == font_family or 'Consolas' == font_family:
168 | return True
169 | return False
170 |
171 | def list_numbering_start(attrs):
172 | """extract numbering from list element attributes"""
173 | if 'start' in attrs:
174 | return int(attrs['start']) - 1
175 | else:
176 | return 0
177 |
178 | class HTML2Text(HTMLParser.HTMLParser):
179 | def __init__(self, out=None, baseurl=''):
180 | HTMLParser.HTMLParser.__init__(self)
181 |
182 | # Config options
183 | self.unicode_snob = UNICODE_SNOB
184 | self.links_each_paragraph = LINKS_EACH_PARAGRAPH
185 | self.body_width = BODY_WIDTH
186 | self.skip_internal_links = SKIP_INTERNAL_LINKS
187 | self.inline_links = INLINE_LINKS
188 | self.google_list_indent = GOOGLE_LIST_INDENT
189 | self.ignore_links = IGNORE_ANCHORS
190 | self.ignore_images = IGNORE_IMAGES
191 | self.ignore_emphasis = IGNORE_EMPHASIS
192 | self.google_doc = False
193 | self.ul_item_mark = '*'
194 |
195 | if out is None: self.out = self.outtextf
196 | else: self.out = out
197 | self.outtextlist = [] # empty list to store output characters before they are "joined"
198 | try:
199 | self.outtext = unicode()
200 | except NameError: # Python3
201 | self.outtext = str()
202 | self.quiet = 0
203 | self.p_p = 0 # number of newline character to print before next output
204 | self.outcount = 0
205 | self.start = 1
206 | self.space = 0
207 | self.a = []
208 | self.astack = []
209 | self.acount = 0
210 | self.list = []
211 | self.blockquote = 0
212 | self.pre = 0
213 | self.startpre = 0
214 | self.code = False
215 | self.br_toggle = ''
216 | self.lastWasNL = 0
217 | self.lastWasList = False
218 | self.style = 0
219 | self.style_def = {}
220 | self.tag_stack = []
221 | self.emphasis = 0
222 | self.drop_white_space = 0
223 | self.inheader = False
224 | self.abbr_title = None # current abbreviation definition
225 | self.abbr_data = None # last inner HTML (for abbr being defined)
226 | self.abbr_list = {} # stack of abbreviations to write later
227 | self.baseurl = baseurl
228 |
229 | try: del unifiable_n[name2cp('nbsp')]
230 | except KeyError: pass
231 | unifiable['nbsp'] = ' _place_holder;'
232 |
233 |
234 | def feed(self, data):
235 | data = data.replace("' + 'script>", "")
236 | HTMLParser.HTMLParser.feed(self, data)
237 |
238 | def handle(self, data):
239 | self.feed(data)
240 | self.feed("")
241 | return self.optwrap(self.close())
242 |
243 | def outtextf(self, s):
244 | self.outtextlist.append(s)
245 | if s: self.lastWasNL = s[-1] == '\n'
246 |
247 | def close(self):
248 | HTMLParser.HTMLParser.close(self)
249 |
250 | self.pbr()
251 | self.o('', 0, 'end')
252 |
253 | self.outtext = self.outtext.join(self.outtextlist)
254 |
255 | if self.google_doc:
256 | self.outtext = self.outtext.replace(' _place_holder;', ' ');
257 |
258 | return self.outtext
259 |
260 | def handle_charref(self, c):
261 | self.o(self.charref(c), 1)
262 |
263 | def handle_entityref(self, c):
264 | self.o(self.entityref(c), 1)
265 |
266 | def handle_starttag(self, tag, attrs):
267 | self.handle_tag(tag, attrs, 1)
268 |
269 | def handle_endtag(self, tag):
270 | self.handle_tag(tag, None, 0)
271 |
272 | def previousIndex(self, attrs):
273 | """ returns the index of certain set of attributes (of a link) in the
274 | self.a list
275 |
276 | If the set of attributes is not found, returns None
277 | """
278 | if not has_key(attrs, 'href'): return None
279 |
280 | i = -1
281 | for a in self.a:
282 | i += 1
283 | match = 0
284 |
285 | if has_key(a, 'href') and a['href'] == attrs['href']:
286 | if has_key(a, 'title') or has_key(attrs, 'title'):
287 | if (has_key(a, 'title') and has_key(attrs, 'title') and
288 | a['title'] == attrs['title']):
289 | match = True
290 | else:
291 | match = True
292 |
293 | if match: return i
294 |
295 | def drop_last(self, nLetters):
296 | if not self.quiet:
297 | self.outtext = self.outtext[:-nLetters]
298 |
299 | def handle_emphasis(self, start, tag_style, parent_style):
300 | """handles various text emphases"""
301 | tag_emphasis = google_text_emphasis(tag_style)
302 | parent_emphasis = google_text_emphasis(parent_style)
303 |
304 | # handle Google's text emphasis
305 | strikethrough = 'line-through' in tag_emphasis and self.hide_strikethrough
306 | bold = 'bold' in tag_emphasis and not 'bold' in parent_emphasis
307 | italic = 'italic' in tag_emphasis and not 'italic' in parent_emphasis
308 | fixed = google_fixed_width_font(tag_style) and not \
309 | google_fixed_width_font(parent_style) and not self.pre
310 |
311 | if start:
312 | # crossed-out text must be handled before other attributes
313 | # in order not to output qualifiers unnecessarily
314 | if bold or italic or fixed:
315 | self.emphasis += 1
316 | if strikethrough:
317 | self.quiet += 1
318 | if italic:
319 | self.o("_")
320 | self.drop_white_space += 1
321 | if bold:
322 | self.o("**")
323 | self.drop_white_space += 1
324 | if fixed:
325 | self.o('`')
326 | self.drop_white_space += 1
327 | self.code = True
328 | else:
329 | if bold or italic or fixed:
330 | # there must not be whitespace before closing emphasis mark
331 | self.emphasis -= 1
332 | self.space = 0
333 | self.outtext = self.outtext.rstrip()
334 | if fixed:
335 | if self.drop_white_space:
336 | # empty emphasis, drop it
337 | self.drop_last(1)
338 | self.drop_white_space -= 1
339 | else:
340 | self.o('`')
341 | self.code = False
342 | if bold:
343 | if self.drop_white_space:
344 | # empty emphasis, drop it
345 | self.drop_last(2)
346 | self.drop_white_space -= 1
347 | else:
348 | self.o("**")
349 | if italic:
350 | if self.drop_white_space:
351 | # empty emphasis, drop it
352 | self.drop_last(1)
353 | self.drop_white_space -= 1
354 | else:
355 | self.o("_")
356 | # space is only allowed after *all* emphasis marks
357 | if (bold or italic) and not self.emphasis:
358 | self.o(" ")
359 | if strikethrough:
360 | self.quiet -= 1
361 |
362 | def handle_tag(self, tag, attrs, start):
363 | #attrs = fixattrs(attrs)
364 | if attrs is None:
365 | attrs = {}
366 | else:
367 | attrs = dict(attrs)
368 |
369 | if self.google_doc:
370 | # the attrs parameter is empty for a closing tag. in addition, we
371 | # need the attributes of the parent nodes in order to get a
372 | # complete style description for the current element. we assume
373 | # that google docs export well formed html.
374 | parent_style = {}
375 | if start:
376 | if self.tag_stack:
377 | parent_style = self.tag_stack[-1][2]
378 | tag_style = element_style(attrs, self.style_def, parent_style)
379 | self.tag_stack.append((tag, attrs, tag_style))
380 | else:
381 | dummy, attrs, tag_style = self.tag_stack.pop()
382 | if self.tag_stack:
383 | parent_style = self.tag_stack[-1][2]
384 |
385 | if hn(tag):
386 | self.p()
387 | if start:
388 | self.inheader = True
389 | self.o(hn(tag)*"#" + ' ')
390 | else:
391 | self.inheader = False
392 | return # prevent redundant emphasis marks on headers
393 |
394 | if tag in ['p', 'div']:
395 | if self.google_doc:
396 | if start and google_has_height(tag_style):
397 | self.p()
398 | else:
399 | self.soft_br()
400 | else:
401 | self.p()
402 |
403 | if tag == "br" and start: self.o(" \n")
404 |
405 | if tag == "hr" and start:
406 | self.p()
407 | self.o("* * *")
408 | self.p()
409 |
410 | if tag in ["head", "style", 'script']:
411 | if start: self.quiet += 1
412 | else: self.quiet -= 1
413 |
414 | if tag == "style":
415 | if start: self.style += 1
416 | else: self.style -= 1
417 |
418 | if tag in ["body"]:
419 | self.quiet = 0 # sites like 9rules.com never close
420 |
421 | if tag == "blockquote":
422 | if start:
423 | self.p(); self.o('> ', 0, 1); self.start = 1
424 | self.blockquote += 1
425 | else:
426 | self.blockquote -= 1
427 | self.p()
428 |
429 | if tag in ['em', 'i', 'u'] and not self.ignore_emphasis: self.o("_")
430 | if tag in ['strong', 'b'] and not self.ignore_emphasis: self.o("**")
431 | if tag in ['del', 'strike']:
432 | if start:
433 | self.o("<"+tag+">")
434 | else:
435 | self.o(""+tag+">")
436 |
437 | if self.google_doc:
438 | if not self.inheader:
439 | # handle some font attributes, but leave headers clean
440 | self.handle_emphasis(start, tag_style, parent_style)
441 |
442 | if tag in ["code", "tt"] and not self.pre: self.o('`') #TODO: `` `this` ``
443 | if tag == "abbr":
444 | if start:
445 | self.abbr_title = None
446 | self.abbr_data = ''
447 | if has_key(attrs, 'title'):
448 | self.abbr_title = attrs['title']
449 | else:
450 | if self.abbr_title != None:
451 | self.abbr_list[self.abbr_data] = self.abbr_title
452 | self.abbr_title = None
453 | self.abbr_data = ''
454 |
455 | if tag == "a" and not self.ignore_links:
456 | if start:
457 | if has_key(attrs, 'href') and not (self.skip_internal_links and attrs['href'].startswith('#')):
458 | self.astack.append(attrs)
459 | self.o("[")
460 | else:
461 | self.astack.append(None)
462 | else:
463 | if self.astack:
464 | a = self.astack.pop()
465 | if a:
466 | if self.inline_links:
467 | self.o("](" + a['href'] + ")")
468 | else:
469 | i = self.previousIndex(a)
470 | if i is not None:
471 | a = self.a[i]
472 | else:
473 | self.acount += 1
474 | a['count'] = self.acount
475 | a['outcount'] = self.outcount
476 | self.a.append(a)
477 | self.o("][" + str(a['count']) + "]")
478 |
479 | if tag == "img" and start and not self.ignore_images:
480 | if has_key(attrs, 'src'):
481 | attrs['href'] = attrs['src']
482 | alt = attrs.get('alt', '')
483 | if self.inline_links:
484 | self.o("")
487 | else:
488 | i = self.previousIndex(attrs)
489 | if i is not None:
490 | attrs = self.a[i]
491 | else:
492 | self.acount += 1
493 | attrs['count'] = self.acount
494 | attrs['outcount'] = self.outcount
495 | self.a.append(attrs)
496 | self.o("![")
497 | self.o(alt)
498 | self.o("]["+ str(attrs['count']) +"]")
499 |
500 | if tag == 'dl' and start: self.p()
501 | if tag == 'dt' and not start: self.pbr()
502 | if tag == 'dd' and start: self.o(' ')
503 | if tag == 'dd' and not start: self.pbr()
504 |
505 | if tag in ["ol", "ul"]:
506 | # Google Docs create sub lists as top level lists
507 | if (not self.list) and (not self.lastWasList):
508 | self.p()
509 | if start:
510 | if self.google_doc:
511 | list_style = google_list_style(tag_style)
512 | else:
513 | list_style = tag
514 | numbering_start = list_numbering_start(attrs)
515 | self.list.append({'name':list_style, 'num':numbering_start})
516 | else:
517 | if self.list: self.list.pop()
518 | self.lastWasList = True
519 | else:
520 | self.lastWasList = False
521 |
522 | if tag == 'li':
523 | self.pbr()
524 | if start:
525 | if self.list: li = self.list[-1]
526 | else: li = {'name':'ul', 'num':0}
527 | if self.google_doc:
528 | nest_count = self.google_nest_count(tag_style)
529 | else:
530 | nest_count = len(self.list)
531 | self.o(" " * nest_count) #TODO: line up - s > 9 correctly.
532 | if li['name'] == "ul": self.o(self.ul_item_mark + " ")
533 | elif li['name'] == "ol":
534 | li['num'] += 1
535 | self.o(str(li['num'])+". ")
536 | self.start = 1
537 |
538 | if tag in ["table", "tr"] and start: self.p()
539 | if tag == 'td': self.pbr()
540 |
541 | if tag == "pre":
542 | if start:
543 | self.startpre = 1
544 | self.pre = 1
545 | else:
546 | self.pre = 0
547 | self.p()
548 |
549 | def pbr(self):
550 | if self.p_p == 0: self.p_p = 1
551 |
552 | def p(self): self.p_p = 2
553 |
554 | def soft_br(self):
555 | self.pbr()
556 | self.br_toggle = ' '
557 |
558 | def o(self, data, puredata=0, force=0):
559 | if self.abbr_data is not None: self.abbr_data += data
560 |
561 | if not self.quiet:
562 | if self.google_doc:
563 | # prevent white space immediately after 'begin emphasis' marks ('**' and '_')
564 | lstripped_data = data.lstrip()
565 | if self.drop_white_space and not (self.pre or self.code):
566 | data = lstripped_data
567 | if lstripped_data != '':
568 | self.drop_white_space = 0
569 |
570 | if puredata and not self.pre:
571 | data = re.sub('\s+', ' ', data)
572 | if data and data[0] == ' ':
573 | self.space = 1
574 | data = data[1:]
575 | if not data and not force: return
576 |
577 | if self.startpre:
578 | #self.out(" :") #TODO: not output when already one there
579 | self.startpre = 0
580 |
581 | bq = (">" * self.blockquote)
582 | if not (force and data and data[0] == ">") and self.blockquote: bq += " "
583 |
584 | if self.pre:
585 | bq += " "
586 | data = data.replace("\n", "\n"+bq)
587 |
588 | if self.start:
589 | self.space = 0
590 | self.p_p = 0
591 | self.start = 0
592 |
593 | if force == 'end':
594 | # It's the end.
595 | self.p_p = 0
596 | self.out("\n")
597 | self.space = 0
598 |
599 | if self.p_p:
600 | self.out((self.br_toggle+'\n'+bq)*self.p_p)
601 | self.space = 0
602 | self.br_toggle = ''
603 |
604 | if self.space:
605 | if not self.lastWasNL: self.out(' ')
606 | self.space = 0
607 |
608 | if self.a and ((self.p_p == 2 and self.links_each_paragraph) or force == "end"):
609 | if force == "end": self.out("\n")
610 |
611 | newa = []
612 | for link in self.a:
613 | if self.outcount > link['outcount']:
614 | self.out(" ["+ str(link['count']) +"]: " + urlparse.urljoin(self.baseurl, link['href']))
615 | if has_key(link, 'title'): self.out(" ("+link['title']+")")
616 | self.out("\n")
617 | else:
618 | newa.append(link)
619 |
620 | if self.a != newa: self.out("\n") # Don't need an extra line when nothing was done.
621 |
622 | self.a = newa
623 |
624 | if self.abbr_list and force == "end":
625 | for abbr, definition in self.abbr_list.items():
626 | self.out(" *[" + abbr + "]: " + definition + "\n")
627 |
628 | self.p_p = 0
629 | self.out(data)
630 | self.outcount += 1
631 |
632 | def handle_data(self, data):
633 | if r'\/script>' in data: self.quiet -= 1
634 |
635 | if self.style:
636 | self.style_def.update(dumb_css_parser(data))
637 |
638 | self.o(data, 1)
639 |
640 | def unknown_decl(self, data): pass
641 |
642 | def charref(self, name):
643 | if name[0] in ['x','X']:
644 | c = int(name[1:], 16)
645 | else:
646 | c = int(name)
647 |
648 | if not self.unicode_snob and c in unifiable_n.keys():
649 | return unifiable_n[c]
650 | else:
651 | try:
652 | return unichr(c)
653 | except NameError: #Python3
654 | return chr(c)
655 |
656 | def entityref(self, c):
657 | if not self.unicode_snob and c in unifiable.keys():
658 | return unifiable[c]
659 | else:
660 | try: name2cp(c)
661 | except KeyError: return "&" + c + ';'
662 | else:
663 | try:
664 | return unichr(name2cp(c))
665 | except NameError: #Python3
666 | return chr(name2cp(c))
667 |
668 | def replaceEntities(self, s):
669 | s = s.group(1)
670 | if s[0] == "#":
671 | return self.charref(s[1:])
672 | else: return self.entityref(s)
673 |
674 | r_unescape = re.compile(r"&(#?[xX]?(?:[0-9a-fA-F]+|\w{1,8}));")
675 | def unescape(self, s):
676 | return self.r_unescape.sub(self.replaceEntities, s)
677 |
678 | def google_nest_count(self, style):
679 | """calculate the nesting count of google doc lists"""
680 | nest_count = 0
681 | if 'margin-left' in style:
682 | nest_count = int(style['margin-left'][:-2]) / self.google_list_indent
683 | return nest_count
684 |
685 |
686 | def optwrap(self, text):
687 | """Wrap all paragraphs in the provided text."""
688 | if not self.body_width:
689 | return text
690 |
691 | assert wrap, "Requires Python 2.3."
692 | result = ''
693 | newlines = 0
694 | for para in text.split("\n"):
695 | if len(para) > 0:
696 | if not skipwrap(para):
697 | for line in wrap(para, self.body_width):
698 | result += line + "\n"
699 | result += "\n"
700 | newlines = 2
701 | else:
702 | if not onlywhite(para):
703 | result += para + "\n"
704 | newlines = 1
705 | else:
706 | if newlines < 2:
707 | result += "\n"
708 | newlines += 1
709 | return result
710 |
711 | ordered_list_matcher = re.compile(r'\d+\.\s')
712 | unordered_list_matcher = re.compile(r'[-\*\+]\s')
713 |
714 | def skipwrap(para):
715 | # If the text begins with four spaces or one tab, it's a code block; don't wrap
716 | if para[0:4] == ' ' or para[0] == '\t':
717 | return True
718 | # If the text begins with only two "--", possibly preceded by whitespace, that's
719 | # an emdash; so wrap.
720 | stripped = para.lstrip()
721 | if stripped[0:2] == "--" and stripped[2] != "-":
722 | return False
723 | # I'm not sure what this is for; I thought it was to detect lists, but there's
724 | # a
-inside- case in one of the tests that also depends upon it.
725 | if stripped[0] == '-' or stripped[0] == '*':
726 | return True
727 | # If the text begins with a single -, *, or +, followed by a space, or an integer,
728 | # followed by a ., followed by a space (in either case optionally preceeded by
729 | # whitespace), it's a list; don't wrap.
730 | if ordered_list_matcher.match(stripped) or unordered_list_matcher.match(stripped):
731 | return True
732 | return False
733 |
734 | def wrapwrite(text):
735 | text = text.encode('utf-8')
736 | try: #Python3
737 | sys.stdout.buffer.write(text)
738 | except AttributeError:
739 | sys.stdout.write(text)
740 |
741 | def html2text(html, baseurl=''):
742 | h = HTML2Text(baseurl=baseurl)
743 | return h.handle(html)
744 |
745 | def unescape(s, unicode_snob=False):
746 | h = HTML2Text()
747 | h.unicode_snob = unicode_snob
748 | return h.unescape(s)
749 |
750 | def main():
751 | baseurl = ''
752 |
753 | p = optparse.OptionParser('%prog [(filename|url) [encoding]]',
754 | version='%prog ' + __version__)
755 | p.add_option("--ignore-emphasis", dest="ignore_emphasis", action="store_true",
756 | default=IGNORE_EMPHASIS, help="don't include any formatting for emphasis")
757 | p.add_option("--ignore-links", dest="ignore_links", action="store_true",
758 | default=IGNORE_ANCHORS, help="don't include any formatting for links")
759 | p.add_option("--ignore-images", dest="ignore_images", action="store_true",
760 | default=IGNORE_IMAGES, help="don't include any formatting for images")
761 | p.add_option("-g", "--google-doc", action="store_true", dest="google_doc",
762 | default=False, help="convert an html-exported Google Document")
763 | p.add_option("-d", "--dash-unordered-list", action="store_true", dest="ul_style_dash",
764 | default=False, help="use a dash rather than a star for unordered list items")
765 | p.add_option("-b", "--body-width", dest="body_width", action="store", type="int",
766 | default=BODY_WIDTH, help="number of characters per output line, 0 for no wrap")
767 | p.add_option("-i", "--google-list-indent", dest="list_indent", action="store", type="int",
768 | default=GOOGLE_LIST_INDENT, help="number of pixels Google indents nested lists")
769 | p.add_option("-s", "--hide-strikethrough", action="store_true", dest="hide_strikethrough",
770 | default=False, help="hide strike-through text. only relevent when -g is specified as well")
771 | (options, args) = p.parse_args()
772 |
773 | # process input
774 | encoding = "utf-8"
775 |
776 | data = os.environ['POPCLIP_TEXT']
777 |
778 | data = data.decode(encoding)
779 | h = HTML2Text(baseurl=baseurl)
780 | # handle options
781 | if options.ul_style_dash: h.ul_item_mark = '-'
782 |
783 | h.body_width = options.body_width
784 | h.list_indent = options.list_indent
785 | h.ignore_emphasis = options.ignore_emphasis
786 | h.ignore_links = options.ignore_links
787 | h.ignore_images = options.ignore_images
788 | h.google_doc = options.google_doc
789 | h.hide_strikethrough = options.hide_strikethrough
790 |
791 | print h.handle(data)
792 |
793 | main()
794 |
795 |
796 | # Markdown Mark by [Dustin Curtis](https://github.com/dcurtis/markdown-mark)
797 |
--------------------------------------------------------------------------------
/mise.toml:
--------------------------------------------------------------------------------
1 | [tools]
2 | ruby = "3.3.0"
3 |
--------------------------------------------------------------------------------
/nvUltra.popclipext/Config.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Actions
6 |
7 |
8 | Image File
9 | rocket.png
10 | Script Interpreter
11 | /usr/bin/ruby
12 | Shell Script File
13 | nvUltra.rb
14 |
15 |
16 | Apps
17 |
18 |
19 | Bundle Identifier
20 | com.multimarkdown.nvultra
21 | Check Installed
22 |
23 | Link
24 | https://nvultra.com
25 | Name
26 | nvUltra
27 |
28 |
29 | Options
30 |
31 |
32 | Option Identifier
33 | nvnotebook
34 | Option Type
35 | string
36 | Option Label
37 | Folder
38 |
39 |
40 | Credits
41 |
42 |
43 | Name
44 | Brett Terpstra
45 |
46 |
47 | Extension Description
48 | Create a note in nvUltra.
49 | Extension Identifier
50 | com.brettterpstra.popclip.extension.nvultra
51 | Extension Name
52 | nvUltra
53 | Required Software Version
54 | 701
55 |
56 |
57 |
--------------------------------------------------------------------------------
/nvUltra.popclipext/README.md:
--------------------------------------------------------------------------------
1 | ### nvUltra
2 |
3 | [nvUltra](https://nvultra.com) extension for PopClip. Add text as new note to frontmost notebook, or define a notebook in settings.
4 |
5 | #### Credits
6 |
7 | Originally created by Marc Abramowitz - see [https://github.com/msabramo/nvALT.popclipext](https://github.com/msabramo/nvALT.popclipext). Icon and minor modifications by Nick Moore.
8 |
--------------------------------------------------------------------------------
/nvUltra.popclipext/_Signature.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Signature
6 |
7 | PyaeNniM4p3m4gA91mI8gA7ws3017cImL1rcLJuh6HpclyTUj5R9msgoHdA6at6gT1qs
8 | jgodXdKrH497/qKnfbKj4gxlhCZ1QiyU8yNHhtXwIOAuyqAprN6zV4JspU3E33om3jc7
9 | 06a7Lzx+8hDDM4ltTr+2ooSDddRCqx+6X00=
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/nvUltra.popclipext/nvUltra.rb:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env ruby
2 | # frozen_string_literal: true
3 |
4 | require 'erb'
5 |
6 | nb = ENV['POPCLIP_OPTION_NVNOTEBOOK']
7 | text = ENV['POPCLIP_TEXT']
8 |
9 | notebook = nb && !nb.empty? ? %(¬ebook="#{ERB::Util.url_encode(nb)}") : ''
10 |
11 | url = "x-nvultra://make/?txt=#{ERB::Util.url_encode(text)}#{notebook}"
12 |
13 | `open "#{url}"`
14 |
--------------------------------------------------------------------------------
/nvUltra.popclipext/rocket.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ttscoff/popclipextensions/81a97925c317a804ad731e348c57b3cf7a635b22/nvUltra.popclipext/rocket.png
--------------------------------------------------------------------------------