Convert a .rtf into a mac .r resource, in a scriptable way - macos

I currently have a SLA in a .rtf format, which is to be integrated into .dmg using the intermediary .r mac resource format, which is used by the Rez utility. I had already done it by hand once, but updates made to the .rtf file are overwhelming to propagate to the disk image, and error-prone. I would like to automate this task, which could also help adding other languages or variants.
How could the process of .rtf to .r text conversion be automated?
Thanks.

Only because I didn't fully understand how the accepted answer actually achieved the goal, I use a combination of a script to generate the hex encoding:
#!/usr/bin/env ruby
# Makes resource (.r) text from binaries.
def usage
puts "usage: #{$0} infile"
puts ""
puts " infile The file to convert (the output will go to stdout)"
exit 1
end
infile = ARGV[0] || usage
data = File.read(infile)
data.bytes.each_slice(16) do |slice|
hex = slice.each_slice(2).map { |pair| pair.pack('C*').unpack('H*')[0] }.join(' ')
# We could put the comments in too, but it probably isn't a big deal.
puts "\t$\"#{hex}\""
end
The output of this is inserted into a variable during the build and then the variable ends up in a template (we're using Ant to do this, but the specifics aren't particularly interesting):
data 'RTF ' (5000, "English SLA") {
#english.licence#
};
The one bit of this which did take quite a while to figure out is that 'RTF ' can be used for the resource directly. The Apple docs say to separately insert 'TEXT' (with just the plain text) and 'styl' (with just the style). There are tools to do this of course, but it was one more tool to run and I could never figure out how to make hyperlinks work in the resulting DMG. With 'RTF ', hyperlinks just work.
Hoping that this saves someone time in the future.

Use the unrtf port (from macports), then format the lines, heading and tail with a shell script.

Related

Editing thickness in postscript (.ps or .eps) figures via unix shell commands?

I have many figures (graphs) in postscript (.eps) format that I wish to thicken the plots with.
I found the following code, but the output file is no different. I was wondering what I was doing wrong.
The code:
# get list of all arguments
set args = ($*)
# if not enough arguments, complain.
if ($#args < 2) then
echo "Usage: ps_thicken ps_file factor"
echo "Thickens all lines in a PostScript file by changing the linewidth macro."
echo "Result goes to standard output."
exit 1
endif
sed -e "s/^\/lw {\(.*\) div setlinewidth/\/lw {$2 mul \1 div setlinewidth/" $1
Now to execute this from my command line, I use the command (filename is ps_thicken, and has appropriate permissions):
./ps_thicken old_file.eps 10 > new_thick_file.eps
Which I thought should make everything 10x thicker, but it just doesnt change anything.
Any help would be greatly appreciated, I'm pretty new to shell script!
PostScript is a programming language, so it isn't really possible to make changes in an automated fashion like this. At least not without writing a PostScript program to do so!
Note that linewidth isn't a 'macro' (PostScript doesn't have macros) its am operator. What the code you've posted for sed does (if I recall sed well enough) is look for the definition of /lw and replace it with a modified version. The problem with that is that /lw is a function declartation in a particular PostScript program. Most PostScript programs won't have (or use) a function called 'lw'.
You would be much better to prepend the PostScript program code with something like:
/oldsetlinewidth /linewidth load def
/setlinewidth {2 div oldsetlinewidth} bind def
That will define (in the current dictionary) a function called 'setlinewidth'. Now, if the following program simply uses the current definition of setlinewdith when creating its own functions, it will use the redefined one above. Which will have the effect of dividing all line widths by 2 in this case. Obviously to increase the width you would use something like 2 mul instead of 2 div.
Note that this is by no means foolproof, its entirely possible for a PostScript program to explicitly load the definition of setlinewidth from systemdict, and you can't replace that (at least not easily) because systemdict is read-only.
However its unlikely that an EPS program would pull such tricks, so that should probably work well enough for you.
[based on comments]
Hmm, you mean 'failed to import' into an application or something else ?
If you're loading the EPS into an application then simply putting that code in front of it will break it. EPS (unlike PostScript) is required to follow some rules, so to modify it successfully you will have to follow them. This includes skipping over any EPS preview.
This is not really a trivial exercise. Your best bet is probably to run the files through Ghostscript, you can do a lot by harnessing a PostScript interpreter to do the work.
Start with the 2 lines of PostScript above in a file, then run the EPS file you want to 'modify' through Ghostscript, using the eps2write device. That will produce a new EPS which has the changes 'baked in'.
Eg (assuming the linewidth modifying code is in 'lw.ps'):
gs -sDEVICE=eps2write -o out.eps lw.ps file.eps
But be aware that the resulting EPS is a completely rewritten program and will bear no relation to the original. In particular any preview thumbnail will be lost.

Ruby self-editing source code

I am creating a grammar corrector app. You input slang and it returns a formal English correction. All the slang words that are supported are kept inside arrays. I created a method that looks like this for when a slang is entered that is not supported.
def addtodic(lingo)
print"\nCorrection not supported. Please type a synonym to add '#{lingo}' the dictionary: "
syn = gets.chomp
if $hello.include?("#{syn}")
$hello.unshift(lingo)
puts"\nCorrection: Hello.\n"
elsif $howru.include?("#{syn}")
$howru.unshift(lingo)
puts"\nCorrection: Hello. How are you?\n"
end
end
This works, but only until the application is closed. how can I make this persist so that it amends the source code as well? If I cannot, how would I go about creating an external file that holds all of the cases and referencing that in my source code?
You will want to load and store your arrays in a external file.
How to store arrays in a file in ruby? is relevant to what you are trying to do.
Short example
Suppose you have a file that has one slang phrase per line
% cat hello.txt
hi
hey
yo dawg
The following script will read the file into an array, add a term, then write the array to a file again.
# Read the file ($/ is record separator)
$hello = File.read('hello.txt').split $/
# Add a term
$hello.unshift 'hallo'
# Write file back to original location
open('hello.txt', 'w') { |f| f.puts $hello.join $/ }
The file will now contain an extra line with the term you just added.
% cat hello.txt
hallo
hi
hey
yo dawg
This is just one simple way of storing an array to file. Check the link at the beginning of this answer for other ways (which will work better for less trivial examples).

How to make a word list from a text file in a more Ruby way?

I'd like to get a word list from a text file using Ruby. I found how to use regex to parse only words here, so I made a script like following:
src = File.open("text.txt")
word_list = []
src.each do |line|
word_list << line.downcase.split(/[^[:alpha:]]/).delete_if {|x| x == ""}
end
word_list.flatten!.uniq!.sort!
p word_list
And the following is a sample text file text.txt:
TextMate may be the latest craze for developing Ruby on Rails
applications, but Vim is forever. This plugin offers the following
features for Ruby on Rails application development.
Automatically detects buffers containing files from Rails applications, and applies settings to those buffers (and only those
buffers). You can use an autocommand to apply your own custom
settings as well.
Unintrusive. Only files in a Rails application should be affected; regular Ruby scripts are left untouched. Even when enabled, the
plugin should keep out of your way if you're not using its features.
Easy navigation of the Rails directory structure. gf considers context and knows about partials, fixtures, and much more. There are
two commands, :A (alternate) and :R (related) for easy jumping between
files, including favorites like model to migration, template to
helper, and controller to functional test. For more advanced usage,
:Rmodel, :Rview, :Rcontroller, and several other commands are
provided.
As a Ruby novice, I'd like to learn better (more clear, concise, and following conventions) solutions for this problem.
Thanks for any advices and corrections.
A more idiomatic code would be:
word_list = open("text.txt")
.lines
.flat_map { |line| line.downcase.split(/[^[:alpha:]]/).reject(&:empty?) }
.uniq
.sort
# I suppose you want each line and collect the results
word_list = File.open("text.txt").each_line.collect do |line|
# collecting is done via collect above, no need anymore
# .reject(&:empty?) calls .empty? on each element
line.downcase.split(/[^[:alpha:]]/).reject(&:empty?)
# you can chain on blocks as well
end.flatten!.uniq!.sort!
p word_list

Applying a diff-patch to a string/file

For an offline-capable smartphone app, I'm creating a one-way text sync for Xml files. I'd like my server to send the delta/difference (e.g. a GNU diff-patch) to the target device.
This is the plan:
Time = 0
Server: has version_1 of Xml file (~800 kiB)
Client: has version_1 of Xml file (~800 kiB)
Time = 1
Server: has version_1 and version_2 of Xml file (each ~800 kiB)
computes delta of these versions (=patch) (~10 kiB)
sends patch to Client (~10 kiB transferred)
Client: computes version_2 from version_1 and patch <= this is the problem =>
Is there a Ruby library that can do this last step to apply a text patch to files/strings? The patch can be formatted as required by the library.
Thanks for your help!
(I'm using the Rhodes Cross-Platform Framework, which uses Ruby as programming language.)
Your first task is to choose a patch format. The hardest format for humans to read (IMHO) turns out to be the easiest format for software to apply: the ed(1) script. You can start off with a simple /usr/bin/diff -e old.xml new.xml to generate the patches; diff(1) will produce line-oriented patches but that should be fine to start with. The ed format looks like this:
36a
<tr><td class="eg" style="background: #182349;"> </td><td><tt>#182349</tt></td></tr>
.
34c
<tr><td class="eg" style="background: #66ccff;"> </td><td><tt>#xxxxxx</tt></td></tr>
.
20,23d
The numbers are line numbers, line number ranges are separated with commas. Then there are three single letter commands:
a: add the next block of text at this position.
c: change the text at this position to the following block. This is equivalent to a d followed by an a command.
d: delete these lines.
You'll also notice that the line numbers in the patch go from the bottom up so you don't have to worry about changes messing up the lines numbers in subsequent chunks of the patch. The actual chunks of text to be added or changed follow the commands as a sequence of lines terminated by a line with a single period (i.e. /^\.$/ or patch_line == '.' depending on your preference). In summary, the format looks like this:
[line-number-range][command]
[optional-argument-lines...]
[dot-terminator-if-there-are-arguments]
So, to apply an ed patch, all you need to do is load the target file into an array (one element per line), parse the patch using a simple state machine, call Array#insert to add new lines and Array#delete_at to remove them. Shouldn't take more than a couple dozen lines of Ruby to write the patcher and no library is needed.
If you can arrange your XML to come out like this:
<tag>
blah blah
</tag>
<other-tag x="y">
mumble mumble
</other>
rather than:
<tag>blah blah</tag><other-tag x="y">mumble mumble</other>
then the above simple line-oriented approach will work fine; the extra EOLs aren't going to cost much space so go for easy implementation to start.
There are Ruby libraries for producing diffs between two arrays (google "ruby algorithm::diff" to start). Combining a diff library with an XML parser will let you produce patches that are tag-based rather than line-based and this might suit you better. The important thing is the choice of patch formats, once you choose the ed format (and realize the wisdom of the patch working from the bottom to the top) then everything else pretty much falls into place with little effort.
I know this question is almost five years old, but I'm going to post an answer anyway. When searching for how to make and apply patches for strings in Ruby, even now, I was unable to find any resources that answer this question satisfactorily. For that reason, I'll show how I solved this problem in my application.
Making Patches
I'm assuming you're using Linux, or else have access to the program diff through Cygwin. In that case, you can use the excellent Diffy gem to create ed script patches:
patch_text = Diffy::Diff.new(old_text, new_text, :diff => "-e").to_s
Applying Patches
Applying patches is not quite as straightforward. I opted to write my own algorithm, ask for improvements in Code Review, and finally settle on using the code below. This code is identical to 200_success's answer except for one change to improve its correctness.
require 'stringio'
def self.apply_patch(old_text, patch)
text = old_text.split("\n")
patch = StringIO.new(patch)
current_line = 1
while patch_line = patch.gets
# Grab the command
m = %r{\A(?:(\d+))?(?:,(\d+))?([acd]|s/\.//)\Z}.match(patch_line)
raise ArgumentError.new("Invalid ed command: #{patch_line.chomp}") if m.nil?
first_line = (m[1] || current_line).to_i
last_line = (m[2] || first_line).to_i
command = m[3]
case command
when "s/.//"
(first_line..last_line).each { |i| text[i - 1].sub!(/./, '') }
else
if ['d', 'c'].include?(command)
text[first_line - 1 .. last_line - 1] = []
end
if ['a', 'c'].include?(command)
current_line = first_line - (command=='a' ? 0 : 1) # Adds are 0-indexed, but Changes and Deletes are 1-indexed
while (patch_line = patch.gets) && (patch_line.chomp! != '.') && (patch_line != '.')
text.insert(current_line, patch_line)
current_line += 1
end
end
end
end
text.join("\n")
end

Reformatting text (or, better, LaTeX) in 80 colums in SciTE

I recently dived into LaTeX, starting with the help of a WYSIWYM editor like Lix. Now I'm staring writing tex files in Sci-TE, It already has syntax higlighting and I adapted the tex.properties file to work in Windows showing a preview on Go [F5]
One pretty thing Lyx does, and it's hard to acheive with a common text editor, is to format text in 80 columns: I can write a paragraph and hit Return each time I reach near the edge column but if, after the first draft, I want to add or cut some words here and there I end up breaking the layout and having to rearrange newlines.
It would be useful to have a tool in Sci-TE so I can select a paragraph of text I added or deleted some words in and have it rearranged in 80 columns. Probably not something working on the whole document since it could probably break some intended anticipated line break.
Probably I could easily write a Python plugin for geany, I saw vim has something similar, but I'd like to know if its' possible in Sci-TE too.
I was a bit disappointed when I found no answer as I was searching for same. No helpers by Google either, so I searched for Lua examples and syntax in a hope to craft it myself. I don't know Lua so this can perhaps be made differently or efficiently but its better then nothing I hope - here is Lua function which needs to be put in SciTE start-up Lua script:
function wrap_text()
local border = 80
local t = {}
local pos = editor.SelectionStart
local sel = editor:GetSelText()
if #sel == 0 then return end
local para = {}
local function helper(line) table.insert(para, line) return "" end
helper((sel:gsub("(.-)\r?\n", helper)))
for k, v in pairs(para) do
line = ""
for token in string.gmatch(v, "[^%s]+") do
if string.len(token .. line) >= border then
t[#t + 1] = line
line = token .. " "
else
line = line .. token .. " "
end
end
t[#t + 1] = line:gsub("%s$", "")
end
editor:ReplaceSel(table.concat(t, "\n"))
editor:GotoPos(pos)
end
Usage is like any other function from start-up script, but for completness I'll paste my tool definition from SciTE properties file:
command.name.8.*=Wrap Text
command.mode.8.*=subsystem:lua,savebefore:no,groupundo
command.8.*=wrap_text
command.replace.selection.8.*=2
It does respect paragraphs, so it can be used on broader selection, not just one paragraph.
This is one way to do it in scite: first, add this to your .SciTEUser.properties (Options/Open User Options file):
# Column guide, indicates long lines (https://wiki.archlinux.org/index.php/SciTE)
# this is what they call "margin line" in gedit (at right),
# in scite, "margin" is the area on left for line numbers
edge.mode=1
edge.column=80
... and save, so you can see a line at 80 characters.
Then scale the scite window, so the text you see is wrapped at the line.
Finally, select the long line text which is to be broken into lines, and do Edit / Paragraph / Split (for me the shortcut Ctrl-K also works for that).
Unfortunately, there seems to be no "break-lines-as-you-type" facility in scite, like the "Line Breaking" facility in geany. not anymore, now there's a plugin - see this answer
Well, I was rather disappointed that there seems to be no "break-lines-as-you-type" facility in scite; and I finally managed to code a small Lua plugin/add-on/extension for that, and released it here:
lua-users wiki: Scite Line Break
Installation and usage instructions are in the script itself. Here is how SciTE may look when the extension properly installed, and toggle activated after startup:
Note that it's pretty much the same functionality as in geany - it inserts linebreaks upon typing text - but not on pressing backspace, nor upon copy/pasting.
the same but more easy, I think...
put this in the user properties:
command.name.0.*=swrap
command.0.*=fold -s $(FileNameExt) > /tmp/scite_temp ; cat /tmp/scite_temp >$(FileNameExt)
command.is.filter.0.*=1
Ciao
Pietro

Resources