Create a pdf for me of all the muscles in upper limb with their origin insertion observation action and diagrams
Anatomical diagram of shoulder girdle muscles showing trapezius, rhomboids, levator scapulae, serratus anterior, pectoralis minor from anterior and posterior views, with muscle labels and attachment points on bones, medical textbook style illustration
Anatomical diagram of shoulder joint muscles showing deltoid, supraspinatus, infraspinatus, teres minor, teres major, subscapularis, coracobrachialis with origin and insertion points labeled on humerus and scapula, anterior and posterior views, medical illustration style
400, message: Got more than 4194304 bytes when reading: b'data: {"candidates": [{"content": {"role": "model","parts": [{"inlineData": {"mimeType": "image/png"...'.
We encountered an error while processing your request. Please try again or reach out to us for help.
Create a pdf for me of all the muscles in upper limb with their origin insertion observation action and diagrams
ls /home/daytona/workspace/ 2>/dev/null || echo "workspace empty"
mkdir -p /home/daytona/workspace/upper-limb-muscles && python3 -c "import report…
~/upper-limb-muscles/build_pdf.py
"""
Upper Limb Muscles - Comprehensive PDF Generator
Data sourced from THIEME Atlas of Anatomy & Gray's Anatomy for Students
"""
import os
import io
import requests
from reportlab.lib.pagesizes import A4
from reportlab.lib import colors
from reportlab.lib.units import cm, mm
from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
from reportlab.lib.enums import TA_LEFT, TA_CENTER, TA_JUSTIFY
from reportlab.platypus import (
SimpleDocTemplate, Paragraph, Spacer, Table, TableStyle,
PageBreak, HRFlowable, Image, KeepTogether
)
from reportlab.platypus.flowables import HRFlowable
from reportlab.pdfgen import canvas
from reportlab.graphics.shapes import Drawing, Rect, String, Line, Circle
from reportlab.graphics import renderPDF
OUT = "/home/daytona/workspace/upper-limb-muscles/Upper_Limb_Muscles.pdf"
# ── colour palette ──────────────────────────────────────────────────────────
C_DARK = colors.HexColor("#1a2744") # deep navy
C_MID = colors.HexColor("#2e5fa3") # medium blue
C_LIGHT = colors.HexColor("#d6e4f7") # pale blue fill
C_ACC = colors.HexColor("#c0392b") # red accent
C_GOLD = colors.HexColor("#e67e22") # orange-gold
C_WHITE = colors.white
C_GRAY = colors.HexColor("#f4f6fb") # very light bg
C_HEAD_BG = colors.HexColor("#1a2744")
C_SUB_BG = colors.HexColor("#2e5fa3")
# ── styles ───────────────────────────────────────────────────────────────────
styles = getSampleStyleSheet()
def S(name, **kw):
return ParagraphStyle(name, **kw)
sTitle = S("sTitle",
fontName="Helvetica-Bold", fontSize=28, textColor=C_WHITE,
leading=34, alignment=TA_CENTER)
sSubtitle = S("sSubtitle",
fontName="Helvetica", fontSize=14, textColor=C_LIGHT,
leading=18, alignment=TA_CENTER)
sChapter = S("sChapter",
fontName="Helvetica-Bold", fontSize=16, textColor=C_WHITE,
leading=20, spaceAfter=0, spaceBefore=0)
sMuscle = S("sMuscle",
fontName="Helvetica-Bold", fontSize=13, textColor=C_DARK,
leading=16, spaceAfter=2, spaceBefore=6)
sLabel = S("sLabel",
fontName="Helvetica-Bold", fontSize=9, textColor=C_MID,
leading=11)
sBody = S("sBody",
fontName="Helvetica", fontSize=9, textColor=colors.HexColor("#222222"),
leading=13, spaceAfter=1)
sBodySm = S("sBodySm",
fontName="Helvetica", fontSize=8, textColor=colors.HexColor("#333333"),
leading=11)
sNote = S("sNote",
fontName="Helvetica-Oblique", fontSize=8, textColor=colors.HexColor("#555555"),
leading=10)
sTOC = S("sTOC",
fontName="Helvetica", fontSize=10, textColor=C_DARK,
leading=14, leftIndent=12)
sTOCHead = S("sTOCHead",
fontName="Helvetica-Bold", fontSize=11, textColor=C_MID,
leading=15, spaceBefore=4)
# ── image helper ─────────────────────────────────────────────────────────────
IMG_DIR = "/home/daytona/workspace/upper-limb-muscles/imgs"
os.makedirs(IMG_DIR, exist_ok=True)
def get_img(url, width=7*cm, height=5*cm):
"""Download image and return ReportLab Image flowable, or None on failure."""
fname = os.path.join(IMG_DIR, url.split("/")[-1] + ".png")
if not os.path.exists(fname):
try:
r = requests.get(url, timeout=10)
if r.status_code == 200:
with open(fname, "wb") as f:
f.write(r.content)
else:
return None
except Exception:
return None
try:
img = Image(fname, width=width, height=height, kind="proportional")
return img
except Exception:
return None
# ── muscle data ───────────────────────────────────────────────────────────────
# Structure: { group, muscles: [{name, origin, insertion, actions, innervation,
# observation, img_url}] }
MUSCLES = [
# ════════════════════════════════════════════════════════════
# SECTION 1 – SHOULDER GIRDLE MUSCLES
# ════════════════════════════════════════════════════════════
{
"group": "1. SHOULDER GIRDLE MUSCLES",
"color": C_HEAD_BG,
"muscles": [
{
"name": "Trapezius",
"origin": (
"Descending part: occipital bone (superior nuchal line, external occipital protuberance), "
"spinous processes of all cervical vertebrae (via nuchal ligament).\n"
"Transverse part: broad aponeurosis at T1–T4 spinous processes.\n"
"Ascending part: spinous processes of T5–T12."
),
"insertion": (
"Lateral third of clavicle (descending part); acromion (transverse part); "
"scapular spine (ascending part)."
),
"actions": (
"Descending: draws scapula obliquely upward, rotates glenoid cavity superiorly; "
"tilts head ipsilaterally and rotates to opposite side.\n"
"Transverse: retracts (draws) scapula medially.\n"
"Ascending: draws scapula medially downward.\n"
"Whole muscle: steadies scapula on thorax."
),
"innervation": "Accessory nerve (CN XI); cervical plexus C2, C4.",
"observation": (
"Most superficial muscle of the back. Its fibres converge from skull and vertebral column "
"onto the shoulder girdle. Upper fibres are responsible for 'shrugging'. "
"Paralysis (CN XI lesion) causes drooping shoulder and inability to shrug. "
"Visible as a diamond-shaped muscle in the upper back."
),
"img_url": "https://cdn.orris.care/cdss_images/cb3f86d813f4e3487931665a18ebe15c14d7e4ce65c5a1b29612dfdea9ca4d48.png",
},
{
"name": "Rhomboid Major",
"origin": "Spinous processes of T2–T5 and supraspinous ligament.",
"insertion": "Medial border of scapula (between spine and inferior angle).",
"actions": "Retracts and elevates the scapula; rotates glenoid cavity inferiorly.",
"innervation": "Dorsal scapular nerve (C4, C5).",
"observation": (
"Deep to trapezius. Fibres run obliquely downward and laterally. "
"Acts with rhomboid minor to hold medial border of scapula against thoracic wall. "
"Winging of scapula occurs when both rhomboids and serratus anterior are weak."
),
"img_url": None,
},
{
"name": "Rhomboid Minor",
"origin": "Lower part of nuchal ligament; spinous processes of C7–T1.",
"insertion": "Medial border of scapula at the level of the scapular spine.",
"actions": "Retracts and elevates the scapula; rotates glenoid cavity inferiorly.",
"innervation": "Dorsal scapular nerve (C4, C5).",
"observation": (
"Lies superior to rhomboid major, separated by a narrow gap. "
"Works synergistically with rhomboid major."
),
"img_url": None,
},
{
"name": "Levator Scapulae",
"origin": "Posterior tubercles of transverse processes of C1–C4.",
"insertion": "Medial border of scapula (from superior angle to the root of the scapular spine).",
"actions": "Elevates the scapula; tilts glenoid cavity inferiorly (downward rotation).",
"innervation": "Dorsal scapular nerve (C3–C5); direct branches from C3, C4.",
"observation": (
"Deep to trapezius in the neck. Often tense and tender in neck-pain syndromes. "
"Works with upper trapezius to elevate the shoulder. "
"Countered by lower trapezius and serratus anterior for upward rotation."
),
"img_url": None,
},
{
"name": "Serratus Anterior",
"origin": "Outer surfaces and superior borders of ribs 1–8 (or 9), by fleshy slips.",
"insertion": "Costal surface (anterior surface) of medial border of scapula.",
"actions": (
"Protracts scapula (draws it laterally and anteriorly against thoracic wall); "
"rotates glenoid cavity superiorly (essential for arm elevation above 90°); "
"holds medial border of scapula against thorax."
),
"innervation": "Long thoracic nerve (C5, C6, C7).",
"observation": (
"Visible as a series of digitations on the lateral chest wall. "
"Paralysis (long thoracic nerve injury, e.g. in radical mastectomy or carrying heavy loads) "
"causes 'winged scapula' — medial border protrudes backward. "
"Critical for overhead activities."
),
"img_url": None,
},
{
"name": "Pectoralis Minor",
"origin": "Anterior surfaces of ribs 3–5 (occasionally 2–4) near the costochondral junctions.",
"insertion": "Coracoid process of scapula.",
"actions": (
"Depresses and protracts the scapula; tilts it anteriorly; "
"assists in deep inspiration (raises ribs when scapula is fixed)."
),
"innervation": "Medial pectoral nerve (C8, T1).",
"observation": (
"Deep to pectoralis major. Important surgical landmark in the axilla. "
"Tightness of pectoralis minor is a common cause of shoulder impingement posture "
"(anteriorly tilted scapula)."
),
"img_url": None,
},
{
"name": "Subclavius",
"origin": "Junction of first rib and its costal cartilage.",
"insertion": "Groove on inferior surface of middle third of clavicle.",
"actions": "Depresses and anchors the clavicle; protects the subclavian vessels.",
"innervation": "Nerve to subclavius (C5, C6).",
"observation": (
"Small muscle lying between clavicle and first rib. "
"Acts as a shock absorber protecting the brachial plexus in clavicle fractures."
),
"img_url": None,
},
],
},
# ════════════════════════════════════════════════════════════
# SECTION 2 – SHOULDER JOINT MUSCLES
# ════════════════════════════════════════════════════════════
{
"group": "2. SHOULDER (GLENOHUMERAL) JOINT MUSCLES",
"color": C_HEAD_BG,
"muscles": [
{
"name": "Deltoid",
"origin": (
"Clavicular part: lateral third of clavicle.\n"
"Acromial part: acromion.\n"
"Spinal part: scapular spine."
),
"insertion": "Deltoid tuberosity on the lateral humerus.",
"actions": (
"Clavicular part: flexion, internal rotation, adduction.\n"
"Acromial part: abduction (primary abductor 60°–90°).\n"
"Spinal part: extension, external rotation, adduction.\n"
"Above 60°, clavicular and spinal parts assist abduction."
),
"innervation": "Axillary nerve (C5, C6).",
"observation": (
"Gives the shoulder its rounded contour. "
"Loss of deltoid (axillary nerve injury, e.g. shoulder dislocation or surgical neck fracture) "
"produces a flat, square-looking shoulder. "
"Most powerful abductor of the arm."
),
"img_url": "https://cdn.orris.care/cdss_images/49b6b40716fd5263777f34e9b4c2b5bfc0f84e6b592a7362d7d90924f013ec86.png",
},
{
"name": "Supraspinatus",
"origin": "Supraspinous fossa of scapula.",
"insertion": "Superior facet of the greater tubercle of humerus.",
"actions": (
"Initiates abduction of the arm (first 0°–15°); "
"stabilises the humeral head in the glenoid cavity (rotator cuff)."
),
"innervation": "Suprascapular nerve (C4, C5, C6).",
"observation": (
"Part of the rotator cuff (SITS: Supraspinatus, Infraspinatus, Teres minor, Subscapularis). "
"Most commonly torn rotator cuff muscle, especially in adults over 40. "
"Passes under the coracoacromial arch — impingement occurs here. "
"Tear tested by 'empty can' test."
),
"img_url": "https://cdn.orris.care/cdss_images/0f5288dee10d8d20b019a66af694054a33d9560f166130d5762e8577fec783b7.png",
},
{
"name": "Infraspinatus",
"origin": "Infraspinous fossa of scapula.",
"insertion": "Middle facet of the greater tubercle of humerus.",
"actions": "External rotation of the arm; stabilises glenohumeral joint (rotator cuff).",
"innervation": "Suprascapular nerve (C5, C6).",
"observation": (
"Most powerful external rotator of the shoulder. "
"Tested by resisted external rotation with elbow at 90°. "
"Injury leads to inability to externally rotate arm (e.g., cannot scratch back)."
),
"img_url": None,
},
{
"name": "Teres Minor",
"origin": "Upper two thirds of the posterior surface of the lateral border of scapula.",
"insertion": "Inferior facet of the greater tubercle of humerus.",
"actions": "External rotation of the arm; stabilises glenohumeral joint (rotator cuff).",
"innervation": "Axillary nerve (C5, C6).",
"observation": (
"Smallest rotator cuff muscle. Works synergistically with infraspinatus for external rotation. "
"Distinguished from teres major by its external rotation action "
"(teres major is an internal rotator)."
),
"img_url": None,
},
{
"name": "Subscapularis",
"origin": "Subscapular fossa (costal/anterior surface of scapula).",
"insertion": "Lesser tubercle of humerus and shoulder joint capsule.",
"actions": (
"Internal rotation of the arm (most powerful); "
"adduction; stabilises glenohumeral joint (rotator cuff — anterior component)."
),
"innervation": "Upper and lower subscapular nerves (C5, C6, C7).",
"observation": (
"Only rotator cuff muscle to internally rotate. "
"Located on the anterior (costal) surface of scapula. "
"Torn in posterior shoulder dislocation. "
"Tested by lift-off test (Gerber's test) and belly-press test."
),
"img_url": None,
},
{
"name": "Teres Major",
"origin": "Oval area on dorsal surface of inferior angle of scapula.",
"insertion": "Crest of lesser tubercle (medial lip of intertubercular sulcus) of humerus.",
"actions": "Internal rotation, adduction, and extension of arm at glenohumeral joint.",
"innervation": "Lower subscapular nerve (C5, C6, C7).",
"observation": (
"Not a rotator cuff muscle despite the name. Acts with latissimus dorsi. "
"Forms the posterior axillary fold. "
"Mnemonic: 'Teres major is latissimus dorsi's little helper'."
),
"img_url": None,
},
{
"name": "Latissimus Dorsi",
"origin": (
"Spinous processes of T7–T12 (via thoracolumbar fascia); iliac crest; "
"ribs 9–12 (lower 3–4 ribs); inferior angle of scapula (variable)."
),
"insertion": "Floor of intertubercular sulcus (bicipital groove) of humerus.",
"actions": "Extension, adduction, and internal rotation of the arm; depresses the shoulder girdle.",
"innervation": "Thoracodorsal nerve (C6, C7, C8).",
"observation": (
"Broadest muscle of the back; gives V-shape torso. "
"Powerful in pulling the arm downward (pull-ups, rowing). "
"Forms posterior axillary fold. Used in latissimus dorsi flap reconstruction."
),
"img_url": None,
},
{
"name": "Pectoralis Major",
"origin": (
"Clavicular head: anterior surface of medial half of clavicle.\n"
"Sternocostal head: anterior surface of sternum; costal cartilages of ribs 1–6; "
"aponeurosis of external oblique."
),
"insertion": "Crest of greater tubercle (lateral lip of intertubercular sulcus) of humerus.",
"actions": (
"Clavicular head: flexion and internal rotation.\n"
"Sternocostal head: extension (from flexed position), internal rotation, adduction.\n"
"Both heads: adduction; accessory muscle of respiration."
),
"innervation": "Lateral pectoral nerve (C5–C7) for clavicular head; medial pectoral nerve (C8–T1) for sternocostal head.",
"observation": (
"Most superficial anterior chest muscle. Forms anterior axillary fold. "
"Rupture (seen in weightlifters using anabolic steroids) causes loss of anterior axillary fold "
"and weakness in adduction. Tested by adduction against resistance."
),
"img_url": None,
},
{
"name": "Coracobrachialis",
"origin": "Tip of coracoid process of scapula (with short head of biceps).",
"insertion": "Medial surface of shaft of humerus (middle third).",
"actions": "Flexion and adduction of arm at glenohumeral joint.",
"innervation": "Musculocutaneous nerve (C5, C6, C7). (Nerve pierces the muscle.)",
"observation": (
"Small muscle in the medial arm. The musculocutaneous nerve passes through it — "
"entrapment can cause musculocutaneous neuropathy (weakness of elbow flexion + lateral forearm numbness)."
),
"img_url": None,
},
],
},
# ════════════════════════════════════════════════════════════
# SECTION 3 – ARM MUSCLES
# ════════════════════════════════════════════════════════════
{
"group": "3. ARM MUSCLES",
"color": C_HEAD_BG,
"muscles": [
{
"name": "Biceps Brachii",
"origin": (
"Long head: supraglenoid tubercle of scapula (via long tendon through intertubercular sulcus).\n"
"Short head: tip of coracoid process of scapula (with coracobrachialis)."
),
"insertion": (
"Radial tuberosity of radius; bicipital aponeurosis into deep fascia of forearm."
),
"actions": (
"Supination of forearm (most powerful supinator, especially with elbow at 90°); "
"flexion of elbow; weak flexion of shoulder."
),
"innervation": "Musculocutaneous nerve (C5, C6). (C6 = 'turn the door knob'.)",
"observation": (
"Belly is visible when flexing and supinating. Long head tendon runs intra-articularly "
"and is prone to tenosynovitis and rupture (Popeye deformity = distal biceps rupture, "
"or proximal long-head rupture gives bulge above elbow). "
"Tested by resisted supination > resisted flexion."
),
"img_url": None,
},
{
"name": "Brachialis",
"origin": "Distal half of anterior surface of humerus (covers the insertion of deltoid).",
"insertion": "Coronoid process and ulnar tuberosity of ulna.",
"actions": "Pure flexor of the elbow (regardless of forearm position — no role in supination/pronation).",
"innervation": "Musculocutaneous nerve (C5, C6); small contribution from radial nerve (C7) laterally.",
"observation": (
"Deep to biceps; the 'workhorse' of elbow flexion. "
"Being a pure elbow flexor makes it the most important elbow flexor "
"(acts in all positions of forearm rotation). "
"Fractures of the coronoid process can disrupt its insertion."
),
"img_url": None,
},
{
"name": "Triceps Brachii",
"origin": (
"Long head: infraglenoid tubercle of scapula.\n"
"Lateral head: posterior surface of humerus above radial groove (spiral groove).\n"
"Medial head: posterior surface of humerus below radial groove."
),
"insertion": "Posterior surface of olecranon of ulna; deep fascia of forearm.",
"actions": "Extension of elbow (primary extensor); long head also extends and adducts shoulder.",
"innervation": "Radial nerve (C6, C7, C8).",
"observation": (
"Only muscle on posterior compartment of arm. "
"Radial nerve winds around the humerus in the spiral (radial) groove between lateral and medial heads — "
"mid-shaft humeral fractures risk radial nerve palsy (wrist drop). "
"Triceps reflex tests C7."
),
"img_url": None,
},
{
"name": "Anconeus",
"origin": "Lateral epicondyle of humerus (posterior surface).",
"insertion": "Lateral surface of olecranon and proximal posterior ulna.",
"actions": "Assists elbow extension; abducts the ulna in pronation.",
"innervation": "Radial nerve (C7, C8).",
"observation": (
"Small triangular muscle at the elbow. Continuous functionally with the medial head of triceps. "
"Tightens the posterior capsule of the elbow joint during extension."
),
"img_url": None,
},
],
},
# ════════════════════════════════════════════════════════════
# SECTION 4 – ANTERIOR FOREARM MUSCLES
# ════════════════════════════════════════════════════════════
{
"group": "4. FOREARM MUSCLES – ANTERIOR (FLEXOR) COMPARTMENT",
"color": C_HEAD_BG,
"muscles": [
{
"name": "Pronator Teres",
"origin": (
"Humeral head: medial epicondyle (common flexor origin).\n"
"Ulnar head: medial side of coronoid process of ulna."
),
"insertion": "Middle of lateral surface of radius (pronator ridge).",
"actions": "Pronation of forearm; weak elbow flexion.",
"innervation": "Median nerve (C6, C7). Enters between the two heads.",
"observation": (
"Superficial layer. Median nerve passes between its two heads — "
"pronator teres syndrome (compression of median nerve here) gives pain on resisted pronation, "
"forearm ache, and AIN-like symptoms. Forms medial boundary of cubital fossa."
),
"img_url": "https://cdn.orris.care/cdss_images/ebb92003cff63fb5c9e5339874a0949b516ee7d2f9ccca98ad06356b4b0ce44e.png",
},
{
"name": "Flexor Carpi Radialis",
"origin": "Medial epicondyle of humerus (common flexor origin).",
"insertion": "Bases of 2nd and 3rd metacarpals (palmar surface).",
"actions": "Flexion of wrist; radial deviation (abduction) of hand; weak elbow flexion.",
"innervation": "Median nerve (C6, C7).",
"observation": (
"Tendon is a useful landmark for radial artery pulse at the wrist (FCR tendon is just medial). "
"Used as graft/transfer in tendon surgery. Passes through a separate fibro-osseous canal "
"at the wrist (not the carpal tunnel)."
),
"img_url": None,
},
{
"name": "Palmaris Longus",
"origin": "Medial epicondyle of humerus (common flexor origin).",
"insertion": "Palmar aponeurosis (flexor retinaculum).",
"actions": "Weak wrist flexion; tightens palmar aponeurosis.",
"innervation": "Median nerve (C7, C8, T1).",
"observation": (
"Absent in ~14% of individuals (bilateral absence ~7%). "
"Tendon is visible at wrist when opposing thumb and little finger and flexing wrist. "
"Commonly harvested for tendon graft surgery (e.g., in flexor pollicis longus reconstruction). "
"Test for absence before planning graft."
),
"img_url": None,
},
{
"name": "Flexor Carpi Ulnaris",
"origin": (
"Humeral head: medial epicondyle (common flexor origin).\n"
"Ulnar head: olecranon and proximal posterior border of ulna."
),
"insertion": "Pisiform; hook of hamate; base of 5th metacarpal.",
"actions": "Wrist flexion; ulnar deviation (adduction) of hand.",
"innervation": "Ulnar nerve (C7, C8, T1). Only forearm flexor supplied by ulnar nerve.",
"observation": (
"Protects the ulnar nerve which runs along its medial border. "
"Ulnar nerve at the wrist runs lateral to FCU tendon. "
"Guyon's canal (ulnar tunnel at wrist) is bounded by FCU tendon medially. "
"Pisiform sesamoid bone lies within its tendon."
),
"img_url": None,
},
{
"name": "Flexor Digitorum Superficialis",
"origin": (
"Humeroulnar head: medial epicondyle + coronoid process.\n"
"Radial head: oblique line on anterior surface of radius."
),
"insertion": "Sides of middle phalanges of 2nd–5th digits (splits to allow FDP through).",
"actions": "Flexion of PIP joints of 2nd–5th digits; assists in MCP joint and wrist flexion.",
"innervation": "Median nerve (C7, C8, T1).",
"observation": (
"Intermediate layer of forearm flexors. Its split tendon forms a 'chiasm' (Camper's chiasm) "
"through which FDP passes. Testing FDS: hold other fingers in extension to eliminate FDP action, "
"then ask patient to flex the tested finger at PIP joint."
),
"img_url": None,
},
{
"name": "Flexor Digitorum Profundus",
"origin": "Proximal two-thirds of anterior and medial surfaces of ulna; adjacent interosseous membrane.",
"insertion": "Palmar surface of bases of distal phalanges of 2nd–5th digits.",
"actions": "Flexion of DIP joints (primary); assists PIP, MCP, and wrist flexion.",
"innervation": (
"Radial part (digits 2 and 3): anterior interosseous nerve (branch of median nerve, C8, T1).\n"
"Ulnar part (digits 4 and 5): ulnar nerve (C8, T1)."
),
"observation": (
"Only muscle that can flex the DIP joints. Testing: hold PIP joint in extension and ask patient "
"to flex DIP joint. The split innervation means median nerve injury spares ring and little finger FDP. "
"Lumbrical muscles arise from its tendons."
),
"img_url": "https://cdn.orris.care/cdss_images/e5deaa199d4d9ae13904a2892d15097515c80e6a91c2f28339a36da51b3797cb.png",
},
{
"name": "Flexor Pollicis Longus",
"origin": "Anterior surface of radius (middle third) and adjacent interosseous membrane.",
"insertion": "Palmar surface of base of distal phalanx of thumb.",
"actions": (
"Flexion of IP and MCP joints of thumb; wrist flexion and radial deviation; "
"opposes thumb (CMC joint)."
),
"innervation": "Anterior interosseous nerve (median nerve branch, C8, T1).",
"observation": (
"Only long flexor of the thumb. Paralysis = inability to flex distal phalanx of thumb "
"(Froment's sign variant). Anterior interosseous nerve syndrome affects FPL and radial FDP, "
"but no sensory loss (pure motor nerve)."
),
"img_url": None,
},
{
"name": "Pronator Quadratus",
"origin": "Distal quarter of anterior surface of ulna.",
"insertion": "Distal quarter of anterior surface of radius.",
"actions": "Primary pronator; stabilises distal radioulnar joint.",
"innervation": "Anterior interosseous nerve (C8, T1).",
"observation": (
"Deepest layer of forearm. Acts as primary pronator regardless of elbow position "
"(pronator teres assists). Disrupted in distal radius fractures (Colles'/Smith's). "
"Wasting is a sign of anterior interosseous nerve palsy."
),
"img_url": None,
},
],
},
# ════════════════════════════════════════════════════════════
# SECTION 5 – POSTERIOR FOREARM MUSCLES
# ════════════════════════════════════════════════════════════
{
"group": "5. FOREARM MUSCLES – POSTERIOR (EXTENSOR) COMPARTMENT",
"color": C_HEAD_BG,
"muscles": [
{
"name": "Brachioradialis",
"origin": "Proximal two-thirds of lateral supracondylar ridge of humerus.",
"insertion": "Lateral surface of distal radius (styloid process).",
"actions": "Flexion of elbow (most effective when forearm in neutral/semi-prone position).",
"innervation": "Radial nerve (C5, C6).",
"observation": (
"Despite being in the extensor compartment (supplied by radial nerve), it flexes the elbow. "
"Best developed in rock climbers. Absent or weak brachioradialis reflex suggests C5–C6 root lesion. "
"Forms lateral boundary of cubital fossa."
),
"img_url": None,
},
{
"name": "Extensor Carpi Radialis Longus",
"origin": "Distal third of lateral supracondylar ridge of humerus.",
"insertion": "Dorsal surface of base of 2nd metacarpal.",
"actions": "Wrist extension; radial deviation of hand.",
"innervation": "Radial nerve (C6, C7).",
"observation": (
"One of the radial extensors — important for maintaining wrist extension during finger flexion "
"(as in grip). Absent in radial nerve palsy (wrist drop)."
),
"img_url": None,
},
{
"name": "Extensor Carpi Radialis Brevis",
"origin": "Lateral epicondyle (common extensor origin); radial collateral ligament.",
"insertion": "Dorsal surface of base of 3rd metacarpal.",
"actions": "Wrist extension; radial deviation of hand.",
"innervation": "Deep branch of radial nerve / posterior interosseous nerve (C7, C8).",
"observation": (
"Tendon passes deep to ECRL. Its origin at the lateral epicondyle is the primary site of "
"'tennis elbow' (lateral epicondylitis/epicondylopathy). "
"Tested by resisted wrist extension with middle finger extension."
),
"img_url": None,
},
{
"name": "Extensor Digitorum",
"origin": "Lateral epicondyle (common extensor origin).",
"insertion": "Extensor expansions (dorsal digital expansions) of 2nd–5th digits.",
"actions": "Extension of 2nd–5th digits (at MCP joints primarily); assists wrist extension.",
"innervation": "Posterior interosseous nerve (C7, C8).",
"observation": (
"Tendons visible on dorsum of hand during digit extension. Joined by extensor digiti minimi "
"and extensor indicis at the extensor retinaculum. Mallet finger from avulsion of extensor hood "
"at distal phalanx. Boutonniere deformity from central slip rupture at PIP joint."
),
"img_url": None,
},
{
"name": "Extensor Digiti Minimi",
"origin": "Lateral epicondyle (common extensor origin); interosseous membrane.",
"insertion": "Extensor expansion of 5th (little) finger.",
"actions": "Extension of little finger at MCP and IP joints.",
"innervation": "Posterior interosseous nerve (C7, C8).",
"observation": (
"Provides independent extension of little finger. "
"Allows little finger to extend while other fingers are flexed (e.g., 'pinky up' gesture)."
),
"img_url": None,
},
{
"name": "Extensor Carpi Ulnaris",
"origin": "Lateral epicondyle (common extensor origin); posterior border of ulna.",
"insertion": "Medial side of base of 5th metacarpal.",
"actions": "Wrist extension; ulnar deviation (adduction) of hand.",
"innervation": "Posterior interosseous nerve (C7, C8).",
"observation": (
"Tendon runs in its own fibro-osseous groove on the posterior ulnar head. "
"Subluxation of ECU tendon occurs in forearm rotation injuries."
),
"img_url": None,
},
{
"name": "Supinator",
"origin": (
"Lateral epicondyle; radial collateral ligament; annular ligament; "
"supinator crest of ulna."
),
"insertion": "Lateral, posterior, and anterior surfaces of proximal third of radius.",
"actions": "Supination of forearm (at all elbow positions).",
"innervation": "Deep branch of radial nerve / posterior interosseous nerve (C6, C7). Nerve passes through the muscle.",
"observation": (
"Posterior interosseous nerve (PIN) passes between superficial and deep heads of supinator "
"(the arcade of Frohse). PIN compression here causes posterior interosseous nerve syndrome: "
"weakness of finger extension, no wrist drop (ECRL preserved), no sensory loss."
),
"img_url": None,
},
{
"name": "Abductor Pollicis Longus",
"origin": "Posterior surface of ulna and radius; interosseous membrane.",
"insertion": "Base of 1st metacarpal (lateral surface).",
"actions": "Abduction and extension of thumb (CMC joint); radial deviation of wrist.",
"innervation": "Posterior interosseous nerve (C7, C8).",
"observation": (
"Forms anterior border of anatomical snuffbox along with extensor pollicis brevis. "
"De Quervain's tenosynovitis affects APL and EPB tendons in their shared fibro-osseous tunnel "
"(first dorsal compartment). Finkelstein's test is positive."
),
"img_url": None,
},
{
"name": "Extensor Pollicis Brevis",
"origin": "Posterior surface of distal radius; interosseous membrane.",
"insertion": "Base of proximal phalanx of thumb.",
"actions": "Extension of MCP joint of thumb; assists radial deviation of wrist.",
"innervation": "Posterior interosseous nerve (C7, C8).",
"observation": (
"Shares first dorsal compartment with APL (De Quervain's tenosynovitis). "
"Forms anterior boundary of anatomical snuffbox."
),
"img_url": None,
},
{
"name": "Extensor Pollicis Longus",
"origin": "Posterior surface of middle third of ulna; interosseous membrane.",
"insertion": "Base of distal phalanx of thumb (dorsal surface).",
"actions": "Extension of IP joint of thumb; assists MCP and CMC extension; radial deviation.",
"innervation": "Posterior interosseous nerve (C7, C8).",
"observation": (
"Tendon hooks around Lister's tubercle (dorsal radial tubercle). "
"Rupture of EPL tendon ('drummer boy palsy') occurs in undisplaced distal radius fractures "
"or rheumatoid arthritis — patient cannot retropulse (extend/lift) thumb off table. "
"Forms posterior boundary of anatomical snuffbox."
),
"img_url": None,
},
{
"name": "Extensor Indicis",
"origin": "Posterior surface of distal ulna; interosseous membrane.",
"insertion": "Extensor expansion of index (2nd) finger.",
"actions": "Independent extension of index finger.",
"innervation": "Posterior interosseous nerve (C7, C8).",
"observation": (
"Allows independent extension of index finger (points with index finger while others are flexed). "
"Used as tendon transfer donor for EPL reconstruction."
),
"img_url": None,
},
],
},
# ════════════════════════════════════════════════════════════
# SECTION 6 – HAND MUSCLES (INTRINSIC)
# ════════════════════════════════════════════════════════════
{
"group": "6. INTRINSIC MUSCLES OF THE HAND",
"color": C_HEAD_BG,
"muscles": [
# THENAR
{
"name": "Abductor Pollicis Brevis",
"origin": "Flexor retinaculum; tubercles of scaphoid and trapezium.",
"insertion": "Lateral side of base of proximal phalanx of thumb.",
"actions": "Abduction of thumb (palmar/radial direction); assists in opposition.",
"innervation": "Recurrent branch of median nerve (C8, T1).",
"observation": (
"Most superficial thenar muscle. Wasting of this muscle is the classic sign of carpal tunnel syndrome. "
"Test: ask patient to abduct thumb against resistance (point thumb toward ceiling with hand flat)."
),
"img_url": "https://cdn.orris.care/cdss_images/099dab3ee4f7909b98dcc769eb5354beee4c8dc1f3e0b3ab310da987c65ce22c.png",
},
{
"name": "Opponens Pollicis",
"origin": "Flexor retinaculum; tubercle of trapezium.",
"insertion": "Entire lateral border of 1st metacarpal.",
"actions": "Opposition of thumb (flexion, abduction, medial rotation at CMC joint).",
"innervation": "Recurrent branch of median nerve (C8, T1).",
"observation": (
"Deepest thenar muscle. Opposition = complex movement bringing thumb pad to face the finger pads. "
"Lost in median nerve injury (thenar wasting). "
"Mnemonic: 'LOAF' = Lumbricals 1&2, Opponens pollicis, Abductor pollicis brevis, Flexor pollicis brevis — all median."
),
"img_url": None,
},
{
"name": "Flexor Pollicis Brevis",
"origin": (
"Superficial head: flexor retinaculum, tubercle of trapezium.\n"
"Deep head: trapezoid and capitate bones."
),
"insertion": "Base of proximal phalanx of thumb (lateral side).",
"actions": "Flexion of MCP joint of thumb; assists opposition.",
"innervation": "Superficial head: recurrent branch of median nerve (C8, T1). Deep head: deep branch of ulnar nerve (C8, T1).",
"observation": (
"Has dual innervation — one of few muscles with both median and ulnar supply. "
"Superficial head wasting in CTS; deep head wasting in ulnar nerve lesions."
),
"img_url": None,
},
{
"name": "Adductor Pollicis",
"origin": (
"Oblique head: bases of 2nd and 3rd metacarpals; capitate.\n"
"Transverse head: anterior surface of 3rd metacarpal shaft."
),
"insertion": "Medial side of base of proximal phalanx of thumb (via medial sesamoid).",
"actions": "Adduction of thumb; assists in pinch grip (with FPL and FPB).",
"innervation": "Deep branch of ulnar nerve (C8, T1).",
"observation": (
"Only thenar muscle supplied by ulnar nerve. Froment's sign tests this muscle: "
"patient compensates for adductor pollicis weakness by flexing IP joint using FPL "
"when holding paper between thumb and index finger."
),
"img_url": None,
},
# HYPOTHENAR
{
"name": "Abductor Digiti Minimi",
"origin": "Pisiform; pisohamate ligament; flexor carpi ulnaris tendon.",
"insertion": "Medial side of base of proximal phalanx of little finger.",
"actions": "Abduction of little finger; assists flexion of proximal phalanx.",
"innervation": "Deep branch of ulnar nerve (C8, T1).",
"observation": (
"Most medial hypothenar muscle. First muscle encountered entering Guyon's canal. "
"Wasting suggests ulnar nerve lesion at wrist (Guyon's canal syndrome)."
),
"img_url": None,
},
{
"name": "Flexor Digiti Minimi Brevis",
"origin": "Hook of hamate; flexor retinaculum.",
"insertion": "Medial side of base of proximal phalanx of little finger.",
"actions": "Flexion of MCP joint of little finger.",
"innervation": "Deep branch of ulnar nerve (C8, T1).",
"observation": "Forms the medial prominence (hypothenar eminence) of the palm.",
"img_url": None,
},
{
"name": "Opponens Digiti Minimi",
"origin": "Hook of hamate; flexor retinaculum.",
"insertion": "Medial border of 5th metacarpal.",
"actions": "Opposition of little finger (flexion + lateral rotation of 5th metacarpal).",
"innervation": "Deep branch of ulnar nerve (C8, T1).",
"observation": (
"Deepest hypothenar muscle. Draws little finger to meet thumb during opposition. "
"Wasting flattens the hypothenar eminence in ulnar nerve lesions."
),
"img_url": None,
},
# LUMBRICALS
{
"name": "Lumbricals (1st–4th)",
"origin": (
"1st and 2nd (unipennate): lateral sides of tendons of FDP for 2nd and 3rd digits.\n"
"3rd and 4th (bipennate): adjacent sides of FDP tendons for 3rd–5th digits."
),
"insertion": "Lateral bands of extensor expansions of 2nd–5th digits.",
"actions": (
"Flexion of MCP joints; extension of PIP and DIP joints "
"(unique: flex at MCP + extend at IP simultaneously — the 'intrinsic plus' position)."
),
"innervation": (
"1st and 2nd: median nerve (C8, T1).\n"
"3rd and 4th: deep branch of ulnar nerve (C8, T1)."
),
"observation": (
"Unique muscles that arise from tendons (FDP) rather than bone. "
"Intrinsic plus position = MCP flexion + IP extension (lumbricals and interossei action). "
"Intrinsic minus (clawing) = MCP hyperextension + IP flexion — seen in ulnar nerve palsy "
"(ring and little fingers claw). Less clawing with high ulnar lesion (Ulnar paradox — FDP also paralysed)."
),
"img_url": None,
},
# INTEROSSEI
{
"name": "Palmar Interossei (1st–3rd)",
"origin": "Palmar surface of metacarpals (2nd, 4th, 5th).",
"insertion": "Extensor expansions and bases of proximal phalanges of 2nd, 4th, 5th digits.",
"actions": "Adduction of 2nd, 4th, 5th digits toward 3rd digit (PAD = Palmar ADduct); MCP flexion; IP extension.",
"innervation": "Deep branch of ulnar nerve (C8, T1).",
"observation": (
"Three in number (no palmar interosseous to middle finger). "
"Mnemonic: PAD (Palmar = ADduct), DAB (Dorsal = ABduct). "
"Wasting of first dorsal interosseous (visible in first web space) is a classic sign of ulnar nerve palsy."
),
"img_url": None,
},
{
"name": "Dorsal Interossei (1st–4th)",
"origin": "Adjacent sides of metacarpal shafts (bipennate).",
"insertion": "Extensor expansions and bases of proximal phalanges of 2nd–4th digits.",
"actions": "Abduction of 2nd–4th digits away from 3rd digit (DAB = Dorsal ABduct); MCP flexion; IP extension.",
"innervation": "Deep branch of ulnar nerve (C8, T1).",
"observation": (
"Four in number. The 1st dorsal interosseous (between 1st and 2nd metacarpal) is the most powerful "
"and most visible when wasted. Critical for pinch and precision grip. "
"All interossei are tested by asking patient to abduct/adduct fingers against resistance."
),
"img_url": None,
},
],
},
]
# ── page decorations ─────────────────────────────────────────────────────────
def on_page(canvas_obj, doc):
"""Draw header and footer on each page."""
w, h = A4
# top bar
canvas_obj.setFillColor(C_DARK)
canvas_obj.rect(0, h - 1.2*cm, w, 1.2*cm, fill=1, stroke=0)
canvas_obj.setFillColor(C_WHITE)
canvas_obj.setFont("Helvetica-Bold", 9)
canvas_obj.drawString(1.5*cm, h - 0.85*cm, "UPPER LIMB MUSCLES | Origin · Insertion · Action · Observation")
canvas_obj.setFont("Helvetica", 8)
canvas_obj.drawRightString(w - 1.5*cm, h - 0.85*cm, "THIEME Atlas / Gray's Anatomy")
# bottom bar
canvas_obj.setFillColor(C_DARK)
canvas_obj.rect(0, 0, w, 0.9*cm, fill=1, stroke=0)
canvas_obj.setFillColor(C_LIGHT)
canvas_obj.setFont("Helvetica", 8)
canvas_obj.drawCentredString(w/2, 0.3*cm, f"Page {doc.page}")
def cover_page(canvas_obj, doc):
"""Draw the cover."""
w, h = A4
# full-page gradient background
canvas_obj.setFillColor(C_DARK)
canvas_obj.rect(0, 0, w, h, fill=1, stroke=0)
# accent stripe
canvas_obj.setFillColor(C_ACC)
canvas_obj.rect(0, h*0.45, w, 0.5*cm, fill=1, stroke=0)
canvas_obj.setFillColor(C_GOLD)
canvas_obj.rect(0, h*0.45 - 0.3*cm, w, 0.3*cm, fill=1, stroke=0)
# Title
canvas_obj.setFont("Helvetica-Bold", 38)
canvas_obj.setFillColor(C_WHITE)
canvas_obj.drawCentredString(w/2, h*0.62, "UPPER LIMB")
canvas_obj.setFont("Helvetica-Bold", 32)
canvas_obj.setFillColor(C_GOLD)
canvas_obj.drawCentredString(w/2, h*0.56, "MUSCLES")
canvas_obj.setFont("Helvetica", 16)
canvas_obj.setFillColor(C_LIGHT)
canvas_obj.drawCentredString(w/2, h*0.49, "Origin · Insertion · Action · Observation")
# Sub-line
canvas_obj.setFont("Helvetica-Oblique", 11)
canvas_obj.setFillColor(colors.HexColor("#aabbdd"))
canvas_obj.drawCentredString(w/2, h*0.38,
"Based on THIEME Atlas of Anatomy & Gray's Anatomy for Students")
# Decorative circles
for cx, cy, r, col in [
(1.5*cm, h - 2*cm, 0.6*cm, C_MID),
(w - 1.5*cm, h - 2*cm, 0.6*cm, C_MID),
(w/2, h*0.18, 1.8*cm, colors.HexColor("#2a3d66")),
]:
canvas_obj.setFillColor(col)
canvas_obj.circle(cx, cy, r, fill=1, stroke=0)
canvas_obj.setFont("Helvetica-Bold", 11)
canvas_obj.setFillColor(C_WHITE)
canvas_obj.drawCentredString(w/2, h*0.175, "Shoulder · Arm · Forearm · Hand")
# bottom
canvas_obj.setFillColor(C_MID)
canvas_obj.rect(0, 0, w, 1.2*cm, fill=1, stroke=0)
canvas_obj.setFont("Helvetica", 9)
canvas_obj.setFillColor(C_WHITE)
canvas_obj.drawCentredString(w/2, 0.42*cm, "Medical Reference | July 2026")
# ── flowable helpers ──────────────────────────────────────────────────────────
def chapter_header(title):
data = [[Paragraph(title, sChapter)]]
t = Table(data, colWidths=[17.5*cm])
t.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,-1), C_HEAD_BG),
("TOPPADDING", (0,0), (-1,-1), 7),
("BOTTOMPADDING", (0,0), (-1,-1), 7),
("LEFTPADDING", (0,0), (-1,-1), 10),
("RIGHTPADDING", (0,0), (-1,-1), 10),
("ROWBACKGROUNDS", (0,0), (-1,-1), [C_HEAD_BG]),
]))
return t
def muscle_block(m):
"""Return a list of flowables for one muscle entry."""
items = []
# Muscle name bar
name_data = [[Paragraph(m["name"], sMuscle)]]
nt = Table(name_data, colWidths=[17.5*cm])
nt.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,-1), C_LIGHT),
("TOPPADDING", (0,0), (-1,-1), 5),
("BOTTOMPADDING", (0,0), (-1,-1), 5),
("LEFTPADDING", (0,0), (-1,-1), 8),
("RIGHTPADDING", (0,0), (-1,-1), 8),
("LINEBELOW", (0,0), (-1,-1), 1.5, C_MID),
]))
items.append(nt)
def row(label, text):
return [Paragraph(label, sLabel), Paragraph(text.replace("\n", "<br/>"), sBody)]
table_data = [
row("ORIGIN", m["origin"]),
row("INSERTION", m["insertion"]),
row("ACTION", m["actions"]),
row("INNERVATION", m["innervation"]),
row("OBSERVATION", m["observation"]),
]
# Optional image column
img = get_img(m["img_url"]) if m.get("img_url") else None
if img:
col_w = [2.8*cm, 10.2*cm, 4.5*cm]
# attach image to last row
last_row = table_data[-1]
table_data_with_img = table_data[:-1] + [[last_row[0], last_row[1], ""]]
table_data_with_img.append(["", "", img])
t = Table(table_data_with_img, colWidths=col_w, repeatRows=0)
t.setStyle(TableStyle([
("VALIGN", (0,0), (-1,-1), "TOP"),
("TOPPADDING", (0,0), (-1,-1), 4),
("BOTTOMPADDING", (0,0), (-1,-1), 4),
("LEFTPADDING", (0,0), (-1,-1), 5),
("RIGHTPADDING", (0,0), (-1,-1), 5),
("ROWBACKGROUNDS", (0,0), (-1,-1), [C_WHITE, C_GRAY]),
("LINEBELOW", (0,0), (-1,-1), 0.3, colors.HexColor("#cccccc")),
("SPAN", (2, len(table_data)-1), (2, len(table_data))),
]))
else:
col_w = [2.8*cm, 14.7*cm]
t = Table(table_data, colWidths=col_w)
t.setStyle(TableStyle([
("VALIGN", (0,0), (-1,-1), "TOP"),
("TOPPADDING", (0,0), (-1,-1), 4),
("BOTTOMPADDING", (0,0), (-1,-1), 4),
("LEFTPADDING", (0,0), (-1,-1), 5),
("RIGHTPADDING", (0,0), (-1,-1), 5),
("ROWBACKGROUNDS", (0,0), (-1,-1), [C_WHITE, C_GRAY]),
("LINEBELOW", (0,0), (-1,-1), 0.3, colors.HexColor("#cccccc")),
]))
items.append(t)
items.append(Spacer(1, 0.25*cm))
return items
# ── overview table ────────────────────────────────────────────────────────────
def overview_table():
header = ["Muscle", "Innervation", "Action (Key)"]
data = [header]
header_style = [
("BACKGROUND", (0,0), (-1,0), C_MID),
("TEXTCOLOR", (0,0), (-1,0), C_WHITE),
("FONTNAME", (0,0), (-1,0), "Helvetica-Bold"),
("FONTSIZE", (0,0), (-1,0), 9),
("ALIGN", (0,0), (-1,-1), "LEFT"),
("VALIGN", (0,0), (-1,-1), "MIDDLE"),
("TOPPADDING", (0,0), (-1,-1), 4),
("BOTTOMPADDING", (0,0), (-1,-1), 4),
("LEFTPADDING", (0,0), (-1,-1), 5),
("FONTSIZE", (0,1), (-1,-1), 8),
("ROWBACKGROUNDS", (0,1), (-1,-1), [C_WHITE, C_GRAY]),
("GRID", (0,0), (-1,-1), 0.5, colors.HexColor("#aaaaaa")),
]
for section in MUSCLES:
for m in section["muscles"]:
# shorten innervation
inn = m["innervation"].split(".")[0].split("(")[0].strip()
# shorten action
act = m["actions"].split("\n")[0].split(";")[0].strip()
if len(act) > 60:
act = act[:58] + "…"
data.append([m["name"], inn, act])
col_w = [5.5*cm, 5.5*cm, 6.5*cm]
t = Table(data, colWidths=col_w, repeatRows=1)
t.setStyle(TableStyle(header_style))
return t
# ── build doc ─────────────────────────────────────────────────────────────────
def build():
doc = SimpleDocTemplate(
OUT,
pagesize=A4,
leftMargin=1.5*cm, rightMargin=1.5*cm,
topMargin=1.8*cm, bottomMargin=1.4*cm,
title="Upper Limb Muscles",
author="Orris Medical Reference",
subject="Anatomy – Upper Limb",
)
story = []
# ── Cover page (blank with custom canvas) ──
story.append(PageBreak()) # cover is drawn by firstPage callback, skip content
# ── TOC / Overview header ──
story.append(Spacer(1, 0.5*cm))
story.append(Paragraph("CONTENTS AT A GLANCE", S("h",
fontName="Helvetica-Bold", fontSize=14, textColor=C_DARK,
spaceAfter=6, leading=18)))
story.append(HRFlowable(width="100%", thickness=2, color=C_MID, spaceAfter=8))
for i, section in enumerate(MUSCLES, 1):
story.append(Paragraph(section["group"], sTOCHead))
for m in section["muscles"]:
story.append(Paragraph(f" • {m['name']}", sTOC))
story.append(Spacer(1, 0.4*cm))
# ── Quick-reference overview table ──
story.append(PageBreak())
story.append(Paragraph("QUICK REFERENCE TABLE", S("h2",
fontName="Helvetica-Bold", fontSize=14, textColor=C_DARK,
spaceAfter=6, leading=18)))
story.append(HRFlowable(width="100%", thickness=2, color=C_MID, spaceAfter=8))
story.append(overview_table())
story.append(PageBreak())
# ── Main muscle sections ──
for section in MUSCLES:
story.append(chapter_header(section["group"]))
story.append(Spacer(1, 0.2*cm))
for m in section["muscles"]:
block = muscle_block(m)
story.append(KeepTogether(block))
story.append(PageBreak())
# ── Build with cover on first page ──
doc.build(story, onFirstPage=cover_page, onLaterPages=on_page)
print(f"PDF saved → {OUT}")
if __name__ == "__main__":
build()
cd /home/daytona/workspace/upper-limb-muscles && python3 build_pdf.py 2>&1
ls -lh /home/daytona/workspace/upper-limb-muscles/Upper_Limb_Muscles.pdf && pyth…
ls -lh /home/daytona/workspace/upper-limb-muscles/imgs/
Upper Limb Muscles
PDF Document · PDF
| Section | Muscles Covered |
|---|---|
| 1. Shoulder Girdle | Trapezius, Rhomboid Major/Minor, Levator Scapulae, Serratus Anterior, Pectoralis Minor, Subclavius |
| 2. Shoulder Joint | Deltoid, Supraspinatus, Infraspinatus, Teres Minor, Subscapularis, Teres Major, Latissimus Dorsi, Pectoralis Major, Coracobrachialis |
| 3. Arm | Biceps Brachii, Brachialis, Triceps Brachii, Anconeus |
| 4. Anterior Forearm | Pronator Teres, FCR, Palmaris Longus, FCU, FDS, FDP, FPL, Pronator Quadratus |
| 5. Posterior Forearm | Brachioradialis, ECRL, ECRB, Extensor Digitorum, EDM, ECU, Supinator, APL, EPB, EPL, Extensor Indicis |
| 6. Hand (Intrinsic) | Thenar (APB, OP, FPB, Adductor Pollicis), Hypothenar (ADM, FDMB, ODM), Lumbricals 1–4, Palmar Interossei 1–3, Dorsal Interossei 1–4 |