{"spec_id":"barcode-code128","library":"pygal","language":"python","code":"\"\"\" anyplot.ai\nbarcode-code128: Code 128 Barcode\nLibrary: pygal 3.1.0 | Python 3.13.13\nQuality: 87/100 | Updated: 2026-05-21\n\"\"\"\n\nimport os\n\nimport pygal\nfrom pygal.style import Style\n\n\nTHEME = os.getenv(\"ANYPLOT_THEME\", \"light\")\nPAGE_BG = \"#FAF8F1\" if THEME == \"light\" else \"#1A1A17\"\nELEVATED_BG = \"#FFFDF6\"  # barcode must stay on a light surface for scan reliability\nINK = \"#1A1A17\" if THEME == \"light\" else \"#F0EFE8\"\nINK_MUTED = \"#6B6A63\" if THEME == \"light\" else \"#A8A79F\"\n\n# Code 128B character table: SP(0) through ~(94)\nCODE128B_CHARS = \" !\\\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\"\n\n# 107 Code 128 bar/space patterns (indices 0-106); STOP (106) has 7 elements\nCODE128_PATTERNS = [\n    (2, 1, 2, 2, 2, 2),\n    (2, 2, 2, 1, 2, 2),\n    (2, 2, 2, 2, 2, 1),\n    (1, 2, 1, 2, 2, 3),\n    (1, 2, 1, 3, 2, 2),\n    (1, 3, 1, 2, 2, 2),\n    (1, 2, 2, 2, 1, 3),\n    (1, 2, 2, 3, 1, 2),\n    (1, 3, 2, 2, 1, 2),\n    (2, 2, 1, 2, 1, 3),\n    (2, 2, 1, 3, 1, 2),\n    (2, 3, 1, 2, 1, 2),\n    (1, 1, 2, 2, 3, 2),\n    (1, 2, 2, 1, 3, 2),\n    (1, 2, 2, 2, 3, 1),\n    (1, 1, 3, 2, 2, 2),\n    (1, 2, 3, 1, 2, 2),\n    (1, 2, 3, 2, 2, 1),\n    (2, 2, 3, 2, 1, 1),\n    (2, 2, 1, 1, 3, 2),\n    (2, 2, 1, 2, 3, 1),\n    (2, 1, 3, 2, 1, 2),\n    (2, 2, 3, 1, 1, 2),\n    (3, 1, 2, 1, 3, 1),\n    (3, 1, 1, 2, 2, 2),\n    (3, 2, 1, 1, 2, 2),\n    (3, 2, 1, 2, 2, 1),\n    (3, 1, 2, 2, 1, 2),\n    (3, 2, 2, 1, 1, 2),\n    (3, 2, 2, 2, 1, 1),\n    (2, 1, 2, 1, 2, 3),\n    (2, 1, 2, 3, 2, 1),\n    (2, 3, 2, 1, 2, 1),\n    (1, 1, 1, 3, 2, 3),\n    (1, 3, 1, 1, 2, 3),\n    (1, 3, 1, 3, 2, 1),\n    (1, 1, 2, 3, 1, 3),\n    (1, 3, 2, 1, 1, 3),\n    (1, 3, 2, 3, 1, 1),\n    (2, 1, 1, 3, 1, 3),\n    (2, 3, 1, 1, 1, 3),\n    (2, 3, 1, 3, 1, 1),\n    (1, 1, 2, 1, 3, 3),\n    (1, 1, 2, 3, 3, 1),\n    (1, 3, 2, 1, 3, 1),\n    (1, 1, 3, 1, 2, 3),\n    (1, 1, 3, 3, 2, 1),\n    (1, 3, 3, 1, 2, 1),\n    (3, 1, 3, 1, 2, 1),\n    (2, 1, 1, 3, 3, 1),\n    (2, 3, 1, 1, 3, 1),\n    (2, 1, 3, 1, 1, 3),\n    (2, 1, 3, 3, 1, 1),\n    (2, 1, 3, 1, 3, 1),\n    (3, 1, 1, 1, 2, 3),\n    (3, 1, 1, 3, 2, 1),\n    (3, 3, 1, 1, 2, 1),\n    (3, 1, 2, 1, 1, 3),\n    (3, 1, 2, 3, 1, 1),\n    (3, 3, 2, 1, 1, 1),\n    (3, 1, 4, 1, 1, 1),\n    (2, 2, 1, 4, 1, 1),\n    (4, 3, 1, 1, 1, 1),\n    (1, 1, 1, 2, 2, 4),\n    (1, 1, 1, 4, 2, 2),\n    (1, 2, 1, 1, 2, 4),\n    (1, 2, 1, 4, 2, 1),\n    (1, 4, 1, 1, 2, 2),\n    (1, 4, 1, 2, 2, 1),\n    (1, 1, 2, 2, 1, 4),\n    (1, 1, 2, 4, 1, 2),\n    (1, 2, 2, 1, 1, 4),\n    (1, 2, 2, 4, 1, 1),\n    (1, 4, 2, 1, 1, 2),\n    (1, 4, 2, 2, 1, 1),\n    (2, 4, 1, 2, 1, 1),\n    (2, 2, 1, 1, 1, 4),\n    (4, 1, 3, 1, 1, 1),\n    (2, 4, 1, 1, 1, 2),\n    (1, 3, 4, 1, 1, 1),\n    (1, 1, 1, 2, 4, 2),\n    (1, 2, 1, 1, 4, 2),\n    (1, 2, 1, 2, 4, 1),\n    (1, 1, 4, 2, 1, 2),\n    (1, 2, 4, 1, 1, 2),\n    (1, 2, 4, 2, 1, 1),\n    (4, 1, 1, 2, 1, 2),\n    (4, 2, 1, 1, 1, 2),\n    (4, 2, 1, 2, 1, 1),\n    (2, 1, 2, 1, 4, 1),\n    (2, 1, 4, 1, 2, 1),\n    (4, 1, 2, 1, 2, 1),\n    (1, 1, 1, 1, 4, 3),\n    (1, 1, 1, 3, 4, 1),\n    (1, 3, 1, 1, 4, 1),\n    (1, 1, 4, 1, 1, 3),\n    (1, 1, 4, 3, 1, 1),\n    (4, 1, 1, 1, 1, 3),\n    (4, 1, 1, 3, 1, 1),\n    (1, 1, 3, 1, 4, 1),\n    (1, 1, 4, 1, 3, 1),\n    (3, 1, 1, 1, 4, 1),\n    (4, 1, 1, 1, 3, 1),\n    (2, 1, 1, 4, 1, 2),\n    (2, 1, 1, 2, 1, 4),\n    (2, 1, 1, 2, 3, 2),\n    (2, 3, 3, 1, 1, 1, 2),  # STOP (106): 7 elements\n]\n\n# Special symbol indices\nSTART_B = 104\nCODE_C = 99  # switch to Code C (digit-pair encoding)\nSTOP = 106\n\n# Content: alpha prefix in Code B, digit suffix in Code C (demonstrates subset switching)\nalpha_part = \"SHIP-\"\ndigit_part = \"20240101\"\ncontent = alpha_part + digit_part\n\n# Encode: START_B → Code B chars → CODE_C switch → digit pairs → checksum → STOP\nraw_values = [START_B]\nfor ch in alpha_part:\n    raw_values.append(CODE128B_CHARS.index(ch))\nraw_values.append(CODE_C)\nfor i in range(0, len(digit_part), 2):\n    raw_values.append(int(digit_part[i : i + 2]))\n\nchecksum_val = raw_values[0]\nfor pos, v in enumerate(raw_values[1:], 1):\n    checksum_val += pos * v\ncheck_digit = checksum_val % 103\n\nvalues = raw_values + [check_digit, STOP]\n\n# Expand encoded values to bar-module widths\nbar_pattern = []\nfor val in values:\n    bar_pattern.extend(CODE128_PATTERNS[val])\n\n# Build module heights: even idx = bar (100), odd idx = space (0), with quiet zones\nquiet_zone = 10\nbar_heights = [0] * quiet_zone\nfor idx, width in enumerate(bar_pattern):\n    bar_heights.extend([100 if idx % 2 == 0 else 0] * width)\nbar_heights.extend([0] * quiet_zone)\n\n# Style — elevated warm-white panel for barcode area; outer bg follows theme\ncustom_style = Style(\n    background=PAGE_BG,\n    plot_background=ELEVATED_BG,\n    foreground=INK,\n    foreground_strong=INK,\n    foreground_subtle=INK_MUTED,\n    colors=(\"#000000\",),\n    title_font_size=66,\n    label_font_size=56,\n    major_label_font_size=44,\n    legend_font_size=44,\n    value_font_size=0,\n    tooltip_font_size=0,\n)\n\n# Square canvas suits barcode layout; tight bottom margin eliminates dead space\nchart = pygal.Bar(\n    width=2400,\n    height=2400,\n    style=custom_style,\n    show_legend=False,\n    show_x_labels=False,\n    show_y_labels=False,\n    show_x_guides=False,\n    show_y_guides=False,\n    spacing=0,\n    margin_top=200,\n    margin_bottom=100,\n    margin_left=300,\n    margin_right=300,\n    title=\"barcode-code128 · python · pygal · anyplot.ai\",\n    print_values=False,\n    range=(0, 100),\n)\n\nchart.add(\"\", bar_heights)\n# Human-readable text + encoding metadata: content, subset path, char count, check digit\nchart.x_title = f\"{content}  |  Subset: Code B→C  |  {len(content)} chars  |  Check: {check_digit}\"\n\nchart.render_to_png(f\"plot-{THEME}.png\")\nwith open(f\"plot-{THEME}.html\", \"wb\") as f:\n    f.write(chart.render())\n"}