def MagyarKozlonyHeaderExtractor( pdf_file: PdfOfLines) -> Iterable[KozlonyPagesWithHeaderAndFooter]: if not is_magyar_kozlony(pdf_file): return # TODO: assert the header. # The first page is special: # MAGYAR KÖZLÖNY 71 . szám # # A MAGYAR KÖZTÁRSASÁG HIVATALOS LAPJA # 2011. június 28., kedd # publication_date = Date.from_hungarian_text( pdf_file.pages[0].lines[3].content) result_pages = [ PageWithHeader(tuple(pdf_file.pages[0].lines[:5]), tuple(pdf_file.pages[0].lines[5:])) ] for page in pdf_file.pages: # Others are # 15202 M A G Y A R K Ö Z L Ö N Y • 2011. évi 71 . szám # result_pages.append( PageWithHeader(tuple(page.lines[:2]), tuple(page.lines[2:]))) yield KozlonyPagesWithHeaderAndFooter(publication_date, tuple(result_pages))
def test_json_output(tmpdir: Any) -> None: generator = GenerateCommand() generator.run(["json", "2013/185", "--output-dir", str(tmpdir)]) body = json.load(tmpdir.join("2013. évi CLXXV. törvény.json").open()) assert body["identifier"] == "2013. évi CLXXV. törvény" assert body[ "subject"] == "a gondnokoltak és az előzetes jognyilatkozatok nyilvántartásáról" assert body["preamble"] == "" assert body["children"][0]['__type__'] == "Subtitle" assert body["children"][0]['title'] == "A törvény hatálya" assert body["children"][4]['__type__'] == "Article" assert body["children"][4]['identifier'] == "3" assert body["children"][4]['children'][0]['identifier'] == '1' assert body["children"][4]['children'][0]['children'][0][ 'identifier'] == 'a' assert body["children"][4]['children'][0]['children'][0][ 'intro'] == "a gondnokolt" assert body["children"][34]['__type__'] == "Article" assert body["children"][34]['identifier'] == "29" assert body["children"][34]['children'][0][ 'intro'] == "Az illetékekről szóló 1990. évi XCIII. törvény 43. §-a következő (9) bekezdéssel egészül ki:" assert body["children"][36]['__type__'] == "Article" assert body["children"][36]['identifier'] == "31" assert body["children"][36]['children'][0][ 'text'] == "Hatályát veszti a gondnokoltak nyilvántartásáról szóló 2010. évi XVIII. törvény." # This should not throw act: Act = dict2object.to_object(body, Act) assert act.article('27').paragraph().semantic_data == (EnforcementDate( position=None, date=Date(2014, 3, 15)), )
def quick_parse_structure(act_text: str, *, parse_block_amendments: bool = False) -> Act: lines = [] for l in act_text.split('\n'): parts = [] spaces_num = 1 bold = '<BOLD>' in l justified = '<NJ>' not in l l = l.replace("<BOLD>", " ") l = l.replace("<NJ>", " ") for char in l: if char == ' ': if spaces_num == 0: parts.append(IndentedLinePart(5, char, bold=bold)) spaces_num += 1 else: parts.append( IndentedLinePart(5 + spaces_num * 5, char, bold=bold)) spaces_num = 0 lines.append(IndentedLine(tuple(parts), 5 if justified else 40)) act = ActStructureParser.parse("2345 évi I. törvény", Date(2345, 6, 7), "A tesztelésről", lines) if parse_block_amendments: act = ActBlockAmendmentParser.parse(act) print( json.dumps(dict2object.to_dict(act, Act), indent=' ', ensure_ascii=False)) return act
def test_date_from_hungarian_text() -> None: assert Date.from_hungarian_text('2010. november 29., hétfő') == Date( 2010, 11, 29) assert Date.from_hungarian_text('2014. február 11., kedd') == Date( 2014, 2, 11) assert Date.from_hungarian_text('2019. július 9., kedd') == Date( 2019, 7, 9)
def test_end_to_end_2010_181() -> None: # The first MK to use "The new format" is 2009/117. # But subtitles don't have numbers consistently, until the # 2010 CXXX Act about legislation. # Of course this whole project is way easier because of that Act # anyway, because it requires all in-force laws to be non-contradictory # To eachother. # The test is mainly a format-compatibility check. acts = { a.identifier: a for a in parse_single_kozlony(2010, 181) if isinstance(a, Act) } assert len( acts) == 6, "Issue 2010/181 of Magyar Kozlony contains 6 separate Acts" # !!!! assert acts["2010. évi CXXX. törvény"].article("25").paragraph("1").text == \ "A Magyar Köztársaság hivatalos lapja a Magyar Közlöny. A Magyar Közlönyt a kormányzati portálon történő " \ "elektronikus dokumentumként való közzététellel kell kiadni, melynek szövegét hitelesnek kell tekinteni." assert acts["2010. évi CXXX. törvény"].publication_date == Date( 2010, 11, 29)
# You should have received a copy of the GNU General Public License # along with Hun-Law. If not, see <https://www.gnu.org/licenses/>. from typing import Tuple import pytest from hun_law.parsers.grammatical_analyzer import GrammaticalAnalyzer from hun_law.structure import EnforcementDate, DaysAfterPublication, DayInMonthAfterPublication from hun_law.utils import Date from tests.cheap.utils import ref CASES: Tuple[Tuple[str, Tuple[EnforcementDate, ...]], ...] = ( ("E törvény 2013. július 1-jén lép hatályba.", (EnforcementDate(position=None, date=Date(2013, 7, 1)), )), ("Ez a törvény a kihirdetését követő napon lép hatályba.", (EnforcementDate(position=None, date=DaysAfterPublication()), )), ("Ez a törvény kihirdetését követő napon lép hatályba.", (EnforcementDate(position=None, date=DaysAfterPublication()), )), ("Ez a törvény – a (2) bekezdésben meghatározott kivétellel – a kihirdetését követő napon lép hatályba.", (EnforcementDate(position=None, date=DaysAfterPublication()), )), ("Ez a törvény – a (2)–(14) bekezdésben meghatározott kivétellel – a kihirdetését követő napon lép hatályba.", (EnforcementDate(position=None, date=DaysAfterPublication()), )), ("Ez a törvény a kihirdetését követő nyolcadik napon lép hatályba.", (EnforcementDate(position=None, date=DaysAfterPublication(8)), )), ("Ez a törvény a kihirdetését követő tizenötödik napon lép hatályba.", (EnforcementDate(position=None, date=DaysAfterPublication(15)), )), ("Ez a törvény a kihirdetését követő harmincadik napon lép hatályba.", (EnforcementDate(position=None, date=DaysAfterPublication(30)), )), ("Ez a törvény – a (2)–(8) bekezdésben foglalt kivétellel – a kihirdetést követő 8. napon lép hatályba.",
def test_date_add() -> None: assert Date(2000, 12, 31).add_days(1) == Date(2001, 1, 1) assert Date(2020, 2, 28).add_days(1) == Date(2020, 2, 29) assert Date(2021, 2, 28).add_days(1) == Date(2021, 3, 1) assert Date(2021, 8, 28).add_days(10) == Date(2021, 9, 7) assert Date(2011, 3, 28).add_days(45) == Date(2011, 5, 12) assert Date(2011, 7, 28).add_days(20) == Date(2011, 8, 17)
def convert_exact_date(cls, exact_date: model.Date) -> Date: assert isinstance(exact_date.year, str) assert isinstance(exact_date.month, str) assert isinstance(exact_date.day, str) return Date(int(exact_date.year), text_to_month_hun(exact_date.month), int(exact_date.day))
def test_end_to_end_2018_123() -> None: # This is the most modern Act we want to touch right now. # The purpose of the test is mainly document-format-compatibility acts = { a.identifier: a for a in parse_single_kozlony(2018, 123) if isinstance(a, Act) } assert len( acts) == 6, "Issue 2018/123 of Magyar Kozlony contains 6 separate Acts" subtitles_in_2018_L = [ s for s in acts["2018. évi L. törvény"].children if isinstance(s, Subtitle) ] assert len(subtitles_in_2018_L) == 22 assert subtitles_in_2018_L[18].identifier == '19' assert subtitles_in_2018_L[18].title == \ 'A kis összegű követelés értékhatára, a filmalkotásokhoz kapcsolódó gyártási értékhatár és ' \ 'a közbeszerzési értékhatárok', \ "Multiline subtitles parsed correctly" assert acts["2018. évi LII. törvény"].article("5").paragraph( "6" ).intro == "A Tbj. szerint külföldinek minősülő személy által megszerzett" assert acts["2018. évi LII. törvény"].article("5").paragraph("6").point( "b" ).text == "az Szja tv. szerint egyéb jövedelemnek minősülő jövedelmet" assert acts["2018. évi LII. törvény"].article("5").paragraph( "6").wrap_up == "nem terheli adófizetési kötelezettség." text = acts["2018. évi LII. törvény"].article("34").paragraph().point( "11").subpoint("p").text assert text is not None and text.endswith("járadék folyósításának időtartama;"), \ "Multiline points/subpoints do not generate a wrap-up, if the indentation is correct" assert acts["2018. évi LIII. törvény"].subject == "a magánélet védelméről" assert acts["2018. évi LIII. törvény"].preamble is not None assert acts["2018. évi LIII. törvény"].preamble.startswith( "A magánélet, a családi élet, az otthon") assert acts["2018. évi LIII. törvény"].preamble.endswith( "fokozott védelme, a következő törvényt alkotja:") block_amendment = acts["2018. évi LV. törvény"].article("25").paragraph( "5").block_amendment() assert block_amendment.children_type == AlphabeticPoint assert block_amendment.intro == "(3) A büntetés bűntett miatt három évig terjedő szabadságvesztés, ha a rendbontást" child = block_amendment.child("e") assert isinstance(child, AlphabeticPoint) assert child.text == \ "a gyűlés gyülekezési jogról szóló törvény szerinti békés jellegét biztosító korlátozásokat megsértve" assert block_amendment.wrap_up == "követik el." text = acts["2018. évi LIV. törvény"].article("2").paragraph().point( "4").text assert text is not None and text.endswith("felfedett üzleti titokra épül."), \ "Multiline numeric points parsed correctly" # International convention parsing assert acts["2018. évi LI. törvény"].article( "3").paragraph().children_type == QuotedBlock children = acts["2018. évi LI. törvény"].article("3").paragraph().children assert children is not None and len(children) == 2, \ "Multiple quote blocks parsed properly" last_line_of_hungarian_version = acts["2018. évi LI. törvény"].article( "3").paragraph().quoted_block(0).lines[-1].content assert last_line_of_hungarian_version.endswith("Szlovák Köztársaság nevében"), \ "Quote blocks are separated correctly" assert acts["2018. évi LI. törvény"].article("3").paragraph( ).wrap_up is None, "No junk is parsed after Quote blocks" assert acts["2018. évi LI. törvény"].publication_date == Date(2018, 7, 31)
def test_semantic_reparse_abbrevs() -> None: TEST_ACT = Act( identifier="2050. évi XD. törvény", publication_date=Date(2050, 3, 4), subject="A nyelvtani tesztelésről", preamble='', children=( Article( identifier="1", children=(Paragraph( text= "Fontos lesz később a tesztelés X tulajdonságiról szóló 2040. évi DX. törvény (a továbbiakban Xtv.) rövidítésének feloldása.", ), )), Article( identifier="2", children=( Paragraph( identifier="1", text= "Bekeverünk a tesztelés Y tulajdonságiról szóló 2041. évi X. törvény (a továbbiakban Ytv.) dolgaival", ), Paragraph( identifier="2", text= "Itt megemlítendő az Ytv. 10. §-a és a tesztelés Z tulajdonságiról szóló 2041. évi XXX. törvény (a továbbiakban Ztv.) 1. §-a közötti különbség", ), Paragraph( identifier="3", intro="Mert később használatban van", children=( AlphabeticPoint(identifier="a", text="az Xtv. 1. § c) pontja, és"), AlphabeticPoint(identifier="b", text="az Ytv. 2. §-a."), ), ), ), ), Article( identifier="3", children=(Paragraph( text= "Mégegyszer megemlítendő, hogy fontos az Xtv. 1. §-a, Ytv. 1. §-a, és Ztv. 1337. §-a.", ), )), Article( identifier="4", children=(Paragraph( intro= "Az Ytv. 12. § (8) bekezdése helyébe a következő rendelkezés lép:", children=(BlockAmendmentContainer(children=(Paragraph( identifier='8', text="Beillesztett referencia: 12. §, vajon lesz baj?" ), ), ), ), ), ), ), ), ) with_semantics_1 = ActSemanticsParser.add_semantics_to_act(TEST_ACT) assert with_semantics_1.is_semantic_parsed assert with_semantics_1.article('1').paragraph().act_id_abbreviations == ( ActIdAbbreviation('Xtv.', '2040. évi DX. törvény'), ) assert with_semantics_1.article('2').paragraph( '1').act_id_abbreviations == (ActIdAbbreviation( 'Ytv.', '2041. évi X. törvény'), ) assert with_semantics_1.article('2').paragraph( '2').act_id_abbreviations == (ActIdAbbreviation( 'Ztv.', '2041. évi XXX. törvény'), ) assert with_semantics_1.article('3').paragraph().outgoing_references == ( OutgoingReference(start_pos=40, end_pos=44, reference=Reference(act='2040. évi DX. törvény')), OutgoingReference(start_pos=45, end_pos=51, reference=Reference(act='2040. évi DX. törvény', article='1')), OutgoingReference(start_pos=53, end_pos=57, reference=Reference(act='2041. évi X. törvény')), OutgoingReference(start_pos=58, end_pos=64, reference=Reference(act='2041. évi X. törvény', article='1')), OutgoingReference(start_pos=69, end_pos=73, reference=Reference(act='2041. évi XXX. törvény')), OutgoingReference(start_pos=74, end_pos=83, reference=Reference(act='2041. évi XXX. törvény', article='1337')), ) with_semantics_2 = ActSemanticsParser.add_semantics_to_act( with_semantics_1) # TODO: with_semantics_2 is with_semantics_1 assert with_semantics_2 == with_semantics_1 modified_paragraph = attr.evolve( with_semantics_1.article("2").paragraph("1"), text= "Bekeverünk a tesztelés Y új tulajdonságiról szóló 2057. évi X. törvény (a továbbiakban Ytv.) dolgaival", semantic_data=None, outgoing_references=None, act_id_abbreviations=None, ) modified_article = attr.evolve( with_semantics_1.article("2"), children=(modified_paragraph, ) + with_semantics_1.article("2").children[1:], ) modified_act = attr.evolve( with_semantics_1, children=(with_semantics_1.children[0], modified_article, with_semantics_1.children[2], with_semantics_1.children[3]), ) assert not modified_act.is_semantic_parsed modified_with_semantics = ActSemanticsParser.add_semantics_to_act( modified_act) assert modified_with_semantics.article('2').paragraph( '1').act_id_abbreviations == (ActIdAbbreviation( 'Ytv.', '2057. évi X. törvény'), ) assert modified_with_semantics.article('3').paragraph( ).outgoing_references == ( OutgoingReference(start_pos=40, end_pos=44, reference=Reference(act='2040. évi DX. törvény')), OutgoingReference(start_pos=45, end_pos=51, reference=Reference(act='2040. évi DX. törvény', article='1')), OutgoingReference(start_pos=53, end_pos=57, reference=Reference(act='2057. évi X. törvény')), OutgoingReference(start_pos=58, end_pos=64, reference=Reference(act='2057. évi X. törvény', article='1')), OutgoingReference(start_pos=69, end_pos=73, reference=Reference(act='2041. évi XXX. törvény')), OutgoingReference(start_pos=74, end_pos=83, reference=Reference(act='2041. évi XXX. törvény', article='1337')), ) assert modified_with_semantics.article('4').paragraph().semantic_data == ( BlockAmendment(position=Reference(act='2057. évi X. törvény', article='12', paragraph='8'), ), ) assert with_semantics_1.article('1') is modified_with_semantics.article( '1') # Note that because of the abbreviation change, everything else may be reparsed, # so no asserts for e.g. article('3') # No need to reparse BlockAmendments though a4_children = with_semantics_1.article('4').paragraph().children modified_a4_children = modified_with_semantics.article( '4').paragraph().children assert a4_children is not None assert modified_a4_children is not None assert a4_children[0] is modified_a4_children[0]
def test_semantic_reparse_simple() -> None: TEST_ACT = Act( identifier="2050. évi XD. törvény", publication_date=Date(2050, 3, 4), subject="A nyelvtani tesztelésről", preamble='', children=( Article( identifier="1", children=(Paragraph( text= "Fontos lesz később a tesztelés X tulajdonságiról szóló 2040. évi DX. törvény (a továbbiakban Xtv.) rövidítésének feloldása.", ), )), Article( identifier="2", children=( Paragraph( identifier="1", text= "Bekeverünk a tesztelés Y tulajdonságiról szóló 2041. évi X. törvény dolgaival.", ), Paragraph( identifier="2", text= "Itt megemlítendő a 1. § és a tesztelés Z tulajdonságiról szóló 2041. évi XXX. törvény (a továbbiakban Ztv.) 1. §-a közötti különbség", ), Paragraph( identifier="3", intro="Az Xtv.", wrap_up="szöveg lép.", children=( AlphabeticPoint( identifier="a", text= "12. § (7) bekezdésében a „fontatlan” szövegrész helyébe a „nem fontos”,", ), AlphabeticPoint( identifier="b", text= "11. §-ben a „nemigazán” szövegrész helyébe a „nem”", ), ), ), ), ), Article( identifier="3", children=(Paragraph( text= "Ez a törvény a kihirdetését követő napon lép hatályba."), )), Article( identifier="4", children=(Paragraph( intro= "A Ztv. 12. § (8) bekezdése helyébe a következő rendelkezés lép:", children=(BlockAmendmentContainer(children=(Paragraph( identifier='8', text="Beillesztett referencia: 11. §, vajon lesz baj?" ), ), ), ), ), ), ), ), ) with_semantics_1 = ActSemanticsParser.add_semantics_to_act(TEST_ACT) assert with_semantics_1.is_semantic_parsed assert with_semantics_1.article('1').paragraph().act_id_abbreviations == ( ActIdAbbreviation('Xtv.', '2040. évi DX. törvény'), ) assert with_semantics_1.article('2').paragraph( '2').act_id_abbreviations == (ActIdAbbreviation( 'Ztv.', '2041. évi XXX. törvény'), ) assert with_semantics_1.article('1').paragraph().outgoing_references == ( OutgoingReference(start_pos=55, end_pos=76, reference=Reference(act='2040. évi DX. törvény')), ) assert with_semantics_1.article('2').paragraph( '1').outgoing_references == (OutgoingReference( start_pos=47, end_pos=67, reference=Reference(act='2041. évi X. törvény')), ) assert with_semantics_1.article('2').paragraph('3').point( 'a').semantic_data == (TextAmendment(position=Reference( act='2040. évi DX. törvény', article='12', paragraph='7'), original_text='fontatlan', replacement_text='nem fontos'), ) assert with_semantics_1.article('3').paragraph().semantic_data == ( EnforcementDate(position=None, date=DaysAfterPublication(days=1)), ) assert with_semantics_1.article('4').paragraph().semantic_data == ( BlockAmendment(position=Reference(act='2041. évi XXX. törvény', article='12', paragraph='8'), ), ) a4_children = with_semantics_1.article('4').paragraph().children assert a4_children is not None the_block_amendment = a4_children[0] assert isinstance(the_block_amendment, BlockAmendmentContainer) assert the_block_amendment.semantic_data is None assert the_block_amendment.outgoing_references is None assert the_block_amendment.act_id_abbreviations is None with_semantics_2 = ActSemanticsParser.add_semantics_to_act( with_semantics_1) assert with_semantics_2 is with_semantics_1 modified_paragraph = attr.evolve( with_semantics_1.article("2").paragraph("1"), text="Az 1. § és 3. § egészen fontos.", semantic_data=None, outgoing_references=None, act_id_abbreviations=None, ) modified_article = attr.evolve( with_semantics_1.article("2"), children=(modified_paragraph, ) + with_semantics_1.article("2").children[1:], ) modified_act = attr.evolve( with_semantics_1, children=(with_semantics_1.children[0], modified_article, with_semantics_1.children[2], with_semantics_1.children[3]), ) assert modified_act.article('1').is_semantic_parsed assert not modified_act.article('2').is_semantic_parsed assert modified_act.article('3').is_semantic_parsed assert modified_act.article('4').is_semantic_parsed assert not modified_act.is_semantic_parsed modified_with_semantics = ActSemanticsParser.add_semantics_to_act( modified_act) assert modified_with_semantics.is_semantic_parsed assert modified_with_semantics.article('2').paragraph( '1').outgoing_references == ( OutgoingReference(start_pos=3, end_pos=7, reference=Reference(act=None, article='1')), OutgoingReference(start_pos=11, end_pos=15, reference=Reference(act=None, article='3')), ) # Check if nothing else was touched but the modified part. assert with_semantics_1.article('1') is modified_with_semantics.article( '1') assert with_semantics_1.article('2').paragraph( '2') is modified_with_semantics.article('2').paragraph('2') assert with_semantics_1.article('2').paragraph( '3') is modified_with_semantics.article('2').paragraph('3') assert with_semantics_1.article('3') is modified_with_semantics.article( '3') assert with_semantics_1.article('4') is modified_with_semantics.article( '4')