Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Convert Unix `cal` output to latex table code: one-liner solution?

Trying to achieve the following struggled my mind:

Convert Unix cal output to latex table code, using a short and sweet one-liner (or few-liner).

E.g cal -h 02 2012 | $magicline should yield

Mo      &Tu     &We     &Th     &Fr     \\
        &       & 1     & 2     & 3     \\
 6      & 7     & 8     & 9     &10     \\
13      &14     &15     &16     &17     \\
20      &21     &22     &23     &24     \\
27      &28     &       &       &       \\

The only reasonable solution I could come up with so far was

cal -h | sed -r -e '1d' -e \
  's/^(..)?(...)?(...)?(...)?(...)?(...)?(...)?$/\2\t\&\3\t\&\4\t\&\5\t\&\6\t\\\\/'

... and I really tried hard. The nice thing about it being that it's uncomplicated and easy to understand, the bad thing about it that it's "unflexible" (It couldn't cope with a week of 8 days) and a little verbose. I'm looking for alternative solutions to learn from ;-)

EDIT: Found another one that seems acceptable

cal -h | tail -n +2 |
    perl -ne 'chomp;
        $,="\t&";
        $\="\t\\\\\n";
        $line=$_;
        print map {substr($line,$_*3,3)} (1..5)'

EDIT: Nice one:

cal -h | perl \
    -F'(.{1,3})' -ane \
        'BEGIN{$,="\t&";$\="\t\\\\\n"}
            next if $.==1;
            print @F[3,5,7,9,11]'
like image 376
Jo So Avatar asked Oct 09 '22 19:10

Jo So


2 Answers

Tested on OS-X:

cal 02 2012 |grep . |tail +2 |perl -F'/(.{3})/' -ane \
    'chomp(@F=grep $_,@F); $m=$#F if !$m; printf "%s"."\t&%s"x$m."\t\\\\\n", @F;'

Where cal output has 3-character columns; {3} could be changed to match your cal output.

like image 199
MisterEd Avatar answered Oct 13 '22 10:10

MisterEd


Using the GNU version of awk:

My output of cal using an english LANG.

Command:

LANG=en_US cal

Output:

    February 2012   
Su Mo Tu We Th Fr Sa
          1  2  3  4
 5  6  7  8  9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29

The awk one-line:

LANG=en_US cal | awk '
BEGIN { 
  FIELDWIDTHS = "3 3 3 3 3 3 3"; 
  OFS = "&";
} 
FNR == 1 || $0 ~ /^\s*$/ { next } 
{ 
  for (i=2; i<=6; i++) { 
    printf "%-3s%2s", $i, i < 6 ? OFS : "\\\\";
  } 
  printf "\n";
}'

Result:

Mo  &Tu  &We  &Th  &Fr \\
    &    & 1  & 2  & 3 \\
 6  & 7  & 8  & 9  &10 \\
13  &14  &15  &16  &17 \\
20  &21  &22  &23  &24 \\
27  &28  &29  &    &   \\
like image 25
Birei Avatar answered Oct 13 '22 12:10

Birei