Source code for puzzlepiece.parse

import re
import time
from pyqtgraph.Qt import QtWidgets


[docs] def parse_params(text, puzzle): """ Parse a string of the following format to construct references to :class:`~puzzlepiece.param.BaseParam` objects: ``[Piece name]:[param name], [Piece name]:[param name], ...`` :param text: The string to parse. :param puzzle: The app's :class:`~puzzlepiece.puzzle.Puzzle`. :rtype: list(puzzlepiece.param.BaseParam, ) """ args = text.split(", ") result = [] for arg in args: piece, name = arg.split(":") if name in puzzle.pieces[piece].params: result.append(puzzle.pieces[piece].params[name]) else: raise SyntaxError(f"Parameter parse error for {arg}") return result
[docs] def run(text, puzzle): """ Execute a set of puzzlepiece script commands. Commands can be separated by new lines, or a semicolon (``;``) + space. If a command needs to *include* a semicolon followed by a space, it can be inserted as ``\;`` (backslash character + semicolon + space). Comments can be added by starting the line with ``#``. The available commands are: - ``set:[Piece name]:[param name]:[value]`` - ``run:[Piece name]:[action name]`` - ``get:[Piece name]:[param name]`` - ``sleep:[duration in s]`` - ``prompt:[text]`` - ``print:[text]`` :param text: The string to parse. :param puzzle: The app's :class:`~puzzlepiece.puzzle.Puzzle`. """ text = text.replace("\\;", "<!--semicolon-->") text = text.replace("; ", "\n") instructions = text.split("\n") for instruction in instructions: if len(instruction) == 0 or instruction[0] == "#": continue task, *params = instruction.split(":") if task == "set": piece, param, *value = params value = ":".join(value) value = value.replace("<!--semicolon-->", ";") puzzle.pieces[piece].params[param].set_value(value) elif task == "run": piece, *action = params action = ":".join(action) puzzle.pieces[piece].actions[action]() elif task == "get": piece, *param = params param = ":".join(param) puzzle.pieces[piece].params[param].get_value() elif task == "sleep": duration = params[0] time.sleep(float(duration)) elif task == "prompt": text = ":".join(params) text = format(text, puzzle) box = QtWidgets.QMessageBox() box.setText(text) box.exec() elif task == "print": text = ":".join(params) text = format(text, puzzle) print(text) else: raise SyntaxError("Unknown task in {}".format(instruction)) puzzle.process_events()
[docs] def format(text, puzzle): """ Insert values of :class:`~puzzlepiece.param.BaseParam` objects into a string. To insert a value, use the following format: ``The value is: {[Piece name]:[param name]}`` If a param has a getter, it will be called. One can also apply additional formatting: ``The formatted value is {[Piece name]:[param/readout name];[format]}`` where `format` follows the 'new' standard as described at https://pyformat.info/. For example: ``The laser power is {laser:power;:.1f}`` :param text: The string to parse. :param puzzle: The app's :class:`~puzzlepiece.puzzle.Puzzle`. :rtype: str """ for match in re.findall(r"{[a-zA-Z0-9:; _\-\.]+}", text): m = str(match) elements = m[1:-1].split(";") param = parse_params(elements[0], puzzle)[0] if len(elements) == 1: if param._format is not None: result = param._format.format(param.get_value()) else: result = str(param.get_value()) elif len(elements) == 2: result = ("{" + elements[1] + "}").format(param.get_value()) text = text.replace(m, result) return text