metering 0.23.0

German energy metering domain library — DST-correct Europe/Berlin calendar arithmetic on both the Liefertag and the 06:00 Gastag, gas m3→kWh_Hs conversion, SigLinDe gas SLP, billing-period aggregation with Benutzungsstundenzahl and Blindmehrarbeit, Ersatzwertbildung in the market's own code list, a robust validation engine, para 14a netzorientierte Steuerung and Modul 3 registers, conservation-checked allocation for para 42b/42c, charging sessions onto the settlement grid, check-digit-validated MaLo-IDs and EICs, and SLP/RLM/iMSys classification. Zero I/O, no async, no clock, exact decimal quantities.
Documentation
+
�/�j��(�Rt^RIHt^RIt^RIt^RIt^RIHt]!]4P4PPtRR/t]P!R]P4tRRltR	R
ltRRltR
Rlt]R8Xd]!]!44hR#)uCheck every passage the crate presents as verbatim source text against the PDFs.

Reads `src/**/*.rs`, `site/content/docs/*.md` and `README.md`, pulls out every
`*"…"*` passage, and searches a corpus built with `pdftotext -layout` over
`specs/` (plus any extra directories given on the command line).

A quote is verified when every fragment of it — the passage split on `…`, since
the crate elides — appears in the corpus after normalisation. Normalisation
strips the things a PDF-to-text pass and a doc comment disagree about: markdown
emphasis, escaped brackets, soft hyphens, line-break hyphenation, typographic
quotes and dashes, and non-breaking spaces.

Exit code is 1 when a quote that is expected to verify does not.

    python3 scripts/verify_quotes.py [extra-pdf-dir ...]
)�annotationsN)�Pathz4a b c d e werden im deutschen energiemarkt verwendetuna label inside a figure — pdftotext cannot see it; the neighbouring § 2.3 Wertegruppe F passage does verifyz[*_]{1,2}"(.+?)"[*_]{1,2}c� �V^8�dQhRRRR/#)��text�str�return�)�formats"�A/Users/hupe/Workspaces/hupe1980/metering/scripts/verify_quotes.py�__annotate__r+s��5�5�C�5�C�5�c���VPRR4pVPRR4p\P!RRV4p\P!RRV4pVPRR4PRR4PR	R4pVPR
R4PRR4pVPR
R4PRR4PRR4p\P!RRV4pVPRR4PRR4p\P!RRV\PR7p\P!RRV4P	4P4#)�­�� � z	-\s*\n\s*u$(?<=[a-zäöüß])-(?=[a-zäöüß])u„�"u“u”u’�'u‘u–�-u—u−z[*_`]z\[�[z\]�]z^\s*(///|//!|//)\s?)�flagsz\s+)�replace�re�sub�M�strip�lower)rs&r�	normaliser+s)���<�<��b�!�D��<�<��c�"�D�
�6�6�,��D�)�D�
�6�6�9�2�t�D�D��<�<��s�#�+�+�E�3�7�?�?��s�K�D��<�<��s�#�+�+�E�3�7�D��<�<��s�#�+�+�E�3�7�?�?��s�K�D�
�6�6�(�B��%�D��<�<��s�#�+�+�E�3�7�D�
�6�6�(�"�d�"�$�$�?�D��6�6�&�#�t�$�*�*�,�2�2�4�4r
c� �V^8�dQhRRRR/#)r�dirs�
list[Path]rrr	)r
s"rrr?s��'�'��'��'r
c	��.pVFfp\VPR44FEp\P!RR\	V4R.RRRR7pVPVP4KG	Kh	\RPV44#)z*.pdf�	pdftotextz-layoutrTF)�capture_outputr�check�
)	�sorted�rglob�
subprocess�runr�append�stdoutr�join)r!�parts�	directory�pdf�outs&    r�corpusr3?sx���E��	��)�/�/�'�2�3�C��.�.��i��S��3�7�#���	�C�
�L�L����$�4���T�Y�Y�u�%�&�&r
c��V^8�dQhRR/#)rrr"r	)r
s"rrrMs��,�,��,r
c�T�\\R,PR44pV\\R,R,R,PR44,
pVP	\R,4VUu.uFqP4'gKVNK	up#uupi)�srcz*.rs�site�content�docsz*.mdz	README.md)r(�ROOTr)�globr,�exists)�files�fs  r�sourcesr?Mst���D�5�L�'�'��/�0�E�	�V�T�F�]�Y�.��7�=�=�f�E�
F�F�E�	�L�L���#�$��+�u�!���
�A�A�u�+�+��+s�B%�B%c��V^8�dQhRR/#)rr�intr	)r
s"rrrTs��1 �1 �c�1 r
c�Taa�\R,.\PR,Uu.uFp\V4P	4NK	up,pVUu.uFq"P4'gKVNK	ppV'g\
R\PR7^#\V4oS'g\
R\PR7^#^;p;rE.p\4EF�pVPRR7p\PV4EF�p	\V	4o\P!RS4'gK.\!SP#R44^8dKOV^,
p\$;QJd#V3R	l\&4F'gKR
M	RM!V3R	l\&44'dV^,
pK�SP#R4U
u.uF3p
\!V
P)44^8�gK#V
P)4NK5	pp
V'dM\*;QJdV3R
lV4F'dKRM	R
M!V3R
lV44'd
V^,
pEKM\-V3RlV4S4pVP/\1VP3\44V34EK�	EK�	\
VRVRVR\!V4R24VFwr}\
RVRV
R,24K	V'd\
R\PR7V'd^#^#uupiuupiuup
i)�specs:�NNu1no PDF directory found — run `just specs` first)�fileu(empty corpus — is pdftotext installed?zutf-8)�encodingu:[äöüßÄÖÜ]|\b(der|die|das|und|nicht|wird|sind|von)\brc3�,<"�TF	qS9x�K	R#5i�Nr	)�.0�marker�quotes& �r�	<genexpr>�main.<locals>.<genexpr>ps����>��v�U�?����TFu…c3�,<"�TF	qS9x�K	R#5irHr	�rIr>�haystacks& �rrLrMts���� B�	�1�h��	�rNc3�8<"�TFqS9gKVx�K	R#5irHr	rPs& �rrLrMws����J�9�a��8I���9�s��
z German passages: z verified, z known-unverifiable, z
 unmatchedz  z
    :N�Nu�
An unmatched passage is a misquote until proven otherwise. Either the wording is wrong, or the source is not in the corpus — add its directory as an argument, or record it in UNVERIFIABLE with the reason.)r:�sys�argvr�
expanduser�is_dir�print�stderrr3r?�	read_text�QUOTE�findallrr�search�len�split�any�UNVERIFIABLEr�all�nextr,r�relative_to)�ar!�d�checked�verified�skipped�failures�pathr�rawr>�	fragments�missing�fragmentrQrKs              @@r�mainrpTs_����7�N��S�X�X�b�\�J�\��t�A�w�1�1�3�\�J�J�D��*�t�!�x�x�z�A�A�t�D�*��
�A��
�
�S���d�|�H��
�8�s�z�z�J��#$�$�G�$�h�&(�H��	���~�~�w�~�/���=�=��&�C��c�N�E��9�9�Z�\a�b�b���5�;�;�s�#�$�q�(���q�L�G��s�>��>�s�s�s�>��>�>�>��1����,1�K�K��,>�V�,>�q�#�a�g�g�i�.�SU�BU������,>�I�V��S�S� B�	� B�S�S�S� B�	� B�B�B��A�
���J�9�J�E�R������T�%5�%5�d�%;�!<�g� F�G�''��.
�W�I�'��z��W�I�EZ�
��]�O�:�'�(�"���
��4�&��x��~�.�/�0�#��
�
L����		
��1��a���aK��*��:Ws�"L�L �4L � L%�0L%�__main__)�__doc__�
__future__rrr*rT�pathlibr�__file__�resolve�parentr:ra�compile�Sr[rr3r?rp�__name__�
SystemExitr	r
r�<module>r|s����"#�	��
���H�~����&�&�-�-��;�	3���	�
�
�/����6��5�('�,�1 �h�z��
�T�V�
��r