def parse_line(line, sco, note_system="base40", lineno=1): """Parse a line, append the parsed result into the sco and return the sco A line can be a BlankLine, a reference record, a comment, or have tabular data (spines) in which case we parse each item individually with :func:`humdrum.parse_item`. Both reference record and comments start with !, but a reference record starts with 3 exclamation marks (!!!) while a comment starts with one, two, four or more exclamation marks. Global comments have more than one exclamation marks and will be catched by this function. Local comments have only one exclamation mark and are applied to an individual spine. A local comment will be catched in :func:`humdrum.parse_item()`. """ if utils.search_string(r"^[ \t]*$", line) is not None: sco.append(score.BlankLine()) elif utils.search_string(r"^!{3}[a-zA-Z ]+", line): record = parse_reference_record(line) if record.name.startswith("COM"): sco.composer = record.data elif record.name.startswith("OTL"): sco.title = record.data sco.append(record) elif utils.search_string(r"^(!{2})|(!{4,})[a-zA-Z ]+", line): sco.append(parse_comment(line)) else: sline = enumerate(split_spine(line, sco, lineno)) parsed = [parse_item(i, sco, note_system, lineno, n) for n, i in sline] sco.append(parsed) return sco
def parse_bar(item): """Search a string for bar elements and return a :class:`score.Bar` This function will search for the bar number, if a bar begins or ends a repetition and if it's a double bar. Humdrum has a bunch of syntax for visual bar lines that we don't parse. See :ref:`todo`. """ return score.Bar(utils.search_string("[0-9]+([a-z]+)?", item), bool(utils.search_string(":\\||:!", item)), bool(utils.search_string("\\|:|!:", item)), bool(utils.search_string("==", item)))
def test_search_string_foo_in_foobar(): assert utils.search_string("^foo", "foobar") == "foo"
def test_search_string_numbers_in_foobar(): assert utils.search_string("[0-9]+", "foobar") == None