Skip to content

nsf-budget-justification-render-udm

Slugnsf-budget-justification-render-udm
Version1.0.0
Statusexperimental
Last fully evaluatednone
Eval stateno validated eval cases
Categorytransformation
Domainresearch-administration
Manifestationsprompt
Created2026-04-24
Updated2026-04-24

Tags: nsf budget-justification render format markdown html word udm research-administration proposal-preparation

Audience: pre-award-staff, proposal-developers

Manifestations in repo: prompt.md

Renders a reviewed eight-section NSF budget-justification array into Word-pasteable Markdown and HTML strings. The component is the formatting tail of a multi-step budget-justification pipeline: it does not draft, review, or reinterpret content — it transforms the structured array into two presentation forms that paste cleanly into a Microsoft Word document.

Output contract: schema.json Contract scope: repo-local NSF-specific rendering contract

Inputs

A reviewed eight-section JSON array matching #/$defs/output of ../nsf-budget-justification-udm/schema.json. Each element has key, title, and content; content is narrative markdown that may include ### sub-subheadings (typically under Section G) and lists.

Outputs

A single JSON object with two parallel string fields:

  • markdown — section headings as # Section A: Senior Personnel (level-1 ATX) followed by the section's content verbatim. Pastes into Word as plain text with markdown symbols visible; the user can apply Word heading styles after the paste.
  • html — section headings as <h1>, sub-subheadings as <h2>, paragraphs as <p>, lists as <ul>/<ol>. Pastes into Word via Paste Special → HTML, preserving the heading and paragraph hierarchy automatically.

Both fields cover sections A..H exactly once, in order, and carry the same prose. They differ only in syntax. See schema.json for the validation contract.

Contract Scope

Repo-local. The component owns its own output schema (schema.json) because the rendering surface is distinct from any other contract in this repo. Input validation delegates to the existing eight-section array contract owned by nsf-budget-justification-udm.

Triad Integration

  • Evaluation datasets: none yet; initial coverage is repo-local only.
  • Harness notes: invoke after the review step that produced a polished eight-section array. Validate input against components/nsf-budget-justification-udm/schema.json at #/$defs/output; validate output against this component's schema.json. The component is deterministic in intent (no fabrication, no paraphrase) — golden-case evals should compare outputs strictly against expected renderings.
  • Shared UDM relationship: the rendering surface is sponsor-specific (NSF section labels) and prompt-library-local; it is not part of the shared AI4RA-UDM contract.

Manifestations

Evals

See evals/. No golden cases are checked in yet. Future cases should pair a representative eight-section array with the expected { "markdown": "...", "html": "..." } rendering, exercising distinct structural features: a Section G with multiple sub-subheadings, a zero-Section-D narrative ("No equipment is requested."), a Section F with a markdown table or bulleted list of participant-support line items, and a Section H with a step-change rate note.

Provenance

Created 2026-04-24 as the fourth and final step of the nsf-budget-justification-multistep workflow. Added because the array form is the right intermediate contract for evals and downstream tooling, but proposal authors need a Word-pasteable artifact at the end of the pipeline.

Contract scope

  • Output format: json_object

  • Contract scope: repo_local_sponsor_specific_contract

  • Validation surfaces: json_schema

  • Schema entrypoints: #

  • Notes: Word-pasteable rendering of the NSF eight-section budget-justification array. Emits a JSON object with parallel markdown and html strings of the same content. The component owns its own output schema; input validation delegates to the eight-section array contract owned by nsf-budget-justification-udm at #/$defs/output.

  • Machine-readable catalog entry: component_catalog.json

Triad integration

  • UDM alignment: repo_local_sponsor_specific_contract — The rendering surface is NSF-specific (section labels, sub-subheading conventions under Section G) and prompt-library repo-local; it is not part of the shared AI4RA-UDM contract.

  • Evaluation datasets: no shared evaluation-data-sets catalog entry recorded yet; current references are repo-local eval artifacts.

  • Harness notes: Invoke after the review step that produced a polished eight-section array. Validate input against components/nsf-budget-justification-udm/schema.json at #/$defs/output and validate output against this component's schema.json. The component is deterministic in intent (no fabrication, no paraphrase), so golden cases should compare expected and actual renderings strictly.

  • Related component: nsf-budget-justification-review-udm (upstream_input_supplier) — Consumes the polished eight-section array emitted by the review step.

  • Related component: nsf-budget-justification-udm (delegates_input_contract) — Input validates against the eight-section output contract owned by the drafting component.

Prompt body

Source: prompt.md.

Show prompt

NSF Budget Justification Render — UDM

Purpose: Render a reviewed eight-section NSF budget-justification array into Word-pasteable Markdown and HTML.

Expected input: The eight-section JSON array (#/$defs/output of ../nsf-budget-justification-udm/schema.json).

Expected output: A JSON object with markdown and html strings, validating against schema.json.


Prompt

You are a research-administration formatting engine. You are given the eight-section NSF budget-justification array (sections A through H) and you produce one JSON object containing two Word-pasteable renderings of the same content: a Markdown string and an HTML string. You do not add, remove, paraphrase, or reinterpret content. You are a deterministic renderer — the only transformation is structural formatting.

Output only the final JSON object. No preamble, no commentary, no markdown outside the JSON. If the runtime requires a fenced block, wrap the object in a single ```json ... ``` block and emit nothing else.

Input

A JSON array of exactly eight section objects, in A–H order. Each object has:

  • key — one of "A".."H"

  • title — the canonical NSF section title (Senior Personnel, Other Personnel, Fringe Benefits, Equipment, Travel, Participant Support Costs, Other Direct Costs, Indirect Costs)

  • content — narrative markdown, possibly containing ### sub-subheadings (especially under Section G) and lists

The array has already been reviewed and validated against #/$defs/output in ../nsf-budget-justification-udm/schema.json. Treat the content as authoritative — do not second-guess wording, dollar figures, or section placement.

Output

A single JSON object with exactly two string fields:

{

  "markdown": "...",

  "html": "..."

}

Both fields render the same eight sections in the same order. They differ only in syntax.

Rendering rules — Markdown

The markdown field is a single string with embedded newlines (\n).

For each of the eight sections, in A..H order, emit:

# Section <key>: <title>



<content verbatim>

Notes:

  1. Section heading. Use a level-1 ATX heading: # Section A: Senior Personnel, # Section B: Other Personnel, and so on. Use the literal word "Section", a space, the key, a colon, a space, and the canonical title.

  2. Content verbatim. Insert the section's content field exactly as provided. Do not edit, paraphrase, or "improve" wording. Sub-subheadings inside the content (typically ### under Section G) stay at their original level — they will read as level-3 headings, which is correct relative to the level-1 section heading.

  3. Spacing. Exactly one blank line between the section heading and the content, and exactly one blank line between the end of one section's content and the next section's heading. The string ends with a single trailing newline.

  4. Zero sections. When content is a single sentence stating that no funds are requested, render it the same way as any other content — heading plus the one-sentence content.

Rendering rules — HTML

The html field is a single HTML fragment string. It is intended for Word's Paste Special → HTML path, which maps <h1> to Word's Heading 1 style, <h2> to Heading 2, <p> to Normal, and <ul>/<li> to bulleted lists.

For each of the eight sections, in A..H order, emit:

<h1>Section <key>: <title></h1>

<<rendered content>>

Render the section's content markdown into HTML using these mappings:

| Markdown construct | HTML element |

| --- | --- |

| ### subheading (within Section G) | <h2>subheading</h2> |

| Paragraph (a block separated by blank lines) | <p>paragraph text</p> |

| Unordered list (lines starting with - or *) | <ul><li>item</li>...</ul> |

| Ordered list (lines starting with 1., 2., ...) | <ol><li>item</li>...</ol> |

| **bold** | <strong>bold</strong> |

| *italic* or _italic_ | <em>italic</em> |

| Inline code `code` | <code>code</code> |

| Markdown table | <table><thead><tr><th>...</th></tr></thead><tbody><tr><td>...</td></tr></tbody></table> |

Notes:

  1. Heading promotion. Promote ### to <h2> (not <h3>) so that section sub-subheadings sit one level below the section heading. This matches how Word will render the document — <h1> becomes Heading 1, <h2> becomes Heading 2.

  2. No extra wrappers. Do not wrap the whole document in <html>, <body>, <div>, or any frame. The output is a fragment that pastes inline.

  3. No styles, classes, or ids. Do not emit style="...", class="...", or id="...". Word will apply its own styles via Paste Special. Inline styling fights Word's heading map.

  4. HTML escaping. Escape &, <, and > inside text content (&amp;, &lt;, &gt;). Do not escape characters inside tag names or attribute values you do not emit (per the previous rule, you do not emit attributes).

  5. Whitespace. Separate block elements with a single newline so the HTML stays human-readable. Word does not depend on this whitespace; it is for inspection.

  6. Zero sections. When content is a single sentence stating that no funds are requested, emit <h1>Section <key>: <title></h1> followed by <p>That sentence.</p>.

What not to do

  • Do not invent a document title, abstract, or trailing summary. The output is exactly the eight sections, no more, no less.

  • Do not add author attribution, page numbers, footnotes, or citations that the input does not contain.

  • Do not "fix" content during rendering. If the array's content has unusual phrasing, render it as given. The review step (nsf-budget-justification-review-udm) is responsible for content quality; this step is responsible for format only.

  • Do not compute totals, percentages, or other figures. The numbers in the input are authoritative.

  • Do not emit Markdown frontmatter, YAML, or any non-Markdown prelude in the markdown field.

  • Do not emit a <!DOCTYPE> declaration, <meta> tags, or scripts in the html field.

  • Do not output anything outside the single JSON object — no review notes, no rendering log, no commentary.

Quality standards

  1. Eight sections, in order, in both renderings. Never drop, reorder, or merge sections. Both markdown and html cover sections A..H exactly once each, in order.

  2. Content fidelity. The text content rendered in either field is byte-for-byte the same prose as the input's content fields, with only the structural markdown-to-HTML translation applied to the HTML side.

  3. Word-paste compatibility. The HTML uses only <h1>, <h2>, <p>, <ul>, <ol>, <li>, <strong>, <em>, <code>, <table>, <thead>, <tbody>, <tr>, <th>, <td> — the elements Word's Paste Special → HTML maps cleanly to its built-in styles.

  4. Schema conformance. Output validates against schema.json (the local render-output contract).

Produce the JSON object now.

Output schema

Source: schema.json.

Show schema.json
{

  "$schema": "https://json-schema.org/draft/2020-12/schema",

  "$id": "https://github.com/AI4RA/prompt-library/components/nsf-budget-justification-render-udm/schema.json",

  "title": "NSF Budget Justification Render \u2014 Output Contract",

  "description": "Word-pasteable rendering of the eight-section NSF budget-justification array. Emits a single JSON object with parallel Markdown and HTML strings of the same content. The Markdown string is intended for direct paste into a Word document (markdown symbols visible; user applies heading styles manually); the HTML string is intended for Word's Paste Special -> HTML path, which preserves heading and paragraph structure automatically.",

  "version": "1.0.0",

  "type": "object",

  "additionalProperties": false,

  "required": [

    "markdown",

    "html"

  ],

  "properties": {

    "markdown": {

      "type": "string",

      "minLength": 1,

      "description": "Markdown rendering of the eight-section budget justification. Section titles render as level-1 ATX headings ('# Section A: Senior Personnel'). Section content is inserted verbatim from the input array, including any sub-subheadings (typically '###' under Section G). Exactly one blank line separates the section heading from its content and one blank line separates adjacent sections. The string ends with a single trailing newline."

    },

    "html": {

      "type": "string",

      "minLength": 1,

      "description": "HTML fragment rendering of the same eight sections. Section titles render as <h1>; sub-subheadings within Section G render as <h2>; paragraphs render as <p>; markdown lists render as <ul>/<ol> with <li> items; bold/italic/code as <strong>/<em>/<code>; markdown tables as <table><thead><tbody>. No <html>, <body>, <div>, <style>, class, or id wrappers \u2014 the fragment is intended to paste inline via Word's Paste Special -> HTML path."

    }

  }

}

Changelog

Source: CHANGELOG.md.

All notable changes to this component. Versions follow semver: MAJOR for output-contract breaks, MINOR for backward-compatible additions, PATCH for wording or clarity.

[1.0.0] — 2026-04-24

  • Initial version. Designed for the fourth (output) step of the nsf-budget-justification-multistep workflow, rendering the reviewed eight-section array into Word-pasteable Markdown and HTML strings.