core.html_diff

Diffs HTML fragments. Nice to show what changed between two revisions of a document for an arbitrary user.

Examples: .. code-block:: pycon

>>> from htmldiff import render_html_diff
>>> render_html_diff('Foo <b>bar</b> baz', 'Foo <i>bar</i> baz')
'<div class="diff">Foo <i class="tagdiff_replaced">bar</i> baz</div>'
>>> render_html_diff('Foo bar baz', 'Foo baz')
'<div class="diff">Foo <del>bar</del> baz</div>'
>>> render_html_diff('Foo baz', 'Foo blah baz')
'<div class="diff">Foo <ins>blah</ins> baz</div>'
copyright:
  1. 2011 by Armin Ronacher

license:

BSD

Attributes

Position

_leading_space_re

_diff_split_re

Classes

StreamDiffer

A class that can diff a stream of Genshi events. It will inject

Functions

diff_genshi_stream(→ genshi.core.Stream)

Renders a creole diff for two texts.

render_html_diff(→ markupsafe.Markup)

Renders the diff between two HTML fragments.

parse_html(→ genshi.input.ET)

Parse an HTML fragment into a Genshi stream.

Module Contents

core.html_diff.Position: TypeAlias = tuple[str | None, int, int][source]
core.html_diff._leading_space_re[source]
core.html_diff._diff_split_re[source]
core.html_diff.diff_genshi_stream(old_stream: genshi.core.Stream, new_stream: genshi.core.Stream) genshi.core.Stream[source]

Renders a creole diff for two texts.

core.html_diff.render_html_diff(old: str, new: str, wrapper_element: str = 'div', wrapper_class: str = 'diff') markupsafe.Markup[source]

Renders the diff between two HTML fragments.

core.html_diff.parse_html(html: str, wrapper_element: str = 'div', wrapper_class: str = 'diff') genshi.input.ET[source]

Parse an HTML fragment into a Genshi stream.

class core.html_diff.StreamDiffer(old_stream: genshi.input.ET, new_stream: genshi.input.ET)[source]

A class that can diff a stream of Genshi events. It will inject <ins> and <del> tags into the stream. It probably breaks in very ugly ways if you pass a random Genshi stream to it. I’m not exactly sure if it’s correct what creoleparser is doing here, but it appears that it’s not using a namespace. That’s fine with me so the tags the StreamDiffer adds are also unnamespaced.

_old: list[StreamEvent][source]
_new: list[StreamEvent][source]
_result: list[StreamEvent][source]
_stack: list[str][source]
_context: str | None[source]
context(kind: str | None) Iterator[None][source]
inject_class(attrs: genshi.core.Attrs, classname: str) genshi.core.Attrs[source]
append(type: genshi.core.StreamEventKind, data: Any, pos: Position) None[source]
text_split(text: str) list[str][source]
cut_leading_space(s: str) tuple[str, str][source]
mark_text(pos: Position, text: str, tag: str) None[source]
diff_text(pos: Position, old_text: str, new_text: str) None[source]
replace(old_start: int, old_end: int, new_start: int, new_end: int) None[source]
delete(start: int, end: int) None[source]
insert(start: int, end: int) None[source]
unchanged(start: int, end: int) None[source]
enter(pos: Any, tag: Any, attrs: dict[str, Any]) None[source]
enter_mark_replaced(pos: Position, tag: str, attrs: genshi.core.Attrs) None[source]
leave(pos: Position, tag: str) bool[source]
leave_all() None[source]
block_process(events: list[StreamEvent]) None[source]
process() None[source]
get_diff_stream() genshi.core.Stream[source]