Yes, lua filters operate on the AST (abstract syntax tree).
I think that some pre-processing will be necessary because (AFAIK) the Para (p) element doesn't retain attributes in the AST.
Here's an example using HTML derived from yours (the p element is wrapped in a div). Note: I think perhaps the lua div logic could be simpler, but this seems to work.
% cat kursiv.html
<span class="Kursiv">span-text-with-class</span>
<div class="Normal_fett"><p>para-text-class-from-div</p></div>
% pandoc kursiv.html -L kursiv.lua
<em><span>span-text-with-class</span></em>
<div>
<p><strong>para-text-class-from-div</strong></p>
</div>
% cat kursiv.lua
function Span(span)
local class, index = span.attr.classes:find('Kursiv')
if class then
span.attr.classes:remove(index)
return pandoc.Emph({span})
end
end
function Div(div)
local class, index = div.attr.classes:find('Normal_fett')
if class then
div.attr.classes:remove(index)
div.content = div.content:map(
function(elem)
elem.content = {pandoc.Strong(elem.content)}
return elem
end
)
return div
end
end