【summernote-ext-highlight】首个 summernote 官方推荐的代码高亮插件

summernote 是一个超级简单的WYSIWYG编辑器,summernote-ext-highlight 是首个被summernote官方推荐的代码高亮编辑器🎉🎉🎉🎉

summernote-ext-highlight基于Google code-prettify开发,提供快速添加代码块UI层,只需简单配置即可使用👍👍👍。

使用方法

<script src="http://your domain/summernote-ext-highlight.js"></script>

$('.summernote').summernote({
    height: 200,
    tabsize: 2,
    // close prettify Html
    prettifyHtml:false,
    toolbar:[
        // Add highlight plugin
        ['highlight', ['highlight']],
    ],
    lang:'zh-CN'
});

地址https://github.com/heyanlong/summernote-ext-highlight

使用MIT协议,欢迎Star、Fork

使用C语言为PHP添加内置类

PHP可以简单拆分为zend vm + 一系列内置库,PHP通过加载动态链接库(so或dll)使其功能变得更加强大。

每一位PHPer或多或少的了解过PHP扩展的开发,但好多都局限于为PHP添加一个方法或者一个简单的类,不够全面。今天我尝试为PHP添加一个完整的类,记录一下学习过程。

PHP实现

我要实现的类(PHP)

<?php

namespace Yanlong\Http;

class Client extends BaseClient implements ClientInterface
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function getHost()
    {
        return $this->host;
    }
}

经过拆解,一个完整的PHP类需要包含

  1. 命名空间
  2. 类修饰符,默认为public
  3. 继承与接口
  4. 定义属性
  5. 定义方法

C实现

接下来尝试使用ZEND API来完成当前类

//
// Created by 何延龙 on 2018/8/2.
//
#include "php.h"
#include "common.h"
#include "client.h"

zend_class_entry *guzzle_client_ce;

static zend_function_entry guzzle_client_method[] = {
        PHP_ME(Client, __construct, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_CTOR)
        PHP_ME(Client, getHost, NULL, ZEND_ACC_PRIVATE)

        PHP_FE_END
};

void guzzle_init_client() {
    zend_class_entry ce;

    // 初始化一个有命名空间的类
    // GUZZLE_NS 为 Yanlong\\Http
    INIT_NS_CLASS_ENTRY(ce, GUZZLE_NS, "Client", guzzle_client_method);

    // 注册一个需要继承的类
    // 不需要继承则调用 zend_register_internal_class
    guzzle_client_ce = zend_register_internal_class_ex(&ce, guzzle_base_client_ce);

    // 绑定要实现的接口
    zend_class_implements(guzzle_client_ce, 1, guzzle_client_interface_ce);

    // 为类添加属性 访问类型为private
    zend_declare_property_null(guzzle_client_ce, ZEND_STRL("host"), ZEND_ACC_PRIVATE);
}

PHP_METHOD (Client, __construct) {

    zend_string *host;

    if (zend_parse_parameters(ZEND_NUM_ARGS(), "S", &host) == FAILURE) {
        return;
    }

    zend_update_property_str(guzzle_client_ce, getThis(), ZEND_STRL("host"), host);

}

PHP_METHOD (Client, getHost) {

    // 读取并return
    zend_read_property(guzzle_client_ce, getThis(), ZEND_STRL("host"), 0, return_value);

}

可以看到很简单的几行PHP代码,从C来写其实很复杂,C写的每一行代码,其实都是zend vm解析PHP需要执行的。

从上倒下简单拆解一下,梳理PHP执行流程

// 定义一个class结构体,详细查看zend.h _zend_class_entry
zend_class_entry *guzzle_client_ce;
// 对class结构体初始化
// 主要通过INIT_NS_CLASS_ENTRY宏对_zend_class_entry 的属性进行赋值
// 通过zend api zend_register_internal_class_ex 注册到PHP引擎
void guzzle_init_client() {
    zend_class_entry ce;

    // 初始化一个有命名空间的类
    // GUZZLE_NS 为 Yanlong\\Http
    INIT_NS_CLASS_ENTRY(ce, GUZZLE_NS, "Client", guzzle_client_method);

    // 注册一个需要继承的类
    // 不需要继承则调用 zend_register_internal_class
    guzzle_client_ce = zend_register_internal_class_ex(&ce, guzzle_base_client_ce);

    // 绑定要实现的接口
    zend_class_implements(guzzle_client_ce, 1, guzzle_client_interface_ce);

    // 为类添加属性 访问类型为private
    zend_declare_property_null(guzzle_client_ce, ZEND_STRL("host"), ZEND_ACC_PRIVATE);
}
// 通过PHP_METHOD 宏进行方法定义
// 展开 zim_Client___construct(zend_execute_data *execute_data, zval *return_value)
PHP_METHOD (Client, __construct) {

    zend_string *host;

    if (zend_parse_parameters(ZEND_NUM_ARGS(), "S", &host) == FAILURE) {
        return;
    }

    zend_update_property_str(guzzle_client_ce, getThis(), ZEND_STRL("host"), host);

}

可见使用C编写PHP类和使用PHP直接来写流程相似,阅读zend api后大概就能实现80%的常用功能,当然像trait和匿名函数操作还需要更底层的api来实现。

相关API

注册类 zend_API.h

zend_register_internal_class 注册一个普通类
zend_register_internal_class_ex 注册一个需要继承的类
zend_register_internal_interface 注册一个接口
zend_class_implements 实现N个接口

访问修饰符 zend_compile.h

ZEND_ACC_STATIC
ZEND_ACC_ABSTRACT
ZEND_ACC_FINAL
ZEND_ACC_PUBLIC
ZEND_ACC_PROTECTED
ZEND_ACC_PRIVATE
ZEND_ACC_CTOR 构造函数专用
ZEND_ACC_DTOR 析构函数专用

参数解析

zend_parse_parameters

参数返回

*return_value

如何自己制作机械键盘

看到同事都在用机械键盘来编写世界上最好的语言,自己心里痒痒😂但是找来找去也没找到合适的,主要还是给闹的。

后来在网上搜寻了一番找到了GH60[1]和tmk_keyboard[2]项目。软件硬件都有了😄搞起来。

准备

  1. PCB 绘制工具 KiCad
  2. AVR C 语言开发环境 CrossPack-AVR
  3. 试轴器一个,包含 黑、红、青、茶、四个常用轴体
  4. 制作材料一套,主要包含键盘冒、轴体若干、1n4148二级管若干、atmega32u4主控一个、恒温电烙铁一个、鸡翅木板一块

定制自己喜欢的布局

todo

根据布局开发PCB[3]

todo

  1. 开源的机械键盘硬件方案
  2. 基于AVR和Cortex-M的键盘主控程序
  3. 印制电路板,现代电子产品的基石,电子元器件的支撑体