Coryza rubrics of repertory
homeopathy AND coryza
homeopathic repertory coryza rubrics Kent repertory
http://homeoint.org/books/kentrep/kentnose.htm
http://homeoint.org/books/kentrep1/kent0325.htm
Kent repertory Nose coryza complete rubric subrubrics "coryza, annual"
Nose - Coryza - discharge, with - fluent
- Nose - Discharge - watery / acrid
- Eye - Lachrymation - coryza, during
- Nose - Sneezing - paroxysmal
- relevant modalities, such as open air agg. or warm room amel.
Make a quick-reference PDF of coryza rubrics
/tmp/workspace
mkdir -p "/tmp/workspace/coryza-rubrics-pdf/src" "/tmp/workspace/coryza-rubrics-pdf/output" && python - <<'PY' from reportlab.lib.pagesizes import A4 from reportlab.lib import colors from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle from reportlab.lib.enums import TA_CENTER from reportlab.lib.units import mm from reportlab.platypus import SimpleDocTemplate, Paragraph, Spacer, Table, TableStyle, PageBreak, KeepTogether from reportlab.pdfbase.pdfmetrics import stringWidth out='/tmp/workspace/coryza-rubrics-pdf/output/Coryza_Rubrics_Quick_Reference.pdf' styles=getSampleStyleSheet() styles.add(ParagraphStyle(name='TitleQR', parent=styles['Title'], fontName='Helvetica-Bold', fontSize=19, leading=23, alignment=TA_CENTER, textColor=colors.HexColor('#123047'), spaceAfter=4)) styles.add(ParagraphStyle(name='SubQR', parent=styles['Normal'], fontName='Helvetica', fontSize=8.7, leading=11, alignment=TA_CENTER, textColor=colors.HexColor('#4e6170'), spaceAfter=11)) styles.add(ParagraphStyle(name='SecQR', parent=styles['Heading2'], fontName='Helvetica-Bold', fontSize=11, leading=13, textColor=colors.white, backColor=colors.HexColor('#1d5c76'), borderPadding=(4,6,4,6), spaceBefore=7, spaceAfter=5)) styles.add(ParagraphStyle(name='BodyQR', parent=styles['Normal'], fontName='Helvetica', fontSize=8.35, leading=10.5, spaceAfter=2.5)) styles.add(ParagraphStyle(name='SmallQR', parent=styles['Normal'], fontName='Helvetica', fontSize=7.25, leading=9, textColor=colors.HexColor('#3e4a52'))) styles.add(ParagraphStyle(name='FootQR', parent=styles['Normal'], fontName='Helvetica-Oblique', fontSize=7, leading=8.2, textColor=colors.HexColor('#555555'))) def P(t,style='BodyQR'): return Paragraph(t, styles[style]) def tbl(rows, widths): t=Table(rows, colWidths=widths, hAlign='LEFT', repeatRows=1) t.setStyle(TableStyle([ ('BACKGROUND',(0,0),(-1,0),colors.HexColor('#d8e9ef')), ('TEXTCOLOR',(0,0),(-1,0),colors.HexColor('#123047')), ('FONTNAME',(0,0),(-1,0),'Helvetica-Bold'), ('FONTSIZE',(0,0),(-1,-1),7.7), ('LEADING',(0,0),(-1,-1),9.4), ('VALIGN',(0,0),(-1,-1),'TOP'), ('GRID',(0,0),(-1,-1),0.3,colors.HexColor('#b9cbd1')), ('ROWBACKGROUNDS',(0,1),(-1,-1),[colors.white,colors.HexColor('#f5f9fa')]), ('LEFTPADDING',(0,0),(-1,-1),4),('RIGHTPADDING',(0,0),(-1,-1),4), ('TOPPADDING',(0,0),(-1,-1),3),('BOTTOMPADDING',(0,0),(-1,-1),3), ])) return t def header_footer(canvas, doc): canvas.saveState() w,h=A4 canvas.setStrokeColor(colors.HexColor('#1d5c76')); canvas.setLineWidth(.5); canvas.line(16*mm,12*mm,w-16*mm,12*mm) canvas.setFont('Helvetica',7); canvas.setFillColor(colors.HexColor('#56646b')) canvas.drawString(16*mm,7.6*mm,'Coryza Rubrics Quick Reference') canvas.drawRightString(w-16*mm,7.6*mm,f'Page {doc.page}') canvas.restoreState() doc=SimpleDocTemplate(out,pagesize=A4, rightMargin=15*mm,leftMargin=15*mm,topMargin=13*mm,bottomMargin=17*mm,title='Coryza Rubrics Quick Reference',author='Orris') story=[] story += [P('CORYZA RUBRICS','TitleQR'),P('Quick-reference sheet | Kent repertory terminology | Nose chapter, Coryza (pp. 325-329)','SubQR')] story += [P('Core location','SecQR'), P('<b>Primary rubric:</b> <b>Nose - Coryza</b>. Select only what is observed, then add discharge character, obstruction, sneezing, eye, throat, head and general modalities. “Coryza” may be fluent or dry, acute or recurrent, and may occur with allergy or respiratory infection.', 'BodyQR')] rows=[[P('Rubric group','SmallQR'),P('Useful subrubrics / qualifiers','SmallQR')], [P('<b>Timing</b>','SmallQR'),P('daytime; morning; forenoon; noon; afternoon; evening; night; on waking','SmallQR')], [P('<b>Course / pattern</b>','SmallQR'),P('annual (hay fever); spring; summer; chronic, long-continued; sudden attacks; suppressed; alternating with fluent coryza','SmallQR')], [P('<b>Discharge state</b>','SmallQR'),P('discharge, <b>with</b> (fluent); discharge, <b>without</b> (dry); dry by night with fluent discharge by day','SmallQR')], [P('<b>Modalities</b>','SmallQR'),P('cold air; open air; warm room amel.; cold room; in bed; after rising; swallowing agg.; talking agg.','SmallQR')], [P('<b>Concomitants</b>','SmallQR'),P('with cough; croup; fever; sore throat; laryngeal inflammation; extending to frontal sinuses','SmallQR')]] story += [tbl(rows,[42*mm,125*mm]),Spacer(1,6)] story += [P('High-yield repertorial branches','SecQR')] branches=[ ('<b>1. Fluent coryza</b>','Nose - Coryza - discharge, with (fluent). Qualify by time, temperature, air, sleep, eating, or other modality where present.'), ('<b>2. Dry coryza</b>','Nose - Coryza - discharge, without. Add time: afternoon, evening, night, or in bed. Consider the alternating dry/fluent pattern if documented.'), ('<b>3. Seasonal / allergic pattern</b>','Nose - Coryza - annual (hay fever); annual - asthmatic breathing; spring; rose cold. Add sneezing, itching and lachrymation rubrics.'), ('<b>4. Complicated presentation</b>','Nose - Coryza - cough, with; croup, with; sore throat, with; fever, with; inflammation larynx, with; extending to frontal sinuses.'), ('<b>5. Suppressed coryza</b>','Nose - Coryza - suppressed. Record what followed suppression, for example headache, cough or other complaint, only if clearly temporally related.')] for a,b in branches: story += [P(a+'<br/>'+b)] story += [Spacer(1,4),P('Related rubrics to cross-reference','SecQR')] relrows=[[P('Clinical feature','SmallQR'),P('Common companion rubric areas','SmallQR')], [P('Nasal discharge','SmallQR'),P('Nose - Discharge: watery, thick, yellow, greenish, offensive, tenacious/viscid, postnasal, etc.','SmallQR')], [P('Blocked nose','SmallQR'),P('Nose - Obstruction: side, alternating sides, night, room temperature and other modalities.','SmallQR')], [P('Sneezing / irritation','SmallQR'),P('Nose - Sneezing: frequent, violent, paroxysmal, time; Nose - Itching: inside/tip.','SmallQR')], [P('Eyes','SmallQR'),P('Eye - Lachrymation - coryza, during; add character of tears and eye irritation where available.','SmallQR')], [P('Head / throat','SmallQR'),P('Head - Pain - coryza, with; throat pain or inflammation rubrics.','SmallQR')]] story += [tbl(relrows,[42*mm,125*mm])] story += [PageBreak()] story += [P('REPERTORIZATION WORKSHEET','TitleQR'),P('A compact sequence for documenting and translating a coryza presentation into rubrics','SubQR')] story += [P('Five-step sequence','SecQR')] steps=[ ('<b>1. State the core:</b>','Nose - Coryza.'), ('<b>2. Define the state:</b>','Fluent discharge, dry coryza, or an alternating pattern.'), ('<b>3. Define the discharge:</b>','Use Nose - Discharge for quantity, consistency, color, odor, and posterior flow.'), ('<b>4. Add modalities:</b>','Time of day; cold/open air; warm room; in bed; swallowing or talking.'), ('<b>5. Add concomitants:</b>','Sneezing, obstruction, itching, lachrymation, cough, sore throat, fever, headache, or sinus extension.')] for a,b in steps: story += [P(a+' '+b)] story += [P('Quick documentation grid','SecQR')] grid=[[P('<b>Feature</b>','SmallQR'),P('<b>Record before choosing rubrics</b>','SmallQR')], [P('Onset and course','SmallQR'),P('Acute or recurrent? Seasonal? Annual? Sudden attacks? Suppressed?','SmallQR')], [P('Timing','SmallQR'),P('Morning / daytime / afternoon / evening / night / on waking.','SmallQR')], [P('Flow','SmallQR'),P('No discharge, fluent discharge, or alternation of dry and fluent phases.','SmallQR')], [P('Discharge details','SmallQR'),P('Watery or thick; bland or irritating; color; odor; crusts; postnasal flow.','SmallQR')], [P('Aggravations / ameliorations','SmallQR'),P('Cold or open air, warm room, cold room, bed, swallowing, talking.','SmallQR')], [P('Associated symptoms','SmallQR'),P('Sneezing, itching, obstruction, eyes, head pain, throat, cough, fever, breathing.','SmallQR')]] story += [tbl(grid,[45*mm,122*mm]),Spacer(1,6)] story += [P('Examples of rubric construction','SecQR')] exrows=[[P('Observed presentation','SmallQR'),P('Rubric pathway','SmallQR')], [P('Watery flow with eye watering and repeated sneezing every spring','SmallQR'),P('Nose - Coryza - annual (hay fever) / spring + Nose - Coryza - discharge, with + Eye - Lachrymation - coryza, during + Nose - Sneezing [qualify further].','SmallQR')], [P('Blocked, dry nose chiefly at night; discharge becomes fluent in daytime','SmallQR'),P('Nose - Coryza - discharge, without - night + Nose - Coryza - discharge, without - fluent during the day + Nose - Obstruction - night.','SmallQR')], [P('Coryza with sore throat and cough, worse when swallowing','SmallQR'),P('Nose - Coryza - sore throat, with + Nose - Coryza - cough, with + Nose - Coryza - swallowing agg.; add throat and cough particulars.','SmallQR')]] story += [tbl(exrows,[65*mm,102*mm]),Spacer(1,6)] story += [P('Safety note','SecQR'),P('This sheet is a repertory-navigation aid, not a diagnosis or substitute for evidence-based care. Seek prompt clinical assessment for breathing difficulty, facial swelling, severe headache or facial pain, persistent high fever, dehydration, chest pain, confusion, symptoms in a young infant, or symptoms that are severe or prolonged.', 'FootQR')] story += [Spacer(1,5),P('Source note: Rubric names and organization based on James Tyler Kent, <i>Repertory of the Homoeopathic Materia Medica</i>, Nose chapter, “Coryza” entries, pp. 325-329 (online index consulted). Wording and availability can differ across Kent editions and modern repertories.', 'FootQR')] doc.build(story,onFirstPage=header_footer,onLaterPages=header_footer) print(out) PY
python - <<'PY' from pathlib import Path from pypdf import PdfReader p=Path('/tmp/workspace/coryza-rubrics-pdf/output/Coryza_Rubrics_Quick_Reference.pdf') assert p.exists() and p.stat().st_size > 0, 'PDF missing or empty' r=PdfReader(str(p)) text='\n'.join(page.extract_text() or '' for page in r.pages) assert len(r.pages)==2, f'Unexpected pages: {len(r.pages)}' for phrase in ['CORYZA RUBRICS','Primary rubric:', 'REPERTORIZATION WORKSHEET','Safety note']: assert phrase in text, f'Missing {phrase}' print(f'OK: {p.name} | {len(r.pages)} pages | {p.stat().st_size} bytes | {len(text)} extracted chars') PY
Coryza Rubrics Quick Reference
PDF Document · PDF
Coryza rubrics kent boennighusen all book
homeopathy AND coryza
Boenninghausen repertory coryza rubrics nose online "Coryza"
Kent repertory Nose Coryza full rubrics online
What should I prepare?
Nose - Coryza - discharge, with - fluent
- Nose - Discharge - watery / acrid
- Eye - Lachrymation - coryza, during
- Nose - Sneezing - paroxysmal
- relevant modalities, such as open air agg. or warm room amel.
Coryza Rubrics Quick Reference
PDF Document · PDF
List all Kent coryza rubrics with remedy grades
homeopathy AND coryza
site:homeoint.org/books/kentrep1/kent0325.htm "CORYZA"
http://homeoint.org/books/kentrep1/kent0325.htm
Kent repertory coryza remedies grades bold italics online full text
/tmp/workspace
python - <<'PY' from urllib.request import urlopen from pathlib import Path url='http://homeoint.org/books/kentrep1/kent0325.htm' data=urlopen(url,timeout=30).read() p=Path('/tmp/workspace/coryza-rubrics-pdf/src/kent0325.html') p.write_bytes(data) print(len(data), p) PY
~/coryza-rubrics-pdf
mkdir -p "/tmp/workspace/coryza-rubrics-pdf/src" && python - <<'PY' from urllib.request import urlopen from pathlib import Path url='http://homeoint.org/books/kentrep1/kent0325.htm' data=urlopen(url,timeout=30).read() p=Path('/tmp/workspace/coryza-rubrics-pdf/src/kent0325.html') p.write_bytes(data) print(len(data), p) PY
python - <<'PY' from bs4 import BeautifulSoup from pathlib import Path p=Path('/tmp/workspace/coryza-rubrics-pdf/src/kent0325.html') s=BeautifulSoup(p.read_bytes(),'html.parser') text=s.get_text('\n',strip=True) Path('/tmp/workspace/coryza-rubrics-pdf/src/kent0325.txt').write_text(text) start=text.find('CORYZA') print(text[start:start+14000]) PY
python - <<'PY' from pathlib import Path x=Path('/tmp/workspace/coryza-rubrics-pdf/src/kent0325.html').read_text(errors='replace') i=x.find('CORYZA') print(x[i:i+8000]) PY
python - <<'PY' from bs4 import BeautifulSoup, NavigableString from pathlib import Path from html import escape src=Path('/tmp/workspace/coryza-rubrics-pdf/src/kent0325.html') soup=BeautifulSoup(src.read_bytes(),'html.parser') ps=soup.find_all('p') start=next(i for i,p in enumerate(ps) if p.get_text(' ',strip=True).startswith('CORYZA')) end=next(i for i,p in enumerate(ps[start+1:],start+1) if p.get_text(' ',strip=True).startswith('CRACKLING in')) sel=ps[start:end] # Convert p inner HTML to ReportLab friendly markup. Preserve bold=grade 3 and italic=grade 2. def render(node): if isinstance(node,NavigableString): return escape(str(node)) name=(node.name or '').lower() inner=''.join(render(c) for c in node.children) if name=='b': return '<b>'+inner+'</b>' if name=='i': return '<i>'+inner+'</i>' if name=='br': return '<br/>' if name=='a': return inner # font and unknown presentation tags stripped return inner def clean(s): import re s=s.replace('\xa0',' ') s=re.sub(r'\s+',' ',s) s=s.replace(' :', ':') return s.strip() entries=[] for p in sel: body=clean(''.join(render(c) for c in p.children)) plain=BeautifulSoup(str(p),'html.parser').get_text(' ',strip=True) # Skip horizontal separators and noise if not plain or set(plain.replace(' ',''))=={'-'}: continue # approximate indent based on visual original hierarchy depth=sum(1 for x in p.parents if getattr(x,'name',None)=='dir') entries.append((depth,body,plain)) # output diagnostic out=Path('/tmp/workspace/coryza-rubrics-pdf/src/coryza_entries.html') html='''<!DOCTYPE html><html><head><meta charset="utf-8"><title>Kent Coryza entries</title></head><body>''' for d,b,pl in entries: html += f'<p style="margin-left:{max(0,d-1)*20}px">{b}</p>\n' html+='</body></html>' out.write_text(html) print('entries',len(entries),'first',entries[:4],'last',entries[-4:]) PY
python - <<'PY' from bs4 import BeautifulSoup from pathlib import Path from reportlab.lib.pagesizes import A4 from reportlab.lib import colors from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle from reportlab.lib.enums import TA_CENTER from reportlab.lib.units import mm from reportlab.platypus import SimpleDocTemplate, Paragraph, Spacer, KeepTogether source=Path('/tmp/workspace/coryza-rubrics-pdf/src/coryza_entries.html') soup=BeautifulSoup(source.read_text(),'html.parser') entries=[] for p in soup.find_all('p'): margin=int((p.get('style','margin-left:0px').split(':')[1].replace('px','').replace(';','') or '0')) entries.append((margin//20,p.decode_contents())) # Fix common source formatting caused by font/i nesting across a trailing comma: maintain content faithful; reduce cosmetic double spaces. import re for i,(d,t) in enumerate(entries): t=re.sub(r'\s+', ' ', t).strip() entries[i]=(d,t) outdir=Path('/tmp/workspace/coryza-rubrics-pdf/output'); outdir.mkdir(parents=True,exist_ok=True) txt=outdir/'Kent_Coryza_Rubrics_Graded.txt' lines=['KENT REPERTORY: NOSE - CORYZA (pp. 325-329)', 'Complete source transcription with typography-based grades', '', 'GRADE KEY: Bold = Grade 3; Italic = Grade 2; ordinary type = Grade 1.', 'Note: Formatting is reproduced from the online Kent source. Remedy abbreviations and grades may vary across editions/software.', ''] for d,t in entries: plain=BeautifulSoup(t,'html.parser').get_text(' ',strip=True) lines.append((' '*d)+plain) txt.write_text('\n'.join(lines)) pdf=outdir/'Kent_Coryza_Rubrics_With_Grades.pdf' styles=getSampleStyleSheet() styles.add(ParagraphStyle(name='T',parent=styles['Title'],fontName='Helvetica-Bold',fontSize=16,leading=19,alignment=TA_CENTER,textColor=colors.HexColor('#173d55'),spaceAfter=3)) styles.add(ParagraphStyle(name='St',parent=styles['Normal'],fontName='Helvetica',fontSize=8,leading=9.7,alignment=TA_CENTER,textColor=colors.HexColor('#425866'),spaceAfter=8)) styles.add(ParagraphStyle(name='H',parent=styles['Heading2'],fontName='Helvetica-Bold',fontSize=10,leading=12,textColor=colors.white,backColor=colors.HexColor('#1f617d'),borderPadding=(3,5,3,5),spaceBefore=7,spaceAfter=4)) styles.add(ParagraphStyle(name='E0',parent=styles['Normal'],fontName='Helvetica',fontSize=7.35,leading=9.1,spaceAfter=2.2)) for n,lm in [(1,7),(2,14),(3,21),(4,28)]: styles.add(ParagraphStyle(name=f'E{n}',parent=styles['E0'],leftIndent=lm)) styles.add(ParagraphStyle(name='Note',parent=styles['Normal'],fontName='Helvetica-Oblique',fontSize=7,leading=8.4,textColor=colors.HexColor('#4c555b'))) def footer(canv,doc): canv.saveState(); w,h=A4 canv.setStrokeColor(colors.HexColor('#1f617d'));canv.setLineWidth(.4);canv.line(14*mm,11*mm,w-14*mm,11*mm) canv.setFillColor(colors.HexColor('#56646b'));canv.setFont('Helvetica',6.8) canv.drawString(14*mm,7*mm,'Kent Repertory - Nose, Coryza') canv.drawRightString(w-14*mm,7*mm,f'Page {doc.page}') canv.restoreState() doc=SimpleDocTemplate(str(pdf),pagesize=A4,leftMargin=14*mm,rightMargin=14*mm,topMargin=12*mm,bottomMargin=15*mm,title='Kent Coryza Rubrics with Grades') story=[Paragraph('KENT: NOSE - CORYZA','T'),Paragraph('Complete rubric transcription with remedy grades | pp. 325-329', 'St'),Paragraph('<b>Grade key:</b> <b>bold</b> = Grade 3; <i>italic</i> = Grade 2; ordinary type = Grade 1. Grade formatting follows the online Kent source. Remedy abbreviations and grading can differ in other editions or repertory software.', 'Note'),Spacer(1,4)] for depth,content in entries: plain=BeautifulSoup(content,'html.parser').get_text(' ',strip=True) if plain in ('CORYZA','CORYZA, daytime','CORYZA, croup, with','CORYZA, discharge, without, afternoon','CORYZA, swallowing agg.'): story.append(Paragraph(plain,'H')) else: story.append(Paragraph(content, f'E{min(depth,4)}')) story += [Spacer(1,5),Paragraph('Source: J. T. Kent, Repertory of the Homoeopathic Materia Medica, Nose chapter, Coryza entries, pp. 325-329. Transcribed from the online text hosted by Homeoint. This is a repertorial reference, not clinical treatment guidance.', 'Note')] doc.build(story,onFirstPage=footer,onLaterPages=footer) print(pdf,txt,len(entries)) PY python - <<'PY' from pathlib import Path from pypdf import PdfReader p=Path('/tmp/workspace/coryza-rubrics-pdf/output/Kent_Coryza_Rubrics_With_Grades.pdf') t=Path('/tmp/workspace/coryza-rubrics-pdf/output/Kent_Coryza_Rubrics_Graded.txt') r=PdfReader(str(p)); text='\n'.join(x.extract_text() or '' for x in r.pages) assert p.exists() and p.stat().st_size>3000 assert t.exists() and t.stat().st_size>5000 for term in ['CORYZA, daytime','CORYZA, croup, with','CORYZA, swallowing agg.','frontal sinuses']: assert term in text,term print('Verified:',len(r.pages),'pages',p.stat().st_size,'bytes; text',t.stat().st_size,'bytes') PY
python - <<'PY' from bs4 import BeautifulSoup from pathlib import Path from reportlab.lib.pagesizes import A4 from reportlab.lib import colors from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle from reportlab.lib.enums import TA_CENTER from reportlab.lib.units import mm from reportlab.platypus import SimpleDocTemplate, Paragraph, Spacer source=Path('/tmp/workspace/coryza-rubrics-pdf/src/coryza_entries.html') soup=BeautifulSoup(source.read_text(),'html.parser') entries=[] for p in soup.find_all('p'): margin=int((p.get('style','margin-left:0px').split(':')[1].replace('px','').replace(';','') or '0')) entries.append((margin//20,p.decode_contents())) import re entries=[(d,re.sub(r'\s+',' ',t).strip()) for d,t in entries] outdir=Path('/tmp/workspace/coryza-rubrics-pdf/output'); outdir.mkdir(parents=True,exist_ok=True) txt=outdir/'Kent_Coryza_Rubrics_Graded.txt' lines=['KENT REPERTORY: NOSE - CORYZA (pp. 325-329)', 'Complete source transcription with typography-based grades', '', 'GRADE KEY: Bold = Grade 3; Italic = Grade 2; ordinary type = Grade 1.', 'Note: Typography and remedy abbreviations are reproduced from the online Kent source. They may vary across editions or repertory software.', ''] for d,t in entries: lines.append((' '*d)+BeautifulSoup(t,'html.parser').get_text(' ',strip=True)) txt.write_text('\n'.join(lines)) pdf=outdir/'Kent_Coryza_Rubrics_With_Grades.pdf' styles=getSampleStyleSheet() styles.add(ParagraphStyle(name='T',parent=styles['Title'],fontName='Helvetica-Bold',fontSize=16,leading=19,alignment=TA_CENTER,textColor=colors.HexColor('#173d55'),spaceAfter=3)) styles.add(ParagraphStyle(name='St',parent=styles['Normal'],fontName='Helvetica',fontSize=8,leading=9.7,alignment=TA_CENTER,textColor=colors.HexColor('#425866'),spaceAfter=8)) styles.add(ParagraphStyle(name='H',parent=styles['Heading2'],fontName='Helvetica-Bold',fontSize=10,leading=12,textColor=colors.white,backColor=colors.HexColor('#1f617d'),borderPadding=(3,5,3,5),spaceBefore=7,spaceAfter=4)) styles.add(ParagraphStyle(name='E0',parent=styles['Normal'],fontName='Helvetica',fontSize=7.35,leading=9.1,spaceAfter=2.2)) for n,lm in [(1,7),(2,14),(3,21),(4,28)]: styles.add(ParagraphStyle(name=f'E{n}',parent=styles['E0'],leftIndent=lm)) styles.add(ParagraphStyle(name='Note',parent=styles['Normal'],fontName='Helvetica-Oblique',fontSize=7,leading=8.4,textColor=colors.HexColor('#4c555b'))) def footer(canv,doc): canv.saveState(); w,h=A4 canv.setStrokeColor(colors.HexColor('#1f617d'));canv.setLineWidth(.4);canv.line(14*mm,11*mm,w-14*mm,11*mm) canv.setFillColor(colors.HexColor('#56646b'));canv.setFont('Helvetica',6.8) canv.drawString(14*mm,7*mm,'Kent Repertory - Nose, Coryza') canv.drawRightString(w-14*mm,7*mm,f'Page {doc.page}') canv.restoreState() doc=SimpleDocTemplate(str(pdf),pagesize=A4,leftMargin=14*mm,rightMargin=14*mm,topMargin=12*mm,bottomMargin=15*mm,title='Kent Coryza Rubrics with Grades') story=[Paragraph('KENT: NOSE - CORYZA',styles['T']),Paragraph('Complete rubric transcription with remedy grades | pp. 325-329', styles['St']),Paragraph('<b>Grade key:</b> <b>bold</b> = Grade 3; <i>italic</i> = Grade 2; ordinary type = Grade 1. Grade formatting follows the online Kent source. Remedy abbreviations and grading can differ in other editions or repertory software.', styles['Note']),Spacer(1,4)] heads={'CORYZA','CORYZA, daytime','CORYZA, croup, with','CORYZA, discharge, without, afternoon','CORYZA, swallowing agg.'} for depth,content in entries: plain=BeautifulSoup(content,'html.parser').get_text(' ',strip=True) story.append(Paragraph(plain,styles['H']) if plain in heads else Paragraph(content,styles[f'E{min(depth,4)}'])) story += [Spacer(1,5),Paragraph('Source: J. T. Kent, Repertory of the Homoeopathic Materia Medica, Nose chapter, Coryza entries, pp. 325-329. Transcribed from the online text hosted by Homeoint. This is a repertorial reference, not clinical treatment guidance.', styles['Note'])] doc.build(story,onFirstPage=footer,onLaterPages=footer) print(pdf,txt,len(entries)) PY python - <<'PY' from pathlib import Path from pypdf import PdfReader p=Path('/tmp/workspace/coryza-rubrics-pdf/output/Kent_Coryza_Rubrics_With_Grades.pdf'); t=Path('/tmp/workspace/coryza-rubrics-pdf/output/Kent_Coryza_Rubrics_Graded.txt') assert p.exists() and p.stat().st_size>3000; assert t.exists() and t.stat().st_size>5000 r=PdfReader(str(p)); x='\n'.join(page.extract_text() or '' for page in r.pages) for v in ['CORYZA, daytime','CORYZA, croup, with','CORYZA, swallowing agg.','frontal sinuses']: assert v in x,v print(f'OK {len(r.pages)} pages | PDF {p.stat().st_size} bytes | TXT {t.stat().st_size} bytes') PY
Kent Coryza Rubrics With Grades
PDF Document · PDF
Kent Coryza Rubrics Graded
Text File · TXT