From f71ba86ec04e2ce0ff5a0e64f4f20becadcc6ddc Mon Sep 17 00:00:00 2001 From: Leonard Richardson Date: Thu, 26 Apr 2012 23:29:32 -0400 Subject: Added a new method, wrap(). --- NEWS.txt | 2 ++ bs4/element.py | 5 +++++ bs4/tests/test_tree.py | 31 ++++++++++++++++++++++++++----- doc/source/index.rst | 18 ++++++++++++++++-- 4 files changed, 49 insertions(+), 7 deletions(-) diff --git a/NEWS.txt b/NEWS.txt index 46b156e..ecd2164 100644 --- a/NEWS.txt +++ b/NEWS.txt @@ -1,5 +1,7 @@ = 4.0.5 (unreleased) = +* Added a new method, wrap(), which wraps an element in a tag. + * Renamed replace_with_children() to unwrap(), which is easier to understand and also the jQuery name of the function. diff --git a/bs4/element.py b/bs4/element.py index eb7e8aa..3ef6ef1 100644 --- a/bs4/element.py +++ b/bs4/element.py @@ -160,6 +160,11 @@ class PageElement(object): replace_with_children = unwrap replaceWithChildren = unwrap # BS3 + def wrap(self, wrap_inside): + me = self.replace_with(wrap_inside) + wrap_inside.append(me) + return wrap_inside + def extract(self): """Destructively rips this element out of the tree.""" if self.parent is not None: diff --git a/bs4/tests/test_tree.py b/bs4/tests/test_tree.py index 867fdaa..9a10edf 100644 --- a/bs4/tests/test_tree.py +++ b/bs4/tests/test_tree.py @@ -352,7 +352,7 @@ class TestFindAllByAttribute(TreeTest): class TestIndex(TreeTest): """Test Tag.index""" def test_index(self): - tree = self.soup(""" + tree = self.soup("""
Identical Not identical Identical @@ -360,10 +360,10 @@ class TestIndex(TreeTest): Identical with child Also not identical Identical with child - """) - wrap = tree.wrap - for i, element in enumerate(wrap.contents): - self.assertEqual(i, wrap.index(element)) +
""") + div = tree.div + for i, element in enumerate(div.contents): + self.assertEqual(i, div.index(element)) self.assertRaises(ValueError, tree.index, 1) @@ -926,6 +926,27 @@ class TestTreeModification(SoupTest): self.assertEqual(tree.em, None) self.assertEqual(tree.p.text, "Unneeded formatting is unneeded") + def test_wrap(self): + soup = self.soup("I wish I was bold.") + value = soup.string.wrap(soup.new_tag("b")) + self.assertEqual(value.decode(), "I wish I was bold.") + self.assertEqual( + soup.decode(), self.document_for("I wish I was bold.")) + + def test_wrap_extracts_tag_from_elsewhere(self): + soup = self.soup("I wish I was bold.") + soup.b.next_sibling.wrap(soup.b) + self.assertEqual( + soup.decode(), self.document_for("I wish I was bold.")) + + def test_wrap_puts_new_contents_at_the_end(self): + soup = self.soup("I like being bold.I wish I was bold.") + soup.b.next_sibling.wrap(soup.b) + self.assertEqual(2, len(soup.b.contents)) + self.assertEqual( + soup.decode(), self.document_for( + "I like being bold.I wish I was bold.")) + def test_extract(self): soup = self.soup( 'Some content. More content.') diff --git a/doc/source/index.rst b/doc/source/index.rst index ef60c24..0e049d1 100644 --- a/doc/source/index.rst +++ b/doc/source/index.rst @@ -1894,11 +1894,24 @@ and replaces it with the tag or string of your choice:: ``replace_with()`` returns the tag or string that was replaced, so that you can examine it or add it back to another part of the tree. +``wrap()`` +---------- + +``PageElement.wrap()`` wraps an element in the tag you specify. It +returns the new wrapper. (New in Beautiful Soup 4.0.5.) + + soup = BeautifulSoup("

I wish I was bold.

") + soup.p.string.wrap(soup.new_tag("b")) + # I wish I was bold. + + soup.p.wrap(soup.new_tag("div") + #

I wish I was bold.

+ ``unwrap()`` --------------------------- -``Tag.unwrap()`` replaces a tag with whatever's inside -that tag. It's good for stripping out markup:: +``Tag.unwrap()`` is the opposite of ``wrap()``. It replaces a tag with +whatever's inside that tag. It's good for stripping out markup:: markup = 'I linked to example.com' soup = BeautifulSoup(markup) @@ -1911,6 +1924,7 @@ that tag. It's good for stripping out markup:: Like ``replace_with()``, ``unwrap()`` returns the tag that was replaced. + Output ====== -- cgit v1.2.3