defmodule Pdf.Component.Footnote do @moduledoc """ Footnote component for PDF documents. Renders footnotes at a given position with a separator line, superscript numbers, and smaller text. ## Examples doc |> Pdf.Component.Footnote.render({50, 100}, %{width: 450}, [ "Source: World Bank Data, 2025", "All figures adjusted for inflation", "Excluding outlier regions" ]) """ @default_font "Helvetica" @default_font_size 7 @default_color {0.4, 0.4, 0.4} @default_line_color {0.75, 0.75, 0.75} @default_line_height 11 @default_separator_width 80 @doc """ Render footnotes at `{x, y}`. ## Style options - `:width` — available width (default `450`) - `:font` — font name (default `"Helvetica"`) - `:font_size` — text size (default `7`) - `:color` — text color - `:line_color` — separator line color - `:line_height` — spacing between notes (default `11`) - `:separator_width` — width of the top separator line (default `80`) - `:start_number` — first footnote number (default `1`) """ def render(doc, {x, y}, style \\ %{}, notes) do _width = Map.get(style, :width, 450) font = Map.get(style, :font, @default_font) font_size = Map.get(style, :font_size, @default_font_size) color = Map.get(style, :color, @default_color) line_color = Map.get(style, :line_color, @default_line_color) line_height = Map.get(style, :line_height, @default_line_height) sep_width = Map.get(style, :separator_width, @default_separator_width) start_num = Map.get(style, :start_number, 1) # Separator line doc = doc |> Pdf.save_state() |> Pdf.set_stroke_color(line_color) |> Pdf.set_line_width(0.5) |> Pdf.line({x, y}, {x + sep_width, y}) |> Pdf.stroke() |> Pdf.restore_state() # Footnote entries notes |> Enum.with_index(start_num) |> Enum.reduce(doc, fn {note, num}, d -> ny = y - 8 - (num - start_num) * line_height num_text = "#{num}" num_w = String.length(num_text) * (font_size - 1) * 0.55 d |> Pdf.set_font(font, font_size - 1) |> Pdf.set_fill_color(color) |> Pdf.text_at({x, ny + 2}, num_text) |> Pdf.set_font(font, font_size) |> Pdf.set_fill_color(color) |> Pdf.text_at({x + num_w + 3, ny}, note) end) end end