diff --git a/news/changelog-1.10.md b/news/changelog-1.10.md
index d43a69482c4..fd0baeae203 100644
--- a/news/changelog-1.10.md
+++ b/news/changelog-1.10.md
@@ -21,6 +21,10 @@ All changes included in 1.10:
- ([#14250](https://github.com/quarto-dev/quarto-cli/issues/14250)): Fix `quarto create` producing read-only files when Quarto is installed via system packages (e.g., `.deb`). Files copied from installed resources now have user-write permission ensured.
+## Lua API
+
+- ([#14297](https://github.com/quarto-dev/quarto-cli/pull/14297)): Fix `quarto.utils.is_empty_node()` returning inverted results for text nodes (`Str`, `Code`, `RawInline`).
+
## Other fixes and improvements
- ([#6651](https://github.com/quarto-dev/quarto-cli/issues/6651)): Fix dart-sass compilation failing in enterprise environments where `.bat` files are blocked by group policy.
diff --git a/src/resources/pandoc/datadir/_utils.lua b/src/resources/pandoc/datadir/_utils.lua
index b312fa2d048..2ea4b0580c1 100644
--- a/src/resources/pandoc/datadir/_utils.lua
+++ b/src/resources/pandoc/datadir/_utils.lua
@@ -592,7 +592,7 @@ local function is_empty_node (node)
return not next(node.caption)
elseif node.text then
-- looks like a code node or text node
- return node.text ~= ''
+ return node.text == ''
else
-- Not sure what this is, but it's probably not empty.
return false
diff --git a/tests/docs/smoke-all/lua/quarto-utils-is-empty-node/test.lua b/tests/docs/smoke-all/lua/quarto-utils-is-empty-node/test.lua
new file mode 100644
index 00000000000..4fd3d8fe7a2
--- /dev/null
+++ b/tests/docs/smoke-all/lua/quarto-utils-is-empty-node/test.lua
@@ -0,0 +1,26 @@
+function Pandoc(doc)
+ local is_empty = quarto.utils.is_empty_node
+
+ -- nil is empty
+ assert(is_empty(nil) == true, "nil should be empty")
+
+ -- text nodes: Str
+ assert(is_empty(pandoc.Str("")) == true, "Str('') should be empty")
+ assert(is_empty(pandoc.Str("hello")) == false, "Str('hello') should not be empty")
+
+ -- text nodes: Code
+ assert(is_empty(pandoc.Code("")) == true, "Code('') should be empty")
+ assert(is_empty(pandoc.Code("x")) == false, "Code('x') should not be empty")
+
+ -- text nodes: RawInline
+ assert(is_empty(pandoc.RawInline("html", "")) == true, "RawInline('') should be empty")
+ assert(is_empty(pandoc.RawInline("html", "
")) == false, "RawInline('
') should not be empty")
+
+ -- container nodes: empty vs non-empty
+ assert(is_empty(pandoc.Para({})) == true, "Para({}) should be empty")
+ assert(is_empty(pandoc.Para({pandoc.Str("hi")})) == false, "Para with content should not be empty")
+
+ -- empty table
+ assert(is_empty({}) == true, "empty table should be empty")
+ assert(is_empty({1}) == false, "non-empty table should not be empty")
+end
diff --git a/tests/docs/smoke-all/lua/quarto-utils-is-empty-node/test.qmd b/tests/docs/smoke-all/lua/quarto-utils-is-empty-node/test.qmd
new file mode 100644
index 00000000000..3d0c81aa31a
--- /dev/null
+++ b/tests/docs/smoke-all/lua/quarto-utils-is-empty-node/test.qmd
@@ -0,0 +1,7 @@
+---
+title: is_empty_node tests
+filters:
+ - test.lua
+---
+
+Some content.