tags:

views:

193

answers:

5

Golf - implement a simple templating scheme.

Expansions are:

  • %KEY% -> VALUE
  • %% -> %

Command line arguments:

  • ARG1: dictionary file, formatted in the key=value style as in example
  • ARG2: template file

Here my not quite golf attempt(python): 261 chars.

import sys
dd = dict([ll.split("=",2) for ll in open( sys.argv[1],'r') if len(ll.split("=", 2)) == 2])
tt = "".join([ ll for ll in open( sys.argv[2],'r')])
sys.stdout.write("".join([(((s == "") and "%") or ((s in dd) and dd[s]) or s) for s in tt.split("%")]))

DICT

NAME=MyName
ODDS=100

TEMPLATE

I, %NAME% am %ODDS% %% sure that that this a waste of time.

RESULT

I, My Name am 100 % sure that this is a waste of time.

Yes, I realize this is a defective templating system, "snaps" for a shorter and better implementation.

+1  A: 

C#.

string s = "NAME=MyName ODDS=100"; // any whitespace separates entries
string t = "I, %NAME% am %ODDS% %% sure that that this a waste of time.";

foreach(var p in s.Split().Select(l=>l.Split('=')).ToDictionary(
e=>"%"+e[0]+"%",e=>e[1]))t=t.Replace(p.Key,p.Value);t=t.Replace("%%","%");
Console.WriteLine(t);

That's 159 for the algorithm portion, I believe. Note that this may produce unexpected results if you feed it something like "NAME=%%" (it'll collapse the %% further into %) but any short simple algorithm will exhibit behavior like this one way or the other, since you have to do the string replacements in some order.

mquander
+1 Nice, I was about to post something like that
Andy White
+2  A: 

In Python, you could leverage the inbuilt string formatting to make it shorter. Just needs a little regex hacking to get the syntax to match.

import sys, re
sys.stdout.write(re.sub(r'%(.+?)%',r'%(\1)s',open(sys.argv[2]).read())%dict(l.split("=",2) for l in open(sys.argv[1],'r')))

Down to 139 bytes. (Though perhaps the args/file-IO stuff shouldn't really be part of a golf challenge?)

bobince
A: 

Ruby, 114 characters

d=Hash[*[open(ARGV[0]).read.scan(/(.+)=(.*)/),'','%'].flatten]
print open(ARGV[1]).read.gsub(/%([^%]*)%/){d[$1]}
Joshua Swink
+1  A: 

in vc++.. might be the fastest way :)

void customFormat(const char* format, char dicItemSep, char dicValueSep, const char* dic, char* out)
{
    if(out)
    {
     const char x = '%';
     while(*format)
     {
      while(*format && *format != x)*out++=*format++;
  if(!*format || !*(++format))goto exit;
      if(*format == x)
      {
       *out++=x;
       continue;
      }
      const char *first = format;
      const char *d = dic;
      while(*first)
      {
       while(*d)
       {
        while(*d && (*d != *first))d++;
        if(*d == *first)
        {
         while((*first++ == *d++) && (*d != dicValueSep));
         if(!*first)goto exit;
         if(*d != dicValueSep || *first != x)
         {
          first = format;
          while(*d && (*d != dicItemSep))d++;
          continue;
         }
         break;
        }
       }
       if(!*d)break;
       d++;
       while((*d != dicItemSep) && *d && (*out++ = *d++));
       format = ++first;
       break;
      }
     }
    exit:
     *out = 0;
    }
}
int _tmain(int argc, _TCHAR* argv[])
{
    char t[1024];
    customFormat
     (
      "%NAME% am %ODDS% %% sure that that this a waste of time.",
      '\n',
      '=',
      "NAME=MyName\nODDS=100",
      t
     );
    printf("%s", t);
}
Tolgahan Albayrak
A: 

Not really an answer to the question, but I hope you realize that if you need this for any kind of real-word task, Python has a much more readable template format with {variable}

 # MyDict.py
 dict = {
     some : 'every',
     p : '?', 
     q : '?..'
 }

 # main file
 import MyDict
 print """
    What is {some}thing{p} 
    Who values this mysterious {some}thing{q}
 """.format(**dict)

If you want, you can preserve your dictionary format:

  with open(dictionary_file, 'r') as f:
      for l in f.readlines():
           k, v = '='.split(l)
           if v: dict[k] = v
ilya n.