` an older theme
// emits, and of the bare text a `[caption]` shortcode carries — so none
// of them needs its own pattern for the words, only for the box.
foreach ( array( self::CAPTION_SHORTCODE, self::FIGURE, self::LEGACY_BOX ) as $pattern ) {
if ( ! preg_match_all( $pattern, $html, $boxes, PREG_OFFSET_CAPTURE ) ) {
continue;
}
foreach ( $boxes[0] as $box ) {
$inner = (string) preg_replace( self::TAG, '', (string) $box[0] );
// ⚠️ And the shortcode's OWN brackets, which are text to
// strip_tags: `[caption width="600"][/caption]` around a lone
// picture would otherwise read as a caption saying "caption".
$inner = (string) preg_replace( '/\[\/?caption\b[^\]]*\]/i', '', $inner );
// Tags stripped before the emptiness test: a caption holding only
// a
is an empty caption wearing markup.
if ( '' !== trim( html_entity_decode( strip_tags( $inner ), ENT_QUOTES, 'UTF-8' ) ) ) {
$spans[] = array( (int) $box[1], (int) $box[1] + strlen( (string) $box[0] ) );
}
}
}
return $spans;
}
/** Is this offset inside one of those spans? */
private static function within( $offset, array $spans ) {
foreach ( $spans as $span ) {
if ( $offset >= $span[0] && $offset < $span[1] ) {
return true;
}
}
return false;
}
/**
* The library id WordPress writes onto an inserted image, as `wp-image-123`.
*
* ⭐ 0 is a normal answer, not a failure: an image pasted in by hand, or one
* hotlinked from elsewhere, belongs to no attachment — and its alt still
* needs writing, which is why nothing here requires an id.
*
* @param string $tag The tag.
* @return int
*/
private static function attachment_id( $tag ) {
return preg_match( '/(?