' . self::html( $m[1] ) . '';
} elseif ( preg_match( '/^`([^`]+)`$/u', $part, $m ) ) {
$out .= '' . esc_html( $m[1] ) . '';
} elseif ( preg_match( '/^\[([^\]]+)\]\(([^)\s]+)\)$/u', $part, $m ) ) {
$href = esc_url( $m[2] );
$out .= '' !== $href ? '' . self::html( $m[1] ) . '' : self::html( $m[1] );
} else {
$out .= esc_html( $part );
}
}
return $out;
}
public static function blocks( $text, array $p_attrs = array(), array $first = array() ) {
$lines = array();
foreach ( is_array( $text ) ? $text : array( (string) $text ) as $chunk ) {
foreach ( preg_split( '/\r\n|\r|\n/', (string) $chunk ) ?: array() as $line ) {
$lines[] = $line;
}
$lines[] = '';
}
$out = '';
$para = array();
$list = array();
$kind = '';
$flush = static function () use ( &$para, &$list, &$kind, &$out, $p_attrs, &$first ) {
if ( $para ) {
$prefix = (string) ( $first['prefix'] ?? '' );
$out .= AIEO_Content_Blocks::paragraph( (array) ( $first['attrs'] ?? array() ) + $p_attrs, $prefix . implode( '
', array_map( array( __CLASS__, 'html' ), $para ) ) );
$para = array();
$first = array();
}
if ( $list ) {
$out .= AIEO_Content_Blocks::list_block( array(), array_map( array( __CLASS__, 'html' ), $list ), 'ol' === $kind );
$list = array();
$kind = '';
}
};
foreach ( $lines as $line ) {
$line = trim( $line );
if ( '' === $line ) {
$flush();
} elseif ( preg_match( '/^(#{2,4})\s+(.+)$/u', $line, $m ) ) {
$flush();
$out .= AIEO_Content_Blocks::heading( array( 'level' => strlen( $m[1] ) ), self::html( $m[2] ) );
} elseif ( preg_match( '/^[-*]\s+(.+)$/u', $line, $m ) ) {
if ( $para || 'ol' === $kind ) {
$flush();
}
$kind = 'ul';
$list[] = $m[1];
} elseif ( preg_match( '/^\d+[.)]\s+(.+)$/u', $line, $m ) ) {
if ( $para || 'ul' === $kind ) {
$flush();
}
$kind = 'ol';
$list[] = $m[1];
} else {
if ( $list ) {
$flush();
}
$para[] = $line;
}
}
$flush();
return $out;
}
public static function plain( $text ) {
$text = preg_replace( '/\*\*(.+?)\*\*/su', '$1', (string) $text );
$text = preg_replace( '/`([^`]+)`/u', '$1', $text );
return (string) preg_replace( '/\[([^\]]+)\]\([^)\s]+\)/u', '$1', $text );
}
const COLOURS = array( 'accent' => 'accent-text', 'success' => 'success', 'warning' => 'warning-ink', 'danger' => 'danger' );
const COLOUR_TOKEN = '/\{\{([a-z][a-z0-9-]*):([^{}]+)\}\}/u';
const LINE_BREAK = ' // ';
public static function heading( $text ) {
$out = '';
foreach ( preg_split( '/(\{\{[a-z][a-z0-9-]*:[^{}]+\}\})/u', (string) $text, -1, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY ) ?: array() as $part ) {
if ( preg_match( '/^' . substr( self::COLOUR_TOKEN, 1, -2 ) . '$/u', $part, $m ) && isset( self::COLOURS[ $m[1] ] ) ) {
$out .= '' . self::html( $m[2] ) . '';
} else {
$out .= self::html( $part );
}
}
return str_replace( self::LINE_BREAK, '
', $out );
}
public static function heading_plain( $text ) {
$text = (string) preg_replace_callback( self::COLOUR_TOKEN, static fn ( $m ) => isset( self::COLOURS[ $m[1] ] ) ? $m[2] : $m[0], (string) $text );
return str_replace( self::LINE_BREAK, ' ', self::plain( $text ) );
}
public static function heading_text( $html ) {
$html = (string) preg_replace_callback(
'#]*\bclass="has-inline-color has-([a-z0-9-]+)-color"[^>]*>(.*?)#su',
static function ( $m ) {
$tone = array_search( $m[1], self::COLOURS, true );
return false === $tone ? $m[2] : '{{' . $tone . ':' . $m[2] . '}}';
},
(string) $html
);
return self::text( (string) preg_replace( '# ?
#i', self::LINE_BREAK, $html ) );
}
public static function text( $html ) {
$html = (string) $html;
$html = preg_replace( '#<(strong|b)\b[^>]*>(.*?)\1>#su', '**$2**', $html );
$html = preg_replace( '#]*>(.*?)#su', '`$1`', $html );
$html = preg_replace_callback(
'#]*href="([^"]*)"[^>]*>(.*?)#su',
static function ( $m ) {
return '[' . $m[2] . '](' . html_entity_decode( $m[1], ENT_QUOTES | ENT_HTML5, 'UTF-8' ) . ')';
},
$html
);
$html = preg_replace( '#
#i', "\n", $html );
return trim( html_entity_decode( wp_strip_all_tags( $html ), ENT_QUOTES | ENT_HTML5, 'UTF-8' ) );
}
}