We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
KeyError when using Medline.parse
### Setup

I am reporting a problem with Biopython version, Python version, and operating
system as follows:

3.10.6 (main, Oct  7 2022, 20:19:58) [GCC 11.2.0]
CPython
Linux-4.14.330-250.540.amzn2.x86_64-x86_64-with-glibc2.31
1.82

### Expected behaviour

This should work and parse records as expected:
`records = Medline.parse(lines)`

### Actual behaviour
```
File /opt/conda/lib/python3.10/site-packages/Bio/Medline/__init__.py:175, in parse(handle)
    173         record[key][-1] += line[5:]  # including space using line[5:]
    174     else:
--> 175         record[key].append(line[6:])
    176 elif line:
    177     key = line[:4].rstrip()

KeyError: 'AB'
```

### Steps to reproduce

Offending record:
```
PMID- 29939664
STAT- Publisher
CTDT- 20220621
PB  - StatPearls Publishing
DP  - 2023 Jan
TI  - Morvan Syndrome.
BTI - StatPearls
AB  - Morvan syndrome or Morvan's fibrillary chorea (MFC) is a rare constellation of 
      neurological symptoms, consisting of peripheral nerve hyperexcitability, 
      autonomic instability, and encephalopathy often associated with autoantibodies to 
      voltage-gated potassium channel complexes (VGKCs). On 12 April 1890, the French 
      physician, Dr. Augustine Marie Morvan first published a novel description of this 
      neurological syndrome in La Gazette Hebdomadaire de Medecine et de Chirurgie.  He 
      called it "la choree fibrillaire," which we now know as Morvan syndrome. There 
      have been approximately 60 cases published in the French and other literature but 
      only a few in English literature since then. See table 1 in media section at the 
      end of this script for a review and comparison of the varied clinical features 
      and clinical outcomes in 20 such cases reported in English literature.            
                                                                                        
                                            As per table 1, Morvan syndrome is 
      predominantly a male-dominant entity with a male to female ratio of 19 to 1. The 
      only female case was a rheumatoid arthritis patient on gold therapy who developed 
      mild Morvan syndrome features, and whose condition reverted once treatment was 
      discontinued. Insomnia, hyperhidrosis, dysautonomia, and myokymia were consistent 
      findings noted in 100% (all 20) of the patients. Whereas, hallucinations were 
      seen in 75% (15) of the patients and anti-voltage-gated potassium channel 
      antibodies (VGKC) were observed in 45% (9) of the patients. Another very 
      consistent finding was the conspicuous absence of seizures in 100% (all 20) of 
      the cases and benign findings on MRI in 100% (all 20) in contrast to Limbic 
      encephalitis where seizures and temporal lobe structural abnormalities on MRI are 
      classic findings. Myokymia was seen in 100% (all 20) of the patients, and it was 
      confirmed in most 80%(16) cases with EMG studies which showed spontaneous, either 
      repetitive or continuous muscle activity in the form of fasciculations which were 
      a combination doublet, triplet, multiplet, or neuromyotonic discharges. Other 
      sporadic findings were elevated manganese levels in 5% (1), oligoclonal bands in 
      cerebrospinal fluid (CSF) in 15% (3), thymoma in 40% (8), Acetylcholine receptor 
      (AchR) antibodies in 30% (6) of patients. However, AchR antibodies in association 
      with myasthenic features were seen in only 10% (2) of the patients. Twenty 
      percent (4) of the patients had AchR antibodies without myasthenic features. 
      Treatment modalities tried with varied effectiveness were thymectomy in 25% (5), 
      anticonvulsant therapy in 45% (9), immunosuppression in 50% (10), and IVIG in 20% 
      (4) of the patients. The most effective treatment was plasma exchange which was 
      tried in 55% (11) of the patients, all of whom except one patient showed dramatic 
      improvement. Treatment effectiveness was even more significant when 
      immunosuppression and plasma exchange was tried together. Death was the outcome 
      in only 20% (4) of the patients.
CI  - Copyright (c) 2023, StatPearls Publishing LLC.
FAU - Masood, Wajeed
AU  - Masood W
AD  - Methodist University, Campbell University School of Osteopathic Medicine.
FAU - Sitammagari, Kranthi K
AU  - Sitammagari KK
AD  - Methodist Un, Campbell Un School of OM
LA  - eng
PT  - Study Guide
PT  - Book Chapter
PL  - Treasure Island (FL)
COIS- Disclosure: Wajeed Masood declares no relevant financial relationships with 
      ineligible companies. Disclosure: Kranthi Sitammagari declares no relevant 
      financial relationships with ineligible companies.
EDAT- 2022/06/21 00:00
CRDT- 2022/06/21 00:00
AID - NBK507887 [bookaccession]
```

I believe it might be failing due to the extra blank line in the abstract.

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `Bio/Medline/__init__.py`
Content:
```
1 # Copyright 1999 by Jeffrey Chang.  All rights reserved.
2 #
3 # This file is part of the Biopython distribution and governed by your
4 # choice of the "Biopython License Agreement" or the "BSD 3-Clause License".
5 # Please see the LICENSE file that should have been included as part of this
6 # package.
7 
8 """Code to work with Medline from the NCBI.
9 
10 Classes:
11  - Record           A dictionary holding Medline data.
12 
13 Functions:
14  - read             Reads one Medline record
15  - parse            Allows you to iterate over a bunch of Medline records
16 
17 """
18 
19 
20 class Record(dict):
21     """A dictionary holding information from a Medline record.
22 
23     All data are stored under the mnemonic appearing in the Medline
24     file. These mnemonics have the following interpretations:
25 
26     ========= ==============================
27     Mnemonic  Description
28     --------- ------------------------------
29     AB        Abstract
30     CI        Copyright Information
31     AD        Affiliation
32     IRAD      Investigator Affiliation
33     AID       Article Identifier
34     AU        Author
35     FAU       Full Author
36     CN        Corporate Author
37     DCOM      Date Completed
38     DA        Date Created
39     LR        Date Last Revised
40     DEP       Date of Electronic Publication
41     DP        Date of Publication
42     EDAT      Entrez Date
43     GS        Gene Symbol
44     GN        General Note
45     GR        Grant Number
46     IR        Investigator Name
47     FIR       Full Investigator Name
48     IS        ISSN
49     IP        Issue
50     TA        Journal Title Abbreviation
51     JT        Journal Title
52     LA        Language
53     LID       Location Identifier
54     MID       Manuscript Identifier
55     MHDA      MeSH Date
56     MH        MeSH Terms
57     JID       NLM Unique ID
58     RF        Number of References
59     OAB       Other Abstract
60     OCI       Other Copyright Information
61     OID       Other ID
62     OT        Other Term
63     OTO       Other Term Owner
64     OWN       Owner
65     PG        Pagination
66     PS        Personal Name as Subject
67     FPS       Full Personal Name as Subject
68     PL        Place of Publication
69     PHST      Publication History Status
70     PST       Publication Status
71     PT        Publication Type
72     PUBM      Publishing Model
73     PMC       PubMed Central Identifier
74     PMID      PubMed Unique Identifier
75     RN        Registry Number/EC Number
76     NM        Substance Name
77     SI        Secondary Source ID
78     SO        Source
79     SFM       Space Flight Mission
80     STAT      Status
81     SB        Subset
82     TI        Title
83     TT        Transliterated Title
84     VI        Volume
85     CON       Comment on
86     CIN       Comment in
87     EIN       Erratum in
88     EFR       Erratum for
89     CRI       Corrected and Republished in
90     CRF       Corrected and Republished from
91     PRIN      Partial retraction in
92     PROF      Partial retraction of
93     RPI       Republished in
94     RPF       Republished from
95     RIN       Retraction in
96     ROF       Retraction of
97     UIN       Update in
98     UOF       Update of
99     SPIN      Summary for patients in
100     ORI       Original report in
101     ========= ==============================
102 
103     """
104 
105 
106 def parse(handle):
107     """Read Medline records one by one from the handle.
108 
109     The handle is either is a Medline file, a file-like object, or a list
110     of lines describing one or more Medline records.
111 
112     Typical usage::
113 
114         >>> from Bio import Medline
115         >>> with open("Medline/pubmed_result2.txt") as handle:
116         ...     records = Medline.parse(handle)
117         ...     for record in records:
118         ...         print(record['TI'])
119         ...
120         A high level interface to SCOP and ASTRAL ...
121         GenomeDiagram: a python package for the visualization of ...
122         Open source clustering software.
123         PDB file parser and structure class implemented in Python.
124 
125     """
126     # These keys point to string values
127     textkeys = (
128         "ID",
129         "PMID",
130         "SO",
131         "RF",
132         "NI",
133         "JC",
134         "TA",
135         "IS",
136         "CY",
137         "TT",
138         "CA",
139         "IP",
140         "VI",
141         "DP",
142         "YR",
143         "PG",
144         "LID",
145         "DA",
146         "LR",
147         "OWN",
148         "STAT",
149         "DCOM",
150         "PUBM",
151         "DEP",
152         "PL",
153         "JID",
154         "SB",
155         "PMC",
156         "EDAT",
157         "MHDA",
158         "PST",
159         "AB",
160         "EA",
161         "TI",
162         "JT",
163     )
164     handle = iter(handle)
165 
166     key = ""
167     record = Record()
168     for line in handle:
169         line = line.rstrip()
170         if line[:6] == "      ":  # continuation line
171             if key in ["MH", "AD"]:
172                 # Multi-line MESH term, want to append to last entry in list
173                 record[key][-1] += line[5:]  # including space using line[5:]
174             else:
175                 record[key].append(line[6:])
176         elif line:
177             key = line[:4].rstrip()
178             if key not in record:
179                 record[key] = []
180             record[key].append(line[6:])
181         elif record:
182             # Join each list of strings into one string.
183             for key in record:
184                 if key in textkeys:
185                     record[key] = " ".join(record[key])
186             yield record
187             record = Record()
188     if record:  # catch last one
189         for key in record:
190             if key in textkeys:
191                 record[key] = " ".join(record[key])
192         yield record
193 
194 
195 def read(handle):
196     """Read a single Medline record from the handle.
197 
198     The handle is either is a Medline file, a file-like object, or a list
199     of lines describing a Medline record.
200 
201     Typical usage:
202 
203         >>> from Bio import Medline
204         >>> with open("Medline/pubmed_result1.txt") as handle:
205         ...     record = Medline.read(handle)
206         ...     print(record['TI'])
207         ...
208         The Bio* toolkits--a brief overview.
209 
210     """
211     records = parse(handle)
212     return next(records)
213 
214 
215 if __name__ == "__main__":
216     from Bio._utils import run_doctest
217 
218     run_doctest()
219
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/Bio/Medline/__init__.py b/Bio/Medline/__init__.py
--- a/Bio/Medline/__init__.py
+++ b/Bio/Medline/__init__.py
@@ -166,19 +166,26 @@
     key = ""
     record = Record()
     for line in handle:
-        line = line.rstrip()
         if line[:6] == "      ":  # continuation line
+            line = line.rstrip()
+            if line == "":
+                # All blank continuation lines should be considered a new line.
+                # See issue #4557
+                line = "      \n"
+
             if key in ["MH", "AD"]:
                 # Multi-line MESH term, want to append to last entry in list
                 record[key][-1] += line[5:]  # including space using line[5:]
             else:
                 record[key].append(line[6:])
-        elif line:
+        elif line != "\n" and line != "\r\n":
+            line = line.rstrip()
             key = line[:4].rstrip()
             if key not in record:
                 record[key] = []
             record[key].append(line[6:])
         elif record:
+            # End of the record
             # Join each list of strings into one string.
             for key in record:
                 if key in textkeys:

{"golden_diff": "diff --git a/Bio/Medline/__init__.py b/Bio/Medline/__init__.py\n--- a/Bio/Medline/__init__.py\n+++ b/Bio/Medline/__init__.py\n@@ -166,19 +166,26 @@\n     key = \"\"\n     record = Record()\n     for line in handle:\n-        line = line.rstrip()\n         if line[:6] == \"      \":  # continuation line\n+            line = line.rstrip()\n+            if line == \"\":\n+                # All blank continuation lines should be considered a new line.\n+                # See issue #4557\n+                line = \"      \\n\"\n+\n             if key in [\"MH\", \"AD\"]:\n                 # Multi-line MESH term, want to append to last entry in list\n                 record[key][-1] += line[5:]  # including space using line[5:]\n             else:\n                 record[key].append(line[6:])\n-        elif line:\n+        elif line != \"\\n\" and line != \"\\r\\n\":\n+            line = line.rstrip()\n             key = line[:4].rstrip()\n             if key not in record:\n                 record[key] = []\n             record[key].append(line[6:])\n         elif record:\n+            # End of the record\n             # Join each list of strings into one string.\n             for key in record:\n                 if key in textkeys:\n", "issue": "KeyError when using Medline.parse\n### Setup\r\n\r\nI am reporting a problem with Biopython version, Python version, and operating\r\nsystem as follows:\r\n\r\n3.10.6 (main, Oct  7 2022, 20:19:58) [GCC 11.2.0]\r\nCPython\r\nLinux-4.14.330-250.540.amzn2.x86_64-x86_64-with-glibc2.31\r\n1.82\r\n\r\n### Expected behaviour\r\n\r\nThis should work and parse records as expected:\r\n`records = Medline.parse(lines)`\r\n\r\n### Actual behaviour\r\n```\r\nFile /opt/conda/lib/python3.10/site-packages/Bio/Medline/__init__.py:175, in parse(handle)\r\n    173         record[key][-1] += line[5:]  # including space using line[5:]\r\n    174     else:\r\n--> 175         record[key].append(line[6:])\r\n    176 elif line:\r\n    177     key = line[:4].rstrip()\r\n\r\nKeyError: 'AB'\r\n```\r\n\r\n### Steps to reproduce\r\n\r\nOffending record:\r\n```\r\nPMID- 29939664\r\nSTAT- Publisher\r\nCTDT- 20220621\r\nPB  - StatPearls Publishing\r\nDP  - 2023 Jan\r\nTI  - Morvan Syndrome.\r\nBTI - StatPearls\r\nAB  - Morvan syndrome or Morvan's fibrillary chorea (MFC) is a rare constellation of \r\n      neurological symptoms, consisting of peripheral nerve hyperexcitability, \r\n      autonomic instability, and encephalopathy often associated with autoantibodies to \r\n      voltage-gated potassium channel complexes (VGKCs). On 12 April 1890, the French \r\n      physician, Dr. Augustine Marie Morvan first published a novel description of this \r\n      neurological syndrome in La Gazette Hebdomadaire de Medecine et de Chirurgie.  He \r\n      called it \"la choree fibrillaire,\" which we now know as Morvan syndrome. There \r\n      have been approximately 60 cases published in the French and other literature but \r\n      only a few in English literature since then. See table 1 in media section at the \r\n      end of this script for a review and comparison of the varied clinical features \r\n      and clinical outcomes in 20 such cases reported in English literature.            \r\n                                                                                        \r\n                                            As per table 1, Morvan syndrome is \r\n      predominantly a male-dominant entity with a male to female ratio of 19 to 1. The \r\n      only female case was a rheumatoid arthritis patient on gold therapy who developed \r\n      mild Morvan syndrome features, and whose condition reverted once treatment was \r\n      discontinued. Insomnia, hyperhidrosis, dysautonomia, and myokymia were consistent \r\n      findings noted in 100% (all 20) of the patients. Whereas, hallucinations were \r\n      seen in 75% (15) of the patients and anti-voltage-gated potassium channel \r\n      antibodies (VGKC) were observed in 45% (9) of the patients. Another very \r\n      consistent finding was the conspicuous absence of seizures in 100% (all 20) of \r\n      the cases and benign findings on MRI in 100% (all 20) in contrast to Limbic \r\n      encephalitis where seizures and temporal lobe structural abnormalities on MRI are \r\n      classic findings. Myokymia was seen in 100% (all 20) of the patients, and it was \r\n      confirmed in most 80%(16) cases with EMG studies which showed spontaneous, either \r\n      repetitive or continuous muscle activity in the form of fasciculations which were \r\n      a combination doublet, triplet, multiplet, or neuromyotonic discharges. Other \r\n      sporadic findings were elevated manganese levels in 5% (1), oligoclonal bands in \r\n      cerebrospinal fluid (CSF) in 15% (3), thymoma in 40% (8), Acetylcholine receptor \r\n      (AchR) antibodies in 30% (6) of patients. However, AchR antibodies in association \r\n      with myasthenic features were seen in only 10% (2) of the patients. Twenty \r\n      percent (4) of the patients had AchR antibodies without myasthenic features. \r\n      Treatment modalities tried with varied effectiveness were thymectomy in 25% (5), \r\n      anticonvulsant therapy in 45% (9), immunosuppression in 50% (10), and IVIG in 20% \r\n      (4) of the patients. The most effective treatment was plasma exchange which was \r\n      tried in 55% (11) of the patients, all of whom except one patient showed dramatic \r\n      improvement. Treatment effectiveness was even more significant when \r\n      immunosuppression and plasma exchange was tried together. Death was the outcome \r\n      in only 20% (4) of the patients.\r\nCI  - Copyright (c) 2023, StatPearls Publishing LLC.\r\nFAU - Masood, Wajeed\r\nAU  - Masood W\r\nAD  - Methodist University, Campbell University School of Osteopathic Medicine.\r\nFAU - Sitammagari, Kranthi K\r\nAU  - Sitammagari KK\r\nAD  - Methodist Un, Campbell Un School of OM\r\nLA  - eng\r\nPT  - Study Guide\r\nPT  - Book Chapter\r\nPL  - Treasure Island (FL)\r\nCOIS- Disclosure: Wajeed Masood declares no relevant financial relationships with \r\n      ineligible companies. Disclosure: Kranthi Sitammagari declares no relevant \r\n      financial relationships with ineligible companies.\r\nEDAT- 2022/06/21 00:00\r\nCRDT- 2022/06/21 00:00\r\nAID - NBK507887 [bookaccession]\r\n```\r\n\r\nI believe it might be failing due to the extra blank line in the abstract.\n", "before_files": [{"content": "# Copyright 1999 by Jeffrey Chang.  All rights reserved.\n#\n# This file is part of the Biopython distribution and governed by your\n# choice of the \"Biopython License Agreement\" or the \"BSD 3-Clause License\".\n# Please see the LICENSE file that should have been included as part of this\n# package.\n\n\"\"\"Code to work with Medline from the NCBI.\n\nClasses:\n - Record           A dictionary holding Medline data.\n\nFunctions:\n - read             Reads one Medline record\n - parse            Allows you to iterate over a bunch of Medline records\n\n\"\"\"\n\n\nclass Record(dict):\n    \"\"\"A dictionary holding information from a Medline record.\n\n    All data are stored under the mnemonic appearing in the Medline\n    file. These mnemonics have the following interpretations:\n\n    ========= ==============================\n    Mnemonic  Description\n    --------- ------------------------------\n    AB        Abstract\n    CI        Copyright Information\n    AD        Affiliation\n    IRAD      Investigator Affiliation\n    AID       Article Identifier\n    AU        Author\n    FAU       Full Author\n    CN        Corporate Author\n    DCOM      Date Completed\n    DA        Date Created\n    LR        Date Last Revised\n    DEP       Date of Electronic Publication\n    DP        Date of Publication\n    EDAT      Entrez Date\n    GS        Gene Symbol\n    GN        General Note\n    GR        Grant Number\n    IR        Investigator Name\n    FIR       Full Investigator Name\n    IS        ISSN\n    IP        Issue\n    TA        Journal Title Abbreviation\n    JT        Journal Title\n    LA        Language\n    LID       Location Identifier\n    MID       Manuscript Identifier\n    MHDA      MeSH Date\n    MH        MeSH Terms\n    JID       NLM Unique ID\n    RF        Number of References\n    OAB       Other Abstract\n    OCI       Other Copyright Information\n    OID       Other ID\n    OT        Other Term\n    OTO       Other Term Owner\n    OWN       Owner\n    PG        Pagination\n    PS        Personal Name as Subject\n    FPS       Full Personal Name as Subject\n    PL        Place of Publication\n    PHST      Publication History Status\n    PST       Publication Status\n    PT        Publication Type\n    PUBM      Publishing Model\n    PMC       PubMed Central Identifier\n    PMID      PubMed Unique Identifier\n    RN        Registry Number/EC Number\n    NM        Substance Name\n    SI        Secondary Source ID\n    SO        Source\n    SFM       Space Flight Mission\n    STAT      Status\n    SB        Subset\n    TI        Title\n    TT        Transliterated Title\n    VI        Volume\n    CON       Comment on\n    CIN       Comment in\n    EIN       Erratum in\n    EFR       Erratum for\n    CRI       Corrected and Republished in\n    CRF       Corrected and Republished from\n    PRIN      Partial retraction in\n    PROF      Partial retraction of\n    RPI       Republished in\n    RPF       Republished from\n    RIN       Retraction in\n    ROF       Retraction of\n    UIN       Update in\n    UOF       Update of\n    SPIN      Summary for patients in\n    ORI       Original report in\n    ========= ==============================\n\n    \"\"\"\n\n\ndef parse(handle):\n    \"\"\"Read Medline records one by one from the handle.\n\n    The handle is either is a Medline file, a file-like object, or a list\n    of lines describing one or more Medline records.\n\n    Typical usage::\n\n        >>> from Bio import Medline\n        >>> with open(\"Medline/pubmed_result2.txt\") as handle:\n        ...     records = Medline.parse(handle)\n        ...     for record in records:\n        ...         print(record['TI'])\n        ...\n        A high level interface to SCOP and ASTRAL ...\n        GenomeDiagram: a python package for the visualization of ...\n        Open source clustering software.\n        PDB file parser and structure class implemented in Python.\n\n    \"\"\"\n    # These keys point to string values\n    textkeys = (\n        \"ID\",\n        \"PMID\",\n        \"SO\",\n        \"RF\",\n        \"NI\",\n        \"JC\",\n        \"TA\",\n        \"IS\",\n        \"CY\",\n        \"TT\",\n        \"CA\",\n        \"IP\",\n        \"VI\",\n        \"DP\",\n        \"YR\",\n        \"PG\",\n        \"LID\",\n        \"DA\",\n        \"LR\",\n        \"OWN\",\n        \"STAT\",\n        \"DCOM\",\n        \"PUBM\",\n        \"DEP\",\n        \"PL\",\n        \"JID\",\n        \"SB\",\n        \"PMC\",\n        \"EDAT\",\n        \"MHDA\",\n        \"PST\",\n        \"AB\",\n        \"EA\",\n        \"TI\",\n        \"JT\",\n    )\n    handle = iter(handle)\n\n    key = \"\"\n    record = Record()\n    for line in handle:\n        line = line.rstrip()\n        if line[:6] == \"      \":  # continuation line\n            if key in [\"MH\", \"AD\"]:\n                # Multi-line MESH term, want to append to last entry in list\n                record[key][-1] += line[5:]  # including space using line[5:]\n            else:\n                record[key].append(line[6:])\n        elif line:\n            key = line[:4].rstrip()\n            if key not in record:\n                record[key] = []\n            record[key].append(line[6:])\n        elif record:\n            # Join each list of strings into one string.\n            for key in record:\n                if key in textkeys:\n                    record[key] = \" \".join(record[key])\n            yield record\n            record = Record()\n    if record:  # catch last one\n        for key in record:\n            if key in textkeys:\n                record[key] = \" \".join(record[key])\n        yield record\n\n\ndef read(handle):\n    \"\"\"Read a single Medline record from the handle.\n\n    The handle is either is a Medline file, a file-like object, or a list\n    of lines describing a Medline record.\n\n    Typical usage:\n\n        >>> from Bio import Medline\n        >>> with open(\"Medline/pubmed_result1.txt\") as handle:\n        ...     record = Medline.read(handle)\n        ...     print(record['TI'])\n        ...\n        The Bio* toolkits--a brief overview.\n\n    \"\"\"\n    records = parse(handle)\n    return next(records)\n\n\nif __name__ == \"__main__\":\n    from Bio._utils import run_doctest\n\n    run_doctest()\n", "path": "Bio/Medline/__init__.py"}], "after_files": [{"content": "# Copyright 1999 by Jeffrey Chang.  All rights reserved.\n#\n# This file is part of the Biopython distribution and governed by your\n# choice of the \"Biopython License Agreement\" or the \"BSD 3-Clause License\".\n# Please see the LICENSE file that should have been included as part of this\n# package.\n\n\"\"\"Code to work with Medline from the NCBI.\n\nClasses:\n - Record           A dictionary holding Medline data.\n\nFunctions:\n - read             Reads one Medline record\n - parse            Allows you to iterate over a bunch of Medline records\n\n\"\"\"\n\n\nclass Record(dict):\n    \"\"\"A dictionary holding information from a Medline record.\n\n    All data are stored under the mnemonic appearing in the Medline\n    file. These mnemonics have the following interpretations:\n\n    ========= ==============================\n    Mnemonic  Description\n    --------- ------------------------------\n    AB        Abstract\n    CI        Copyright Information\n    AD        Affiliation\n    IRAD      Investigator Affiliation\n    AID       Article Identifier\n    AU        Author\n    FAU       Full Author\n    CN        Corporate Author\n    DCOM      Date Completed\n    DA        Date Created\n    LR        Date Last Revised\n    DEP       Date of Electronic Publication\n    DP        Date of Publication\n    EDAT      Entrez Date\n    GS        Gene Symbol\n    GN        General Note\n    GR        Grant Number\n    IR        Investigator Name\n    FIR       Full Investigator Name\n    IS        ISSN\n    IP        Issue\n    TA        Journal Title Abbreviation\n    JT        Journal Title\n    LA        Language\n    LID       Location Identifier\n    MID       Manuscript Identifier\n    MHDA      MeSH Date\n    MH        MeSH Terms\n    JID       NLM Unique ID\n    RF        Number of References\n    OAB       Other Abstract\n    OCI       Other Copyright Information\n    OID       Other ID\n    OT        Other Term\n    OTO       Other Term Owner\n    OWN       Owner\n    PG        Pagination\n    PS        Personal Name as Subject\n    FPS       Full Personal Name as Subject\n    PL        Place of Publication\n    PHST      Publication History Status\n    PST       Publication Status\n    PT        Publication Type\n    PUBM      Publishing Model\n    PMC       PubMed Central Identifier\n    PMID      PubMed Unique Identifier\n    RN        Registry Number/EC Number\n    NM        Substance Name\n    SI        Secondary Source ID\n    SO        Source\n    SFM       Space Flight Mission\n    STAT      Status\n    SB        Subset\n    TI        Title\n    TT        Transliterated Title\n    VI        Volume\n    CON       Comment on\n    CIN       Comment in\n    EIN       Erratum in\n    EFR       Erratum for\n    CRI       Corrected and Republished in\n    CRF       Corrected and Republished from\n    PRIN      Partial retraction in\n    PROF      Partial retraction of\n    RPI       Republished in\n    RPF       Republished from\n    RIN       Retraction in\n    ROF       Retraction of\n    UIN       Update in\n    UOF       Update of\n    SPIN      Summary for patients in\n    ORI       Original report in\n    ========= ==============================\n\n    \"\"\"\n\n\ndef parse(handle):\n    \"\"\"Read Medline records one by one from the handle.\n\n    The handle is either is a Medline file, a file-like object, or a list\n    of lines describing one or more Medline records.\n\n    Typical usage::\n\n        >>> from Bio import Medline\n        >>> with open(\"Medline/pubmed_result2.txt\") as handle:\n        ...     records = Medline.parse(handle)\n        ...     for record in records:\n        ...         print(record['TI'])\n        ...\n        A high level interface to SCOP and ASTRAL ...\n        GenomeDiagram: a python package for the visualization of ...\n        Open source clustering software.\n        PDB file parser and structure class implemented in Python.\n\n    \"\"\"\n    # These keys point to string values\n    textkeys = (\n        \"ID\",\n        \"PMID\",\n        \"SO\",\n        \"RF\",\n        \"NI\",\n        \"JC\",\n        \"TA\",\n        \"IS\",\n        \"CY\",\n        \"TT\",\n        \"CA\",\n        \"IP\",\n        \"VI\",\n        \"DP\",\n        \"YR\",\n        \"PG\",\n        \"LID\",\n        \"DA\",\n        \"LR\",\n        \"OWN\",\n        \"STAT\",\n        \"DCOM\",\n        \"PUBM\",\n        \"DEP\",\n        \"PL\",\n        \"JID\",\n        \"SB\",\n        \"PMC\",\n        \"EDAT\",\n        \"MHDA\",\n        \"PST\",\n        \"AB\",\n        \"EA\",\n        \"TI\",\n        \"JT\",\n    )\n    handle = iter(handle)\n\n    key = \"\"\n    record = Record()\n    for line in handle:\n        if line[:6] == \"      \":  # continuation line\n            line = line.rstrip()\n            if line == \"\":\n                # All blank continuation lines should be considered a new line.\n                # See issue #4557\n                line = \"      \\n\"\n\n            if key in [\"MH\", \"AD\"]:\n                # Multi-line MESH term, want to append to last entry in list\n                record[key][-1] += line[5:]  # including space using line[5:]\n            else:\n                record[key].append(line[6:])\n        elif line != \"\\n\" and line != \"\\r\\n\":\n            line = line.rstrip()\n            key = line[:4].rstrip()\n            if key not in record:\n                record[key] = []\n            record[key].append(line[6:])\n        elif record:\n            # End of the record\n            # Join each list of strings into one string.\n            for key in record:\n                if key in textkeys:\n                    record[key] = \" \".join(record[key])\n            yield record\n            record = Record()\n    if record:  # catch last one\n        for key in record:\n            if key in textkeys:\n                record[key] = \" \".join(record[key])\n        yield record\n\n\ndef read(handle):\n    \"\"\"Read a single Medline record from the handle.\n\n    The handle is either is a Medline file, a file-like object, or a list\n    of lines describing a Medline record.\n\n    Typical usage:\n\n        >>> from Bio import Medline\n        >>> with open(\"Medline/pubmed_result1.txt\") as handle:\n        ...     record = Medline.read(handle)\n        ...     print(record['TI'])\n        ...\n        The Bio* toolkits--a brief overview.\n\n    \"\"\"\n    records = parse(handle)\n    return next(records)\n\n\nif __name__ == \"__main__\":\n    from Bio._utils import run_doctest\n\n    run_doctest()\n", "path": "Bio/Medline/__init__.py"}]}