Your IP : 216.73.217.176


Current Path : /home/bechata/mp/wp-content/uploads/2022/ejn73c/
Upload File :
Current File : /home/bechata/mp/wp-content/uploads/2022/ejn73c/Modules.tar

MarkdownExtraParser.php000066600000021026151771432760011242 0ustar00<?php
/**
 * Module Name: MarkdownExtraParser
 * Module Description: Parse Markdown plaintext into HTML plaintext.
 *
 * @author Terry Lin
 * @link https://terryl.in/
 *
 * @package Githuber
 * @since 1.7.0
 * @version 1.11.2
 */

namespace Githuber\Module;
use Markdown;
use ParsedownExtra;

class MarkdownExtraParser extends ParsedownExtra {

	// Stores shortcodes we remove and then replace
	protected $preserve_text_hash = array();

	/**
	 * Preserve shortcodes, untouched by Markdown.
	 * This requires use within a WordPress installation.
	 * @var boolean
	 */
	public $preserve_shortcodes = true;

	/**
	 * Preserve single-line <code> blocks.
	 * @var boolean
	 */
	public $preserve_inline_code_blocks = true;

	/**
	 * Constructer.
	 */
	public function __construct() {
		parent::__construct();

		$is_html5_figure = githuber_get_option( 'support_html_figure', 'githuber_extensions' );

		if ( 'no' !== $is_html5_figure ) {
			$this->InlineTypes['%'] = array( 'Figure' );
			$this->inlineMarkerList = '!%"*_&[:<>`~\\';
		}

		$is_allow_shortcode = githuber_get_option( 'allow_shortcode', 'githuber_preferences' );

		if ( 'no' === $is_allow_shortcode ) {
			$this->preserve_shortcodes = false;
		}
	}

	/**
	 * Remove bare <p> elements. <p>s with attributes will be preserved.
	 *
	 * @param  string $text HTML content.
	 * @return string <p>-less content.
	 */
	public function remove_bare_p_tags( $text ) {
		return preg_replace( "#<p>(.*?)</p>(\n|$)#ums", '$1$2', $text );
	}

	/**
	 * Teansform Markdown to HTML.
	 * 
	 * @param string $text Markdown content.
	 */
	public function transform( $text ) {

		// Preserve anything inside a single-line <code> element
		if ( $this->preserve_inline_code_blocks ) {
			$text = $this->single_line_code_preserve( $text );
		}
		// Remove all shortcodes so their interiors are left intact
		if ( $this->preserve_shortcodes ) {
			$text = $this->shortcode_preserve( $text );
		}

		$parsed_content = $this->text( $text );

		$parsed_content = $this->do_restore( $parsed_content );

		return $parsed_content;
	}

	/**
	 * Extend ParseDown for HTML 5 figure tag.
	 *
	 * @param array $excerpt
	 * @return array
	 */
	protected function inlineFigure( $excerpt ) {

        if ( !isset( $excerpt['text'][1] ) || '[' !== $excerpt['text'][1] ) {
            return;
        }

        $excerpt['text']= substr($excerpt['text'], 1);

        $link = $this->inlineLink($excerpt);

        if ( null === $link ) {
            return;
		}

		$attr_href  = $link['element']['attributes']['href'];
		$attr_text  = $link['element']['text'];
		$attr_title = $link['element']['attributes']['title'];
		
		$markup = '<figure>';

		$markup .= '<img src="' . $attr_href . '" alt="' . $attr_text . '">';

		if ( ! empty( $attr_title ) ) {
			$markup .= '<figcaption>' . $attr_title . '</figcaption>';
		}

		$markup .= '</figure>';

        $inline = array(
			'extent'  => $link['extent'] + 1,
			'markup'  => $markup,
            'element' => array(
                'name'       => 'img',
                'attributes' => array(
                    'src' => $attr_href,
                    'alt' => $attr_text,
                ),
            ),
        );

        return $inline;
	}
	
	/**
	 * The below methods are from Jetpack: Markdown modular
	 * 
	 * @link https://github.com/Automattic/jetpack/blob/master/_inc/lib/markdown/gfm.php
	 * @license GPL
	 */

	/**
	 * Retrieve the shortcode regular expression for searching.
	 * @return string A regex for grabbing shortcodes.
	 */
	protected function get_shortcode_regex() {
		$pattern = get_shortcode_regex();

		// don't match markdown link anchors that could be mistaken for shortcodes.
		$pattern .= '(?!\()';

		return "/$pattern/s";
	}

	/**
	 * Called to preserve WP shortcodes from being formatted by Markdown in any way.
	 *
	 * @param  string $text Text in which to preserve shortcodes
	 * @return string Text with shortcodes replaced by a hash that will be restored later
	 */
	protected function shortcode_preserve( $text ) {
		$text = preg_replace_callback( $this->get_shortcode_regex(), array( $this, 'do_remove_text' ), $text );
		return $text;
	}

	/**
	 * Regex callback for text preservation
	 *
	 * @param  array $m Regex $matches array
	 * @return string    A placeholder that will later be replaced by the original text
	 */
	protected function do_remove_text( $m ) {
		return $this->hash_block( $m[0] );
	}
	/**
	 * Call this to store a text block for later restoration.
	 *
	 * @param  string $text Text to preserve for later
	 * @return string  Placeholder that will be swapped out later for the original text
	 */
	protected function hash_block( $text ) {
		$hash                              = md5( $text );
		$this->preserve_text_hash[ $hash ] = $text;
		$placeholder                       = $this->hash_maker( $hash );

		return $placeholder;
	}

	/**
	 * Preserve inline code block contents by HTML encoding them. Useful before getting to KSES stripping.
	 *
	 * @param  string $text Text that may need preserving
	 * @return string Text that was preserved if needed
	 */
	
	public function single_line_code_preserve( $text ) {
		return preg_replace_callback( "/[`]{1}([^\n`]*?[^\n`])[`]{1}/", array( $this, 'do_single_line_code_preserve' ), $text );
	}

	/**
	 * Regex callback for inline code presevation
	 *
	 * @param  array $matches Regex matches
	 * @return string Codeblock with escaped interior
	 */
	public function do_single_line_code_preserve( $matches ) {

		if ( 'yes' === githuber_get_option( 'support_inline_code_keyboard_style', 'githuber_extensions' ) ) {
			$first_char = substr( $matches[1], 0, 1 );
			$last_char  = substr( $matches[1], -1 );
			
			if ( '{' === $first_char && '}' === $last_char ) {
				return '<code class="kb-btn">' . $this->hash_block( esc_html( substr( $matches[1], 1, -1 ) ) ) . '</code>';
			}
		}
		return '<code>' . $this->hash_block( esc_html( $matches[1] ) ) . '</code>';
	}

	/**
	 * Preserve code block contents by HTML encoding them. Useful before getting to KSES stripping.
	 *
	 * @param  string $text Markdown/HTML content
	 * @return string       Markdown/HTML content with escaped code blocks
	 */
	public function codeblock_preserve( $text ) {
		return preg_replace_callback( "/^(\t*[`~]{3})([^`\n]+)?\n([\s\S]*?)\n(\\1)/m", array( $this, 'do_codeblock_preserve' ), $text );
	}

	/**
	 * Regex callback for code block preservation.
	 *
	 * @param  array $matches Regex matches
	 * @return string Codeblock with escaped interior
	 */
	public function do_codeblock_preserve( $matches ) {
		$block = stripslashes( $matches[3] );

		// Issue #209
		$block = str_replace( '&#', '_!_!_', $block );

		// check `
		$block = str_replace( '`', '&#x60;', $block );
		$block = esc_html( $block );
		$block = str_replace( '\\', '\\\\', $block );
		$open  = $matches[1] . $matches[2] . "\n";
		$end   =  "\n" . $matches[4];

		return $open . $block . $end;
	}

	/**
	 * Restore previously preserved (i.e. escaped) code block contents.
	 *
	 * @param  string $text Markdown/HTML content with escaped code blocks
	 * @return string Markdown/HTML content
	 */
	public function codeblock_restore( $text ) {
		return preg_replace_callback( "/^(\t*[`~]{3})([^`\n]+)?\n([\s\S]*?)\n(\\1)/m", array( $this, 'do_codeblock_restore' ), $text );
	}

	/**
	 * Regex callback for code block restoration (unescaping).
	 *
	 * @param  array $matches Regex matches
	 * @return string Codeblock with unescaped interior
	 */
	public function do_codeblock_restore( $matches ) {
		$block = html_entity_decode( $matches[3], ENT_QUOTES );

		// Issue #209
		$block = str_replace( '_!_!_', '&#', $block );

		$block = str_replace( '&#x60;', '`', $block );
		$open  = $matches[1] . $matches[2] . "\n";
		$end   =  "\n" . $matches[4];

		return $open . $block . $end;
	}

	/**
	 * Restores any text preserved by $this->hash_block()
	 *
	 * @param  string $text Text that may have hashed preservation placeholders
	 * @return string Text with hashed preseravtion placeholders replaced by original text
	 */
	protected function do_restore( $text ) {
		// Reverse hashes to ensure nested blocks are restored.
		$hashes = array_reverse( $this->preserve_text_hash, true );
		foreach ( $hashes as $hash => $value ) {
			$placeholder = $this->hash_maker( $hash );
			$text        = str_replace( $placeholder, $value, $text );
		}
		// reset the hash
		$this->preserve_text_hash = array();

		// Restore "`"
		$text = str_replace( '&#x60;', '`', $text );

		return $text;
	}

	/**
	 * Less glamorous than the Keymaker
	 *
	 * @param  string $hash An md5 hash
	 * @return string A placeholder hash
	 */
	protected function hash_maker( $hash ) {
		return 'MARKDOWN_HASH' . $hash . 'MARKDOWN_HASH';
	}
}
MarkdownParser.php000066600000020611151771432760010235 0ustar00<?php
/**
 * Module Name: MarkdownParser
 * Module Description: Parse Markdown plaintext into HTML plaintext.
 *
 * @author Terry Lin
 * @link https://terryl.in/
 *
 * @package Githuber
 * @since 1.0.0
 * @version 1.11.2
 */

namespace Githuber\Module;
use Parsedown;

class MarkdownParser extends Parsedown {

	// Stores shortcodes we remove and then replace
	protected $preserve_text_hash = array();

	/**
	 * Preserve shortcodes, untouched by Markdown.
	 * This requires use within a WordPress installation.
	 * @var boolean
	 */
	public $preserve_shortcodes = true;

	/**
	 * Preserve single-line <code> blocks.
	 * @var boolean
	 */
	public $preserve_inline_code_blocks = true;

	/**
	 * Constructer.
	 */
	public function __construct() {

		$is_html5_figure = githuber_get_option( 'support_html_figure', 'githuber_extensions' );

		if ( 'no' !== $is_html5_figure ) {
			$this->InlineTypes['%'] = array( 'Figure' );
			$this->inlineMarkerList = '!%"*_&[:<>`~\\';
		}

		$is_allow_shortcode = githuber_get_option( 'allow_shortcode', 'githuber_preferences' );

		if ( 'no' === $is_allow_shortcode ) {
			$this->preserve_shortcodes = false;
		}
	}

	/**
	 * Remove bare <p> elements. <p>s with attributes will be preserved.
	 *
	 * @param  string $text HTML content.
	 * @return string <p>-less content.
	 */
	public function remove_bare_p_tags( $text ) {
		return preg_replace( "#<p>(.*?)</p>(\n|$)#ums", '$1$2', $text );
	}

	/**
	 * Teansform Markdown to HTML.
	 * 
	 * @param string $text Markdown content.
	 */
	public function transform( $text ) {

		// Preserve anything inside a single-line <code> element
		if ( $this->preserve_inline_code_blocks ) {
			$text = $this->single_line_code_preserve( $text );
		}
		// Remove all shortcodes so their interiors are left intact
		if ( $this->preserve_shortcodes ) {
			$text = $this->shortcode_preserve( $text );
		}

		$parsed_content = $this->text( $text );

		$parsed_content = $this->do_restore( $parsed_content );

		return $parsed_content;
	}

	/**
	 * Extend ParseDown for HTML 5 figure tag.
	 *
	 * @param array $excerpt
	 * @return array
	 */
	protected function inlineFigure( $excerpt ) {

        if ( !isset( $excerpt['text'][1] ) || '[' !== $excerpt['text'][1] ) {
            return;
        }

        $excerpt['text']= substr($excerpt['text'], 1);

        $link = $this->inlineLink($excerpt);

        if ( null === $link ) {
            return;
		}

		$attr_href  = $link['element']['attributes']['href'];
		$attr_text  = $link['element']['text'];
		$attr_title = $link['element']['attributes']['title'];
		
		$markup = '<figure>';

		$markup .= '<img src="' . $attr_href . '" alt="' . $attr_text . '">';

		if ( ! empty( $attr_title ) ) {
			$markup .= '<figcaption>' . $attr_title . '</figcaption>';
		}

		$markup .= '</figure>';

        $inline = array(
			'extent'  => $link['extent'] + 1,
			'markup'  => $markup,
            'element' => array(
                'name'       => 'img',
                'attributes' => array(
                    'src' => $attr_href,
                    'alt' => $attr_text,
                ),
            ),
        );

        return $inline;
	}
	
	/**
	 * The below methods are from Jetpack: Markdown modular
	 * 
	 * @link https://github.com/Automattic/jetpack/blob/master/_inc/lib/markdown/gfm.php
	 * @license GPL
	 */

	/**
	 * Retrieve the shortcode regular expression for searching.
	 * @return string A regex for grabbing shortcodes.
	 */
	protected function get_shortcode_regex() {
		$pattern = get_shortcode_regex();

		// don't match markdown link anchors that could be mistaken for shortcodes.
		$pattern .= '(?!\()';

		return "/$pattern/s";
	}

	/**
	 * Called to preserve WP shortcodes from being formatted by Markdown in any way.
	 *
	 * @param  string $text Text in which to preserve shortcodes
	 * @return string Text with shortcodes replaced by a hash that will be restored later
	 */
	protected function shortcode_preserve( $text ) {
		$text = preg_replace_callback( $this->get_shortcode_regex(), array( $this, 'do_remove_text' ), $text );
		return $text;
	}

	/**
	 * Regex callback for text preservation
	 *
	 * @param  array $m Regex $matches array
	 * @return string    A placeholder that will later be replaced by the original text
	 */
	protected function do_remove_text( $m ) {
		return $this->hash_block( $m[0] );
	}
	/**
	 * Call this to store a text block for later restoration.
	 *
	 * @param  string $text Text to preserve for later
	 * @return string  Placeholder that will be swapped out later for the original text
	 */
	protected function hash_block( $text ) {
		$hash                              = md5( $text );
		$this->preserve_text_hash[ $hash ] = $text;
		$placeholder                       = $this->hash_maker( $hash );

		return $placeholder;
	}

	/**
	 * Preserve inline code block contents by HTML encoding them. Useful before getting to KSES stripping.
	 *
	 * @param  string $text Text that may need preserving
	 * @return string Text that was preserved if needed
	 */
	public function single_line_code_preserve( $text ) {
		return preg_replace_callback( "/[`]{1}([^\n`]*?[^\n`])[`]{1}/", array( $this, 'do_single_line_code_preserve' ), $text );
	}

	/**
	 * Regex callback for inline code presevation
	 *
	 * @param  array $matches Regex matches
	 * @return string Codeblock with escaped interior
	 */
	public function do_single_line_code_preserve( $matches ) {

		if ( 'yes' === githuber_get_option( 'support_inline_code_keyboard_style', 'githuber_extensions' ) ) {
			if ( '}' === substr( $matches[1], -1 ) && '{' !== substr( $matches[1], 0, 1 ) ) {
				return '<code class="kb-btn">' . $this->hash_block( esc_html( $matches[1] ) ) . '</code>';
			}
		}
		return '<code>' . $this->hash_block( esc_html( $matches[1] ) ) . '</code>';
	}

	/**
	 * Preserve code block contents by HTML encoding them. Useful before getting to KSES stripping.
	 *
	 * @param  string $text Markdown/HTML content
	 * @return string       Markdown/HTML content with escaped code blocks
	 */
	public function codeblock_preserve( $text ) {
		return preg_replace_callback( "/^(\t*[`~]{3})([^`\n]+)?\n([\s\S]*?)\n(\\1)/m", array( $this, 'do_codeblock_preserve' ), $text );
	}

	/**
	 * Regex callback for code block preservation.
	 *
	 * @param  array $matches Regex matches
	 * @return string Codeblock with escaped interior
	 */
	public function do_codeblock_preserve( $matches ) {
		$block = stripslashes( $matches[3] );

		// Issue #209
		$block = str_replace( '&#', '_!_!_', $block );

		// check `
		$block = str_replace( '`', '&#x60;', $block );
		$block = esc_html( $block );
		$block = str_replace( '\\', '\\\\', $block );
		$open  = $matches[1] . $matches[2] . "\n";
		$end   =  "\n" . $matches[4];

		return $open . $block . $end;
	}

	/**
	 * Restore previously preserved (i.e. escaped) code block contents.
	 *
	 * @param  string $text Markdown/HTML content with escaped code blocks
	 * @return string Markdown/HTML content
	 */
	public function codeblock_restore( $text ) {
		return preg_replace_callback( "/^(\t*[`~]{3})([^`\n]+)?\n([\s\S]*?)\n(\\1)/m", array( $this, 'do_codeblock_restore' ), $text );
	}

	/**
	 * Regex callback for code block restoration (unescaping).
	 *
	 * @param  array $matches Regex matches
	 * @return string Codeblock with unescaped interior
	 */
	public function do_codeblock_restore( $matches ) {
		$block = html_entity_decode( $matches[3], ENT_QUOTES );

		// Issue #209
		$block = str_replace( '_!_!_', '&#', $block );

		$block = str_replace( '&#x60;', '`', $block );
		$open  = $matches[1] . $matches[2] . "\n";
		$end   =  "\n" . $matches[4];

		return $open . $block . $end;
	}

	/**
	 * Restores any text preserved by $this->hash_block()
	 *
	 * @param  string $text Text that may have hashed preservation placeholders
	 * @return string Text with hashed preseravtion placeholders replaced by original text
	 */
	protected function do_restore( $text ) {
		// Reverse hashes to ensure nested blocks are restored.
		$hashes = array_reverse( $this->preserve_text_hash, true );
		foreach ( $hashes as $hash => $value ) {
			$placeholder = $this->hash_maker( $hash );
			$text        = str_replace( $placeholder, $value, $text );
		}
		// reset the hash
		$this->preserve_text_hash = array();

		// Restore "`"
		$text = str_replace( '&#x60;', '`', $text );

		return $text;
	}

	/**
	 * Less glamorous than the Keymaker
	 *
	 * @param  string $hash An md5 hash
	 * @return string A placeholder hash
	 */
	protected function hash_maker( $hash ) {
		return 'MARKDOWN_HASH' . $hash . 'MARKDOWN_HASH';
	}
}
Highlight.php000066600000026352151771432760007215 0ustar00<?php
/**
 * Module Name: HightLight
 * Module Description: A syntax highlighter by highlight.js
 *
 * @author Terry Lin
 * @link https://terryl.in/
 *
 * @package Githuber
 * @since 1.0.0
 * @version 1.4.0
 * 
 */

namespace Githuber\Module;

class Highlight extends ModuleAbstract {

	/**
	 * The version of Prism we are using.
	 *
	 * @var string
	 */
	public $highlight_version = '9.15.10';

	/**
	 * The priority order to load CSS file, the value should be higher than theme's.
	 * Overwrite the theme's style to make sure that it's safe to display the correct syntax highlight.
	 *
	 * @var integer
	 */
	public $css_priority = 999;

	// This is what highlight.js uses.
	public static $highlight_codes = array(
		'1c'             => '1C:Enterprise (v7, v8)',
		'abnf'           => 'Augmented Backus-Naur Form',
		'accesslog'      => 'Access log',
		'actionscript'   => 'ActionScript',
		'ada'            => 'Ada',
		'angelscript'    => 'AngelScript',
		'apache'         => 'Apache',
		'applescript'    => 'AppleScript',
		'arcade'         => 'ArcGIS Arcade',
		'arduino'        => 'Arduino',
		'armasm'         => 'ARM Assembly',
		'asciidoc'       => 'AsciiDoc',
		'aspectj'        => 'AspectJ',
		'autohotkey'     => 'AutoHotkey',
		'autoit'         => 'AutoIt',
		'avrasm'         => 'AVR Assembler',
		'awk'            => 'Awk',
		'axapta'         => 'Microsoft Axapta (now Dynamics 365)',
		'bash'           => 'Bash',
		'basic'          => 'Basic',
		'bnf'            => 'Backus–Naur Form',
		'brainfuck'      => 'Brainfuck',
		'c'              => 'C',
		'cal'            => 'C/AL',
		'capnproto'      => 'Cap’n Proto',
		'ceylon'         => 'Ceylon',
		'clean'          => 'Clean',
		'clojure-repl'   => 'Clojure REPL',
		'clojure'        => 'Clojure',
		'cmake'          => 'CMake',
		'coffeescript'   => 'CoffeeScript',
		'coq'            => 'Coq',
		'cos'            => 'Cache Object Script',
		'cpp'            => 'C++',
		'crmsh'          => 'crmsh',
		'crystal'        => 'Crystal',
		'cs'             => 'C#',
		'csp'            => 'CSP',
		'css'            => 'CSS',
		'd'              => 'D',
		'dart'           => 'Dart',
		'delphi'         => 'Delphi',
		'diff'           => 'Diff',
		'django'         => 'Django',
		'dns'            => 'DNS Zone file',
		'dockerfile'     => 'Dockerfile',
		'dos'            => 'DOS .bat',
		'dsconfig'       => 'dsconfig',
		'dts'            => 'Device Tree',
		'dust'           => 'Dust',
		'ebnf'           => 'Extended Backus-Naur Form',
		'elixir'         => 'Elixir',
		'elm'            => 'Elm',
		'erb'            => 'ERB (Embedded Ruby)',
		'erlang-repl'    => 'Erlang REPL',
		'erlang'         => 'Erlang',
		'excel'          => 'Excel',
		'fix'            => 'FIX',
		'flix'           => 'Flix',
		'fortran'        => 'Fortran',
		'fsharp'         => 'F#',
		'gams'           => 'GAMS',
		'gauss'          => 'GAUSS',
		'gcode'          => 'G-code (ISO 6983)',
		'gherkin'        => 'Gherkin',
		'glsl'           => 'GLSL',
		'gml'            => 'GML',
		'go'             => 'Golang',
		'golo'           => 'Golo',
		'gradle'         => 'Gradle',
		'groovy'         => 'Groovy',
		'haml'           => 'Haml',
		'handlebars'     => 'Handlebars',
		'haskell'        => 'Haskell',
		'haxe'           => 'Haxe',
		'hsp'            => 'HSP',
		'htmlbars'       => 'HTMLBars',
		'http'           => 'HTTP (Header Plaintext)',
		'hy'             => 'Hy',
		'inform7'        => 'Inform 7',
		'ini'            => 'TOML, also INI',
		'irpf90'         => 'IRPF90',
		'isbl'           => 'ISBL',
		'java'           => 'Java',
		'javascript'     => 'JavaScript',
		'jboss-cli'      => 'jboss-cli',
		'json'           => 'JSON / JSON with Comments',
		'julia-repl'     => 'Julia REPL',
		'julia'          => 'Julia',
		'kotlin'         => 'Kotlin',
		'lasso'          => 'Lasso',
		'ldif'           => 'LDIF',
		'leaf'           => 'Leaf',
		'less'           => 'Less',
		'lisp'           => 'Lisp',
		'livecodeserver' => 'LiveCode',
		'livescript'     => 'LiveScript',
		'llvm'           => 'LLVM IR',
		'lsl'            => 'LSL (Linden Scripting Language)',
		'lua'            => 'Lua',
		'makefile'       => 'Makefile',
		'markdown'       => 'Markdown',
		'mathematica'    => 'Mathematica',
		'matlab'         => 'Matlab',
		'maxima'         => 'Maxima',
		'mel'            => 'MEL',
		'mercury'        => 'Mercury',
		'mipsasm'        => 'MIPS Assembly',
		'mizar'          => 'Mizar',
		'mojolicious'    => 'Mojolicious',
		'monkey'         => 'Monkey',
		'moonscript'     => 'MoonScript',
		'n1ql'           => 'N1QL',
		'nginx'          => 'Nginx',
		'nimrod'         => 'Nim (formerly Nimrod)',
		'nix'            => 'Nix',
		'nsis'           => 'NSIS',
		'objectivec'     => 'Objective-C',
		'ocaml'          => 'OCaml',
		'openscad'       => 'OpenSCAD',
		'oxygene'        => 'Oxygene',
		'parser3'        => 'Parser3',
		'perl'           => 'Perl',
		'pf'             => 'pf.conf',
		'pgsql'          => 'PostgreSQL SQL dialect and PL/pgSQL',
		'php'            => 'PHP',
		'plaintext'      => 'Plaintext',
		'pony'           => 'Pony',
		'powershell'     => 'PowerShell',
		'processing'     => 'Processing',
		'profile'        => 'Python profile',
		'prolog'         => 'Prolog',
		'properties'     => 'Properties',
		'protobuf'       => 'Protocol Buffers',
		'puppet'         => 'Puppet',
		'purebasic'      => 'PureBASIC',
		'python'         => 'Pythin',
		'q'              => 'Q',
		'qml'            => 'QML',
		'r'              => 'R',
		'reasonml'       => 'ReasonML',
		'rib'            => 'RenderMan RIB',
		'roboconf'       => 'Roboconf',
		'routeros'       => 'Microtik RouterOS script',
		'rsl'            => 'RenderMan RSL',
		'ruby'           => 'Ruby',
		'ruleslanguage'  => 'Oracle Rules Language',
		'rust'           => 'Rust',
		'sas'            => 'SAS',
		'scala'          => 'Scala',
		'scheme'         => 'Scheme',
		'scilab'         => 'Scilab',
		'scss'           => 'SCSS',
		'shell'          => 'Shell Session',
		'smali'          => 'Smali',
		'smalltalk'      => 'Smalltalk',
		'sml'            => 'SML (Standard ML)',
		'sqf'            => 'SQF',
		'sql'            => 'SQL (Structured Query Language)',
		'stan'           => 'Stan',
		'stata'          => 'Stata',
		'step21'         => 'STEP Part 21',
		'stylus'         => 'Stylus',
		'subunit'        => 'SubUnit',
		'swift'          => 'Swift',
		'taggerscript'   => 'Tagger Script',
		'tap'            => 'Test Anything Protocol',
		'tcl'            => 'Tcl',
		'tex'            => 'TeX',
		'thrift'         => 'Thrift',
		'tp'             => 'TP',
		'twig'           => 'Twig',
		'typescript'     => 'TypeScript',
		'vala'           => 'Vala',
		'vbnet'          => 'VB.NET',
		'vbscript-html'  => 'VBScript in HTML',
		'vbscript'       => 'VBScript in HTML',
		'verilog'        => 'Verilog',
		'vhdl'           => 'VHDL',
		'vim'            => 'Vim Script',
		'x86asm'         => 'Intel x86 Assembly',
		'xl'             => 'XL',
		'xml'            => 'HTML, XML',
		'xquery'         => 'XQuery',
		'yaml'           => 'YAML',
		'zephir'         => 'Zephir',
	);

	/**
	 * Constant. Should be same as `Markdown::MD_POST_META_HIGHLIGHT`.
	 */
	const MD_POST_META_HIGHLIGHT = '_githuber_highlightjs';
	
	/**
	 * Constructer.
	 */
	public function __construct() {
		parent::__construct();
	}

	/**
	 * Initialize.
	 *
	 * @return void
	 */
	public function init() {
		add_action( 'wp_enqueue_scripts', array( $this, 'front_enqueue_styles' ), $this->css_priority );
		add_action( 'wp_enqueue_scripts', array( $this, 'front_enqueue_scripts' ) );
		add_action( 'wp_print_footer_scripts', array( $this, 'front_print_footer_scripts' ) );
	}
 
	/**
	 * Register CSS style files for frontend use.
	 * 
	 * @return void
	 */
	public function front_enqueue_styles() {
		if ( $this->is_module_should_be_loaded( self::MD_POST_META_HIGHLIGHT ) ) {
			$highlight_src   = githuber_get_option( 'highlight_src', 'githuber_modules' );
			$highlight_theme = githuber_get_option( 'highlight_theme', 'githuber_modules' );

			$theme = ( 'default' === $highlight_theme || empty( $highlight_theme ) ) ? 'default' : $highlight_theme;

			switch ( $highlight_src ) {
				case 'cloudflare':
					$style_url[] = 'https://cdnjs.cloudflare.com/ajax/libs/highlight.js/' . $this->highlight_version . '/styles/' . $theme . '.min.css';
					break;

				default:
					$style_url[] = $this->githuber_plugin_url . 'assets/vendor/highlight.js/styles/' . $theme . '.min.css';
					break;
			}

			foreach ( $style_url as $key => $url ) {
				wp_enqueue_style( 'highlight-css-' . $key, $url, array(), $this->highlight_version, 'all' );
			}
		}
	}

	/**
	 * Register JS files for frontend use.
	 * 
	 * @return void
	 */
	public function front_enqueue_scripts() {
		if ( $this->is_module_should_be_loaded( self::MD_POST_META_HIGHLIGHT ) ) {
			$highlight_src         = githuber_get_option( 'highlight_src', 'githuber_modules' );
			$post_id               = githuber_get_current_post_id();
			$highlight_meta_string = get_metadata( 'post', $post_id, self::MD_POST_META_HIGHLIGHT );
			$highlight_meta_array  = explode( ',', $highlight_meta_string[0] );

			switch ( $highlight_src ) {
				case 'cloudflare':
					$script_url[] = 'https://cdnjs.cloudflare.com/ajax/libs/highlight.js/' . $this->highlight_version . '/highlight.min.js';

					if ( ! empty( $highlight_meta_array ) ) {
						foreach ( array_reverse( $highlight_meta_array ) as $component_name ) {
							if ( 'c' === $component_name ) {
								$component_name = 'cpp';
							}
							$script_url[] = 'https://cdnjs.cloudflare.com/ajax/libs/highlight.js/' . $this->highlight_version . '/languages/' . $component_name . '.min.js';
						}
					}
					break;

				default: 
					$script_url[] = $this->githuber_plugin_url . 'assets/vendor/highlight.js/highlight.min.js';

					if ( ! empty( $highlight_meta_array ) ) {
						foreach ( array_reverse( $highlight_meta_array ) as $component_name ) {
							if ( 'c' === $component_name ) {
								$component_name = 'cpp';
							}
							$script_url[] = $this->githuber_plugin_url . 'assets/vendor/highlight.js/languages/' . $component_name . '.min.js';
						}
					}

					break;
			}

			foreach ( $script_url as $key => $url ) {
				wp_enqueue_script( 'highlight-js-' . $key, $url, array(), $this->highlight_version, true );
			}
		}
	}

	/**
	 * Print Javascript plaintext in page footer.
	 */
	public function front_print_footer_scripts() {
		$script = '
			<script id="module-highlight-js">
				(function($) {
					$(function() {
						$("pre code").each(function(i, e) {
							var thisclass = $(this).attr("class");

							if (typeof thisclass !== "undefined") {
								if (
									thisclass.indexOf("katex") === -1 &&
									thisclass.indexOf("mermaid") === -1 &&
									thisclass.indexOf("seq") === -1 &&
									thisclass.indexOf("flow") === -1
								) {
									if (typeof hljs !== "undefined") {
										$(this).closest("pre").addClass("hljs");
										hljs.highlightBlock(e);
									} else {
										
										console.log("%c WP Githuber MD %c You have enabled highlight.js modules already, but you have to update this post to take effect, identifying which file should be loaded.\nGithuber MD does not load a whole-fat-packed file for every post.", "background: #222; color: #bada55", "color: #637338");
									}
								}
							}
						});
					});
				})(jQuery);
			</script>
		';
		echo preg_replace( '/\s+/', ' ', $script );
	}
}
KaTeX.php000066600000011256151771432760006257 0ustar00<?php
/**
 * Module Name: KaTex
 * Module Description: Use KaTex markup for complex equations and other geekery.
 *
 * @author Terry Lin
 * @link https://terryl.in/
 *
 * @package Githuber
 * @since 1.0.0
 * @version 1.14.0
 */

namespace Githuber\Module;

class KaTeX extends ModuleAbstract {

	/**
	 * The version of KaTeX we are using.
	 *
	 * @var string
	 */
	public $katex_version = '0.12.0';

	/**
	 * The priority order to load CSS file, the value should be higher than theme's.
	 * Overwrite the theme's style it's safe to display the correct syntax highlight.
	 *
	 * @var integer
	 */
	public $css_priority = 1000;

	/**
	 * Constants.
	 */
	const MD_POST_META_KATEX = '_is_githuber_katex';

	/**
	 * Constructer.
	 */
	public function __construct() {
		parent::__construct();
	}

	/**
	 * Initialize.
	 *
	 * @return void
	 */
	public function init() {
		add_action( 'wp_enqueue_scripts', array( $this, 'front_enqueue_styles'), $this->css_priority );
		add_action( 'wp_enqueue_scripts', array( $this, 'front_enqueue_scripts' ) );
		add_action( 'wp_print_footer_scripts', array( $this, 'front_print_footer_scripts' ) );
	}
 
	/**
	 * Register CSS style files for frontend use.
	 * 
	 * @return void
	 */
	public function front_enqueue_styles() {
		if ( $this->is_module_should_be_loaded( self::MD_POST_META_KATEX ) ) {
			
			$option = githuber_get_option( 'katex_src', 'githuber_modules' );

			switch ( $option ) {
				case 'cloudflare':
					$style_url = 'https://cdnjs.cloudflare.com/ajax/libs/KaTeX/' . $this->katex_version . '/katex.min.css';
					break;

				case 'jsdelivr':
					$style_url = 'https://cdn.jsdelivr.net/npm/katex@' . $this->katex_version . '/dist/katex.min.css';
					break;

				default:
					$style_url = $this->githuber_plugin_url . 'assets/vendor/katex/katex.min.css';
					break;
			} 
			wp_enqueue_style( 'katex', $style_url, array(), $this->katex_version, 'all' );
		}
	}

	/**
	 * Register JS files for frontend use.
	 * 
	 * @return void
	 */
	public function front_enqueue_scripts() {
		if ( $this->is_module_should_be_loaded( self::MD_POST_META_KATEX ) ) {

			$option = githuber_get_option( 'katex_src', 'githuber_modules' );

			switch ( $option ) {
				case 'cloudflare':
					$script_url = 'https://cdnjs.cloudflare.com/ajax/libs/KaTeX/' . $this->katex_version . '/katex.min.js';
					break;

				case 'jsdelivr':
					$script_url = 'https://cdn.jsdelivr.net/npm/katex@' . $this->katex_version . '/dist/katex.min.js';
					break;

				default:
					$script_url = $this->githuber_plugin_url . 'assets/vendor/katex/katex.min.js';
					break;
			} 
			wp_enqueue_script( 'katex', $script_url, array(), $this->katex_version, true );
		}
	}

	/**
	 * Print Javascript plaintext in page footer.
	 */
	public function front_print_footer_scripts() {
		$script = '
			<script id="module-katex">
				(function($) {
					$(function() {
						if (typeof katex !== "undefined") {
                            if ($(".language-katex").length > 0) {
								$(".language-katex").parent("pre").attr("style", "text-align: center; background: none;");
								$(".language-katex").addClass("katex-container").removeClass("language-katex");
								$(".katex-container").each(function() {
									var katexText = $(this).text();
									var el = $(this).get(0);
									if ($(this).parent("code").length == 0) {
										try {
											katex.render(katexText, el)
										} catch (err) {
											$(this).html("<span class=\'err\'>" + err)
										}
									}
								});
							}
							if ($(".katex-inline").length > 0) {
								$(".katex-inline").each(function() {
									var katexText = $(this).text();
									var el = $(this).get(0);
									if ($(this).parent("code").length == 0) {
										try {
											katex.render(katexText, el)
										} catch (err) {
											$(this).html("<span class=\'err\'>" + err)
										}
									}
								});
							}
						}
					});
                })(jQuery);
			</script>
		';
		echo preg_replace( '/\s+/', ' ', $script );
	}

	/**
	 * Katex Inline Markup
	 * 
	 * Ex.
	 * `$$ x_{1,2} = {-b\pm\sqrt{b^2 - 4ac} \over 2a}.$$`
	 *
	 * @param string  $content HTML or Markdown content.
	 * @return void
	 */
	public static function katex_inline_markup( $content ) {

		$regex = '%<code>\$\$((?:[^$]+ |(?<=(?<!\\\\)\\\\)\$ )+)(?<!\\\\)\$\$<\/code>%ix';
		$content = preg_replace_callback( $regex, function() {
			$matches = func_get_arg(0);

			if ( ! empty( $matches[1] ) ) {
				$katex = $matches[1];
				$katex = str_replace( array( '&lt;', '&gt;', '&quot;', '&#039;', '&#038;', '&amp;', "\n", "\r" ), array( '<', '>', '"', "'", '&', '&', ' ', ' ' ), $katex );
				return '<code class="katex-inline">' . trim( $katex ) . '</code>';
			}
		}, $content );

		return $content;
	}
}
ModuleAbstract.php000066600000003146151771432760010213 0ustar00<?php

/**
 * Class ModuleAbstract
 * 
 * Modules are specifically used for frontend.
 *
 * @author Terry Lin
 * @link https://terryl.in/
 *
 * @package Githuber
 * @since 1.0.0
 * @version 1.0.0
 */

namespace Githuber\Module;

abstract class ModuleAbstract {

	/**
	 * The plugin url.
	 *
	 * @var string
	 */
	public $githuber_plugin_url;

	/**
	 * Post Id.
	 *
	 * @var integer
	 */
	public static $front_post_id = 0;

	/**
	 * Constructer.
	 * 
	 * @return void
	 */
	public function __construct() {
		/**
		 * Basic plugin information. Mapping from the Constant in the plugin loader script.
		 */
		$this->githuber_plugin_url  = GITHUBER_PLUGIN_URL;
	}

	/**
	 * Initialize.
	 *
	 * @return void
	 */
	abstract public function init();
	
	/**
	 * Register CSS style files for frontend use.
	 *
	 * @return void
	 */
	abstract public function front_enqueue_styles();

	/**
	 * Register JS files for frontend use.
	 *
	 * @return void
	 */
	abstract public function front_enqueue_scripts();

	/**
	 * Print Javascript plaintext in page footer.
	 *
	 * @return void
	 */
	abstract public function front_print_footer_scripts();

	/**
	 * Check if this module should be loaded.
	 */
	public function is_module_should_be_loaded( $meta_name ) {
		if ( empty( self::$front_post_id ) ) {
			// Get current post ID if an user is viewing a post.
			self::$front_post_id = githuber_get_current_post_id();
		} 
		
		if ( ! empty( self::$front_post_id ) ) {
			$post_meta = get_metadata( 'post', self::$front_post_id, $meta_name );
			if ( empty( $post_meta[0] ) ) {
				return false;
			}
			return (bool) $post_meta[0];
		}
		return false;
	}
}
Mermaid.php000066600000004667151771432760006671 0ustar00<?php
/**
 * Module Name: Mermaid
 * Module Description: Generation of diagrams and flowcharts from text in a similar manner as markdown.
 *
 * @author Terry Lin
 * @link https://terryl.in/
 *
 * @package Githuber
 * @since 1.4.0
 * @version 1.4.0
 */

namespace Githuber\Module;

class Mermaid extends ModuleAbstract {

	/**
	 * The version of flowchart.js we are using.
	 *
	 * @var string
	 */
    public $mermaid_version = '8.9.0';

	/**
	 * Constructer.
	 */
	public function __construct() {
		parent::__construct();
	}

	/**
	 * Constants.
	 */
	const MD_POST_META_MERMAID = '_is_githuber_mermaid';

	/**
	 * Initialize.
	 *
	 * @return void
	 */
	public function init() {
		add_action( 'wp_enqueue_scripts', array( $this, 'front_enqueue_scripts' ) );
		add_action( 'wp_print_footer_scripts', array( $this, 'front_print_footer_scripts' ) );
	}
 
	/**
	 * Register CSS style files for frontend use.
	 * 
	 * @return void
	 */
	public function front_enqueue_styles() {

	}

	/**
	 * Register JS files for frontend use.
	 * 
	 * @return void
	 */
	public function front_enqueue_scripts() {
		if ( $this->is_module_should_be_loaded( self::MD_POST_META_MERMAID ) ) {
			$option = githuber_get_option( 'mermaid_src', 'githuber_modules' );

			switch ( $option ) {
                case 'cloudflare':
                    $script_url = 'https://cdnjs.cloudflare.com/ajax/libs/mermaid/' . $this->mermaid_version . '/mermaid.min.js';
                    break;

				case 'jsdelivr':
                    $script_url = 'https://cdn.jsdelivr.net/npm/mermaid@' . $this->mermaid_version . '/dist/mermaid.min.js';
					break;

				default:
					$script_url = $this->githuber_plugin_url . 'assets/vendor/mermaid/mermaid.min.js';
					break;
			} 

			wp_enqueue_script( 'mermaid', $script_url, array(), $this->mermaid_version, true );
		}
	}

	/**
	 * Print Javascript plaintext in page footer.
	 */
	public function front_print_footer_scripts() {
		$script = '
			<script id="module-mermaid">
				(function($) {
					$(function() {
						if (typeof mermaid !== "undefined") {
                            if ($(".language-mermaid").length > 0) {
								$(".language-mermaid").parent("pre").attr("style", "text-align: center; background: none;");
								$(".language-mermaid").addClass("mermaid").removeClass("language-mermaid");
								mermaid.init();
                            }
						}
					});
                })(jQuery);
			</script>
		';
		echo preg_replace( '/\s+/', ' ', $script );
	}
}
SequenceDiagram.php000066600000007457151771432760010350 0ustar00<?php
/**
 * Module Name: Sequence Diagram
 * Module Description: Turn text into vector UML sequence diagrams.
 * 
 * JavaScript package: https://github.com/bramp/js-sequence-diagrams
 *
 * @author Terry Lin
 * @link https://terryl.in/
 *
 * @package Githuber
 * @since 1.0.0
 * @version 1.0.0
 */

namespace Githuber\Module;

class SequenceDiagram extends ModuleAbstract {

	/**
	 * The version of js-sequence-diagrams.js we are using.
	 *
	 * @var string
	 */
    public $sequence_diagram_version = '1.0.6';

	/**
	 * The version of raphael.js we are using.
	 *
	 * @var string
	 */
	public $raphael_version = '2.2.27';
	
	/**
	 * The version of underscore.js we are using.
	 *
	 * @var string
	 */
    public $underscore_version = '2.2.27';

	/**
	 * Constructer.
	 */
	public function __construct() {
		parent::__construct();
	}

	/**
	 * Constants.
	 */
	const MD_POST_META_SEQUENCE = '_is_githuber_sequence';

	/**
	 * Initialize.
	 *
	 * @return void
	 */
	public function init() {
		add_action( 'wp_enqueue_scripts', array( $this, 'front_enqueue_scripts' ) );
		add_action( 'wp_print_footer_scripts', array( $this, 'front_print_footer_scripts' ) );
	}
 
	/**
	 * Register CSS style files for frontend use.
	 * 
	 * @return void
	 */
	public function front_enqueue_styles() {

	}

	/**
	 * Register JS files for frontend use.
	 * 
	 * @return void
	 */
	public function front_enqueue_scripts() {
		if ( $this->is_module_should_be_loaded( self::MD_POST_META_SEQUENCE ) ) {
			$option = githuber_get_option( 'flowchart_src', 'githuber_modules' );

			switch ( $option ) {
				case 'cloudflare':
					$script_url[0] = 'https://cdnjs.cloudflare.com/ajax/libs/raphael/' . $this->raphael_version . '/raphael.min.js';
					$script_url[1] = 'https://cdnjs.cloudflare.com/ajax/libs/underscore.js/' . $this->underscore_version . '/underscore-min.js';
					$script_url[2] = 'https://cdnjs.cloudflare.com/ajax/libs/js-sequence-diagrams/' . $this->sequence_diagram_version . '/js-sequence-diagram.min.js';
					break;

				case 'jsdelivr':
					$script_url[0] = 'https://cdn.jsdelivr.net/npm/raphael@' . $this->raphael_version . '/raphael.min.js';
					$script_url[1] = 'https://cdn.jsdelivr.net/npm/underscore@' . $this->underscore_version . '/underscore.min.js';
					$script_url[2] = 'https://cdn.jsdelivr.net/gh/bramp/js-sequence-diagrams@v' . $this->sequence_diagram_version . '/build/sequence-diagram-min.js';
					break;

				default:
					$script_url[0] = $this->githuber_plugin_url . 'assets/vendor/raphael/raphael.min.js';
					$script_url[1] = $this->githuber_plugin_url . 'assets/vendor/underscore/underscore.min.js';
					$script_url[2] = $this->githuber_plugin_url . 'assets/vendor/js-sequence-diagrams/sequence-diagram.min.js';
					break;
			} 

			wp_enqueue_script( 'raphael', $script_url[0], array(), $this->raphael_version, true );
			wp_enqueue_script( 'underscore', $script_url[1], array(), $this->underscore_version, true );
			wp_enqueue_script( 'sequence-diagrams', $script_url[2], array(), $this->sequence_diagram_version, true );
		}
	}

	/**
	 * Print Javascript plaintext in page footer.
	 */
	public function front_print_footer_scripts() {
		$script = '
			<script id="module-sequence-diagram">
				(function($) {
					$(function() {
						if (typeof $.fn.sequenceDiagram !== "undefined") {
							$(".language-sequence").parent("pre").attr("style", "text-align: center; background: none;");
							$(".language-seq").parent("pre").attr("style", "text-align: center; background: none;");
							$(".language-sequence").addClass("sequence-diagram").removeClass("language-sequence");
							$(".language-seq").addClass("sequence-diagram").removeClass("language-seq");
							$(".sequence-diagram").sequenceDiagram({
								theme: "simple"
							});
						}
					});
                })(jQuery);
			</script>
		';
		echo preg_replace( '/\s+/', ' ', $script );
	}
}
Clipboard.php000066600000006407151771432760007204 0ustar00<?php
/**
 * Module Name: Clipboard
 * Module Description: Copy text into clipboard.
 *
 * @author Terry Lin
 * @link https://terryl.in/
 *
 * @package Githuber
 * @since 1.9.2
 * @version 1.10.1
 */

namespace Githuber\Module;

class Clipboard extends ModuleAbstract {

	/**
	 * The version of flowchart.js we are using.
	 *
	 * @var string
	 */
    public $clipboard_version = '2.0.4';

	/**
	 * Constructer.
	 */
	public function __construct() {
		parent::__construct();
	}

	/**
	 * Initialize.
	 *
	 * @return void
	 */
	public function init() {
		add_action( 'wp_enqueue_scripts', array( $this, 'front_enqueue_scripts' ) );
		add_action( 'wp_print_footer_scripts', array( $this, 'front_print_footer_scripts' ) );
	}
 
	/**
	 * Register JS files for frontend use.
	 * 
	 * @return void
	 */
	public function front_enqueue_scripts() {
	
        $clipboard_src = githuber_get_option( 'clipboard_src', 'githuber_modules' );

        switch ( $clipboard_src ) {
            case 'cloudflare':
                $script_url = 'https://cdnjs.cloudflare.com/ajax/libs/clipboard.js/' . $this->clipboard_version . '/clipboard.min.js';
                break;

            case 'jsdelivr':
                $script_url = 'https://cdn.jsdelivr.net/npm/clipboard@' . $this->clipboard_version . '/dist/clipboard.min.js';
                break;

            default:
                $script_url = $this->githuber_plugin_url . 'assets/vendor/clipboard/clipboard.min.js';
                break;
        } 

		wp_enqueue_script( 'clipboard', $script_url, array(), $this->clipboard_version, true );
	}

	/**
	 * Register CSS style files for frontend use.
	 */
	public function front_enqueue_styles() {

	}

	/**
	 * Print Javascript plaintext in page footer.
	 */
	public function front_print_footer_scripts() {
		$script = '
			<script id="module-clipboard">

				(function($) {

					$(function() {
	
						var pre = document.getElementsByTagName("pre");
						var pasteContent = document.getElementById("paste-content");
						var hasLanguage = false;
		
						for (var i = 0; i < pre.length; i++) {
							var codeClass = pre[i].children[0].className;
							var isLanguage = codeClass.indexOf("language-");
		
							var excludedCodeClassNames = [
								"language-katex",
								"language-seq",
								"language-sequence",
								"language-flow",
								"language-flowchart",
								"language-mermaid",
							];
		
							var isExcluded = excludedCodeClassNames.indexOf(codeClass);
		
							if (isExcluded !== -1) {
								isLanguage = -1;
							}
		
							if (isLanguage !== -1) {
								var button = document.createElement("button");
								button.className = "copy-button";
								button.textContent = "Copy";
			
								pre[i].appendChild(button);
								hasLanguage = true;
							}
						};

						if (hasLanguage) {
							var copyCode = new ClipboardJS(".copy-button", {
								target: function(trigger) {
									return trigger.previousElementSibling;
								}
							});

							copyCode.on("success", function(event) {
								event.clearSelection();
								event.trigger.textContent = "Copied";
								window.setTimeout(function() {
									event.trigger.textContent = "Copy";
								}, 2000);
							});

						}
					});

				})(jQuery);

			</script>
		';

		echo preg_replace( '/\s+/', ' ', $script );
	}
}
Toc.php000066600000005701151771432760006026 0ustar00<?php
/**
 * Module Name: Table of Content
 * Module Description: Display table of content in article section.
 *
 * @author Terry Lin
 * @link https://terryl.in/
 *
 * @package Githuber
 * @since 1.9.0
 * @version 1.10.1
 */

namespace Githuber\Module;

class Toc extends ModuleAbstract {

	/**
	 * Constructer.
	 */
	public function __construct() {
		parent::__construct();
	}

	public function init() {

		add_action( 'wp_enqueue_scripts', array( $this, 'front_enqueue_scripts' ) );
		add_action( 'wp_print_footer_scripts', array( $this, 'front_print_footer_scripts' ) );

		if ( 'yes' === githuber_get_option( 'display_toc_in_post', 'githuber_modules' ) ) {

			add_filter( 'the_content', function( $string ) {

				// Only single page will display TOC.
				if ( ! is_single() ) {
					return $string;
				}
	
				$css = githuber_get_option( 'post_toc_float', 'githuber_modules' );

				if ( 'yes' === githuber_get_option( 'post_toc_border', 'githuber_modules' ) ) {
					$css .= ' with-border';
				}

				return '<div class="post-toc-block float-' . $css . '"> 
					<div class="post-toc-header">' . __( 'Table of Content', 'wp-githuber-md' ) . '</div>
					<nav id="md-post-toc" class="md-post-toc"></nav>
					</div>' . $string;
			}, 10, 1 );
		}
	}

	/**
	 * Register CSS style files for frontend use.
	 * 
	 * @return void
	 */
	public function front_enqueue_styles() {

	}

	/**
	 * Register JS files for frontend use.
	 * 
	 * @return void
	 */
	public function front_enqueue_scripts() {
	
		// Only single page will display TOC.
		if ( ! is_single() ) {
			return;
		}

		wp_register_script( 'githuber-toc', GITHUBER_PLUGIN_URL . 'assets/js/jquery.toc.min.js', array( 'jquery' ), '1.0.1' );
		wp_enqueue_script( 'githuber-toc' );
	}

	/**
	 * Print Javascript plaintext in page footer.
	 */
	public function front_print_footer_scripts() {

		// Only single page will display TOC.
		if ( ! is_single() ) {
			return;
		}

		$script = '
			<script id="module-toc">
				(function($) {
					$(function() {
		';

		// Show TOC in post.
		if ( 'yes' == githuber_get_option( 'display_toc_in_post', 'githuber_modules' ) ) {

			$script .= '
				$("#md-post-toc").initTOC({
					selector: "h2, h3, h4, h5, h6",
					scope: ".post",
				});

				$("#md-post-toc a").click(function(e) {
					e.preventDefault();
					var aid = $( this ).attr( "href" );
					$( "html, body" ).animate( { scrollTop: $(aid).offset().top - 80 }, "slow" );
				});
			';
		}

		// Show TOC in widget area.
		if ( 'yes' == githuber_get_option( 'is_toc_widget', 'githuber_modules' ) ) {

			$script .= '
				$("#md-widget-toc").initTOC({
					selector: "h2, h3, h4, h5, h6",
					scope: ".post",
				});

				$("#md-widget-toc a").click(function(e) {
					e.preventDefault();
					var aid = $( this ).attr( "href" );
					$( "html, body" ).animate( { scrollTop: $(aid).offset().top - 80 }, "slow" );
				});
			';
		}

		$script .= '
					});
				})(jQuery);
			</script>
		';

		echo preg_replace( '/\s+/', ' ', $script );
	}
}
Prism.php000066600000037107151771432760006400 0ustar00<?php
/**
 * Module Name: Prism
 * Module Description: A syntax highlighter by Prism.js
 *
 * @author Terry Lin
 * @link https://terryl.in/
 *
 * @package Githuber
 * @since 1.0.0
 * @version 1.4.0
 * 
 */

namespace Githuber\Module;

class Prism extends ModuleAbstract {

	/**
	 * The version of Prism we are using.
	 *
	 * @var string
	 */
	public $prism_version = '1.15.0';

	/**
	 * The priority order to load CSS file, the value should be higher than theme's.
	 * Overwrite the theme's style to make sure that it's safe to display the correct syntax highlight.
	 *
	 * @var integer
	 */
	public $css_priority = 999;

	// This is what Prism.js uses.
	public static $prism_codes = array(
		'html'              => 'HTML',
		'xml'               => 'XML',
		'svg'               => 'SVG',
		'mathml'            => 'MathML',
		'css'               => 'CSS',
		'clike'             => 'C-like',
		'javascript'        => 'JavaScript',
		'abap'              => 'ABAP',
		'actionscript'      => 'ActionScript',
		'ada'               => 'Ada',
		'apacheconf'        => 'Apache Configuration',
		'apl'               => 'APL',
		'applescript'       => 'AppleScript',
		'arduino'           => 'Arduino',
		'arff'              => 'ARFF',
		'asciidoc'          => 'AsciiDoc',
		'asm6502'           => '6502 Assembly',
		'aspnet'            => 'ASP.NET (C#)',
		'autohotkey'        => 'AutoHotkey',
		'autoit'            => 'AutoIt',
		'bash'              => 'Bash',
		'basic'             => 'BASIC',
		'batch'             => 'Batch',
		'bison'             => 'Bison',
		'brainfuck'         => 'Brainfuck',
		'bro'               => 'Bro',
		'c'                 => 'C',
		'csharp'            => 'C#',
		'cpp'               => 'C++',
		'coffeescript'      => 'CoffeeScript',
		'clojure'           => 'Clojure',
		'crystal'           => 'Crystal',
		'csp'               => 'Content-Security-Policy',
		'css-extras'        => 'CSS Extras',
		'd'                 => 'D',
		'dart'              => 'Dart',
		'diff'              => 'Diff',
		'django'            => 'Django/Jinja2',
		'docker'            => 'Docker',
		'eiffel'            => 'Eiffel',
		'elixir'            => 'Elixir',
		'elm'               => 'Elm',
		'erb'               => 'ERB',
		'erlang'            => 'Erlang',
		'fsharp'            => 'F#',
		'flow'              => 'Flow',
		'fortran'           => 'Fortran',
		'gedcom'            => 'GEDCOM',
		'gherkin'           => 'Gherkin',
		'git'               => 'Git',
		'glsl'              => 'GLSL',
		'go'                => 'Go',
		'graphql'           => 'GraphQL',
		'groovy'            => 'Groovy',
		'haml'              => 'Haml',
		'handlebars'        => 'Handlebars',
		'haskell'           => 'Haskell',
		'haxe'              => 'Haxe',
		'http'              => 'HTTP',
		'hpkp'              => 'HTTP Public-Key-Pins',
		'hsts'              => 'HTTP Strict-Transport-Security',
		'ichigojam'         => 'IchigoJam',
		'icon'              => 'Icon',
		'inform7'           => 'Inform 7',
		'ini'               => 'Ini',
		'io'                => 'Io',
		'j'                 => 'J',
		'java'              => 'Java',
		'jolie'             => 'Jolie',
		'json'              => 'JSON',
		'julia'             => 'Julia',
		'keyman'            => 'Keyman',
		'kotlin'            => 'Kotlin',
		'latex'             => 'LaTeX',
		'less'              => 'Less',
		'liquid'            => 'Liquid',
		'lisp'              => 'Lisp',
		'livescript'        => 'LiveScript',
		'lolcode'           => 'LOLCODE',
		'lua'               => 'Lua',
		'makefile'          => 'Makefile',
		'markdown'          => 'Markdown',
		'markup-templating' => 'Markup templating',
		'matlab'            => 'MATLAB',
		'mel'               => 'MEL',
		'mizar'             => 'Mizar',
		'monkey'            => 'Monkey',
		'n4js'              => 'N4JS',
		'nasm'              => 'NASM',
		'nginx'             => 'nginx',
		'nim'               => 'Nim',
		'nix'               => 'Nix',
		'nsis'              => 'NSIS',
		'objectivec'        => 'Objective-C',
		'ocaml'             => 'OCaml',
		'opencl'            => 'OpenCL',
		'oz'                => 'Oz',
		'parigp'            => 'PARI/GP',
		'parser'            => 'Parser',
		'pascal'            => 'Pascal',
		'perl'              => 'Perl',
		'php'               => 'PHP',
		'php-extras'        => 'PHP Extras',
		'plsql'             => 'PL/SQL',
		'powershell'        => 'PowerShell',
		'processing'        => 'Processing',
		'prolog'            => 'Prolog',
		'properties'        => '.properties',
		'protobuf'          => 'Protocol Buffers',
		'pug'               => 'Pug',
		'puppet'            => 'Puppet',
		'pure'              => 'Pure',
		'python'            => 'Python',
		'q'                 => 'Q (kdb+ database)',
		'qore'              => 'Qore',
		'r'                 => 'R',
		'jsx'               => 'React JSX',
		'tsx'               => 'React TSX',
		'renpy'             => 'Ren\'py',
		'reason'            => 'Reason',
		'rest'              => 'reST (reStructuredText)',
		'rip'               => 'Rip',
		'roboconf'          => 'Roboconf',
		'ruby'              => 'Ruby',
		'rust'              => 'Rust',
		'sas'               => 'SAS',
		'sass'              => 'Sass (Sass)',
		'scss'              => 'Sass (Scss)',
		'scala'             => 'Scala',
		'scheme'            => 'Scheme',
		'smalltalk'         => 'Smalltalk',
		'smarty'            => 'Smarty',
		'sql'               => 'SQL',
		'soy'               => 'Soy (Closure Template)',
		'stylus'            => 'Stylus',
		'swift'             => 'Swift',
		'tcl'               => 'Tcl',
		'textile'           => 'Textile',
		'twig'              => 'Twig',
		'typescript'        => 'TypeScript',
		'vbnet'             => 'VB.Net',
		'velocity'          => 'Velocity',
		'verilog'           => 'Verilog',
		'vhdl'              => 'VHDL',
		'vim'               => 'vim',
		'visual-basic'      => 'Visual Basic',
		'wasm'              => 'WebAssembly',
		'wiki'              => 'Wiki markup',
		'xeora'             => 'Xeora',
		'xojo'              => 'Xojo (REALbasic)',
		'yaml'              => 'YAML',
	);
	
	// The below codes need a parent componet being loaded before.
	public static $prism_component_parent = array(
		'javascript'        => array( 'clike' ),
		'actionscript'      => array( 'javascript' ),
		'arduino'           => array( 'cpp' ),
		'aspnet'            => array( 'markup' ),
		'bison'             => array( 'c' ),
		'c'                 => array( 'clike' ),
		'csharp'            => array( 'clike' ),
		'cpp'               => array( 'c' ),
		'coffeescript'      => array( 'javascript' ),
		'crystal'           => array( 'ruby' ),
		'css-extras'        => array( 'css' ),
		'd'                 => array( 'clike' ),
		'dart'              => array( 'clike' ),
		'django'            => array( 'markup' ),
		'erb'               => array( 'ruby', 'markup-templating' ),
		'fsharp'            => array( 'clike' ),
		//'flow'            => array( 'javascript' ),
		'glsl'              => array( 'clike' ),
		'go'                => array( 'clike' ),
		'groovy'            => array( 'clike' ),
		'haml'              => array( 'ruby' ),
		'handlebars'        => array( 'markup-templating' ),
		'haxe'              => array( 'clike' ),
		'java'              => array( 'clike' ),
		'jolie'             => array( 'clike' ),
		'kotlin'            => array( 'clike' ),
		'less'              => array( 'css' ),
		'markdown'          => array( 'markup' ),
		'markup-templating' => array( 'markup' ),
		'n4js'              => array( 'javascript' ),
		'nginx'             => array( 'clike' ),
		'objectivec'        => array( 'c' ),
		'opencl'            => array( 'cpp' ),
		'parser'            => array( 'markup' ),
		'php'               => array( 'clike', 'markup-templating' ),
		'php-extras'        => array( 'php' ),
		'plsql'             => array( 'sql' ),
		'processing'        => array( 'clike' ),
		'protobuf'          => array( 'clike' ),
		'pug'               => array( 'javascript' ),
		'qore'              => array( 'clike' ),
		'jsx'               => array( 'markup', 'javascript' ),
		'tsx'               => array( 'jsx', 'typescript'),
		'reason'            => array( 'clike' ),
		'ruby'              => array( 'clike' ),
		'sass'              => array( 'css' ),
		'scss'              => array( 'css' ),
		'scala'             => array( 'java' ),
		'smarty'            => array( 'markup-templating' ),
		'soy'               => array( 'markup-templating' ),
		'swift'             => array( 'clike' ),
		'textile'           => array( 'markup' ),
		'twig'              => array( 'markup' ),
		'typescript'        => array( 'javascript' ),
		'vbnet'             => array( 'basic' ),
		'velocity'          => array( 'markup' ),
		'wiki'              => array( 'markup' ),
		'xeora'             => array( 'markup' )
	);

	/**
	 * Constant. Should be same as `Markdown::MD_POST_META_PRISM`.
	 */
	const MD_POST_META_PRISM = '_githuber_prismjs';
	
	/**
	 * Constructer.
	 */
	public function __construct() {
		parent::__construct();
	}

	/**
	 * Initialize.
	 *
	 * @return void
	 */
	public function init() {
		add_action( 'wp_enqueue_scripts', array( $this, 'front_enqueue_styles' ), $this->css_priority );
		add_action( 'wp_print_footer_scripts', array( $this, 'auto_loader_config_scripts' ) );
		add_action( 'wp_enqueue_scripts', array( $this, 'front_enqueue_scripts' ) );
		add_action( 'wp_print_footer_scripts', array( $this, 'front_print_footer_scripts' ) );
	}
 
	/**
	 * Register CSS style files for frontend use.
	 * 
	 * @return void
	 */
	public function front_enqueue_styles() {

		if ( $this->is_module_should_be_loaded( self::MD_POST_META_PRISM ) ) {
			$prism_src         = githuber_get_option( 'prism_src', 'githuber_modules' );
			$prism_theme       = githuber_get_option( 'prism_theme', 'githuber_modules' );
			$prism_line_number = githuber_get_option( 'prism_line_number', 'githuber_modules' );
			$theme             = ( 'default' === $prism_theme || empty( $prism_theme ) ) ? 'prism' : 'prism-' . $prism_theme;

			switch ( $prism_src ) {
				case 'cloudflare':
					$style_url[] = 'https://cdnjs.cloudflare.com/ajax/libs/prism/' . $this->prism_version . '/themes/' . $theme . '.min.css';
					if ( 'yes' === $prism_line_number ) {
						$style_url[] = 'https://cdnjs.cloudflare.com/ajax/libs/prism/' . $this->prism_version . '/plugins/line-numbers/prism-line-numbers.min.css';
					}
					break;

				case 'jsdelivr':
					$style_url[] = 'https://cdn.jsdelivr.net/npm/prismjs@' . $this->prism_version . '/themes/' . $theme . '.css';
					if ( 'yes' === $prism_line_number ) {
						$style_url[] = 'https://cdnjs.cloudflare.com/ajax/libs/prism/' . $this->prism_version . '/plugins/line-numbers/prism-line-numbers.css';
					}
					break;

				default:
					$style_url[] = $this->githuber_plugin_url . 'assets/vendor/prism/themes/' . $theme . '.min.css';
					if ( 'yes' === $prism_line_number ) {
						$style_url[] = $this->githuber_plugin_url . 'assets/vendor/prism/plugins/line-numbers/prism-line-numbers.css';
					}
					break;
			}

			foreach ( $style_url as $key => $url ) {
				wp_enqueue_style( 'prism-css-' . $key, $url, array(), $this->prism_version, 'all' );
			}
		}
	}

	/**
	 * Register JS files for frontend use.
	 * 
	 * @return void
	 */
	public function front_enqueue_scripts() {
		if ( $this->is_module_should_be_loaded( self::MD_POST_META_PRISM ) ) {
			$prism_src         = githuber_get_option( 'prism_src', 'githuber_modules' );
			$prism_line_number = githuber_get_option( 'prism_line_number', 'githuber_modules' );
			$post_id           = githuber_get_current_post_id();
			$prism_meta_string = get_metadata( 'post', $post_id, self::MD_POST_META_PRISM );
			$prism_meta_array  = explode( ',', $prism_meta_string[0] );

			switch ( $prism_src ) {
				case 'cloudflare':
					$script_url[] = 'https://cdnjs.cloudflare.com/ajax/libs/prism/' . $this->prism_version . '/components/prism-core.min.js';
					$script_url[] = 'https://cdnjs.cloudflare.com/ajax/libs/prism/' . $this->prism_version . '/prism.min.js';

					if ( 'yes' === $prism_line_number ) {
						$script_url[] = 'https://cdnjs.cloudflare.com/ajax/libs/prism/' . $this->prism_version . '/plugins/line-numbers/prism-line-numbers.min.js';
					}

					// AutoLoader plugin
					$script_url[] = 'https://cdnjs.cloudflare.com/ajax/libs/prism/' . $this->prism_version . '/plugins/autoloader/prism-autoloader.min.js';

					break;

				case 'jsdelivr':
					$script_url[] = 'https://cdn.jsdelivr.net/npm/prismjs@' . $this->prism_version . '/components/prism-core.min.js';
					$script_url[] = 'https://cdn.jsdelivr.net/npm/prismjs@' . $this->prism_version . '/prism.min.js';

					if ( 'yes' === $prism_line_number ) {
						$script_url[] = 'https://cdn.jsdelivr.net/npm/prismjs@' . $this->prism_version . '/plugins/line-numbers/prism-line-numbers.min.js';
					}

					// AutoLoader plugin (Add since 1.11.4)
					$script_url[] = 'https://cdn.jsdelivr.net/npm/prismjs@' . $this->prism_version . '/plugins/autoloader/prism-autoloader.min.js';

					break;

				default: 
					$script_url[] = $this->githuber_plugin_url . 'assets/vendor/prism/components/prism-core.min.js';
					$script_url[] = $this->githuber_plugin_url . 'assets/vendor/prism/prism.min.js';

					if ( 'yes' === $prism_line_number ) {
						$script_url[] = $this->githuber_plugin_url . 'assets/vendor/prism/plugins/line-numbers/prism-line-numbers.min.js';
					}

					// AutoLoader plugin (Add since 1.11.4)
					$script_url[] = $this->githuber_plugin_url . 'assets/vendor/prism/plugins/autoloader/prism-autoloader.min.js';

					break;
			}

			foreach ( $script_url as $key => $url ) {
				wp_enqueue_script( 'prism-js-' . $key, $url, array(), $this->prism_version, true );
			}
		}
	}

	/**
	 * Configure auto loader path.
	 * 
	 * @since 1.11.4
	 */
	public function auto_loader_config_scripts() {
		if ( $this->is_module_should_be_loaded( self::MD_POST_META_PRISM ) ) {
			$prism_src = githuber_get_option( 'prism_src', 'githuber_modules' );

			switch ( $prism_src ) {
				case 'cloudflare':
					$script_path = 'https://cdnjs.cloudflare.com/ajax/libs/prism/' . $this->prism_version . '/components/';

					break;

				case 'jsdelivr':
					$script_path = 'https://cdn.jsdelivr.net/npm/prismjs@' . $this->prism_version . '/components/';

					break;

				default: 
					$script_path = $this->githuber_plugin_url . 'assets/vendor/prism/components/';

					break;
			}

			$script = '
				<script id="auto_loader_config_scripts">
					Prism.plugins.autoloader.languages_path = "' . $script_path . '";
				</script>
			';

			echo preg_replace( '/\s+/', ' ', $script );
		}
	}

	/**
	 * Print Javascript plaintext in page footer.
	 */
	public function front_print_footer_scripts() {
		$prism_line_number = githuber_get_option( 'prism_line_number', 'githuber_modules' );

		if ( 'yes' === $prism_line_number ) {
			$script = '
				<script id="module-prism-line-number">
					(function($) {
						$(function() {
							$("code").each(function() {
								var parent_div = $(this).parent("pre");
								var pre_css = $(this).attr("class");
								if (typeof pre_css !== "undefined" && -1 !== pre_css.indexOf("language-")) {
									parent_div.addClass("line-numbers");
								}
							});
						});
					})(jQuery);
				</script>
			';
			echo preg_replace( '/\s+/', ' ', $script );
		}
	}

	/**
	 * (Deprecated since 1.11.4) (Use auto-loader instead)
	 * 
	 *
	 * Check if component is already loaded or not.
	 * Those scripts are already included in prism.js, so we do not need to load those scripts again.
	 *
	 * @param string $name Prism component name.
	 *
	 * @return boolean
	 */
	public function is_component_already_loaded( $name ) {
		switch ( $name ) {
			case 'markup':
			case 'xml':
			case 'html':
			case 'mathml':
			case 'svg':
			case 'clike':
			case 'javascript':
			case 'js':
				return true;
				break;
			default:
				return false;
		}
	}
}
Emojify.php000066600000007220151771432760006701 0ustar00<?php
/**
 * Module Name: Emoji
 * Module Description: Emoji are ideograms and smileys used in electronic messages and web pages.
 *
 * @author Terry Lin
 * @link https://terryl.in/
 *
 * @package Githuber
 * @since 1.0.0
 * @version 1.14.0
 */

namespace Githuber\Module;

/**
 * Emogify
 */
class Emojify extends ModuleAbstract {

	/**
	 * The version of Emojify we are using.
	 *
	 * @var string
	 */
	public $emojify_version = '1.1.0';

	/**
	 * The priority order to load CSS file, the value should be higher than theme's.
	 *
	 * @var integer
	 */
	public $css_priority = 1000;

	/**
	 * Constructer.
	 */
	public function __construct() {
		parent::__construct();
	}

	/**
	 * Initialize.
	 *
	 * @return void
	 */
	public function init() {
		add_action( 'wp_enqueue_scripts', array( $this, 'front_enqueue_styles'), $this->css_priority );
		add_action( 'wp_enqueue_scripts', array( $this, 'front_enqueue_scripts' ) );
		add_action( 'wp_print_footer_scripts', array( $this, 'front_print_footer_scripts' ) );
	}

	/**
	 * Register CSS style files for frontend use.
	 * 
	 * @return void
	 */
	public function front_enqueue_styles() {

		$option = githuber_get_option( 'emojify_src', 'githuber_modules' );

		switch ( $option ) {
			case 'cloudflare':
				$style_url = 'https://cdnjs.cloudflare.com/ajax/libs/emojify.js/' . $this->emojify_version . '/css/basic/emojify.min.css';
				break;

			case 'jsdelivr':
				$style_url = 'https://cdn.jsdelivr.net/npm/emojify.js@' . $this->emojify_version . '/dist/css/basic/emojify.min.css';
				break;

			default:
				$style_url = $this->githuber_plugin_url . 'assets/vendor/emojify/css/emojify.min.css';
				break;
		}
		wp_enqueue_style( 'emojify', $style_url, array(), $this->emojify_version, 'all' );
	}

	/**
	 * Register JS files for frontend use.
	 * 
	 * @return void
	 */
	public function front_enqueue_scripts() {

		$option = githuber_get_option( 'emojify_src', 'githuber_modules' );

		switch ( $option ) {
			case 'cloudflare':
				$script_url = 'https://cdnjs.cloudflare.com/ajax/libs//emojify.js/' . $this->emojify_version . '/js/emojify.min.js';
				break;

			case 'jsdelivr':
				$script_url = 'https://cdn.jsdelivr.net/npm/emojify.js@' . $this->emojify_version . '/dist/js/emojify.min.js';
				break;

			default:
				$script_url = $this->githuber_plugin_url . 'assets/vendor/emojify/js/emojify.min.js';
				break;
		} 
		wp_enqueue_script( 'emojify', $script_url, array(), $this->emojify_version, true );
	}

	/**
	 * Print Javascript plaintext in page footer.
	 */
	public function front_print_footer_scripts() {

		$option = githuber_get_option( 'emojify_src', 'githuber_modules' );

		switch ( $option ) {
			case 'cloudflare':
				// https://cdnjs.cloudflare.com/ajax/libs/emojify.js/1.1.0/images/basic/+1.png
				$img_dir = 'https://cdnjs.cloudflare.com/ajax/libs//emojify.js/' . $this->emojify_version . '/images/basic';
				break;

			case 'jsdelivr':
				// https://cdn.jsdelivr.net/npm/emojify.js@1.1.0/dist/images/basic/+1.png
				$img_dir = 'https://cdn.jsdelivr.net/npm/emojify.js@' . $this->emojify_version . '/dist/images/basic';
				break;

			default:
				$img_dir = $this->githuber_plugin_url . 'assets/vendor/emojify/images';
				break;
		} 

		$script = '
			<script id="module-emojify">
				(function($) {
					$(function() {
						if (typeof emojify !== "undefined") {
							emojify.setConfig({
								img_dir: "' . $img_dir . '",
								blacklist: {
									"classes": ["no-emojify"],
									"elements": ["script", "textarea", "pre", "code"]
								}
							});
							emojify.run();
						} else {
							console.log("[wp-githuber-md] emogify is undefined.");
						}
					});
				})(jQuery);
			</script>
		';
		echo $script;
	}
}
FlowChart.php000066600000006047151771432760007176 0ustar00<?php
/**
 * Module Name: Flow Chart
 * Module Description: Draws simple SVG flow chart diagrams from textual representation of the diagram.
 *
 * @author Terry Lin
 * @link https://terryl.in/
 *
 * @package Githuber
 * @since 1.0.0
 * @version 1.0.0
 */

namespace Githuber\Module;

class FlowChart extends ModuleAbstract {

	/**
	 * The version of flowchart.js we are using.
	 *
	 * @var string
	 */
    public $flowchart_version = '1.14.1'; // 1.11.3 => 1.14.1

	/**
	 * The version of raphael.js we are using.
	 *
	 * @var string
	 */
	public $raphael_version = '2.2.27';
	
	/**
	 * Constants.
	 */
	const MD_POST_META_FLOW = '_is_githuber_flow_chart';

	/**
	 * Constructer.
	 */
	public function __construct() {
		parent::__construct();
	}

	/**
	 * Initialize.
	 *
	 * @return void
	 */
	public function init() {
		add_action( 'wp_enqueue_scripts', array( $this, 'front_enqueue_scripts' ) );
		add_action( 'wp_print_footer_scripts', array( $this, 'front_print_footer_scripts' ) );
	}
 
	/**
	 * Register CSS style files for frontend use.
	 * 
	 * @return void
	 */
	public function front_enqueue_styles() {

	}

	/**
	 * Register JS files for frontend use.
	 * 
	 * @return void
	 */
	public function front_enqueue_scripts() {

		if ( $this->is_module_should_be_loaded( self::MD_POST_META_FLOW ) ) {

			$option  = githuber_get_option( 'flowchart_src', 'githuber_modules' );

			switch ( $option ) {
				case 'cloudflare':
					$script_url[0] = 'https://cdnjs.cloudflare.com/ajax/libs/raphael/' . $this->raphael_version . '/raphael.min.js';
					$script_url[1] = 'https://cdnjs.cloudflare.com/ajax/libs/flowchart/' . $this->flowchart_version . '/flowchart.min.js';
					break;

				case 'jsdelivr':
					$script_url[0] = 'https://cdn.jsdelivr.net/npm/raphael@' . $this->raphael_version . '/raphael.min.js';

					// It doesn't have the latest files in `release` folder on jsdelivr, rollback to 1.12.1
					$this->flowchart_version = '1.12.1';
					$script_url[1] = 'https://cdn.jsdelivr.net/npm/flowchart.js@' . $this->flowchart_version . '/release/flowchart.min.js';
					break;

				default:
					$script_url[0] = $this->githuber_plugin_url . 'assets/vendor/raphael/raphael.min.js';
					$script_url[1] = $this->githuber_plugin_url . 'assets/vendor/flowchart/flowchart.min.js';
					break;
			} 
			wp_enqueue_script( 'raphael', $script_url[0], array(), $this->raphael_version, true );
			wp_enqueue_script( 'flowchart', $script_url[1], array(), $this->flowchart_version, true );
		}
	}

	/**
	 * Print Javascript plaintext in page footer.
	 */
	public function front_print_footer_scripts() {
		$script = '
			<script id="module-flowchart">
				(function($) {
					$(function() {
						if (typeof $.fn.flowChart !== "undefined") {
							if ($(".language-flow").length > 0) {
								$(".language-flow").parent("pre").attr("style", "text-align: center; background: none;");
								$(".language-flow").addClass("flowchart").removeClass("language-flow");
								$(".flowchart").flowChart();
							}
						}
					});
				})(jQuery);
			</script>
		';
		echo preg_replace( '/\s+/', ' ', $script );
	}
}
MathJax.php000066600000011776151771432760006646 0ustar00<?php
/**
 * Module Name: MathJax
 * Module Description: Use MathJax markup for complex equations and other geekery.
 *
 * @author Terry Lin
 * @link https://terryl.in/
 *
 * @package Githuber
 * @since 1.0.0
 * @version 1.7.0
 */

namespace Githuber\Module;

class MathJax extends ModuleAbstract {

	/**
	 * The version of MathJax we are using.
	 *
	 * @var string
	 */
	public $mathjax_version = '2.7.7';

	/**
	 * The priority order to load CSS file, the value should be higher than theme's.
	 * Overwrite the theme's style it's safe to display the correct syntax highlight.
	 *
	 * @var integer
	 */
	public $css_priority = 1000;

	/**
	 * Constants.
	 */
	const MD_POST_META_MATHJAX = '_is_githuber_mathjax';

	/**
	 * Constructer.
	 */
	public function __construct() {
		parent::__construct();
	}

	/**
	 * Initialize.
	 *
	 * @return void
	 */
	public function init() {
		//add_action( 'wp_enqueue_scripts', array( $this, 'front_enqueue_styles'), $this->css_priority );
		add_action( 'wp_enqueue_scripts', array( $this, 'front_enqueue_scripts' ) );
		add_action( 'wp_print_footer_scripts', array( $this, 'front_print_footer_scripts' ) );
	}
 
	/**
	 * Register CSS style files for frontend use.
	 * 
	 * @return void
	 */
	public function front_enqueue_styles() {

	}

	/**
	 * Register JS files for frontend use.
	 * 
	 * @return void
	 */
	public function front_enqueue_scripts() {
		if ( $this->is_module_should_be_loaded( self::MD_POST_META_MATHJAX ) ) {

            $option = githuber_get_option( 'mathjax_src', 'githuber_modules' );

			switch ( $option ) {
                case 'cloudflare':
					$script_url = 'https://cdnjs.cloudflare.com/ajax/libs/mathjax/' . $this->mathjax_version . '/MathJax.js';
					break;

                case 'jsdelivr':
					$script_url = 'https://cdn.jsdelivr.net/npm/mathjax@' . $this->mathjax_version . '/MathJax.js';
					break;

				default:
					$script_url = $this->githuber_plugin_url . 'assets/vendor/mathjax/MathJax.js';
					break;
			} 
			wp_enqueue_script( 'mathjax', $script_url, array(), $this->mathjax_version, true );
		}
	}

	/**
	 * Print Javascript plaintext in page footer.
	 */
	public function front_print_footer_scripts() {
		$script = '
            <script id="module-mathjax" >
                (function($) {
                    $(function() {
                        if (typeof MathJax !== "undefined") {
							var c = $(".language-mathjax").length;

                            if (c > 0) {
								$(".language-mathjax").each(function(i) {
									var content = $(this).html();
									if ($(this).hasClass("mathjax-inline")) {
										$(this).html("$ " + content + " $");
									} else {
										$(this).html("$$" + "\n" + content + "\n" + "$$");
									}

									if (i + 1 === c) {
										MathJax.Hub.Config({
											showProcessingMessages: false,
											messageStyle: "none",
											extensions: [
												"tex2jax.js",
												"TeX/mediawiki-texvc.js",
												"TeX/noUndefined.js",
												"TeX/autoload-all.js",
												"TeX/AMSmath.js",
												"TeX/AMSsymbols.js"
											],
											jax: [
												"input/TeX",
												"output/SVG"
											],
											elements: document.getElementsByClassName("language-mathjax"),
											tex2jax: {
												skipTags: [
													"script",
													"noscript",
													"style",
													"textarea"
												],
												inlineMath: [
													[\'$\', \'$\']
												],
												displayMath: [
													[\'$$\', \'$$\']
												],
												processClass: "language-mathjax"
											}
										});

										MathJax.Hub.Queue(["Typeset", MathJax.Hub]);

										$(".language-mathjax").attr("style", "background: transparent; border: 0;");
										$(".language-mathjax").closest("pre").attr("style", "background: transparent; border: 0;");
									}
								});
                            } else {
                                console.log("[wp-githuber-md] MathJax code blocks not found.");
                            }
                        } else {
                            console.log("[wp-githuber-md] MathJax is not loadded.");
                        }  
                    });
                })(jQuery);
            </script>
		';
		echo preg_replace( '/\s+/', ' ', $script );
	}

	/**
	 * MathJax Inline Markup
	 * 
	 * Ex.
	 * `$ x_{1,2} = {-b\pm\sqrt{b^2 - 4ac} \over 2a}. $`
	 *
	 * @param string  $content HTML or Markdown content.
	 * @return void
	 */
	public static function mathjax_inline_markup( $content ) {

		$regex = '%<code>\$((?:[^$]+ |(?<=(?<!\\\\)\\\\)\$ )+)(?<!\\\\)\$<\/code>%ix';
		$content = preg_replace_callback( $regex, function() {
			$matches = func_get_arg(0);

			if ( ! empty( $matches[1] ) ) {
				$mathjax = $matches[1];
				$mathjax = str_replace( array( '&lt;', '&gt;', '&quot;', '&#039;', '&#038;', '&amp;', "\n", "\r" ), array( '<', '>', '"', "'", '&', '&', ' ', ' ' ), $mathjax );
				return '<code class="mathjax-inline language-mathjax">' . trim( $mathjax ) . '</code>';
			}
		}, $content );

		return $content;
	}
}
MarkdownForComments.php000066600000000522151771432760011234 0ustar00<?php
/**
 * Module Name: Markdown for Comments
 * Module Description: Display a simple Markdown editor in comment area.
 *
 * @author Terry Lin
 * @link https://terryl.in/
 *
 * @package Githuber
 * @since 1.12.0
 * @version 1.12.0
 */

namespace Githuber\Module;

/**
 * Todo
 */
class MardkwonForComments extends ModuleAbstract {

	
}
TaskList.php000066600000001552151771432760007037 0ustar00<?php
/**
 * Module Name: TaskList
 * Module Description: upport Github Flavored Markdown task lists.
 *
 * @author Terry Lin
 * @link https://terryl.in/
 *
 * @package Githuber
 * @since 1.0.0
 * @version 1.0.0
 */

namespace Githuber\Module;

class TaskList {

	/**
	 * Support Github Flavored Markdown task lists.
	 * 
	 * @param string $text HTML content.
	 * @return string filtered HTML content.
	 */
	public static function parse_gfm_task_list( $text ) {
		$checked_item   = '<li class="gfm-task-list"><input type="checkbox">$1$2';
		$unchecked_item = '<li class="gfm-task-list"><input type="checkbox" checked>$1$2';

		// Replace task-list signs to corresponding HTML code.
		$text = preg_replace( "#<li>\[\s\] (.*?)([</li>|<ul>])#", $checked_item, $text );
		$text = preg_replace( "#<li>\[[x]\] (.*?)([</li>|<ul>])#", $unchecked_item, $text );
		return $text;
	}
}