You can incorporate Markdown into your survey questions and option text to add formatting such as headings, bold text, and italics.
Use the Survey Markdown Previewer to paste the contents of a Python string and check the result in both chat and traditional views before adding it to a survey.
Line breaks
Python evaluates string escapes before the resulting text reaches the Markdown parser. In a single-line Python string, \n creates a newline and \n\n creates the blank line needed to start a new paragraph.
Landscape view follows the normal Markdown rule that treats a single newline as a space, while chat view preserves that newline visually. For a line break that appears consistently in both views, the evaluated string must contain a backslash immediately before the newline. This requires \\\n in a single-line Python string or \\ at the end of a physical line in a triple-quoted string. Two spaces before a newline also create a visible line break, but the backslash is easier to see and copy reliably.
Example question source
s.text_question("This is the first line.\\\nThis is still the same paragraph.\n\nThis is a new paragraph.")
is the same as
s.text_question(
"""This is the first line.\\
This is still the same paragraph.
This is a new paragraph.""")
Rendered output
This is the first line.
This is still the same paragraph.
This is a new paragraph.
Headings
You can insert headings as follows:
s.text_question(
"""# Heading 1
## Heading 2
### Heading 3
#### Heading 4
##### Heading 5
###### Heading 6""")
These display like this:

Lists
s.text_question(
"""### Unordered List
- Item 1
- Subitem 1.1
- Subitem 1.2
- Item 2
- Item 3
# Ordered List
1. First item
2. Second item
1. Subitem 2.1
2. Subitem 2.2
3. Third item
""")
These display like this:

Emphasis
s.text_question(
"""- *Italic text*
- _Italic text_
- **Bold text**
- __Bold text__
- ***Bold and italic text***
- ___Bold and italic text___
- ~~Strikethrough~~
""")
These display like this:

Images
s.text_question(
"""
""")
Use an absolute image URL. Root-relative image paths point at the survey host, which may not contain the referenced asset.

Links
s.text_question("[Markdown Guide](https://www.markdownguide.org)")

Code
s.text_question(
"""### Inline Code
Use `code()` to include inline code.
# Code Block
```python
def hello_world():
print("Hello, World!")
```""")

Tables
s.text_question(
"""| Column 1 | Column 2 | Column 3 |
|----------|----------|----------|
| Row 1 | Data | Value |
| Row 2 | Example | Test |""")

Document and table formatting limits
Survey text uses Markdown, rather than the page layout of a Word document. Ordinary tables with several columns are supported; a cell spanning multiple columns or rows is not. Merged cells do not retain their spanning layout when pasted and may need manual cleanup.
- Use a simple rectangular table with one value per cell. Split merged header cells into separate headings, repeating a heading when necessary.
- Keep cell contents short. Line breaks and multiple paragraphs inside pasted table cells become spaces; put long instructions or separate paragraphs outside the table.
- Do not rely on nested tables, multi-column page layouts, exact column widths, fonts, colors or page breaks to convey meaning. Use headings, lists and ordinary paragraphs instead.
- Use the survey's media controls for images and videos, rather than relying on floating document objects or a pasted document layout.
Formatted clipboard paste is converted to editable Markdown. It does not add support for embedded HTML in respondent question text. After pasting, check that the words, emphasis, links and table relationships still mean what you intended, then preview the survey in both chat and traditional styles on desktop and mobile. See Creating a new survey for the paste workflow.
Horizontal rule
s.text_question(
"""Text above the rule.
---
Text below the rule.""")
Always leave a blank line before and after ---. Without the blank line before it, Markdown treats --- as a level-two heading underline for the preceding text instead of as a horizontal rule.

Task lists
s.text_question(
"""
- [x] Completed Task
- [ ] Incomplete Task
""")

Escaping special characters
s.text_question(
"""
Use a backslash to escape characters:
\\*This text is not italicized\\*
""")
Python needs two backslashes in the source string so that Markdown receives one backslash and escapes the asterisks without triggering an invalid Python escape warning.

Footnotes
s.text_question(
"""
This is an example of a footnote.[^1]
[^1]: Footnote explanation.
""")

Block quotes
Start a line with > to display a block quote:
s.text_question(
"""> This text is displayed as a block quote.""")
Unsupported features
We do not support:
- Emoji shortcodes such as
:smile:. Unicode emoji characters can be used directly. - Embedded HTML
