How to write nose topic in exam while covering all topics in 5 mins to write
| Wall | Formation |
|---|---|
| Roof | Cribriform plate of ethmoid (middle 1/3) |
| Floor | Palatine process of maxilla (3/4) + horizontal plate of palatine (1/4) |
| Medial (septum) | Bony: perpendicular plate of ethmoid + vomer; Cartilaginous: septal cartilage |
| Lateral wall | Nasal bone, frontal process of maxilla, lacrimal, ethmoid, inf. nasal concha, palatine, medial pterygoid plate |
No need of lining of nasal cavity to write in exam
| Wall | Formed by |
|---|---|
| Roof | Cribriform plate of ethmoid (middle 1/3) |
| Floor | Palatine process of maxilla (3/4) + horizontal plate of palatine (1/4) |
| Medial (septum) | Perpendicular plate of ethmoid + vomer + septal cartilage |
| Lateral wall | Nasal, lacrimal, ethmoid, inferior concha, palatine, medial pterygoid plate |
| Meatus/Recess | Opens Into |
|---|---|
| Inferior meatus | Nasolacrimal duct |
| Middle meatus - hiatus semilunaris | Frontal sinus, Anterior ethmoidal, Maxillary sinus |
| Middle meatus - on bulla | Middle ethmoidal sinus |
| Superior meatus | Posterior ethmoidal sinus |
| Sphenoethmoidal recess | Sphenoidal sinus |
📝 Draw a small lateral wall diagram here - saves time and gets marks!
| Skip | Replace with |
|---|---|
| Lining details | 1 extra clinical point |
| Full autonomic detail | Just write "via Vidian nerve" |
| Minor alar cartilages detail | Not exam-relevant |
Create a one-page quick reference PDF for nasal anatomy
mkdir -p /home/daytona/workspace/nasal-anatomy && ls /home/daytona/workspace/
~/nasal-anatomy/create_pdf.py
from reportlab.lib.pagesizes import A4
from reportlab.lib import colors
from reportlab.lib.units import mm
from reportlab.platypus import SimpleDocTemplate, Table, TableStyle, Paragraph, Spacer, HRFlowable
from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
from reportlab.lib.enums import TA_CENTER, TA_LEFT
from reportlab.platypus import KeepTogether
OUTPUT = "/home/daytona/workspace/nasal-anatomy/Nasal_Anatomy_Quick_Reference.pdf"
doc = SimpleDocTemplate(
OUTPUT,
pagesize=A4,
topMargin=8*mm,
bottomMargin=8*mm,
leftMargin=10*mm,
rightMargin=10*mm,
)
W, H = A4
styles = getSampleStyleSheet()
# ── colour palette ──────────────────────────────────────────────────────────
BLUE_DARK = colors.HexColor("#1a3a5c")
BLUE_MED = colors.HexColor("#2e6da4")
BLUE_LIGHT = colors.HexColor("#d6e8f7")
BLUE_XLIGHT = colors.HexColor("#eef5fc")
RED_DARK = colors.HexColor("#8b0000")
RED_LIGHT = colors.HexColor("#fde8e8")
GREEN_DARK = colors.HexColor("#1a5c2e")
GREEN_LIGHT = colors.HexColor("#e8f7ec")
ORANGE_DARK = colors.HexColor("#7a3900")
ORANGE_LIGHT= colors.HexColor("#fff3e0")
GREY_LIGHT = colors.HexColor("#f5f5f5")
WHITE = colors.white
BLACK = colors.black
# ── styles ───────────────────────────────────────────────────────────────────
title_style = ParagraphStyle("title",
fontSize=16, leading=20, textColor=WHITE,
alignment=TA_CENTER, fontName="Helvetica-Bold")
subtitle_style = ParagraphStyle("subtitle",
fontSize=8, leading=10, textColor=colors.HexColor("#c8dcf0"),
alignment=TA_CENTER, fontName="Helvetica")
sec_hdr = ParagraphStyle("sec_hdr",
fontSize=7.5, leading=9, textColor=WHITE,
alignment=TA_CENTER, fontName="Helvetica-Bold")
body = ParagraphStyle("body",
fontSize=6.5, leading=8.5, textColor=BLACK,
fontName="Helvetica")
body_bold = ParagraphStyle("body_bold",
fontSize=6.5, leading=8.5, textColor=BLUE_DARK,
fontName="Helvetica-Bold")
bullet = ParagraphStyle("bullet",
fontSize=6.2, leading=8, textColor=BLACK,
fontName="Helvetica", leftIndent=6, bulletIndent=2)
clinical = ParagraphStyle("clinical",
fontSize=6.2, leading=8, textColor=RED_DARK,
fontName="Helvetica-Bold")
mem = ParagraphStyle("mem",
fontSize=6.2, leading=8, textColor=GREEN_DARK,
fontName="Helvetica-Oblique")
def section_table(header_text, header_bg, rows, col_widths, header_text_color=WHITE):
"""Build a section with a coloured header row + data rows."""
header_style = ParagraphStyle("hdr2",
fontSize=7.2, leading=9, textColor=header_text_color,
alignment=TA_CENTER, fontName="Helvetica-Bold")
data = [[Paragraph(header_text, header_style)]] + rows
# header spans all columns
n_cols = len(col_widths)
style = TableStyle([
("SPAN", (0, 0), (n_cols-1, 0)),
("BACKGROUND", (0, 0), (n_cols-1, 0), header_bg),
("BACKGROUND", (0, 1), (n_cols-1, -1), GREY_LIGHT),
("ROWBACKGROUNDS",(0, 1),(n_cols-1, -1), [WHITE, BLUE_XLIGHT]),
("GRID", (0, 0), (-1, -1), 0.3, colors.HexColor("#c0c0c0")),
("TOPPADDING", (0, 0), (-1, -1), 2),
("BOTTOMPADDING",(0, 0), (-1, -1), 2),
("LEFTPADDING", (0, 0), (-1, -1), 3),
("RIGHTPADDING", (0, 0), (-1, -1), 3),
("VALIGN", (0, 0), (-1, -1), "MIDDLE"),
])
t = Table(data, colWidths=col_widths, style=style, repeatRows=1)
return t
def cell(txt, bold=False, color=BLACK):
s = ParagraphStyle("c", fontSize=6.2, leading=8,
fontName="Helvetica-Bold" if bold else "Helvetica",
textColor=color)
return Paragraph(txt, s)
# page width available
PW = A4[0] - 20*mm # 170 mm
story = []
# ════════════════════════════════════════════════════════════════════════════
# TITLE BANNER
# ════════════════════════════════════════════════════════════════════════════
title_data = [[
Paragraph("NASAL ANATOMY", title_style),
]]
title_tbl = Table(title_data, colWidths=[PW], style=TableStyle([
("BACKGROUND", (0,0), (-1,-1), BLUE_DARK),
("TOPPADDING", (0,0), (-1,-1), 5),
("BOTTOMPADDING",(0,0),(-1,-1), 3),
("ROUNDEDCORNERS", [4]),
]))
story.append(title_tbl)
sub_data = [[Paragraph("One-Page Exam Quick Reference | Head & Neck Anatomy", subtitle_style)]]
sub_tbl = Table(sub_data, colWidths=[PW], style=TableStyle([
("BACKGROUND", (0,0),(-1,-1), BLUE_MED),
("TOPPADDING",(0,0),(-1,-1),2),
("BOTTOMPADDING",(0,0),(-1,-1),2),
]))
story.append(sub_tbl)
story.append(Spacer(1, 3*mm))
# ════════════════════════════════════════════════════════════════════════════
# ROW 1: Functions + External Nose | Nasal Cavity Boundaries
# ════════════════════════════════════════════════════════════════════════════
half = PW/2 - 2*mm
# --- LEFT: Functions + External Nose ---
func_rows = [
[cell("1. Respiration", bold=True), cell("2. Olfaction", bold=True), cell("3. Protection")],
[cell("4. Air conditioning"), cell("5. Vocal resonance"), cell("6. Nasal reflex")],
]
func_tbl = Table(func_rows, colWidths=[half/3]*3, style=TableStyle([
("BACKGROUND", (0,0),(-1,-1), BLUE_XLIGHT),
("GRID", (0,0),(-1,-1), 0.3, colors.HexColor("#c0c0c0")),
("TOPPADDING",(0,0),(-1,-1),2), ("BOTTOMPADDING",(0,0),(-1,-1),2),
("LEFTPADDING",(0,0),(-1,-1),2), ("RIGHTPADDING",(0,0),(-1,-1),2),
]))
ext_rows = [
[cell("Tip/Apex"), cell("Lower free end")],
[cell("Root/Bridge"), cell("Upper narrow; continuous with forehead")],
[cell("Dorsum"), cell("Round border between tip and root")],
[cell("Nostrils/Nares"), cell("Two piriform apertures at lower end")],
[cell("Ala"), cell("Lower flared side of nose")],
]
ext_tbl = Table(ext_rows, colWidths=[half*0.35, half*0.65], style=TableStyle([
("ROWBACKGROUNDS",(0,0),(-1,-1),[WHITE, BLUE_XLIGHT]),
("GRID",(0,0),(-1,-1),0.3,colors.HexColor("#c0c0c0")),
("TOPPADDING",(0,0),(-1,-1),2),("BOTTOMPADDING",(0,0),(-1,-1),2),
("LEFTPADDING",(0,0),(-1,-1),3),("RIGHTPADDING",(0,0),(-1,-1),3),
]))
skel_rows = [
[cell("Upper 1/3", bold=True), cell("BONY: 2 nasal bones + frontal process of maxilla")],
[cell("Lower 2/3", bold=True), cell("CARTILAGINOUS: 2 lateral + 1 septal + 2 major alar (5 total)")],
]
skel_tbl = Table(skel_rows, colWidths=[half*0.3, half*0.7], style=TableStyle([
("ROWBACKGROUNDS",(0,0),(-1,-1),[WHITE, BLUE_XLIGHT]),
("GRID",(0,0),(-1,-1),0.3,colors.HexColor("#c0c0c0")),
("TOPPADDING",(0,0),(-1,-1),2),("BOTTOMPADDING",(0,0),(-1,-1),2),
("LEFTPADDING",(0,0),(-1,-1),3),("RIGHTPADDING",(0,0),(-1,-1),3),
]))
hdr_s = ParagraphStyle("hs", fontSize=7, leading=9, textColor=WHITE,
fontName="Helvetica-Bold", alignment=TA_CENTER)
left_block_data = [
[Paragraph("FUNCTIONS (6)", hdr_s)],
[func_tbl],
[Paragraph("EXTERNAL NOSE FEATURES", hdr_s)],
[ext_tbl],
[Paragraph("SKELETON", hdr_s)],
[skel_tbl],
]
left_block_style = TableStyle([
("BACKGROUND", (0,0),(0,0), BLUE_MED),
("BACKGROUND", (0,2),(0,2), BLUE_MED),
("BACKGROUND", (0,4),(0,4), BLUE_MED),
("BACKGROUND", (0,1),(0,1), WHITE),
("BACKGROUND", (0,3),(0,3), WHITE),
("BACKGROUND", (0,5),(0,5), WHITE),
("TOPPADDING",(0,0),(-1,-1),1),("BOTTOMPADDING",(0,0),(-1,-1),1),
("LEFTPADDING",(0,0),(-1,-1),0),("RIGHTPADDING",(0,0),(-1,-1),0),
("BOX",(0,0),(-1,-1),0.5, BLUE_MED),
])
left_block = Table(left_block_data, colWidths=[half], style=left_block_style)
# --- RIGHT: Nasal Cavity Boundaries ---
bnd_rows = [
[cell("Roof", bold=True, color=BLUE_DARK),
cell("Cribriform plate of ethmoid (middle 1/3); Nasal spine of frontal + nasal bone (ant 1/3); Sphenoid (post 1/3)")],
[cell("Floor", bold=True, color=BLUE_DARK),
cell("Palatine process of maxilla (3/4) + Horizontal plate of palatine (1/4)")],
[cell("Medial wall\n(Septum)", bold=True, color=BLUE_DARK),
cell("Bony: Perp. plate of ethmoid (posterosuperior) + Vomer (posteroinferior)\nCartilaginous: Septal cartilage (anterior)")],
[cell("Lateral wall", bold=True, color=BLUE_DARK),
cell("Bones: Nasal, Frontal process of maxilla, Lacrimal, Ethmoid conchae, Inf. nasal concha, Palatine, Med. pterygoid plate\nCartilages: Lateral nasal + Major alar")],
]
bnd_tbl = Table(bnd_rows, colWidths=[half*0.22, half*0.78], style=TableStyle([
("ROWBACKGROUNDS",(0,0),(-1,-1),[WHITE, BLUE_XLIGHT]),
("GRID",(0,0),(-1,-1),0.3,colors.HexColor("#c0c0c0")),
("TOPPADDING",(0,0),(-1,-1),2),("BOTTOMPADDING",(0,0),(-1,-1),2),
("LEFTPADDING",(0,0),(-1,-1),3),("RIGHTPADDING",(0,0),(-1,-1),3),
("VALIGN",(0,0),(-1,-1),"TOP"),
]))
# Conchae + Meatuses
meat_rows = [
[cell("Inferior meatus", bold=True, color=BLUE_DARK), cell("Nasolacrimal duct (anterior part)", color=BLUE_DARK)],
[cell("Middle meatus\n- On bulla ethmoidalis\n- Hiatus semilunaris\n (Ant/Mid/Post)", bold=True, color=BLUE_DARK),
cell("Middle ethmoidal sinuses\nFrontal sinus (anterior part)\nAnterior ethmoidal sinus (middle part)\nMaxillary sinus (posterior part)")],
[cell("Superior meatus", bold=True, color=BLUE_DARK), cell("Posterior ethmoidal sinuses")],
[cell("Sphenoethmoidal\nrecess", bold=True, color=BLUE_DARK), cell("Sphenoidal sinus")],
]
meat_tbl = Table(meat_rows, colWidths=[half*0.32, half*0.68], style=TableStyle([
("ROWBACKGROUNDS",(0,0),(-1,-1),[WHITE, BLUE_XLIGHT]),
("GRID",(0,0),(-1,-1),0.3,colors.HexColor("#c0c0c0")),
("TOPPADDING",(0,0),(-1,-1),2),("BOTTOMPADDING",(0,0),(-1,-1),2),
("LEFTPADDING",(0,0),(-1,-1),3),("RIGHTPADDING",(0,0),(-1,-1),3),
("VALIGN",(0,0),(-1,-1),"TOP"),
]))
concha_note = Paragraph(
"<b>Conchae:</b> Superior & Middle = projections of ethmoid labyrinth | "
"Inferior = independent bone | Superior is smallest, Inferior is largest",
ParagraphStyle("cn", fontSize=5.8, leading=7.5, fontName="Helvetica",
textColor=BLUE_DARK, backColor=BLUE_XLIGHT,
leftIndent=2, rightIndent=2)
)
right_block_data = [
[Paragraph("NASAL CAVITY - BOUNDARIES", hdr_s)],
[bnd_tbl],
[Paragraph("MEATUSES & SINUS OPENINGS", hdr_s)],
[meat_tbl],
[concha_note],
]
right_block_style = TableStyle([
("BACKGROUND", (0,0),(0,0), BLUE_MED),
("BACKGROUND", (0,2),(0,2), BLUE_MED),
("TOPPADDING",(0,0),(-1,-1),1),("BOTTOMPADDING",(0,0),(-1,-1),1),
("LEFTPADDING",(0,0),(-1,-1),0),("RIGHTPADDING",(0,0),(-1,-1),0),
("BOX",(0,0),(-1,-1),0.5, BLUE_MED),
])
right_block = Table(right_block_data, colWidths=[half], style=right_block_style)
row1 = Table([[left_block, right_block]], colWidths=[half, half],
style=TableStyle([
("LEFTPADDING",(0,0),(-1,-1),0),("RIGHTPADDING",(0,0),(-1,-1),0),
("TOPPADDING",(0,0),(-1,-1),0),("BOTTOMPADDING",(0,0),(-1,-1),0),
("INNERGRID",(0,0),(-1,-1),2,WHITE),
]))
story.append(row1)
story.append(Spacer(1, 2.5*mm))
# ════════════════════════════════════════════════════════════════════════════
# ROW 2: Blood Supply | Nerve Supply | Lymphatics
# ════════════════════════════════════════════════════════════════════════════
third = PW/3 - 1.5*mm
# --- Blood Supply ---
bs_rows = [
[cell("Ant. ethmoidal a.", bold=True), cell("← Ophthalmic a.")],
[cell("Post. ethmoidal a.", bold=True), cell("← Ophthalmic a.")],
[cell("Sphenopalatine a.", bold=True), cell("← Maxillary a.")],
[cell("Greater palatine a.", bold=True), cell("← Maxillary a.")],
[cell("Superior labial a.", bold=True), cell("← Facial a.")],
]
bs_tbl = Table(bs_rows, colWidths=[third*0.52, third*0.48], style=TableStyle([
("ROWBACKGROUNDS",(0,0),(-1,-1),[WHITE, BLUE_XLIGHT]),
("GRID",(0,0),(-1,-1),0.3,colors.HexColor("#c0c0c0")),
("TOPPADDING",(0,0),(-1,-1),2),("BOTTOMPADDING",(0,0),(-1,-1),2),
("LEFTPADDING",(0,0),(-1,-1),3),("RIGHTPADDING",(0,0),(-1,-1),3),
]))
little_para = Paragraph(
"<b>Little's Area (Kiesselbach's Plexus)</b><br/>"
"Anteroinferior septum | All 5 arteries anastomose<br/>"
"<font color='#8b0000'>★ Commonest site of EPISTAXIS</font>",
ParagraphStyle("little", fontSize=6, leading=7.8, fontName="Helvetica",
backColor=RED_LIGHT, textColor=RED_DARK,
leftIndent=2, rightIndent=2, borderPad=2)
)
lat_rows = [
[cell("Anterosuperior", bold=True), cell("Anterior ethmoidal a.")],
[cell("Anteroinferior", bold=True), cell("Facial + Greater palatine a.")],
[cell("Posterosuperior", bold=True), cell("Sphenopalatine a.")],
[cell("Posteroinferior", bold=True), cell("Greater palatine a.")],
]
lat_tbl = Table(lat_rows, colWidths=[third*0.45, third*0.55], style=TableStyle([
("ROWBACKGROUNDS",(0,0),(-1,-1),[WHITE, BLUE_XLIGHT]),
("GRID",(0,0),(-1,-1),0.3,colors.HexColor("#c0c0c0")),
("TOPPADDING",(0,0),(-1,-1),2),("BOTTOMPADDING",(0,0),(-1,-1),2),
("LEFTPADDING",(0,0),(-1,-1),3),("RIGHTPADDING",(0,0),(-1,-1),3),
]))
lat_hdr = Paragraph("Lateral Wall (4 Quadrants)", ParagraphStyle("lh", fontSize=6.2,
leading=8, fontName="Helvetica-Bold", textColor=BLUE_DARK,
backColor=BLUE_XLIGHT, alignment=TA_CENTER))
bs_block_data = [
[Paragraph("BLOOD SUPPLY — NASAL SEPTUM", hdr_s)],
[bs_tbl],
[little_para],
[lat_hdr],
[lat_tbl],
]
bs_block = Table(bs_block_data, colWidths=[third], style=TableStyle([
("BACKGROUND",(0,0),(0,0), RED_DARK),
("TOPPADDING",(0,0),(-1,-1),1),("BOTTOMPADDING",(0,0),(-1,-1),1),
("LEFTPADDING",(0,0),(-1,-1),0),("RIGHTPADDING",(0,0),(-1,-1),0),
("BOX",(0,0),(-1,-1),0.5, RED_DARK),
]))
# --- Nerve Supply ---
ns_rows = [
[cell("Olfactory nn.", bold=True, color=GREEN_DARK), cell("Smell from upper 1/3 (below cribriform plate)")],
[cell("Ant. ethmoidal n.", bold=True), cell("Anterosuperior part (septum + lat. wall)")],
[cell("Nasopalatine n.", bold=True), cell("Posteroinferior septum\n(from pterygopalatine ganglion)")],
[cell("Post. sup. nasal nn.", bold=True), cell("Posterosuperior septum + lat. wall")],
[cell("Nasal br. of greater\npalatine n.", bold=True), cell("Posterior septum")],
[cell("Ant. sup. alveolar n.", bold=True), cell("Anteroinferior part (from maxillary n.)")],
[cell("Infraorbital n.", bold=True), cell("Vestibule and anterior part")],
]
ns_tbl = Table(ns_rows, colWidths=[third*0.42, third*0.58], style=TableStyle([
("ROWBACKGROUNDS",(0,0),(-1,-1),[WHITE, GREEN_LIGHT]),
("GRID",(0,0),(-1,-1),0.3,colors.HexColor("#c0c0c0")),
("TOPPADDING",(0,0),(-1,-1),2),("BOTTOMPADDING",(0,0),(-1,-1),2),
("LEFTPADDING",(0,0),(-1,-1),3),("RIGHTPADDING",(0,0),(-1,-1),3),
("VALIGN",(0,0),(-1,-1),"TOP"),
]))
vidian_para = Paragraph(
"<b>Vidian Nerve</b> (Nerve of pterygoid canal)<br/>"
"Para: nasal gland secretion | Sympa: vasoconstriction<br/>"
"<i>Section of Vidian nerve → controls rhinorrhea</i>",
ParagraphStyle("vidian", fontSize=5.8, leading=7.5, fontName="Helvetica",
backColor=GREEN_LIGHT, textColor=GREEN_DARK,
leftIndent=2, rightIndent=2)
)
ns_block_data = [
[Paragraph("NERVE SUPPLY", hdr_s)],
[ns_tbl],
[vidian_para],
]
ns_block = Table(ns_block_data, colWidths=[third], style=TableStyle([
("BACKGROUND",(0,0),(0,0), GREEN_DARK),
("TOPPADDING",(0,0),(-1,-1),1),("BOTTOMPADDING",(0,0),(-1,-1),1),
("LEFTPADDING",(0,0),(-1,-1),0),("RIGHTPADDING",(0,0),(-1,-1),0),
("BOX",(0,0),(-1,-1),0.5, GREEN_DARK),
]))
# --- Lymphatics + Clinical ---
lymph_rows = [
[cell("Anterior half", bold=True), cell("Submandibular nodes")],
[cell("Posterior half", bold=True), cell("Retropharyngeal nodes")],
]
lymph_tbl = Table(lymph_rows, colWidths=[third*0.4, third*0.6], style=TableStyle([
("ROWBACKGROUNDS",(0,0),(-1,-1),[WHITE, ORANGE_LIGHT]),
("GRID",(0,0),(-1,-1),0.3,colors.HexColor("#c0c0c0")),
("TOPPADDING",(0,0),(-1,-1),2),("BOTTOMPADDING",(0,0),(-1,-1),2),
("LEFTPADDING",(0,0),(-1,-1),3),("RIGHTPADDING",(0,0),(-1,-1),3),
]))
clin_rows = [
[cell("Epistaxis", bold=True, color=RED_DARK), cell("Kiesselbach's plexus; commonest in children; Little's area")],
[cell("DNS", bold=True, color=RED_DARK), cell("Deviated nasal septum; causes nasal obstruction; treat by SMR / septoplasty")],
[cell("Rhinophyma", bold=True, color=RED_DARK), cell("Lobulated tumor; hypertrophy of sebaceous glands of nose")],
[cell("Rhinitis", bold=True, color=RED_DARK), cell("Mucosa inflammation; allergic type → Vidian nerve section")],
[cell("Nasal #", bold=True, color=RED_DARK), cell("Nasal bones = commonest facial fracture")],
]
clin_tbl = Table(clin_rows, colWidths=[third*0.28, third*0.72], style=TableStyle([
("ROWBACKGROUNDS",(0,0),(-1,-1),[WHITE, RED_LIGHT]),
("GRID",(0,0),(-1,-1),0.3,colors.HexColor("#c0c0c0")),
("TOPPADDING",(0,0),(-1,-1),2),("BOTTOMPADDING",(0,0),(-1,-1),2),
("LEFTPADDING",(0,0),(-1,-1),3),("RIGHTPADDING",(0,0),(-1,-1),3),
("VALIGN",(0,0),(-1,-1),"TOP"),
]))
lc_block_data = [
[Paragraph("LYMPHATIC DRAINAGE", hdr_s)],
[lymph_tbl],
[Paragraph("CLINICAL CORRELATIONS ★", hdr_s)],
[clin_tbl],
]
lc_block = Table(lc_block_data, colWidths=[third], style=TableStyle([
("BACKGROUND",(0,0),(0,0), ORANGE_DARK),
("BACKGROUND",(0,2),(0,2), RED_DARK),
("TOPPADDING",(0,0),(-1,-1),1),("BOTTOMPADDING",(0,0),(-1,-1),1),
("LEFTPADDING",(0,0),(-1,-1),0),("RIGHTPADDING",(0,0),(-1,-1),0),
("BOX",(0,0),(-1,-1),0.5, ORANGE_DARK),
]))
row2 = Table([[bs_block, ns_block, lc_block]],
colWidths=[third, third, third],
style=TableStyle([
("LEFTPADDING",(0,0),(-1,-1),0),("RIGHTPADDING",(0,0),(-1,-1),0),
("TOPPADDING",(0,0),(-1,-1),0),("BOTTOMPADDING",(0,0),(-1,-1),0),
("INNERGRID",(0,0),(-1,-1),2,WHITE),
]))
story.append(row2)
story.append(Spacer(1, 2.5*mm))
# ════════════════════════════════════════════════════════════════════════════
# ROW 3: Memory Mnemonics + Exam Tips
# ════════════════════════════════════════════════════════════════════════════
mem_data = [
[
Paragraph("<b>MEMORY MNEMONICS</b>", ParagraphStyle("mh", fontSize=7, leading=9,
fontName="Helvetica-Bold", textColor=BLUE_DARK, alignment=TA_CENTER)),
Paragraph("<b>EXAM WRITING TIPS</b>", ParagraphStyle("mh2", fontSize=7, leading=9,
fontName="Helvetica-Bold", textColor=BLUE_DARK, alignment=TA_CENTER)),
]
]
mem_tbl_outer = Table(mem_data, colWidths=[PW/2, PW/2], style=TableStyle([
("BACKGROUND",(0,0),(-1,-1), BLUE_XLIGHT),
("GRID",(0,0),(-1,-1),0.4, BLUE_MED),
("TOPPADDING",(0,0),(-1,-1),2),("BOTTOMPADDING",(0,0),(-1,-1),2),
("LEFTPADDING",(0,0),(-1,-1),3),("RIGHTPADDING",(0,0),(-1,-1),3),
]))
story.append(mem_tbl_outer)
mnem_rows = [
[
cell("Septum bones (PVS)", bold=True, color=BLUE_DARK),
cell("Perpendicular plate + Vomer + Septal cartilage"),
cell("Meatuses (NAS)", bold=True, color=BLUE_DARK),
cell("Nasolacrimal (Inf) | All sinuses (Mid) | Sept post ethm (Sup)"),
],
[
cell("Little's Area", bold=True, color=RED_DARK),
cell("5 arteries meet → nosebleed = easy 2 marks in exam"),
cell("Exam Order", bold=True, color=GREEN_DARK),
cell("Def → Functions → Ext Nose → Boundaries → Meatuses → B/S → N/S → Lymph → Clinical"),
],
[
cell("Cartilages (2+1+2)", bold=True, color=BLUE_DARK),
cell("2 Lateral + 1 Septal + 2 Major Alar = 5 main cartilages"),
cell("Time saver", bold=True, color=ORANGE_DARK),
cell("Draw lateral wall diagram = saves ~40 words + earns marks. Bold clinical correlations!"),
],
]
q_widths = [PW*0.15, PW*0.35, PW*0.15, PW*0.35]
mnem_tbl = Table(mnem_rows, colWidths=q_widths, style=TableStyle([
("ROWBACKGROUNDS",(0,0),(-1,-1),[WHITE, BLUE_XLIGHT]),
("GRID",(0,0),(-1,-1),0.3,colors.HexColor("#c0c0c0")),
("TOPPADDING",(0,0),(-1,-1),2),("BOTTOMPADDING",(0,0),(-1,-1),2),
("LEFTPADDING",(0,0),(-1,-1),3),("RIGHTPADDING",(0,0),(-1,-1),3),
("VALIGN",(0,0),(-1,-1),"TOP"),
("LINEAFTER",(1,0),(1,-1),0.8, BLUE_MED), # divider between left and right
]))
story.append(mnem_tbl)
# ════════════════════════════════════════════════════════════════════════════
# FOOTER
# ════════════════════════════════════════════════════════════════════════════
story.append(Spacer(1, 2*mm))
footer_data = [[
Paragraph(
"Source: Textbook of Anatomy – Head, Neck and Brain (Ch. 17) | "
"For exam use: Write in sequence → Definition → External → Boundaries → Meatuses → Blood Supply → Nerves → Lymphatics → Clinical",
ParagraphStyle("footer", fontSize=5.5, leading=7, textColor=WHITE,
fontName="Helvetica", alignment=TA_CENTER)
)
]]
footer_tbl = Table(footer_data, colWidths=[PW], style=TableStyle([
("BACKGROUND",(0,0),(-1,-1), BLUE_DARK),
("TOPPADDING",(0,0),(-1,-1),3),("BOTTOMPADDING",(0,0),(-1,-1),3),
("LEFTPADDING",(0,0),(-1,-1),4),("RIGHTPADDING",(0,0),(-1,-1),4),
]))
story.append(footer_tbl)
# ════════════════════════════════════════════════════════════════════════════
doc.build(story)
print(f"PDF saved to: {OUTPUT}")
cd /home/daytona/workspace/nasal-anatomy && python create_pdf.py
ls -lh /home/daytona/workspace/nasal-anatomy/Nasal_Anatomy_Quick_Reference.pdf
Nasal Anatomy Quick Reference
PDF Document · PDF