Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Provide repository for themes and plugins #3

Open
eklausme opened this issue Apr 12, 2021 · 0 comments
Open

Provide repository for themes and plugins #3

eklausme opened this issue Apr 12, 2021 · 0 comments

Comments

@eklausme
Copy link

As Saaze can be extended quite easily, it is expected that more extensions and template-themes will emerge. We should collect them "somewhere", so people can find them easily.

I created an extension for Saaze modeled after the documentation as given in Extending. This extension provides:

  1. MathJax support for inline and display math, i.e., single dollar and double dollar notation, taking into account to not spoil with math within code-blocks
  2. Embedding YouTube videos like so: [youtube] shortcode [/youtube]
  3. Embedding Tweets from Twitter like so: [twitter] Tweet URL [/twitter]

File definitions.php is:

<?php

require_once 'MathParser.php';

return [
    \Saaze\Interfaces\ContentParserInterface::class => \MathParser::class,
];

File MathParser.php is:

<?php

use Saaze\Content\MarkdownContentParser;

class MathParser extends MarkdownContentParser {
        /**
         * Work on abc $$uvw$$ xyz.
         * Needs MathJax. For this you have to include:
         *    <script src="https://polyfill.io/v3/polyfill.min.js?features=es6"></script>
         *    <script id="MathJax-script" async src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js"></script>
         *
         * @param string $content
         * @return string
         */
        private function displayMath($content) {
                $last = 0;
                for (;;) {
                        $start = strpos($content,"$$",$last);
                        if ($start === false) break;
                        $end = strpos($content,"$$",$start+2);
                        if ($end === false) break;
                        $last = $end + 2;
                        $content = substr($content,0,$start)
                                . "\n<div class=math>\n"
                                . substr($content,$start,$last-$start)
                                . "\n</div>\n"
                                . substr($content,$last);
                        $last += strlen("\n<div class=math>\n") + strlen("\n</div>\n");
                }
                return $content;
        }


        /**
         * Work on abc $uvw$ xyz.
         * @param string $content
         * @return string
         */
        private function inlineMath($content) {
                $last = 0;
		for (;;) {
			$start = strpos($content,"$",$last);
			if ($start === false) break;
			// Check if display math with double dollar found?
			if (substr($content,$start+1,1) == "$") { $last = $start + 2; continue; }
			$end = strpos($content,"$",$start+1);
			if ($end === false) break;
			// Check for display math again, just in case
			if (substr($content,$end+1,1) == "$") { $last = $end + 2; continue; }
			// Replace $xyz$" with \\(xyz\\)
			$content = substr_replace($content,"\\\\(",$start,1);
			$content = substr_replace($content,"\\\\)",$end+2,1);
			$last = $end + 5;	// effectivley added four chars
		}
                return $content;
        }


        /**
         * Convert [youtube]xxx[/youtube] tags in your markdown to HTML:
         * <iframe width="560" height="315" src=https://www.youtube.com/embed/xxx
         *    frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
         * Example: [youtube] a5pnnkXpX-U     [/youtube]
         *
         * @param string $content
         * @return string
         */
        private function youtube($content) {
                $last = 0;
                for (;;) {
                        $start = strpos($content,"[youtube]",$last);
                        if ($start === false) break;
                        // strlen("[youtube]") == 9
                        $end = strpos($content,"[/youtube]",$start+9);
                        if ($end === false) break;
                        $video = trim(substr($content,$start+9,$end-$start-9));
                        $last = $end + 10;
                        $content = substr_replace($content
                                ,"<iframe width=560 height=315 src=https://www.youtube.com/embed/"
                                . $video
                                . " frameborder=0 allow=\"accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture\" allowfullscreen></iframe>"
                                ,$start,$last-$start);
                }
                return $content;
        }


        /**
         * Convert [twitter]xxx[/twitter] tags in your markdown HTML which Twitter-JavaScript understands.
         * xxx is for example: https://twitter.com/eklausmeier/status/1352896936051937281
         * i.e., just the URL, no other information is required.
         * This xxx is "Copy link to Tweet" button in Twitter.
         *
         * Make sure that your layout-template contains the following:
         *    <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
         *
         * @param string $content
         * @return string
         */
        private function twitter($content) {
                $last = 0;
                for (;;) {
                        $start = strpos($content,"[twitter]",$last);
                        if ($start === false) break;
                        // strlen("[twitter]") == 9
                        $end = strpos($content,"[/twitter]",$start+9);
                        if ($end === false) break;
                        $tweet = trim(substr($content,$start+9,$end-$start-9));
                        $last = $end + 10;
                        $content = substr_replace($content
                                ,"<blockquote class=\"twitter-tweet\"><a href=\""
                                . $tweet
                                . "\"</a></blockquote>"
                                ,$start,$last-$start);
                }
                return $content;

        }


        /**
         * Parse raw content and return HTML
         * @param string $content
         * @return string
         */
        public function toHtml($content) {
                $arr = explode("`",$content);   // known deficiency: does not cope for HTML comments
                // even elements can be changed, uneven are code-block elements
                for($i=0, $size=count($arr); $i<$size; $i+=2) {
                        $arr[$i] = $this->displayMath($arr[$i]);
                        $arr[$i] = $this->inlineMath($arr[$i]);
                        $arr[$i] = $this->youtube($arr[$i]);
                        $arr[$i] = $this->twitter($arr[$i]);
                }
                return parent::toHtml(implode("`",$arr));       // markdown to HTML
        }
}

The following JavaScript libraries have to be present in layout.blade.php:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>
        @hasSection('title')
        @yield('title') - Saaze
        @else
        Saaze
        @endif
    </title>
    <link rel="stylesheet" href="https://unpkg.com/tailwindcss@^2.1.0/dist/base.min.css" />
    <link rel="stylesheet" href="https://unpkg.com/tailwindcss@^2.1.0/dist/components.min.css" />
    <link rel="stylesheet" href="https://unpkg.com/@tailwindcss/[email protected]/dist/typography.min.css" />
    <link rel="stylesheet" href="https://unpkg.com/tailwindcss@^2.1.0/dist/utilities.min.css" />
    <link href="https://unpkg.com/[email protected]/themes/prism.css" rel="stylesheet" />
    <link href="https://unpkg.com/[email protected]/plugins/line-numbers/prism-line-numbers.css" rel="stylesheet" />
    <script src="https://polyfill.io/v3/polyfill.min.js?features=es6"></script>
    <script id="MathJax-script" async src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js"></script>
    <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
    <script src="https://unpkg.com/[email protected]/components/prism-core.min.js"></script>
    <script src="https://unpkg.com/[email protected]/plugins/autoloader/prism-autoloader.min.js"></script>
    <script src="https://unpkg.com/[email protected]/plugins/line-numbers/prism-line-numbers.min.js"></script>
</head>
<body class="line-numbers">
    <header class="p-6 sm:px-10 sm:flex sm:justify-between sm:items-center mb-10 sm:mb-20">
        <div class="mb-4 sm:mb-0">
            <a href="/" class="text-xl text-purple-600">Saaze</a>
        </div>
        <nav>
            <ul class="flex">
                <li><a href="{{ $GLOBALS['rbase'] }}/" class="text-purple-600">Home</a></li>
                <li class="ml-10"><a href="{{ $GLOBALS['rbase'] }}/about" class="text-purple-600">About</a></li>
                <li class="ml-10"><a href="{{ $GLOBALS['rbase'] }}/blog" class="text-purple-600">Blog</a></li>
            </ul>
        </nav>
    </header>
    <div class="font-serif prose prose-sm sm:prose lg:prose-lg xl:prose-xl mx-auto px-6 my-10 sm:my-20">
        @yield('content')
    </div>
    <footer class="prose prose-sm sm:prose lg:prose-lg xl:prose-xl mx-auto px-6 my-20 sm:my-32">
        <p class="text-center text-gray-600 text-xs sm:text-base">Copyright &copy; {{ date('Y') }}</p>
    </footer>
</body>

</html>

Prism.js or font-change is not required for this extension. I added it anyway, as my blog contains some code snippets.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant