<?php /** * Markdown handling * * Handles all Markdown operations and rendering. * * @package System * @author Pierre Lannoy <https://pierre.lannoy.fr/>. * @since 2.0.0 */ namespace Vibes\System; use cebe\markdownparser\GithubMarkdown; /** * Define the Markdown functionality. * * Handles all Markdown operations and rendering. * * @package System * @author Pierre Lannoy <https://pierre.lannoy.fr/>. * @since 2.0.0 */ class Markdown { /** * Get the changelog. * * @param string $file The filename. * @param array $attributes 'style' => 'markdown', 'html'. * 'mode' => 'raw', 'clean'. * @return string The output of the shortcode, ready to print. * @since 2.0.0 */ public function get_shortcode( $file, $attributes ) { $_attributes = shortcode_atts( [ 'style' => 'html', 'mode' => 'clean', ], $attributes ); $style = $_attributes['style']; $mode = $_attributes['mode']; $error = esc_html__( 'Sorry, unable to find or read the specified file.', 'vibes' ); $result = esc_html( $error ); $changelog = VIBES_PLUGIN_DIR . $file; if ( file_exists( $changelog ) ) { try { // phpcs:ignore $content = file_get_contents( $changelog ); if ( $content ) { switch ( $style ) { case 'html': $result = '<div class="markdown">' . $this->html_from_markdown( $content, ( 'clean' === $mode ) ) . '</div>'; break; default: $result = esc_html( $content ); } } } catch ( \Exception $e ) { $result = esc_html( $error ); } } return $result; } /** * Get the changelog. * * @param string $content The filename. * @param array $attributes 'style' => 'markdown', 'html'. * 'mode' => 'raw', 'clean'. * @return string The output of the inline, ready to print. */ public function get_inline( $content, $attributes ) { $_attributes = shortcode_atts( [ 'style' => 'html', 'mode' => 'clean', ], $attributes ); $style = $_attributes['style']; $mode = $_attributes['mode']; if ( $content ) { switch ( $style ) { case 'html': $result = '<div class="markdown">' . $this->html_from_markdown( $content, ( 'clean' === $mode ) ) . '</div>'; break; default: $result = esc_html( $content ); } } return $result; } /** * Format a changelog in html. * * @param string $content The raw changelog in markdown. * @param boolean $clean Optional. Should the output be cleaned?. * @return string The converted changelog, ready to print. * @since 2.0.0 */ private function html_from_markdown( $content, $clean = false ) { $markdown = new GithubMarkdown(); $markdown->html5 = true; $markdown->enableNewlines = true; $result = $markdown->parse( $content ); if ( $clean ) { $result = preg_replace( '/<h1>.*<\/h1>/iU', '', $result ); for ( $i = 8; $i > 1; $i-- ) { $result = str_replace( [ '<h' . $i . '>', '</h' . $i . '>' ], [ '<h' . (string) ( $i + 1 ) . '>', '</h' . (string) ( $i + 1 ) . '>' ], $result ); } $result = preg_replace_callback( '/<h([0-9])>(.*)<\/h([0-9])>/iU', function( $matches ) { return '<h' . $matches[1] . ' id="' . sanitize_title_with_dashes( $matches[2] ) . '">' . $matches[2] . '</h' . $matches[3] . '>'; }, $result ); } return wp_kses( $result, [ 'a' => [ 'href' => [], 'title' => [], 'rel' => [], ], 'blockquote' => [ 'cite' => [] ], 'br' => [], 'p' => [], 'code' => [ 'class' => [] ], 'pre' => [], 'em' => [], 'strong' => [], 'ul' => [], 'ol' => [], 'li' => [], 'h3' => [ 'id' => [] ], 'h4' => [ ], 'h5' => [ ], ] ); } }