You can find this script at http://arc.stuff.gen.nz/arcfilter.scsh I
would appreciate any comments or feedback that anyone can give. None
of my coder friends understand scheme. Or particularly want to :[
Some queries:
I figured out how to do conditional variable binding in a schemey way:
(let ((filtering-rx ((lambda ()
(if (string=? ".css" (file-name-extension fromfile))
(rx (: (submatch "\"" (* any))
,source-root
(submatch (* any) "\"" )))
(rx (:
(submatch (:"<" (* any) "\"" (* any)))
,source-root
(submatch (: (* any) "\"" (* any) ">"))))
)))))
;body of let
)
but this seems a little clumsy --- what with the use of the lambda form
plus an extra set of brackets --- when you consider that a C-like
language would just do it thus:
if (condition)
{x = true;}
else
{x = false;}
I know that you could something similar with set!, but I thought we
didn't like set!. Is there a nicer way to do it?
Also, I get output like this:
ajt@ariel:~/webwork$ ~/Projects/Scheme/arcfilter.scsh
body{ background: url("/~ajt/graphics/whale-bay.jpg");
div.paper{background: url("/~ajt/graphics/paper.png");
<table background="/~ajt/graphics/controlbarbg.png" cellpadding=10>
<td > <a href="/~ajt/index.php"> Home </a> |</td>
<td > <a href="/~ajt/stuff.php"> Stuff </a> |</td>
<td > <a href="/~ajt/gallery.php"> Gallery </a> | </td>
<td > <a href="/~ajt/me.php"> Me </a></td>
<td > <a href="/~ajt/diary/index.php"> Diary </a> |</td>
<td > <a href="/~ajt/guestbook.php" >Guestbook</a> | </td>
<td > <a href="/~ajt/about.html"> About </a>
ajt@ariel:~/webwork$
which I'm not asking for. The only thing I can think of is that this
awk invocation:
(awk (read-line inport) (line) ()
(#t
(regexp-substitute/global
outport
filtering-rx
line
'pre 1 target-root 2 'post)
(newline outport)
)
is returning 'line' (whose values are in fact what's getting printed
above) which is somehow bubbling up to the top and getting outputed by
the interpreter. But I would have thought that I'd only be getting the
last line at most, if that were the case, returned as the value of 'main'.
The program's roughly 100 lines of code, which is a lot more than the
10 line bash script I had when I started. Admittedly it's doing a lot
more than the bash script ever was...
The script as it stands isn't doing any checks to see whether the
directory is writable or anything. It might also be a good idea to add
some sort of output to stdout to give some sort of feedback as to what
it's doing, perhaps with a -v.
The only other improvement I can think of making is putting the
reading of the directories into a function, which stores the list
somehow, so that the source directory doesn't need to get read twice.
Also, I couldn't find any documentation for read-line. I know it's in
SLIB, but I don't think that's where scsh gets its read-line from (is
it?).
thanks,
Andrew.
That ought to be equivalent to:
(let ((filtering-rx
(if (string=? ".css" (file-name-extension fromfile))
(rx (: (submatch "\"" (* any))
,source-root
(submatch (* any) "\"" )))
(rx (:
(submatch (:"<" (* any) "\"" (* any)))
,source-root
(submatch (: (* any) "\"" (* any) ">"))))
)))
;body of let
)
I'm not familiar with RX, but if it is a procedure (and the `(:' is
doing the funny quoting) you ought to be able to do this:
(let ((filtering-rx
(rx (if (string=? (file-name-extension fromfile) ".css")
(: (submatch "\"" (* any))
,source-root
(submatch (* any) "\"" ))
(: (submatch (:"<" (* any) "\"" (* any)))
,source-root
(submatch (: (* any) "\"" (* any) ">")))))))
;body of let
)
> but this seems a little clumsy --- what with the use of the lambda form
> plus an extra set of brackets
It is. I don't think they are necessary.
--- when you consider that a C-like
> language would just do it thus:
>
> if (condition)
> {x = true;}
> else
> {x = false;}
x = condition ? true : false;
C has conditional expressions, no one uses them much.
x = condition;
> Just:
>
> x = condition;
Actually just:
x = (condition);
David S.
"Joe Marshall" <prunes...@attbi.com> writes:
> I'm not familiar with RX, but if it is a procedure (and the `(:' is
> doing the funny quoting) you ought to be able to do this:
no, "(:" is not doing any quoting. its an alternative for "(seq". Afaik it's a
keyword for the rx _macro_.
Andrew Tarr <a...@stuff.gen.nz> writes:
> You can find this script at http://arc.stuff.gen.nz/arcfilter.scsh I
> would appreciate any comments or feedback that anyone can give. None
my comment:
this approach is ugly imho:
(define (relativize-to-dir filename dirname)
(let* ((ndirname (file-name-as-directory dirname))
(index (string-length ndirname)))
(if (string= filename ndirname 0 index 0 index)
(string-drop filename index)
(filename))))
Better is to operate on the algebra of paths.
I use this: (find it in http://maruska.dyndns.org/comp/scsh/scheme/fs/tree.scm
and http://maruska.dyndns.org/comp/scsh/scheme/packages.scm)
;; inverse of path-list->file-name:
(define (file-name->path-list filename)
(split-file-name filename))
;; let's have 2 sets, 1 w/ an operation, and 2 mappings
;;
;; get the (inverse) image of op. on:
;; args result
;;trans| ^
;; V proc | inverse
;; ARGS-------> RES
;;
(define (call-in-image proc trans inverse args)
(let ((images (map trans args)))
(inverse
(apply proc images))))
;; fixme: standard ?
(define (nthcdr list n)
(cond ((= n 0) list)
(#t (nthcdr (cdr list) (- n 1)))))
;;; given 2 paths, the difference (not relation !!)
(define (minus path root) ; get the subpath from root -> path
;; only if the start is equal !!
(let ((l (length root))
(lp (length path)))
(if (and (>= lp l)
(list= string= root (take path l)))
(nthcdr path (length root))
(begin
(error "cannot minus" path root)))))
(define (minus* path-string root-string) ; get the subpath from root -> path
(call-in-image
minus
file-name->path-list
path-list->file-name
(list path-string root-string)))
Michal, your method of dealing with paths and filenames is much better
than my ugly hack. It seems to me that people would need to do this
sort of thing pretty often... I'm sort of surprised that it isn't in
scsh, to be honest. Is there a scsh-lib it can (or should) go into?
Joe, I've fixed my conditional assignment to what you suggested. I
thought something like this ought to work, and I thought I had tried
it already. But perhaps I had an extra set of brackets in, or
something.
And Michal is right, rx is the scsh regular expression macro and the
":" is a keyword equivalent to "seq", FWIW.
Now, all I've got to do is try and chase up the output I'm not asking for.
That, and just make it better :]
Andrew.
Andrew> thanks to everyone who replied.
Andrew> Michal, your method of dealing with paths and filenames is much better
Andrew> than my ugly hack. It seems to me that people would need to do this
Andrew> sort of thing pretty often... I'm sort of surprised that it isn't in
Andrew> scsh, to be honest. Is there a scsh-lib it can (or should) go into?
There is no scsh-lib, but RT Happe has done a pretty good job in
collecting scsh code and linking it within the resource part of the
scsh home-page (http://www.scsh.net/resources.html).
This page also contains a wiki for Code Snippets at
http://www.scsh.net/cgi-bin/wiki.cgi?CodeSnippets
which, however, has been mostly ignored by the scsh users. Maybe
someone could tell me why...
--
Martin