Last active
March 30, 2024 21:17
-
-
Save ttscoff/6ad0b0610277484b4aaa to your computer and use it in GitHub Desktop.
ezsnippets v1, define expansions as you write (based on work by Stephen Margheim: http://www.alfredforum.com/topic/4680-snippets-on-the-fly-text-expansion/))
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/ruby | |
=begin | |
# ezsnippets | |
Brett Terpstra 2014, MIT License | |
Based on a great idea by Stephen Margheim <http://twitter.com/s_margheim> | |
- http://www.alfredforum.com/topic/4680-snippets-on-the-fly-text-expansion/ | |
- https://github.com/smargh/alfred_snippets | |
## Summary | |
Create snippets on the fly as you write, then have them expanded in the | |
final document | |
## Details | |
This version of the idea lets you write snippets definitions right in your | |
text. The first time you type a long phrase you know you're going to want | |
again, just surround it in curly brackets and end it with a colon and a | |
shortcut. The shortcut can be anything you want, but it's probably best to use | |
something you're not likely to type again. Start it with a double comma or | |
other punctuation if you want to be safe. | |
The shortcut can have no spaces, before, inside, or after it. Other than that, | |
it's up to you. You can use *, ?, ,, :, \, ~, etc. If you're using a colon as | |
a prefix, make sure there are three in a row (2 to split, 1 for the | |
definition). | |
For accuracy, the script will only match the snippet if it's preceded by a | |
word boundary or a space. That allows some matching safety and precision while | |
still allowing to you pluralize the snippet in the text. Snippets will be | |
replaced in order from longest to shortest, so ",,ru" won't overwrite | |
",,rumble". | |
Snippet abbreviations can _only_ be defined once. If you define the same | |
snippet abbreviation two or more times, the script will gracefully fail and no | |
replacements will be made. It's assumed that this was a mistake on your part, | |
and that there will be multiple abbreviations in the document that are | |
intended to mean different things. | |
The original script is designed for Alfred, this one is probably going | |
to be used in Services and PopClip. | |
## Example: | |
Lorem ipsum dolor sit amet {on-the-fly text expansion::,otf}, | |
consectetur adipisicing elit ,otf, sed do eiusmod tempor incididunt | |
,otf. | |
becomes: | |
Lorem ipsum dolor sit amet on-the-fly text expansion, | |
consectetur adipisicing elit on-the-fly text expansion, sed do eiusmod | |
tempor incididunt on-the-fly text expansion. | |
## Usage: | |
Just pipe text containing snippet definitions and instances to it. | |
cat "mywriting.md" | ezsnippets | |
=end | |
silent = true | |
def usage(err=false) | |
puts "cat <filename> | ezsnippets" | |
if err | |
Process.exit 1 | |
else | |
Process.exit 0 | |
end | |
end | |
args = ARGV.join(" ") | |
if args =~ /(d(ebug)?|t(est)?)/ | |
silent = false | |
input = STDIN.stat.size > 0 ? STDIN.read.force_encoding('utf-8') : DATA.read | |
else | |
if STDIN.stat.size > 0 | |
if RUBY_VERSION.to_f > 1.9 | |
Encoding.default_external = Encoding::UTF_8 | |
Encoding.default_internal = Encoding::UTF_8 | |
input = STDIN.read.force_encoding('utf-8') | |
else | |
input = STDIN.read | |
end | |
if input.length == 0 | |
$stderr.puts "Input must be received on STDIN" | |
Process.exit 1 | |
end | |
else | |
usage(true) | |
end | |
end | |
message = [] | |
abbrs = {} | |
total_replaced = {} | |
found = 0 | |
input.gsub! (/\{(.*?)::(\S+)\}/m) do |match| | |
found += 1 | |
unless abbrs.has_key? $2 | |
abbrs[$2] = $1 | |
else | |
# $stderr.puts "Abbreviation #{$2} defined multiple times." | |
# $stderr.puts "Edit text with an alternate snippet for additional instances of \"#{$1}\"." | |
# raise MultipleDefinitionException | |
message.push("Abbreviation #{$2} defined multiple times.\nEdit text with an alternate snippet for additional instances of \"#{$1}\".") | |
found = -1 | |
break | |
end | |
$1 | |
end | |
if found < 1 | |
$stdout.puts input | |
message.push("No snippet definitions found in text") if found == 0 | |
$stderr.puts %Q{\n---\n#{message.join("\n")}} unless message.empty? || silent | |
Process.exit | |
else | |
message.push("Found #{abbrs.length} snippet definitions") | |
end | |
abbrs.sort_by {|k,v| k.length }.reverse.each {|short, long| | |
$stderr.printf("%s: %s\n", short, long) unless silent | |
total_replaced[short] = 0 | |
input.gsub!(/(?<=[\b\s])#{Regexp.escape(short)}/) do |m| | |
total_replaced[short] += 1 | |
long | |
end | |
} | |
total = abbrs.length | |
total_replaced.each {|abbr,count| | |
message.push("#{abbr}:\t\t#{count}") | |
total += count.to_i | |
} | |
message.push("#{total} replacements made in file") | |
$stdout.print input | |
unless silent | |
$stderr.puts message.join("\n") | |
end | |
__END__ | |
Lorem ipsum {a test string::,tst} dolor sit amet, consectetur | |
adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna | |
aliqua. Ut {a longer phrase that will repeat. Not sure why you'd do this but | |
it can break lines and paragraphs, too::,ns} enim ad minim veniam, quis nostrud | |
exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. {The | |
Ministry of Silly Walks::,sw}. Duis aute irure dolor in reprehenderit in | |
voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint | |
occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit | |
anim id est laborum. | |
Sed ut perspiciatis unde omnis ,tst iste natus error sit voluptatem accusantium | |
doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore | |
veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim | |
ipsam voluptatem ,ns quia voluptas sit aspernatur aut odit aut fugit, sed quia | |
consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque | |
porro quisquam est, qui ,sw dolorem ipsum quia dolor sit amet, consectetur, | |
adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et | |
dolore magnam aliquam quaerat voluptatem. Ut enim ad minima veniam, quis | |
nostrum exercitationem ullam corporis suscipit laboriosam, nisi ut aliquid ex | |
ea commodi consequatur? Quis autem vel eum iure reprehenderit qui in ea | |
voluptate velit esse quam nihil molestiae consequatur, vel illum qui dolorem | |
eum fugiat quo voluptas nulla pariatur? | |
,sw |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment