示例#1
0
文件: colors.py 项目: saka29/nutshell
 def __init__(self, colors, start=0, *, dep: ['@NUTSHELL', '@TABLE'] = (None, None)):
     _nutshell, _table = dep
     self._vars = _table.vars if _table else {}
     self._packed_dict = None
     self._src = [i.split('#')[0].strip() for i in colors]
     self.colors = list(enumerate((k.split(':', 1) for k in self._src if k), 1))
     if _nutshell is not None:
         self.colors = [(i, (v[0], _nutshell.replace_line(v[1]))) for i, v in self.colors]
     d = {}
     self.non_override_colors = set()
     for lno, (color, states) in self.colors:
         states = self._sep_states(multisplit(states, (None, ',')))
         if '..' in color:
             states = list(states)
             crange = ColorRange(len(states)-1, *(self.unpack(c.strip(), lno) for c in color.split('..')))
             for state, color in zip(states, crange):
                 d[state] = self.unpack(color, lno)
             continue
         color = self.unpack(color.strip(), lno)
         for term in states:
             try:
                 state = int(term.lstrip('*'))
             except ValueError:
                 raise Error(lno, f'State {term} is not an integer')
             d[state] = color
             if term.startswith('*'):
                 self.non_override_colors.add(state)
     self.states = d
示例#2
0
 def _sep_states(self, start) -> dict:
     states, comments, dims = {}, {}, {}
     cur_states, cur_comments = set(), []
     last_comment, last_comment_lno = None, 0
     replace_constants = (
         lambda x: x
     ) if self._nutshell is None else self._nutshell.replace_line
     for lno, line in enumerate(map(str.strip, self._src[start - 1:]),
                                start):
         if not line:
             continue
         if line.startswith('#'):
             cur_comments.append(line)
             last_comment_lno = lno
             continue
         if last_comment_lno:
             *cur_comments, last_comment = cur_comments
             cur_states = set()
             for word in multisplit(replace_constants(last_comment),
                                    (None, ',')):
                 if word.isdigit():
                     state = int(word)
                     if not 0 < state < 256:
                         raise Error(
                             last_comment_lno,
                             f'Icon declared for invalid state {state}')
                     if state in states:
                         raise Error(
                             last_comment_lno,
                             f'State {state} has already been assigned an icon'
                         )
                     cur_states.add(state)
                 elif word in self._vars:
                     cur_states.update(self._vars[word])
                 elif TableRange.check(word):
                     cur_states.update(TableRange(word))
             last_comment_lno = 0
         if cur_states:
             line = line.translate(TWO_STATE)
             for state in cur_states:
                 states.setdefault(state, []).append(line)
                 comments.setdefault(state, []).extend(cur_comments)
             cur_comments = []
     for state, rle in states.items():
         states[state] = rle[1:]
         dims[state] = list(
             map(int, chain.from_iterable(self._rDIMS.findall(rle[0]))))
     return states, comments, dims
示例#3
0
def infile(path: Path):
    """Path to a file that defines @ICONS. Hyphen for stdin."""
    with StreamProxy(path, alternate=sys.stdin, use_alternate=(path.name == '-')) as f:
        file = f.readlines()
    it = iter(file)
    # seek to @ICONS
    for i in iter(lambda: next(it).strip(), '@ICONS'):
        pass
    # Return line of and line after @RULE header (to extract rulename from),
    # as well as the lines on which icon colors are defined
    return (
      next(((a.split(), b) for a, b in zip(*[map(str.strip, file)]*2) if a.startswith(('@RULE', '@NUTSHELL'))), None),
      [
        multisplit(i.split('#')[0].strip(), (' ', ':'), amounts=(1, 1))
        for i in
        takewhile(lambda s: not s.startswith('@'), it)
        if i.startswith(STARTS)
      ]
      )