{"spec_id":"qrcode-basic","library":"ggplot2","language":"r","code":"#' anyplot.ai\n#' qrcode-basic: Basic QR Code Generator\n#' Library: ggplot2 3.5.1 | R 4.4.1\n#' Quality: 90/100 | Created: 2026-06-24\n\nlibrary(ggplot2)\nlibrary(ragg)\nlibrary(qrcode)\n\n# Theme tokens — Imprint palette, theme-adaptive chrome\nTHEME       <- Sys.getenv(\"ANYPLOT_THEME\", \"light\")\nPAGE_BG     <- if (THEME == \"light\") \"#FAF8F1\" else \"#1A1A17\"\nELEVATED_BG <- if (THEME == \"light\") \"#FFFDF6\" else \"#242420\"\nINK         <- if (THEME == \"light\") \"#1A1A17\" else \"#F0EFE8\"\nINK_SOFT    <- if (THEME == \"light\") \"#4A4A44\" else \"#B8B7B0\"\nINK_MUTED   <- if (THEME == \"light\") \"#6B6A63\" else \"#A8A79F\"\n\n# QR module colors — high contrast ink/paper tones for reliable scanning\nMODULE_DARK  <- INK      # encodes data bits\nMODULE_LIGHT <- PAGE_BG  # background (quiet) modules\n\n# Content to encode\nencode_url <- \"https://anyplot.ai\"\n\n# Generate QR code (error correction level M = 15%)\n# Returns a logical matrix: TRUE = dark module, FALSE = light module\n# The package includes a 3-module quiet zone border in the matrix\nqr     <- qr_code(encode_url, ecl = \"M\")\nqr_mat <- as.matrix(qr)\nn      <- nrow(qr_mat)\n\n# Build tidy data frame for geom_tile\n# as.vector(t(m)) = row-major order: m[1,1], m[1,2], ..., m[n,n]\n# y is flipped so matrix row 1 appears at the top of the plot\nqr_df <- data.frame(\n  x    = rep(seq_len(n), times = n),\n  y    = rep(seq(n, 1L),  each  = n),\n  dark = as.character(as.vector(t(qr_mat)))\n)\n\n# Title fontsize: baseline 12pt for ~67-char title; scale down if longer\nplot_title <- \"qrcode-basic · r · ggplot2 · anyplot.ai\"\ntitle_n    <- nchar(plot_title)\ntitle_size <- if (title_n > 67) max(round(12L * 67L / title_n), 8L) else 12L\n\n# Build plot — square canvas suits the symmetric QR grid\np <- ggplot(qr_df, aes(x = x, y = y, fill = dark)) +\n  geom_tile(color = NA, linewidth = 0) +\n  scale_fill_manual(\n    values = c(\"TRUE\" = MODULE_DARK, \"FALSE\" = MODULE_LIGHT),\n    guide  = \"none\"\n  ) +\n  coord_fixed() +\n  labs(\n    title    = plot_title,\n    subtitle = encode_url,\n    x        = NULL,\n    y        = NULL\n  ) +\n  theme_minimal(base_size = 8) +\n  theme(\n    plot.background  = element_rect(fill = PAGE_BG, color = PAGE_BG),\n    panel.background = element_rect(fill = PAGE_BG, color = NA),\n    panel.grid.major = element_blank(),\n    panel.grid.minor = element_blank(),\n    panel.border     = element_blank(),\n    axis.text        = element_blank(),\n    axis.ticks       = element_blank(),\n    axis.title       = element_blank(),\n    plot.title       = element_text(\n      color  = INK,\n      size   = title_size,\n      hjust  = 0.5,\n      face   = \"bold\"\n    ),\n    plot.subtitle    = element_text(\n      color  = INK_SOFT,\n      size   = 9,\n      hjust  = 0.5\n    ),\n    plot.margin      = margin(20, 20, 20, 20)\n  )\n\n# Save — square PNG (2400 × 2400 px at dpi = 400)\nggsave(\n  filename = sprintf(\"plot-%s.png\", THEME),\n  plot     = p,\n  device   = ragg::agg_png,\n  width    = 6,\n  height   = 6,\n  units    = \"in\",\n  dpi      = 400\n)\n"}