整体介绍

Scintilla主要用于对文本的编辑,因此该部分的功能是Scintilla的核心所在。Scintilla以字节为基础单元处理整个文本。对于不同的编码格式,每个字符所占的字节个数并不相同。

比如常用的UTF-8编码,一个中文等于三个字节,中文标点占三个字节。一个英文字符等于一个字节,英文标点占一个字节。而对于Unicode编码,一个英文等于两个字节,一个中文(含繁体)等于两个字节。

在实际开发中,选择UTF-8编码,对于文本"abc",调用Scintilla获取文档字节总长的方法(SCI_GETLENGTH),返回值为3;对于文本"测试",调用Scintilla获取文档字节总长的方法(SCI_GETLENGTH),返回值为6

SCI_GETTEXT

SCI_GETTEXT(position length, char *text NUL-terminated) → position

该消息可获取从文档开头获取length-1长度的字节,所获取字节存入形参text内,因此text的空间应至少分配length的字节(最后一个字节为\0)。该消息返回值position为所获取字节的长度(注:改返回值通常等于length-1)。如果需要获取文档中的全部字节,可以先调用消息SCI_GETLENGTH,获取文档字节总长lenTotal,然后再调用方法:

SCI_GETTEXT(lenTotal+1, *text)

以UTF-8编码,如下文本内容为例:

如果对该文本发送如下消息:

SCI_GETTEXT(3, *text)

则返回的position=2,text所获取的文本内容为“Sc”

如果对该文本发送如下消息:

SCI_GETTEXT(15, *text)

则返回的position=14,text所获取的文本内容为“Scintilla是��”。此处最后的乱码是由于UTF-8中文占三个字节,而传入的length=15,实际获取字节数为length-1=14,刚好少了一个字节。如果发送如下消息:

SCI_GETTEXT(16, *text)

则返回的position=15text所获取的文本内容为“Scintilla是一”

SCI_SETTEXT

SCI_SETTEXT(<unused>, const char *text)

该消息可替换当前编辑器中的所有文本内容(即先清空后载入text的内容),text最后必须以\0作为结尾。

以UTF-8编码,如下文本内容为例:

如果对该文本发送如下消息:

SCI_SETTEXT(0,"Scintilla完全开放源代码,并且提供一个license允许用户自由地将它用在开源软件或是商业软件中") 

则文本内容为如下:

注:本消息(SCI_SETTEXT)经常用来载入并显示文本文件。而对于打开文本文件的操作,正常而言是不允许有回退(undo)操作的,因此在完成本消息调用后,通常会调用消息SCI_EMPTYUNDOBUFFER,用来清空回退(undo)操作历史序列。

SCI_SETSAVEPOINT

SCI_SETSAVEPOINT()

该消息用于设置控件内文本内容的保存标记。通常本消息与外部保存操作联动(Ctrl+S)。当文本内容变化后,回退(undo)操作历史序列会有相应变化,此时如果调用SCI_GETMODIFY消息:

bool dirtyFlag = SCI_GETMODIFY()

返回的当前文本修改状态dirtyFlag = true

该消息使用场景:

  • 打开文本文件后,执行SCI_SETSAVEPOINT()

  • 保存文本文件后,执行SCI_SETSAVEPOINT()

SCI_SETSAVEPOINT消息与如下两个事件相关:

  • SCN_SAVEPOINTREACHED :执行SCI_SETSAVEPOINT后,该事件触发。

  • SCN_SAVEPOINTLEFT :当文本内容有更改后,该事件触发。(此时外部容器可以做对应处理,比如可以将文件标题最后增加*号,表示需要保存)

SCI_GETLINE

SCI_GETLINE(line line, char *text) → position

该消息用于获取某一行(如果有换行情况,则换行符也会被获取)的文本内容。形参line的起始为序号0,所获取的文本内容被存入在形参text中。text的大小可以通过调用消息获取:

SCI_LINELENGTH(line line)

对于消息SCI_GETLINE而言,如果其形参line的值大于文本的行数,则text存入的字节为空。

以UTF-8编码,如下文本内容为例(注意第一行最后有换行):

如果对该文本执行如下代码:

int line = 0;
int len = SCI_LINELENGTH(line);     //伪代码
char* textLine = new char[len+1];
memset(textLine, 0, len + 1);
SCI_GETLINE(line, textLine)         //伪代码

执行过程中的变量值为(注意最后的\r\n):

len = 59;
textLine = "Scintilla是一个强大和稳定的源代码编辑控件\r\n"

SCI_REPLACESEL

SCI_REPLACESEL(<unused>, const char *text)

该消息用于替换选中的文本内容,其中形参text为待替入的字符串,以\0结尾。如果当前没有任何选中的内容,则该消息实际上执行的是插入操作(插入点为光标所在位置)。

完成本消息的调用后,光标位置位于插入字符串的末端。

以UTF-8编码,如下文本内容为例(注意选中的文本):

如果对该文本发送如下消息:

SCI_REPLACESEL(0,"123abc")

则结果为:

注意:执行该消息后,光标位置为所插入字符串"123abc"的末端。

SCI_SETREADONLY,SCI_GETREADONLY

SCI_SETREADONLY(bool readOnly), SCI_GETREADONLY → bool

SCI_SETREADONLYSCI_GETREADONLY 用于设置与读取文本的只读属性。当发送如下消息:

SCI_SETREADONLY(true)

则文本内容不可编辑。

Scintilla的源码中,与编辑相关的处理,都会判断当前文本的只读属性,如Document.cxx中的插入字符串操作,有如下判断:

Sci::Position Document::InsertString(Sci::Position position, const char *s, Sci::Position insertLength) {if (insertLength <= 0) {return 0;}CheckReadOnly();    // 判断当前文本的只读属性if (cb.IsReadOnly()) {return 0;}......
}

SCI_GETTEXTRANGE

SCI_GETTEXTRANGE(<unused>, Sci_TextRange *tr) → position

该消息类似SCI_GETTEXT消息,用于获得文档中的文本内容。区别在于SCI_GETTEXT是从文档头部开始获取,而本消息SCI_GETTEXTRANGE可以设定获取范围。

Sci_TextRangeScintilla定义的一个用于存储文本范围的数据结构,如下为其定义:

typedef long Sci_PositionCR;
​
struct Sci_CharacterRange {Sci_PositionCR cpMin;Sci_PositionCR cpMax;
};
​
struct Sci_TextRange {struct Sci_CharacterRange chrg; //文本范围: 起始点与结束点char *lpstrText;                //保存所选文本范围内的内容
};

以UTF-8编码,如下文本内容为例:

如果对该文本执行如下代码:

char text[10000] = { 0 };
Sci_TextRange textRange;
textRange.chrg.cpMin = 1;
textRange.chrg.cpMax = 5;
textRange.lpstrText = text;
SCI_GETTEXTRANGE(&textRange);           //伪代码

执行过程中的变量值为:

text = "cint"

如果对该文本执行如下代码:

char text[10000] = { 0 };
Sci_TextRange textRange;
textRange.chrg.cpMin = 9;
textRange.chrg.cpMax = 15;
textRange.lpstrText = text;
SCI_GETTEXTRANGE(&textRange);           //伪代码

执行过程中的变量值为(注意textRange设定的范围包含字节数为6,是3的整倍数,刚好包含两个UTF-8中文字符。如果不是3的整倍数,则获取的文本末尾会是乱码):

text = "是一"

SCI_GETSTYLEDTEXT

SCI_GETSTYLEDTEXT(<unused>, Sci_TextRange *tr) → position

该消息用于获取每个字节的值以及其当前样式,具体所返回数据详见下面的样例。在Scintilla中,文本内容的样式控制(如设置字体、下划线等)是通过设定不同的样式类型完成的。如下为Scintilla预先定义好的样式类型:

#define STYLE_DEFAULT 32                //默认样式
#define STYLE_LINENUMBER 33
#define STYLE_BRACELIGHT 34
#define STYLE_BRACEBAD 35
#define STYLE_CONTROLCHAR 36
#define STYLE_INDENTGUIDE 37
#define STYLE_CALLTIP 38
#define STYLE_FOLDDISPLAYTEXT 39
#define STYLE_LASTPREDEFINED 39
#define STYLE_MAX 255                   //最多可以设置255个样式

在Scintilla文本中的每一个字节都有其对应的样式,因此在显示文本时,Scintilla便可以根据每一个字节的样式,来进行特性化显示。具体样式的设定方法,在后面Styling相关说明时有详细展示。

本消息中的结构体Sci_TextRange在介绍SCI_GETTEXTRANGE时已经做过详细说明。

以UTF-8编码,如下文本内容为例(其中字符串"Sci"的样式做了单独定义,其样式值设定为STYLE_TEST=50):

如果对该文本执行如下代码:

#define STYLE_TEST      50                                  //自定义样式类型 STYLE_TEST=50
SCI_GETSTYLEDTEXT(SCI_STARTSTYLING,0);                      //伪代码,样式起始字节
SCI_GETSTYLEDTEXT(SCI_SETSTYLING, 3, STYLE_TEST);           //伪代码,样式结束字节
​
char styledText[10000] = { 0 };
Sci_TextRange textRange;
textRange.chrg.cpMin = 0;
textRange.chrg.cpMax = 15;
textRange.lpstrText = styledText;
SCI_GETSTYLEDTEXT(&textRange);          //伪代码

执行过程中的变量值styledText为:

-       styledText,100  0x00000005a46fa950  <字符串中的字符无效。>    char[100][0] 83 'S'  char[1] 50 '2'  char[2] 99 'c'  char[3] 50 '2'  char[4] 105 'i' char[5] 50 '2'  char[6] 110 'n' char[7] 0 '\0'  char[8] 116 't' char[9] 0 '\0'  char[10]    105 'i' char[11]    0 '\0'  char[12]    108 'l' char[13]    0 '\0'  char[14]    108 'l' char[15]    0 '\0'  char[16]    97 'a'  char[17]    0 '\0'  char

如上可见,变量styledText的第0、2、4位是文本字节的值“Sci”,第1、3、5位是定义的样式类型50,后面没有定义,则样式类型为0。

SCI_ALLOCATE

SCI_ALLOCATE(position bytes)

本消息用于分配一个足够大的文档缓冲区,从而避免了在文本内容修改时所造成的频繁文本内存扩容以及拷贝。

Scintilla的文本内容存放在CellBuffer的成员变量substance中:

class CellBuffer {
private:bool hasStyles;bool largeDocument;SplitVector<char> substance;                //存放Scintilla的文本内容SplitVector<char> style;bool readOnly;bool utf8Substance;Scintilla::LineEndType utf8LineEnds;......
}

在对Scintilla的文本做增加字符串的动作时(比如输入一些字符串),会调用到CellBuffer的插入字符串方法:

void CellBuffer::BasicInsertString(Sci::Position position, const char *s, Sci::Position insertLength)

在该方法内部,成员变量substance会根据当前空间大小进行动态扩容:

void RoomFor(ptrdiff_t insertionLength) {if (gapLength <= insertionLength) {while (growSize < static_cast<ptrdiff_t>(body.size() / 6))growSize *= 2;ReAllocate(body.size() + insertionLength + growSize);}
}

因此,提前给Scintilla设置一个缓存空间,可以提高性能。

SCI_ADDTEXT

SCI_ADDTEXT(position length, const char *text)

该消息用于在光标所在位置插入一定长度的字符串(形参const char *text),插入长度为(形参position length)。如果text="123abc"length=4,则插入字符串为“123a”。

以UTF-8编码,如下文本内容为例:

如果对该文本发送如下消息(注意当前光标在文字“”后面):

SCI_ADDTEXT(4,"123abc")

则结果为:

注意当前光标在新增加的字符串“123a”后面。

SCI_ADDSTYLEDTEXT

SCI_ADDSTYLEDTEXT(position length, cell *c)

该消息类似于SCI_ADDTEXT,用于在光标所在位置插入一定长度的字符串,所不同的是,插入字符串带有样式信息。

如预定义样式如下(具体样式的设定方法,在后面Styling相关说明时有详细展示):

#define STYLE_TEST  50  //自定义样式类型 STYLE_TEST=50,字体大小:12,颜色:蓝色,带下划线

以UTF-8编码,如下文本内容为例:

如果对该文本执行如下代码:

#define STYLE_TEST      50                                  //自定义样式类型 STYLE_TEST=50
​
char textWithStyle[1000] = {0};
textWithStyle[0] = '1';
textWithStyle[1] = STYLE_SEL;
textWithStyle[2] = '2';
textWithStyle[3] = STYLE_SEL;
textWithStyle[4] = '3';
textWithStyle[5] = STYLE_SEL;
textWithStyle[6] = 'a';
textWithStyle[7] = STYLE_SEL;
textWithStyle[8] = 'b';
textWithStyle[9] = STYLE_SEL;
textWithStyle[10] = 'c';
textWithStyle[11] = STYLE_SEL;
​
SCI_GETSTYLEDTEXT(12,textWithStyle);            //伪代码

则结果为:

SCI_APPENDTEXT

SCI_APPENDTEXT(position length, const char *text)

该消息类似于SCI_ADDTEXT,区别在于本消息用于在文档结尾位置插入一定长度的字符串,而SCI_ADDTEXT则是在光标所在位置插入。

以UTF-8编码,如下文本内容为例:

如果对该文本发送如下消息(注意当前光标在文字“”后面):

SCI_APPENDTEXT(4,"123abc")

则结果为:

注意当前新增加的字符串位于文档末尾处,光标位置不变,仍然在文字“”后面,另外,当前文档如果有选中字符串,其选中状态不变。

SCI_INSERTTEXT

SCI_INSERTTEXT(position pos, const char *text)

该消息类似于SCI_ADDTEXT,区别在于本消息用于在文档指定位置处插入全部长度的字符串,入参position pos 即为指定插入位置处。

以UTF-8编码,如下文本内容为例:

如果对该文本发送如下消息:

SCI_INSERTTEXT(12,"123abc")

则结果为:

SCI_CHANGEINSERTION

SCI_CHANGEINSERTION(position length, const char *text)

当准备在文本内容中增加或插入字符串时(比如调用SCI_SETTEXTSCI_ADDTEXT以及SCI_INSERTTEXT等消息),Scintilla会发送通知事件:SCN_MODIFIED,发送同时会携带通知数据:Scintilla::NotificationData

当有增加或插入字符串的动作时,Scintilla::NotificationData数据中的成员变量modificationType的值被设为SC_MOD_INSERTCHECK

此时,用户可以通过该消息SCI_CHANGEINSERTION对即将增加或插入字符串做修改。

Scintilla的通知事件的处理可以通过继承Editor类的纯虚函数实现:

virtual void NotifyParent(Scintilla::NotificationData scn) = 0;

实现方法为(QT程序会采用信号与槽的实现方式,原理一样):

//MyTextEdit继承ScintillaBase类,而ScintillaBase类又继承Editor类,从而可以处理Scintilla的通知事件
void MyTextEdit::NotifyParent(Scintilla::NotificationData *scn)
{int snCode = (int)scn->nmhdr.code;switch (snCode) {case SCN_MODIFIED:{int modificationType = (int)scn->modificationType;switch (modificationType){case SC_MOD_INSERTCHECK:{//TODO: 此处就可以发送SCI_CHANGEINSERTION消息对即将增加或插入字符串做修改break;}default:break;}break;}}
}

以UTF-8编码,如下文本内容为例:

对该文本内容的通知事件做如下处理(如果插入的字符串为"123abc",则将其修改为字符串"change",之后再插入):

//MyTextEdit继承ScintillaBase类,而ScintillaBase类又继承Editor类,从而可以处理Scintilla的通知事件
void MyTextEdit::NotifyParent(Scintilla::NotificationData *scn)
{int snCode = (int)scn->nmhdr.code;switch (snCode) {case SCN_MODIFIED:{int modificationType = (int)scn->modificationType;switch (modificationType){case SC_MOD_INSERTCHECK:{//如果插入的字符串为"123abc",则将其修改为字符串"change",之后再插入。if (strcmp(scn->text, "123abc")==0){m_sciEditor->SendScintilla(SCI_CHANGEINSERTION, 6, "change");}break;}default:break;}break;}}
}

此时对该文本发送如下消息:

SCI_INSERTTEXT(12,"123abc")

则结果为:

SCI_CLEARALL

SCI_CLEARALL()

该消息用于清空全部文本内容。注:当前文本处于非只读状态

以UTF-8编码,如下文本内容为例:

此时对该文本发送如下消息:

SCI_CLEARALL()

则结果为:

SCI_DELETERANGE

SCI_DELETERANGE(position start, position lengthDelete)

该消息用于清空设定起始位置与长度的文本内容。注:当前文本处于非只读状态

以UTF-8编码,如下文本内容为例:

此时对该文本发送如下消息:

SCI_DELETERANGE(1,8)

则结果为:

SCI_CLEARDOCUMENTSTYLE

SCI_CLEARDOCUMENTSTYLE()

该消息用于清除当前文本内容的所有样式以及重置当前的折叠状态(取消全部折叠)。

以UTF-8编码,如下文本内容为例(其中字符串"Sci"有独特样式):

此时对该文本发送如下消息:

SCI_CLEARDOCUMENTSTYLE()

则结果为:

SCI_GETCHARAT

SCI_GETCHARAT(position pos) → int

该消息用于获取所选位置的字节(注意不是字符,特别是对于中文,如“”,该字符的UTF-8编码为“E4B8AD”,因此如果此时发送消息SCI_GETCHARAT(0),则返回值为0xE4)。

以UTF-8编码,如下文本内容为例:

此时对该文本发送如下消息:

int res = SCI_GETCHARAT(9);

则结果res值为:0xffffffe6

SCI_GETSTYLEAT(position pos)

SCI_GETSTYLEAT(position pos) → int

该消息用于清除当前文本内容的所有样式以及重置当前的折叠状态(取消全部折叠)。

以UTF-8编码,如下文本内容为例(其中字符串"Sci"的样式值设定为50。具体样式的设定方法,在后面Styling相关说明时有详细展示):

此时对该文本发送如下消息:

int res = SCI_GETSTYLEAT(0);

则结果res值为:50

SCI_RELEASEALLEXTENDEDSTYLESSCI_ALLOCATEEXTENDEDSTYLES

SCI_RELEASEALLEXTENDEDSTYLES()

SCI_ALLOCATEEXTENDEDSTYLES(int numberStyles) → int

这两个消息应用于扩展样式。在Scintilla中,文本内容的样式控制(如设置字体、下划线等)是通过设定不同的样式类型完成的。如下为Scintilla预先定义好的样式类型:

#define STYLE_DEFAULT 32                //默认样式
#define STYLE_LINENUMBER 33
#define STYLE_BRACELIGHT 34
#define STYLE_BRACEBAD 35
#define STYLE_CONTROLCHAR 36
#define STYLE_INDENTGUIDE 37
#define STYLE_CALLTIP 38
#define STYLE_FOLDDISPLAYTEXT 39
#define STYLE_LASTPREDEFINED 39
#define STYLE_MAX 255                   //最多可以设置255个样式

由上可见,样式的定义值最多到255。但是针对页边(通常位于编辑器左侧,可以设置断点、页码等)以及注解功能,各自也需要样式定义,因此就需要扩充样式值。在Scintilla中,这两种消息分别对应如下两个函数:

void ViewStyle::ReleaseAllExtendedStyles() noexcept {nextExtendedStyle = 256;            //从256开始
}
​
int ViewStyle::AllocateExtendedStyles(int numberStyles) {//numberStyles是扩充的数量const int startRange = nextExtendedStyle;nextExtendedStyle += numberStyles;EnsureStyle(nextExtendedStyle);for (int i=startRange; i<nextExtendedStyle; i++) {styles[i].ClearTo(styles[StyleDefault]);}return startRange;
}

后续针对页边以及注解的样式扩充消息:SCI_MARGINSETSTYLEOFFSET(页边样式偏移) 以及 SCI_ANNOTATIONSETSTYLEOFFSET(注解样式偏移)。其调用之前需要应用消息SCI_ALLOCATEEXTENDEDSTYLES

SCI_TARGETASUTF8

SCI_TARGETASUTF8(<unused>, char *s) → position

目前这个消息在Scintilla的源码中没有做实现,ScintillaAPI文档对其描述主要是用于检索编码为UTF-8的目标值。

SCI_ENCODEDFROMUTF8SCI_SETLENGTHFORENCODE

SCI_ENCODEDFROMUTF8(const char *utf8, char *encoded) → position

SCI_SETLENGTHFORENCODE(position bytes)

上述两个消息作用在于将UTF8字符串转换成当前文档的编码格式,在ScintillaQt.cpp中有如下处理过程:

std::string ScintillaQt::EncodedFromUTF8(std::string_view utf8) const {if (IsUnicodeMode()) {return std::string(utf8);} else {QString text = QString::fromUtf8(utf8.data(), static_cast<int>(utf8.length()));QTextCodec *codec = QTextCodec::codecForName(CharacterSetID(CharacterSetOfDocument()));QByteArray ba = codec->fromUnicode(text);return std::string(ba.data(), ba.length());}
}

但是该函数并没有实际被调用,因此上述两消息暂时也无法应用。

Scintilla教程(2): 文本检索与修改相关推荐

  1. ps如何修改图片大小尺寸_PS新手入门教程:学习如何修改画布的大小

    PS新手入门教程:学习如何修改画布的大小.在photoshop中,可以把画布理解为一张白纸,而我们要处理的图像可以理解为这张白纸表面上的画.我们修改画布的大小时,图像并不会随着画布的大小而整体变大或缩 ...

  2. Magento教程 25:如何修改系统发送的通知信件?

    欢迎使用Magento购物车系统 ,上次和大家介绍的是限制会员留言的产品评论设定 :Astral Web这次要介绍如何修改通知信件的内文. 所谓的通知信件就是当客户注册成功.订单完成.出货通知等系统自 ...

  3. Magento教程 10:如何修改网站文字?

    你知道知名运动品牌NIKE.休闲鞋品牌TOMS都在使用Magento吗? Magento是一种多商店购物网站系统,其便利性佳.扩充性高,且功能强大,因此广受商家青睐. 此外,Magento在后台.前台 ...

  4. SAP UI5 应用开发教程之一百 - 如何修改 SAP UI5 框架的源代码实现,以及使用本地部署的 SAP UI5 SDK 试读版

    一套适合 SAP UI5 初学者循序渐进的学习教程 作者简介 Jerry Wang,2007 年从电子科技大学计算机专业硕士毕业后加入 SAP 成都研究院工作至今.Jerry 是 SAP 社区导师,S ...

  5. mysql修改游戏元宝_页游源码【武斗乾坤】自带安装启动教程+元宝游戏数据修改教程+自由一键游戏启动服务端...

    页游源码[武斗乾坤]自带安装启动教程+元宝游戏数据修改教程+自由一键游戏启动服务端_站长下载 资源说明: 1.本资源为一键启动服务端,只需要安装好所需组件一键启动即可运行. 2.资源默认为单机架设,无 ...

  6. zblog首页模板修改php,【zblog】zblogphp主题模板修改教程 zblogphp模板怎么修改?

    zblogphp主题模板修改教程 zblogphp模板怎么修改? 这一篇主要是介绍"zblogphp"的模板修改教程,zblogasp的模板修改教程请看本站之前发的一篇教程&quo ...

  7. 视频消重教程视频教程 视频md5修改app

             视频消重教程视频教程 视频md5修改app          在印尼不太平,在印度也不好过.近日有印度立法者表示Tik Tok中出现了.网络欺凌等内容,认为Tik Tok导致了青少年 ...

  8. BLE-NRF51822教程11-手机动态修改设备名

    该教程讲解如何实现用手机来动态修改设备名,达到手机连接设备后修改设备名称,然后断开连接再扫描能够看到新的设备名. 教程基于sdk9.0 下的uartdemo,如下目录中xxx\Keil_v5\ARM\ ...

  9. 反编译android 状态栏沉浸,教程:反编译修改实现状态栏时间居左,去除锁屏运营商...

    本帖最后由 Gleam 于 2017-7-30 21:15 编辑 重要的事情说三遍: 操作不当会有风险,如不能开机,systemui无限错误等,修改之前确定是否备份system分区. 操作不当会有风险 ...

  10. InDesign 教程如何创建和修改和使用母版页

    欢迎观看indesign教程,小编带大家学习 InDesign 的基本工具和使用技巧,了解InDesign如何创建和修改母版页,以及如何将母版页应用至文档页面. 母版页对于在整个文档中实现一致性非常有 ...

最新文章

  1. [嵌入式]Bootloader的作用
  2. 【漫画解读银行业务】
  3. x390更换开机_ThinkPad X390怎么装win10系统|ThinkPad X390用u盘重装win10系统教程-系统城...
  4. 如何从过滤器中排除URL
  5. OutOfMemoryError:Java堆空间–分析和解决方法
  6. OpenStack Weekly Rank 2015.08.24
  7. 实战篇—关于某产品的切分细则
  8. C++模版 (一) ----- 函数模版
  9. HelloDjango 第 10 篇:小细节 Markdown 文章自动生成目录,提升阅读体验
  10. vue引入bootstrap.min.css报错:Cannot find module ./assets/css/bootstrap.min.css
  11. 为什么root下不能使用passwd命令_Linux:CentOS 7中常用的基础命令
  12. storm中分组策略Field Grouping简单总结笔记
  13. Azure School女神相邀,把每分钟都过的更充实
  14. CCPC 合肥站 打铁记
  15. Latex 插入大括号分类情况
  16. 67、INGeo:利用占用网格先验加速/减少迭代次数
  17. Eclipse配置Python的IDE
  18. 测试有没有说梦话的软件,抖音上记录梦话的软件是什么 记录梦话的软件介绍...
  19. 现实迷途 第三十二章 阴晴反复(下)
  20. numpy——.npy和.npz文件

热门文章

  1. Linux开机自动挂载Windows分区的两种方法
  2. Oracle数据库备份与还原语句
  3. IBM系统分析——领域建模
  4. 2020高压电工考试软件及高压电工模拟考试题库
  5. 由中缀、后缀确定前缀表达式
  6. 前端开发者常见的英文单词汇总
  7. 利用SAP Leonardo做图片近似查找 ——Python实现
  8. 优秀的项目经理应该具备的能力
  9. python md5加密解密_python md5加密解密
  10. 用Python批量生成字幕图片用于视频剪辑