Attachment 'dictate-1.3.py'

Download

   1 #-*- coding: utf-8 -*-
   2 '''
   3 MoinMoin - dictate parser, Version 1.3, 9.10.2012
   4 
   5 A simple parser that reads key:value pairs from a dictionary listings, and optionally (1) sorts entries by keys, (2) highlights and counts duplicate keys, (3) counts entries and non-conforming lines, (4) formats the output as either normal for dictionary entries or as a simple two-column table, (5) displays the output in final or markup modes, and (5) includes a summary table at the head of the listing.
   6 
   7 The parser works as both a processing instruction and page section. The parser name is follow by a list of keywords separated by spaces to select the options required.
   8 
   9 Keywords
  10 
  11 ascending : enrtries sorted on ascending value of first group of digits in the key, then alphabtically as requested by sort and reverse keywords. Sort must also be set.
  12 
  13 descending : enrtries sorted on descending value of first group of digits in the key, then alphabtically as requested by sort and reverse keywords. Sort must also be set.
  14 
  15 case : perform case sensitive sort. By default, sort is case insensitive.
  16 
  17 raw : display the output as raw markup, so it can be cut and pasted into the same or another page. By default, text will be formatted.
  18 
  19 reverse : sort in descending order. By default, sorting is in ascending order.
  20 
  21 sort : sort entries by keys for display only. By default, entries are unsorted.
  22 
  23 summary : display a table at the head of the listing with counts of unique keys, duplicate keys, ignored lines (line that are not in " key:: value" format), and the sorting and layout options used in processing the text. By default, no summary is provided.
  24 
  25 tabulate : tabulate the valid " key:: value" entries as a simple two-column table. By default, text will be formatted s normal dictionary entires (as is this list of keywords).
  26 
  27 val : perform sort and duplicate detection on val. By default, key is used.
  28 
  29 warn : highlight duplicate keys. This is done the insertion of the symbol  before the key in the listing. In the case of the dictionary entry formatting the duplicate entries are formatted as normal lines. By default, no warning is given.
  30 
  31 Usage
  32 
  33 As processing instruction
  34 
  35 #format dictate [ascending|descending ][case ][raw ][reverse ][sort ][summary ][tabluate ][val ][warn ]
  36 
  37  key:: value
  38  key:: value
  39  ...
  40 As parser section
  41 
  42 {{{#!dictate [ascending|descending ][case ][raw ][reverse ][sort ][summary ][tabluate ][val ][warn ]
  43  key:: value
  44  key:: value
  45  ...
  46 }}}
  47 
  48 History
  49 
  50 Version 1.3 - 8.10.2012: added ascending/descending numerical sorting; removed markup from val for plain text sorting
  51 Version 1.2 - 2.1.2011: added options to sort on val not only key, and to do reverse sorting
  52 Version 1.1 - 2.1.2011: added case sensitive/insensitive sorting
  53 Version 1.0 - 1.1.2011: initial version
  54 
  55 Developed with inspiration and code from:
  56 
  57 keyval.py parser - @copyright: 2006 by Matt Cooper <macooper@vt.edu>
  58 sort.py parser - @copyright: 2005 ReimarBauer
  59 
  60 Copyright
  61 
  62 @copyright: 2012 Ian Riley <ian.riley@internode.on.net>
  63 
  64 License
  65 
  66 GNU GPL, see COPYING for details.
  67 
  68 
  69 '''
  70 Dependencies = []
  71 
  72 from MoinMoin.parser import text_moin_wiki as wiki
  73 from MoinMoin import wikiutil
  74 from operator import itemgetter
  75 import re
  76 
  77 class Parser:
  78     parsername = 'dictate'
  79 
  80     def __init__(self, raw, request, **kw):
  81         self.raw = raw
  82         self.request = request
  83         self.form = request.form
  84         self._ = request.getText
  85         self.args = kw.get('format_args', '')
  86 
  87     def format(self, formatter):
  88         txt = "%s"
  89         txtvb = "<<Verbatim(%s)>>"
  90         eol = "\n"
  91         sep = ":: "
  92         space = " "
  93         parsing = ("{{{", "}}}", )
  94         tab = "||"
  95         bold = "'''"
  96         large = ("~+", "+~", )
  97         warn = ("", " /!\\ ", )
  98         headings = ("Summary", "Dictionary", )
  99         sort_types = ("Not sorted", "Keys", "Values", )
 100         case_types = ("n/a", "Insensitive", "Sensitive", )
 101         order_types = ("n/a", "Forward", "Reverse", )
 102         numeric_types = ("n/a", "Ascending", "Descending", )
 103         layout_types = ("Dict", "Table", )
 104         keydup, valdup = (False, False, )
 105         dictates, current, entries, results = ([], [], [], [], )
 106         counter, keydups, valdups, ignored, layout = (0, 0, 0, 0, 0, )
 107 
 108         # set options, default setting is false
 109         dictates = self.args.split(space)
 110         numsorting = ("ascending" in dictates) or ("descending" in dictates)
 111         numrevsort = ("descending" in dictates)
 112         casesort = "case" in dictates
 113         markup = "raw" in dictates
 114         revsort = "reverse" in dictates
 115         sorting = "sort" in dictates
 116         summarise = "summary" in dictates
 117         tabulate = "table" in dictates
 118         valsort = "val" in dictates
 119         warning = "warn" in dictates
 120         del dictates
 121 
 122         # [0-3] dict, [4-7] tabulate, for warn (none, key, val, both)
 123         layouts = (space+txt+sep+txt+eol, \
 124                    warn[warning][1:]+txt+sep+txt+eol, \
 125                    txt+sep+warn[warning][1:]+txt+eol, \
 126                    warn[warning][1:]+txt+sep+warn[warning][1:]+txt+eol, \
 127                    tab+txtvb+tab+txt+tab, \
 128                    tab+warn[warning]+txtvb+tab+txt+tab, \
 129                    tab+txtvb+tab+warn[warning]+txt+tab, \
 130                    tab+warn[warning]+txtvb+tab+warn[warning]+txt+tab, ) 
 131                   
 132         summary = (bold+large[0]+headings[0]+large[1]+bold+eol+ \
 133                    "||<:>Entries||<:>Unique<<BR>>Keys||<:>Duplicate<<BR>>Keys \
 134                     ||<:>Unique<<BR>>Values||<:>Duplicate<<BR>>Values||<:>Ignored<<BR>>Lines \
 135                     ||<:>Sort||<:>Case||<:>Order||<:>Numeric \
 136                     ||<:>Warn||<:>Layout||<:>Raw||"+eol+ \
 137                    "||<:>%s||<:>%s||<:>%s \
 138                     ||<:>%s||<:>%s||<:>%s \
 139                     ||<:>%s||<:>%s||<:>%s||<:>%s \
 140                     ||<:>%s||<:>%s||<:>%s||"+eol+ \
 141                    bold+large[0]+headings[1]+large[1]+bold+eol)
 142 
 143         lines = self.raw.split(eol)
 144         for line in lines:
 145             if line:
 146                 # handle dict lines
 147                 if (line[0] == space) and (sep in line):
 148                     counter = counter + 1 
 149                     key, val = (line.lstrip(space)).split(sep)
 150                     
 151                     #convert val to html then remove tags for plain text sorting
 152                     val_html = wiki.Parser('', self.request)
 153                     val_html.format(formatter)
 154                     val_txt = re.sub('<[^>]*>', '', val_html.scan(val))
 155                     key_num = re.findall(r'\d+', key)
 156                     if key_num: key_num = int(key_num[0])
 157                     val_num = re.findall(r'\d+', val)
 158                     if val_num: val_num = int(val_num[0])
 159                     
 160                     sortables = (key.lower(), key, key_num,
 161                                  val_txt.lower(), val_txt, val_num)
 162                     keydup = (sortables[casesort] in (entry[casesort] for entry in entries))
 163                     keydups = keydups + keydup
 164                     valdup = (sortables[casesort + 3] in (entry[casesort + 3] for entry in entries))
 165                     valdups = valdups + valdup
 166                     entries.append((sortables + (val, counter, keydup, valdup, ))) 
 167                     #entries.append((key.lower(), key, key_num, 
 168                     #                val_txt.lower(), val_txt, val_num,
 169                     #                val, counter, keydup, valdup, )) 
 170                 # count non-dict lines
 171                 else:
 172                     ignored = ignored + 1
 173         del lines, sortables
 174 
 175         if sorting:
 176             # first sort the secondary term, as this order is stable (ie preserved)
 177             entries = sorted(entries, key=itemgetter(casesort + ((not valsort) * 3)), reverse=revsort)
 178             # then sort on the primary term
 179             entries = sorted(entries, key=itemgetter(casesort + (valsort * 3)), reverse=revsort)
 180             if numsorting:
 181                 # sort on numbers, demoting primay and secondary alpha sorting
 182                 entries = sorted(entries, key=itemgetter(2 + ((valsort) * 3)), reverse=numrevsort)
 183 
 184         for entry in entries:
 185             layout = (tabulate * 4) + (warning * (entry[8] + (entry[9] * 2)))
 186             results.append((layouts[layout]) % (entry[1], entry[6], ))
 187         del entries
 188         if markup:
 189             results.insert(0, parsing[0])
 190             results.append(parsing[1])
 191         if summarise:
 192             results.insert(0, summary % (counter, counter-keydups, keydups,
 193                                          counter-valdups, valdups, ignored, \
 194                                          sort_types[sorting * (valsort + 1)], \
 195                                          case_types[sorting * (casesort + 1)], \
 196                                          order_types[sorting * (revsort + 1)], \
 197                                          numeric_types[numsorting * (numrevsort + 1)], \
 198                                          warning, layout_types[tabulate], markup, ))
 199         wikiizer = wiki.Parser(eol.join(results), self.request)
 200         wikiizer.format(formatter)

You are not allowed to attach a file to this page.