Elian  Harber

Elian Harber

1664976900

Gfmrun: GitHub-Flavored Markdown Runner

gfmrun

A (GitHub-Flavored Markdown Runner). Runs stuff inside code gates (maybe!).

This project is not intended to fully replace the example code running capabilities of any given language's tooling, but instead to fill a gap. In the case of a Go repository, for example, it can be handy to have some verifiable code examples in the README.md and example functions in *_test.go files.

Explicitly Supported Languages

Bash

If a code example has a declared language of bash, then gfmrun will write the source to a temporary file and run it via whatever executable is first in line to respond to bash.

for i in {97..99} ; do
  echo "$i problems" >&2
done

echo "Begot by all the supernova (${0})"
exit 0

Go

If a code example has a declared language of go and the first line is package main, then gfmrun will write the source to a temporary file, build it, and run it. It is worth noting that go run is not used, as this executes a child process of its own, thus making process management and exit success detection all the more complex.

package main

import (
  "fmt"
  "os"

  "golang.org/x/example/stringutil"
)

func main() {
  fmt.Printf("---> %v\n", os.Args[0])
  fmt.Println("we could make an entire album out of this one sound")
  fmt.Println(stringutil.Reverse("[SQUEAK INTENSIFIES]"))
}
package main

import (
  "log"
)

func main() {
  log.Fatal("we can handle errors too")
}

Java

If a code example has a declared language of java and a line matching ^public class ([^ ]+), then gfmrun will write the source to a temporary file, build it, and run the class by name.

public class GalacticPerimeter {
  public static void main(String[] args) {
    System.out.println(System.getenv("FILE"));
    System.out.println("Awaken the hive");
  }
}

JavaScript (assumed node.js compatible)

If a code example has a declared language of javascript, then gfmrun will write the source to a temporary file and run it via whatever executable is first in line to respond to node.

var main = function() {
  console.log("they won't stop at dancin, no");
  console.log("they won't stop at dancin");
};

if (require.main == module) {
  main();
}

JSON

If a code example has a declared language of json, then gfmrun will write the source to a temporary file and "run" it via the node executable for validation.

{
  "no": "output",
  "levels": [
    8000,
    9000,
    9001
  ]
}

Python

If a code example has a declared language of python, then gfmrun will write the source to a temporary file and run it via whatever executable is first in line to respond to python.

from __future__ import print_function

import sys


def main():
    print('lipstick ringo dance all night {!r}!'.format(sys.argv))
    return 0


if __name__ == '__main__':
    sys.exit(main())

Ruby

If a code example has a declared language of ruby, then gfmrun will write the source to a temporary file and run it via whatever executable is first in line to respond to ruby.


def main
  puts $0
  puts "get out of the path of the king"
  return 0
end

if $0 == __FILE__
  exit main
end

Shell

If a code example has a declared language that can be mapped to the linguist definition of shell, then gfmrun will write the source to a temporary file and run it via whatever executable is first in line to respond to bash.

if [ 0 -eq 0 ] ; then
  echo "Just the way you like it, yes"
  echo "just the way you like it. (${0})"
fi
exit 0

Sh

If a code example has a declared language of sh, then gfmrun will write the source to a temporary file and run it via whatever executable is first in line to respond to sh.

if [ 5 -eq 3 ] ; then
  echo "YOU FOUND THE MARBLE IN THE OATMEAL"
else
  echo "Saddle up preacher, don't look back. (${0})"
fi
exit 0

Zsh

If a code example has a declared language of zsh, then gfmrun will write the source to a temporary file and run it via whatever executable is first in line to respond to zsh.

printf "Kiss me.\nJust kiss me.\n(${0})\n"

bye 0

Implicitly Supported Languages

If a code example's declared language can be matched to one of the explicitly supported languages listed above via the linguist languages definition, then the matched language's runner will be used.

This example declares node, but will be run via the javascript frob, which happens to use the node executable anyway:

if (1 / 1 == 1) {
  console.log("kiss me, Nefertiti");
}

Disabling automatic download of languages.yml

By default, the linguist languages definition is downloaded if not present. This behavior can be disabled by passing the --no-auto-pull / -N flag or setting a GFMRUN_NO_AUTO_PULL=true environment variable.

Tag annotation comments

gfmrun supports the use of JSON tags embedded in comments preceding code blocks, e.g. (just pretend ^ are backticks):

<!-- { "awesome": "maybe", "all on one line": "yep" } -->
^^^ go
package lolmain
// ... stuff
^^^
<!-- {
  "wow": "cool",
  "multiple": "lines"
} -->
^^^ go
package lolmain
// ... stuff
^^^
<!-- {
  "super": "advanced",
  "whitespace after the comment": "mindblown"
} -->


^^^ go
package lolmain
// ... stuff
^^^

"output" tag

Given a regular expression string value, asserts that the program output (stdout) matches.

"error" tag

Given a regular expression string value, asserts that the program error (stderr) matches.

"args" tag

Given a string array, run the program with the value as command line arguments.

"interrupt" tag

Given either a truthy or duration string value, interrupts the program via increasingly serious signals (INT, HUP, TERM, and finally KILL). If the value is truthy, then the default duration is used (3s). If the value is a string duration, then the parsed duration is used. This tag is intended for use with long-lived example programs such as HTTP servers.

"os" tag

Given either a string or array of strings, skips the program if the current OS does not match. When absent, no filter is applied.

Examples

No tag annotations, expected to be short-lived and exit successfully:

var _ = 1 / 1;

Annotated with an "output" JSON tag that informs gfmrun to verify the example program's output:

console.log("Ohai from the land of GitHub-Flavored Markdown :wave:");

Annotated with an "interrupt" JSON tag that informs gfmrun to interrupt the example program after a specified duration, which implies that the exit code is ignored (not Windows-compatible):

package main

import (
  "fmt"
  "net/http"
)

func main() {
  http.HandleFunc("/", func(w http.ResponseWriter, req *http.Request) {
    w.WriteHeader(http.StatusOK)
    fmt.Fprintf(w, "Why Hello From Your Friendly Server Example :bomb:\n")
  })
  http.ListenAndServe(":8990", nil)
}

Similar to the above example, but the "interrupt" tag is truthy rather than a specific interval, which will result in the default interrupt duration being used (3s). It is also annotated with an "output" tag that takes precedence over the "interrupt" tag's behavior of ignoring the exit code:

package main

import (
  "fmt"
  "net/http"
)

func main() {
  http.HandleFunc("/", func(w http.ResponseWriter, req *http.Request) {
    w.WriteHeader(http.StatusOK)
    fmt.Fprintf(w, "Hello Again From Your Friendly Server Example :bomb:\n")
  })
  fmt.Println(":bomb:")
  http.ListenAndServe(":8989", nil)
}

Download Details:

Author: urfave
Source Code: https://github.com/urfave/gfmrun 
License: MIT license

#go #golang #markdown #github 

Gfmrun: GitHub-Flavored Markdown Runner

Report.jl: A Markdown Report Writer for Julia

Report.jl

Lightweight Markdown report generator for Julia.

The very general idea is that you can create markdown-formatted reports from within Julia code. Potentially helpful when running a data analysis pipeline that creates tables and plots as output. Uses pandoc Markdown and some of its extensions.

Some examples:

using Report
# create a Markdown document
doc = Report.Markdown("Report.md", "w", "figures")

# add a header to the document 
write(doc, Report.Header(1, "Report on Report.jl"))

# do some stuff, read in data, plot something
# Table(nrows, ncolumns, header, data, caption) creates a simple_table
write(doc, Report.Table(6, 3, ["Col1","Col2","Col3"], data, "Example table"))

# add a plot that was stored in `filename`
write(doc, Report.Figure(filename, "Yet another plot"))

# add some julia code to help you remember what you have done (uses fenced_code_blocks)

code = """
doc = Report.Markdown("Report.md", "w", "figures")
write(doc, Report.Header(1, "Report on Report.jl"))
write(doc, Report.Table(6, 3, ["Col1","Col2","Col3"], data, "Example table"))
write(doc, Report.Figure(filename, "Yet another plot"))
"""

write(doc, Report.Code("julia", code))

Download Details:

Author: Sveme
Source Code: https://github.com/sveme/Report.jl 
License: View license

#julia #markdown #report 

Report.jl: A Markdown Report Writer for Julia
Royce  Reinger

Royce Reinger

1662604440

6 Popular React Client Markdown Rendering Libraries

In today's post we will learn about 6 Popular React Client Markdown Rendering Libraries.

Markdown is a lightweight markup language for creating formatted text using a plain-text editor. It’s a common way of creating and formatting dynamic rich text content on a website, blog, or an e-commerce platform.

A Markdown file is saved with a .md or .markdown extension, and examples of Markdown usage include writing a readme.md file for a Github repository and adding new article content in a content management system (CMS).

1 - React-markdown

Markdown component for React

Install

This package is ESM only. In Node.js (version 12.20+, 14.14+, or 16.0+), install with npm:

npm install react-markdown

In Deno with esm.sh:

import ReactMarkdown from 'https://esm.sh/react-markdown@7'

In browsers with esm.sh:

<script type="module">
  import ReactMarkdown from 'https://esm.sh/react-markdown@7?bundle'
</script>

Use

A basic hello world:

import React from 'react'
import ReactMarkdown from 'react-markdown'
import ReactDom from 'react-dom'

ReactDom.render(<ReactMarkdown># Hello, *world*!</ReactMarkdown>, document.body)

View on Github

2 - React-markdown-editor-lite

A light-weight Markdown editor based on React

Install

npm install react-markdown-editor-lite --save
# or
yarn add react-markdown-editor-lite

Basic usage

Following steps:

  • Import react-markdown-editor-lite
  • Register plugins if required
  • Initialize a markdown parser, such as markdown-it
  • Start usage
// import react, react-markdown-editor-lite, and a markdown parser you like
import React from 'react';
import * as ReactDOM from 'react-dom';
import MarkdownIt from 'markdown-it';
import MdEditor from 'react-markdown-editor-lite';
// import style manually
import 'react-markdown-editor-lite/lib/index.css';

// Register plugins if required
// MdEditor.use(YOUR_PLUGINS_HERE);

// Initialize a markdown parser
const mdParser = new MarkdownIt(/* Markdown-it options */);

// Finish!
function handleEditorChange({ html, text }) {
  console.log('handleEditorChange', html, text);
}
export default props => {
  return (
    <MdEditor style={{ height: '500px' }} renderHTML={text => mdParser.render(text)} onChange={handleEditorChange} />
  );
};

View on Github

3 - Commonmark-react-renderer

React renderer for CommonMark (rationalized Markdown)

Installing

npm install --save commonmark-react-renderer

Basic usage

var CommonMark = require('commonmark');
var ReactRenderer = require('commonmark-react-renderer');

var parser = new CommonMark.Parser();
var renderer = new ReactRenderer();

var input = '# This is a header\n\nAnd this is a paragraph';
var ast = parser.parse(input);
var result = renderer.render(ast);

// `result`:
[
    <h1>This is a header</h1>,
    <p>And this is a paragraph</p>
]

View on Github

4 - React-remarkable

A React component for rendering Markdown with remarkable

npm install --save react-remarkable

Usage

var React = require('react');
var Markdown = require('react-remarkable');

var MyComponent = React.createClass({

  render() {
    return (
      <div>
        {/* Pass Markdown source to the `source` prop */}
        <Markdown source="**Markdown is awesome!**" />

        {/* Or pass it as children */}
        {/* You can nest React components, too */}
        <Markdown>{`
          ## Reasons React is great

          1. Server-side rendering
          2. This totally works:

          <SomeOtherAmazingComponent />

          Pretty neat!
        `}</Markdown>
      </div>
    );
  }

});

View on Github

5 - React-markdown-renderer

Simple React component that renders Markdown

Installing

npm install react-markdown-renderer --save

Basic Usage

import React from 'react';
import ReactDOM from 'react-dom';
import MarkdownRenderer from 'react-markdown-renderer';

const markdown = '# This is a H1  \n## This is a H2  \n###### This is a H6';

ReactDOM.render(
  <MarkdownRenderer markdown={markdown} />,
  document.getElementById('content')
);

View on Github

6 - React-markings

Markdown in components, components in markdown

Embed React components inside your markdown (in any paragraph position) like this:

import * as React from 'react';
import md from 'react-markings';

function Example() {
  return (
    <pre>
      <code>...</code>
    </pre>
  );
}

export default function ReadMe() {
  return md`
    # react-markings

    > Markdown in components, components in markdown

    - Allows you to write markdown using [commonmark.js](https://github.com/commonmark/commonmark.js)
    - Renders markdown as React elements using [commonmark-react-renderer](https://github.com/rexxars/commonmark-react-renderer)
    - Embed React components inside your markdown (in any paragraph position) like this:

    ${<Example/>}
  `;
}

View on Github

Thank you for following this article. 

#react #client #markdown 

6 Popular React Client Markdown Rendering Libraries
Emmy  Monahan

Emmy Monahan

1662347880

Markdown Editor In Laravel 9 Vite With Tailwind CSS

In this section we install & setup Markdown editor in Laravel 9 Vite with Tailwind CSS. Install & Setup Markdown Editor in Laravel 9.

Source: https://larainfo.com

#laravel #markdown #tailwindcss 

Markdown Editor In Laravel 9 Vite With Tailwind CSS
Hoang Tran

Hoang Tran

1662340500

Trình Chỉnh Sửa Markdown Trong Laravel 9 Vite Với Tailwind CSS

Trong phần này, chúng tôi cài đặt và thiết lập trình chỉnh sửa Markdown trong Laravel 9 Vite với Tailwind CSS.

Bước 1: Tạo Dự án Laravel và Kết nối Cơ sở dữ liệu

Đang cài đặt ứng dụng laravel 9 mới.

composer create-project laravel/laravel laravel-markdown

Bây giờ, bạn phải kết nối ứng dụng laravel với cơ sở dữ liệu,

.env

DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=database_name
DB_USERNAME=database_user_name
DB_PASSWORD=database_password

Bước 2: Cài đặt Laravel Breeze

Tiếp theo, bạn cần cài đặt laravel khoe thông qua trình soạn nhạc.

composer require laravel/breeze --dev

lắp giàn giáo khoe.

php artisan breeze:install

cài đặt npm và di chuyển cơ sở dữ liệu.

npm install
npm run dev
php artisan migrate

Bước 3: Cài đặt Tailwind CSS Typography

cài đặt kiểu chữ CSS tailwind.

npm install -D @tailwindcss/typography

Sau đó, thêm plugin vào tệp tailwind.config.js của bạn:

tailwind.config.js

const defaultTheme = require('tailwindcss/defaultTheme');

/** @type {import('tailwindcss').Config} */
module.exports = {
    content: [
        './vendor/laravel/framework/src/Illuminate/Pagination/resources/views/*.blade.php',
        './storage/framework/views/*.php',
        './resources/views/**/*.blade.php',
    ],

    theme: {
        extend: {
            fontFamily: {
                sans: ['Nunito', ...defaultTheme.fontFamily.sans],
            },
        },
    },

    plugins: [require('@tailwindcss/forms'),require('@tailwindcss/typography')],
};

vít chạy

npm run dev

Bước 4: Cài đặt Laravel Markdown

cài đặt trình chỉnh sửa markdown thông qua trình soạn nhạc:

composer require graham-campbell/markdown:^14.0

Cấu hình Markdown

Laravel Markdown hỗ trợ cấu hình tùy chọn.

Để bắt đầu, bạn cần xuất bản tất cả nội dung của nhà cung cấp:

php artisan vendor:publish

Bước 5: Tạo bộ điều khiển và định tuyến di chuyển sau phương thức

Chạy bên dưới để tạo mô hình bài đăng, di chuyển và bộ điều khiển.

php artisan make:model Post -mcr

create_posts_table.php

public function up()
{
    Schema::create('posts', function (Blueprint $table) {
        $table->id();
        $table->string('title');
        $table->string('slug');
        $table->longText('description');
        $table->timestamps();
    });
}

Chạy lại di chuyển

php artisan migrate

app / Models / Post.php

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;

class Post extends Model
{
    use HasFactory;

    protected $fillable = [
        'title',
        'slug',
        'description',
    ];
}

web.php

<?php
use App\Http\Controllers\PostController;
use Illuminate\Support\Facades\Route;

/*
|--------------------------------------------------------------------------
| Web Routes
|--------------------------------------------------------------------------
|
| Here is where you can register web routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| contains the "web" middleware group. Now create something great!
|
*/

Route::get('/', function () {
    return view('welcome');
});

Route::get('/dashboard', function () {
    return view('dashboard');
})->middleware(['auth'])->name('dashboard');
Route::resource('posts', PostController::class);
require __DIR__.'/auth.php';

Bây giờ bạn cần nhập GrahamCampbell \ Markdown \ Facades \ Markdown ; và sử dụng lớp Markdown trong mô tả bài đăng.

app / Http / Controllers / PostController.php

<?php

namespace App\Http\Controllers;

use App\Models\Post;
use Illuminate\Http\Request;
use GrahamCampbell\Markdown\Facades\Markdown;

class PostController extends Controller
{
    /**
     * Display a listing of the resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function index()
    {
        $posts = Post::latest()->paginate(10);

        return view('posts.index', compact('posts'));
    }

    /**
     * Show the form for creating a new resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function create()
    {
        return view('posts.create');
    }

    /**
     * Store a newly created resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\Response
     */
    public function store(Request $request)
    {
        $request->validate([
            'title' => 'required|string|max:255',
            'slug' => 'required|string|max:255',
            'description' => 'required'
        ]);
        Post::create([
            'title' => $request->title,
            'slug' => str()->slug($request->slug),
            'description' => Markdown::convert($request->description)->getContent(),
        ]);

        return redirect()->route('posts.index')->with('message', 'Post Created Successfully');
    }

    /**
     * Display the specified resource.
     *
     * @param  \App\Models\Post  $post
     * @return \Illuminate\Http\Response
     */
    public function show(Post $post)
    {
        return view('posts.show', compact('post'));
    }

    /**
     * Show the form for editing the specified resource.
     *
     * @param  \App\Models\Post  $post
     * @return \Illuminate\Http\Response
     */
    public function edit(Post $post)
    {
        //
    }

    /**
     * Update the specified resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \App\Models\Post  $post
     * @return \Illuminate\Http\Response
     */
    public function update(Request $request, Post $post)
    {
        //
    }

    /**
     * Remove the specified resource from storage.
     *
     * @param  \App\Models\Post  $post
     * @return \Illuminate\Http\Response
     */
    public function destroy(Post $post)
    {
        //
    }
}

Bước 6: Tạo @stack trong app.blade.php

Tiếp theo, bạn cần tạo @stack ('styles') cho tệp css và @stack ('scripts') cho js.

views / layouts / app.blade.php

<!DOCTYPE html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">

    <head>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <meta name="csrf-token" content="{{ csrf_token() }}">

        <title>{{ config('app.name', 'Laravel') }}</title>

        <!-- Fonts -->
        <link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Nunito:wght@400;600;700&display=swap">
        @stack('styles') 
        <!-- Scripts -->
        @vite(['resources/css/app.css', 'resources/js/app.js'])

    </head>

    <body class="font-sans antialiased">
        <div class="min-h-screen bg-gray-100">
            @include('layouts.navigation')

            <!-- Page Heading -->
            <header class="bg-white shadow">
                <div class="px-4 py-6 mx-auto max-w-7xl sm:px-6 lg:px-8">
                    {{ $header }}
                </div>
            </header>

            <!-- Page Content -->
            <main>
                {{ $slot }}
            </main>
        </div>
        @stack('scripts')
    </body>

</html>

Bước 7: Tạo tệp dạng xem phiến và thêm EasyMDE Markdown Editor

Bây giờ thêm trình chỉnh sửa đánh dấu dễ làm.

view / posts / create.blade.php

<x-app-layout>
    @push('styles')
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/easymde/dist/easymde.min.css">
    @endpush
    <x-slot name="header">
        <h2 class="text-xl font-semibold leading-tight text-gray-800">
            {{ __('Post Create') }}
        </h2>
    </x-slot>

    <div class="py-12">
        <div class="mx-auto max-w-7xl sm:px-6 lg:px-8">
            <div class="overflow-hidden bg-white shadow-sm sm:rounded-lg">
                <div class="p-6 bg-white border-b border-gray-200">
                    <form method="POST" action="{{ route('posts.store') }}">
                        @csrf
                        <div class="mb-6">
                            <label class="block">
                                <span class="text-gray-700">Title</span>
                                <input type="text" name="title"
                                    class="block w-full @error('title') border-red-500 @enderror mt-1 rounded-md"
                                    placeholder="" value="{{old('title')}}" />
                            </label>
                            @error('title')
                            <div class="text-sm text-red-600">{{ $message }}</div>
                            @enderror
                        </div>
                        <div class="mb-6">
                            <label class="block">
                                <span class="text-gray-700">Slug</span>
                                <input type="text" name="slug"
                                    class="block w-full @error('slug') border-red-500 @enderror mt-1 rounded-md"
                                    placeholder="" value="{{old('slug')}}" />
                            </label>
                            @error('slug')
                            <div class="text-sm text-red-600">{{ $message }}</div>
                            @enderror
                        </div>
                        <div class="mb-6">
                            <label class="block">
                                <span class="text-gray-700">Description</span>
                                <textarea id="markdown-editor" class="block w-full mt-1 rounded-md" name="description"
                                    rows="3"></textarea>
                            </label>
                            @error('description')
                            <div class="text-sm text-red-600">{{ $message }}</div>
                            @enderror
                        </div>
                        <button type="submit"
                            class="text-white bg-blue-600  rounded text-sm px-5 py-2.5">Submit</button>

                    </form>
                </div>
            </div>
        </div>
    </div>
    @push('scripts')
    <script src="https://cdn.jsdelivr.net/npm/easymde/dist/easymde.min.js"></script>
    <script>
        const easyMDE = new EasyMDE({
            showIcons: ['strikethrough', 'code', 'table', 'redo', 'heading', 'undo', 'heading-bigger', 'heading-smaller', 'heading-1', 'heading-2', 'heading-3', 'clean-block', 'horizontal-rule'],
            element: document.getElementById('markdown-editor')});
    </script>
    @endpush
</x-app-layout>

trình chỉnh sửa đánh dấu laravel 9

view / posts / show.blade.php

<x-app-layout>
    <x-slot name="header">
        <h2 class="text-xl font-semibold leading-tight text-gray-800">
            {{ __('Posts Show') }}
        </h2>
    </x-slot>

    <div class="py-12">
        <div class="max-w-4xl mx-auto sm:px-6 lg:px-8">
            <div class="overflow-hidden bg-white shadow-sm sm:rounded-lg">
                <div class="p-6 bg-white border-b border-gray-200">

                    <div>
                        <h1 class="text-2xl">{{ $post->title }}</h1>
                        <div class="prose lg:prose-xl">{!! $post->description !!}</div>
                    </div>

                </div>
            </div>
        </div>
    </div>
    
</x-app-layout>

trình soạn thảo đánh dấu laravel với tailwind css

Bước 8: Chạy máy chủ

chạy vite xây dựng

npm run dev
//or 
npm run build

chạy máy chủ laravel

php artisan serve 

Nguồn:  https://larainfo.com

#laravel #markdown #tailwindcss 

Trình Chỉnh Sửa Markdown Trong Laravel 9 Vite Với Tailwind CSS

Редактор уценки в Laravel 9 Vite с помощью Tailwind CSS

В этом разделе мы устанавливаем и настраиваем редактор Markdown в Laravel 9 Vite с помощью Tailwind CSS.

Шаг 1: Создайте проект Laravel и подключите базу данных

Установка свежего нового приложения laravel 9.

composer create-project laravel/laravel laravel-markdown

Теперь вам нужно подключить приложение laravel к базе данных,

.env

DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=database_name
DB_USERNAME=database_user_name
DB_PASSWORD=database_password

Шаг 2: Установите Laravel Breeze

Далее вам нужно установить laravel breeze через composer.

composer require laravel/breeze --dev

установить ветрозащитные леса.

php artisan breeze:install

установить npm и перенести базу данных.

npm install
npm run dev
php artisan migrate

Шаг 3: Установите типографику Tailwind CSS

установить CSS-типографику попутного ветра.

npm install -D @tailwindcss/typography

Затем добавьте плагин в файл tailwind.config.js:

хвостовой ветер.config.js

const defaultTheme = require('tailwindcss/defaultTheme');

/** @type {import('tailwindcss').Config} */
module.exports = {
    content: [
        './vendor/laravel/framework/src/Illuminate/Pagination/resources/views/*.blade.php',
        './storage/framework/views/*.php',
        './resources/views/**/*.blade.php',
    ],

    theme: {
        extend: {
            fontFamily: {
                sans: ['Nunito', ...defaultTheme.fontFamily.sans],
            },
        },
    },

    plugins: [require('@tailwindcss/forms'),require('@tailwindcss/typography')],
};

запустить винт

npm run dev

Шаг 4: Установите Laravel Markdown

установить редактор уценки через композитор:

composer require graham-campbell/markdown:^14.0

Конфигурация уценки

Laravel Markdown поддерживает дополнительную настройку.

Для начала вам необходимо опубликовать все активы поставщиков:

php artisan vendor:publish

Шаг 5. Создайте постмодальный контроллер миграции и маршрут

Запустите ниже, чтобы создать пост-модель, миграцию и контроллер.

php artisan make:model Post -mcr

create_posts_table.php

public function up()
{
    Schema::create('posts', function (Blueprint $table) {
        $table->id();
        $table->string('title');
        $table->string('slug');
        $table->longText('description');
        $table->timestamps();
    });
}

Запустите миграцию еще раз

php artisan migrate

приложение/Модели/Post.php

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;

class Post extends Model
{
    use HasFactory;

    protected $fillable = [
        'title',
        'slug',
        'description',
    ];
}

веб.php

<?php
use App\Http\Controllers\PostController;
use Illuminate\Support\Facades\Route;

/*
|--------------------------------------------------------------------------
| Web Routes
|--------------------------------------------------------------------------
|
| Here is where you can register web routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| contains the "web" middleware group. Now create something great!
|
*/

Route::get('/', function () {
    return view('welcome');
});

Route::get('/dashboard', function () {
    return view('dashboard');
})->middleware(['auth'])->name('dashboard');
Route::resource('posts', PostController::class);
require __DIR__.'/auth.php';

Теперь вам нужно импортировать GrahamCampbell\Markdown\Facades\Markdown ; и используйте класс Markdown в описании поста.

приложение/Http/Контроллеры/PostController.php

<?php

namespace App\Http\Controllers;

use App\Models\Post;
use Illuminate\Http\Request;
use GrahamCampbell\Markdown\Facades\Markdown;

class PostController extends Controller
{
    /**
     * Display a listing of the resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function index()
    {
        $posts = Post::latest()->paginate(10);

        return view('posts.index', compact('posts'));
    }

    /**
     * Show the form for creating a new resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function create()
    {
        return view('posts.create');
    }

    /**
     * Store a newly created resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\Response
     */
    public function store(Request $request)
    {
        $request->validate([
            'title' => 'required|string|max:255',
            'slug' => 'required|string|max:255',
            'description' => 'required'
        ]);
        Post::create([
            'title' => $request->title,
            'slug' => str()->slug($request->slug),
            'description' => Markdown::convert($request->description)->getContent(),
        ]);

        return redirect()->route('posts.index')->with('message', 'Post Created Successfully');
    }

    /**
     * Display the specified resource.
     *
     * @param  \App\Models\Post  $post
     * @return \Illuminate\Http\Response
     */
    public function show(Post $post)
    {
        return view('posts.show', compact('post'));
    }

    /**
     * Show the form for editing the specified resource.
     *
     * @param  \App\Models\Post  $post
     * @return \Illuminate\Http\Response
     */
    public function edit(Post $post)
    {
        //
    }

    /**
     * Update the specified resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \App\Models\Post  $post
     * @return \Illuminate\Http\Response
     */
    public function update(Request $request, Post $post)
    {
        //
    }

    /**
     * Remove the specified resource from storage.
     *
     * @param  \App\Models\Post  $post
     * @return \Illuminate\Http\Response
     */
    public function destroy(Post $post)
    {
        //
    }
}

Шаг 6: Создайте @stack в app.blade.php

Затем вам нужно создать @stack('styles') для файла css и @stack('scripts') для js.

представления/макеты/app.blade.php

<!DOCTYPE html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">

    <head>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <meta name="csrf-token" content="{{ csrf_token() }}">

        <title>{{ config('app.name', 'Laravel') }}</title>

        <!-- Fonts -->
        <link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Nunito:wght@400;600;700&display=swap">
        @stack('styles') 
        <!-- Scripts -->
        @vite(['resources/css/app.css', 'resources/js/app.js'])

    </head>

    <body class="font-sans antialiased">
        <div class="min-h-screen bg-gray-100">
            @include('layouts.navigation')

            <!-- Page Heading -->
            <header class="bg-white shadow">
                <div class="px-4 py-6 mx-auto max-w-7xl sm:px-6 lg:px-8">
                    {{ $header }}
                </div>
            </header>

            <!-- Page Content -->
            <main>
                {{ $slot }}
            </main>
        </div>
        @stack('scripts')
    </body>

</html>

Шаг 7. Создайте файл представления блейда и добавьте редактор разметки EasyMDE Markdown.

Теперь добавьте редактор уценки easymade.

просмотр/сообщения/create.blade.php

<x-app-layout>
    @push('styles')
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/easymde/dist/easymde.min.css">
    @endpush
    <x-slot name="header">
        <h2 class="text-xl font-semibold leading-tight text-gray-800">
            {{ __('Post Create') }}
        </h2>
    </x-slot>

    <div class="py-12">
        <div class="mx-auto max-w-7xl sm:px-6 lg:px-8">
            <div class="overflow-hidden bg-white shadow-sm sm:rounded-lg">
                <div class="p-6 bg-white border-b border-gray-200">
                    <form method="POST" action="{{ route('posts.store') }}">
                        @csrf
                        <div class="mb-6">
                            <label class="block">
                                <span class="text-gray-700">Title</span>
                                <input type="text" name="title"
                                    class="block w-full @error('title') border-red-500 @enderror mt-1 rounded-md"
                                    placeholder="" value="{{old('title')}}" />
                            </label>
                            @error('title')
                            <div class="text-sm text-red-600">{{ $message }}</div>
                            @enderror
                        </div>
                        <div class="mb-6">
                            <label class="block">
                                <span class="text-gray-700">Slug</span>
                                <input type="text" name="slug"
                                    class="block w-full @error('slug') border-red-500 @enderror mt-1 rounded-md"
                                    placeholder="" value="{{old('slug')}}" />
                            </label>
                            @error('slug')
                            <div class="text-sm text-red-600">{{ $message }}</div>
                            @enderror
                        </div>
                        <div class="mb-6">
                            <label class="block">
                                <span class="text-gray-700">Description</span>
                                <textarea id="markdown-editor" class="block w-full mt-1 rounded-md" name="description"
                                    rows="3"></textarea>
                            </label>
                            @error('description')
                            <div class="text-sm text-red-600">{{ $message }}</div>
                            @enderror
                        </div>
                        <button type="submit"
                            class="text-white bg-blue-600  rounded text-sm px-5 py-2.5">Submit</button>

                    </form>
                </div>
            </div>
        </div>
    </div>
    @push('scripts')
    <script src="https://cdn.jsdelivr.net/npm/easymde/dist/easymde.min.js"></script>
    <script>
        const easyMDE = new EasyMDE({
            showIcons: ['strikethrough', 'code', 'table', 'redo', 'heading', 'undo', 'heading-bigger', 'heading-smaller', 'heading-1', 'heading-2', 'heading-3', 'clean-block', 'horizontal-rule'],
            element: document.getElementById('markdown-editor')});
    </script>
    @endpush
</x-app-layout>

редактор уценки laravel 9

вид/сообщения/show.blade.php

<x-app-layout>
    <x-slot name="header">
        <h2 class="text-xl font-semibold leading-tight text-gray-800">
            {{ __('Posts Show') }}
        </h2>
    </x-slot>

    <div class="py-12">
        <div class="max-w-4xl mx-auto sm:px-6 lg:px-8">
            <div class="overflow-hidden bg-white shadow-sm sm:rounded-lg">
                <div class="p-6 bg-white border-b border-gray-200">

                    <div>
                        <h1 class="text-2xl">{{ $post->title }}</h1>
                        <div class="prose lg:prose-xl">{!! $post->description !!}</div>
                    </div>

                </div>
            </div>
        </div>
    </div>
    
</x-app-layout>

Редактор уценки laravel с попутным ветром css

Шаг 8: Запустите сервер

запустить сборку vite

npm run dev
//or 
npm run build

запустить сервер laravel

php artisan serve 

Источник:  https://larainfo.com

#laravel #markdown #tailwindcss 

Редактор уценки в Laravel 9 Vite с помощью Tailwind CSS
小泉  晃

小泉 晃

1662324720

帶有 Tailwind CSS 的 Laravel 9 Vite 中的 Markdown 編輯器

在本節中,我們使用 Tailwind CSS 在 Laravel 9 Vite 中安裝和設置 Markdown 編輯器。

第 1 步:創建 Laravel 項目並連接數據庫

安裝一個全新的 laravel 9 應用程序。

composer create-project laravel/laravel laravel-markdown

現在,您必須將 laravel 應用程序連接到數據庫,

.env

DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=database_name
DB_USERNAME=database_user_name
DB_PASSWORD=database_password

第 2 步:安裝 Laravel Breeze

接下來,您需要通過 composer 安裝 laravel 微風。

composer require laravel/breeze --dev

安裝微風腳手架。

php artisan breeze:install

安裝 npm 並遷移數據庫。

npm install
npm run dev
php artisan migrate

第 3 步:安裝 Tailwind CSS 排版

安裝順風 CSS 排版。

npm install -D @tailwindcss/typography

然後將插件添加到您的 tailwind.config.js 文件中:

tailwind.config.js

const defaultTheme = require('tailwindcss/defaultTheme');

/** @type {import('tailwindcss').Config} */
module.exports = {
    content: [
        './vendor/laravel/framework/src/Illuminate/Pagination/resources/views/*.blade.php',
        './storage/framework/views/*.php',
        './resources/views/**/*.blade.php',
    ],

    theme: {
        extend: {
            fontFamily: {
                sans: ['Nunito', ...defaultTheme.fontFamily.sans],
            },
        },
    },

    plugins: [require('@tailwindcss/forms'),require('@tailwindcss/typography')],
};

運行螺絲

npm run dev

第 4 步:安裝 Laravel Markdown

通過 composer 安裝 markdown 編輯器:

composer require graham-campbell/markdown:^14.0

降價配置

Laravel Markdown 支持可選配置。

首先,您需要發布所有供應商資產:

php artisan vendor:publish

第 5 步:創建後模態遷移控制器和路由

在下面運行以創建後期模型、遷移和控制器。

php artisan make:model Post -mcr

create_posts_table.php

public function up()
{
    Schema::create('posts', function (Blueprint $table) {
        $table->id();
        $table->string('title');
        $table->string('slug');
        $table->longText('description');
        $table->timestamps();
    });
}

再次運行遷移

php artisan migrate

應用程序/模型/Post.php

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;

class Post extends Model
{
    use HasFactory;

    protected $fillable = [
        'title',
        'slug',
        'description',
    ];
}

網頁.php

<?php
use App\Http\Controllers\PostController;
use Illuminate\Support\Facades\Route;

/*
|--------------------------------------------------------------------------
| Web Routes
|--------------------------------------------------------------------------
|
| Here is where you can register web routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| contains the "web" middleware group. Now create something great!
|
*/

Route::get('/', function () {
    return view('welcome');
});

Route::get('/dashboard', function () {
    return view('dashboard');
})->middleware(['auth'])->name('dashboard');
Route::resource('posts', PostController::class);
require __DIR__.'/auth.php';

現在你需要導入GrahamCampbell\Markdown\Facades\Markdown;並在帖子描述中使用 Markdown 類。

應用程序/Http/Controllers/PostController.php

<?php

namespace App\Http\Controllers;

use App\Models\Post;
use Illuminate\Http\Request;
use GrahamCampbell\Markdown\Facades\Markdown;

class PostController extends Controller
{
    /**
     * Display a listing of the resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function index()
    {
        $posts = Post::latest()->paginate(10);

        return view('posts.index', compact('posts'));
    }

    /**
     * Show the form for creating a new resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function create()
    {
        return view('posts.create');
    }

    /**
     * Store a newly created resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\Response
     */
    public function store(Request $request)
    {
        $request->validate([
            'title' => 'required|string|max:255',
            'slug' => 'required|string|max:255',
            'description' => 'required'
        ]);
        Post::create([
            'title' => $request->title,
            'slug' => str()->slug($request->slug),
            'description' => Markdown::convert($request->description)->getContent(),
        ]);

        return redirect()->route('posts.index')->with('message', 'Post Created Successfully');
    }

    /**
     * Display the specified resource.
     *
     * @param  \App\Models\Post  $post
     * @return \Illuminate\Http\Response
     */
    public function show(Post $post)
    {
        return view('posts.show', compact('post'));
    }

    /**
     * Show the form for editing the specified resource.
     *
     * @param  \App\Models\Post  $post
     * @return \Illuminate\Http\Response
     */
    public function edit(Post $post)
    {
        //
    }

    /**
     * Update the specified resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \App\Models\Post  $post
     * @return \Illuminate\Http\Response
     */
    public function update(Request $request, Post $post)
    {
        //
    }

    /**
     * Remove the specified resource from storage.
     *
     * @param  \App\Models\Post  $post
     * @return \Illuminate\Http\Response
     */
    public function destroy(Post $post)
    {
        //
    }
}

第 6 步:在 app.blade.php 中創建 @stack

接下來,您需要為 css 文件創建 @stack('styles') 和為 js 文件創建 @stack('scripts')。

視圖/佈局/app.blade.php

<!DOCTYPE html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">

    <head>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <meta name="csrf-token" content="{{ csrf_token() }}">

        <title>{{ config('app.name', 'Laravel') }}</title>

        <!-- Fonts -->
        <link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Nunito:wght@400;600;700&display=swap">
        @stack('styles') 
        <!-- Scripts -->
        @vite(['resources/css/app.css', 'resources/js/app.js'])

    </head>

    <body class="font-sans antialiased">
        <div class="min-h-screen bg-gray-100">
            @include('layouts.navigation')

            <!-- Page Heading -->
            <header class="bg-white shadow">
                <div class="px-4 py-6 mx-auto max-w-7xl sm:px-6 lg:px-8">
                    {{ $header }}
                </div>
            </header>

            <!-- Page Content -->
            <main>
                {{ $slot }}
            </main>
        </div>
        @stack('scripts')
    </body>

</html>

第 7 步:創建刀片視圖文件並添加 EasyMDE Markdown Editor

現在添加easymade markdown 編輯器。

查看/posts/create.blade.php

<x-app-layout>
    @push('styles')
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/easymde/dist/easymde.min.css">
    @endpush
    <x-slot name="header">
        <h2 class="text-xl font-semibold leading-tight text-gray-800">
            {{ __('Post Create') }}
        </h2>
    </x-slot>

    <div class="py-12">
        <div class="mx-auto max-w-7xl sm:px-6 lg:px-8">
            <div class="overflow-hidden bg-white shadow-sm sm:rounded-lg">
                <div class="p-6 bg-white border-b border-gray-200">
                    <form method="POST" action="{{ route('posts.store') }}">
                        @csrf
                        <div class="mb-6">
                            <label class="block">
                                <span class="text-gray-700">Title</span>
                                <input type="text" name="title"
                                    class="block w-full @error('title') border-red-500 @enderror mt-1 rounded-md"
                                    placeholder="" value="{{old('title')}}" />
                            </label>
                            @error('title')
                            <div class="text-sm text-red-600">{{ $message }}</div>
                            @enderror
                        </div>
                        <div class="mb-6">
                            <label class="block">
                                <span class="text-gray-700">Slug</span>
                                <input type="text" name="slug"
                                    class="block w-full @error('slug') border-red-500 @enderror mt-1 rounded-md"
                                    placeholder="" value="{{old('slug')}}" />
                            </label>
                            @error('slug')
                            <div class="text-sm text-red-600">{{ $message }}</div>
                            @enderror
                        </div>
                        <div class="mb-6">
                            <label class="block">
                                <span class="text-gray-700">Description</span>
                                <textarea id="markdown-editor" class="block w-full mt-1 rounded-md" name="description"
                                    rows="3"></textarea>
                            </label>
                            @error('description')
                            <div class="text-sm text-red-600">{{ $message }}</div>
                            @enderror
                        </div>
                        <button type="submit"
                            class="text-white bg-blue-600  rounded text-sm px-5 py-2.5">Submit</button>

                    </form>
                </div>
            </div>
        </div>
    </div>
    @push('scripts')
    <script src="https://cdn.jsdelivr.net/npm/easymde/dist/easymde.min.js"></script>
    <script>
        const easyMDE = new EasyMDE({
            showIcons: ['strikethrough', 'code', 'table', 'redo', 'heading', 'undo', 'heading-bigger', 'heading-smaller', 'heading-1', 'heading-2', 'heading-3', 'clean-block', 'horizontal-rule'],
            element: document.getElementById('markdown-editor')});
    </script>
    @endpush
</x-app-layout>

laravel 9 降價編輯器

查看/posts/show.blade.php

<x-app-layout>
    <x-slot name="header">
        <h2 class="text-xl font-semibold leading-tight text-gray-800">
            {{ __('Posts Show') }}
        </h2>
    </x-slot>

    <div class="py-12">
        <div class="max-w-4xl mx-auto sm:px-6 lg:px-8">
            <div class="overflow-hidden bg-white shadow-sm sm:rounded-lg">
                <div class="p-6 bg-white border-b border-gray-200">

                    <div>
                        <h1 class="text-2xl">{{ $post->title }}</h1>
                        <div class="prose lg:prose-xl">{!! $post->description !!}</div>
                    </div>

                </div>
            </div>
        </div>
    </div>
    
</x-app-layout>

帶有順風 css 的 laravel 降價編輯器

第 8 步:運行服務器

運行 vite 構建

npm run dev
//or 
npm run build

運行 laravel 服務器

php artisan serve 

來源:  https ://larainfo.com

#laravel #markdown #tailwindcss 

帶有 Tailwind CSS 的 Laravel 9 Vite 中的 Markdown 編輯器
Eladio  Rau

Eladio Rau

1662316680

Éditeur Markdown Dans Laravel 9 Vite Avec Tailwind CSS

Dans cette section, nous installons et configurons l'éditeur Markdown dans Laravel 9 Vite avec Tailwind CSS.

Étape 1 : Créer un projet Laravel et connecter la base de données

Installation d'une nouvelle application laravel 9.

composer create-project laravel/laravel laravel-markdown

Maintenant, vous devez connecter l'application laravel à la base de données,

.env

DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=database_name
DB_USERNAME=database_user_name
DB_PASSWORD=database_password

Étape 2 : Installer Laravel Breeze

Ensuite, vous devez installer laravel Breeze via composer.

composer require laravel/breeze --dev

installer un échafaudage brise.

php artisan breeze:install

installez npm et migrez la base de données.

npm install
npm run dev
php artisan migrate

Étape 3 : Installer Tailwind CSS Typography

installer la typographie CSS tailwind.

npm install -D @tailwindcss/typography

Ajoutez ensuite le plugin à votre fichier tailwind.config.js :

tailwind.config.js

const defaultTheme = require('tailwindcss/defaultTheme');

/** @type {import('tailwindcss').Config} */
module.exports = {
    content: [
        './vendor/laravel/framework/src/Illuminate/Pagination/resources/views/*.blade.php',
        './storage/framework/views/*.php',
        './resources/views/**/*.blade.php',
    ],

    theme: {
        extend: {
            fontFamily: {
                sans: ['Nunito', ...defaultTheme.fontFamily.sans],
            },
        },
    },

    plugins: [require('@tailwindcss/forms'),require('@tailwindcss/typography')],
};

exécuter la vis

npm run dev

Étape 4 : Installer Laravel Markdown

installez l'éditeur Markdown via composer :

composer require graham-campbell/markdown:^14.0

Configuration de la démarque

Laravel Markdown prend en charge la configuration facultative.

Pour commencer, vous devez publier tous les éléments du fournisseur :

php artisan vendor:publish

Étape 5 : Créer un contrôleur de migration post-modale et une route

Exécutez ci-dessous pour créer un post-modèle, une migration et un contrôleur.

php artisan make:model Post -mcr

create_posts_table.php

public function up()
{
    Schema::create('posts', function (Blueprint $table) {
        $table->id();
        $table->string('title');
        $table->string('slug');
        $table->longText('description');
        $table->timestamps();
    });
}

Réexécutez la migration

php artisan migrate

app/Modèles/Post.php

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;

class Post extends Model
{
    use HasFactory;

    protected $fillable = [
        'title',
        'slug',
        'description',
    ];
}

web.php

<?php
use App\Http\Controllers\PostController;
use Illuminate\Support\Facades\Route;

/*
|--------------------------------------------------------------------------
| Web Routes
|--------------------------------------------------------------------------
|
| Here is where you can register web routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| contains the "web" middleware group. Now create something great!
|
*/

Route::get('/', function () {
    return view('welcome');
});

Route::get('/dashboard', function () {
    return view('dashboard');
})->middleware(['auth'])->name('dashboard');
Route::resource('posts', PostController::class);
require __DIR__.'/auth.php';

Vous devez maintenant importer GrahamCampbell\Markdown\Facades\Markdown ; et utilisez la classe Markdown dans la description du message.

app/Http/Controllers/PostController.php

<?php

namespace App\Http\Controllers;

use App\Models\Post;
use Illuminate\Http\Request;
use GrahamCampbell\Markdown\Facades\Markdown;

class PostController extends Controller
{
    /**
     * Display a listing of the resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function index()
    {
        $posts = Post::latest()->paginate(10);

        return view('posts.index', compact('posts'));
    }

    /**
     * Show the form for creating a new resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function create()
    {
        return view('posts.create');
    }

    /**
     * Store a newly created resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\Response
     */
    public function store(Request $request)
    {
        $request->validate([
            'title' => 'required|string|max:255',
            'slug' => 'required|string|max:255',
            'description' => 'required'
        ]);
        Post::create([
            'title' => $request->title,
            'slug' => str()->slug($request->slug),
            'description' => Markdown::convert($request->description)->getContent(),
        ]);

        return redirect()->route('posts.index')->with('message', 'Post Created Successfully');
    }

    /**
     * Display the specified resource.
     *
     * @param  \App\Models\Post  $post
     * @return \Illuminate\Http\Response
     */
    public function show(Post $post)
    {
        return view('posts.show', compact('post'));
    }

    /**
     * Show the form for editing the specified resource.
     *
     * @param  \App\Models\Post  $post
     * @return \Illuminate\Http\Response
     */
    public function edit(Post $post)
    {
        //
    }

    /**
     * Update the specified resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \App\Models\Post  $post
     * @return \Illuminate\Http\Response
     */
    public function update(Request $request, Post $post)
    {
        //
    }

    /**
     * Remove the specified resource from storage.
     *
     * @param  \App\Models\Post  $post
     * @return \Illuminate\Http\Response
     */
    public function destroy(Post $post)
    {
        //
    }
}

Étape 6 : Créer @stack dans app.blade.php

Ensuite, vous devez créer @stack('styles') pour le fichier css et @stack('scripts') pour js.

vues/mises en page/app.blade.php

<!DOCTYPE html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">

    <head>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <meta name="csrf-token" content="{{ csrf_token() }}">

        <title>{{ config('app.name', 'Laravel') }}</title>

        <!-- Fonts -->
        <link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Nunito:wght@400;600;700&display=swap">
        @stack('styles') 
        <!-- Scripts -->
        @vite(['resources/css/app.css', 'resources/js/app.js'])

    </head>

    <body class="font-sans antialiased">
        <div class="min-h-screen bg-gray-100">
            @include('layouts.navigation')

            <!-- Page Heading -->
            <header class="bg-white shadow">
                <div class="px-4 py-6 mx-auto max-w-7xl sm:px-6 lg:px-8">
                    {{ $header }}
                </div>
            </header>

            <!-- Page Content -->
            <main>
                {{ $slot }}
            </main>
        </div>
        @stack('scripts')
    </body>

</html>

Étape 7 : Créer un fichier de vue de lame et ajouter EasyMDE Markdown Editor

Ajoutez maintenant l'éditeur de démarquage easymade.

voir/messages/create.blade.php

<x-app-layout>
    @push('styles')
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/easymde/dist/easymde.min.css">
    @endpush
    <x-slot name="header">
        <h2 class="text-xl font-semibold leading-tight text-gray-800">
            {{ __('Post Create') }}
        </h2>
    </x-slot>

    <div class="py-12">
        <div class="mx-auto max-w-7xl sm:px-6 lg:px-8">
            <div class="overflow-hidden bg-white shadow-sm sm:rounded-lg">
                <div class="p-6 bg-white border-b border-gray-200">
                    <form method="POST" action="{{ route('posts.store') }}">
                        @csrf
                        <div class="mb-6">
                            <label class="block">
                                <span class="text-gray-700">Title</span>
                                <input type="text" name="title"
                                    class="block w-full @error('title') border-red-500 @enderror mt-1 rounded-md"
                                    placeholder="" value="{{old('title')}}" />
                            </label>
                            @error('title')
                            <div class="text-sm text-red-600">{{ $message }}</div>
                            @enderror
                        </div>
                        <div class="mb-6">
                            <label class="block">
                                <span class="text-gray-700">Slug</span>
                                <input type="text" name="slug"
                                    class="block w-full @error('slug') border-red-500 @enderror mt-1 rounded-md"
                                    placeholder="" value="{{old('slug')}}" />
                            </label>
                            @error('slug')
                            <div class="text-sm text-red-600">{{ $message }}</div>
                            @enderror
                        </div>
                        <div class="mb-6">
                            <label class="block">
                                <span class="text-gray-700">Description</span>
                                <textarea id="markdown-editor" class="block w-full mt-1 rounded-md" name="description"
                                    rows="3"></textarea>
                            </label>
                            @error('description')
                            <div class="text-sm text-red-600">{{ $message }}</div>
                            @enderror
                        </div>
                        <button type="submit"
                            class="text-white bg-blue-600  rounded text-sm px-5 py-2.5">Submit</button>

                    </form>
                </div>
            </div>
        </div>
    </div>
    @push('scripts')
    <script src="https://cdn.jsdelivr.net/npm/easymde/dist/easymde.min.js"></script>
    <script>
        const easyMDE = new EasyMDE({
            showIcons: ['strikethrough', 'code', 'table', 'redo', 'heading', 'undo', 'heading-bigger', 'heading-smaller', 'heading-1', 'heading-2', 'heading-3', 'clean-block', 'horizontal-rule'],
            element: document.getElementById('markdown-editor')});
    </script>
    @endpush
</x-app-layout>

éditeur de démarquage laravel 9

voir/messages/show.blade.php

<x-app-layout>
    <x-slot name="header">
        <h2 class="text-xl font-semibold leading-tight text-gray-800">
            {{ __('Posts Show') }}
        </h2>
    </x-slot>

    <div class="py-12">
        <div class="max-w-4xl mx-auto sm:px-6 lg:px-8">
            <div class="overflow-hidden bg-white shadow-sm sm:rounded-lg">
                <div class="p-6 bg-white border-b border-gray-200">

                    <div>
                        <h1 class="text-2xl">{{ $post->title }}</h1>
                        <div class="prose lg:prose-xl">{!! $post->description !!}</div>
                    </div>

                </div>
            </div>
        </div>
    </div>
    
</x-app-layout>

éditeur de démarquage laravel avec tailwind css

Étape 8 : Exécutez le serveur

exécuter vite construire

npm run dev
//or 
npm run build

exécuter le serveur laravel

php artisan serve 

Source :  https://larainfo.com

#laravel #markdown #tailwindcss 

Éditeur Markdown Dans Laravel 9 Vite Avec Tailwind CSS
Lilly  Wilson

Lilly Wilson

1662309240

Editor De Rebajas En Laravel 9 Vite Con Tailwind CSS

En esta sección instalamos y configuramos el editor Markdown en Laravel 9 Vite con Tailwind CSS.

Paso 1: Crear proyecto Laravel y conectar base de datos

Instalación de una nueva aplicación laravel 9 nueva.

composer create-project laravel/laravel laravel-markdown

Ahora, debe conectar la aplicación laravel a la base de datos,

.env

DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=database_name
DB_USERNAME=database_user_name
DB_PASSWORD=database_password

Paso 2: Instalar Laravel Breeze

A continuación, necesita instalar laravel brisa a través de composer.

composer require laravel/breeze --dev

instalar andamio brisa.

php artisan breeze:install

instale npm y migre la base de datos.

npm install
npm run dev
php artisan migrate

Paso 3: Instale la tipografía Tailwind CSS

instale la tipografía CSS de viento de cola.

npm install -D @tailwindcss/typography

Luego agregue el complemento a su archivo tailwind.config.js:

tailwind.config.js

const defaultTheme = require('tailwindcss/defaultTheme');

/** @type {import('tailwindcss').Config} */
module.exports = {
    content: [
        './vendor/laravel/framework/src/Illuminate/Pagination/resources/views/*.blade.php',
        './storage/framework/views/*.php',
        './resources/views/**/*.blade.php',
    ],

    theme: {
        extend: {
            fontFamily: {
                sans: ['Nunito', ...defaultTheme.fontFamily.sans],
            },
        },
    },

    plugins: [require('@tailwindcss/forms'),require('@tailwindcss/typography')],
};

correr tornillo

npm run dev

Paso 4: Instalar Laravel Markdown

instale el editor de rebajas a través del compositor:

composer require graham-campbell/markdown:^14.0

Configuración de descuento

Laravel Markdown admite configuración opcional.

Para comenzar, deberá publicar todos los activos de los proveedores:

php artisan vendor:publish

Paso 5: crear una ruta y un controlador de migración posmodal

Ejecute a continuación para crear el modelo posterior, la migración y el controlador.

php artisan make:model Post -mcr

create_posts_table.php

public function up()
{
    Schema::create('posts', function (Blueprint $table) {
        $table->id();
        $table->string('title');
        $table->string('slug');
        $table->longText('description');
        $table->timestamps();
    });
}

Ejecutar migrar de nuevo

php artisan migrate

aplicación/Modelos/Post.php

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;

class Post extends Model
{
    use HasFactory;

    protected $fillable = [
        'title',
        'slug',
        'description',
    ];
}

web.php

<?php
use App\Http\Controllers\PostController;
use Illuminate\Support\Facades\Route;

/*
|--------------------------------------------------------------------------
| Web Routes
|--------------------------------------------------------------------------
|
| Here is where you can register web routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| contains the "web" middleware group. Now create something great!
|
*/

Route::get('/', function () {
    return view('welcome');
});

Route::get('/dashboard', function () {
    return view('dashboard');
})->middleware(['auth'])->name('dashboard');
Route::resource('posts', PostController::class);
require __DIR__.'/auth.php';

Ahora necesita importar GrahamCampbell\Markdown\Facades\Markdown ; y use la clase Markdown en la descripción de la publicación.

app/Http/Controllers/PostController.php

<?php

namespace App\Http\Controllers;

use App\Models\Post;
use Illuminate\Http\Request;
use GrahamCampbell\Markdown\Facades\Markdown;

class PostController extends Controller
{
    /**
     * Display a listing of the resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function index()
    {
        $posts = Post::latest()->paginate(10);

        return view('posts.index', compact('posts'));
    }

    /**
     * Show the form for creating a new resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function create()
    {
        return view('posts.create');
    }

    /**
     * Store a newly created resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\Response
     */
    public function store(Request $request)
    {
        $request->validate([
            'title' => 'required|string|max:255',
            'slug' => 'required|string|max:255',
            'description' => 'required'
        ]);
        Post::create([
            'title' => $request->title,
            'slug' => str()->slug($request->slug),
            'description' => Markdown::convert($request->description)->getContent(),
        ]);

        return redirect()->route('posts.index')->with('message', 'Post Created Successfully');
    }

    /**
     * Display the specified resource.
     *
     * @param  \App\Models\Post  $post
     * @return \Illuminate\Http\Response
     */
    public function show(Post $post)
    {
        return view('posts.show', compact('post'));
    }

    /**
     * Show the form for editing the specified resource.
     *
     * @param  \App\Models\Post  $post
     * @return \Illuminate\Http\Response
     */
    public function edit(Post $post)
    {
        //
    }

    /**
     * Update the specified resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \App\Models\Post  $post
     * @return \Illuminate\Http\Response
     */
    public function update(Request $request, Post $post)
    {
        //
    }

    /**
     * Remove the specified resource from storage.
     *
     * @param  \App\Models\Post  $post
     * @return \Illuminate\Http\Response
     */
    public function destroy(Post $post)
    {
        //
    }
}

Paso 6: Crea @stack en app.blade.php

A continuación, debe crear @stack('styles') para el archivo css y @stack('scripts') para js.

vistas/diseños/app.blade.php

<!DOCTYPE html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">

    <head>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <meta name="csrf-token" content="{{ csrf_token() }}">

        <title>{{ config('app.name', 'Laravel') }}</title>

        <!-- Fonts -->
        <link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Nunito:wght@400;600;700&display=swap">
        @stack('styles') 
        <!-- Scripts -->
        @vite(['resources/css/app.css', 'resources/js/app.js'])

    </head>

    <body class="font-sans antialiased">
        <div class="min-h-screen bg-gray-100">
            @include('layouts.navigation')

            <!-- Page Heading -->
            <header class="bg-white shadow">
                <div class="px-4 py-6 mx-auto max-w-7xl sm:px-6 lg:px-8">
                    {{ $header }}
                </div>
            </header>

            <!-- Page Content -->
            <main>
                {{ $slot }}
            </main>
        </div>
        @stack('scripts')
    </body>

</html>

Paso 7: Cree un archivo de vista de hoja y agregue EasyMDE Markdown Editor

Ahora agregue el editor de rebajas easymade.

ver/mensajes/create.blade.php

<x-app-layout>
    @push('styles')
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/easymde/dist/easymde.min.css">
    @endpush
    <x-slot name="header">
        <h2 class="text-xl font-semibold leading-tight text-gray-800">
            {{ __('Post Create') }}
        </h2>
    </x-slot>

    <div class="py-12">
        <div class="mx-auto max-w-7xl sm:px-6 lg:px-8">
            <div class="overflow-hidden bg-white shadow-sm sm:rounded-lg">
                <div class="p-6 bg-white border-b border-gray-200">
                    <form method="POST" action="{{ route('posts.store') }}">
                        @csrf
                        <div class="mb-6">
                            <label class="block">
                                <span class="text-gray-700">Title</span>
                                <input type="text" name="title"
                                    class="block w-full @error('title') border-red-500 @enderror mt-1 rounded-md"
                                    placeholder="" value="{{old('title')}}" />
                            </label>
                            @error('title')
                            <div class="text-sm text-red-600">{{ $message }}</div>
                            @enderror
                        </div>
                        <div class="mb-6">
                            <label class="block">
                                <span class="text-gray-700">Slug</span>
                                <input type="text" name="slug"
                                    class="block w-full @error('slug') border-red-500 @enderror mt-1 rounded-md"
                                    placeholder="" value="{{old('slug')}}" />
                            </label>
                            @error('slug')
                            <div class="text-sm text-red-600">{{ $message }}</div>
                            @enderror
                        </div>
                        <div class="mb-6">
                            <label class="block">
                                <span class="text-gray-700">Description</span>
                                <textarea id="markdown-editor" class="block w-full mt-1 rounded-md" name="description"
                                    rows="3"></textarea>
                            </label>
                            @error('description')
                            <div class="text-sm text-red-600">{{ $message }}</div>
                            @enderror
                        </div>
                        <button type="submit"
                            class="text-white bg-blue-600  rounded text-sm px-5 py-2.5">Submit</button>

                    </form>
                </div>
            </div>
        </div>
    </div>
    @push('scripts')
    <script src="https://cdn.jsdelivr.net/npm/easymde/dist/easymde.min.js"></script>
    <script>
        const easyMDE = new EasyMDE({
            showIcons: ['strikethrough', 'code', 'table', 'redo', 'heading', 'undo', 'heading-bigger', 'heading-smaller', 'heading-1', 'heading-2', 'heading-3', 'clean-block', 'horizontal-rule'],
            element: document.getElementById('markdown-editor')});
    </script>
    @endpush
</x-app-layout>

editor de rebajas de laravel 9

ver/mensajes/show.blade.php

<x-app-layout>
    <x-slot name="header">
        <h2 class="text-xl font-semibold leading-tight text-gray-800">
            {{ __('Posts Show') }}
        </h2>
    </x-slot>

    <div class="py-12">
        <div class="max-w-4xl mx-auto sm:px-6 lg:px-8">
            <div class="overflow-hidden bg-white shadow-sm sm:rounded-lg">
                <div class="p-6 bg-white border-b border-gray-200">

                    <div>
                        <h1 class="text-2xl">{{ $post->title }}</h1>
                        <div class="prose lg:prose-xl">{!! $post->description !!}</div>
                    </div>

                </div>
            </div>
        </div>
    </div>
    
</x-app-layout>

editor de rebajas de laravel con css de viento de cola

Paso 8: Ejecute el servidor

ejecutar compilación vite

npm run dev
//or 
npm run build

ejecutar el servidor laravel

php artisan serve 

Fuente:  https://larainfo.com

#laravel #markdown #tailwindcss 

Editor De Rebajas En Laravel 9 Vite Con Tailwind CSS

Editor De Markdown Em Laravel 9 Vite Com Tailwind CSS

Nesta seção, instalamos e configuramos o editor Markdown no Laravel 9 Vite com Tailwind CSS.

Etapa 1: criar projeto Laravel e conectar banco de dados

Instalando um novo aplicativo laravel 9.

composer create-project laravel/laravel laravel-markdown

Agora, você precisa conectar o aplicativo laravel ao banco de dados,

.env

DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=database_name
DB_USERNAME=database_user_name
DB_PASSWORD=database_password

Passo 2: Instale o Laravel Breeze

Em seguida, você precisa instalar o laravel brisa via compositor.

composer require laravel/breeze --dev

instale o andaime da brisa.

php artisan breeze:install

instale o npm e migre o banco de dados.

npm install
npm run dev
php artisan migrate

Etapa 3: instalar a tipografia CSS Tailwind

instalar tipografia CSS tailwind.

npm install -D @tailwindcss/typography

Em seguida, adicione o plug-in ao seu arquivo tailwind.config.js:

tailwind.config.js

const defaultTheme = require('tailwindcss/defaultTheme');

/** @type {import('tailwindcss').Config} */
module.exports = {
    content: [
        './vendor/laravel/framework/src/Illuminate/Pagination/resources/views/*.blade.php',
        './storage/framework/views/*.php',
        './resources/views/**/*.blade.php',
    ],

    theme: {
        extend: {
            fontFamily: {
                sans: ['Nunito', ...defaultTheme.fontFamily.sans],
            },
        },
    },

    plugins: [require('@tailwindcss/forms'),require('@tailwindcss/typography')],
};

executar o parafuso

npm run dev

Passo 4: Instale o Laravel Markdown

instale o editor de markdown via compositor:

composer require graham-campbell/markdown:^14.0

Configuração de redução

O Laravel Markdown suporta configuração opcional.

Para começar, você precisará publicar todos os ativos do fornecedor:

php artisan vendor:publish

Etapa 5: criar controlador e rota de migração pós-modal

Execute abaixo para criar post model, migration e controller.

php artisan make:model Post -mcr

create_posts_table.php

public function up()
{
    Schema::create('posts', function (Blueprint $table) {
        $table->id();
        $table->string('title');
        $table->string('slug');
        $table->longText('description');
        $table->timestamps();
    });
}

Execute migrar novamente

php artisan migrate

app/Models/Post.php

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;

class Post extends Model
{
    use HasFactory;

    protected $fillable = [
        'title',
        'slug',
        'description',
    ];
}

web.php

<?php
use App\Http\Controllers\PostController;
use Illuminate\Support\Facades\Route;

/*
|--------------------------------------------------------------------------
| Web Routes
|--------------------------------------------------------------------------
|
| Here is where you can register web routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| contains the "web" middleware group. Now create something great!
|
*/

Route::get('/', function () {
    return view('welcome');
});

Route::get('/dashboard', function () {
    return view('dashboard');
})->middleware(['auth'])->name('dashboard');
Route::resource('posts', PostController::class);
require __DIR__.'/auth.php';

Agora você precisa importar GrahamCampbell\Markdown\Facades\Markdown ; e use a classe Markdown na descrição do post.

app/Http/Controllers/PostController.php

<?php

namespace App\Http\Controllers;

use App\Models\Post;
use Illuminate\Http\Request;
use GrahamCampbell\Markdown\Facades\Markdown;

class PostController extends Controller
{
    /**
     * Display a listing of the resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function index()
    {
        $posts = Post::latest()->paginate(10);

        return view('posts.index', compact('posts'));
    }

    /**
     * Show the form for creating a new resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function create()
    {
        return view('posts.create');
    }

    /**
     * Store a newly created resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\Response
     */
    public function store(Request $request)
    {
        $request->validate([
            'title' => 'required|string|max:255',
            'slug' => 'required|string|max:255',
            'description' => 'required'
        ]);
        Post::create([
            'title' => $request->title,
            'slug' => str()->slug($request->slug),
            'description' => Markdown::convert($request->description)->getContent(),
        ]);

        return redirect()->route('posts.index')->with('message', 'Post Created Successfully');
    }

    /**
     * Display the specified resource.
     *
     * @param  \App\Models\Post  $post
     * @return \Illuminate\Http\Response
     */
    public function show(Post $post)
    {
        return view('posts.show', compact('post'));
    }

    /**
     * Show the form for editing the specified resource.
     *
     * @param  \App\Models\Post  $post
     * @return \Illuminate\Http\Response
     */
    public function edit(Post $post)
    {
        //
    }

    /**
     * Update the specified resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \App\Models\Post  $post
     * @return \Illuminate\Http\Response
     */
    public function update(Request $request, Post $post)
    {
        //
    }

    /**
     * Remove the specified resource from storage.
     *
     * @param  \App\Models\Post  $post
     * @return \Illuminate\Http\Response
     */
    public function destroy(Post $post)
    {
        //
    }
}

Etapa 6: crie @stack em app.blade.php

Em seguida, você precisa criar @stack('styles') para o arquivo css e @stack('scripts') para js.

views/layouts/app.blade.php

<!DOCTYPE html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">

    <head>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <meta name="csrf-token" content="{{ csrf_token() }}">

        <title>{{ config('app.name', 'Laravel') }}</title>

        <!-- Fonts -->
        <link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Nunito:wght@400;600;700&display=swap">
        @stack('styles') 
        <!-- Scripts -->
        @vite(['resources/css/app.css', 'resources/js/app.js'])

    </head>

    <body class="font-sans antialiased">
        <div class="min-h-screen bg-gray-100">
            @include('layouts.navigation')

            <!-- Page Heading -->
            <header class="bg-white shadow">
                <div class="px-4 py-6 mx-auto max-w-7xl sm:px-6 lg:px-8">
                    {{ $header }}
                </div>
            </header>

            <!-- Page Content -->
            <main>
                {{ $slot }}
            </main>
        </div>
        @stack('scripts')
    </body>

</html>

Etapa 7: Crie o arquivo de visualização do blade e adicione o EasyMDE Markdown Editor

Agora adicione o editor de markdown easymade.

view/posts/create.blade.php

<x-app-layout>
    @push('styles')
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/easymde/dist/easymde.min.css">
    @endpush
    <x-slot name="header">
        <h2 class="text-xl font-semibold leading-tight text-gray-800">
            {{ __('Post Create') }}
        </h2>
    </x-slot>

    <div class="py-12">
        <div class="mx-auto max-w-7xl sm:px-6 lg:px-8">
            <div class="overflow-hidden bg-white shadow-sm sm:rounded-lg">
                <div class="p-6 bg-white border-b border-gray-200">
                    <form method="POST" action="{{ route('posts.store') }}">
                        @csrf
                        <div class="mb-6">
                            <label class="block">
                                <span class="text-gray-700">Title</span>
                                <input type="text" name="title"
                                    class="block w-full @error('title') border-red-500 @enderror mt-1 rounded-md"
                                    placeholder="" value="{{old('title')}}" />
                            </label>
                            @error('title')
                            <div class="text-sm text-red-600">{{ $message }}</div>
                            @enderror
                        </div>
                        <div class="mb-6">
                            <label class="block">
                                <span class="text-gray-700">Slug</span>
                                <input type="text" name="slug"
                                    class="block w-full @error('slug') border-red-500 @enderror mt-1 rounded-md"
                                    placeholder="" value="{{old('slug')}}" />
                            </label>
                            @error('slug')
                            <div class="text-sm text-red-600">{{ $message }}</div>
                            @enderror
                        </div>
                        <div class="mb-6">
                            <label class="block">
                                <span class="text-gray-700">Description</span>
                                <textarea id="markdown-editor" class="block w-full mt-1 rounded-md" name="description"
                                    rows="3"></textarea>
                            </label>
                            @error('description')
                            <div class="text-sm text-red-600">{{ $message }}</div>
                            @enderror
                        </div>
                        <button type="submit"
                            class="text-white bg-blue-600  rounded text-sm px-5 py-2.5">Submit</button>

                    </form>
                </div>
            </div>
        </div>
    </div>
    @push('scripts')
    <script src="https://cdn.jsdelivr.net/npm/easymde/dist/easymde.min.js"></script>
    <script>
        const easyMDE = new EasyMDE({
            showIcons: ['strikethrough', 'code', 'table', 'redo', 'heading', 'undo', 'heading-bigger', 'heading-smaller', 'heading-1', 'heading-2', 'heading-3', 'clean-block', 'horizontal-rule'],
            element: document.getElementById('markdown-editor')});
    </script>
    @endpush
</x-app-layout>

editor de markdown laravel 9

view/posts/show.blade.php

<x-app-layout>
    <x-slot name="header">
        <h2 class="text-xl font-semibold leading-tight text-gray-800">
            {{ __('Posts Show') }}
        </h2>
    </x-slot>

    <div class="py-12">
        <div class="max-w-4xl mx-auto sm:px-6 lg:px-8">
            <div class="overflow-hidden bg-white shadow-sm sm:rounded-lg">
                <div class="p-6 bg-white border-b border-gray-200">

                    <div>
                        <h1 class="text-2xl">{{ $post->title }}</h1>
                        <div class="prose lg:prose-xl">{!! $post->description !!}</div>
                    </div>

                </div>
            </div>
        </div>
    </div>
    
</x-app-layout>

editor de markdown laravel com tailwind css

Etapa 8: execute o servidor

executar vite build

npm run dev
//or 
npm run build

executar servidor laravel

php artisan serve 

Fonte:  https://larainfo.com

#laravel #markdown #tailwindcss 

Editor De Markdown Em Laravel 9 Vite Com Tailwind CSS
Mike  Kozey

Mike Kozey

1661958120

Quill_markdown: A Quill to Markdown Converter and Vice Versa

Quill Markdown

This package converts quill delta to markdown (.md) and vice versa for the package flutter_quill.

String content = '[{"insert":"Heading"},{"insert":"\\n","attributes":{"header":1}},{"insert":"bold","attributes":{"bold":true}},{"insert":"\\n"},{"insert":"bold and italic","attributes":{"bold":true,"italic":true}},{"insert":"\\nsome code"},{"insert":"\\n","attributes":{"code-block":true}},{"insert":"A quote"},{"insert":"\\n","attributes":{"blockquote":true}},{"insert":"ordered list"},{"insert":"\\n","attributes":{"list":"ordered"}},{"insert":"unordered list"},{"insert":"\\n","attributes":{"list":"bullet"}},{"insert":"link","attributes":{"link":"pub.dev/packages/quill_markdown"}},{"insert":"\\n"}]';
content = quillToMarkdown(content);
print(content);
content = markdownToQuill(content);
print(content);

Known Limitations:

See why

  • Doesn't convert image, leaves that attribute.
  • Doesn't convert strike, leaves that attribute.
  • Doesn't convert color, leaves that attribute.
  • Doesn't convert background, leaves that attribute.
  • Doesn't convert underline, leaves that attribute.
  • Doesn't convert indent, leaves that attribute.
  • Doesn't convert checkbox, leaves that attribute.
  • Markdown to quill converter is very buggy.

Use this package as a library

Depend on it

Run this command:

With Flutter:

 $ flutter pub add quill_markdown

This will add a line like this to your package's pubspec.yaml (and run an implicit flutter pub get):

dependencies:
  quill_markdown: ^0.1.0

Alternatively, your editor might support flutter pub get. Check the docs for your editor to learn more.

Import it

Now in your Dart code, you can use:

import 'package:quill_markdown/quill_markdown.dart';

example/main.dart

import 'package:flutter/material.dart';
import 'package:quill_markdown/quill_markdown.dart';

class HomePage extends StatefulWidget {
  @override
  _HomePageState createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
        body: Center(
      child: FlatButton(
          onPressed: () {
            String content =
                '[{"insert":"Heading"},{"insert":"\\n","attributes":{"header":1}},{"insert":"bold","attributes":{"bold":true}},{"insert":"\\n"},{"insert":"bold and italic","attributes":{"bold":true,"italic":true}},{"insert":"\\nsome code"},{"insert":"\\n","attributes":{"code-block":true}},{"insert":"A quote"},{"insert":"\\n","attributes":{"blockquote":true}},{"insert":"ordered list"},{"insert":"\\n","attributes":{"list":"ordered"}},{"insert":"unordered list"},{"insert":"\\n","attributes":{"list":"bullet"}},{"insert":"link","attributes":{"link":"pub.dev/packages/quill_markdown"}},{"insert":"\\n"}]';
            content = quillToMarkdown(content)!;
            print(content);
            content = markdownToQuill(content)!;
            print(content);
          },
          child: Text('Convert')),
    ));
  }
}

Download Details:

Author: ArjanAswal
Source Code: https://github.com/ArjanAswal/quill_markdown 
License: MIT license

#flutter #dart #markdown 

Quill_markdown: A Quill to Markdown Converter and Vice Versa
Dexter  Goodwin

Dexter Goodwin

1661957760

Code-surfer: Rad Code Slides <🏄/>

Code Surfer

Help to keep this project alive with your support ❤️

Code Surfer adds code highlighting, code zooming, code scrolling, code focusing, code morphing, and fun to MDX Deck slides.

To create a new project run:

npm init code-surfer-deck my-deck
cd my-deck
npm start

Examples

How to use Code Surfer

It may help to know how MDX Deck works first

To use Code Surfer you need to import it and wrap the code you want to show inside <CodeSurfer> tags (the empty lines before and after the codeblock are required):

import { CodeSurfer } from "code-surfer"

# Deck Title

---

<CodeSurfer>

```js
console.log(1);
console.log(2);
console.log(3);
```

</CodeSurfer>

Here is a live deck using all the features (and its mdx source) just in case you prefer to read code instead of docs.

Focus

Add a focus string after the language in the first line of a codeblock to tell Code Surfer what lines and columns you want to focus.

Code Surfer will fade out all the code that isn't focused and, if necessary, zoom it out to fit it in the slide.

<CodeSurfer>

```js 1:2,3[8:10]
console.log(1);
console.log(2);
console.log(3);
```

</CodeSurfer>

In the example above 1:2,3[8:10] means: "focus from the line 1 to line 2 and the columns 8 to 10 from line 3". More examples:

  • 5:10 focus lines 5,6,7,8,9 and 10
  • 1,3:5,7 focus lines 1,3,4,5 and 7
  • 2[5] focus column 5 in line 2
  • 2[5:8] focus columns 5, 6, 7 and 8 in line 2
  • 1,2[1,3:5,7],3 focus line 1, columns 1, 3, 4, 5 and 7 in line 2 and line 3

Note: In previous versions of CodeSurfer we used tokens instead of columns.

Steps

Add more codeblocks to add steps to a Code Surfer slide.

<CodeSurfer>

```js
console.log(1);
console.log(2);
console.log(3);
```

```js 1
console.log(1);
console.log(2);
console.log(3);
```

```js
console.log(1);
console.log(2);
console.log(3);
console.log(4);
console.log(5);
```

</CodeSurfer>

You can change the focus and/or the code for different steps and Code Surfer will make the transition between the steps: zooming, scrolling, fading in, fading out, adding and removing lines.

Title and Subtitle

<CodeSurfer>

```js 1 title="Title" subtitle="Look at the first line"
console.log(1);
console.log(2);
console.log(3);
```

```js 2 title="Title" subtitle="and now the second"
console.log(1);
console.log(2);
console.log(3);
```

</CodeSurfer>

Themes

Code Surfer Themes

There are many Code Surfer themes available on the @code-surfer/themes package.

You can pass the theme as a prop <CodeSurfer theme={someTheme}>:

import { CodeSurfer } from "code-surfer"
import { nightOwl } from "@code-surfer/themes"

<CodeSurfer theme={nightOwl}>

```js
console.log(1);
console.log(2);
console.log(3);
```

</CodeSurfer>

Or set the theme for the whole deck as any other MDX Deck theme:

import { CodeSurfer } from "code-surfer"
import { nightOwl } from "@code-surfer/themes"

export const theme = nightOwl

<CodeSurfer>

```js
console.log(1);
console.log(2);
console.log(3);
```

</CodeSurfer>

Exporting the theme like this will also change the text and background colors for slides that aren't using Code Surfer. If you want to keep the colors from a different mdx deck theme you can compose both themes together: export const themes = [codeSurferTheme, mdxDeckTheme]

Custom Styles

You can write your own Code Surfer theme and change the style of the code, title and subtitle:

Themes use Theme UI internally

// custom-theme.js
export default {
  colors: {
    background: "#222",
    text: "#ddd",
    primary: "#a66"
  },
  styles: {
    CodeSurfer: {
      pre: {
        color: "text",
        backgroundColor: "background"
      },
      code: {
        color: "text",
        backgroundColor: "background"
      },
      tokens: {
        "comment cdata doctype": {
          fontStyle: "italic"
        },
        "builtin changed keyword punctuation operator tag deleted string attr-value char number inserted": {
          color: "primary"
        },
        "line-number": {
          opacity: 0.8
        }
      },
      title: {
        backgroundColor: "background",
        color: "text"
      },
      subtitle: {
        color: "#d6deeb",
        backgroundColor: "rgba(10,10,10,0.9)"
      },
      unfocused: {
        // only the opacity of unfocused code can be changed
        opacity: 0.1
      }
    }
  }
};

And use it in your deck like any other theme:

import { CodeSurfer } from "code-surfer"
import customTheme from "./custom-theme"

<CodeSurfer theme={customTheme}>

```js
console.log(1);
console.log(2);
console.log(3);
```

</CodeSurfer>

Languages

Code Surfer uses Prism for parsing different languages, so it supports all the languages supported by Prism.

Most popular languages are supported out of the box, for the rest you need to import them:

import { CodeSurfer } from "code-surfer"
import "prismjs/components/prism-smalltalk"

<CodeSurfer>

```smalltalk
result := a > b
    ifTrue:[ 'greater' ]
    ifFalse:[ 'less or equal' ]
```

</CodeSurfer>

Columns

If you want to show more than one piece of code at the same time, use <CodeSurferColumns>:

import { CodeSurferColumns, Step } from "code-surfer"

<CodeSurferColumns>

<Step subtitle="First Step">

```js
console.log(1);
console.log(2);
```

```js
console.log("a");
console.log("b");
```

</Step>

<Step subtitle="Second Step">

```js 2
console.log(1);
console.log(2);
```

```js 2
console.log("a");
console.log("b");
```

</Step>

</CodeSurferColumns>

Each <Step> can have its own title and subtitle.

You can use different themes for each column: <CodeSurferColumns themes={[nightOwl, ultramin]}>. And change the relative size of the columns with <CodeSurferColumns sizes={[1,3]}>.

Columns aren't only for code, you can use them for any kind of content:

import { CodeSurferColumns, Step } from "code-surfer"
import MyComponent from "./my-component.jsx"

<CodeSurferColumns>

<Step>

```js
console.log(1);
console.log(2);
```

# Some Markdown

</Step>

<Step>

```js 2
console.log(1);
console.log(2);
```

<MyComponent/>

</Step>

</CodeSurferColumns>

Import Code

Instead of writing the code inside codeblocks you can import it from a file:

import { CodeSurfer } from "code-surfer"

<CodeSurfer>

```js 5:10 file=./my-code.js
```

```js file=./my-other-code.js
```

</CodeSurfer>

Line Numbers

To show line numbers add the showNumbers flag to the first step:

import { CodeSurfer } from "code-surfer"

<CodeSurfer>

```js showNumbers
console.log(1);
console.log(2);
console.log(3);
```

```js
console.log(1);
console.log(2);
console.log(4);
```

</CodeSurfer>

Diffs

Codeblocks can also be diffs. This is particularly useful when using empty diffs for code that doesn't change:

import { CodeSurfer } from "code-surfer"

<CodeSurfer>

```js
console.log(1);
console.log(2);
console.log(3);
```

```diff 1 subtitle="log 1"

```

```diff 2 subtitle="log 2"

```

```diff 3 subtitle="log 3"

```

</CodeSurfer>

Related

Download Details:

Author: Pomber
Source Code: https://github.com/pomber/code-surfer 
License: MIT license

#javascript #code #react #markdown 

Code-surfer: Rad Code Slides <🏄/>
Reid  Rohan

Reid Rohan

1661881800

Dox: JavaScript Documentation Generator for Node using Markdown, jsdoc

Dox

Dox is a JavaScript documentation generator written with node. Dox no longer generates an opinionated structure or style for your docs, it simply gives you a JSON representation, allowing you to use markdown and JSDoc-style tags.

Installation

Install from npm:

$ npm install -g dox

Usage Examples

dox(1) operates over stdio:

$ dox < utils.js
...JSON...

to inspect the generated data you can use the --debug flag, which is easier to read than the JSON output:

 $ dox --debug < utils.js

utils.js:

/**
 * Escape the given `html`.
 *
 * @example
 *     utils.escape('<script></script>')
 *     // => '&lt;script&gt;&lt;/script&gt;'
 *
 * @param {String} html string to be escaped
 * @return {String} escaped html
 * @api public
 */

exports.escape = function(html){
  return String(html)
    .replace(/&(?!\w+;)/g, '&amp;')
    .replace(/</g, '&lt;')
    .replace(/>/g, '&gt;');
};

output:

[
  {
    "tags": [
      {
        "type": "example",
        "string": "    utils.escape('<script></script>')\n    // => '&lt;script&gt;&lt;/script&gt;'",
        "html": "<pre><code>utils.escape(&#39;&lt;script&gt;&lt;/script&gt;&#39;)\n// =&gt; &#39;&amp;lt;script&amp;gt;&amp;lt;/script&amp;gt;&#39;\n</code></pre>"
      },
      {
        "type": "param",
        "string": "{String} html string to be escaped",
        "types": [
          "String"
        ],
        "name": "html",
        "description": "string to be escaped"
      },
      {
        "type": "return",
        "string": "{String} escaped html",
        "types": [
          "String"
        ],
        "description": "escaped html"
      },
      {
        "type": "api",
        "string": "public",
        "visibility": "public"
      }
    ],
    "description": {
      "full": "<p>Escape the given <code>html</code>.</p>",
      "summary": "<p>Escape the given <code>html</code>.</p>",
      "body": ""
    },
    "isPrivate": false,
    "ignore": false,
    "code": "exports.escape = function(html){\n  return String(html)\n    .replace(/&(?!\\w+;)/g, '&amp;')\n    .replace(/</g, '&lt;')\n    .replace(/>/g, '&gt;');\n};",
    "ctx": {
      "type": "method",
      "receiver": "exports",
      "name": "escape",
      "string": "exports.escape()"
    }
  }
]

This output can then be passed to a template for rendering. Look below at the "Properties" section for details.

Usage


Usage: dox [options]

  Options:

    -h, --help                     output usage information
    -V, --version                  output the version number
    -r, --raw                      output "raw" comments, leaving the markdown intact
    -a, --api                      output markdown readme documentation
    -s, --skipPrefixes [prefixes]  skip comments prefixed with these prefixes, separated by commas
    -d, --debug                    output parsed comments for debugging
    -S, --skipSingleStar           set to false to ignore `/* ... */` comments

  Examples:

    # stdin
    $ dox > myfile.json

    # operates over stdio
    $ dox < myfile.js > myfile.json

Programmatic Usage

var dox = require('dox'),
    code = "...";

var obj = dox.parseComments(code);

// [{ tags:[ ... ], description, ... }, { ... }, ...]

Properties

A "comment" is comprised of the following detailed properties:

- tags
- description
- isPrivate
- isEvent
- isConstructor
- line
- ignore
- code
- ctx

Description

A dox description is comprised of three parts, the "full" description, the "summary", and the "body". The following example has only a "summary", as it consists of a single paragraph only, therefore the "full" property has only this value as well.

/**
 * Output the given `str` to _stdout_.
 */

exports.write = function(str) {
  process.stdout.write(str);
};

yields:

description:
     { full: '<p>Output the given <code>str</code> to <em>stdout</em>.</p>',
       summary: '<p>Output the given <code>str</code> to <em>stdout</em>.</p>',
       body: '' },

Large descriptions might look something like the following, where the "summary" is still the first paragraph, the remaining description becomes the "body". Keep in mind this is markdown, so you can indent code, use lists, links, etc. Dox also augments markdown, allowing "Some Title:\n" to form a header.

/**
 * Output the given `str` to _stdout_
 * or the stream specified by `options`.
 *
 * Options:
 *
 *   - `stream` defaulting to _stdout_
 *
 * Examples:
 *
 *     mymodule.write('foo')
 *     mymodule.write('foo', { stream: process.stderr })
 *
 */

exports.write = function(str, options) {
  options = options || {};
  (options.stream || process.stdout).write(str);
};

yields:

description:
     { full: '<p>Output the given <code>str</code> to <em>stdout</em><br />or the stream specified by <code>options</code>.</p>\n\n<h2>Options</h2>\n\n<ul>\n<li><code>stream</code> defaulting to <em>stdout</em></li>\n</ul>\n\n<h2>Examples</h2>\n\n<pre><code>mymodule.write(\'foo\')\nmymodule.write(\'foo\', { stream: process.stderr })\n</code></pre>',
       summary: '<p>Output the given <code>str</code> to <em>stdout</em><br />or the stream specified by <code>options</code>.</p>',
       body: '<h2>Options</h2>\n\n<ul>\n<li><code>stream</code> defaulting to <em>stdout</em></li>\n</ul>\n\n<h2>Examples</h2>\n\n<pre><code>mymodule.write(\'foo\')\nmymodule.write(\'foo\', { stream: process.stderr })\n</code></pre>' }

Tags

Dox also supports JSdoc-style tags. Currently only @api is special-cased, providing the comment.isPrivate boolean so you may omit "private" utilities etc.

/**
 * Output the given `str` to _stdout_
 * or the stream specified by `options`.
 *
 * @param {String} str
 * @param {{stream: Writable}} options
 * @return {Object} exports for chaining
 */

exports.write = function(str, options) {
  options = options || {};
  (options.stream || process.stdout).write(str);
  return this;
};

yields:

tags:
   [ { type: 'param',
       string: '{String} str',
       types: [ 'String' ],
       name: 'str',
       description: '' },
     { type: 'param',
       string: '{{stream: Writable}} options',
       types: [ { stream: ['Writable'] } ],
       name: 'options',
       description: '' },
     { type: 'return',
       string: '{Object} exports for chaining',
       types: [ 'Object' ],
       description: 'exports for chaining' },
     { type: 'api',
       visibility: 'public' } ]

Complex jsdoc tags

dox supports all jsdoc type strings specified in the jsdoc documentation. You can specify complex object types including optional flag =, nullable ?, non-nullable ! and variable arguments ....

Additionally you can use typesDescription which contains formatted HTML for displaying complex types.

/**
 * Generates a person information string based on input.
 *
 * @param {string | {name: string, age: number | date}} name Name or person object
 * @param {{separator: string} =} options An options object
 * @return {string} The constructed information string
 */

exports.generatePersonInfo = function(name, options) {
  var str = '';
  var separator = options && options.separator ? options.separator : ' ';

  if(typeof name === 'object') {
    str = [name.name, '(', name.age, ')'].join(separator);
  } else {
    str = name;
  }
};

yields:

tags:
[
  {
    "tags": [
      {
        "type": "param",
        "string": "{string | {name: string, age: number | date}} name Name or person object",
        "name": "name",
        "description": "Name or person object",
        "types": [
          "string",
          {
            "name": [
              "string"
            ],
            "age": [
              "number",
              "date"
            ]
          }
        ],
        "typesDescription": "<code>string</code>|{ name: <code>string</code>, age: <code>number</code>|<code>date</code> }",
        "optional": false,
        "nullable": false,
        "nonNullable": false,
        "variable": false
      },
      {
        "type": "param",
        "string": "{{separator: string} =} options An options object",
        "name": "options",
        "description": "An options object",
        "types": [
          {
            "separator": [
              "string"
            ]
          }
        ],
        "typesDescription": "{ separator: <code>string</code> }|<code>undefined</code>",
        "optional": true,
        "nullable": false,
        "nonNullable": false,
        "variable": false
      },
      {
        "type": "return",
        "string": "{string} The constructed information string",
        "types": [
          "string"
        ],
        "typesDescription": "<code>string</code>",
        "optional": false,
        "nullable": false,
        "nonNullable": false,
        "variable": false,
        "description": "The constructed information string"
      }
    ]

Code

The .code property is the code following the comment block, in our previous examples:

exports.write = function(str, options) {
  options = options || {};
  (options.stream || process.stdout).write(str);
  return this;
};

Ctx

The .ctx object indicates the context of the code block, is it a method, a function, a variable etc. Below are some examples:

exports.write = function(str, options) {
};

yields:

ctx:
 { type: 'method',
   receiver: 'exports',
   name: 'write',
   string: 'exports.write()' } }
var foo = 'bar';

yields:

ctx:
 { type: 'declaration',
   name: 'foo',
   value: '\'bar\'',
   string: 'foo' }
function User() {

}

yields:

ctx:
 { type: 'function',
   name: 'User',
   string: 'User()' } }

Extending Context Matching

Context matching in dox is done by performing pattern matching against the code following a comment block. dox.contextPatternMatchers is an array of all pattern matching functions, which dox will iterate over until one of them returns a result. If none return a result, then the comment block does not receive a ctx value.

This array is exposed to allow for extension of unsupported context patterns by adding more functions. Each function is passed the code following the comment block and (if detected) the parent context if the block.

dox.contextPatternMatchers.push(function (str, parentContext) {
  // return a context object if found
  // return false otherwise
});

Ignore

Comments and their associated bodies of code may be flagged with "!" to be considered worth ignoring, these are typically things like file comments containing copyright etc, however you of course can output them in your templates if you want.

/**
 * Not ignored.
 */

vs

/*!
 * Ignored.
 */

You may use -S, --skipSingleStar or {skipSingleStar: true} to ignore /* ... */ comments.

Running tests

Install dev dependencies and execute make test:

 $ npm install -d
 $ make test

Download Details:

Author: tj
Source Code: https://github.com/tj/dox 
License: MIT License

#javascript #markdown #jsdoc 

Dox: JavaScript Documentation Generator for Node using Markdown, jsdoc
Elian  Harber

Elian Harber

1661334669

Glamour: Stylesheet-based Markdown Rendering for Your CLI Apps

Glamour    

Stylesheet-based markdown rendering for your CLI apps.

Glamour dark style example

glamour lets you render markdown documents & templates on ANSI compatible terminals. You can create your own stylesheet or simply use one of the stylish defaults.

Usage

import "github.com/charmbracelet/glamour"

in := `# Hello World

This is a simple example of Markdown rendering with Glamour!
Check out the [other examples](https://github.com/charmbracelet/glamour/tree/master/examples) too.

Bye!
`

out, err := glamour.Render(in, "dark")
fmt.Print(out)

Hello World example

Custom Renderer

import "github.com/charmbracelet/glamour"

r, _ := glamour.NewTermRenderer(
    // detect background color and pick either the default dark or light theme
    glamour.WithAutoStyle(),
    // wrap output at specific width
    glamour.WithWordWrap(40),
)

out, err := r.Render(in)
fmt.Print(out)

Styles

You can find all available default styles in our gallery. Want to create your own style? Learn how!

There are a few options for using a custom style:

  1. Call glamour.Render(inputText, "desiredStyle")
  2. Set the GLAMOUR_STYLE environment variable to your desired default style or a file location for a style and call glamour.RenderWithEnvironmentConfig(inputText)
  3. Set the GLAMOUR_STYLE environment variable and pass glamour.WithEnvironmentConfig() to your custom renderer

Glamourous Projects

Check out these projects, which use glamour:

  • Glow, a markdown renderer for the command-line.
  • GitHub CLI, GitHub’s official command line tool.
  • GLab, an open source GitLab command line tool.
  • Meteor, an easy-to-use, plugin-driven metadata collection framework.

Download Details:

Author: Charmbracelet
Source Code: https://github.com/charmbracelet/glamour 
License: MIT license

#go #golang #markdown #cli 

Glamour: Stylesheet-based Markdown Rendering for Your CLI Apps
Nat  Grady

Nat Grady

1661323260

Shinyhelper: Add Markdown Help Files to 'shiny' Apps

shinyhelper

Easily add help documentation to shiny elements, using markdown files.

The advantages of using this package are:

  • add help files with a single extra function call
  • leverage the formatting power of markdown to go beyond simple tooltips
  • customise the appearance and positioning of the help icons, and the size of help pages
  • additional function to quickly create a suitable directory of markdown files

Installation

shinyhelper 0.3.2 now on CRAN!

You can install the package with:

install.packages("shinyhelper")

To get the latest development version, you can use the devtools package to install from GitHub directly:

devtools::install_github("cwthom/shinyhelper")

In both cases, then load the package in with:

library(shinyhelper)

Demo

There is a live demo hosted on shinyapps.io. Click here to go to the demo!

Alternatively, run the demo locally with:

library(shinyhelper)

shinyhelper_demo()

Usage

You can add help files to any shiny element, including all inputs and outputs, with a simple call to helper():

# load the package
library(shinyhelper)

...
# For elements in your ui you wish to add a help icon to
helper(plotOutput(outputId = "plot"))

# if you have %>% loaded, you can do plotOutput(outputId = "plot") %>% helper()

...
# In your server script, include:
observe_helpers()

# this triggers the modal dialogs when the user clicks an icon
# specify the name of your directory of help markdown files here

# e.g. observe_helpers(help_dir = "help_mds") will look for a directory called help_mds

# If you wish to include mathematical formulae in your markdown, use the `withMathJax` argument:
# observe_helpers(withMathJax = TRUE)

You can define helpers in dynamic UI elements as well, and have the help file rendered dynamically on the server side. This allows for :

  • conditioning which help file to show
  • defining inline content based on input settings

Content

All you need now is some content for your help page. You can specify this in 2 ways:

inline

To specify inline content, simply set type = "inline" in helper, and supply the title and content arguments. content can be a character vector, in which case each element will be a new line. You can also use raw HTML tags to format your inline content E.g.

plotOutput(outputId = "plot") %>% helper(type = "inline",
                                         title = "Plot",
                                         content = c("This is a <b>plot</b>.",
                                                     "This is on a new line."))

markdown

To use markdown, set type = "markdown" in helper, and supply the name of your markdown file (without the .md) in the content argument. This file should be in the directory specified by the help_dir argument to observe_helpers. E.g.

plotOutput(outputId = "plot") %>% helper(type = "markdown",
                                         content = "Plot")

# this will search for 'Plot.md' in the directory given in observe_helpers

You can specify a title argument too, or leave it blank and use a ## Heading in your markdown document.

Changing the Icon Appearance

You can change the type of icon used and its colour, as well as passing CSS inline.

Icon

The icons are shiny::icon("question-circle") icons by default, but you can change them individually using the icon argument of helper():

plotOutput(outputId = "plot") %>% helper(icon = "exclamation")

Please see Font Awesome for the available icons.

Colour

You can change the icon colour with the colour argument. Pass it any valid CSS colour as a character string.

plotOutput(outputId = "plot") %>% helper(colour = "green")

Inline CSS

You can pass a style argument to modify CSS inline. This applies to the <div> containing the icon.

plotOutput(outputId = "plot") %>% helper(style = "color: red;")

Note: Passing a colour in a style argument will override colour.

Changing the Help Page Size

By default, all help files are medium sized modalDialog() boxes (size = "m"). You can change each one though, by passing the size argument to helper():

plotOutput(outputId = "plot") %>% helper(size = "l")

Other Arguments

You can also change:

  • the label on the modalButton, with the buttonLabel argument
  • the easyClose and fade arguments governing the behaviour of the modal

Creating your Help Files

There is also a function, create_help_files() to quickly create a directory of help files from a vector of names.

# Run this interactively, not in a shiny app
create_help_files(files = c("Clusters", "Columns", "PlotHelp"), 
                  help_dir = "helpfiles")

The help_dir will be "helpfiles" by default.

Credits

Obviously, this package would not be possible (or indeed meaningful) without the incredible shiny package. Full credit to the authors of shiny for doing all of the actual work!

Many thanks also to Guangchang Yu for the wonderful hexSticker package!

Download Details:

Author: cwthom
Source Code: https://github.com/cwthom/shinyhelper 

#r #markdown #elements 

Shinyhelper: Add Markdown Help Files to 'shiny' Apps