Package: decorator-parser
Decorators ParserLicense© 2023 Smartschool Inc. All rights reserved.Installation guideInstall Python 3.7 or newer fromhttps://www.python.org/downloads/Install PIP usingthis guideRunpip install decorator-parserin your command lineAPIparsedefparse(self,path=None,data=None)Parses given string or file and returns a list of dictionaries. If bothpathanddataare provided,datawill be ignored.Decorators formatDecorator name can be any string that does not contain '@' character. If decorator
does not satisfy this requirementInvalidDecoratorExceptionwill be thrown.Example:@decorator(some nice value)Standard decoratorsDecorators can be used in one of three ways:@decorator(value)or@decorator()
Some very long and complicated value that would be hard to read if it were in parenthesis like the value above.or@decorator
Some very long and complicated value that would be hard to read if it were in parenthesis like the value above.All of these create Python dictionary like this:{'decorator':'value'}@new decoratorUsing @new decorator starts a new dictionary and adds it to the current list of dictionaries. In a single piece of text between two @new decorators (which correspond to a single Python dictionary) there can not be two decorators with the same name. Using a same name without an appropriate @new decorator will result inDuplicateDecoratorExceptionbeing thrown.Example:task.txt:@question()
Who is Lincoln?

@new
@question()
What is the purpose of the Bill of Rights?run.py:fromdecorator_parser.parseimportParsertask_parser=Parser()print(task_parser.parse_file('task.txt'))result:[{'question':'Who is Lincoln?'},{'question':'What is the purpose of the Bill of Rights?'}]Global decoratorsIn addition to standard decorators, decorators which name starts withglobal-are added to each dictionary while parsing a file. Dictionary key is the decorator's suffix afterglobal-Example:task.txt:@global-topic(History)
@question()
Who is Lincoln?

@new
@question()
What is the purpose of the Bill of Rights?run.py:fromdecorator_parser.parseimportParsertask_parser=Parser()print(task_parser.parse_file('task.txt'))result:[{'topic':'History','question':'Who is Lincoln?'},{'topic':'History','question':'What is the purpose of the Bill of Rights?'}]ConstraintsDecorators can use constraints on their values. If a decorator has value that does not match regular expression
provided, Parser will throwInvalidValueException. Parser class takes optionalconstraintsargument in its constructor which
is a Python dictionary in a format shown below (if format of the given dictionary is invalid,InvalidConstraintExceptionwill be thrown):example={'question':{'regex':'([^@]+)','description':'any non-empty string without @'},'correct':{'regex':'([1-4])','description':'any number from 1 to 4'}}Example 1task.txt:@correct(11)run.py:fromdecorator_parser.parseimportParsertask_parser=Parser(example)print(task_parser.parse_file('task.txt'))Will result in the following output:errors.InvalidValueException: Line 1: 'correct' should be any number from 1 to 4 but is 11Example 2If we take Example 1 but change task.txt file to:correct(1)The output will be:[{'correct':'1'}]Ignored decoratorsIf you need to use @ symbol for something else than decorator, you can specify
names to exclude from the searchExample:task.txt:@question
Some long question with @ref in itrun.py:fromdecorator_parser.parseimportParsertask_parser=Parser(ignored=['ref'])print(task_parser.parse_file('task.txt'))Will result in the following output:[{'question':'Some long question with @ref in it'}]