diff --git a/chatmastermind/message.py b/chatmastermind/message.py new file mode 100644 index 0000000..cb426e7 --- /dev/null +++ b/chatmastermind/message.py @@ -0,0 +1,52 @@ +""" +Module implementing message related functions and classes. +""" +from typing import Type, TypeVar + +QuestionInst = TypeVar('QuestionInst', bound='Question') + + +class MessageError(Exception): + pass + + +def source_code(text: str, include_delims: bool = False) -> list[str]: + """ + Extracts all source code sections from the given text, i. e. all lines + surrounded by lines tarting with '```'. If 'include_delims' is True, + the surrounding lines are included, otherwise they are omitted. The + result list contains every source code section as a single string. + The order in the list represents the order of the sections in the text. + """ + code_sections: list[str] = [] + code_lines: list[str] = [] + in_code_block = False + + for line in text.split('\n'): + if line.strip().startswith('```'): + if include_delims: + code_lines.append(line) + if in_code_block: + code_sections.append('\n'.join(code_lines) + '\n') + code_lines.clear() + in_code_block = not in_code_block + elif in_code_block: + code_lines.append(line) + + return code_sections + + +class Question(str): + """ + A single question with a defined prefix. + """ + prefix = '=== QUESTION ===' + + def __new__(cls: Type[QuestionInst], string: str) -> QuestionInst: + """ + Make sure the question string does not contain the prefix. + """ + if cls.prefix in string: + raise MessageError(f"Question '{string}' contains the prefix '{cls.prefix}'") + instance = super().__new__(cls, string) + return instance