2011-07-28 8 views
2

私はテンプレート設定ファイルを実装しようとしています。 私はPythonを好むだろうが、私はperlでも答えをとるだろう。 私は私の例としてperlを使用しました。pythonまたはperlのテンプレート構成ですか?

私は少しを検索し、 見つけた - python single configuration file - ConfigObj - python configuration file generator - ePerl を私はそれらからの私の問題を解決することができませんでした。

私は(さえないセクションで)ほとんどINI形式の設定ファイルを生成しようとしている:

# Comments 
VAR1 = value1 
EDITOR = vi 

をし、私は、テキスト内のスクリプト言語を埋め込むんだテンプレートから生成することを必要とします:

# Config: 
MYPWD = <: `pwd` :> 

間でテキスト '<:' と '>' スクリプト言語(PythonやPerlの)であろう。テンプレートと同様に、その標準出力がキャプチャされ、結果のテキストに挿入されます。この例で使用されているテンプレートは基本的にはeperlですが、使用できる場合はPythonを使用したいと考えています。

、最終的には、定義された変数は再利用可能でなければなりません:

# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
# platform.cfg 
# This one variable 
VAR =value 
# this is a templated variable. The langage is perl, but could be python. 
HELLO= <: print 'World' :> 
# This is a multi-line code which should resolve to a single line value. 
LONGER = <: 
if (1) { 
    print "abc "; 
} 
$pwd = `/bin/pwd`; 
chomp($pwd); 
print $pwd; 
:> 
# Another one to test the carriage returns. 
MULTIPLE = /<: print "proj" :>/<: print "tahiti":>/<: 
print "pd/1/"; 
$system = `grep -w VAR platform.cfg | egrep -v 'print|platform.cfg' | cut -d = -f 2-`; 
chomp($system); 
print $system; 
:> 
# variables dependent from the previous variable definition 
VAR1 = <: print $VAR :>1 
# variables dependent from the previous variable definition 
VAR2 = <: print $VAR1 :>2 
# variables dependent from the previous variable definition 
VAR3 = <: print $VAR2 :>3 
# variables dependent from the previous variable definition 
VAR4 = <: print $VAR3 :>4 
# BTW, multi-line comments are significant 
# and should be preserved as the documentation for the 
# variable just below: 
VAR5 = <: print $VAR4 :>5 
VAR6 = <: print $VAR5 :>6 
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 

そして、私は外にこの結果を得るために探しています:

# Config: 
CODE_HOME = /some/path 
CODE_BIN = <:=$CODE_HOME:>/bin 

ここで私が読んテストソースファイルですスクリプト。 設定ファイルに定義されている変数をインタプリタの一部にする方法を理解できませんでしたか?

# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
# platform.cfg 
# This one variable 
VAR =value 
# this is a templated variable. The langage is perl, but could be python. 
HELLO= World 
# This is a multi-line code which should resolve to a single line value. 
LONGER = abc /src/byop/CODE 
# Another one to test the carriage returns. 
MULTIPLE = /proj/tahiti/pd/1/value 
# variables dependent from the previous variable definition 
VAR1 = value1 
# variables dependent from the previous variable definition 
VAR2 = value12 
# variables dependent from the previous variable definition 
VAR3 = value123 
# variables dependent from the previous variable definition 
VAR4 = value1234 
# BTW, multi-line comments are significant 
# and should be preserved as the documentation for the 
# variable just below: 
VAR5 = value12345 
VAR6 = value123456 
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 

お寄せいただきありがとうございます。

+0

これは非常に具体的で独特なテンプレートの方言のようです。これがどのような形式になるのか分かりますか? – SingleNegationElimination

+0

@TokenMacGuy:コメントをいただきありがとうございます。私は設定とテンプレートをマージすることをよりよく説明するために私の質問を編集しました。あなたの質問に答えようとしています:着信ファイルのフォーマットは、ブラケット付きの設定ファイルです: '<:' and ':>'。これらの区切り文字の間にあるものは、スクリプティング言語(Python、またはperl、pick one)にあり、テンプレートで以前に定義された変数にスクリプト言語がアクセスできるようにするという制約が追加されています。 (それはもっと明確ですか?) – GED

+0

これは現場で構成しているテンプレート言語ですか? – SingleNegationElimination

答えて

1

別の構文を使用しても構わない場合は、makoのようなテンプレートライブラリがあります。Jinaj2もかなりいいです。試してみたライブラリで行ってください!コードブロックのためのPythonを使用して除いて、基本的には以上のように動作します

import re, StringIO, sys 

def exec_block(block, variables): 
    """Captures output of exec'd code block""" 
    code = compile(block.strip(), '<string>', 'exec') 
    _stdout, result = sys.stdout, StringIO.StringIO() 
    sys.stdout = sys.__stdout__ = result 
    exec(code, variables) 
    sys.stdout = sys.__stdout__ = _stdout 
    return result.getvalue() 

def format_template(template): 
    """Replaces code blocks with {0} for string formating later""" 
    def sub_blocks(matchobj): 
     """re.sub function, adds match to blocks and replaces with {0}""" 
     blocks.append(matchobj.group(0)[2:-2].strip()) 
     return '{0}' 

    blocks = [] 
    template = re.sub(r'<:.+?:>', sub_blocks, template, flags=re.DOTALL).splitlines() 
    blocks.reverse() 
    return blocks, template 

def render_template(blocks, template): 
    """renders template, execs each code block and stores variables as we go""" 
    composed, variables = [], {} 
    for line in template: 
     if '{0}' in line: 
      replacement = exec_block(blocks.pop(), variables).strip() 
      line = line.format(replacement) 
     if not line.startswith('#') and '=' in line: 
      k, v = [x.strip() for x in line.split('=')] 
      variables[k] = v 
     composed.append(line) 
    return '\n'.join(composed) 

if __name__ == '__main__': 
    import sys 
    with open(sys.argv[1]) as f: 
     blocks, template = format_template(f.read()) 
     print rend_template(blocks, template) 

:あなたはが本当に独自のテンプレートライブラリを実装する場合、これはあなたのスタートを与えるかもしれません。 1つの割り当てにつき1つのブロックしかサポートしていませんが、これは実際は私にとって最良のアプローチです。あなたは次のようにそれを設定ファイルを養うことができます:

VAR = value 
LONGER = <: 
    print 'something' 
:> 
VAR1 = <: print VAR :>1 
# comment 
VAR2 = <: print VAR1 :>2 
VAR3 = <: print VAR2 :>3 
VAR4 = <: print VAR3 :>4 

そしてそれは、各ブロックはあなたのための変数をレンダリングexecします:

VAR = value 
LONGER = something 
VAR1 = value1 
# comment 
VAR2 = value12 
VAR3 = value123 
VAR4 = value1234 
4

私は、まさにこの目的のためにTemplate::MasonLiteを開発しました。私は多くの設定ファイル(私の場合はApacheの設定)をたくさん生成していました。私は特別な依存関係なしに複数のホスト上で実行するためにスクリプトが必要でした。そこで、私はHTML :: Masonのカットダウン版を開発しました。これはスクリプトに直接埋め込むことができます(余分に〜70行)。 Mason templating syntaxは、全く新しい言語を構成するのではなく、任意のロジック(条件、ループなど)に対してPerlを使用します。

Template :: MasonLiteの実装はCPANにはありません(上のリンクのみ)。なぜなら、CPANをさらに別のテンプレートエンジンで混乱させたくないからです。

私はそれを開発した時点で、私はテンプレートのどのような元気な形も欠いていたcfengineを使用していました。私は以来、テンプレート言語を含む人形劇に移行しました。私はまだgenerating presentation slidesのためにTemplate :: MasonLiteを使用します。

+0

CPAN上に存在する軽量テンプレートシステム:[Text :: Template](http://p3rl.org/Text::Template)(設定可能な区切り文字、Perl構文)、[Template :: Tiny](http://p3rl.org/Template :: Tiny)( '[%' '%]'デリミタ、Template-Toolkit構文) – daxim

+0

@Grant:OPのように、割り当てをテンプレートエンジンに戻すことはサポートされていません。 – bukzor

+0

@Grant:ありがとう、私はそれを試みたが、構成変数(別名:VAR2 = から派生した値)を再利用する方法を見つけることができませんでした – GED

関連する問題