Beefy Boxes and Bandwidth Generously Provided by pair Networks
Think about Loose Coupling
 
PerlMonks  

Re: LaTeX Abbreviations for Linguists

by graff (Chancellor)
on Jul 06, 2009 at 22:07 UTC ( [id://777694]=note: print w/replies, xml ) Need Help??


in reply to LaTeX Abbreviations for Linguists

Apart from the problem cited in the first reply, you could accomplish the same goal with a lot fewer lines of code -- e.g. this:
if ( $abbr =~ s/([123][sdp])// ) { push(@abbr, $1); $abbr =~ s/\s//g; };
will replace 45 lines of OP code (the 5-line block that is repeated 9 times, for each combination of 1/2/3 with s/d/p).

A similar refactoring should be done on all those blocks that "do the nasty" with @inlist -- you should be able to reduce all of those blocks down to a single loop as well, and then you only have to fix the misuse of "push" on the one remaining instance of that problem.

(updated to fix wording in 1st paragraph)

Oh, and instead of this:

if ( $file[$i] =~ m/(\\gll|\\ag\.|\\bg\.|\\cg\.|\\dg\.|\\eg\.|\\fg\.|\ +\exg\.|\\exg)/ )
How about:
if ( $file[$i] =~ /(\\(?:gll|[abcdef]g\.|exg\.?))/ )
(updated last snippet to include a much-needed ":" after the first "?")

Replies are listed 'Best First'.
Re^2: LaTeX Abbreviations for Linguists
by Omukawa (Acolyte) on Sep 05, 2009 at 09:13 UTC
    @jwkrahn and graff: Thank you very much for your comments and corrections. I've revised and edited the script.
      #Last Updated 05.09.09
      Um... okay, given the date of your last reply, that comment line in your code can be interpreted correctly, but you should be aware that taken by itself, that date string could mean three different things.

      This regex in your code looks wrong, and is very different from the one I recommended (and from the one I quoted out of the original version of your script):

      if ( $file[$i] =~ m/(\\(gll|[abcdef(exg.)]g\.)|textsc\/)/ ) {
      It creates a character class that includes "e" two times, and also includes period and open and close parens. It will match things like "\)g.", "\(g.", "\.g.", "\xg.", etc, and probably won't match things that you want it to match, like "exg". I realize now that in my earlier reply, I left out a colon; I've updated that accordingly, and I apologize for that mistake.

      Consistent indentation is a nice thing, and so is using @ARGV for things like asking for usage help and providing file names and options -- please get acquainted with using @ARGV (and Getopt::Std and/or Getopt::Long), because making the user manually type things in after the script is running is a Real Pain™.

      A long list of "configuration" or "initialization" data (your "@lgr" list) would be handled more cleanly (and would be easier to maintain) as a __DATA__ segment that gets read into an array or hash on start-up.

      The regex alternation character (vertical-bar, |) does not work as such inside a regex character class (between square brackets), it just matches a literal "|" -- so you should study the perlre man page to understand how character classes work.

      Also, when you want to delete all occurrences of particular characters from a string, using tr/xyz//d is much more efficient than s/x//g; s/y//g; s/z//g; (using tr is even more efficient than s/[xyz]//g).

      For a small script like this, modifying global-scope variables inside of subroutines isn't such a big deal, because the script is small, but it's usually not a good idea. As a general rule (and in the interest of creating subroutines that are modular and easy to maintain and adapt), it's better to pass data to subs as parameters, and have the sub either return its resulting data to the caller, or modify its parameters in-place (because they were passed as references).

      If you document your code with POD, it will be easier to read and maintain the documentation, which is important. If the documentation includes a brief description of what the code actually does, that will help you to organize your thoughts in a sensible way about the algorithm, and then organize your code according to what makes sense (and is documented). As it is, there's a lot of inefficiency in your code, because the algorithm hasn't been thought out. In particular, you are using arrays where you should be using hashes.

      This note in your help text is not necessarily true:

      ... Note: The script and the TeX file have to be in the same directory +. ...
      The script could be in the shell's execution PATH, so it doesn't have to be where the data file is; also, a user can provide (relative or absolute) paths for both the script and the data file, so they don't both have to be in the same place. Also, it's always a good idea to include the filename string and $! in the error message when you "die" on a failed "open" call.

      I happened to notice this one odd entry in your long list of LGR abbrevs:

      N-=non- (e.g. NSG nonsingular, NPST nonpast)
      There's nothing in your code that handles this "N" prefix on other abbrevs, so things like "NPST" and "NSG" will never be labeled as "nonpast" or "nonsingular" in your output. Also, that explanation will never appear in the output either, unless "N-" happens to occur in the tex file.

      One last point: do you have a suitable "test.tex" file that contains at least one example of every kind of abbreviation you intend to handle with this script, along with some variety of "normal" content? If not, make one. The point would be to make sure that all these abbreviations get listed as intended.

      Of course, you can't anticipate all the ways that "normal" LaTeX content might cause your script to miss things that are real abbreviations (e.g. if two abbrevs occur next to each other separated by a single space, the second one will be missed), or to list things as abbrevs when they really aren't (e.g. FULL WORDS IN UPPERCASE, or any single-digit number). But even a little bit of testing is better than none.

      Here's how I would write your script (though this version won't behave exactly the same as yours, and might have some mistakes in it -- I didn't have any LaTeX files with abbreviations to test it on):

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://777694]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others exploiting the Monastery: (5)
As of 2024-04-19 14:30 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found