diff --git a/lib/telemetry_docs.ex b/lib/telemetry_docs.ex index e1c9338..fee09c7 100644 --- a/lib/telemetry_docs.ex +++ b/lib/telemetry_docs.ex @@ -177,7 +177,7 @@ defmodule TelemetryDocs do rows = Enum.map_join(fields, "\n", fn {name, opts} -> type = Keyword.fetch!(opts, :type) - doc = Keyword.fetch!(opts, :doc) + doc = opts |> Keyword.fetch!(:doc) |> collapse_newlines() "| `:#{name}` | `#{type}` | #{doc} |" end) @@ -188,4 +188,12 @@ defmodule TelemetryDocs do #{rows}\ """ end + + # Collapses newlines (and surrounding whitespace) into single spaces so that + # multi-line docs don't break the Markdown table they're rendered into. + defp collapse_newlines(doc) do + doc + |> String.replace(~r/\s*\n\s*/, " ") + |> String.trim() + end end diff --git a/test/telemetry_docs_test.exs b/test/telemetry_docs_test.exs index 16ad1a8..0196baa 100644 --- a/test/telemetry_docs_test.exs +++ b/test/telemetry_docs_test.exs @@ -185,6 +185,35 @@ defmodule TelemetryDocsTest do refute result =~ "\n\n\n" end + test "collapses newlines in field docs so they don't break the table" do + sections = [ + [ + title: "Events", + events: [ + "[:app, :event]": [ + doc: "An event.", + measurements: [ + millis_behind_latest: [ + type: "t:integer/0", + doc: """ + The number of milliseconds behind latest record. + See the docs. + Only present if the request succeeds. + """ + ] + ], + metadata: [] + ] + ] + ] + ] + + result = TelemetryDocs.sections_to_markdown(sections) + + assert result =~ + "| `:millis_behind_latest` | `t:integer/0` | The number of milliseconds behind latest record. See the docs. Only present if the request succeeds. |" + end + test "raises on invalid section options" do assert_raise NimbleOptions.ValidationError, fn -> TelemetryDocs.sections_to_markdown([[title: 123]])