Skip to content

fix(ipynb): extract titles from string cell sources - #2768

Open
Vasyl Smutok (vsmutok) wants to merge 1 commit into
microsoft:mainfrom
vsmutok:fix/ipynb-string-source
Open

Vasyl Smutok (vsmutok) wants to merge 1 commit into
microsoft:mainfrom
vsmutok:fix/ipynb-string-source

Conversation

@vsmutok

Copy link
Copy Markdown

Summary

nbformat allows a cell's source to be either a list of strings or a single string, and both forms validate. IpynbConverter iterated over source assuming it was a list of lines, so with the single-string form it walked the characters one at a time and line.startswith("# ") never matched — the notebook title was silently dropped while the body still converted correctly.

This normalizes string sources into a list of lines with splitlines(keepends=True) before the title scan. Line endings are preserved, so the generated markdown is byte-for-byte identical for both forms.

Before / after

# source: ["# My Title\n", "hello"]  -> title 'My Title'   (unchanged)
# source: "# My Title\nhello"        -> title None          (before)
# source: "# My Title\nhello"        -> title 'My Title'   (after)

Tests

Added two regression tests in packages/markitdown/tests/test_module_misc.py:

  • test_ipynb_string_source_extracts_title — reproduces the issue.
  • test_ipynb_string_and_list_sources_convert_identically — asserts both source forms produce the same markdown (markdown/code/raw cells, including a source without a trailing newline).

Both fail on main and pass with the fix. Full suite locally on Python 3.14:

1165 passed, 12 skipped

Fixes #2762

nbformat allows a cell's `source` to be either a list of strings or a
single string. `IpynbConverter` iterated over `source` as if it were a
list of lines, so for the single-string form it walked the characters
one by one and `line.startswith("# ")` never matched, silently dropping
the notebook title.

Normalize string sources into a list of lines (keeping line endings so
the rendered markdown is unchanged) before the title scan.

Fixes microsoft#2762
@vsmutok

Copy link
Copy Markdown
Author

Vasyl Smutok (Vasyl Smutok (@vsmutok)) please read the following Contributor License Agreement(CLA). If you agree with the CLA, please reply with the following information.

@microsoft-github-policy-service agree [company="{your company}"]

Options:

  • (default - no company specified) I have sole ownership of intellectual property rights to my Submissions and I am not making Submissions in the course of work for my employer.
@microsoft-github-policy-service agree
  • (when company given) I am making Submissions in the course of work for my employer (or my employer has intellectual property rights in my Submissions by contract or applicable law). I have permission from my employer to make Submissions and enter into this Agreement on behalf of my employer. By signing below, the defined term “You” includes me and my employer.
@microsoft-github-policy-service agree company="Microsoft"

Contributor License Agreement

@microsoft-github-policy-service agree [company="{your company}"]

@vsmutok

Copy link
Copy Markdown
Author

@microsoft-github-policy-service agree

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

IpynbConverter: title is never extracted when a markdown cell's source is a single string (valid nbformat form)

1 participant