Suggest me a video to study thyroid gland

Searching the Web

best YouTube video thyroid gland anatomy physiology study

Here are some great YouTube videos to study the thyroid gland, depending on what angle you want to approach it from:

1. Thyroid Overview - Endocrinology (Prof. Zach Murphy)

  • Best for: Physiology & big-picture overview
  • Covers structure, hormones (T3/T4), feedback loops, and clinical relevance
  • Clear lecture style, good for medical/nursing students

2. Thyroid Gland Anatomy - Armando Hasudungan

  • Best for: Detailed anatomy
  • Covers embryology, blood supply, nerve supply, and relations
  • Armando's hand-drawn illustrations are excellent for visual learners

3. Thyroid and Parathyroid Glands (Anatomy + Histology)

  • Best for: Gross + microscopic anatomy combined
  • Includes histological features of follicular cells, parafollicular cells
  • Good if you need both macro and micro in one sitting

4. Thyroid Gland Anatomy (Short Overview)

  • Best for: Quick revision
  • Short and focused if you just need a refresher

My recommendation: Start with Armando Hasudungan's video for anatomy, then follow it up with Zach Murphy's physiology overview - together they cover the thyroid comprehensively for exams. If you need histology too, add the third video to your playlist.
Would you like me to also pull up textbook content on any specific aspect (anatomy, hormones, disorders, etc.)?

Prepare a 10 question quiz on muscles of mastication

Reading File
Finding Sources
Reading File
Reading File
Finding Sources
Reading File
Reading File
I have rich, textbook-sourced data from Gray's Anatomy for Students and Cummings Otolaryngology. Here is the quiz:

Muscles of Mastication - 10 Question Quiz


Q1. Which four muscles are classically considered the primary muscles of mastication?
Show Answer
Masseter, Temporalis, Medial pterygoid, and Lateral pterygoid. All are innervated by the mandibular nerve (V3).
- Gray's Anatomy for Students, Table 8.11

Q2. The masseter muscle originates from the zygomatic arch. Where does it insert, and what is its primary function?
Show Answer
It inserts on the lateral surface of the ramus of the mandible. Its primary function is elevation (and protrusion) of the mandible.
- Gray's Anatomy for Students, Table 8.11

Q3. The temporalis muscle is unique among jaw-closers because it can both elevate AND retract the mandible. What is its insertion, and which part is responsible for retraction?
Show Answer
It inserts on the coronoid process of the mandible and anterior margin of the ramus. The posterior fibers are responsible for retraction; the anterior/middle fibers elevate.
- Cummings Otolaryngology, Table 92.1

Q4. All four primary muscles of mastication share the same nerve supply. Name the nerve and its parent trunk.
Show Answer
They are all innervated by the mandibular nerve (V3), the third division of the trigeminal nerve (CN V). Specific branches include the masseteric nerve, deep temporal nerves, and nerves to the medial and lateral pterygoids.
- Gray's Anatomy for Students, Table 8.11

Q5. The lateral pterygoid has two heads with different functions. What does each head do?
Show Answer
  • Superior head - elevation and protrusion of the mandible
  • Inferior head - depression and lateral displacement of the mandible
The inferior head is the main driver of jaw opening (along with gravity), while the superior head works with the other closers.
- Cummings Otolaryngology, Ch. 86

Q6. Which muscle inserts on the medial surface of the angle of the mandible, and what movements does it produce?
Show Answer
The medial pterygoid. It produces elevation, protrusion, and lateral (side-to-side) movements of the mandible. Along with the masseter, it forms a muscular sling around the mandibular angle.
- Cummings Otolaryngology, Table 92.1

Q7. Which three muscles are responsible for depression (opening) of the mandible, and what nerve innervates the mylohyoid?
Show Answer
The jaw-opening muscles are the digastric (anterior belly), mylohyoid, and geniohyoid. The mylohyoid is innervated by the nerve to mylohyoid, a branch of the inferior alveolar nerve (V3).
- Cummings Otolaryngology, Table 92.1

Q8. A patient presents with inability to protrude the jaw and difficulty chewing side-to-side. Damage to which muscle is most likely responsible?
Show Answer
The lateral pterygoid. It is the primary muscle for protrusion and lateral (grinding) movements. Bilateral damage prevents protrusion; unilateral damage causes the jaw to deviate toward the side of the lesion on opening.
- Cummings Otolaryngology, Ch. 86

Q9. What is the blood supply to all four primary muscles of mastication?
Show Answer
Branches of the maxillary artery (a terminal branch of the external carotid artery).
- K.J. Lee's Essential Otolaryngology

Q10. During normal jaw opening, what happens at the temporomandibular joint beyond simple rotation - and which muscle drives this movement?
Show Answer
During opening, the mandibular head translates (protrudes) forward onto the articular tubercle in addition to rotating. This forward translation is driven primarily by the lateral pterygoid (inferior head), assisted by gravity and the digastric/mylohyoid muscles.
- Gray's Anatomy for Students, p. 1116

Score Guide: 9-10 correct = Excellent | 7-8 = Good | 5-6 = Review pterygoids and functions | <5 = Re-read the chapter

Create a printable PDF quiz with answer key

Reading File
Running Command

ls /home/daytona/workspace/ 2>/dev/null || echo "workspace empty or missing"

Running Command

mkdir -p /home/daytona/workspace/mastication-quiz

Writing File

~/mastication-quiz/generate_quiz_pdf.py

from reportlab.lib.pagesizes import A4
from reportlab.lib import colors
from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
from reportlab.lib.units import mm
from reportlab.platypus import (
    SimpleDocTemplate, Paragraph, Spacer, HRFlowable,
    Table, TableStyle, PageBreak, KeepTogether
)
from reportlab.lib.enums import TA_CENTER, TA_LEFT, TA_JUSTIFY
from reportlab.pdfgen import canvas
from reportlab.platypus.flowables import Flowable

# ── Colour palette ──────────────────────────────────────────────────────────
DARK_BLUE   = colors.HexColor("#1A3A5C")
MID_BLUE    = colors.HexColor("#2E6DA4")
LIGHT_BLUE  = colors.HexColor("#D6E8F7")
ACCENT      = colors.HexColor("#E07B39")
ANSWER_BG   = colors.HexColor("#EAF4EA")
ANSWER_LINE = colors.HexColor("#3A8A3A")
LIGHT_GRAY  = colors.HexColor("#F5F5F5")
RULE_GRAY   = colors.HexColor("#CCCCCC")
WHITE       = colors.white

PAGE_W, PAGE_H = A4
MARGIN = 20 * mm

# ── Quiz data ────────────────────────────────────────────────────────────────
QUESTIONS = [
    {
        "n": 1,
        "q": "Which four muscles are classically considered the primary muscles of mastication?",
        "a": "Masseter, Temporalis, Medial pterygoid, and Lateral pterygoid. All are innervated by the mandibular nerve (V3).",
        "ref": "Gray's Anatomy for Students, Table 8.11"
    },
    {
        "n": 2,
        "q": "The masseter originates from the zygomatic arch. Where does it insert, and what is its primary function?",
        "a": "Inserts on the lateral surface of the ramus of the mandible. Primary function: elevation (and protrusion) of the mandible.",
        "ref": "Gray's Anatomy for Students, Table 8.11"
    },
    {
        "n": 3,
        "q": "The temporalis can both elevate AND retract the mandible. What is its insertion, and which part of the muscle is responsible for retraction?",
        "a": "Inserts on the coronoid process of the mandible and the anterior margin of the ramus. The posterior fibres are responsible for retraction; anterior/middle fibres elevate.",
        "ref": "Cummings Otolaryngology, Table 92.1"
    },
    {
        "n": 4,
        "q": "All four primary muscles of mastication share the same nerve supply. Name the nerve and its parent cranial nerve trunk.",
        "a": "All are innervated by the mandibular nerve (V3), the third division of the trigeminal nerve (CN V). Specific branches: masseteric nerve, deep temporal nerves, and nerves to the medial and lateral pterygoids.",
        "ref": "Gray's Anatomy for Students, Table 8.11"
    },
    {
        "n": 5,
        "q": "The lateral pterygoid has two heads with different functions. Describe the action of each head.",
        "a": "Superior head: elevation and protrusion of the mandible. Inferior head: depression and lateral displacement of the mandible. The inferior head is the main driver of jaw opening.",
        "ref": "Cummings Otolaryngology, Ch. 86"
    },
    {
        "n": 6,
        "q": "Which muscle inserts on the medial surface of the angle of the mandible, and what movements does it produce?",
        "a": "The medial pterygoid. It produces elevation, protrusion, and lateral (side-to-side) movements of the mandible. Together with the masseter it forms a muscular sling around the mandibular angle.",
        "ref": "Cummings Otolaryngology, Table 92.1"
    },
    {
        "n": 7,
        "q": "Which three muscles are responsible for depression (opening) of the mandible, and what nerve innervates the mylohyoid?",
        "a": "The anterior belly of the digastric, mylohyoid, and geniohyoid. The mylohyoid is innervated by the nerve to mylohyoid, a branch of the inferior alveolar nerve (V3).",
        "ref": "Cummings Otolaryngology, Table 92.1"
    },
    {
        "n": 8,
        "q": "A patient presents with inability to protrude the jaw and difficulty with side-to-side chewing. Damage to which muscle is most likely responsible? What sign appears on jaw opening if only one side is affected?",
        "a": "The lateral pterygoid. Bilateral damage prevents protrusion. Unilateral damage causes the jaw to deviate toward the side of the lesion on opening.",
        "ref": "Cummings Otolaryngology, Ch. 86"
    },
    {
        "n": 9,
        "q": "What is the blood supply to all four primary muscles of mastication?",
        "a": "Branches of the maxillary artery (a terminal branch of the external carotid artery).",
        "ref": "K.J. Lee's Essential Otolaryngology"
    },
    {
        "n": 10,
        "q": "During jaw opening, the mandible does not simply rotate — what additional movement occurs at the TMJ, and which muscle drives it?",
        "a": "The mandibular head translates (protrudes) forward onto the articular tubercle in addition to rotating. This forward translation is driven primarily by the lateral pterygoid (inferior head), assisted by gravity and the suprahyoid muscles.",
        "ref": "Gray's Anatomy for Students, p. 1116"
    },
]

# ── Page numbering canvas ────────────────────────────────────────────────────
class NumberedCanvas(canvas.Canvas):
    def __init__(self, *args, **kwargs):
        canvas.Canvas.__init__(self, *args, **kwargs)
        self._saved_page_states = []

    def showPage(self):
        self._saved_page_states.append(dict(self.__dict__))
        self._startPage()

    def save(self):
        num_pages = len(self._saved_page_states)
        for state in self._saved_page_states:
            self.__dict__.update(state)
            self.draw_page_number(num_pages)
            canvas.Canvas.showPage(self)
        canvas.Canvas.save(self)

    def draw_page_number(self, page_count):
        pg = self._pageNumber
        self.setFont("Helvetica", 8)
        self.setFillColor(colors.HexColor("#888888"))
        self.drawRightString(PAGE_W - MARGIN, 10 * mm,
                             f"Page {pg} of {page_count}")
        self.drawString(MARGIN, 10 * mm, "Muscles of Mastication Quiz")


# ── Header / footer watermark on every page ──────────────────────────────────
def header_footer(canvas_obj, doc):
    canvas_obj.saveState()
    # Top colour bar
    canvas_obj.setFillColor(DARK_BLUE)
    canvas_obj.rect(0, PAGE_H - 14 * mm, PAGE_W, 14 * mm, fill=1, stroke=0)
    canvas_obj.setFillColor(WHITE)
    canvas_obj.setFont("Helvetica-Bold", 11)
    canvas_obj.drawString(MARGIN, PAGE_H - 9 * mm, "Muscles of Mastication")
    canvas_obj.setFont("Helvetica", 9)
    canvas_obj.drawRightString(PAGE_W - MARGIN, PAGE_H - 9 * mm,
                               "Anatomy Quiz")
    # Bottom rule
    canvas_obj.setStrokeColor(RULE_GRAY)
    canvas_obj.setLineWidth(0.5)
    canvas_obj.line(MARGIN, 15 * mm, PAGE_W - MARGIN, 15 * mm)
    canvas_obj.restoreState()


# ── Build PDF ────────────────────────────────────────────────────────────────
def build_pdf(output_path):
    doc = SimpleDocTemplate(
        output_path,
        pagesize=A4,
        leftMargin=MARGIN,
        rightMargin=MARGIN,
        topMargin=22 * mm,
        bottomMargin=22 * mm,
        title="Muscles of Mastication – Quiz & Answer Key",
        author="Orris Medical Education",
    )

    styles = getSampleStyleSheet()

    # Custom styles
    title_style = ParagraphStyle(
        "QuizTitle",
        parent=styles["Title"],
        fontSize=22,
        textColor=DARK_BLUE,
        spaceAfter=4,
        alignment=TA_CENTER,
        fontName="Helvetica-Bold",
    )
    subtitle_style = ParagraphStyle(
        "Subtitle",
        parent=styles["Normal"],
        fontSize=11,
        textColor=MID_BLUE,
        spaceAfter=2,
        alignment=TA_CENTER,
        fontName="Helvetica",
    )
    instr_style = ParagraphStyle(
        "Instructions",
        parent=styles["Normal"],
        fontSize=9,
        textColor=colors.HexColor("#555555"),
        spaceAfter=2,
        alignment=TA_CENTER,
        fontName="Helvetica-Oblique",
    )
    q_label_style = ParagraphStyle(
        "QLabel",
        parent=styles["Normal"],
        fontSize=10,
        textColor=WHITE,
        fontName="Helvetica-Bold",
        leading=14,
    )
    q_text_style = ParagraphStyle(
        "QText",
        parent=styles["Normal"],
        fontSize=11,
        textColor=DARK_BLUE,
        fontName="Helvetica-Bold",
        leading=15,
        spaceAfter=3,
    )
    blank_label_style = ParagraphStyle(
        "BlankLabel",
        parent=styles["Normal"],
        fontSize=9,
        textColor=colors.HexColor("#777777"),
        fontName="Helvetica-Oblique",
    )
    section_style = ParagraphStyle(
        "SectionHead",
        parent=styles["Normal"],
        fontSize=15,
        textColor=WHITE,
        fontName="Helvetica-Bold",
        leading=20,
        alignment=TA_CENTER,
    )
    ans_q_style = ParagraphStyle(
        "AnsQ",
        parent=styles["Normal"],
        fontSize=10,
        textColor=DARK_BLUE,
        fontName="Helvetica-Bold",
        leading=14,
        spaceAfter=2,
    )
    ans_text_style = ParagraphStyle(
        "AnsText",
        parent=styles["Normal"],
        fontSize=10,
        textColor=colors.HexColor("#1A5C1A"),
        fontName="Helvetica",
        leading=14,
        spaceAfter=2,
    )
    ref_style = ParagraphStyle(
        "Ref",
        parent=styles["Normal"],
        fontSize=8,
        textColor=colors.HexColor("#888888"),
        fontName="Helvetica-Oblique",
        spaceAfter=0,
    )
    score_style = ParagraphStyle(
        "Score",
        parent=styles["Normal"],
        fontSize=10,
        textColor=DARK_BLUE,
        fontName="Helvetica",
        leading=15,
    )

    story = []

    # ── COVER / TITLE ──────────────────────────────────────────────────────
    story.append(Spacer(1, 10 * mm))
    story.append(Paragraph("Muscles of Mastication", title_style))
    story.append(Paragraph("10-Question Anatomy Quiz", subtitle_style))
    story.append(Spacer(1, 3 * mm))
    story.append(HRFlowable(width="60%", thickness=2, color=ACCENT,
                             hAlign="CENTER"))
    story.append(Spacer(1, 4 * mm))

    story.append(Paragraph(
        "Name: ______________________________________  "
        "Date: _________________  "
        "Score: _______ / 10",
        ParagraphStyle("NameLine", parent=styles["Normal"], fontSize=10,
                       textColor=DARK_BLUE, fontName="Helvetica",
                       alignment=TA_CENTER)
    ))
    story.append(Spacer(1, 3 * mm))
    story.append(Paragraph(
        "Write your answers in the space provided. Each question carries 1 mark.",
        instr_style
    ))
    story.append(Spacer(1, 6 * mm))

    # ── QUESTIONS ──────────────────────────────────────────────────────────
    for item in QUESTIONS:
        # Question number badge + text in a table
        badge = Table(
            [[Paragraph(f"Q{item['n']}", q_label_style),
              Paragraph(item["q"], q_text_style)]],
            colWidths=[10 * mm, PAGE_W - 2 * MARGIN - 10 * mm],
        )
        badge.setStyle(TableStyle([
            ("BACKGROUND", (0, 0), (0, 0), ACCENT),
            ("BACKGROUND", (1, 0), (1, 0), LIGHT_BLUE),
            ("VALIGN",     (0, 0), (-1, -1), "MIDDLE"),
            ("LEFTPADDING", (0, 0), (0, 0), 4),
            ("RIGHTPADDING", (0, 0), (0, 0), 4),
            ("LEFTPADDING", (1, 0), (1, 0), 6),
            ("TOPPADDING",  (0, 0), (-1, -1), 5),
            ("BOTTOMPADDING", (0, 0), (-1, -1), 5),
            ("ROUNDEDCORNERS", [3, 3, 3, 3]),
        ]))

        # Answer lines
        lines_table = Table(
            [[""] for _ in range(3)],
            colWidths=[PAGE_W - 2 * MARGIN],
            rowHeights=[8 * mm] * 3,
        )
        lines_table.setStyle(TableStyle([
            ("LINEBELOW", (0, 0), (-1, -1), 0.5, RULE_GRAY),
            ("BACKGROUND", (0, 0), (-1, -1), LIGHT_GRAY),
            ("LEFTPADDING", (0, 0), (-1, -1), 4),
        ]))

        block = KeepTogether([
            badge,
            Spacer(1, 2 * mm),
            lines_table,
            Spacer(1, 5 * mm),
        ])
        story.append(block)

    # ── SCORE GUIDE ────────────────────────────────────────────────────────
    story.append(Spacer(1, 2 * mm))
    score_data = [
        [Paragraph("<b>Score Guide</b>", ParagraphStyle(
            "SG", parent=styles["Normal"], fontSize=10,
            textColor=DARK_BLUE, fontName="Helvetica-Bold"))],
        [Paragraph(
            "9–10 &nbsp; Excellent &nbsp;|&nbsp; "
            "7–8 &nbsp; Good &nbsp;|&nbsp; "
            "5–6 &nbsp; Review pterygoids &amp; functions &nbsp;|&nbsp; "
            "&lt;5 &nbsp; Re-read the chapter",
            score_style)]
    ]
    score_table = Table(score_data, colWidths=[PAGE_W - 2 * MARGIN])
    score_table.setStyle(TableStyle([
        ("BACKGROUND", (0, 0), (-1, -1), LIGHT_BLUE),
        ("BOX", (0, 0), (-1, -1), 1, MID_BLUE),
        ("LEFTPADDING", (0, 0), (-1, -1), 8),
        ("TOPPADDING", (0, 0), (-1, -1), 5),
        ("BOTTOMPADDING", (0, 0), (-1, -1), 5),
    ]))
    story.append(score_table)

    # ── PAGE BREAK → ANSWER KEY ────────────────────────────────────────────
    story.append(PageBreak())

    # Answer key header band
    ak_header = Table(
        [[Paragraph("ANSWER KEY", section_style)]],
        colWidths=[PAGE_W - 2 * MARGIN],
        rowHeights=[14 * mm],
    )
    ak_header.setStyle(TableStyle([
        ("BACKGROUND", (0, 0), (-1, -1), DARK_BLUE),
        ("VALIGN",     (0, 0), (-1, -1), "MIDDLE"),
        ("LEFTPADDING", (0, 0), (-1, -1), 0),
    ]))
    story.append(ak_header)
    story.append(Spacer(1, 4 * mm))
    story.append(Paragraph(
        "Muscles of Mastication – Detailed Answers &amp; References",
        ParagraphStyle("AKSub", parent=styles["Normal"], fontSize=11,
                       textColor=MID_BLUE, fontName="Helvetica-Oblique",
                       alignment=TA_CENTER)
    ))
    story.append(Spacer(1, 5 * mm))

    for item in QUESTIONS:
        # Question row
        q_row = Table(
            [[Paragraph(f"Q{item['n']}", q_label_style),
              Paragraph(item["q"], ans_q_style)]],
            colWidths=[10 * mm, PAGE_W - 2 * MARGIN - 10 * mm],
        )
        q_row.setStyle(TableStyle([
            ("BACKGROUND", (0, 0), (0, 0), ACCENT),
            ("BACKGROUND", (1, 0), (1, 0), LIGHT_BLUE),
            ("VALIGN",     (0, 0), (-1, -1), "MIDDLE"),
            ("LEFTPADDING", (0, 0), (0, 0), 4),
            ("LEFTPADDING", (1, 0), (1, 0), 6),
            ("TOPPADDING",  (0, 0), (-1, -1), 4),
            ("BOTTOMPADDING", (0, 0), (-1, -1), 4),
        ]))

        # Answer box
        ans_box = Table(
            [[Paragraph(f"<b>Answer:</b> {item['a']}", ans_text_style)],
             [Paragraph(f"Reference: {item['ref']}", ref_style)]],
            colWidths=[PAGE_W - 2 * MARGIN],
        )
        ans_box.setStyle(TableStyle([
            ("BACKGROUND",  (0, 0), (-1, -1), ANSWER_BG),
            ("LINEAFTER",   (0, 0), (0, -1), 3, ANSWER_LINE),
            ("LEFTPADDING", (0, 0), (-1, -1), 8),
            ("TOPPADDING",  (0, 0), (-1, -1), 4),
            ("BOTTOMPADDING", (0, 0), (-1, -1), 4),
            ("BOX", (0, 0), (-1, -1), 0.5, RULE_GRAY),
        ]))

        block = KeepTogether([
            q_row,
            ans_box,
            Spacer(1, 5 * mm),
        ])
        story.append(block)

    # ── FOOTER NOTE ────────────────────────────────────────────────────────
    story.append(HRFlowable(width="100%", thickness=0.5, color=RULE_GRAY))
    story.append(Spacer(1, 2 * mm))
    story.append(Paragraph(
        "Sources: Gray's Anatomy for Students (Table 8.11) · "
        "Cummings Otolaryngology Head &amp; Neck Surgery (Tables 86.2, 92.1) · "
        "K.J. Lee's Essential Otolaryngology",
        ParagraphStyle("FootNote", parent=styles["Normal"], fontSize=7.5,
                       textColor=colors.HexColor("#888888"),
                       fontName="Helvetica-Oblique", alignment=TA_CENTER)
    ))

    doc.build(story, onFirstPage=header_footer, onLaterPages=header_footer,
              canvasmaker=NumberedCanvas)
    print("PDF created successfully.")


if __name__ == "__main__":
    build_pdf("/home/daytona/workspace/mastication-quiz/Muscles_of_Mastication_Quiz.pdf")
Running Command

python3 /home/daytona/workspace/mastication-quiz/generate_quiz_pdf.py

Running Command

ls -lh /home/daytona/workspace/mastication-quiz/

Your PDF is ready. Here's what's included:
Page 1 - Quiz Sheet:
  • Name / Date / Score line at the top
  • All 10 questions in styled cards (orange badge + blue background)
  • 3 ruled answer lines per question for handwritten responses
  • Score guide at the bottom
Page 2 - Answer Key:
  • Each question repeated with a full detailed answer in a green-tinted box
  • Left green border on each answer block for easy visual scanning
  • Textbook reference cited under every answer (Gray's Anatomy, Cummings Otolaryngology, K.J. Lee's)
Formatting: A4, page numbers, header bar on every page, print-ready.

Muscles of Mastication Quiz

PDF Document · PDF

Create a quiz of 10 questions on topic tmj

Finding Sources
Reading File
Reading File
Reading File
Reading File
Finding Sources
Reading File
I have rich textbook content from Scott-Brown's Otorhinolaryngology, Cummings Otolaryngology, Gray's Anatomy, and Rosen's Emergency Medicine. Here is the quiz:

Temporomandibular Joint (TMJ) - 10 Question Quiz


Q1. What type of joint is the TMJ, and which two bony structures articulate to form it?
Show Answer
The TMJ is a synovial joint. It is formed by the mandibular (glenoid) fossa of the temporal bone articulating with the mandibular condyle.
- Scott-Brown's Otorhinolaryngology Head & Neck Surgery, Ch. 41

Q2. The TMJ has four unusual features that distinguish it from most other synovial joints. Name them.
Show Answer
  1. The joint space is divided into upper and lower cavities by an intra-articular disc.
  2. Articular surfaces are covered by fibrous tissue (not hyaline cartilage), reflecting intramembranous development.
  3. A secondary condylar cartilage is present in the condyle head until adolescence.
  4. Movements of the joint are influenced by the teeth.
- Scott-Brown's Otorhinolaryngology Head & Neck Surgery, Ch. 41

Q3. The TMJ disc divides the joint into two compartments, each permitting a different type of movement. What movement occurs in each compartment?
Show Answer
  • Upper compartment - gliding (translatory) movement
  • Lower compartment - hinge (rotatory) movement
- Scott-Brown's Otorhinolaryngology Head & Neck Surgery, Ch. 41

Q4. Describe the structure of the retrodiscal tissue (bilaminar zone) and the functional significance of each lamina.
Show Answer
The retrodiscal tissue has a bilaminar structure:
  • Superior lamina - loose, highly vascular, contains elastin fibres; attaches to the squamotympanic fissure. Its elastic recoil may help the disc return to position on jaw closing.
  • Inferior lamina - relatively avascular, less extensible (few elastin fibres); attaches to the posterior margin of the condyle.
The retrodiscal tissue volume increases 4-5x via venous engorgement as the jaw opens.
- Scott-Brown's Otorhinolaryngology Head & Neck Surgery, Ch. 41

Q5. Which muscle inserts onto the pterygoid fovea of the mandibular condyle, and what is the pterygoid fovea?
Show Answer
The lateral pterygoid muscle inserts here. The pterygoid fovea is a small depression on the anterior surface of the neck of the condyle, which also receives fibres attaching to the articular disc and TMJ capsule.
- Gray's Anatomy for Students, Table 8.11; Scott-Brown's, Ch. 41

Q6. Name the three ligaments associated with the TMJ. Which one is the principal ligament that limits mandibular movement?
Show Answer
The three ligaments are:
  1. Lateral (temporomandibular) ligament - the principal ligament; limits posterior displacement and rotation of the condyle
  2. Sphenomandibular ligament - accessory; from spine of sphenoid to lingula of mandible
  3. Stylomandibular ligament - accessory; from styloid process to angle/posterior border of mandible
- Gray's Anatomy for Students, Fig. 8.142

Q7. A patient presents unable to close their mouth after a wide yawn, with jaw protruding and deviation away from one side, drooling, and garbled speech. What is the diagnosis, and toward which side does the jaw deviate?
Show Answer
This is anterior dislocation of the TMJ. In unilateral dislocation, the jaw deviates away from the affected joint (toward the unaffected side). Bilateral dislocation causes symmetric protrusion without lateral deviation.
- Rosen's Emergency Medicine, Ch. on Facial Trauma

Q8. Describe the technique for manual reduction of a dislocated TMJ. What precaution must be taken regarding finger placement?
Show Answer
The patient is seated upright. The operator stands in front. Thumbs or index fingers are placed in the buccal sulcus (not on the crowns of the teeth) on either side. The angle of the jaw is pressed downward while the chin is rotated upward and backward. Adequate analgesia and sedation are required. If fingers must rest near tooth crowns, they should be wrapped in gauze - when reduction occurs, masticatory muscle spasm snaps the jaw shut forcefully.
- Rosen's Emergency Medicine, Ch. on Facial Trauma

Q9. What are the absolute indications for TMJ surgery? What imaging modality is most appropriate for evaluating the disc and soft tissue structures of the TMJ?
Show Answer
Absolute indications: treatment of neoplasms, growth abnormalities, and ankylosis of the joint.
For soft tissue and disc evaluation, MRI is the modality of choice (CT is preferred for bony fractures). Surgery is otherwise considered only when pain/dysfunction is refractory to non-surgical therapy (NSAIDs, physical therapy, occlusal splints, counselling) and imaging confirms pathology.
- Cummings Otolaryngology, Ch. 92

Q10. What is TMJ arthrocentesis, what does the procedure involve, and what is its reported success rate?
Show Answer
Arthrocentesis is the simplest, least invasive TMJ surgical procedure. It is performed under IV sedation and local anaesthesia. Two 18-gauge needles are inserted into the superior joint space - one for irrigation inflow, one for outflow - using Ringer's lactate for lavage. Blocking the outflow port allows distension for lysis of adhesions. It achieves a 70-90% success rate in reducing TMJ pain and improving mandibular range of motion.
- Cummings Otolaryngology, Ch. 92

Score Guide: 9-10 = Excellent | 7-8 = Good | 5-6 = Review disc anatomy & disorders | <5 = Re-read the chapter

Would you like me to generate this as a printable PDF with an answer key (same format as the last one)?

Create a visual diagram of TMJ anatomy and movements

Generating Image

Detailed anatomical educational diagram of the Temporomandibular Joint (TMJ) showing two panels side by side. Left panel: cross-sectional sagittal view of TMJ anatomy with clearly labeled structures including: mandibular fossa, articular eminence, articular disc (meniscus) with its anterior band, intermediate zone, and posterior band, upper joint compartment (gliding movement), lower joint compartment (hinge movement), mandibular condyle, pterygoid fovea, retrodiscal tissue (bilaminar zone) with superior elastic lamina and inferior non-elastic lamina, joint capsule, synovial membrane, lateral pterygoid muscle attachment, sphenomandibular ligament, lateral temporomandibular ligament, and stylomandibular ligament. Right panel: diagram of TMJ movements of the mandible showing four movement types with arrows: Elevation (jaw closing - upward arrow), Depression (jaw opening - downward arrow with condyle translating forward), Protrusion (forward arrow), Retraction (backward arrow), and Lateral excursion (side-to-side arrow). Each movement labeled with the primary muscles responsible. Clean medical illustration style on white background, blue and orange color scheme, professional anatomy textbook quality with all labels in clear sans-serif font.

TMJ Anatomy and Movements Diagram
Here is the diagram covering:
Left panel - TMJ Anatomy (sagittal cross-section):
  • Mandibular fossa and articular eminence (temporal bone)
  • Articular disc with its three zones (anterior band, intermediate zone, posterior band)
  • Upper compartment (gliding) and lower compartment (hinge)
  • Mandibular condyle and pterygoid fovea
  • Retrodiscal bilaminar tissue (superior elastic + inferior non-elastic lamina)
  • Joint capsule and synovial membrane
  • Lateral pterygoid muscle attachment
  • Three associated ligaments (lateral TMJ, sphenomandibular, stylomandibular)
Right panel - Mandibular Movements:
  • Elevation - temporalis, masseter, medial pterygoid
  • Depression - lateral pterygoid (inferior head), digastric, mylohyoid + gravity
  • Protrusion - lateral pterygoid, medial pterygoid
  • Retraction - posterior fibres of temporalis
  • Lateral excursion - contralateral lateral pterygoid
Would you like me to also generate a PDF combining this diagram with the TMJ quiz from earlier?

Prepare a 15 questions quiz on dural venous sinuses

Finding Sources
Reading File
Reading File
Finding Sources
Finding Sources
Reading File
Reading File
Excellent - I now have comprehensive data from Gray's Anatomy, Color Atlas of Human Anatomy, Harrison's, and Adams & Victor's Neurology. Here is the 15-question quiz:

Dural Venous Sinuses - 15 Question Quiz


Q1. What are dural venous sinuses, and what is unique about their walls compared to peripheral veins?
Show Answer
Dural venous sinuses are venous channels of the dura mater that drain blood from the brain into the internal jugular veins. Their rigid walls are formed by the cranial periosteum and dura mater (not a muscular wall like peripheral veins). Their interior is lined with endothelium, and they are valveless.
- Color Atlas of Human Anatomy Vol. 2, p. 134

Q2. Name all the dural venous sinuses. (List at least 10.)
Show Answer
  1. Superior sagittal sinus
  2. Inferior sagittal sinus
  3. Straight sinus
  4. Occipital sinus
  5. Confluence of sinuses (torcular Herophili)
  6. Transverse sinus (right and left)
  7. Sigmoid sinus (right and left)
  8. Cavernous sinus (right and left)
  9. Intercavernous sinus
  10. Sphenoparietal sinus (right and left)
  11. Superior petrosal sinus (right and left)
  12. Inferior petrosal sinus (right and left)
  13. Basilar plexus
  14. Marginal sinus
- Gray's Anatomy for Students, Table 8.3

Q3. Where is the superior sagittal sinus located, and what does it receive?
Show Answer
It runs along the superior border of the falx cerebri, ending at the confluence of sinuses. It receives superior cerebral veins, diploic veins, emissary veins, and cerebrospinal fluid (via arachnoid granulations).
- Gray's Anatomy for Students, Table 8.3

Q4. The straight sinus lies at the junction of two dural folds. Name them, and list what it receives.
Show Answer
The straight sinus lies at the junction of the falx cerebri and the tentorium cerebelli. It receives the inferior sagittal sinus, the great cerebral vein (of Galen), posterior cerebral veins, superior cerebellar veins, and veins from the falx cerebri.
- Gray's Anatomy for Students, Table 8.3

Q5. What is the confluence of sinuses (torcular Herophili)? Where is it located, and which sinuses meet there?
Show Answer
The confluence of sinuses is a dilated venous space at the internal occipital protuberance. It receives the superior sagittal, straight, and occipital sinuses, and gives rise to the right and left transverse sinuses.
- Gray's Anatomy for Students, Table 8.3; Color Atlas of Human Anatomy, p. 134

Q6. Describe the course of the sigmoid sinus from origin to termination.
Show Answer
The sigmoid sinus is a continuation of the transverse sinus. It travels in an S-shaped course along the posterior inferior border of the petrous part of the temporal bone (grooving the parietal, temporal, and occipital bones) and terminates at the jugular foramen, where it becomes the internal jugular vein.
- Color Atlas of Human Anatomy Vol. 2, p. 134

Q7. The cavernous sinus has a very important anatomical relationship with several structures that pass through or within its walls. List all the structures and specify which pass through the sinus itself vs. in its lateral wall.
Show Answer
Passing through the sinus:
  • Internal carotid artery
  • Abducent nerve (CN VI)
In the lateral wall (medial to lateral order):
  • Oculomotor nerve (CN III)
  • Trochlear nerve (CN IV)
  • Ophthalmic branch of trigeminal (V1)
  • Maxillary branch of trigeminal (V2)
- Color Atlas of Human Anatomy, p. 134; Harrison's Principles of Internal Medicine 22E

Q8. Name four tributaries that drain into the cavernous sinus.
Show Answer
  1. Superior and inferior ophthalmic veins (connecting to the facial/angular vein)
  2. Sphenoparietal sinus
  3. Superficial cerebral veins
  4. Emissary veins from the pterygoid plexus
  5. Intercavernous sinuses (connecting the two cavernous sinuses across the sella turcica)
- Gray's Anatomy for Students, Table 8.3; Color Atlas of Human Anatomy, p. 134

Q9. What is the clinical significance of the connection between the cavernous sinus and the facial vein? Give a clinical example.
Show Answer
The cavernous sinus communicates with the facial/angular vein via the superior ophthalmic vein. This creates a route for infection to spread from the "danger triangle of the face" (upper lip, nose) to the cavernous sinus - a valveless pathway. A furuncle or infected pimple in this region can lead to septic cavernous sinus thrombosis, a life-threatening condition.
- Color Atlas of Human Anatomy, p. 134

Q10. A patient develops fever, headache, proptosis, chemosis, and painful ophthalmoplegia with ptosis. What is the diagnosis, and which cranial nerves are involved?
Show Answer
Septic cavernous sinus thrombosis. Cranial nerves affected are:
  • CN III (oculomotor) - ptosis, ophthalmoplegia
  • CN IV (trochlear) - loss of superior oblique function
  • CN VI (abducens) - lateral gaze palsy (often the earliest nerve affected due to its position inside the sinus)
  • CN V1 and V2 (ophthalmic and maxillary) - hyperesthesia, decreased corneal reflex
Signs also include dilated tortuous retinal veins and papilledema from raised venous pressure.
- Harrison's Principles of Internal Medicine 22E

Q11. Thrombosis of the transverse sinus presents with a characteristic symptom triad. What is it, and what associated condition can cause it?
Show Answer
Transverse sinus thrombosis classically presents with headache, earache (otalgia), and sixth nerve (CN VI) palsy, with retroorbital or facial pain - known as Gradenigo's syndrome. It is strongly associated with otitis media (infection spreading from the mastoid/middle ear to the adjacent sigmoid-transverse sinus system).
- Harrison's Principles of Internal Medicine 22E

Q12. What is the marginal sinus, and what does it connect?
Show Answer
The marginal sinus encircles the foramen magnum and connects the dural venous sinuses with the vertebral venous plexuses. It links the occipital/confluence system above with the extracranial epidural venous network of the spine below.
- Color Atlas of Human Anatomy Vol. 2, p. 134

Q13. What is the preferred imaging modality for diagnosing dural venous sinus thrombosis, and what is the key diagnostic finding on MRI?
Show Answer
The diagnosis is suggested by an absent flow void within the affected sinus on standard MRI. Confirmation is by contrast-enhanced MR venography (MRV), CT venography, or the venous phase of cerebral angiography. MRV is the modality of choice.
- Harrison's Principles of Internal Medicine 22E

Q14. What is the first-line treatment for aseptic dural venous sinus thrombosis, and what is the concern with using it when hemorrhagic infarction is present?
Show Answer
First-line treatment is anticoagulation with unfractionated or low-molecular-weight heparin, followed by warfarin or a newer anticoagulant. The concern is that small intracerebral hemorrhage from septic thrombophlebitis is NOT an absolute contraindication to heparin - anticoagulation is still recommended when there is progressive neurological deterioration despite antibiotics. Mortality remains high (10-20% have large hemorrhagic venous infarctions).
- Harrison's 22E; Adams & Victor's Principles of Neurology 12th Ed.

Q15. Deep cerebral vein thrombosis (occlusion of the vein of Galen and internal cerebral veins) produces a distinctive clinical picture. Describe it and name the structure most affected on imaging.
Show Answer
Deep cerebral vein thrombosis produces bithalamic infarction, manifesting as inattention, spatial neglect, amnesia, akinetic mutism, and apathy. Coma and pupillary changes may occur in severe cases. On MRI, a large bilobular region of signal change encompassing both thalami is the hallmark finding - much of which may represent reversible edema. Confirmation requires MR venography.
- Adams & Victor's Principles of Neurology, 12th Ed.

Score Guide: 14-15 = Outstanding | 11-13 = Strong | 8-10 = Review tributaries & clinical syndromes | <8 = Re-read the chapter

Would you like this converted into a printable PDF with answer key, like the muscles of mastication quiz?

Create a printable PDF quiz with answer key on dural venous sinuses

Writing File

~/dvs-quiz/generate_dvs_quiz.py

from reportlab.lib.pagesizes import A4
from reportlab.lib import colors
from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
from reportlab.lib.units import mm
from reportlab.platypus import (
    SimpleDocTemplate, Paragraph, Spacer, HRFlowable,
    Table, TableStyle, PageBreak, KeepTogether
)
from reportlab.lib.enums import TA_CENTER, TA_LEFT
from reportlab.pdfgen import canvas

# ── Colour palette ───────────────────────────────────────────────────────────
DARK_TEAL   = colors.HexColor("#0D4A5A")
MID_TEAL    = colors.HexColor("#1A7A96")
LIGHT_TEAL  = colors.HexColor("#D0EEF5")
ACCENT      = colors.HexColor("#C0582A")
ANSWER_BG   = colors.HexColor("#EAF4F0")
ANSWER_LINE = colors.HexColor("#1A8A5A")
LIGHT_GRAY  = colors.HexColor("#F7F7F7")
RULE_GRAY   = colors.HexColor("#CCCCCC")
WHITE       = colors.white

PAGE_W, PAGE_H = A4
MARGIN = 20 * mm

# ── Quiz data ────────────────────────────────────────────────────────────────
QUESTIONS = [
    {
        "n": 1,
        "q": "What are dural venous sinuses, and what is unique about their walls compared to peripheral veins?",
        "a": (
            "Dural venous sinuses are venous channels of the dura mater that drain blood from the brain into "
            "the internal jugular veins. Their rigid walls are formed by cranial periosteum and dura mater "
            "(not a muscular wall like peripheral veins). Their interior is lined with endothelium, and they "
            "are valveless."
        ),
        "ref": "Color Atlas of Human Anatomy Vol. 2, p. 134"
    },
    {
        "n": 2,
        "q": "Name at least 10 dural venous sinuses.",
        "a": (
            "Superior sagittal, Inferior sagittal, Straight, Occipital, Confluence of sinuses (torcular Herophili), "
            "Transverse (R & L), Sigmoid (R & L), Cavernous (R & L), Intercavernous, Sphenoparietal (R & L), "
            "Superior petrosal (R & L), Inferior petrosal (R & L), Basilar plexus, Marginal sinus."
        ),
        "ref": "Gray's Anatomy for Students, Table 8.3"
    },
    {
        "n": 3,
        "q": "Where is the superior sagittal sinus located, and what does it receive?",
        "a": (
            "It runs along the superior border of the falx cerebri, ending at the confluence of sinuses. "
            "It receives superior cerebral veins, diploic veins, emissary veins, and CSF via arachnoid granulations."
        ),
        "ref": "Gray's Anatomy for Students, Table 8.3"
    },
    {
        "n": 4,
        "q": "The straight sinus lies at the junction of two dural folds. Name them, and list its tributaries.",
        "a": (
            "Junction of the falx cerebri and tentorium cerebelli. Receives: inferior sagittal sinus, great "
            "cerebral vein (of Galen), posterior cerebral veins, superior cerebellar veins, and veins from "
            "the falx cerebri."
        ),
        "ref": "Gray's Anatomy for Students, Table 8.3"
    },
    {
        "n": 5,
        "q": "What is the confluence of sinuses (torcular Herophili)? Where is it located, and which sinuses meet there?",
        "a": (
            "A dilated venous space at the internal occipital protuberance. Receives: superior sagittal, straight, "
            "and occipital sinuses. Gives rise to the right and left transverse sinuses."
        ),
        "ref": "Gray's Anatomy for Students, Table 8.3; Color Atlas of Human Anatomy, p. 134"
    },
    {
        "n": 6,
        "q": "Describe the course of the sigmoid sinus from its origin to its termination.",
        "a": (
            "The sigmoid sinus is a continuation of the transverse sinus. It travels in an S-shaped course "
            "along the posterior inferior border of the petrous temporal bone (grooving the parietal, temporal, "
            "and occipital bones) and terminates at the jugular foramen, where it becomes the internal jugular vein."
        ),
        "ref": "Color Atlas of Human Anatomy Vol. 2, p. 134"
    },
    {
        "n": 7,
        "q": (
            "List all structures that pass through the cavernous sinus itself, and all structures "
            "that run within its lateral wall."
        ),
        "a": (
            "THROUGH the sinus: Internal carotid artery; Abducent nerve (CN VI).\n"
            "LATERAL WALL (medial to lateral): Oculomotor nerve (CN III); Trochlear nerve (CN IV); "
            "Ophthalmic nerve (V1); Maxillary nerve (V2)."
        ),
        "ref": "Color Atlas of Human Anatomy, p. 134; Harrison's Principles of Internal Medicine 22E"
    },
    {
        "n": 8,
        "q": "Name four tributaries that drain into the cavernous sinus.",
        "a": (
            "1. Superior and inferior ophthalmic veins (connection to facial/angular vein)\n"
            "2. Sphenoparietal sinus\n"
            "3. Superficial cerebral veins\n"
            "4. Emissary veins from the pterygoid plexus\n"
            "(Intercavernous sinuses connect the two cavernous sinuses to each other)"
        ),
        "ref": "Gray's Anatomy for Students, Table 8.3"
    },
    {
        "n": 9,
        "q": (
            "What is the clinical significance of the connection between the cavernous sinus and the facial vein? "
            "Give a clinical example."
        ),
        "a": (
            "The cavernous sinus communicates with the facial/angular vein via the superior ophthalmic vein "
            "through a valveless pathway. Infection from the 'danger triangle of the face' (nose, upper lip) "
            "can spread retrogradely to cause septic cavernous sinus thrombosis - a life-threatening condition."
        ),
        "ref": "Color Atlas of Human Anatomy, p. 134"
    },
    {
        "n": 10,
        "q": (
            "A patient develops fever, headache, proptosis, chemosis, and painful ophthalmoplegia with ptosis. "
            "What is the diagnosis and which cranial nerves are involved?"
        ),
        "a": (
            "Septic cavernous sinus thrombosis. Cranial nerves affected:\n"
            "CN III (ptosis, ophthalmoplegia), CN IV (superior oblique palsy), "
            "CN VI (lateral gaze palsy - often earliest), CN V1 & V2 (hyperesthesia, decreased corneal reflex). "
            "May also show dilated tortuous retinal veins and papilledema."
        ),
        "ref": "Harrison's Principles of Internal Medicine 22E"
    },
    {
        "n": 11,
        "q": (
            "Thrombosis of the transverse sinus presents with a characteristic triad. "
            "What is it, and what condition can cause it?"
        ),
        "a": (
            "Headache, otalgia (earache), and CN VI palsy with retroorbital/facial pain - known as Gradenigo's syndrome. "
            "Strongly associated with otitis media (infection spreading from mastoid/middle ear to the "
            "adjacent sigmoid-transverse sinus system)."
        ),
        "ref": "Harrison's Principles of Internal Medicine 22E"
    },
    {
        "n": 12,
        "q": "What is the marginal sinus and what does it connect?",
        "a": (
            "The marginal sinus encircles the foramen magnum and connects the dural venous sinuses "
            "with the vertebral venous plexuses of the spine, forming a link between the intracranial "
            "and extracranial epidural venous systems."
        ),
        "ref": "Color Atlas of Human Anatomy Vol. 2, p. 134"
    },
    {
        "n": 13,
        "q": (
            "What is the preferred imaging modality for diagnosing dural venous sinus thrombosis, "
            "and what is the key diagnostic finding on MRI?"
        ),
        "a": (
            "Contrast-enhanced MR venography (MRV) is the modality of choice. On standard MRI, the key finding "
            "is an absent flow void within the affected sinus. CT venography or the venous phase of cerebral "
            "angiography can also confirm the diagnosis."
        ),
        "ref": "Harrison's Principles of Internal Medicine 22E"
    },
    {
        "n": 14,
        "q": (
            "What is the first-line treatment for aseptic dural venous sinus thrombosis, and is the presence "
            "of small hemorrhagic infarction an absolute contraindication to this treatment?"
        ),
        "a": (
            "First-line treatment is anticoagulation with unfractionated or low-molecular-weight heparin, "
            "followed by warfarin or a newer anticoagulant. A small intracerebral hemorrhage from septic "
            "thrombophlebitis is NOT an absolute contraindication to heparin - anticoagulation is still "
            "recommended with progressive neurological deterioration despite antibiotics."
        ),
        "ref": "Harrison's 22E; Adams & Victor's Principles of Neurology, 12th Ed."
    },
    {
        "n": 15,
        "q": (
            "Deep cerebral vein thrombosis (occlusion of the vein of Galen and internal cerebral veins) "
            "produces a distinctive clinical picture. Describe it and identify the key MRI finding."
        ),
        "a": (
            "Produces bithalamic infarction: inattention, spatial neglect, amnesia, akinetic mutism, and apathy. "
            "Coma and pupillary changes may occur in severe cases. Key MRI finding: a large bilobular region of "
            "signal change encompassing both thalami (often reversible edema). Confirmed by MR venography."
        ),
        "ref": "Adams & Victor's Principles of Neurology, 12th Ed."
    },
]


# ── Page numbering canvas ────────────────────────────────────────────────────
class NumberedCanvas(canvas.Canvas):
    def __init__(self, *args, **kwargs):
        canvas.Canvas.__init__(self, *args, **kwargs)
        self._saved_page_states = []

    def showPage(self):
        self._saved_page_states.append(dict(self.__dict__))
        self._startPage()

    def save(self):
        num_pages = len(self._saved_page_states)
        for state in self._saved_page_states:
            self.__dict__.update(state)
            self.draw_page_number(num_pages)
            canvas.Canvas.showPage(self)
        canvas.Canvas.save(self)

    def draw_page_number(self, page_count):
        pg = self._pageNumber
        self.setFont("Helvetica", 8)
        self.setFillColor(colors.HexColor("#888888"))
        self.drawRightString(PAGE_W - MARGIN, 10 * mm,
                             f"Page {pg} of {page_count}")
        self.drawString(MARGIN, 10 * mm, "Dural Venous Sinuses Quiz")


# ── Per-page header/footer ────────────────────────────────────────────────────
def header_footer(canvas_obj, doc):
    canvas_obj.saveState()
    canvas_obj.setFillColor(DARK_TEAL)
    canvas_obj.rect(0, PAGE_H - 14 * mm, PAGE_W, 14 * mm, fill=1, stroke=0)
    canvas_obj.setFillColor(WHITE)
    canvas_obj.setFont("Helvetica-Bold", 11)
    canvas_obj.drawString(MARGIN, PAGE_H - 9 * mm, "Dural Venous Sinuses")
    canvas_obj.setFont("Helvetica", 9)
    canvas_obj.drawRightString(PAGE_W - MARGIN, PAGE_H - 9 * mm, "Neuroanatomy Quiz")
    canvas_obj.setStrokeColor(RULE_GRAY)
    canvas_obj.setLineWidth(0.5)
    canvas_obj.line(MARGIN, 15 * mm, PAGE_W - MARGIN, 15 * mm)
    canvas_obj.restoreState()


# ── Build PDF ─────────────────────────────────────────────────────────────────
def build_pdf(output_path):
    doc = SimpleDocTemplate(
        output_path,
        pagesize=A4,
        leftMargin=MARGIN,
        rightMargin=MARGIN,
        topMargin=22 * mm,
        bottomMargin=22 * mm,
        title="Dural Venous Sinuses – Quiz & Answer Key",
        author="Orris Medical Education",
    )

    styles = getSampleStyleSheet()

    title_style = ParagraphStyle(
        "QuizTitle", parent=styles["Title"],
        fontSize=22, textColor=DARK_TEAL,
        spaceAfter=4, alignment=TA_CENTER, fontName="Helvetica-Bold",
    )
    subtitle_style = ParagraphStyle(
        "Subtitle", parent=styles["Normal"],
        fontSize=11, textColor=MID_TEAL,
        spaceAfter=2, alignment=TA_CENTER, fontName="Helvetica",
    )
    instr_style = ParagraphStyle(
        "Instructions", parent=styles["Normal"],
        fontSize=9, textColor=colors.HexColor("#555555"),
        spaceAfter=2, alignment=TA_CENTER, fontName="Helvetica-Oblique",
    )
    q_label_style = ParagraphStyle(
        "QLabel", parent=styles["Normal"],
        fontSize=10, textColor=WHITE,
        fontName="Helvetica-Bold", leading=14,
    )
    q_text_style = ParagraphStyle(
        "QText", parent=styles["Normal"],
        fontSize=10.5, textColor=DARK_TEAL,
        fontName="Helvetica-Bold", leading=14, spaceAfter=3,
    )
    section_style = ParagraphStyle(
        "SectionHead", parent=styles["Normal"],
        fontSize=15, textColor=WHITE,
        fontName="Helvetica-Bold", leading=20, alignment=TA_CENTER,
    )
    ans_q_style = ParagraphStyle(
        "AnsQ", parent=styles["Normal"],
        fontSize=10, textColor=DARK_TEAL,
        fontName="Helvetica-Bold", leading=13, spaceAfter=2,
    )
    ans_text_style = ParagraphStyle(
        "AnsText", parent=styles["Normal"],
        fontSize=9.5, textColor=colors.HexColor("#0A5C30"),
        fontName="Helvetica", leading=13, spaceAfter=2,
    )
    ref_style = ParagraphStyle(
        "Ref", parent=styles["Normal"],
        fontSize=7.5, textColor=colors.HexColor("#888888"),
        fontName="Helvetica-Oblique", spaceAfter=0,
    )
    score_style = ParagraphStyle(
        "Score", parent=styles["Normal"],
        fontSize=10, textColor=DARK_TEAL,
        fontName="Helvetica", leading=15,
    )

    story = []

    # ── TITLE ──────────────────────────────────────────────────────────────
    story.append(Spacer(1, 8 * mm))
    story.append(Paragraph("Dural Venous Sinuses", title_style))
    story.append(Paragraph("15-Question Neuroanatomy Quiz", subtitle_style))
    story.append(Spacer(1, 3 * mm))
    story.append(HRFlowable(width="60%", thickness=2, color=ACCENT, hAlign="CENTER"))
    story.append(Spacer(1, 4 * mm))
    story.append(Paragraph(
        "Name: ______________________________________  "
        "Date: _________________  "
        "Score: _______ / 15",
        ParagraphStyle("NameLine", parent=styles["Normal"], fontSize=10,
                       textColor=DARK_TEAL, fontName="Helvetica",
                       alignment=TA_CENTER)
    ))
    story.append(Spacer(1, 3 * mm))
    story.append(Paragraph(
        "Write your answers in the space provided. Each question carries 1 mark.",
        instr_style
    ))
    story.append(Spacer(1, 5 * mm))

    # ── QUESTIONS ──────────────────────────────────────────────────────────
    for item in QUESTIONS:
        badge = Table(
            [[Paragraph(f"Q{item['n']}", q_label_style),
              Paragraph(item["q"], q_text_style)]],
            colWidths=[10 * mm, PAGE_W - 2 * MARGIN - 10 * mm],
        )
        badge.setStyle(TableStyle([
            ("BACKGROUND",   (0, 0), (0, 0), ACCENT),
            ("BACKGROUND",   (1, 0), (1, 0), LIGHT_TEAL),
            ("VALIGN",       (0, 0), (-1, -1), "MIDDLE"),
            ("LEFTPADDING",  (0, 0), (0, 0), 4),
            ("RIGHTPADDING", (0, 0), (0, 0), 4),
            ("LEFTPADDING",  (1, 0), (1, 0), 6),
            ("TOPPADDING",   (0, 0), (-1, -1), 5),
            ("BOTTOMPADDING",(0, 0), (-1, -1), 5),
        ]))

        # For Q2 and Q7/Q8 (listing questions) give 5 lines; others get 3
        n_lines = 5 if item["n"] in (2, 7, 8, 10) else 3
        lines_table = Table(
            [[""] for _ in range(n_lines)],
            colWidths=[PAGE_W - 2 * MARGIN],
            rowHeights=[7.5 * mm] * n_lines,
        )
        lines_table.setStyle(TableStyle([
            ("LINEBELOW",    (0, 0), (-1, -1), 0.5, RULE_GRAY),
            ("BACKGROUND",   (0, 0), (-1, -1), LIGHT_GRAY),
            ("LEFTPADDING",  (0, 0), (-1, -1), 4),
        ]))

        block = KeepTogether([
            badge,
            Spacer(1, 2 * mm),
            lines_table,
            Spacer(1, 4 * mm),
        ])
        story.append(block)

    # ── SCORE GUIDE ────────────────────────────────────────────────────────
    story.append(Spacer(1, 1 * mm))
    score_data = [
        [Paragraph("<b>Score Guide</b>", ParagraphStyle(
            "SG", parent=styles["Normal"], fontSize=10,
            textColor=DARK_TEAL, fontName="Helvetica-Bold"))],
        [Paragraph(
            "14–15 Outstanding  |  11–13 Strong  |  8–10 Review tributaries &amp; clinical syndromes  |  &lt;8 Re-read the chapter",
            score_style)]
    ]
    score_table = Table(score_data, colWidths=[PAGE_W - 2 * MARGIN])
    score_table.setStyle(TableStyle([
        ("BACKGROUND",   (0, 0), (-1, -1), LIGHT_TEAL),
        ("BOX",          (0, 0), (-1, -1), 1, MID_TEAL),
        ("LEFTPADDING",  (0, 0), (-1, -1), 8),
        ("TOPPADDING",   (0, 0), (-1, -1), 5),
        ("BOTTOMPADDING",(0, 0), (-1, -1), 5),
    ]))
    story.append(score_table)

    # ── PAGE BREAK → ANSWER KEY ────────────────────────────────────────────
    story.append(PageBreak())

    ak_header = Table(
        [[Paragraph("ANSWER KEY", section_style)]],
        colWidths=[PAGE_W - 2 * MARGIN],
        rowHeights=[14 * mm],
    )
    ak_header.setStyle(TableStyle([
        ("BACKGROUND", (0, 0), (-1, -1), DARK_TEAL),
        ("VALIGN",     (0, 0), (-1, -1), "MIDDLE"),
    ]))
    story.append(ak_header)
    story.append(Spacer(1, 4 * mm))
    story.append(Paragraph(
        "Dural Venous Sinuses – Detailed Answers &amp; References",
        ParagraphStyle("AKSub", parent=styles["Normal"], fontSize=11,
                       textColor=MID_TEAL, fontName="Helvetica-Oblique",
                       alignment=TA_CENTER)
    ))
    story.append(Spacer(1, 5 * mm))

    for item in QUESTIONS:
        q_row = Table(
            [[Paragraph(f"Q{item['n']}", q_label_style),
              Paragraph(item["q"], ans_q_style)]],
            colWidths=[10 * mm, PAGE_W - 2 * MARGIN - 10 * mm],
        )
        q_row.setStyle(TableStyle([
            ("BACKGROUND",   (0, 0), (0, 0), ACCENT),
            ("BACKGROUND",   (1, 0), (1, 0), LIGHT_TEAL),
            ("VALIGN",       (0, 0), (-1, -1), "MIDDLE"),
            ("LEFTPADDING",  (0, 0), (0, 0), 4),
            ("LEFTPADDING",  (1, 0), (1, 0), 6),
            ("TOPPADDING",   (0, 0), (-1, -1), 4),
            ("BOTTOMPADDING",(0, 0), (-1, -1), 4),
        ]))

        # Replace \n in answers with <br/> for ReportLab
        ans_html = item["a"].replace("\n", "<br/>")
        ans_box = Table(
            [[Paragraph(f"<b>Answer:</b> {ans_html}", ans_text_style)],
             [Paragraph(f"Reference: {item['ref']}", ref_style)]],
            colWidths=[PAGE_W - 2 * MARGIN],
        )
        ans_box.setStyle(TableStyle([
            ("BACKGROUND",   (0, 0), (-1, -1), ANSWER_BG),
            ("LINEAFTER",    (0, 0), (0, -1), 3, ANSWER_LINE),
            ("LEFTPADDING",  (0, 0), (-1, -1), 8),
            ("TOPPADDING",   (0, 0), (-1, -1), 4),
            ("BOTTOMPADDING",(0, 0), (-1, -1), 4),
            ("BOX",          (0, 0), (-1, -1), 0.5, RULE_GRAY),
        ]))

        block = KeepTogether([
            q_row,
            ans_box,
            Spacer(1, 4 * mm),
        ])
        story.append(block)

    # ── SOURCES ────────────────────────────────────────────────────────────
    story.append(HRFlowable(width="100%", thickness=0.5, color=RULE_GRAY))
    story.append(Spacer(1, 2 * mm))
    story.append(Paragraph(
        "Sources: Gray's Anatomy for Students (Table 8.3) · "
        "Color Atlas of Human Anatomy Vol. 2 (p. 134) · "
        "Harrison's Principles of Internal Medicine 22E · "
        "Adams &amp; Victor's Principles of Neurology 12th Ed.",
        ParagraphStyle("FootNote", parent=styles["Normal"], fontSize=7.5,
                       textColor=colors.HexColor("#888888"),
                       fontName="Helvetica-Oblique", alignment=TA_CENTER)
    ))

    doc.build(story, onFirstPage=header_footer, onLaterPages=header_footer,
              canvasmaker=NumberedCanvas)
    print("PDF created successfully.")


if __name__ == "__main__":
    import os
    os.makedirs("/home/daytona/workspace/dvs-quiz", exist_ok=True)
    build_pdf("/home/daytona/workspace/dvs-quiz/Dural_Venous_Sinuses_Quiz.pdf")
Running Command

python3 /home/daytona/workspace/dvs-quiz/generate_dvs_quiz.py

Running Command

ls -lh /home/daytona/workspace/dvs-quiz/

Your PDF is ready. Here's what's included:
Page 1-2 - Quiz Sheet (15 Questions):
  • Name / Date / Score line at the top
  • All 15 questions in teal-themed cards (burnt orange badge + teal background)
  • Answer lines per question - more lines for listing/enumeration questions (Q2, Q7, Q8, Q10)
  • Score guide at the bottom
Final pages - Answer Key:
  • Each question repeated with full detailed answer in a green-tinted box with a left green border
  • Textbook reference cited under every answer (Gray's Anatomy, Color Atlas, Harrison's, Adams & Victor's)
  • Teal color scheme throughout to distinguish it from the mastication quiz

Dural Venous Sinuses Quiz

PDF Document · PDF

Summarizer whole of upper limb on one shot

Finding Sources
Finding Sources
Reading File
Finding Sources
Finding Sources
Finding Sources
Finding Sources
Reading File
Reading File
This covers the complete upper limb in one shot across 10 sections:
  1. Bones - shoulder girdle, humerus, forearm, carpals (with mnemonic), hand
  2. Joints - SC, AC, glenohumeral, elbow, radioulnar, wrist, carpal tunnel
  3. Muscles - pectoral, deltoid, rotator cuff (SITS), arm (ant/post), forearm (ant/post), intrinsic hand (thenar, hypothenar, lumbricals, interossei)
  4. Brachial Plexus - full RTDCB breakdown with mnemonic, all branches
  5. Nerves - axillary, musculocutaneous, radial, median, ulnar - supplies + injury signs
  6. Blood supply - full arterial tree from subclavian to palmar arches; superficial veins (cephalic, basilic, median cubital)
  7. Spaces & openings - quadrangular space, triangular spaces, axilla, cubital fossa, carpal tunnel, Guyon's canal
  8. Lymphatics - 5 axillary node groups
  9. Dermatomes - C5 to T1
  10. Clinical correlations - 13 key conditions with nerve/sign
Would you like this exported as a PDF revision sheet or a quiz on any section?

Generate a printable PDF summary card of the upper limb for quick revision

Writing File

~/upper-limb-summary/generate_summary.py

from reportlab.lib.pagesizes import A4
from reportlab.lib import colors
from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
from reportlab.lib.units import mm
from reportlab.platypus import (
    SimpleDocTemplate, Paragraph, Spacer, HRFlowable,
    Table, TableStyle, PageBreak, KeepTogether
)
from reportlab.lib.enums import TA_CENTER, TA_LEFT
from reportlab.pdfgen import canvas

# ── Palette ──────────────────────────────────────────────────────────────────
NAVY        = colors.HexColor("#0F2D4A")
ROYAL       = colors.HexColor("#1B5EA8")
SKY         = colors.HexColor("#C8DEF5")
LIGHT_SKY   = colors.HexColor("#E8F2FC")
ORANGE      = colors.HexColor("#C05A20")
GREEN       = colors.HexColor("#1A6B3C")
LIGHT_GREEN = colors.HexColor("#E6F4EC")
PURPLE      = colors.HexColor("#5C2D91")
LIGHT_PURP  = colors.HexColor("#EDE7F6")
RED         = colors.HexColor("#B71C1C")
LIGHT_RED   = colors.HexColor("#FDECEA")
YELLOW_BG   = colors.HexColor("#FFF9E6")
GRAY_BG     = colors.HexColor("#F5F5F5")
RULE        = colors.HexColor("#CCCCCC")
WHITE       = colors.white

PAGE_W, PAGE_H = A4
M = 14 * mm   # margin
CW = PAGE_W - 2 * M  # content width

# ── Canvas helpers ───────────────────────────────────────────────────────────
class NumberedCanvas(canvas.Canvas):
    def __init__(self, *args, **kwargs):
        canvas.Canvas.__init__(self, *args, **kwargs)
        self._pages = []

    def showPage(self):
        self._pages.append(dict(self.__dict__))
        self._startPage()

    def save(self):
        n = len(self._pages)
        for s in self._pages:
            self.__dict__.update(s)
            self._draw_footer(n)
            canvas.Canvas.showPage(self)
        canvas.Canvas.save(self)

    def _draw_footer(self, total):
        pg = self._pageNumber
        self.setFont("Helvetica", 7.5)
        self.setFillColor(colors.HexColor("#888888"))
        self.drawRightString(PAGE_W - M, 9 * mm, f"Page {pg} of {total}")
        self.drawString(M, 9 * mm, "Upper Limb — Quick Revision Summary")


def page_header(c, doc):
    c.saveState()
    c.setFillColor(NAVY)
    c.rect(0, PAGE_H - 13 * mm, PAGE_W, 13 * mm, fill=1, stroke=0)
    c.setFillColor(WHITE)
    c.setFont("Helvetica-Bold", 11)
    c.drawString(M, PAGE_H - 8.5 * mm, "UPPER LIMB")
    c.setFont("Helvetica", 9)
    c.drawRightString(PAGE_W - M, PAGE_H - 8.5 * mm, "Anatomy Quick Revision Card")
    c.setStrokeColor(RULE)
    c.setLineWidth(0.4)
    c.line(M, 13 * mm, PAGE_W - M, 13 * mm)
    c.restoreState()


# ── Style helpers ─────────────────────────────────────────────────────────────
S = getSampleStyleSheet()

def sec_head(text, bg=NAVY, fg=WHITE):
    """Full-width coloured section header."""
    p = Paragraph(f"<b>{text}</b>",
                  ParagraphStyle("sh", parent=S["Normal"], fontSize=9.5,
                                 textColor=fg, fontName="Helvetica-Bold",
                                 leading=13, leftPadding=6, topPadding=3,
                                 bottomPadding=3))
    t = Table([[p]], colWidths=[CW])
    t.setStyle(TableStyle([
        ("BACKGROUND", (0,0), (-1,-1), bg),
        ("TOPPADDING",  (0,0), (-1,-1), 0),
        ("BOTTOMPADDING",(0,0),(-1,-1), 0),
        ("LEFTPADDING", (0,0), (-1,-1), 0),
    ]))
    return t

def sub_head(text, bg=ROYAL):
    p = Paragraph(f"<b>{text}</b>",
                  ParagraphStyle("subh", parent=S["Normal"], fontSize=8.5,
                                 textColor=WHITE, fontName="Helvetica-Bold",
                                 leading=12))
    t = Table([[p]], colWidths=[CW])
    t.setStyle(TableStyle([
        ("BACKGROUND",  (0,0),(-1,-1), bg),
        ("TOPPADDING",  (0,0),(-1,-1), 3),
        ("BOTTOMPADDING",(0,0),(-1,-1), 3),
        ("LEFTPADDING", (0,0),(-1,-1), 6),
    ]))
    return t

def body(text, size=8, color=colors.black, indent=0, bg=None):
    style = ParagraphStyle("body", parent=S["Normal"], fontSize=size,
                           textColor=color, fontName="Helvetica",
                           leading=11.5, leftIndent=indent)
    p = Paragraph(text, style)
    if bg:
        t = Table([[p]], colWidths=[CW])
        t.setStyle(TableStyle([
            ("BACKGROUND",(0,0),(-1,-1), bg),
            ("TOPPADDING",(0,0),(-1,-1), 2),
            ("BOTTOMPADDING",(0,0),(-1,-1), 2),
            ("LEFTPADDING",(0,0),(-1,-1), 6),
        ]))
        return t
    return p

def mini_table(headers, rows, col_widths, header_bg=ROYAL, row_bg=WHITE, alt_bg=LIGHT_SKY):
    h_style = ParagraphStyle("th", parent=S["Normal"], fontSize=7.5,
                              textColor=WHITE, fontName="Helvetica-Bold", leading=10)
    c_style = ParagraphStyle("td", parent=S["Normal"], fontSize=7.5,
                              textColor=colors.black, fontName="Helvetica", leading=10)
    data = [[Paragraph(h, h_style) for h in headers]]
    for i, row in enumerate(rows):
        data.append([Paragraph(str(c), c_style) for c in row])
    t = Table(data, colWidths=col_widths)
    style_cmds = [
        ("BACKGROUND", (0,0), (-1,0), header_bg),
        ("VALIGN",     (0,0), (-1,-1), "TOP"),
        ("TOPPADDING", (0,0), (-1,-1), 2),
        ("BOTTOMPADDING",(0,0),(-1,-1), 2),
        ("LEFTPADDING",(0,0),(-1,-1), 3),
        ("GRID",       (0,0), (-1,-1), 0.3, RULE),
    ]
    for i in range(1, len(rows)+1):
        bg = alt_bg if i % 2 == 0 else row_bg
        style_cmds.append(("BACKGROUND",(0,i),(-1,i), bg))
    t.setStyle(TableStyle(style_cmds))
    return t

def bullet(items, color=NAVY, size=8):
    out = []
    for item in items:
        out.append(Paragraph(f"<font color='#{color.hexval()[2:]}'>&#x25CF;</font> {item}",
                              ParagraphStyle("bl", parent=S["Normal"], fontSize=size,
                                             fontName="Helvetica", leading=11.5, leftIndent=8)))
    return out

def sp(h=2): return Spacer(1, h*mm)

def colored_box(content_list, bg=LIGHT_SKY, border=ROYAL):
    inner = Table([[item] for item in content_list], colWidths=[CW - 6])
    inner.setStyle(TableStyle([
        ("TOPPADDING",(0,0),(-1,-1), 1),
        ("BOTTOMPADDING",(0,0),(-1,-1), 1),
        ("LEFTPADDING",(0,0),(-1,-1), 0),
        ("RIGHTPADDING",(0,0),(-1,-1), 0),
    ]))
    outer = Table([[inner]], colWidths=[CW])
    outer.setStyle(TableStyle([
        ("BACKGROUND",(0,0),(-1,-1), bg),
        ("BOX",(0,0),(-1,-1), 1, border),
        ("TOPPADDING",(0,0),(-1,-1), 3),
        ("BOTTOMPADDING",(0,0),(-1,-1), 3),
        ("LEFTPADDING",(0,0),(-1,-1), 4),
    ]))
    return outer

# ══════════════════════════════════════════════════════════════════════════════
# STORY
# ══════════════════════════════════════════════════════════════════════════════
def build():
    import os; os.makedirs("/home/daytona/workspace/upper-limb-summary", exist_ok=True)
    out = "/home/daytona/workspace/upper-limb-summary/Upper_Limb_Revision_Card.pdf"
    doc = SimpleDocTemplate(out, pagesize=A4,
                            leftMargin=M, rightMargin=M,
                            topMargin=18*mm, bottomMargin=18*mm,
                            title="Upper Limb — Quick Revision Summary")
    story = []

    # ── COVER TITLE ──────────────────────────────────────────────────────────
    story += [
        sp(6),
        Paragraph("UPPER LIMB", ParagraphStyle("title", parent=S["Title"],
                  fontSize=26, textColor=NAVY, fontName="Helvetica-Bold",
                  alignment=TA_CENTER, spaceAfter=2)),
        Paragraph("Complete Quick Revision Summary Card",
                  ParagraphStyle("sub", parent=S["Normal"], fontSize=12,
                                 textColor=ROYAL, fontName="Helvetica",
                                 alignment=TA_CENTER)),
        sp(2),
        HRFlowable(width="50%", thickness=2, color=ORANGE, hAlign="CENTER"),
        sp(4),
        Paragraph("Covers: Bones · Joints · Muscles · Brachial Plexus · Nerves · "
                  "Blood Supply · Spaces · Dermatomes · Clinical Correlations",
                  ParagraphStyle("cov", parent=S["Normal"], fontSize=9,
                                 textColor=colors.HexColor("#555555"),
                                 fontName="Helvetica-Oblique", alignment=TA_CENTER)),
        sp(6),
    ]

    # ═══════════════════════════════════════════════════════════════════════
    # SECTION 1 — BONES
    # ═══════════════════════════════════════════════════════════════════════
    story += [sec_head("1 · BONES"), sp(1)]

    # two-column: shoulder girdle | arm + forearm
    col = CW / 2 - 2

    sg_items = [
        Paragraph("<b>Shoulder Girdle</b>", ParagraphStyle("sh2", parent=S["Normal"], fontSize=8, textColor=NAVY, fontName="Helvetica-Bold")),
        body("• <b>Clavicle</b>: S-shaped; only bony UL-axial link; medial 2/3 convex ant, lat 1/3 concave"),
        body("• <b>Scapula</b>: spine, acromion, coracoid, glenoid cavity, supraspinous/infraspinous/subscapular fossae"),
    ]
    arm_items = [
        Paragraph("<b>Arm & Forearm</b>", ParagraphStyle("sh2", parent=S["Normal"], fontSize=8, textColor=NAVY, fontName="Helvetica-Bold")),
        body("• <b>Humerus</b>: head, anatomical/surgical necks, GT/LT, deltoid tuberosity, radial groove (radial n. + profunda brachii), med/lat epicondyles, capitulum (radius), trochlea (ulna)"),
        body("• <b>Radius</b>: lateral; head, radial tuberosity (biceps), styloid"),
        body("• <b>Ulna</b>: medial; olecranon, coronoid process, trochlear notch"),
    ]

    two_col = Table([[sg_items, arm_items]], colWidths=[col, col])
    two_col.setStyle(TableStyle([
        ("VALIGN",(0,0),(-1,-1),"TOP"),
        ("TOPPADDING",(0,0),(-1,-1),2),("BOTTOMPADDING",(0,0),(-1,-1),2),
        ("LEFTPADDING",(0,0),(-1,-1),3),
        ("LINEAFTER",(0,0),(0,-1),0.3,RULE),
    ]))
    story += [two_col, sp(1)]

    # Carpals
    story += [
        sub_head("Carpals — Proximal → Distal", bg=GREEN),
        body("<b>Proximal row</b>: Scaphoid · Lunate · Triquetrum · Pisiform"),
        body("<b>Distal row</b>: Trapezium · Trapezoid · Capitate · Hamate"),
        body('<b>Mnemonic</b>: <font color="#1A6B3C"><b>"She Looks Too Pretty, Try To Catch Her"</b></font>', color=GREEN),
        body("<b>Scaphoid</b>: most commonly fractured carpal; check anatomical snuffbox tenderness; risk of AVN"),
        sp(2),
    ]

    # ═══════════════════════════════════════════════════════════════════════
    # SECTION 2 — JOINTS
    # ═══════════════════════════════════════════════════════════════════════
    story += [sec_head("2 · JOINTS"), sp(1)]

    jt_headers = ["Joint", "Type", "Key Features / Ligaments"]
    jt_rows = [
        ["Sternoclavicular", "Synovial (saddle)", "Only true UL-axial joint; has intra-articular disc; ant/post SC + costoclavicular ligs"],
        ["Acromioclavicular", "Plane synovial", "AC lig + coracoclavicular lig (conoid + trapezoid); 'shoulder separation'"],
        ["Glenohumeral", "Ball & socket", "Most mobile & most dislocated; glenoid labrum deepens socket; SITS muscles + GH ligs stabilise"],
        ["Elbow", "Hinge synovial", "Trochlea + capitulum; UCL (medial) + RCL (lateral); carrying angle ~170° M / ~167° F"],
        ["Proximal/Distal radioulnar", "Pivot synovial", "Pronation/supination; interosseous membrane connects radius & ulna"],
        ["Radiocarpal (wrist)", "Ellipsoid synovial", "Distal radius + ulnar disc vs scaphoid/lunate/triquetrum; flex/ext/radial & ulnar deviation"],
    ]
    jt_cw = [CW*0.18, CW*0.17, CW*0.65]
    story += [mini_table(jt_headers, jt_rows, jt_cw), sp(2)]

    # Cubital fossa + carpal tunnel side by side
    cf = [
        sub_head("Cubital Fossa", bg=PURPLE),
        body("Boundaries: brachioradialis (lat), pronator teres (med), epicondyle line (sup)"),
        body("Contents (med→lat): <b>T A N</b>"),
        body("  T = Tendon of biceps brachii"),
        body("  A = brachial Artery (→ radial + ulnar)"),
        body("  N = median Nerve"),
        body("(Radial nerve lies just outside, lateral border)"),
    ]
    ct = [
        sub_head("Carpal Tunnel", bg=PURPLE),
        body("Roof: flexor retinaculum (transverse carpal lig)"),
        body("Floor: carpal bones"),
        body("Contents (10 structures):"),
        body("  4× FDS tendons + 4× FDP tendons"),
        body("  1× FPL tendon + <b>median nerve</b>"),
        body("CTS: compress median n. → thenar wasting + lat 3.5 finger numbness"),
    ]
    twobox = Table([[cf, ct]], colWidths=[CW/2 - 2, CW/2 - 2])
    twobox.setStyle(TableStyle([
        ("VALIGN",(0,0),(-1,-1),"TOP"),
        ("LINEAFTER",(0,0),(0,-1),0.3,RULE),
        ("LEFTPADDING",(0,0),(-1,-1),2),
    ]))
    story += [twobox, sp(2)]

    # ═══════════════════════════════════════════════════════════════════════
    # SECTION 3 — MUSCLES
    # ═══════════════════════════════════════════════════════════════════════
    story.append(PageBreak())
    story += [sec_head("3 · MUSCLES"), sp(1)]

    # Rotator cuff highlight box
    rc_content = [
        Paragraph("<b>ROTATOR CUFF — SITS</b>", ParagraphStyle("rc", parent=S["Normal"],
                  fontSize=9, textColor=ORANGE, fontName="Helvetica-Bold")),
    ]
    rc_rows = [
        ["<b>S</b>upraspinatus", "Initiates abduction 0–15°", "Suprascapular (C5,C6)", "Most commonly torn"],
        ["<b>I</b>nfraspinatus", "Lateral rotation", "Suprascapular (C5,C6)", "—"],
        ["<b>T</b>eres minor", "Lateral rotation", "Axillary (C5,C6)", "—"],
        ["<b>S</b>ubscapularis", "Medial rotation", "Upper/lower subscapular", "Only anterior muscle"],
    ]
    rc_cw = [CW*0.22, CW*0.28, CW*0.28, CW*0.22]
    rc_content.append(mini_table(["Muscle","Action","Nerve","Note"], rc_rows, rc_cw,
                                  header_bg=ORANGE, alt_bg=YELLOW_BG))
    story += [colored_box(rc_content, bg=YELLOW_BG, border=ORANGE), sp(2)]

    # Arm muscles table
    story += [sub_head("Arm Compartments"), sp(1)]
    arm_rows = [
        ["Biceps brachii", "Anterior", "Flex elbow, supinate forearm, weak shoulder flex", "Musculocutaneous C5,C6"],
        ["Brachialis", "Anterior", "Pure elbow flexion ('workhorse')", "Musculocutaneous + radial C5,C6"],
        ["Coracobrachialis", "Anterior", "Arm flexion + adduction", "Musculocutaneous C6,C7"],
        ["Triceps brachii", "Posterior", "Elbow extension; long head extends/adducts arm", "Radial C6–C8"],
        ["Anconeus", "Posterior", "Assists elbow extension", "Radial C7,C8"],
    ]
    arm_cw = [CW*0.2, CW*0.13, CW*0.42, CW*0.25]
    story += [mini_table(["Muscle","Compartment","Action","Nerve"], arm_rows, arm_cw), sp(2)]

    # Forearm muscles — compact two-panel
    story += [sub_head("Forearm — Anterior (Flexors/Pronators)"), sp(1)]
    fa_ant = [
        body("<b>Superficial</b> (lateral epicondyle/medial epicondyle origin):"),
        body("Pronator teres · Flexor carpi radialis · Palmaris longus · Flexor carpi ulnaris · FDS", indent=8),
        body("<b>Deep</b>: FDP · FPL · Pronator quadratus", indent=0),
        body("FDS → flexes PIP | FDP → flexes DIP | FPL → flexes thumb IP", color=PURPLE),
    ]
    story += fa_ant + [sp(1)]

    story += [sub_head("Forearm — Posterior (Extensors/Supinators)"), sp(1)]
    fa_post = [
        body("<b>Superficial</b>: Brachioradialis · ECRL · ECRB · ED · EDM · ECU · Anconeus"),
        body("<b>Deep</b>: Supinator · APL · EPB · EPL · Extensor indicis", indent=0),
    ]
    story += fa_post + [sp(2)]

    # Intrinsic hand
    story += [sub_head("Intrinsic Hand Muscles"), sp(1)]
    hand_rows = [
        ["Thenar (3)", "Abd pollicis brevis, Opponens pollicis, FPB", "Opposition/abduction/flexion of thumb", "Recurrent median nerve"],
        ["Hypothenar (3)", "Abd digiti minimi, Opponens DM, FDM", "Little finger movements", "Deep branch ulnar"],
        ["Lumbricals (4)", "1st & 2nd = median; 3rd & 4th = ulnar", "Flex MCP, extend IP ('intrinsic plus')", "Median + Ulnar"],
        ["Dorsal interossei (4)", "Ulnar nerve", "Abduct fingers — DAB", "Ulnar"],
        ["Palmar interossei (3)", "Ulnar nerve", "Adduct fingers — PAD", "Ulnar"],
        ["Adductor pollicis", "Ulnar (deep branch)", "Adducts thumb; Froment's sign if lost", "Ulnar"],
    ]
    hand_cw = [CW*0.18, CW*0.27, CW*0.33, CW*0.22]
    story += [mini_table(["Group","Muscles","Action","Nerve"], hand_rows, hand_cw), sp(2)]

    # ═══════════════════════════════════════════════════════════════════════
    # SECTION 4 — BRACHIAL PLEXUS
    # ═══════════════════════════════════════════════════════════════════════
    story.append(PageBreak())
    story += [sec_head("4 · BRACHIAL PLEXUS"), sp(1)]

    story += [
        colored_box([
            Paragraph('<b>Mnemonic:</b> <font color="#C05A20"><b>R</b></font>obert '
                      '<font color="#C05A20"><b>T</b></font>aylor '
                      '<font color="#C05A20"><b>D</b></font>rinks '
                      '<font color="#C05A20"><b>C</b></font>old '
                      '<font color="#C05A20"><b>B</b></font>eer  →  '
                      'Roots · Trunks · Divisions · Cords · Branches',
                      ParagraphStyle("mn", parent=S["Normal"], fontSize=9,
                                     fontName="Helvetica-Bold", textColor=NAVY)),
        ], bg=YELLOW_BG, border=ORANGE),
        sp(2),
    ]

    bp_rows = [
        ["Roots", "C5, C6, C7, C8, T1 (anterior rami)"],
        ["Trunks", "Superior (C5+C6) · Middle (C7) · Inferior (C8+T1)"],
        ["Divisions", "Each trunk → anterior + posterior (6 divisions total)"],
        ["Cords", "Lateral (ant sup+mid) · Posterior (all post) · Medial (ant inf)\n— named by relation to axillary artery —"],
        ["Terminal branches", "Musculocutaneous · Axillary · Radial · Median (2 roots) · Ulnar"],
    ]
    bp_cw = [CW*0.2, CW*0.8]
    story += [mini_table(["Level","Components"], bp_rows, bp_cw), sp(1)]

    story += [sub_head("Key Pre-terminal Branches", bg=colors.HexColor("#37474F")), sp(1)]
    pre = [
        body("<b>From Roots</b>: Dorsal scapular (C5) → rhomboids/levator scap; Long thoracic (C5-C7) → serratus anterior"),
        body("<b>From Superior Trunk</b>: Suprascapular → supraspinatus/infraspinatus; Nerve to subclavius"),
        body("<b>From Lateral Cord</b>: Lateral pectoral; Musculocutaneous; Lateral root of median"),
        body("<b>From Medial Cord</b>: Medial pectoral; Med cut. nerves arm/forearm; Medial root of median; Ulnar"),
        body("<b>From Posterior Cord</b>: Upper/lower subscapular; Thoracodorsal (latissimus dorsi); Axillary; Radial"),
    ]
    story += pre + [sp(2)]

    # ═══════════════════════════════════════════════════════════════════════
    # SECTION 5 — NERVES (injury signs)
    # ═══════════════════════════════════════════════════════════════════════
    story += [sec_head("5 · NERVE INJURIES — Signs & Mnemonics"), sp(1)]

    nerve_data = [
        {
            "name": "AXILLARY NERVE  (C5, C6)",
            "supplies": "Deltoid, teres minor; skin over lateral arm",
            "injured": "Surgical neck # humerus; anterior GH dislocation",
            "signs": "Loss of shoulder abduction; flat shoulder; numbness 'regimental badge' area",
            "bg": SKY, "border": ROYAL
        },
        {
            "name": "MUSCULOCUTANEOUS NERVE  (C5–C7)",
            "supplies": "Coracobrachialis, biceps, brachialis; skin lateral forearm",
            "injured": "Axilla injury (rare)",
            "signs": "Weak elbow flexion + supination; numbness lateral forearm",
            "bg": LIGHT_SKY, "border": ROYAL
        },
        {
            "name": "RADIAL NERVE  (C5–C8, T1)",
            "supplies": "All posterior compartments arm+forearm; skin posterior arm/forearm + dorsum hand lat 3.5",
            "injured": "Mid-shaft humeral # (radial groove); Saturday night palsy",
            "signs": "WRIST DROP — loss wrist + finger extension; loss brachioradialis; triceps spared (branches above groove); dorsum hand numbness",
            "bg": LIGHT_GREEN, "border": GREEN
        },
        {
            "name": "MEDIAN NERVE  (C6–C8, T1)",
            "supplies": "Most ant forearm; LOAF hand muscles; palmar lat 3.5 digits",
            "injured": "Carpal tunnel (low); supracondylar # (high)",
            "signs": "HIGH: Hand of benediction; ape hand (thenar wasting); can't flex index/middle  |  LOW (CTS): Thenar wasting; opposition lost; lat 3.5 finger numbness; +ve Tinel's & Phalen's",
            "bg": LIGHT_PURP, "border": PURPLE
        },
        {
            "name": "ULNAR NERVE  (C7–T1)",
            "supplies": "FCU, medial FDP; ALL intrinsic hand except LOAF; skin medial 1.5 digits",
            "injured": "Medial epicondyle # / cubital tunnel; Guyon's canal (wrist)",
            "signs": "CLAW HAND (ring + little fingers); ulnar paradox; loss finger ABduction; Froment's sign (FPL compensates weak adductor pollicis)",
            "bg": LIGHT_RED, "border": RED
        },
    ]

    for nd in nerve_data:
        content = [
            Paragraph(f"<b>{nd['name']}</b>",
                      ParagraphStyle("nh", parent=S["Normal"], fontSize=8.5,
                                     textColor=NAVY, fontName="Helvetica-Bold")),
            body(f"<b>Supplies:</b> {nd['supplies']}"),
            body(f"<b>Injured by:</b> {nd['injured']}"),
            body(f"<b>Signs:</b> {nd['signs']}", color=RED),
        ]
        story += [colored_box(content, bg=nd["bg"], border=nd["border"]), sp(1.5)]

    story += [
        colored_box([
            Paragraph("<b>LOAF mnemonic</b> (muscles lost in LOW median nerve injury):",
                      ParagraphStyle("loaf", parent=S["Normal"], fontSize=8.5,
                                     textColor=PURPLE, fontName="Helvetica-Bold")),
            body("<b>L</b>umbricals 1 & 2  ·  <b>O</b>pponens pollicis  ·  <b>A</b>bductor pollicis brevis  ·  <b>F</b>lexor pollicis brevis"),
        ], bg=LIGHT_PURP, border=PURPLE),
        sp(2),
    ]

    # ═══════════════════════════════════════════════════════════════════════
    # SECTION 6 — BLOOD SUPPLY
    # ═══════════════════════════════════════════════════════════════════════
    story.append(PageBreak())
    story += [sec_head("6 · BLOOD SUPPLY"), sp(1)]

    art_content = [
        sub_head("Arterial Tree", bg=colors.HexColor("#B71C1C")),
        body("Subclavian a. → <b>Axillary a.</b> (3 parts divided by pec minor)"),
        body("  1st part: Superior thoracic a.", indent=8),
        body("  2nd part: Thoracoacromial · Lateral thoracic", indent=8),
        body("  3rd part: Subscapular (→circumflex scapular + thoracodorsal) · Ant/Post circumflex humeral", indent=8),
        body("→ <b>Brachial a.</b> (main artery of arm)"),
        body("  → Profunda brachii (radial groove; with radial nerve)", indent=8),
        body("  → Bifurcates in <b>cubital fossa</b> →", indent=8),
        body("      <b>Radial a.</b> → superficial palmar branch → deep palmar arch (mainly radial)", indent=16),
        body("      <b>Ulnar a.</b> → ant/post interosseous aa. → superficial palmar arch (mainly ulnar)", indent=16),
        sp(1),
        body("<b>Superficial palmar arch</b> (mainly ulnar) → common digital arteries → digits 2–5"),
        body("<b>Deep palmar arch</b> (mainly radial) → palmar metacarpal arteries"),
    ]
    story += art_content + [sp(2)]

    vein_content = [
        sub_head("Superficial Veins (Clinically Important)", bg=ROYAL),
        body("• <b>Cephalic vein</b>: lateral side; dorsal venous arch → lateral forearm → deltopectoral groove → axillary vein"),
        body("• <b>Basilic vein</b>: medial side → pierces deep fascia mid-arm → becomes axillary vein"),
        body("• <b>Median cubital vein</b>: connects cephalic + basilic at <b>cubital fossa</b> — standard venepuncture site"),
    ]
    story += vein_content + [sp(2)]

    # ═══════════════════════════════════════════════════════════════════════
    # SECTION 7 — KEY SPACES
    # ═══════════════════════════════════════════════════════════════════════
    story += [sec_head("7 · KEY SPACES & OPENINGS"), sp(1)]
    sp_rows = [
        ["Quadrangular space", "Teres minor (sup), teres major (inf), long head triceps (med), surgical neck (lat)", "Axillary nerve + post circumflex humeral a."],
        ["Triangular space", "Teres minor (sup), teres major (inf), long head triceps (lat)", "Circumflex scapular artery"],
        ["Triangular interval", "Teres major (sup), long head triceps (med), lateral head triceps (lat)", "Radial nerve + profunda brachii a."],
        ["Axilla", "Clavicle (ant), scapula (post), chest wall (med), humerus (lat)", "Brachial plexus cords, axillary a. & v., axillary lymph nodes"],
        ["Guyon's canal", "Pisiform (med), hook of hamate (lat), palmar carpal lig (roof)", "Ulnar nerve + ulnar artery"],
    ]
    sp_cw = [CW*0.2, CW*0.45, CW*0.35]
    story += [mini_table(["Space","Boundaries","Contents"], sp_rows, sp_cw), sp(2)]

    # ═══════════════════════════════════════════════════════════════════════
    # SECTION 8 — DERMATOMES
    # ═══════════════════════════════════════════════════════════════════════
    story += [sec_head("8 · DERMATOMES"), sp(1)]
    derm_rows = [
        ["C5", "Lateral arm (regimental badge area)", "Axillary nerve"],
        ["C6", "Lateral forearm, thumb, index finger", "Musculocutaneous / median"],
        ["C7", "Middle finger", "Median (middle = C7)"],
        ["C8", "Ring & little finger, medial forearm", "Ulnar"],
        ["T1", "Medial arm", "Medial cutaneous nerve of arm"],
    ]
    derm_cw = [CW*0.1, CW*0.5, CW*0.4]
    story += [mini_table(["Root","Region","Nerve"], derm_rows, derm_cw), sp(2)]

    # ═══════════════════════════════════════════════════════════════════════
    # SECTION 9 — CLINICAL CORRELATIONS
    # ═══════════════════════════════════════════════════════════════════════
    story += [sec_head("9 · CLINICAL CORRELATIONS", bg=RED), sp(1)]
    clin_rows = [
        ["Surgical neck # humerus", "Axillary n.", "Loss abduction; flat shoulder; regimental badge numbness"],
        ["Mid-shaft humeral #", "Radial n. (radial groove)", "Wrist drop; spared triceps"],
        ["Supracondylar # (children)", "Ant interosseous n. (median)", "Cannot make 'OK sign'"],
        ["Medial epicondyle #", "Ulnar n.", "Claw hand (ring + little)"],
        ["Anterior GH dislocation", "Axillary n.", "Same as surgical neck #"],
        ["Winged scapula", "Long thoracic n. (C5-C7)", "Serratus ant. palsy; scapula protrudes on wall push"],
        ["Carpal tunnel syndrome", "Median n. at wrist", "Thenar wasting; lat 3.5 finger numbness; Tinel's; Phalen's"],
        ["Erb's palsy (C5, C6)", "Upper brachial plexus", "Waiter's tip: arm adducted/medially rotated, elbow extended, forearm pronated"],
        ["Klumpke's palsy (C8, T1)", "Lower brachial plexus", "Claw hand; Horner's syndrome if sympathetics involved"],
        ["Rotator cuff tear", "Supraspinatus (most common)", "Painful arc 60–120°; weak abduction"],
        ["Scaphoid #", "Avascular (not nerve)", "Anatomical snuffbox tenderness; risk of AVN of proximal fragment"],
        ["Dupuytren's contracture", "Palmar fascia (not nerve)", "Flexion contracture ring > little finger; palmar nodule"],
    ]
    clin_cw = [CW*0.25, CW*0.22, CW*0.53]
    story += [mini_table(["Condition","Nerve/Structure","Key Sign / Note"], clin_rows, clin_cw,
                          header_bg=RED, alt_bg=LIGHT_RED), sp(2)]

    # ═══════════════════════════════════════════════════════════════════════
    # SOURCES
    # ═══════════════════════════════════════════════════════════════════════
    story += [
        HRFlowable(width="100%", thickness=0.4, color=RULE),
        sp(1),
        Paragraph(
            "Sources: Gray's Anatomy for Students (Ch. 7) · Rosen's Emergency Medicine · "
            "Neuroanatomy through Clinical Cases 3rd Ed. · Color Atlas of Human Anatomy Vol. 2",
            ParagraphStyle("src", parent=S["Normal"], fontSize=7,
                           textColor=colors.HexColor("#888888"),
                           fontName="Helvetica-Oblique", alignment=TA_CENTER)),
    ]

    doc.build(story, onFirstPage=page_header, onLaterPages=page_header,
              canvasmaker=NumberedCanvas)
    print("Done:", out)


if __name__ == "__main__":
    build()
Running Command

python3 /home/daytona/workspace/upper-limb-summary/generate_summary.py

Running Command

ls -lh /home/daytona/workspace/upper-limb-summary/

Your PDF revision card is ready!

Upper Limb Revision Card

PDF Document · PDF


Here's what's packed into the card across 4 pages, color-coded by section:
SectionColorContent
1 · BonesNavy/GreenShoulder girdle, humerus, forearm, carpals with mnemonic
2 · JointsNavy/PurpleAll 6 joints in a table + cubital fossa (TAN) + carpal tunnel side-by-side
3 · MusclesOrange/BlueRotator cuff SITS highlight box, arm, forearm, intrinsic hand tables
4 · Brachial PlexusNavy/OrangeRTDCB mnemonic, full table, all pre-terminal branches
5 · Nerve InjuriesColour-codedOne box per nerve - supplies, injured by, signs; LOAF mnemonic
6 · Blood SupplyRed/BlueFull arterial tree + superficial veins
7 · Key SpacesNavyQuadrangular, triangular, axilla, Guyon's canal
8 · DermatomesNavyC5-T1 table
9 · Clinical CorrelationsRed12 conditions with nerve and key sign
This is a shared conversation. Sign in to Orris to start your own chat.