Skip to main content
replaced http://stackoverflow.com/ with https://stackoverflow.com/
Source Link

I repeat here this answer on Stack Overflowthis answer on Stack Overflow.

I first posted an answer with not finalized code, as a simple description of the solution I could think, without any test. But later I remained interested, so I worked to make it (hopefully) perfectly functional.

To precisely define what it is meant to do, let me cite my previous answer:

This is a classic dilemma for any CMS or blog, where the teaser should present the begin of an article: often the solution is either stripping text from its tags and cut at a precise count OR keep tags but cut approximately because the tags are counted too...

So here the intent is to take an HTML element with any number of children, and any nesting level and return:

  • the "same" element (i.e. keeping its tag and attributes)
  • where resulting text content (i.e. visible as characters in the resulting page) is limited to a given count
  • where resulting text is built from successive text nodes in their natural order
  • where encountered tags are keeped intact and at their natural place

Here is my actual solution:

function cutKeepingTags(elem, reqCount) {
  var grabText = '',
      missCount = reqCount;
  $(elem).contents().each(function() {
    switch (this.nodeType) {
      case Node.TEXT_NODE:
        // Get node text, limited to missCount.
        grabText += this.data.substr(0,missCount);
        missCount -= Math.min(this.data.length, missCount);
        break;
      case Node.ELEMENT_NODE:
        // Explore current child:
        var childPart = cutKeepingTags(this, missCount);
        grabText += childPart.text;
        missCount -= childPart.count;
        break;
    }
    if (missCount == 0) {
      // We got text enough, stop looping.
      return false;
    }
  });
  return {
    text:
      // Wrap text using current elem tag.
      elem.outerHTML.match(/^<[^>]+>/m)[0]
      + grabText
      + '</' + elem.localName + '>',
    count: reqCount - missCount
  };
}

And here is a working example. (I kept the HTML example posted by the previous question OP)

I repeat here this answer on Stack Overflow.

I first posted an answer with not finalized code, as a simple description of the solution I could think, without any test. But later I remained interested, so I worked to make it (hopefully) perfectly functional.

To precisely define what it is meant to do, let me cite my previous answer:

This is a classic dilemma for any CMS or blog, where the teaser should present the begin of an article: often the solution is either stripping text from its tags and cut at a precise count OR keep tags but cut approximately because the tags are counted too...

So here the intent is to take an HTML element with any number of children, and any nesting level and return:

  • the "same" element (i.e. keeping its tag and attributes)
  • where resulting text content (i.e. visible as characters in the resulting page) is limited to a given count
  • where resulting text is built from successive text nodes in their natural order
  • where encountered tags are keeped intact and at their natural place

Here is my actual solution:

function cutKeepingTags(elem, reqCount) {
  var grabText = '',
      missCount = reqCount;
  $(elem).contents().each(function() {
    switch (this.nodeType) {
      case Node.TEXT_NODE:
        // Get node text, limited to missCount.
        grabText += this.data.substr(0,missCount);
        missCount -= Math.min(this.data.length, missCount);
        break;
      case Node.ELEMENT_NODE:
        // Explore current child:
        var childPart = cutKeepingTags(this, missCount);
        grabText += childPart.text;
        missCount -= childPart.count;
        break;
    }
    if (missCount == 0) {
      // We got text enough, stop looping.
      return false;
    }
  });
  return {
    text:
      // Wrap text using current elem tag.
      elem.outerHTML.match(/^<[^>]+>/m)[0]
      + grabText
      + '</' + elem.localName + '>',
    count: reqCount - missCount
  };
}

And here is a working example. (I kept the HTML example posted by the previous question OP)

I repeat here this answer on Stack Overflow.

I first posted an answer with not finalized code, as a simple description of the solution I could think, without any test. But later I remained interested, so I worked to make it (hopefully) perfectly functional.

To precisely define what it is meant to do, let me cite my previous answer:

This is a classic dilemma for any CMS or blog, where the teaser should present the begin of an article: often the solution is either stripping text from its tags and cut at a precise count OR keep tags but cut approximately because the tags are counted too...

So here the intent is to take an HTML element with any number of children, and any nesting level and return:

  • the "same" element (i.e. keeping its tag and attributes)
  • where resulting text content (i.e. visible as characters in the resulting page) is limited to a given count
  • where resulting text is built from successive text nodes in their natural order
  • where encountered tags are keeped intact and at their natural place

Here is my actual solution:

function cutKeepingTags(elem, reqCount) {
  var grabText = '',
      missCount = reqCount;
  $(elem).contents().each(function() {
    switch (this.nodeType) {
      case Node.TEXT_NODE:
        // Get node text, limited to missCount.
        grabText += this.data.substr(0,missCount);
        missCount -= Math.min(this.data.length, missCount);
        break;
      case Node.ELEMENT_NODE:
        // Explore current child:
        var childPart = cutKeepingTags(this, missCount);
        grabText += childPart.text;
        missCount -= childPart.count;
        break;
    }
    if (missCount == 0) {
      // We got text enough, stop looping.
      return false;
    }
  });
  return {
    text:
      // Wrap text using current elem tag.
      elem.outerHTML.match(/^<[^>]+>/m)[0]
      + grabText
      + '</' + elem.localName + '>',
    count: reqCount - missCount
  };
}

And here is a working example. (I kept the HTML example posted by the previous question OP)

deleted 103 characters in body
Source Link
Jamal
  • 35.2k
  • 13
  • 134
  • 238

I repeat here this answer on Stack Overflow.

I first posted an answer with not finalized code, as a simple description of the solution I could think, without any test. But later I remained interested, so I worked to make it (hopefully) perfectly functional.

To precisely define what it is meant to do, let me cite my previous answer:

This is a classic dilemma for any CMS or blog, where the teaser should present the begin of an article: often the solution is either stripping text from its tags and cut at a precise count OR keep tags but cut approximativelyapproximately because the tags are counted too...

So here the intent is to take an HTML element with any number of children, and any nesting level and return:

  • the "same" element (i.e. keeping its tag and attributes)
  • where resulting text content (i.e. visible as characters in the resulting page) is limited to a given count
  • where resulting text is built from successive text nodes in their natural order
  • where encountered tags are keeped intact and at their natural place

Here is my actual solution:

function cutKeepingTags(elem, reqCount) {
  var grabText = '',
      missCount = reqCount;
  $(elem).contents().each(function() {
    switch (this.nodeType) {
      case Node.TEXT_NODE:
        // Get node text, limited to missCount.
        grabText += this.data.substr(0,missCount);
        missCount -= Math.min(this.data.length, missCount);
        break;
      case Node.ELEMENT_NODE:
        // Explore current child:
        var childPart = cutKeepingTags(this, missCount);
        grabText += childPart.text;
        missCount -= childPart.count;
        break;
    }
    if (missCount == 0) {
      // We got text enough, stop looping.
      return false;
    }
  });
  return {
    text:
      // Wrap text using current elem tag.
      elem.outerHTML.match(/^<[^>]+>/m)[0]
      + grabText
      + '</' + elem.localName + '>',
    count: reqCount - missCount
  };
}

And here is a working example.
   (I kept the HTML example posted by the previous question OP)

Thanks for any comment about how it may be enhanced (or even corrected if I missed something).

I repeat here this answer on Stack Overflow.

I first posted an answer with not finalized code, as a simple description of the solution I could think, without any test. But later I remained interested, so I worked to make it (hopefully) perfectly functional.

To precisely define what it is meant to do, let me cite my previous answer:

This is a classic dilemma for any CMS or blog, where the teaser should present the begin of an article: often the solution is either stripping text from its tags and cut at a precise count OR keep tags but cut approximatively because the tags are counted too...

So here the intent is to take an HTML element with any number of children, and any nesting level and return:

  • the "same" element (i.e. keeping its tag and attributes)
  • where resulting text content (i.e. visible as characters in the resulting page) is limited to a given count
  • where resulting text is built from successive text nodes in their natural order
  • where encountered tags are keeped intact and at their natural place

Here is my actual solution:

function cutKeepingTags(elem, reqCount) {
  var grabText = '',
      missCount = reqCount;
  $(elem).contents().each(function() {
    switch (this.nodeType) {
      case Node.TEXT_NODE:
        // Get node text, limited to missCount.
        grabText += this.data.substr(0,missCount);
        missCount -= Math.min(this.data.length, missCount);
        break;
      case Node.ELEMENT_NODE:
        // Explore current child:
        var childPart = cutKeepingTags(this, missCount);
        grabText += childPart.text;
        missCount -= childPart.count;
        break;
    }
    if (missCount == 0) {
      // We got text enough, stop looping.
      return false;
    }
  });
  return {
    text:
      // Wrap text using current elem tag.
      elem.outerHTML.match(/^<[^>]+>/m)[0]
      + grabText
      + '</' + elem.localName + '>',
    count: reqCount - missCount
  };
}

And here is a working example.
 (I kept the HTML example posted by the previous question OP)

Thanks for any comment about how it may be enhanced (or even corrected if I missed something).

I repeat here this answer on Stack Overflow.

I first posted an answer with not finalized code, as a simple description of the solution I could think, without any test. But later I remained interested, so I worked to make it (hopefully) perfectly functional.

To precisely define what it is meant to do, let me cite my previous answer:

This is a classic dilemma for any CMS or blog, where the teaser should present the begin of an article: often the solution is either stripping text from its tags and cut at a precise count OR keep tags but cut approximately because the tags are counted too...

So here the intent is to take an HTML element with any number of children, and any nesting level and return:

  • the "same" element (i.e. keeping its tag and attributes)
  • where resulting text content (i.e. visible as characters in the resulting page) is limited to a given count
  • where resulting text is built from successive text nodes in their natural order
  • where encountered tags are keeped intact and at their natural place

Here is my actual solution:

function cutKeepingTags(elem, reqCount) {
  var grabText = '',
      missCount = reqCount;
  $(elem).contents().each(function() {
    switch (this.nodeType) {
      case Node.TEXT_NODE:
        // Get node text, limited to missCount.
        grabText += this.data.substr(0,missCount);
        missCount -= Math.min(this.data.length, missCount);
        break;
      case Node.ELEMENT_NODE:
        // Explore current child:
        var childPart = cutKeepingTags(this, missCount);
        grabText += childPart.text;
        missCount -= childPart.count;
        break;
    }
    if (missCount == 0) {
      // We got text enough, stop looping.
      return false;
    }
  });
  return {
    text:
      // Wrap text using current elem tag.
      elem.outerHTML.match(/^<[^>]+>/m)[0]
      + grabText
      + '</' + elem.localName + '>',
    count: reqCount - missCount
  };
}

And here is a working example.  (I kept the HTML example posted by the previous question OP)

Corrected a text error
Source Link
cFreed
  • 2.9k
  • 16
  • 20

I repeat here this answer on Stack Overflow.

I first posted an answer with not finalized code, as a simple description of the solution I could think, without any test. But later I remained interested, so I worked to make it (hopefully) perfectly functional.

To precisely define what it is meant to do, let me cite my previous answer:

This is a classic dilemma for any CMS or blog, where the teaser should present the begin of an article: often the solution is either stripping text from its tags and cut at a precise count OR keep tags but cut approximatively because the tags are counted too...

So here the intent is to have take an HTML element with any number of children, and any nesting level and return:

  • the "same" element (i.e. keeping its tag and attributes)
  • where resulting text content (i.e. visible as characters in the resulting page) is limited to a given count
  • where resulting text is built from successive text nodes in their natural order
  • where encountered tags are keeped intact and at their natural place

Here is my actual solution:

function cutKeepingTags(elem, reqCount) {
  var grabText = '',
      missCount = reqCount;
  $(elem).contents().each(function() {
    switch (this.nodeType) {
      case Node.TEXT_NODE:
        // Get node text, limited to missCount.
        grabText += this.data.substr(0,missCount);
        missCount -= Math.min(this.data.length, missCount);
        break;
      case Node.ELEMENT_NODE:
        // Explore current child:
        var childPart = cutKeepingTags(this, missCount);
        grabText += childPart.text;
        missCount -= childPart.count;
        break;
    }
    if (missCount == 0) {
      // We got text enough, stop looping.
      return false;
    }
  });
  return {
    text:
      // Wrap text using current elem tag.
      elem.outerHTML.match(/^<[^>]+>/m)[0]
      + grabText
      + '</' + elem.localName + '>',
    count: reqCount - missCount
  };
}

And here is a working example.
(I kept the HTML example posted by the previous question OP)

Thanks for any comment about how it may be enhanced (or even corrected if I missed something).

I repeat here this answer on Stack Overflow.

I first posted an answer with not finalized code, as a simple description of the solution I could think, without any test. But later I remained interested, so I worked to make it (hopefully) perfectly functional.

To precisely define what it is meant to do, let me cite my previous answer:

This is a classic dilemma for any CMS or blog, where the teaser should present the begin of an article: often the solution is either stripping text from its tags and cut at a precise count OR keep tags but cut approximatively because the tags are counted too...

So here the intent is to have take an HTML element with any number of children, and any nesting level and return:

  • the "same" element (i.e. keeping its tag and attributes)
  • where resulting text content (i.e. visible as characters in the resulting page) is limited to a given count
  • where resulting text is built from successive text nodes in their natural order
  • where encountered tags are keeped intact and at their natural place

Here is my actual solution:

function cutKeepingTags(elem, reqCount) {
  var grabText = '',
      missCount = reqCount;
  $(elem).contents().each(function() {
    switch (this.nodeType) {
      case Node.TEXT_NODE:
        // Get node text, limited to missCount.
        grabText += this.data.substr(0,missCount);
        missCount -= Math.min(this.data.length, missCount);
        break;
      case Node.ELEMENT_NODE:
        // Explore current child:
        var childPart = cutKeepingTags(this, missCount);
        grabText += childPart.text;
        missCount -= childPart.count;
        break;
    }
    if (missCount == 0) {
      // We got text enough, stop looping.
      return false;
    }
  });
  return {
    text:
      // Wrap text using current elem tag.
      elem.outerHTML.match(/^<[^>]+>/m)[0]
      + grabText
      + '</' + elem.localName + '>',
    count: reqCount - missCount
  };
}

And here is a working example.
(I kept the HTML example posted by the previous question OP)

Thanks for any comment about how it may be enhanced (or even corrected if I missed something).

I repeat here this answer on Stack Overflow.

I first posted an answer with not finalized code, as a simple description of the solution I could think, without any test. But later I remained interested, so I worked to make it (hopefully) perfectly functional.

To precisely define what it is meant to do, let me cite my previous answer:

This is a classic dilemma for any CMS or blog, where the teaser should present the begin of an article: often the solution is either stripping text from its tags and cut at a precise count OR keep tags but cut approximatively because the tags are counted too...

So here the intent is to take an HTML element with any number of children, and any nesting level and return:

  • the "same" element (i.e. keeping its tag and attributes)
  • where resulting text content (i.e. visible as characters in the resulting page) is limited to a given count
  • where resulting text is built from successive text nodes in their natural order
  • where encountered tags are keeped intact and at their natural place

Here is my actual solution:

function cutKeepingTags(elem, reqCount) {
  var grabText = '',
      missCount = reqCount;
  $(elem).contents().each(function() {
    switch (this.nodeType) {
      case Node.TEXT_NODE:
        // Get node text, limited to missCount.
        grabText += this.data.substr(0,missCount);
        missCount -= Math.min(this.data.length, missCount);
        break;
      case Node.ELEMENT_NODE:
        // Explore current child:
        var childPart = cutKeepingTags(this, missCount);
        grabText += childPart.text;
        missCount -= childPart.count;
        break;
    }
    if (missCount == 0) {
      // We got text enough, stop looping.
      return false;
    }
  });
  return {
    text:
      // Wrap text using current elem tag.
      elem.outerHTML.match(/^<[^>]+>/m)[0]
      + grabText
      + '</' + elem.localName + '>',
    count: reqCount - missCount
  };
}

And here is a working example.
(I kept the HTML example posted by the previous question OP)

Thanks for any comment about how it may be enhanced (or even corrected if I missed something).

edited tags; deleted 1 character in body
Source Link
200_success
  • 145.6k
  • 22
  • 191
  • 480
Loading
deleted 19 characters in body; edited tags; edited title
Source Link
200_success
  • 145.6k
  • 22
  • 191
  • 480
Loading
Source Link
cFreed
  • 2.9k
  • 16
  • 20
Loading