2015-11-30 2 views
1

Je listes Markdown de la forme suivante:Comment est-ce que je pourrais lire une liste de Markdown dans un OrderedDict de Python?

- launchers 
    - say hello 
     - command: echo "hello" | festival --tts 
     - icon: shebang.svg 
    - say world 
     - command: echo "world" | festival --tts 
     - icon: shebang.svg 
    - say date 
     - command: date | festival --tts 

J'ai une fonction qui peut convertir cette liste Markdown à un dictionnaire, comme ce qui suit:

{'say world': {'command': 'echo "world" | festival --tts', 'icon': 'shebang.svg'}, 'say hello': {'command': 'echo "hello" | festival --tts', 'icon': 'shebang.svg'}, 'say date': {'command': 'date | festival --tts'}} 

Quand je fais cela, évidemment le la commande est perdue. Quelle serait une manière appropriée de garder cette commande? Une liste simple serait-elle bonne? Un OrderedDict serait-il meilleur? Comment devrait-il être fait?

Ce que j'ai à ce jour est indiqué ci-dessous un exemple de travail minimal:

import re 

def Markdown_list_to_dictionary(Markdown_list): 
    line = re.compile(r"(*)- ([^:\n]+)(?:: ([^\n]*))?\n?") 
    depth = 0 
    stack = [{}] 
    for indent, name, value in line.findall(Markdown_list): 
     indent = len(indent) 
     if indent > depth: 
      assert not stack[-1], "unexpected indent" 
     elif indent < depth: 
      stack.pop() 
     stack[-1][name] = value or {} 
     if not value: 
      # new branch 
      stack.append(stack[-1][name]) 
     depth = indent 
    return(stack[0]) 

Markdown_list =\ 
""" 
- launchers 
    - say hello 
     - command: echo "hello" | festival --tts 
     - icon: shebang.svg 
    - say world 
     - command: echo "world" | festival --tts 
     - icon: shebang.svg 
    - say date 
     - command: date | festival --tts 
""" 

print(Markdown_list_to_dictionary(Markdown_list)) 
+0

réponse simple: oui, utilisez un 'OrderedDict' si vous voulez conserver votre commande dans le dictionnaire. en utilisant une simple liste ne serait pas en mesure de vous donner le type de structure que vous semblez vouloir puisqu'il n'y a aucun moyen d'ajouter un titre/nom d'appel à une liste interne. –

Répondre

1

Oui, un OrderedDict semble que cela devrait fonctionner dans ce cas. Vous le code serait alors ressembler à quelque chose comme ceci:

import re 
from collections import OrderedDict as _OrderedDict 

def Markdown_list_to_dictionary(Markdown_list): 
    line = re.compile(r"(*)- ([^:\n]+)(?:: ([^\n]*))?\n?") 
    depth = 0 
    stack = [_OrderedDict()] 
    for indent, name, value in line.findall(Markdown_list): 
     indent = len(indent) 
     if indent > depth: 
      assert not stack[-1], "unexpected indent" 
     elif indent < depth: 
      stack.pop() 
     stack[-1][name] = value or _OrderedDict() 
     if not value: 
      # new branch 
      stack.append(stack[-1][name]) 
     depth = indent 
    return(stack[0]) 

Markdown_list =\ 
""" 
- launchers 
    - say hello 
     - command: echo "hello" | festival --tts 
     - icon: shebang.svg 
    - say world 
     - command: echo "world" | festival --tts 
     - icon: shebang.svg 
    - say date 
     - command: date | festival --tts 
""" 

print(Markdown_list_to_dictionary(Markdown_list)) 

Et la sortie comme ceci:

OrderedDict([('launchers', OrderedDict([('say hello', OrderedDict([('command', 'echo "hello" | festival --tts'), ('icon', 'shebang.svg')])), ('say world', OrderedDict([('command', 'echo "world" | festival --tts'), ('icon', 'shebang.svg')])), ('say date', OrderedDict([('command', 'date | festival --tts')]))]))]) 

Il est pas aussi agréable à regarder lors de l'impression, mais il ne fonctionne correctement.